Add kigicli.dev frontend worker with built site assets

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012pFJn6ycA4hPRwM9sqasi6
This commit is contained in:
ZacharyZhang-NYandClaude Fable 5 committed 2026-08-25 23:04:06 -04:00
1 parent 3e1652ca98
commit 257caed650
51 files changed
+4459

No files matched your search

+48
View File
@@ -0,0 +1,48 @@
# kigicli.dev
The Kigi landing site and the Worker that fronts it, deployed to Cloudflare as
the `kigi-frontend` Worker on `kigicli.dev` and `www.kigicli.dev`.
## Layout
| Path | What it is |
| --------------- | ----------------------------------------------------------------- |
| `worker/index.ts` | Worker entry point: installer proxy, `/health`, asset fallthrough |
| `wrangler.jsonc` | Deployment config (custom domains, assets binding, SPA fallback) |
| `dist/` | The built site served by the assets binding |
> **`dist/` is build output, not source.** It was recovered by mirroring the
> live `kigicli.dev` deployment — the original Vite/React project that produced
> these bundles is not in this repo. Content and copy changes therefore have to
> be made against the hashed `dist/assets/index-*.js` and `index-*.css` files
> directly. If the upstream source ever turns up, drop it in beside `dist/` and
> switch `wrangler.jsonc` to point at its build directory.
## Routes
Assets are matched first and served directly. Requests with no matching file
fall through to the Worker, which owns:
- `GET /install.sh` — proxies `install.sh` from the Kigi repo on Gitea
- `GET /install.ps1` — proxies `install.ps1` from the Kigi repo on Gitea
- `GET /health` — plain-text liveness check
- everything else — `env.ASSETS.fetch()`, which serves `index.html` for unknown
paths (single-page-application fallback)
The installer routes are proxied rather than linked so the published install
command (`curl -fsSL https://kigicli.dev/install.sh | bash`) stays stable no
matter where the repo is hosted. Responses are cached for 10 minutes at the
edge, so a push to `main` takes up to that long to show up.
Because assets win over the Worker, never add `install.sh` or `install.ps1` to
`dist/` — they would shadow the proxy routes.
## Deploy
```sh
npm install
npx wrangler deploy
```
Cloudflare Web Analytics injects its beacon `<script>` at the edge; that is why
`dist/index.html` does not contain one and must not have one added.
File diff suppressed because it is too large. Load diff
+1
View File
@@ -0,0 +1 @@
.hero-scene{transform-origin:50%;animation:hero-scene-in 1.2s var(--ease-out) both;position:absolute;inset:0;overflow:hidden;transform:scale(1.06)}.hero-scene canvas{width:100%;height:100%}@keyframes hero-scene-in{0%{opacity:0}to{opacity:1}}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+14
View File
@@ -0,0 +1,14 @@
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/HeroScene-Cl_ooGaM.js","assets/HeroScene-DfWuSUL8.css"])))=>i.map(i=>d[i]);
var e=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports);(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var t=e((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.iterator;function m(e){return typeof e!=`object`||!e?null:(e=p&&e[p]||e[`@@iterator`],typeof e==`function`?e:null)}var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g=Object.assign,_={};function v(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}v.prototype.isReactComponent={},v.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=null)throw Error(`takes an object of state variables to update or a function which returns an object of state variables.`);this.updater.enqueueSetState(this,e,t,`setState`)},v.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function y(){}y.prototype=v.prototype;function b(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}var x=b.prototype=new y;x.constructor=b,g(x,v.prototype),x.isPureReactComponent=!0;var S=Array.isArray;function C(){}var w={H:null,A:null,T:null,S:null},T=Object.prototype.hasOwnProperty;function E(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function D(e,t){return E(e.type,t,e.props)}function O(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function k(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var A=/\/+/g;function j(e,t){return typeof e==`object`&&e&&e.key!=null?k(``+e.key):t.toString(36)}function M(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(C,C):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function N(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,N(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+j(e,0):a,S(o)?(i=``,c!=null&&(i=c.replace(A,`$&/`)+`/`),N(o,r,i,``,function(e){return e})):o!=null&&(O(o)&&(o=D(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(A,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(S(e))for(var u=0;u<e.length;u++)a=e[u],s=l+j(a,u),c+=N(a,r,i,s,o);else if(u=m(e),typeof u==`function`)for(e=u.call(e),u=0;!(a=e.next()).done;)a=a.value,s=l+j(a,u++),c+=N(a,r,i,s,o);else if(s===`object`){if(typeof e.then==`function`)return N(M(e),r,i,a,o);throw r=String(e),Error(`Objects are not valid as a React child (found: `+(r===`[object Object]`?`object with keys {`+Object.keys(e).join(`, `)+`}`:r)+`). If you meant to render a collection of children, use an array instead.`)}return c}function P(e,t,n){if(e==null)return e;var r=[],i=0;return N(e,r,``,``,function(e){return t.call(n,e,i++)}),r}function ee(e){if(e._status===-1){var t=e._result;t=t(),t.then(function(t){(e._status===0||e._status===-1)&&(e._status=1,e._result=t)},function(t){(e._status===0||e._status===-1)&&(e._status=2,e._result=t)}),e._status===-1&&(e._status=0,e._result=t)}if(e._status===1)return e._result.default;throw e._result}var F=typeof reportError==`function`?reportError:function(e){if(typeof window==`object`&&typeof window.ErrorEvent==`function`){var t=new window.ErrorEvent(`error`,{bubbles:!0,cancelable:!0,message:typeof e==`object`&&e&&typeof e.message==`string`?String(e.message):String(e),error:e});if(!window.dispatchEvent(t))return}else if(typeof process==`object`&&typeof process.emit==`function`){process.emit(`uncaughtException`,e);return}console.error(e)},I={map:P,forEach:function(e,t,n){P(e,function(){t.apply(this,arguments)},n)},count:function(e){var t=0;return P(e,function()Line truncated
at`)?` (<anonymous>)`:-1<e.stack.indexOf(`@`)?`@unknown:0:0`:``}return`
`+pe+e+me}var z=!1;function ge(e,t){if(!e||z)return``;z=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{var r={DetermineComponentFrameRoot:function(){try{if(t){var n=function(){throw Error()};if(Object.defineProperty(n.prototype,"props",{set:function(){throw Error()}}),typeof Reflect==`object`&&Reflect.construct){try{Reflect.construct(n,[])}catch(e){var r=e}Reflect.construct(e,[],n)}else{try{n.call()}catch(e){r=e}e.call(n.prototype)}}else{try{throw Error()}catch(e){r=e}(n=e())&&typeof n.catch==`function`&&n.catch(function(){})}}catch(e){if(e&&r&&typeof e.stack==`string`)return[e.stack,r.stack]}return[null,null]}};r.DetermineComponentFrameRoot.displayName=`DetermineComponentFrameRoot`;var i=Object.getOwnPropertyDescriptor(r.DetermineComponentFrameRoot,`name`);i&&i.configurable&&Object.defineProperty(r.DetermineComponentFrameRoot,"name",{value:`DetermineComponentFrameRoot`});var a=r.DetermineComponentFrameRoot(),o=a[0],s=a[1];if(o&&s){var c=o.split(`
`),l=s.split(`
`);for(i=r=0;r<c.length&&!c[r].includes(`DetermineComponentFrameRoot`);)r++;for(;i<l.length&&!l[i].includes(`DetermineComponentFrameRoot`);)i++;if(r===c.length||i===l.length)for(r=c.length-1,i=l.length-1;1<=r&&0<=i&&c[r]!==l[i];)i--;for(;1<=r&&0<=i;r--,i--)if(c[r]!==l[i]){if(r!==1||i!==1)do if(r--,i--,0>i||c[r]!==l[i]){var u=`
`+c[r].replace(` at new `,` at `);return e.displayName&&u.includes(`<anonymous>`)&&(u=u.replace(`<anonymous>`,e.displayName)),u}while(1<=r&&0<=i);break}}}finally{z=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?he(n):``}function _e(e,t){switch(e.tag){case 26:case 27:case 5:return he(e.type);case 16:return he(`Lazy`);case 13:return e.child!==t&&t!==null?he(`Suspense Fallback`):he(`Suspense`);case 19:return he(`SuspenseList`);case 0:case 15:return ge(e.type,!1);case 11:return ge(e.type.render,!1);case 1:return ge(e.type,!0);case 31:return he(`Activity`);default:return``}}function ve(e){try{var t=``,n=null;do t+=_e(e,n),n=e,e=e.return;while(e);return t}catch(e){return`
Error generating stack: `+e.message+`
`+e.stack}}var ye=Object.prototype.hasOwnProperty,B=t.unstable_scheduleCallback,be=t.unstable_cancelCallback,xe=t.unstable_shouldYield,Se=t.unstable_requestPaint,V=t.unstable_now,H=t.unstable_getCurrentPriorityLevel,Ce=t.unstable_ImmediatePriority,we=t.unstable_UserBlockingPriority,Te=t.unstable_NormalPriority,Ee=t.unstable_LowPriority,De=t.unstable_IdlePriority,Oe=t.log,ke=t.unstable_setDisableYieldValue,U=null,Ae=null;function je(e){if(typeof Oe==`function`&&ke(e),Ae&&typeof Ae.setStrictMode==`function`)try{Ae.setStrictMode(U,e)}catch{}}var Me=Math.clz32?Math.clz32:Fe,Ne=Math.log,Pe=Math.LN2;function Fe(e){return e>>>=0,e===0?32:31-(Ne(e)/Pe|0)|0}var Ie=256,Le=262144,Re=4194304;function ze(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function Be(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=ze(n))):i=ze(o):i=ze(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=ze(n))):i=ze(o)):i=ze(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function Ve(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function He(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Ue(){var e=Re;return Re<<=1,!(Re&62914560)&&(Re=4194304),e}function We(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function Ge(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function Ke(e,t,n,r,i,a){var o=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0<n;){var u=31-Me(n),d=1<<u;s[u]=0,c[u]=-1;var f=l[u];if(f!==null)for(l[u]=null,u=0;u<f.length;u++){var p=f[u];p!==null&&(p.lane&=-536870913)}n&=~d}r!==0&&qe(e,r,0),a!==0&&i===0&&e.tag!==0&&(e.suspendedLanes|=a&~(o&~t))}function qe(e,t,n){e.pendingLanes|=t,e.suspendedLanes&=~t;var r=31-Me(t);e.entangledLanes|=t,e.entanglements[r]=e.entanglements[r]|1073741824|n&261930}function Je(e,t){var n=e.entangledLanes|=t;for(e=e.entanglements;n;){var r=31-Me(n),i=1<<r;i&t|e[r]&t&&(e[r]|=t),n&=~i}}function Ye(e,t){var n=t&-t;return n=n&42?1:Xe(n),(n&(e.suspendedLanes|t))===0?n:0}function Xe(e){switch(e){case 2:e=1;break;case 8:e=4;break;case 32:e=16;break;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:e=128;break;case 268435456:e=134217728;break;default:e=0}return e}function Ze(e){return e&=-e,2<e?8<e?e&134217727?32:268435456:8:2}function Qe(){var e=I.p;return e===0?(e=window.event,e===void 0?32:mp(e.type)):e}function $e(e,t){var n=I.p;try{return I.p=e,t()}finally{I.p=n}}var et=Math.random().toString(36).slice(2),tt=`__reactFiber$`+et,nt=`__reactProps$`+et,rt=`__reactContainer$`+et,it=`__reactEvents$`+et,at=`__reactListeners$`+et,ot=`__reactHandles$`+et,st=`__reactResources$`+et,ct=`__reactMarker$`+et;function lt(e){delete e[tt],delete e[nt],delete e[it],delete e[at],delete e[ot]}function ut(e){var t=e[tt];if(t)return t;for(var n=e.parentNode;n;){if(t=n[rt]||n[tt]){if(n=t.alternate,t.child!==null||n!==null&&n.child!==null)for(e=df(e);e!==null;){if(n=e[tt])return n;e=df(e)}return t}e=n,n=e.parentNode}return null}function dt(e){if(e=e[tt]||e[rt]){var t=e.tag;if(t===5||t===6||t===13||t===31||t===26||t===27||t===3)return e}return null}function ft(e){var t=e.tag;if(t===5||t===26||t===27||t===6)return e.stateNode;throw Error(s(33))}function pt(e){var t=e[st];return t||=e[st]={hoistableStyles:new Map,hoistableScripts:new Map},t}function W(e){e[ct]=!0}var mt=new Set,ht={};function gt(e,t){_t(e,t),_t(e+`Capture`,t)}function _t(e,t){for(ht[e]=t,e=0;e<t.length;e++)mt.add(t[e])}var vt=RegExp(`^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7Line truncated
`).replace(kd,``)}function jd(e,t){return t=Ad(t),Ad(e)===t}function Md(e,t,n,r,i,a){switch(n){case`children`:typeof r==`string`?t===`body`||t===`textarea`&&r===``||zt(e,r):(typeof r==`number`||typeof r==`bigint`)&&t!==`body`&&zt(e,``+r);break;case`className`:Ct(e,`class`,r);break;case`tabIndex`:Ct(e,`tabindex`,r);break;case`dir`:case`role`:case`viewBox`:case`width`:case`height`:Ct(e,n,r);break;case`style`:Ht(e,r,a);break;case`data`:if(t!==`object`){Ct(e,`data`,r);break}case`src`:case`href`:if(r===``&&(t!==`a`||n!==`href`)){e.removeAttribute(n);break}if(r==null||typeof r==`function`||typeof r==`symbol`||typeof r==`boolean`){e.removeAttribute(n);break}r=Kt(``+r),e.setAttribute(n,r);break;case`action`:case`formAction`:if(typeof r==`function`){e.setAttribute(n,`javascript:throw new Error('A React form was unexpectedly submitted. If you called form.submit() manually, consider using form.requestSubmit() instead. If you\\'re trying to use event.stopPropagation() in a submit event handler, consider also calling event.preventDefault().')`);break}else typeof a==`function`&&(n===`formAction`?(t!==`input`&&Md(e,t,`name`,i.name,i,null),Md(e,t,`formEncType`,i.formEncType,i,null),Md(e,t,`formMethod`,i.formMethod,i,null),Md(e,t,`formTarget`,i.formTarget,i,null)):(Md(e,t,`encType`,i.encType,i,null),Md(e,t,`method`,i.method,i,null),Md(e,t,`target`,i.target,i,null)));if(r==null||typeof r==`symbol`||typeof r==`boolean`){e.removeAttribute(n);break}r=Kt(``+r),e.setAttribute(n,r);break;case`onClick`:r!=null&&(e.onclick=qt);break;case`onScroll`:r!=null&&vd(`scroll`,e);break;case`onScrollEnd`:r!=null&&vd(`scrollend`,e);break;case`dangerouslySetInnerHTML`:if(r!=null){if(typeof r!=`object`||!(`__html`in r))throw Error(s(61));if(n=r.__html,n!=null){if(i.children!=null)throw Error(s(60));e.innerHTML=n}}break;case`multiple`:e.multiple=r&&typeof r!=`function`&&typeof r!=`symbol`;break;case`muted`:e.muted=r&&typeof r!=`function`&&typeof r!=`symbol`;break;case`suppressContentEditableWarning`:case`suppressHydrationWarning`:case`defaultValue`:case`defaultChecked`:case`innerHTML`:case`ref`:break;case`autoFocus`:break;case`xlinkHref`:if(r==null||typeof r==`function`||typeof r==`boolean`||typeof r==`symbol`){e.removeAttribute(`xlink:href`);break}n=Kt(``+r),e.setAttributeNS(`http://www.w3.org/1999/xlink`,`xlink:href`,n);break;case`contentEditable`:case`spellCheck`:case`draggable`:case`value`:case`autoReverse`:case`externalResourcesRequired`:case`focusable`:case`preserveAlpha`:r!=null&&typeof r!=`function`&&typeof r!=`symbol`?e.setAttribute(n,``+r):e.removeAttribute(n);break;case`inert`:case`allowFullScreen`:case`async`:case`autoPlay`:case`controls`:case`default`:case`defer`:case`disabled`:case`disablePictureInPicture`:case`disableRemotePlayback`:case`formNoValidate`:case`hidden`:case`loop`:case`noModule`:case`noValidate`:case`open`:case`playsInline`:case`readOnly`:case`required`:case`reversed`:case`scoped`:case`seamless`:case`itemScope`:r&&typeof r!=`function`&&typeof r!=`symbol`?e.setAttribute(n,``):e.removeAttribute(n);break;case`capture`:case`download`:!0===r?e.setAttribute(n,``):!1!==r&&r!=null&&typeof r!=`function`&&typeof r!=`symbol`?e.setAttribute(n,r):e.removeAttribute(n);break;case`cols`:case`rows`:case`size`:case`span`:r!=null&&typeof r!=`function`&&typeof r!=`symbol`&&!isNaN(r)&&1<=r?e.setAttribute(n,r):e.removeAttribute(n);break;case`rowSpan`:case`start`:r==null||typeof r==`function`||typeof r==`symbol`||isNaN(r)?e.removeAttribute(n):e.setAttribute(n,r);break;case`popover`:vd(`beforetoggle`,e),vd(`toggle`,e),St(e,`popover`,r);break;case`xlinkActuate`:wt(e,`http://www.w3.org/1999/xlink`,`xlink:actuate`,r);break;case`xlinkArcrole`:wt(e,`http://www.w3.org/1999/xlink`,`xlink:arcrole`,r);break;case`xlinkRole`:wt(e,`http://www.w3.org/1999/xlink`,`xlink:role`,r);break;case`xlinkShow`:wt(e,`http://www.w3.org/1999/xlink`,`xlink:show`,r);break;case`xlinkTitle`:wt(e,`http://www.w3.org/1999/xlink`,`xlink:title`,r);break;case`xlinkType`:wt(e,`http://www.w3.org/1999/xlink`,`xlink:type`,r);break;case`xmlBase`:wt(e,`http://www.w3.org/XML/1998/namespace`,`xml:base`,r);break;case`xmlLang`:wt(e,`http://www.w3.org/XML/1998/namespace`,`xml:lang`,r);break;case`xmlSpace`:wt(e,`http://www.w3.org/XML/1998/namespace`,`xml:space`,r);break;case`is`:St(e,`is`,r);break;case`innerText`:case`textContent`:break;default:(!(2<n.length)||n[0]!==`o`&&n[0]!==`O`||n[1]!==`n`&&n[1]!==`N`)&&(n=Wt.get(n)||n,St(e,n,r))}}function Nd(e,t,n,r,i,a){switch(n){case`style`:Ht(e,r,a);break;case`dangerouslySetInnerHTML`:if(r!=null){if(typeof r!=`object`||!(`__html`in r))throw Error(s(61));if(n=r.__html,n!=null){if(i.children!=null)throw Error(s(60));e.innerHTML=n}}break;case`children`:typeof r==`string`?zt(e,r):(typeof r==`number`||typeof r==`bigint`)&&zt(e,``+r);break;case`onScroll`:r!=null&&vd(`scroll`,e);break;case`onScrollEnd`:r!=null&&vd(`scrollend`,e);break;case`onClick`:r!=null&&(e.onclick=qt);break;case`suppressContentEditableWarning`:case`suppressHydrationWarning`:case`inne Line truncated
<path d="M12 16.25C11.5858 16.25 11.25 16.5858 11.25 17C11.25 17.4142 11.5858 17.75 12 17.75H17C17.4142 17.75 17.75 17.4142 17.75 17C17.75 16.5858 17.4142 16.25 17 16.25H12Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.1318 2.25H5.86821C5.12513 2.24999 4.52196 2.24999 4.03273 2.28996C3.52778 2.33121 3.07851 2.41876 2.66103 2.63148C2.00247 2.96703 1.46703 3.50247 1.13148 4.16103C0.918762 4.57851 0.831214 5.02778 0.789958 5.53273C0.749986 6.02196 0.749993 6.62511 0.75 7.36819V16.6318C0.749993 17.3749 0.749986 17.978 0.789958 18.4673C0.831214 18.9722 0.918762 19.4215 1.13148 19.839C1.46703 20.4975 2.00247 21.033 2.66103 21.3685C3.07851 21.5812 3.52778 21.6688 4.03273 21.71C4.52195 21.75 5.12507 21.75 5.86811 21.75H18.1318C18.8748 21.75 19.4781 21.75 19.9673 21.71C20.4722 21.6688 20.9215 21.5812 21.339 21.3685C21.9975 21.033 22.533 20.4975 22.8685 19.839C23.0812 19.4215 23.1688 18.9722 23.21 18.4673C23.25 17.9781 23.25 17.3749 23.25 16.6319V7.36819C23.25 6.62515 23.25 6.02195 23.21 5.53273C23.1688 5.02778 23.0812 4.57851 22.8685 4.16103C22.533 3.50247 21.9975 2.96703 21.339 2.63148C20.9215 2.41876 20.4722 2.33121 19.9673 2.28996C19.478 2.24999 18.8749 2.24999 18.1318 2.25ZM21.75 7.25C21.7498 6.54743 21.7472 6.04838 21.715 5.65488C21.6813 5.24269 21.619 5.0128 21.532 4.84202C21.3403 4.4657 21.0343 4.15973 20.658 3.96799C20.4872 3.88097 20.2573 3.81865 19.8451 3.78498C19.4242 3.75058 18.8824 3.75 18.1 3.75H5.9C5.11755 3.75 4.57582 3.75058 4.15488 3.78498C3.74269 3.81865 3.5128 3.88097 3.34202 3.96799C2.9657 4.15973 2.65973 4.4657 2.46799 4.84202C2.38097 5.0128 2.31865 5.24269 2.28498 5.65488C2.25283 6.04838 2.25022 6.54743 2.25002 7.25H21.75ZM2.25 8.75H21.75V16.6C21.75 17.3824 21.7494 17.9242 21.715 18.3451C21.6813 18.7573 21.619 18.9872 21.532 19.158C21.3403 19.5343 21.0343 19.8403 20.658 20.032C20.4872 20.119 20.2573 20.1813 19.8451 20.215C19.4242 20.2494 18.8824 20.25 18.1 20.25H5.9C5.11755 20.25 4.57582 20.2494 4.15488 20.215C3.74269 20.1813 3.5128 20.119 3.34202 20.032C2.9657 19.8403 2.65973 19.5343 2.46799 19.158C2.38097 18.9872 2.31865 18.7573 2.28498 18.3451C2.25058 17.9242 2.25 17.3824 2.25 16.6V8.75Z" fill="currentColor"/>`,F:`<path d="M7.46967 10.4697C7.76256 10.1768 8.23744 10.1768 8.53033 10.4697L11.5303 13.4697C11.8232 13.7626 11.8232 14.2374 11.5303 14.5303L8.53033 17.5303C8.23744 17.8232 7.76256 17.8232 7.46967 17.5303C7.17678 17.2374 7.17678 16.7626 7.46967 16.4697L9.93934 14L7.46967 11.5303C7.17678 11.2374 7.17678 10.7626 7.46967 10.4697Z" fill="currentColor"/>
<path d="M12 16.25C11.5858 16.25 11.25 16.5858 11.25 17C11.25 17.4142 11.5858 17.75 12 17.75H17C17.4142 17.75 17.75 17.4142 17.75 17C17.75 16.5858 17.4142 16.25 17 16.25H12Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.03273 2.28996C4.52196 2.24999 5.12511 2.24999 5.86819 2.25H18.1318C18.8749 2.24999 19.478 2.24999 19.9673 2.28996C20.4722 2.33121 20.9215 2.41876 21.339 2.63148C21.9975 2.96703 22.533 3.50247 22.8685 4.16103C23.0812 4.57851 23.1688 5.02778 23.21 5.53273C23.25 6.02195 23.25 6.62507 23.25 7.36811V16.6318C23.25 17.3748 23.25 17.9781 23.21 18.4673C23.1688 18.9722 23.0812 19.4215 22.8685 19.839C22.533 20.4975 21.9975 21.033 21.339 21.3685C20.9215 21.5812 20.4722 21.6688 19.9673 21.71C19.4781 21.75 18.8749 21.75 18.1319 21.75H5.86819C5.12515 21.75 4.52195 21.75 4.03273 21.71C3.52778 21.6688 3.07851 21.5812 2.66103 21.3685C2.00247 21.033 1.46703 20.4975 1.13148 19.839C0.918762 19.4215 0.831214 18.9722 0.789958 18.4673C0.749986 17.978 0.749993 17.3749 0.75 16.6318V7.36821C0.749993 6.62513 0.749986 6.02196 0.789958 5.53273C0.831214 5.02778 0.918762 4.57851 1.13148 4.16103C1.46703 3.50247 2.00247 2.96703 2.66103 2.63148C3.07851 2.41876 3.52778 2.33121 4.03273 2.28996ZM2.25 8.75V16.6C2.25 17.3824 2.25058 17.9242 2.28498 18.3451C2.31865 18.7573 2.38097 18.9872 2.46799 19.158C2.65973 19.5343 2.9657 19.8403 3.34202 20.032C3.5128 20.119 3.74269 20.1813 4.15488 20.215C4.57582 20.2494 5.11755 20.25 5.9 20.25H18.1C18.8824 20.25 19.4242 20.2494 19.8451 20.215C20.2573 20.1813 20.4872 20.119 20.658 20.032C21.0343 19.8403 21.3403 19.5343 21.532 19.158C21.619 18.9872 21.6813 18.7573 21.715 18.3451C21.7494 17.9242 21.75 17.3824 21.75 16.6V8.75H2.25Z" fill="currentColor"/>`}),m=d(`Check`,{O:`<path d="M21.5303 5.46967C21.8232 5.76256 21.8232 6.23744 21.5303 6.53033L9.53033 18.5303C9.23744 18.8232 8.76256 18.8232 8.46967 18.5303L2.46967 12.5303C2.17678 12.2374 2.17678 11.7626 2.46967 11.4697C2.76256 11.1768 3.23744 11.1768 3.53033 11.4697L9 16.9393L20.4697 5.46967C20.7626 5.17678 21.2374 5.17678 21.5303 5.46967Z" fill="currentColor"/>`,F:`<path d="M21.7071 5.29289C22.0976 5.68342 22.0976 6.31658 21.7071 6.70711L9.70711 18.7071C9.31658 19.0976 8.68342 19.0976 8.29289 18.7071L2.29289 12.7071C1.90237 12.3166 1.90237 11.6834 2.29289 11.2929C2.68342 10.9024 3.31658 10.9024 3.70711 11.2929L9 16.5858L20.2929 5.29289C20.6834 4.90237 21.3166 4.90237 21.7071 5.29289Z" fill="currentColor"/>`}),h=d(`ChevronDown`,{F:`<g transform="scale(1.33333)"><path d="M9,13.5c-.192,0-.384-.073-.53-.22L2.22,7.03c-.293-.293-.293-.768,0-1.061s.768-.293,1.061,0l5.72,5.72,5.72-5.72c.293-.293,.768-.293,1.061,0s.293,.768,0,1.061l-6.25,6.25c-.146,.146-.338,.22-.53,.22Z" fill="currentColor"></path></g>`,O:`<g transform="scale(1.33333)"><polyline points="15.25 6.5 9 12.75 2.75 6.5" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></polyline></g>`}),g=d(`Code`,{O:`<path d="M14.1809 4.2755C14.581 4.3827 14.8185 4.79396 14.7113 5.19406L10.7377 20.0238C10.6304 20.4239 10.2192 20.6613 9.81909 20.5541C9.41899 20.4469 9.18156 20.0356 9.28876 19.6355L13.2624 4.80583C13.3696 4.40573 13.7808 4.16829 14.1809 4.2755Z" fill="currentColor"/><path d="M16.4425 7.32781C16.7196 7.01993 17.1938 6.99497 17.5017 7.27206L19.2392 8.8358C19.9756 9.49847 20.5864 10.0482 21.0058 10.5467C21.4468 11.071 21.7603 11.6342 21.7603 12.3295C21.7603 13.0248 21.4468 13.5881 21.0058 14.1123C20.5864 14.6109 19.9756 15.1606 19.2392 15.8233L17.5017 17.387C17.1938 17.6641 16.7196 17.6391 16.4425 17.3313C16.1654 17.0234 16.1904 16.5492 16.4983 16.2721L18.1947 14.7452C18.9826 14.0362 19.5138 13.5558 19.8579 13.1467C20.1882 12.7541 20.2603 12.525 20.2603 12.3295C20.2603 12.1341 20.1882 11.9049 19.8579 11.5123C19.5138 11.1033 18.9826 10.6229 18.1947 9.91383L16.4983 8.387C16.1904 8.10991 16.1654 7.63569 16.4425 7.32781Z" fill="currentColor"/><path d="M7.50178 8.387C7.80966 8.10991 7.83462 7.63569 7.55752 7.32781C7.28043 7.01993 6.80621 6.99497 6.49833 7.27206L4.76084 8.8358C4.0245 9.49847 3.41369 10.0482 2.99428 10.5467C2.55325 11.071 2.23975 11.6342 2.23975 12.3295C2.23975 13.0248 2.55325 13.5881 2.99428 14.1123C3.41369 14.6109 4.02449 15.1606 4.76082 15.8232L6.49833 17.387C6.80621 17.6641 7.28043 17.6391 7.55752 17.3313C7.83462 17.0234 7.80966 16.5492 7.50178 16.2721L5.80531 14.7452C5.01743 14.0362 4.48623 13.5558 4.14213 13.1467C3.81188 12.7541 3.73975 12.525 3.73975 12.3295C3.73975 12.1341 3.81188 11.9049 4.14213 11.5123C4.48623 11.1033 5.01743 10.6229 5.80531 9.91383L7.50178 8.387Z" fill="currentColor"/>`,F:`<path d="M14.1809 4.2755C14.581 4.3827 14.8185 4.79396 14.7113 5.19406L10.7377 20.0238C10.6304 20.4239 10.2192 20.6613 9.81909 20.5541C9.41899 20.4469 9.18156 20.0356 9.28876 19.6355L13.2624 4.80583C13.3696 4.40573 13.7808 4.16829 14.1809 4.2755Z" fill="currentColor"/><path d="M16.4425 7.32781C16.7196 7.01993 17.1938 6.99497 17.5017 7.27206L19.2392 8.8358C19.9756 9.49847 20.5864 10.0482 21.0058 10.5467C21.4468 11.071 21.7603 11.6342 21.7603 12.3295C21.7603 13.0248 21.4468 13.5881 21.0058 14.1123C20.5864 14.6109 19.9756 15.1606 19.2392 15.8233L17.5017 17.387C17.1938 17.6641 16.7196 17.6391 16.4425 17.331Line truncated
+1
View File
@@ -0,0 +1 @@
.btn{justify-content:center;align-items:center;gap:var(--s2);height:44px;padding-inline:var(--s5);border-radius:var(--r-md);letter-spacing:-.01em;white-space:nowrap;transition:transform var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);font-size:14px;font-weight:500;display:inline-flex}.btn:hover{transform:translateY(-1px)}.btn:active{transform:translateY(0)scale(.98)}.btn--lg{height:52px;padding-inline:var(--s6);font-size:15px}.btn--primary{background:var(--ink);color:var(--paper)}.btn--primary:hover{background:var(--ink-hover)}.btn--secondary{-webkit-backdrop-filter:blur(8px);color:var(--ink);box-shadow:inset 0 0 0 1px var(--line-strong);background:#fffc}.btn--secondary:hover{box-shadow:inset 0 0 0 1px var(--taupe);background:#fff}.btn--ghost{color:var(--ink-secondary);padding-inline:var(--s3);background:0 0}.btn--ghost:hover{color:var(--ink);transform:none}.btn--primary.btn--invert{background:var(--paper);color:var(--ink)}.btn--primary.btn--invert:hover{background:#fff}.btn--secondary.btn--invert{color:var(--well-ink);box-shadow:inset 0 0 0 1px var(--well-line);background:0 0}.btn--secondary.btn--invert:hover{background:var(--well-raised);box-shadow:inset 0 0 0 1px var(--well-ink-dim)}.btn--ghost.btn--invert{color:var(--well-ink-dim)}.btn--ghost.btn--invert:hover{color:var(--well-ink)}.nav{z-index:100;transition:transform var(--dur-med) var(--ease-out), background-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);position:fixed;inset:0 0 auto}.nav--scrolled{background:color-mix(in srgb, var(--paper) 82%, transparent);-webkit-backdrop-filter:blur(16px);box-shadow:inset 0 -1px 0 var(--line)}.nav--hidden{transform:translateY(-100%)}.nav__inner{align-items:center;gap:var(--s8);height:64px;display:flex}.nav__logo{align-items:center;gap:var(--s3);letter-spacing:-.02em;font-size:18px;font-weight:500;display:inline-flex}.nav__logo span{font-family:var(--font-serif-medium);letter-spacing:-.02em;font-size:22px}.nav__logo svg{border-radius:6px;display:block}.nav__links{align-items:center;gap:var(--s1);margin-inline-start:var(--s4);display:flex}.nav__link{align-items:center;gap:var(--s1);padding:var(--s2) var(--s3);border-radius:var(--r-sm);color:var(--ink-secondary);transition:color var(--dur-fast) var(--ease-out);font-size:14px;font-weight:400;display:inline-flex;position:relative}.nav__link:after{content:"";left:var(--s3);right:var(--s3);border-radius:var(--r-full);background:var(--ink);transform-origin:0;height:2px;transition:transform var(--dur-fast) var(--ease-out);position:absolute;bottom:2px;transform:scaleX(0)}.nav__link:hover{color:var(--ink)}.nav__link:hover:after{transform:scaleX(1)}.nav__link--icon:after,.nav__link--btn:after{content:none}.nav__link--icon{padding:var(--s2)}.nav__dropdown{position:relative}.nav__dropdown svg{transition:transform var(--dur-fast) var(--ease-out)}.nav__dropdown:hover svg,.nav__dropdown:focus-within svg{transform:rotate(180deg)}.nav__menu{top:calc(100% + var(--s2));min-width:220px;padding:var(--s2);border-radius:var(--r-md);background:var(--paper);box-shadow:0 0 0 1px var(--line), 0 12px 32px #18181814;opacity:0;pointer-events:none;transition:opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);position:absolute;left:0;transform:translateY(-4px)}.nav__menu:before{content:"";left:0;right:0;top:calc(-1 * var(--s2));height:var(--s2);position:absolute}.nav__dropdown:hover .nav__menu,.nav__dropdown:focus-within .nav__menu{opacity:1;pointer-events:auto;transform:translateY(0)}.nav__menu-item{padding:var(--s2) var(--s3);border-radius:var(--r-sm);color:var(--ink-secondary);display:block}.nav__menu-item:hover{color:var(--ink);background:var(--paper-raised)}.nav__cta{margin-inline-start:auto}.nav__burger{color:var(--ink);margin-inline-start:auto;display:none}.nav__mobile{display:none}@media (width<=860px){.nav__links,.nav__cta{display:none}.nav__burger{display:inline-flex}.nav__mobile{gap:var(--s1);padding:var(--s3) var(--s6) var(--s6);background:var(--paper);box-shadow:inset 0 -1px 0 var(--line), 0 16px 32px #18181814;opacity:0;pointer-events:none;visibility:hidden;transition:opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out), visibility 0s linear var(--dur-fast);flex-direction:column;display:flex;position:absolute;top:100%;left:0;right:0;transform:translateY(-8px)}.nav__mobile--open{visibility:visible;transition:opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out), visibility 0s;opacity:1;pointer-events:auto;transform:translateY(0)}.nav__mobile-link{padding:var(--s3) var(--s2);color:var(--ink);font-size:16px}.nav__mobile-cta{margin-top:var(--s3)}}.copycmd{align-items:center;gap:var(--s3);width:100%;max-width:640px;padding:var(--s4) var(--s5);border-radius:var(--r-md);-webkit-backdrop-filter:blur(8px);box-shadow:inset 0 0 0 1px var(--line);text-aliLine truncated
+15
View File
@@ -0,0 +1,15 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<rect width="64" height="64" rx="12" fill="#d7d7d0"/>
<g fill="#1a1614">
<circle cx="18" cy="16" r="3.2"/>
<circle cx="18" cy="27" r="3.2"/>
<circle cx="18" cy="38" r="3.2"/>
<circle cx="18" cy="49" r="3.2"/>
<circle cx="29" cy="32.5" r="3.2"/>
<circle cx="38" cy="23" r="3.2"/>
<circle cx="47" cy="14" r="3.2"/>
<circle cx="38" cy="42" r="3.2"/>
<circle cx="47" cy="51" r="3.2"/>
</g>
<circle cx="53" cy="32.5" r="3.2" fill="#DE4E1A"/>
</svg>

After

Width:  |  Height:  |  Size: 549 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

+43
View File
@@ -0,0 +1,43 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Kigi: the open-source CLI coding agent with built-in Graph Engineering</title>
<meta
name="description"
content="Kigi is a terminal coding agent that turns one objective into a dependency graph of self-verifying agent loops. 29 providers, your existing subscriptions, zero telemetry. Apache-2.0."
/>
<meta property="og:type" content="website" />
<meta property="og:site_name" content="Kigi" />
<meta property="og:url" content="https://kigicli.dev" />
<meta property="og:title" content="Kigi: the open-source CLI coding agent with built-in Graph Engineering" />
<meta
property="og:description"
content="One objective in. Verified work out. 29 providers, your existing subscriptions, zero telemetry."
/>
<meta property="og:image" content="https://kigicli.dev/og.png" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Kigi: the open-source CLI coding agent with built-in Graph Engineering" />
<meta
name="twitter:description"
content="One objective in. Verified work out. 29 providers, your existing subscriptions, zero telemetry."
/>
<meta name="twitter:image" content="https://kigicli.dev/og.png" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="preconnect" href="https://db.onlinewebfonts.com" crossorigin />
<link
rel="stylesheet"
href="https://db.onlinewebfonts.com/c/53077f9a3eee9c479d37d6af20394ded?family=Cooper+BT+W01+Light"
/>
<link
rel="stylesheet"
href="https://db.onlinewebfonts.com/c/5ade3423145f3b9f7031574333ca0b73?family=Cooper+BT+W01+Medium"
/>
<script type="module" crossorigin src="/assets/index-Bf_hNuMB.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-C2SWhjL9.css">
</head>
<body>
<div id="root"></div>
</body>
</html>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 411 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+14
View File
@@ -0,0 +1,14 @@
{
"name": "kigi-frontend",
"version": "0.0.0",
"private": true,
"description": "kigicli.dev — static marketing site plus the installer proxy Worker.",
"scripts": {
"dev": "wrangler dev",
"deploy": "wrangler deploy",
"tail": "wrangler tail"
},
"devDependencies": {
"wrangler": "^4.120.0"
}
}
+114
View File
@@ -0,0 +1,114 @@
/**
* kigicli.dev — static site + installer proxy.
*
* Static assets are served directly by the assets binding (SPA fallback). Only
* paths that do not match an asset reach this Worker, which is where the two
* installer routes live:
*
* GET https://kigicli.dev/install.sh → install.sh from the Kigi repo
* GET https://kigicli.dev/install.ps1 → install.ps1 from the Kigi repo
*
* Keeping these behind our own domain means the published install command never
* has to change when the source host does.
*/
interface Env {
ASSETS: Fetcher;
}
/** Raw-file base for the canonical Kigi repo (Gitea, `main` branch). */
const UPSTREAM = "https://git.zacharyzhang.com/ZacharyZhang-NY/Kigi-CLI/raw/branch/main";
/** Human-facing repo URL, used in the installer-unavailable message. */
const REPO_URL = "https://git.zacharyzhang.com/ZacharyZhang-NY/Kigi-CLI";
interface Installer {
file: string;
contentType: string;
/** Emitted when upstream is unreachable — must be valid in the target shell. */
unavailable: (status: number) => string;
}
const INSTALLERS: Record<string, Installer> = {
"/install.sh": {
file: "install.sh",
contentType: "text/x-shellscript; charset=utf-8",
unavailable: (status) =>
`echo "kigicli.dev: installer unavailable (upstream ${status}). Try ${REPO_URL}" >&2; exit 1\n`,
},
"/install.ps1": {
file: "install.ps1",
contentType: "text/plain; charset=utf-8",
unavailable: (status) =>
`Write-Error "kigicli.dev: installer unavailable (upstream ${status}). Try ${REPO_URL}"; exit 1\n`,
},
};
async function serveInstaller(
request: Request,
path: string,
ctx: ExecutionContext,
): Promise<Response> {
const { file, contentType, unavailable } = INSTALLERS[path];
const cache = caches.default;
const cacheKey = new Request(`${UPSTREAM}/${file}`, { method: "GET" });
let upstream = await cache.match(cacheKey);
if (!upstream) {
upstream = await fetch(cacheKey, {
headers: { "User-Agent": "kigicli.dev-installer-proxy" },
cf: { cacheTtl: 600, cacheEverything: true },
});
if (upstream.ok) {
const cacheable = new Response(upstream.clone().body, upstream);
cacheable.headers.set("Cache-Control", "public, max-age=600");
ctx.waitUntil(cache.put(cacheKey, cacheable));
}
}
if (!upstream.ok) {
return new Response(unavailable(upstream.status), {
status: 502,
headers: { "Content-Type": contentType },
});
}
const headers = new Headers({
"Content-Type": contentType,
"Cache-Control": "public, max-age=600",
"X-Content-Type-Options": "nosniff",
});
console.log(
JSON.stringify({
event: "install_script",
script: path,
ua: request.headers.get("User-Agent") ?? "",
ref: request.headers.get("Referer") ?? "",
}),
);
return new Response(upstream.body, { status: 200, headers });
}
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const url = new URL(request.url);
if (url.pathname in INSTALLERS) {
if (request.method !== "GET" && request.method !== "HEAD") {
return new Response("Method Not Allowed", {
status: 405,
headers: { Allow: "GET, HEAD" },
});
}
return serveInstaller(request, url.pathname, ctx);
}
if (url.pathname === "/health") {
return new Response("ok\n", { headers: { "Content-Type": "text/plain" } });
}
return env.ASSETS.fetch(request);
},
} satisfies ExportedHandler<Env>;
+26
View File
@@ -0,0 +1,26 @@
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "kigi-frontend",
"main": "worker/index.ts",
"compatibility_date": "2026-07-01",
// Assets are matched first and served directly; anything without a matching
// file falls through to the Worker (that is how /install.sh and /install.ps1
// reach it). The SPA fallback applies to the explicit env.ASSETS.fetch() call.
"assets": {
"directory": "./dist",
"binding": "ASSETS",
"not_found_handling": "single-page-application"
},
"workers_dev": false,
"routes": [
{ "pattern": "kigicli.dev", "custom_domain": true },
{ "pattern": "www.kigicli.dev", "custom_domain": true }
],
"observability": {
"enabled": true,
"head_sampling_rate": 1
}
}