@makerstufferupper/flypi 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/dist/ui/assets/{index-Dv6ZykyY.js → index-DmMmjg_M.js} +1 -1
- package/dist/ui/index.html +1 -1
- package/package.json +4 -2
- package/scripts/dev-container.mjs +131 -0
- package/scripts/release-check.mjs +239 -0
- package/src/server/index.ts +12 -2
- package/src/server/session-registry.ts +26 -2
package/README.md
CHANGED
|
@@ -60,6 +60,11 @@ UI comes up normally and the model turn says out loud that no default is set.
|
|
|
60
60
|
- A daemon with a scheduler, a tool permission gate, and an encrypted secrets vault.
|
|
61
61
|
- Any endpoint pi supports, including local OpenAI-compatible servers.
|
|
62
62
|
|
|
63
|
+
## Releasing
|
|
64
|
+
|
|
65
|
+
Maintainers: the runbook is [docs/release.md](docs/release.md) and the rehearsal it starts with is
|
|
66
|
+
[docs/release-checks.md](docs/release-checks.md) — `npm run release:check`.
|
|
67
|
+
|
|
63
68
|
## License
|
|
64
69
|
|
|
65
70
|
MIT
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(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),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var e=Array.isArray,t=Array.prototype.indexOf,n=Array.prototype.includes,r=Array.from,i=Object.defineProperty,a=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyDescriptors,s=Object.prototype,c=Array.prototype,l=Object.getPrototypeOf,u=Object.isExtensible,d=()=>{};function f(e){for(var t=0;t<e.length;t++)e[t]()}function p(){var e,t;return{promise:new Promise((n,r)=>{e=n,t=r}),resolve:e,reject:t}}var m=1024,h=2048,g=4096,_=8192,v=16384,y=32768,b=1<<25,x=65536,S=1<<19,ee=1<<20,te=1<<25,C=1<<21,ne=1<<22,w=1<<23,re=Symbol(`$state`),ie=Symbol(`component`),ae=Symbol(``),oe=Symbol(`attributes`),se=Symbol(`class`),ce=Symbol(`style`),le=Symbol(`text`),ue=Symbol(`form reset`),de=new class extends Error{name=`StaleReactionError`;message="The reaction that called `getAbortSignal()` was re-run or destroyed"},fe=!!globalThis.document?.contentType&&globalThis.document.contentType.includes(`xml`),pe={},T=Symbol(`uninitialized`),me=`http://www.w3.org/1999/xhtml`,he=`http://www.w3.org/2000/svg`,ge=`http://www.w3.org/1998/Math/MathML`;function _e(){console.warn(`https://svelte.dev/e/derived_inert`)}function ve(e){console.warn(`https://svelte.dev/e/hydration_mismatch`)}function ye(){console.warn(`https://svelte.dev/e/select_multiple_invalid_value`)}function be(){console.warn(`https://svelte.dev/e/svelte_boundary_reset_noop`)}var E=!1;function xe(e){E=e}var D;function O(e){if(e===null)throw ve(),pe;return D=e}function Se(){return O(nn(D))}function k(e){if(E){if(nn(D)!==null)throw ve(),pe;D=e}}function Ce(e=1){if(E){for(var t=e,n=D;t--;)n=nn(n);D=n}}function we(e=!0){for(var t=0,n=D;;){if(n.nodeType===8){var r=n.data;if(r===`]`){if(t===0)return n;--t}else(r===`[`||r===`[!`||r[0]===`[`&&!isNaN(Number(r.slice(1))))&&(t+=1)}var i=nn(n);e&&n.remove(),n=i}}function Te(e){if(!e||e.nodeType!==8)throw ve(),pe;return e.data}function Ee(e){return e===this.v}function De(e,t){return e==e?e!==t||typeof e==`object`&&!!e||typeof e==`function`:t==t}function Oe(e){return!De(e,this.v)}function ke(e){throw Error(`https://svelte.dev/e/lifecycle_outside_component`)}function Ae(){throw Error(`https://svelte.dev/e/async_derived_orphan`)}function je(e,t,n){throw Error(`https://svelte.dev/e/each_key_duplicate`)}function Me(e){throw Error(`https://svelte.dev/e/effect_in_teardown`)}function Ne(){throw Error(`https://svelte.dev/e/effect_in_unowned_derived`)}function Pe(e){throw Error(`https://svelte.dev/e/effect_orphan`)}function Fe(){throw Error(`https://svelte.dev/e/effect_update_depth_exceeded`)}function Ie(){throw Error(`https://svelte.dev/e/state_descriptors_fixed`)}function Le(){throw Error(`https://svelte.dev/e/state_prototype_fixed`)}function Re(){throw Error(`https://svelte.dev/e/state_unsafe_mutation`)}function ze(){throw Error(`https://svelte.dev/e/svelte_boundary_reset_onerror`)}var Be=null;function Ve(e){Be=e}function He(e,t=!1,n){Be={p:Be,i:!1,c:null,e:null,s:e,x:null,r:V,l:null}}function Ue(e){var t=Be,n=t.e;if(n!==null){t.e=null;for(var r of n)gn(r)}return e!==void 0&&(t.x=e),t.i=!0,Be=t.p,We(e)}function We(e={}){return i(e,ie,{value:!0}),e}function Ge(){return!0}var Ke=[];function qe(){var e=Ke;Ke=[],f(e)}function Je(e){if(Ke.length===0&&!xt){var t=Ke;queueMicrotask(()=>{t===Ke&&qe()})}Ke.push(e)}function Ye(){for(;Ke.length>0;)qe()}var Xe=~(h|g|m);function A(e,t){e.f=e.f&Xe|t}function Ze(e){e.f&512||e.deps===null?A(e,m):A(e,g)}function Qe(e,t,n){e.f&2048?t.add(e):e.f&4096&&n.add(e),A(e,m)}function $e(e){E&&tn(e)!==null&&rn(e)}var et=!1;function tt(){et||(et=!0,document.addEventListener(`reset`,e=>{Promise.resolve().then(()=>{if(!e.defaultPrevented)for(let t of e.target.elements)t[ue]?.()})},{capture:!0}))}function nt(e){var t=B,n=V;Rn(null),zn(null);try{return e()}finally{Rn(t),zn(n)}}function rt(e,t,n,r=n){e.addEventListener(t,()=>nt(n));let i=e[ue];e[ue]=i?()=>{i(),r(!0)}:()=>r(!0),tt()}function it(e,t,n,r){let i=Ge()?ct:dt;var a=e.filter(e=>!e.settled),o=t.map(i);if(n.length===0&&a.length===0){r(o);return}var s=V,c=at(),l=a.length===1?a[0].promise:a.length>1?Promise.all(a.map(e=>e.promise)):null;function u(e){if(!(s.f&16384)){c();try{r([...o,...e])}catch(e){ln(e,s)}ot()}}var d=st();if(n.length===0){l.then(()=>u([])).finally(d);return}function f(){Promise.all(n.map(e=>ut(e))).then(u).catch(e=>ln(e,s)).finally(d)}l?l.then(()=>{if(s.f&16384){d();return}c(),f(),ot()}):f()}function at(){var e=V,t=B,n=Be,r=M;return function(i=!0){zn(e),Rn(t),Ve(n),i&&!(e.f&16384)&&(r?.activate(),r?.apply())}}function ot(e=!0){zn(null),Rn(null),Ve(null),e&&M?.deactivate()}function st(){var e=V,t=e.b,n=M,r=!!t?.is_rendered();return t?.update_pending_count(1,n),n.increment(r,e),()=>{t?.update_pending_count(-1,n),n.decrement(r,e)}}function ct(e){var t=2|h;return V!==null&&(V.f|=S),{ctx:Be,deps:null,effects:null,equals:Ee,f:t,fn:e,reactions:null,rv:0,v:T,wv:0,parent:V,ac:null}}var lt=Symbol(`obsolete`);function ut(e,t,n){let r=V;r===null&&Ae();var i=void 0,a=Rt(T),o=!B,s=new Set;return yn(()=>{var t=V,n=p();i=n.promise;try{Promise.resolve(e()).then(n.resolve,e=>{e!==de&&n.reject(e)}).finally(ot)}catch(e){n.reject(e),ot()}var c=M;if(o){if(t.f&32768)var l=st();if(r.b?.is_rendered())c.async_deriveds.get(t)?.reject(lt);else for(let e of s.values())e.reject(lt);s.add(n),c.async_deriveds.set(t,n)}let u=(e,t=void 0)=>{l?.(),s.delete(n),t!==lt&&(c.activate(),t?(a.f|=w,Ht(a,t)):(a.f&8388608&&(a.f^=w),Ht(a,e)),c.deactivate())};n.promise.then(u,e=>u(null,e||`unknown`))}),mn(()=>{for(let e of s)e.reject(lt)}),new Promise(e=>{function t(n){function r(){n===i?e(a):t(i)}n.then(r,r)}t(i)})}function j(e){let t=ct(e);return Vn(t),t}function dt(e){let t=ct(e);return t.equals=Oe,t}function ft(e){var t=e.effects;if(t!==null){e.effects=null;for(var n=0;n<t.length;n+=1)En(t[n])}}function pt(e){var t,n=V,r=e.parent;if(!Fn&&r!==null&&e.v!==T&&r.f&24576)return _e(),e.v;zn(r);try{ft(e),t=$n(e)}finally{zn(n)}return t}function mt(e){var t=pt(e);if(!e.equals(t)&&(e.wv=Xn(),(!M?.is_fork||e.deps===null)&&(M===null?e.v=t:(M.capture(e,t,!0),vt?.capture(e,t,!0)),e.deps===null))){A(e,m);return}Fn||(yt===null?Ze(e):(pn()||M?.is_fork)&&yt.set(e,t))}function ht(e){if(e.effects!==null)for(let t of e.effects)(t.teardown||t.ac)&&(t.teardown?.(),t.ac!==null&&nt(()=>{t.ac.abort(de),t.ac=null}),t.fn!==null&&(t.teardown=d),nr(t,0),wn(t))}function gt(e){if(e.effects!==null)for(let t of e.effects)t.teardown&&t.fn!==null&&rr(t)}var _t=null,M=null,vt=null,yt=null,bt=null,xt=!1,St=!1,Ct=null,wt=null,Tt=0,Et=1,Dt=class e{id=Et++;#e=!1;linked=!0;#t=null;#n=null;async_deriveds=new Map;current=new Map;previous=new Map;#r=new Set;#i=new Set;#a=0;#o=new Map;#s=null;#c=[];#l=[];#u=new Set;#d=new Set;#f=new Map;#p=new Set;is_fork=!1;#m=!1;constructor(){_t===null?_t=this:(_t.#n=this,this.#t=_t),_t=this}#h(){if(this.is_fork)return!0;for(let n of this.#o.keys()){for(var e=n,t=!1;e.parent!==null;){if(this.#f.has(e)){t=!0;break}e=e.parent}if(!t)return!0}return!1}skip_effect(e){this.#f.has(e)||this.#f.set(e,{d:[],m:[]}),this.#p.delete(e)}unskip_effect(e,t=e=>this.schedule(e)){var n=this.#f.get(e);if(n){this.#f.delete(e);for(var r of n.d)A(r,h),t(r);for(r of n.m)A(r,g),t(r)}this.#p.add(e)}#g(){var e=[];for(let i of this.#c)if(!(i.f&16384||!(i.f&6144))){for(var t=i,n=!1;t.parent!==null;){t=t.parent;var r=t.f;if(r&96){if(!(r&1024)){n=!0;break}t.f^=m}}n||e.push(t)}return this.#c=[],e}#_(){this.#e=!0;for(let e of this.#u)this.#d.delete(e),A(e,h),this.schedule(e);for(let e of this.#d)A(e,g),this.schedule(e);this.apply();for(var t=Ct=[],n=[],r=wt=[];this.#c.length>0;){Tt++>1e3&&(this.#S(),kt());for(let e of this.#g())try{this.#v(e,t,n)}catch(t){throw Pt(e),this.#h()||this.discard(),t}}if(M=null,r.length>0){var i=e.ensure();for(let e of r)i.schedule(e)}if(Ct=null,wt=null,this.#h()){this.#x(n),this.#x(t);for(let[e,t]of this.#f)Nt(e,t);r.length>0&&M.#_();return}let a=this.#y();if(a){this.#x(n),this.#x(t),a.#b(this);return}this.#u.clear(),this.#d.clear();for(let e of this.#r)e(this);this.#r.clear(),vt=this,jt(n),jt(t),vt=null,this.#s?.resolve();var o=M;if(this.#a===0&&(this.#c.length===0||o!==null)&&this.#S(),this.#c.length>0){if(o!==null){for(let e of this.#c)o.#c.push(e);this.#c=[]}else o=this}o!==null&&(It.clear(),o.#_())}#v(e,t,n){e.f^=m;for(var r=e.first;r!==null;){var i=r.f,a=!!(i&96);if(!(a&&i&1024||i&8192||this.#f.has(r))&&r.fn!==null){a?r.f^=m:i&4?t.push(r):Zn(r)&&(i&16&&this.#d.add(r),rr(r));var o=r.first;if(o!==null){r=o;continue}}for(;r!==null;){var s=r.next;if(s!==null){r=s;break}r=r.parent}}}#y(){for(var e=this.#t;e!==null;){if(!e.is_fork){for(let[t,[,n]]of this.current)if(e.current.has(t)&&!n)return e}e=e.#t}return null}#b(e){for(let[t,n]of e.current)!this.previous.has(t)&&e.previous.has(t)&&this.previous.set(t,e.previous.get(t)),this.current.set(t,n);for(let[t,n]of e.async_deriveds){let e=this.async_deriveds.get(t);e&&n.promise.then(e.resolve).catch(e.reject)}e.async_deriveds.clear(),this.transfer_effects(e.#u,e.#d);let t=e=>{var n=e.reactions;if(n!==null&&!(e.f&2&&!(e.f&6144)))for(let e of n){var r=e.f;if(r&2)t(e);else{var i=e;r&4194320&&!this.async_deriveds.has(i)&&(this.#d.delete(i),A(i,h),this.schedule(i))}}};for(let e of this.current.keys())t(e);this.oncommit(()=>e.discard()),e.#S(),M=this,this.#_()}#x(e){for(var t=0;t<e.length;t+=1)Qe(e[t],this.#u,this.#d)}capture(e,t,n=!1){e.v!==T&&!this.previous.has(e)&&this.previous.set(e,e.v),e.f&8388608||(this.current.set(e,[t,n]),yt?.set(e,t)),this.is_fork||(e.v=t)}activate(){M=this}deactivate(){M=null,yt=null}flush(){try{St=!0,M=this,this.#_()}finally{Tt=0,bt=null,Ct=null,wt=null,St=!1,M=null,yt=null,It.clear()}}discard(){for(let e of this.#i)e(this);this.#i.clear();for(let e of this.async_deriveds.values())e.reject(lt);this.#S(),this.#s?.resolve()}register_created_effect(e){this.#l.push(e)}increment(e,t){if(this.#a+=1,e){let e=this.#o.get(t)??0;this.#o.set(t,e+1)}}decrement(e,t){if(--this.#a,e){let e=this.#o.get(t)??0;e===1?this.#o.delete(t):this.#o.set(t,e-1)}this.#m||(this.#m=!0,Je(()=>{this.#m=!1,this.linked&&this.flush()}))}transfer_effects(e,t){for(let t of e)this.#u.add(t);for(let e of t)this.#d.add(e);e.clear(),t.clear()}oncommit(e){this.#r.add(e)}ondiscard(e){this.#i.add(e)}settled(){return(this.#s??=p()).promise}static ensure(){if(M===null){let t=M=new e;!St&&!xt&&Je(()=>{t.#e||t.flush()})}return M}apply(){yt=null}schedule(e){if(bt=e,e.b?.is_pending&&e.f&16777228&&!(e.f&32768)){e.b.defer_effect(e);return}this.#c.push(e)}#S(){if(this.linked){var e=this.#t,t=this.#n;e===null||(e.#n=t),t===null?_t=e:t.#t=e,this.linked=!1}}};function Ot(e){var t=xt,n=vt;vt=null,xt=!0;try{var r;for(e&&(Ot(),r=e());;){if(Ye(),M===null)return r;M.flush()}}finally{xt=t,vt=n}}function kt(){try{Fe()}catch(e){ln(e,bt)}}var At=null;function jt(e){var t=e.length;if(t!==0){for(var n=0;n<t;){var r=e[n++];if(!(r.f&24576)&&Zn(r)&&(At=new Set,rr(r),r.deps===null&&r.first===null&&r.nodes===null&&r.teardown===null&&r.ac===null&&On(r),At?.size>0)){It.clear();for(let e of At){if(e.f&24576)continue;let t=[e],n=e.parent;for(;n!==null;)At.has(n)&&(At.delete(n),t.push(n)),n=n.parent;for(let e=t.length-1;e>=0;e--){let n=t[e];n.f&24576||rr(n)}}At.clear()}}At=null}}function Mt(e){M.schedule(e)}function Nt(e,t){if(!(e.f&32&&e.f&1024)){e.f&2048?t.d.push(e):e.f&4096&&t.m.push(e),A(e,m);for(var n=e.first;n!==null;)Nt(n,t),n=n.next}}function Pt(e){A(e,m);for(var t=e.first;t!==null;)Pt(t),t=t.next}var Ft=new Set,It=new Map,Lt=!1;function Rt(e,t){return{f:0,v:e,reactions:null,equals:Ee,rv:0,wv:0}}function N(e,t){let n=Rt(e,t);return Vn(n),n}function zt(e,t=!1,n=!0){let r=Rt(e);return t||(r.equals=Oe),r}function P(e,t,n=!1){return B!==null&&(!Ln||B.f&131072)&&Ge()&&B.f&4325394&&(Bn===null||!Bn.has(e))&&Re(),Ht(e,n?Kt(t):t,wt)}var Bt=null,Vt=0;function Ht(e,t,n=null){if(!e.equals(t)){Fn?It.set(e,t):It.has(e)||It.set(e,e.v);var r=Dt.ensure();if(r.capture(e,t),e.f&2){let t=e;e.f&2048&&pt(t),yt===null&&Ze(t)}e.wv=Xn(),Bt=null,Vt=0,Gt(e,h,n),Bt=null,Ge()&&V!==null&&V.f&1024&&!(V.f&96)&&(Wn===null?Gn([e]):Wn.push(e)),!r.is_fork&&Ft.size>0&&!Lt&&Ut()}return t}function Ut(){Lt=!1;for(let e of Ft){e.f&1024&&A(e,g);let t;try{t=Zn(e)}catch{t=!0}t&&rr(e)}Ft.clear()}function Wt(e){P(e,e.v+1)}function Gt(e,t,n){var r=e.reactions;if(r!==null){var i=Ge(),a=r.length;if(Vt+=a,Vt>1e5&&Bt===null&&(Bt=new Set),Bt!==null){if(Bt.has(e))return;Bt.add(e)}for(var o=0;o<a;o++){var s=r[o],c=s.f;if(i||s!==V){var l=(c&h)===0;if(l&&A(s,t),c&131072)Ft.add(s);else if(c&2){var u=s;yt?.delete(u),Gt(u,g,n)}else if(l){var d=s;c&16&&At!==null&&At.add(d),n===null?Mt(d):n.push(d)}}}}}function Kt(t){if(typeof t!=`object`||!t||re in t||ie in t)return t;let n=l(t);if(n!==s&&n!==c)return t;var r=new Map,i=e(t),o=N(0),u=null,d=Jn,f=e=>{if(Jn===d)return e();var t=B,n=Jn;Rn(null),Yn(d);var r=e();return Rn(t),Yn(n),r};return i&&r.set(`length`,N(t.length,u)),new Proxy(t,{defineProperty(e,t,n){(!(`value`in n)||n.configurable===!1||n.enumerable===!1||n.writable===!1)&&Ie();var i=r.get(t);return i===void 0?f(()=>{var e=N(n.value,u);return r.set(t,e),e}):P(i,n.value,!0),!0},deleteProperty(e,t){var n=r.get(t);if(n===void 0){if(t in e){let e=f(()=>N(T,u));r.set(t,e),Wt(o)}}else P(n,T),Wt(o);return!0},get(e,n,i){if(n===re)return t;var o=r.get(n),s=n in e;if(o===void 0&&(!s||a(e,n)?.writable)&&(o=f(()=>N(Kt(s?e[n]:T),u)),r.set(n,o)),o!==void 0){var c=H(o);return c===T?void 0:c}return Reflect.get(e,n,i)},getOwnPropertyDescriptor(e,t){this.has?.(e,t);var n=Reflect.getOwnPropertyDescriptor(e,t),i=r.get(t);if(i!==void 0){var a=H(i);if(a===T)return;if(n&&`value`in n)n.value=a;else return{enumerable:!0,configurable:!0,value:a,writable:!0}}return n},has(e,t){if(t===re)return!0;var n=r.get(t),i=n!==void 0&&n.v!==T||Reflect.has(e,t);return(n!==void 0||V!==null&&(!i||a(e,t)?.writable))&&(n===void 0&&(n=f(()=>N(i?Kt(e[t]):T,u)),r.set(t,n)),H(n)===T)?!1:i},set(e,t,n,s){var c=r.get(t),l=t in e;if(i&&t===`length`)for(var d=n;d<c.v;d+=1){var p=r.get(d+``);p===void 0?d in e&&(p=f(()=>N(T,u)),r.set(d+``,p)):P(p,T)}if(c===void 0)(!l||a(e,t)?.writable)&&(c=f(()=>N(void 0,u)),P(c,Kt(n)),r.set(t,c));else{l=c.v!==T;var m=f(()=>Kt(n));P(c,m)}var h=Reflect.getOwnPropertyDescriptor(e,t);if(h?.set&&h.set.call(s,n),!l){if(i&&typeof t==`string`){var g=r.get(`length`),_=Number(t);Number.isInteger(_)&&_>=g.v&&P(g,_+1)}Wt(o)}return!0},ownKeys(e){H(o);var t=Reflect.ownKeys(e).filter(e=>{var t=r.get(e);return t===void 0||t.v!==T});for(var[n,i]of r)i.v!==T&&!(n in e)&&t.push(n);return t},setPrototypeOf(){Le()}})}function qt(e){try{if(typeof e==`object`&&e&&re in e)return e[re]}catch{}return e}function Jt(e,t){return Object.is(qt(e),qt(t))}var Yt,Xt,Zt,Qt;function $t(){if(Yt===void 0){Yt=window,Xt=/Firefox/.test(navigator.userAgent);var e=Element.prototype,t=Node.prototype,n=Text.prototype;Zt=a(t,`firstChild`).get,Qt=a(t,`nextSibling`).get,u(e)&&(e[se]=void 0,e[oe]=null,e[ce]=void 0,e.__e=void 0),u(n)&&(n[le]=void 0)}}function en(e=``){return document.createTextNode(e)}function tn(e){return Zt.call(e)}function nn(e){return Qt.call(e)}function F(e,t){if(!E)return tn(e);var n=tn(D);if(n===null)n=D.appendChild(en());else if(t&&n.nodeType!==3){var r=en();return n?.before(r),O(r),r}return t&&sn(n),O(n),n}function I(e,t=!1){if(!E){var n=tn(e);return n instanceof Comment&&n.data===``?nn(n):n}if(t){if(D?.nodeType!==3){var r=en();return D?.before(r),O(r),r}sn(D)}return D}function L(e,t=!1){if(!E)return tn(e);var n=F(e,t);return k(e),n}function R(e,t=1,n=!1){let r=E?D:e;for(var i;t--;)i=r,r=nn(r);if(!E)return r;if(n){if(r?.nodeType!==3){var a=en();return r===null?i?.after(a):r.before(a),O(a),a}sn(r)}return O(r),r}function rn(e){e.textContent=``}function an(){return!1}function on(e,t,n){return t==null||t===`http://www.w3.org/1999/xhtml`?n?document.createElement(e,{is:n}):document.createElement(e):n?document.createElementNS(t,e,{is:n}):document.createElementNS(t,e)}function sn(e){if(e.nodeValue.length<65536)return;let t=e.nextSibling;for(;t!==null&&t.nodeType===3;)t.remove(),e.nodeValue+=t.nodeValue,t=e.nextSibling}function cn(e){var t=V;if(t===null)return B.f|=w,e;if(!(t.f&32768)&&!(t.f&4))throw e;ln(e,t)}function ln(e,t){if(e===pe)throw e;if(!(t!==null&&t.f&16384)){for(;t!==null;){if(t.f&128&&!(t.f&33570816)){if(!(t.f&32768))throw e;try{t.b.error(e);return}catch(t){e=t}}t=t.parent}throw e}}function un(e){V===null&&(B===null&&Pe(e),Ne()),Fn&&Me(e)}function dn(e,t){var n=t.last;n===null?t.last=t.first=e:(n.next=e,e.prev=n,t.last=e)}function fn(e,t){var n=V;n!==null&&n.f&8192&&(e|=_);var r={ctx:Be,deps:null,nodes:null,f:e|h|512,first:null,fn:t,last:null,next:null,parent:n,b:n&&n.b,prev:null,teardown:null,wv:0,ac:null};M?.register_created_effect(r);var i=r;if(e&4)Ct===null?Dt.ensure().schedule(r):Ct.push(r);else if(t!==null){try{rr(r)}catch(e){throw En(r),e}i.deps===null&&i.teardown===null&&i.nodes===null&&i.first===i.last&&!(i.f&524288)&&(i=i.first,e&16&&e&65536&&i!==null&&(i.f|=x))}if(i!==null&&(i.parent=n,n!==null&&dn(i,n),B!==null&&B.f&2&&!(e&64))){var a=B;(a.effects??=[]).push(i)}return r}function pn(){return B!==null&&!Ln}function mn(e){let t=fn(8,null);return A(t,m),t.teardown=e,t}function hn(e){un(`$effect`);var t=V.f;if(!B&&t&32&&Be!==null&&!Be.i){var n=Be;(n.e??=[]).push(e)}else return gn(e)}function gn(e){return fn(4|ee,e)}function _n(e){Dt.ensure();let t=fn(64|S,e);return(e={})=>new Promise(n=>{e.outro?kn(t,()=>{En(t),n(void 0)}):(En(t),n(void 0))})}function vn(e){return fn(4,e)}function yn(e){return fn(ne|S,e)}function bn(e,t=0){return fn(8|t,e)}function z(e,t=[],n=[],r=[]){it(r,t,n,t=>{fn(8,()=>{e(...t.map(H))})})}function xn(e,t=0){return fn(16|t,e)}function Sn(e){return fn(32|S,e)}function Cn(e){var t=e.teardown;if(t!==null){let n=Fn,r=B;In(!0),Rn(null);try{t.call(null)}catch(t){ln(t,e.parent)}finally{In(n),Rn(r)}}}function wn(e,t=!1){var n=e.first;for(e.first=e.last=null;n!==null;){let e=n.ac;e!==null&&nt(()=>{e.abort(de)});var r=n.next;n.f&64?n.parent=null:En(n,t),n=r}}function Tn(e){for(var t=e.first;t!==null;){var n=t.next;t.f&32||En(t),t=n}}function En(e,t=!0){var n=!1;(t||e.f&262144)&&e.nodes!==null&&e.nodes.end!==null&&(Dn(e.nodes.start,e.nodes.end),n=!0),e.f|=b,wn(e,t&&!n),nr(e,0);var r=e.nodes&&e.nodes.t;if(r!==null)for(let e of r)e.stop();Cn(e),e.f^=b,e.f|=v;var i=e.parent;i!==null&&i.first!==null&&On(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=e.b=null}function Dn(e,t){for(;e!==null;){var n=e===t?null:nn(e);e.remove(),e=n}}function On(e){var t=e.parent,n=e.prev,r=e.next;n!==null&&(n.next=r),r!==null&&(r.prev=n),t!==null&&(t.first===e&&(t.first=r),t.last===e&&(t.last=n))}function kn(e,t,n=!0){var r=[];e.f|=256,An(e,r,!0);var i=()=>{n&&En(e),t&&t()},a=r.length;if(a>0){var o=()=>--a||i();for(var s of r)s.out(o)}else i()}function An(e,t,n){if(!(e.f&8192)){e.f^=_;var r=e.nodes&&e.nodes.t;if(r!==null)for(let e of r)(e.is_global||n)&&t.push(e);for(var i=e.first;i!==null;){var a=i.next;if(!(i.f&64)){var o=!!(i.f&65536)||!!(i.f&32)&&!!(e.f&16);An(i,t,o?n:!1)}i=a}}}function jn(e){e.f&=-257,Mn(e,!0)}function Mn(e,t){if(!(e.f&256)&&e.f&8192){e.f^=_,e.f&1024||(A(e,h),Dt.ensure().schedule(e));for(var n=e.first;n!==null;){var r=n.next,i=!!(n.f&65536)||!!(n.f&32);Mn(n,i?t:!1),n=r}var a=e.nodes&&e.nodes.t;if(a!==null)for(let e of a)(e.is_global||t)&&e.in()}}function Nn(e,t){if(e.nodes)for(var n=e.nodes.start,r=e.nodes.end;n!==null;){var i=n===r?null:nn(n);t.append(n),n=i}}var Pn=null,Fn=!1;function In(e){Fn=e}var B=null,Ln=!1;function Rn(e){B=e}var V=null;function zn(e){V=e}var Bn=null;function Vn(e){B!==null&&(B.f&2097152||B.f&2)&&(Bn??=new Set).add(e)}var Hn=null,Un=0,Wn=null;function Gn(e){Wn=e}var Kn=1,qn=0,Jn=qn;function Yn(e){Jn=e}function Xn(){return++Kn}function Zn(e){var t=e.f;if(t&2048)return!0;if(t&4096){for(var n=e.deps,r=n.length,i=0;i<r;i++){var a=n[i];if(Zn(a)&&mt(a),a.wv>e.wv)return!0}t&512&&yt===null&&A(e,m)}return!1}function Qn(e,t,n=!0){var r=e.reactions;if(r!==null&&!(Bn!==null&&Bn.has(e)))for(var i=0;i<r.length;i++){var a=r[i];a.f&2?Qn(a,t,!1):t===a&&(n?A(a,h):a.f&1024&&A(a,g),Mt(a))}}function $n(e){var t=Hn,n=Un,r=Wn,i=B,a=Bn,o=Be,s=Ln,c=Jn,l=e.f;Hn=null,Un=0,Wn=null,B=l&96?null:e,Bn=null,Ve(e.ctx),Ln=!1,Jn=++qn,e.ac!==null&&(nt(()=>{e.ac.abort(de)}),e.ac=null);try{e.f|=C;var u=e.fn,d=u();e.f|=y;var f=er(e);if(Ge()&&Wn!==null&&!Ln&&f!==null&&!(e.f&6146))for(var p=0;p<Wn.length;p++)Qn(Wn[p],e);if(i!==null&&i!==e){if(qn++,i.deps!==null)for(let e=0;e<n;e+=1)i.deps[e].rv=qn;if(t!==null)for(let e of t)e.rv=qn;Wn!==null&&(r===null?r=Wn:r.push(...Wn))}return e.f&8388608&&(e.f^=w),d}catch(t){return er(e),cn(t)}finally{e.f^=C,Hn=t,Un=n,Wn=r,B=i,Bn=a,Ve(o),Ln=s,Jn=c}}function er(e){var t=e.deps,n=M?.is_fork;if(Hn!==null){var r;if(n||nr(e,Un),t!==null&&Un>0)for(t.length=Un+Hn.length,r=0;r<Hn.length;r++)t[Un+r]=Hn[r];else e.deps=t=Hn;if(pn()&&e.f&512)for(r=Un;r<t.length;r++)(t[r].reactions??=[]).push(e)}else!n&&t!==null&&Un<t.length&&(nr(e,Un),t.length=Un);return t}function tr(e,r){let i=r.reactions;if(i!==null){var a=t.call(i,e);if(a!==-1){var o=i.length-1;o===0?i=r.reactions=null:(i[a]=i[o],i.pop())}}if(i===null&&r.f&2&&(Hn===null||!n.call(Hn,r))){var s=r;s.f&512&&(s.f^=512),s.v!==T&&Ze(s),s.ac!==null&&nt(()=>{s.ac.abort(de),s.ac=null,A(s,h)}),ht(s),nr(s,0)}}function nr(e,t){var n=e.deps;if(n!==null)for(var r=t;r<n.length;r++)tr(e,n[r])}function rr(e){var t=e.f;if(!(t&16384)){A(e,m);var n=V;V=e;try{t&16777232?Tn(e):wn(e),Cn(e);var r=$n(e);e.teardown=typeof r==`function`?r:null,e.wv=Kn}finally{V=n}}}async function ir(){await Promise.resolve(),Ot()}function H(e){var t=!!(e.f&2);if(Pn?.add(e),B!==null&&!Ln&&!(V!==null&&V.f&16384)&&(Bn===null||!Bn.has(e))){var r=B.deps;if(B.f&2097152)e.rv<qn&&(e.rv=qn,Hn===null&&r!==null&&r[Un]===e?Un++:Hn===null?Hn=[e]:Hn.push(e));else{B.deps??=[],n.call(B.deps,e)||B.deps.push(e);var i=e.reactions;i===null?e.reactions=[B]:n.call(i,B)||i.push(B)}}if(Fn&&It.has(e))return It.get(e);if(t){var a=e;if(Fn){var o=a.v;return(!(a.f&1024)&&a.reactions!==null||or(a))&&(o=pt(a)),It.set(a,o),o}var s=!(a.f&512)&&!Ln&&B!==null&&!!(B.f&512),c=(a.f&y)===0;Zn(a)&&(s&&(a.f|=512),mt(a)),s&&!c&&(gt(a),ar(a))}if(yt?.has(e))return yt.get(e);if(e.f&8388608)throw e.v;return e.v}function ar(e){if(e.f|=512,e.deps!==null)for(let r of e.deps){var t=r.reactions;t===null?r.reactions=[e]:n.call(t,e)||t.push(e),r.f&2&&!(r.f&512)&&(gt(r),ar(r))}}function or(e){if(e.v===T)return!0;if(e.deps===null)return!1;for(let t of e.deps)if(It.has(t)||t.f&2&&or(t))return!0;return!1}function sr(e){var t=Ln;try{return Ln=!0,e()}finally{Ln=t}}function cr(e){if(!(typeof e!=`object`||!e||e instanceof EventTarget)){if(re in e)lr(e);else if(!Array.isArray(e))for(let t in e){let n=e[t];typeof n==`object`&&n&&re in n&&lr(n)}}}function lr(e,t=new Set){if(typeof e==`object`&&e&&!(e instanceof EventTarget)&&!t.has(e)){t.add(e),e instanceof Date&&e.getTime();for(let n in e)try{lr(e[n],t)}catch{}let n=l(e);if(n!==Object.prototype&&n!==Array.prototype&&n!==Map.prototype&&n!==Set.prototype&&n!==Date.prototype){let t=o(n);for(let n in t){let r=t[n].get;if(r)try{r.call(e)}catch{}}}}}[...`allowfullscreen.async.autofocus.autoplay.checked.controls.default.disabled.formnovalidate.indeterminate.inert.ismap.loop.multiple.muted.nomodule.novalidate.open.playsinline.readonly.required.reversed.seamless.selected.webkitdirectory.defer.disablepictureinpicture.disableremoteplayback`.split(`.`)];var ur=[`touchstart`,`touchmove`];function dr(e){return ur.includes(e)}var fr=Symbol(`events`),pr=new Set,mr=new Set;function hr(e,t,n,r={}){function i(e){if(r.capture||br.call(t,e),!e.cancelBubble)return nt(()=>n?.call(this,e))}return e.startsWith(`pointer`)||e.startsWith(`touch`)||e===`wheel`?(i.__removed=!1,Je(()=>{i.__removed||t.addEventListener(e,i,r)})):t.addEventListener(e,i,r),i}function gr(e,t,n,r,i){var a={capture:r,passive:i},o=hr(e,t,n,a);(t===document.body||t===window||t===document||t instanceof HTMLMediaElement)&&mn(()=>{o.__removed=!0,t.removeEventListener(e,o,a)})}function U(e,t,n){(t[fr]??={})[e]=n}function _r(e){for(var t=0;t<e.length;t++)pr.add(e[t]);for(var n of mr)n(e)}var vr=null,yr=!1;function br(e){var t=this,n=t.ownerDocument,r=e.type,a=e.composedPath?.()||[],o=a[0]||e.target;vr=e,yr||(yr=!0,setTimeout(()=>{yr=!1,vr=null}));var s=0,c=vr===e&&e[fr];if(c){var l=a.indexOf(c);if(l!==-1&&(t===document||t===window)){e[fr]=t;return}var u=a.indexOf(t);if(u===-1)return;l<=u&&(s=l)}if(o=a[s]||e.target,o!==t){i(e,`currentTarget`,{configurable:!0,get(){return o||n}});var d=B,f=V;Rn(null),zn(null);try{for(var p,m=[];o!==null&&o!==t;){try{var h=o[fr]?.[r];h!=null&&(!o.disabled||e.target===o)&&h.call(o,e)}catch(e){p?m.push(e):p=e}if(e.cancelBubble)break;s++,o=s<a.length?a[s]:null}if(p){for(let e of m)queueMicrotask(()=>{throw e});throw p}}finally{e[fr]=t,delete e.currentTarget,Rn(d),zn(f)}}}var xr=globalThis?.window?.trustedTypes&&globalThis.window.trustedTypes.createPolicy(`svelte-trusted-html`,{createHTML:e=>e});function Sr(e){return xr?.createHTML(e)??e}function Cr(e){var t=on(`template`);return t.innerHTML=Sr(e.replaceAll(`<!>`,`<!---->`)),t.content}function wr(e,t){var n=V;n.nodes===null&&(n.nodes={start:e,end:t,a:null,t:null})}function W(e,t){var n=!!(t&1),r=!!(t&2),i,a=!e.startsWith(`<!>`);return()=>{if(E)return wr(D,null),D;i===void 0&&(i=Cr(a?e:`<!>`+e),n||(i=tn(i)));var t=r||Xt?document.importNode(i,!0):i.cloneNode(!0);if(n){var o=tn(t),s=t.lastChild;wr(o,s)}else wr(t,t);return t}}function Tr(e,t,n=`svg`){var r=!e.startsWith(`<!>`),i=!!(t&1),a=`<${n}>${r?e:`<!>`+e}</${n}>`,o;return()=>{if(E)return wr(D,null),D;if(!o){var e=tn(Cr(a));if(i)for(o=document.createDocumentFragment();tn(e);)o.appendChild(tn(e));else o=tn(e)}var t=o.cloneNode(!0);if(i){var n=tn(t),r=t.lastChild;wr(n,r)}else wr(t,t);return t}}function Er(e,t){return Tr(e,t,`svg`)}function Dr(e=``){if(!E){var t=en(e+``);return wr(t,t),t}var n=D;return n.nodeType===3?sn(n):(n.before(n=en()),O(n)),wr(n,n),n}function Or(){if(E)return wr(D,null),D;var e=document.createDocumentFragment(),t=document.createComment(``),n=en();return e.append(t,n),wr(t,n),e}function G(e,t){if(E){var n=V;(!(n.f&32768)||n.nodes.end===null)&&(n.nodes.end=D),Se();return}e!==null&&e.before(t)}function kr(e){let t=0,n=Rt(0),r;return()=>{pn()&&(H(n),bn(()=>(t===0&&(r=sr(()=>e(()=>Wt(n)))),t+=1,()=>{Je(()=>{--t,t===0&&(r?.(),r=void 0,Wt(n))})})))}}var Ar=x|S;function jr(e,t,n,r){new Mr(e,t,n,r)}var Mr=class{parent;is_pending=!1;transform_error;#e;#t=E?D:null;#n;#r;#i;#a=null;#o=null;#s=null;#c=null;#l=0;#u=0;#d=!1;#f=new Set;#p=new Set;#m=null;#h=kr(()=>(this.#m=Rt(this.#l),()=>{this.#m=null}));constructor(e,t,n,r){this.#e=e,this.#n=t,this.#r=e=>{var t=V;t.b=this,t.f|=128,n(e)},this.parent=V.b,this.transform_error=r??this.parent?.transform_error??(e=>e),this.#i=xn(()=>{if(E){let e=Te(this.#t);Se();let t=e===`[!`;if(e.startsWith(`[?`)){let t=JSON.parse(e.slice(2));this.#_(t)}else t?this.#b():this.#g()}else this.#x()},Ar),E&&(this.#e=D)}#g(){try{this.#a=Sn(()=>this.#r(this.#e))}catch(e){this.error(e)}}#_(e){let t=this.#n.failed,{reset:n,invoke_onerror:r}=this.#v(e);Je(r),t&&(this.#s=Sn(()=>{t(this.#e,()=>e,()=>n)}))}#v(e){var t=!1,n=!1;let r=()=>{if(!this.#y()){if(t){be();return}t=!0,n&&ze(),this.#s!==null&&kn(this.#s,()=>{this.#s=null}),this.#C(()=>{this.#x()})}};return{reset:r,invoke_onerror:()=>{if(!this.#y())try{n=!0,this.#n.onerror?.(e,r),n=!1}catch(e){ln(e,this.#i&&this.#i.parent)}}}}#y(){return(this.#i.f&(v|b))!==0}#b(){let e=this.#n.pending;e&&(this.is_pending=!0,this.#o=Sn(()=>e(this.#e)),Je(()=>{if(!this.#y()){var e=this.#c=document.createDocumentFragment(),t=en(),n=!1;if(e.append(t),this.#a=this.#C(()=>{try{return Sn(()=>this.#r(t))}catch(e){try{this.error(e),n=!0}catch(e){ln(e,this.#i.parent)}return null}}),this.#a===null){this.#c=null,n&&this.#S(M);return}this.#u===0&&(this.#e.before(e),this.#c=null,kn(this.#o,()=>{this.#o=null}),this.#S(M))}}))}#x(){try{if(this.is_pending=this.has_pending_snippet(),this.#u=0,this.#l=0,this.#a=Sn(()=>{this.#r(this.#e)}),this.#u>0){var e=this.#c=document.createDocumentFragment();Nn(this.#a,e);let t=this.#n.pending;this.#o=Sn(()=>t(this.#e))}else this.#S(M)}catch(e){this.error(e)}}#S(e){this.is_pending=!1,e.transfer_effects(this.#f,this.#p)}defer_effect(e){Qe(e,this.#f,this.#p)}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!this.#n.pending}#C(e){var t=V,n=B,r=Be;zn(this.#i),Rn(this.#i),Ve(this.#i.ctx);try{return Dt.ensure(),e()}finally{zn(t),Rn(n),Ve(r)}}#w(e,t){if(!this.has_pending_snippet()){this.parent&&this.parent.#w(e,t);return}this.#u+=e,this.#u===0&&(this.#S(t),this.#o&&kn(this.#o,()=>{this.#o=null}),this.#c&&=(this.#e.before(this.#c),null))}update_pending_count(e,t){this.#w(e,t),this.#l+=e,!(!this.#m||this.#d)&&(this.#d=!0,Je(()=>{this.#d=!1,this.#m&&Ht(this.#m,this.#l)}))}get_effect_pending(){return this.#h(),H(this.#m)}error(e){if(e===pe||!this.#n.onerror&&!this.#n.failed)throw e;M?.is_fork?(this.#a&&M.skip_effect(this.#a),this.#o&&M.skip_effect(this.#o),this.#s&&M.skip_effect(this.#s),M.oncommit(()=>{this.#y()||this.#T(e)})):this.#T(e)}#T(e){this.#a&&=(En(this.#a),null),this.#o&&=(En(this.#o),null),this.#s&&=(En(this.#s),null),E&&(O(this.#t),Ce(),O(we()));let t=this.#n.failed,n=e=>{if(this.#y())return;let{reset:n,invoke_onerror:r}=this.#v(e);r(),t&&!this.#y()&&(this.#s=this.#C(()=>{try{return Sn(()=>{var r=V;r.b=this,r.f|=128,t(this.#e,()=>e,()=>n)})}catch(e){return ln(e,this.#i.parent),null}}))};Je(()=>{if(!this.#y()){var t;try{t=this.transform_error(e)}catch(e){ln(e,this.#i&&this.#i.parent);return}typeof t==`object`&&t&&typeof t.then==`function`?t.then(n,e=>ln(e,this.#i&&this.#i.parent)):n(t)}})}};function K(e,t){var n=t==null?``:typeof t==`object`?`${t}`:t;n!==(e[le]??=e.nodeValue)&&(e[le]=n,e.nodeValue=`${n}`)}function Nr(e,t){return Fr(e,t)}var Pr=new Map;function Fr(e,{target:t,anchor:n,props:i={},events:a,context:o,intro:s=!0,transformError:c}){$t();var l=void 0,u=_n(()=>{var s=n??t.appendChild(en());jr(s,{pending:()=>{}},t=>{He({});var n=Be;if(o&&(n.c=o),a&&(i.$$events=a),E&&wr(t,null),l=e(t,i)||We(),E&&(V.nodes.end=D,D===null||D.nodeType!==8||D.data!==`]`))throw ve(),pe;Ue()},c);var u=new Set,d=e=>{for(var n=0;n<e.length;n++){var r=e[n];if(!u.has(r)){u.add(r);var i=dr(r);for(let e of[t,document]){var a=Pr.get(e);a===void 0&&(a=new Map,Pr.set(e,a));var o=a.get(r);o===void 0?(e.addEventListener(r,br,{passive:i}),a.set(r,1)):a.set(r,o+1)}}}};return d(r(pr)),mr.add(d),()=>{for(var e of u)for(let n of[t,document]){var r=Pr.get(n),i=r.get(e);--i==0?(n.removeEventListener(e,br),r.delete(e),r.size===0&&Pr.delete(n)):r.set(e,i)}mr.delete(d),s!==n&&s.parentNode?.removeChild(s)}});return Ir.set(l,u),l}var Ir=new WeakMap,Lr=class{anchor;#e=new Map;#t=new Map;#n=new Map;#r=new Set;#i=!0;constructor(e,t=!0){this.anchor=e,this.#i=t}#a=e=>{if(this.#e.has(e)){var t=this.#e.get(e),n=this.#t.get(t);if(n)jn(n),this.#r.delete(t);else{var r=this.#n.get(t);r&&(jn(r.effect),this.#t.set(t,r.effect),this.#n.delete(t),r.fragment.lastChild.remove(),this.anchor.before(r.fragment),n=r.effect)}for(let[t,n]of this.#e){if(this.#e.delete(t),t===e)break;let r=this.#n.get(n);r&&(En(r.effect),this.#n.delete(n))}for(let[e,r]of this.#t){if(e===t||this.#r.has(e))continue;let i=()=>{if(Array.from(this.#e.values()).includes(e)){var t=document.createDocumentFragment();Nn(r,t),t.append(en()),this.#n.set(e,{effect:r,fragment:t})}else En(r);this.#r.delete(e),this.#t.delete(e)};this.#i||!n?(this.#r.add(e),kn(r,i,!1)):i()}}};#o=e=>{this.#e.delete(e);let t=Array.from(this.#e.values());for(let[e,n]of this.#n)t.includes(e)||(En(n.effect),this.#n.delete(e))};ensure(e,t){var n=M,r=an();if(t&&!this.#t.has(e)&&!this.#n.has(e)){if(r){var i=document.createDocumentFragment(),a=en();i.append(a),this.#n.set(e,{effect:Sn(()=>t(a)),fragment:i})}else this.#t.set(e,Sn(()=>t(this.anchor)))}if(this.#e.set(n,e),r){for(let[t,r]of this.#t)t===e?n.unskip_effect(r):n.skip_effect(r);for(let[t,r]of this.#n)t===e?n.unskip_effect(r.effect):n.skip_effect(r.effect);n.oncommit(this.#a),n.ondiscard(this.#o)}else E&&(this.anchor=D),this.#a(n)}};function q(e,t,n=!1){var r;E&&(r=D,Se());var i=new Lr(e),a=n?x:0;function o(e,t){if(E){var n=Te(r);if(e!==parseInt(n.substring(1))){var a=we();O(a),i.anchor=a,xe(!1),i.ensure(e,t),xe(!0);return}}i.ensure(e,t)}xn(()=>{var e=!1;t((t,n=0)=>{e=!0,o(n,t)}),e||o(-1,null)},a)}function Rr(e,t){return t}function zr(e,t,n){for(var i=[],a=t.length,o,s=t.length,c=0;c<a;c++){let n=t[c];kn(n,()=>{if(o){if(o.pending.delete(n),o.done.add(n),o.pending.size===0){var t=e.outrogroups;Br(e,r(o.done)),t.delete(o),t.size===0&&(e.outrogroups=null)}}else--s},!1)}if(s===0){var l=i.length===0&&n!==null&&e.pending.size===0;if(l){var u=n,d=u.parentNode;rn(d),d.append(u),e.items.clear()}Br(e,t,!l)}else o={pending:new Set(t),done:new Set},(e.outrogroups??=new Set).add(o)}function Br(e,t,n=!0){var r;if(e.pending.size>0){r=new Set;for(let t of e.pending.values())for(let n of t)r.add(e.items.get(n).e)}for(var i=0;i<t.length;i++){var a=t[i];r?.has(a)?(a.f|=te,Nn(a,document.createDocumentFragment())):En(t[i],n)}}var Vr;function J(t,n,i,a,o,s=null){var c=t,l=new Map;if(n&4){var u=t;c=E?O(tn(u)):u.appendChild(en())}E&&Se();var d=null,f=dt(()=>{var t=i();return e(t)?t:t==null?[]:r(t)}),p=new Map,m=!0;function h(e){if(!(_.effect.f&16384)){_.pending.delete(e);var t=H(f);_.fallback=d,Ur(_,t,c,n,a),d!==null&&(t.length===0?d.f&33554432?(d.f^=te,Gr(d,null,c)):jn(d):kn(d,()=>{d=null}))}}function g(e){_.pending.delete(e)}var _={effect:xn(()=>{var e=H(f),t=e.length;let r=!1;E&&Te(c)===`[!`!=(t===0)&&(c=we(),O(c),xe(!1),r=!0);for(var u=new Set,_=M,v=an(),y=0;y<t;y+=1){E&&D.nodeType===8&&D.data===`]`&&(c=D,r=!0,xe(!1));var b=e[y],x=a(b,y),S=m?null:l.get(x);S?(S.v&&Ht(S.v,b),S.i&&Ht(S.i,y),v&&_.unskip_effect(S.e)):(S=Wr(l,m?c:Vr??=en(),b,x,y,o,n,i),m||(S.e.f|=te),l.set(x,S)),u.add(x)}if(t===0&&s&&!d&&(m?d=Sn(()=>s(c)):(d=Sn(()=>s(Vr??=en())),d.f|=te)),t>u.size&&je(``,``,``),E&&t>0&&O(we()),!m){if(p.set(_,u),v){for(let[e,t]of l)u.has(e)||_.skip_effect(t.e);_.oncommit(h),_.ondiscard(g)}else h(_)}r&&xe(!0),H(f)}),flags:n,items:l,pending:p,outrogroups:null,fallback:d};m=!1,E&&(c=D)}function Hr(e){for(;e!==null&&!(e.f&32);)e=e.next;return e}function Ur(e,t,n,i,a){var o=!!(i&8),s=t.length,c=e.items,l=Hr(e.effect.first),u,d=null,f,p=[],m=[],h,g,_,v;if(o)for(v=0;v<s;v+=1)h=t[v],g=a(h,v),_=c.get(g).e,_.f&33554432||(_.nodes?.a?.measure(),(f??=new Set).add(_));for(v=0;v<s;v+=1){if(h=t[v],g=a(h,v),_=c.get(g).e,e.outrogroups!==null)for(let t of e.outrogroups)t.pending.delete(_),t.done.delete(_);if(_.f&8192&&(jn(_),o&&(_.nodes?.a?.unfix(),(f??=new Set).delete(_))),_.f&33554432){if(_.f^=te,_===l)Gr(_,null,n);else{var y=d?d.next:l;_===e.effect.last&&(e.effect.last=_.prev),_.prev&&(_.prev.next=_.next),_.next&&(_.next.prev=_.prev),Kr(e,d,_),Kr(e,_,y),Gr(_,y,n),d=_,p=[],m=[],l=Hr(d.next);continue}}if(_!==l){if(u!==void 0&&u.has(_)){if(p.length<m.length){var b=m[0],x;d=b.prev;var S=p[0],ee=p[p.length-1];for(x=0;x<p.length;x+=1)Gr(p[x],b,n);for(x=0;x<m.length;x+=1)u.delete(m[x]);Kr(e,S.prev,ee.next),Kr(e,d,S),Kr(e,ee,b),l=b,d=ee,--v,p=[],m=[]}else u.delete(_),Gr(_,l,n),Kr(e,_.prev,_.next),Kr(e,_,d===null?e.effect.first:d.next),Kr(e,d,_),d=_;continue}for(p=[],m=[];l!==null&&l!==_;)(u??=new Set).add(l),m.push(l),l=Hr(l.next);if(l===null)continue}_.f&33554432||p.push(_),d=_,l=Hr(_.next)}if(e.outrogroups!==null){for(let t of e.outrogroups)t.pending.size===0&&(Br(e,r(t.done)),e.outrogroups?.delete(t));e.outrogroups.size===0&&(e.outrogroups=null)}if(l!==null||u!==void 0){var C=[];if(u!==void 0)for(_ of u)_.f&8192||C.push(_);for(;l!==null;)!(l.f&8192)&&l!==e.fallback&&C.push(l),l=Hr(l.next);var ne=C.length;if(ne>0){var w=i&4&&s===0?n:null;if(o){for(v=0;v<ne;v+=1)C[v].nodes?.a?.measure();for(v=0;v<ne;v+=1)C[v].nodes?.a?.fix()}zr(e,C,w)}}o&&Je(()=>{if(f!==void 0)for(_ of f)_.nodes?.a?.apply()})}function Wr(e,t,n,r,i,a,o,s){var c=o&1?o&16?Rt(n):zt(n,!1,!1):null,l=o&2?Rt(i):null;return{v:c,i:l,e:Sn(()=>(a(t,c??n,l??i,s),()=>{e.delete(r)}))}}function Gr(e,t,n){if(e.nodes)for(var r=e.nodes.start,i=e.nodes.end,a=t&&!(t.f&33554432)?t.nodes.start:n;r!==null;){var o=nn(r);if(a.before(r),r===i)return;r=o}}function Kr(e,t,n){t===null?e.effect.first=n:t.next=n,n===null?e.effect.last=t:n.prev=t}function qr(e,t,n=!1,r=!1,i=!1,a=!1){var o=e,s=``;if(n){var c=e;E&&(o=O(tn(c)))}z(()=>{var e=V;if(s===(s=t()??``)){E&&Se();return}if(n&&!E){e.nodes=null,c.innerHTML=s,s!==``&&wr(tn(c),c.lastChild);return}if(e.nodes!==null&&(Dn(e.nodes.start,e.nodes.end),e.nodes=null),s!==``){if(E){for(var a=D.data,l=Se(),u=l;l!==null&&(l.nodeType!==8||l.data!==``);)u=l,l=nn(l);if(l===null)throw ve(),pe;wr(D,u),o=O(l);return}var d=on(r?`svg`:i?`math`:`template`,r?he:i?ge:void 0);d.innerHTML=s;var f=r||i?d:d.content;if(wr(tn(f),f.lastChild),r||i)for(;tn(f);)o.before(tn(f));else o.before(f)}})}function Jr(e,t,n){vn(()=>{var r=sr(()=>t(e,n?.())||{});if(n&&r?.update){var i=!1,a={};bn(()=>{var e=n();cr(e),i&&De(a,e)&&(a=e,r.update(e))}),i=!0}if(r?.destroy)return()=>r.destroy()})}var Yr=[...`
|
|
2
2
|
\r\f\xA0\v`];function Xr(e,t,n){var r=e==null?``:``+e;if(t&&(r=r?r+` `+t:t),n){for(var i of Object.keys(n))if(n[i])r=r?r+` `+i:i;else if(r.length)for(var a=i.length,o=0;(o=r.indexOf(i,o))>=0;){var s=o+a;(o===0||Yr.includes(r[o-1]))&&(s===r.length||Yr.includes(r[s]))?r=(o===0?``:r.substring(0,o))+r.substring(s+1):o=s}}return r===``?null:r}function Zr(e,t=!1){var n=t?` !important;`:`;`,r=``;for(var i of Object.keys(e)){var a=e[i];a!=null&&a!==``&&(r+=` `+i+`: `+a+n)}return r}function Qr(e){return e[0]!==`-`||e[1]!==`-`?e.toLowerCase():e}function $r(e,t){if(t){var n=``,r,i;if(Array.isArray(t)?(r=t[0],i=t[1]):r=t,e){e=String(e).replaceAll(/\/\*.*?\*\//g,``).trim();var a=!1,o=0,s=!1,c=[];r&&c.push(...Object.keys(r).map(Qr)),i&&c.push(...Object.keys(i).map(Qr));var l=0,u=-1;let t=e.length;for(var d=0;d<t;d++){var f=e[d];if(s?f===`/`&&e[d-1]===`*`&&(s=!1):a?a===f&&(a=!1):f===`/`&&e[d+1]===`*`?s=!0:f===`"`||f===`'`?a=f:f===`(`?o++:f===`)`&&o--,!s&&a===!1&&o===0){if(f===`:`&&u===-1)u=d;else if(f===`;`||d===t-1){if(u!==-1){var p=Qr(e.substring(l,u).trim());if(!c.includes(p)){f!==`;`&&d++;var m=e.substring(l,d).trim();n+=` `+m+`;`}}l=d+1,u=-1}}}}return r&&(n+=Zr(r)),i&&(n+=Zr(i,!0)),n=n.trim(),n===``?null:n}return e==null?null:String(e)}function ei(e,t,n,r,i,a){var o=e[se];if(E||o!==n||o===void 0){var s=Xr(n,r,a);(!E||s!==e.getAttribute(`class`))&&(s==null?e.removeAttribute(`class`):t?e.className=s:e.setAttribute(`class`,s)),e[se]=n}else if(a&&i!==a)for(var c in a){var l=!!a[c];(i==null||l!==!!i[c])&&e.classList.toggle(c,l)}return a}function ti(e,t={},n,r){for(var i in n){var a=n[i];t[i]!==a&&(n[i]==null?e.style.removeProperty(i):e.style.setProperty(i,a,r))}}function ni(e,t,n,r){var i=e[ce];if(E||i!==t){var a=$r(t,r);(!E||a!==e.getAttribute(`style`))&&(a==null?e.removeAttribute(`style`):e.style.cssText=a),e[ce]=t}else r&&(Array.isArray(r)?(ti(e,n?.[0],r[0]),ti(e,n?.[1],r[1],`important`)):ti(e,n,r));return r}function ri(e,t){t?e.hasAttribute(`selected`)||e.setAttribute(`selected`,``):e.removeAttribute(`selected`)}function ii(t,n){var r=t.__defaultValue,i=t.multiple,a=i?r??[]:null;if(!i||e(a)){var o=t.selectedIndex,s=n&&i?new Set(t.selectedOptions):null;for(var c of t.options){var l=ci(c);ri(c,i?a.includes(l):Jt(l,r))}if(n){if(s!==null)for(c of t.options){var u=s.has(c);c.selected!==u&&(c.selected=u)}else t.selectedIndex!==o&&(t.selectedIndex=o)}}}function ai(t,n,r=!1){if(t.multiple){if(n==null)return;if(!e(n))return ye();for(var i of t.options)i.selected=n.includes(ci(i));return}for(i of t.options)if(Jt(ci(i),n)){i.selected=!0;return}(!r||n!==void 0)&&(t.selectedIndex=-1)}function oi(e){var t=new MutationObserver(t=>{t.every(li)||(`__defaultValue`in e&&ii(e,!1),`__value`in e&&ai(e,e.__value))});t.observe(e,{childList:!0,subtree:!0,attributes:!0,attributeFilter:[`value`]}),mn(()=>{t.disconnect()})}function si(e,t,n=t){var r=new WeakSet,i=!0;rt(e,`change`,t=>{var i=t?`[selected]`:`:checked`,a;if(e.multiple)a=[].map.call(e.querySelectorAll(i),ci);else{var o=e.querySelector(i)??e.querySelector(`option:not([disabled])`);a=o&&ci(o)}n(a),e.__value=a,M!==null&&r.add(M)}),vn(()=>{var a=t();if(e===document.activeElement){var o=M;if(r.has(o))return}if(ai(e,a,i),i&&a===void 0){var s=e.querySelector(`:checked`);s!==null&&(a=ci(s),n(a))}e.__value=a,i=!1})}function ci(e){return`__value`in e?e.__value:e.value}function li(e){if(e.target.closest(`selectedcontent`)!==null)return!0;if(e.type===`childList`){var t=[...e.addedNodes,...e.removedNodes];return t.length>0&&t.every(e=>e.nodeName===`SELECTEDCONTENT`)}return!1}var ui=Symbol(`is custom element`),di=Symbol(`is html`),fi=fe?`link`:`LINK`,pi=fe?`progress`:`PROGRESS`;function Y(e){if(E){var t=!1,n=()=>{if(!t){if(t=!0,e.hasAttribute(`value`)){var n=e.value;X(e,`value`,null),e.value=n}if(e.hasAttribute(`checked`)){var r=e.checked;X(e,`checked`,null),e.checked=r}}};e[ue]=n,Je(n),tt()}}function mi(e,t){var n=hi(e);n.value!==(n.value=t??void 0)&&(e.value!==t||t===0&&e.nodeName===pi)&&(e.value=t??``)}function X(e,t,n,r){var i=hi(e);E&&(i[t]=e.getAttribute(t),t===`src`||t===`srcset`||t===`href`&&e.nodeName===fi)||i[t]!==(i[t]=n)&&(t===`loading`&&(e[ae]=n),n==null?e.removeAttribute(t):typeof n!=`string`&&_i(e).has(t)?e[t]=n:e.setAttribute(t,n))}function hi(e){return e[oe]??={[ui]:e.nodeName.includes(`-`),[di]:e.namespaceURI===me}}var gi=new Map;function _i(e){var t=e.getAttribute(`is`)||e.nodeName,n=gi.get(t);if(n)return n;gi.set(t,n=new Set);for(var r,i=e,a=Element.prototype;a!==i;){for(var s in r=o(i),r)r[s].set&&s!==`innerHTML`&&s!==`textContent`&&s!==`innerText`&&n.add(s);i=l(i)}return n}function Z(e,t,n=t){var r=new WeakSet;rt(e,`input`,async i=>{var a=i?e.defaultValue:e.value;if(a=yi(e)?bi(a):a,n(a),M!==null&&r.add(M),await ir(),a!==(a=t())){var o=e.selectionStart,s=e.selectionEnd,c=e.value.length;if(e.value=a??``,s!==null){var l=e.value.length;o===s&&s===c&&l>c?(e.selectionStart=l,e.selectionEnd=l):(e.selectionStart=o,e.selectionEnd=Math.min(s,l))}}}),(E&&e.defaultValue!==e.value||sr(t)==null&&e.value)&&(n(yi(e)?bi(e.value):e.value),M!==null&&r.add(M)),bn(()=>{var n=t();if(e===document.activeElement){var i=M;if(r.has(i))return}yi(e)&&n===bi(e.value)||(e.type!==`date`||n||e.value)&&n!==e.value&&(e.value=n??``)})}function vi(e,t,n=t){rt(e,`change`,t=>{n(t?e.defaultChecked:e.checked)}),(E&&e.defaultChecked!==e.checked||sr(t)==null)&&n(e.checked),bn(()=>{e.checked=!!t()})}function yi(e){var t=e.type;return t===`number`||t===`range`}function bi(e){return e===``?null:+e}function xi(e,t){return e===t||e?.[re]===t}function Si(e=We(),t,n,r){var i=Be.r,a=V;return vn(()=>{var o,s;return bn(()=>{o=s,s=r?.()||[],sr(()=>{xi(n(...s),e)||(t(e,...s),o&&xi(n(...o),e)&&t(null,...o))})}),()=>{let r=a;for(;r!==i&&r.parent!==null&&r.parent.f&33554432;)r=r.parent;let o=()=>{s&&xi(n(...s),e)&&t(null,...s)},c=r.teardown;r.teardown=()=>{o(),c?.()}}}),e}function Ci(e){Be===null&&ke(`onMount`),hn(()=>{let t=sr(e);if(typeof t==`function`)return t})}typeof window<`u`&&((window.__svelte??={}).v??=new Set).add(`5`);function wi(){return{messages:[],streaming:null,tools:{},queue:{steering:[],followUp:[]},running:!1,turn:Ti(),total:Ti()}}function Ti(){return{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:0}}function Ei(e){let t=e,n=typeof t.role==`string`?t.role:`unknown`,r=[];if(n===`toolResult`)r.push({kind:`tool-result`,id:typeof t.toolCallId==`string`?t.toolCallId:``,name:typeof t.toolName==`string`?t.toolName:``,output:ji(t.content),isError:t.isError===!0});else{let e=t.content;if(typeof e==`string`)e&&r.push({kind:`text`,text:e});else if(Array.isArray(e))for(let t of e)r.push(...Di(t))}let i={role:n,blocks:r},a=Oi(t.usage);return a&&(i.usage=a),i}function Di(e){if(!e||typeof e!=`object`)return[];let t=e;switch(t.type){case`text`:return typeof t.text==`string`&&t.text?[{kind:`text`,text:t.text}]:[];case`image`:return typeof t.data==`string`&&typeof t.mimeType==`string`?[{kind:`image`,data:t.data,mimeType:t.mimeType}]:[];case`thinking`:return typeof t.thinking==`string`&&t.thinking?[{kind:`thinking`,text:t.thinking}]:[];case`toolCall`:return[{kind:`tool-call`,id:typeof t.id==`string`?t.id:``,name:typeof t.name==`string`?t.name:``,args:t.arguments}];default:return[]}}function Oi(e){if(!e||typeof e!=`object`)return;let t=e;return{input:ki(t.input),output:ki(t.output),cacheRead:ki(t.cacheRead),cacheWrite:ki(t.cacheWrite),totalTokens:ki(t.totalTokens),cost:Ai(t.cost)}}function ki(e){return typeof e==`number`&&Number.isFinite(e)?e:0}function Ai(e){return typeof e==`number`?e:e&&typeof e==`object`?ki(e.total):0}function ji(e){if(typeof e==`string`)return e;if(Array.isArray(e))return e.map(ji).filter(Boolean).join(`
|
|
3
|
-
`);if(e&&typeof e==`object`){let t=e;return`content`in t?ji(t.content):`text`in t&&typeof t.text==`string`?t.text:JSON.stringify(e,null,2)}return``}function Mi(e,t){return{input:e.input+t.input,output:e.output+t.output,cacheRead:e.cacheRead+t.cacheRead,cacheWrite:e.cacheWrite+t.cacheWrite,totalTokens:e.totalTokens+t.totalTokens,cost:e.cost+t.cost}}function Ni(e,t,n=Date.now,r){switch(t.type){case`agent_start`:return{...e,running:!0,turn:Ti()};case`agent_settled`:return{...e,running:!1,streaming:null,queue:{steering:[],followUp:[]}};case`message_start`:return Pi(t.message)?{...e,streaming:Ei(t.message)}:e;case`message_update`:{let n=t.assistantMessageEvent;return n?.partial?{...e,streaming:Ei(n.partial)}:e}case`message_end`:{let n=Ei(t.message);if(n.role===`system`||n.role===`custom`)return e;if(n.role===`toolResult`){let t=n.blocks[0],r=e.tools[t.id];if(r)return{...e,tools:{...e.tools,[t.id]:{...r,output:t.output,state:t.isError?`error`:`done`}}}}r!==void 0&&(n.seq=r);let i=n.usage?Mi(e.turn,n.usage):e.turn,a={...e.tools};for(let e of n.blocks)e.kind===`tool-call`&&!a[e.id]&&(a[e.id]={id:e.id,name:e.name,args:e.args,output:``,state:`pending`});return{...e,messages:[...e.messages,n],streaming:null,tools:a,turn:i,total:n.usage?Mi(e.total,n.usage):e.total}}case`tool_execution_start`:{let r=t,i=e.tools[r.toolCallId];return{...e,tools:{...e.tools,[r.toolCallId]:{id:r.toolCallId,name:r.toolName,args:r.args,output:i?.output??``,state:`running`,startedAt:i?.startedAt??n()}}}}case`tool_execution_update`:{let n=t,r=e.tools[n.toolCallId];return r?{...e,tools:{...e.tools,[n.toolCallId]:{...r,output:ji(n.partialResult)}}}:e}case`tool_execution_end`:{let r=t,i=e.tools[r.toolCallId],a={id:r.toolCallId,name:r.toolName,args:i?.args,output:ji(r.result),state:r.isError?`error`:`done`,startedAt:i?.startedAt??n(),endedAt:n()};return{...e,tools:{...e.tools,[r.toolCallId]:a}}}case`queue_update`:{let n=t;return{...e,queue:{steering:[...n.steering],followUp:[...n.followUp]}}}default:return e}}function Pi(e){return e?.role===`assistant`}function Fi(e){return e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function Ii(e){return`${`${Fi(e.input)} in / ${Fi(e.output)} out`}${e.cacheRead?` / ${Fi(e.cacheRead)} cached`:``} · $${e.cost.toFixed(4)}`}function Li(e){return e.input+e.cacheRead+e.cacheWrite}function Ri(e){let t=Li(e);return t?`${Fi(e.cacheRead)} read / ${Fi(e.cacheWrite)} write · ${Math.round(e.cacheRead/t*100)}% of the prompt from cache`:`the provider reported no usage`}var zi=new Set([`text_start`,`text_delta`,`thinking_start`,`thinking_delta`,`toolcall_start`,`toolcall_delta`]),Bi={promptTokens:0,outputTokens:0,prefillMs:0,decodeMs:0};function Vi(e){return e!==null&&(e.promptTokens>0||e.outputTokens>0)}function Hi(){return{live:null,last:null,run:{...Bi}}}function Ui(e,t,n=Date.now){switch(t.type){case`agent_start`:return{...e,pendingStart:void 0,live:null,run:{...Bi}};case`turn_start`:return{...e,pendingStart:n()};case`message_start`:return Pi(t.message)?{...e,pendingStart:void 0,live:{requestStart:e.pendingStart??n(),firstTokenAt:null,promptTokens:0,outputTokens:0}}:e;case`message_update`:{if(!e.live)return e;let r=t.assistantMessageEvent,i=Oi(r?.partial?.usage);return{...e,live:{...e.live,firstTokenAt:e.live.firstTokenAt??(zi.has(r?.type??``)?n():null),promptTokens:i?Li(i):e.live.promptTokens,outputTokens:i&&i.output>0?i.output:e.live.outputTokens}}}case`message_end`:{let r=t.message;if(!Pi(r)||!e.live)return e;let i=Oi(r.usage),a=e.live.firstTokenAt,o=i?Li(i):0,s=i?.output??0,c={promptTokens:o,outputTokens:s,prefillMs:a===null?0:Ki(o,a-e.live.requestStart),decodeMs:a===null?0:Ki(s,n()-a)};return{...e,pendingStart:void 0,live:null,last:Vi(c)?c:e.last,run:a===null?e.run:Gi(e.run,c)}}case`agent_settled`:return{...e,pendingStart:void 0,live:null};default:return e}}function Wi(e,t){let n=e.live,r=n?.firstTokenAt==null?e.run:Gi(e.run,{promptTokens:n.promptTokens,outputTokens:n.outputTokens,prefillMs:Ki(n.promptTokens,n.firstTokenAt-n.requestStart),decodeMs:Ki(n.outputTokens,t-n.firstTokenAt)});if(r.promptTokens===0&&r.outputTokens===0){let t=e.last;return t?{prefill:qi(t.promptTokens,t.prefillMs),decode:qi(t.outputTokens,t.decodeMs)}:{prefill:null,decode:null}}return{prefill:qi(r.promptTokens,r.prefillMs),decode:qi(r.outputTokens,r.decodeMs)}}function Gi(e,t){return{promptTokens:e.promptTokens+t.promptTokens,outputTokens:e.outputTokens+t.outputTokens,prefillMs:e.prefillMs+t.prefillMs,decodeMs:e.decodeMs+t.decodeMs}}function Ki(e,t){return e>0?t:0}function qi(e,t){return t>0&&e>0?e*1e3/t:null}function Ji(e){return e>=100?String(Math.round(e)):e.toFixed(1)}var Yi=`flypi.lastAnswers`;function Xi(e){return e.model?`${e.model.provider}/${e.model.modelId}`:null}function Zi(e){return ta()[e]??null}function Qi(e,t){let n=ta();n[e]=t,ea(n)}function $i(e){let t=ta();e in t&&(delete t[e],ea(t))}function ea(e){try{localStorage.setItem(Yi,JSON.stringify(e))}catch{}}function ta(){let e;try{e=JSON.parse(localStorage.getItem(Yi)??``)}catch{return{}}if(!e||typeof e!=`object`)return{};let t={};for(let[n,r]of Object.entries(e)){let e=na(r);e&&(t[n]=e)}return t}function na(e){let t=e;if(!t||typeof t!=`object`)return null;let{promptTokens:n,outputTokens:r,prefillMs:i,decodeMs:a}=t;return ra(n)&&ra(r)&&ra(i)&&ra(a)?{promptTokens:n,outputTokens:r,prefillMs:i,decodeMs:a,model:typeof t.model==`string`?t.model:null}:null}function ra(e){return Number.isFinite(e)}var ia=class{#e=N(Kt(wi()));get transcript(){return H(this.#e)}set transcript(e){P(this.#e,e,!0)}#t=N(Kt(Hi()));get metrics(){return H(this.#t)}set metrics(e){P(this.#t,e,!0)}#n=N(null);get measuredOn(){return H(this.#n)}set measuredOn(e){P(this.#n,e,!0)}#r=N(void 0);get conversationId(){return H(this.#r)}set conversationId(e){P(this.#r,e,!0)}#i=N(void 0);get sessionPath(){return H(this.#i)}set sessionPath(e){P(this.#i,e,!0)}#a=N(Kt([]));get sessions(){return H(this.#a)}set sessions(e){P(this.#a,e,!0)}#o=N(void 0);get debug(){return H(this.#o)}set debug(e){P(this.#o,e,!0)}#s=N(void 0);get scheduler(){return H(this.#s)}set scheduler(e){P(this.#s,e,!0)}#c=N(void 0);get interruptedAt(){return H(this.#c)}set interruptedAt(e){P(this.#c,e,!0)}#l=N(void 0);get config(){return H(this.#l)}set config(e){P(this.#l,e,!0)}#u=N(`chat`);get view(){return H(this.#u)}set view(e){P(this.#u,e,!0)}#d=N(!1);get connected(){return H(this.#d)}set connected(e){P(this.#d,e,!0)}#f=N(void 0);get lastError(){return H(this.#f)}set lastError(e){P(this.#f,e,!0)}#p=N(void 0);get configError(){return H(this.#p)}set configError(e){P(this.#p,e,!0)}#m=N(void 0);get mcpStatus(){return H(this.#m)}set mcpStatus(e){P(this.#m,e,!0)}#h=N(!1);get mcpChecking(){return H(this.#h)}set mcpChecking(e){P(this.#h,e,!0)}#g=N(void 0);get mcpSignIn(){return H(this.#g)}set mcpSignIn(e){P(this.#g,e,!0)}#_=N(!1);get mcpSigningIn(){return H(this.#_)}set mcpSigningIn(e){P(this.#_,e,!0)}#v=N(void 0);get packages(){return H(this.#v)}set packages(e){P(this.#v,e,!0)}#y=N(!1);get packagesBusy(){return H(this.#y)}set packagesBusy(e){P(this.#y,e,!0)}#b=N(void 0);get schedulerError(){return H(this.#b)}set schedulerError(e){P(this.#b,e,!0)}#x=N(!1);get updateInstalling(){return H(this.#x)}set updateInstalling(e){P(this.#x,e,!0)}#S=N(void 0);get updateError(){return H(this.#S)}set updateError(e){P(this.#S,e,!0)}#C=N(void 0);get secrets(){return H(this.#C)}set secrets(e){P(this.#C,e,!0)}#w=N(void 0);get secretsError(){return H(this.#w)}set secretsError(e){P(this.#w,e,!0)}#T=N(void 0);get revealed(){return H(this.#T)}set revealed(e){P(this.#T,e,!0)}#E=N(void 0);get memories(){return H(this.#E)}set memories(e){P(this.#E,e,!0)}#D=N(void 0);get memoryError(){return H(this.#D)}set memoryError(e){P(this.#D,e,!0)}#O=N(Kt([]));get extensionNotes(){return H(this.#O)}set extensionNotes(e){P(this.#O,e,!0)}#k=N(void 0);get extensionDialog(){return H(this.#k)}set extensionDialog(e){P(this.#k,e,!0)}#A=N(void 0);get protocolMismatch(){return H(this.#A)}set protocolMismatch(e){P(this.#A,e,!0)}#j=N(void 0);get pi(){return H(this.#j)}set pi(e){P(this.#j,e,!0)}#M=N(void 0);get piVersions(){return H(this.#M)}set piVersions(e){P(this.#M,e,!0)}#N=N(!1);get piBusy(){return H(this.#N)}set piBusy(e){P(this.#N,e,!0)}#P;#F=0;#I=!1;#L=null;#R;#z=new Map;#B=new Set;constructor(e){this.#P=e}watch(){return this.#P.on(e=>{if(e.type===`connected`){this.connected=!0,this.conversationId?this.send({type:`resume`,conversationId:this.conversationId,afterSeq:this.#F}):this.newSession(),this.view===`chat`&&this.showConfig();return}if(e.type===`disconnected`){this.connected=!1;return}this.handleFrame(e)})}send(e){this.#P.send(e)}async request(e){return new Promise(t=>{this.#z.set(e.requestId,t),this.send(e)})}newSession(){this.request({type:`newSession`,requestId:oa()})}prompt(e,t=`steer`,n=[]){this.conversationId&&this.send({type:`prompt`,conversationId:this.conversationId,text:e,...n.length?{attachments:n}:{},mode:t})}abort(){this.conversationId&&this.send({type:`abort`,conversationId:this.conversationId})}fork(e){this.conversationId&&this.request({type:`fork`,conversationId:this.conversationId,messageSeq:e,requestId:oa()})}listSessions(){this.request({type:`listSessions`,requestId:oa()})}openSession(e){this.conversationId&&this.request({type:`switchSession`,conversationId:this.conversationId,sessionPath:e,requestId:oa()})}rename(e){this.conversationId&&this.send({type:`renameSession`,conversationId:this.conversationId,name:e})}deleteSession(e){let t=e===this.sessionPath;$i(e),this.request({type:`deleteSession`,sessionPath:e,requestId:oa()}).then(()=>{t&&this.newSession()})}setModel(e,t){this.conversationId&&(this.send({type:`setModel`,conversationId:this.conversationId,provider:e,modelId:t}),this.#V(`${e}/${t}`))}#V(e){if(!e||(this.#L=e,!this.sessionPath||this.measuredOn===e))return;if(!this.measuredOn&&(Vi(this.metrics.run)||Vi(this.metrics.last))){this.measuredOn=e,Vi(this.metrics.run)&&Qi(this.sessionPath,{...this.metrics.run,model:e});return}let t=Zi(this.sessionPath),n=t&&t.model===e?t:null;this.metrics={...Hi(),last:n},this.measuredOn=n?e:null}setThinkingLevel(e){this.conversationId&&this.send({type:`setThinkingLevel`,conversationId:this.conversationId,level:e})}answerExtension(e,t){this.conversationId&&(this.send({type:`extensionReply`,conversationId:this.conversationId,dialogId:e,value:t}),this.extensionDialog=void 0)}showDebug(){this.conversationId&&this.request({type:`debug`,conversationId:this.conversationId,requestId:oa()})}loadScheduler(){let e=oa();this.#G.add(e),this.request({type:`scheduler`,requestId:e})}installUpdate(){let e=oa();this.#B.add(e),this.updateError=void 0,this.updateInstalling=!0,this.request({type:`installUpdate`,requestId:e})}openChat(){this.revealed=void 0,this.view=`chat`,this.config||this.showConfig()}openSettings(){this.revealed=void 0,this.view=`settings`}openSecrets(){this.view=`secrets`}openMemory(){this.revealed=void 0,this.view=`memory`}toggleSettings(){this.view===`settings`?this.openChat():this.openSettings()}toggleSecrets(){this.view===`secrets`?this.openChat():this.openSecrets()}toggleMemory(){this.view===`memory`?this.openChat():this.openMemory()}showConfig(){this.request({type:`getConfig`,requestId:this.#K()})}saveConfig(e){this.request({type:`saveConfig`,...e,requestId:this.#K()})}showPackages(){this.request({type:`packages`,requestId:this.#K()})}savePackages(e){this.packagesBusy=!0,this.request({type:`savePackages`,...e,requestId:this.#K()})}showPiVersions(){this.request({type:`piVersions`,requestId:this.#K()})}checkPi(){this.request({type:`piCheck`,requestId:this.#K()})}usePi(e){this.piBusy=!0,this.request({type:`usePi`,version:e,requestId:this.#K()})}checkMcp(){this.mcpChecking=!0,this.request({type:`mcpStatus`,requestId:this.#K()})}signInMcp(e){this.mcpSigningIn=!0,this.request({type:`mcpSignIn`,name:e,requestId:this.#K()})}submitMcpRedirect(e,t){this.send({type:`mcpRedirect`,name:e,url:t})}showSecrets(){this.request({type:`secrets`,requestId:this.#q()})}saveSecrets(e){this.request({type:`saveSecrets`,secrets:e,requestId:this.#q()})}revealSecret(e){this.request({type:`revealSecret`,name:e,requestId:this.#q()})}showMemories(){this.request({type:`memory`,requestId:this.#J()})}saveMemories(e){this.request({type:`saveMemory`,memories:e,requestId:this.#J()})}hideSecret(){this.revealed=void 0}#H=new Set;#U=new Set;#W=new Set;#G=new Set;#K(){let e=oa();return this.#H.add(e),e}#q(){let e=oa();return this.#U.add(e),e}#J(){let e=oa();return this.#W.add(e),e}handleFrame(e){switch(e.type){case`hello`:e.protocolVersion!==1&&(this.protocolMismatch=`server speaks protocol v${e.protocolVersion}, this UI speaks v1`),this.pi=e.pi;return;case`event`:{this.#F=Math.max(this.#F,e.seq);let t=e.event;if(this.transcript=Ni(this.transcript,t,()=>Date.now(),e.seq),this.metrics=Ui(this.metrics,t,()=>Date.now()),t.type===`message_end`&&Vi(this.metrics.run)&&this.sessionPath){let e=this.#L;e&&(this.measuredOn=e),Qi(this.sessionPath,{...this.metrics.run,model:e})}t.type===`agent_settled`&&this.showDebug(),!this.#I&&this.transcript.messages.some(e=>e.role===`user`)&&(this.#I=!0,this.listSessions());return}case`extensionUi`:if(e.kind===`notify`){this.extensionNotes=[...this.extensionNotes.slice(-49),{message:e.message,level:e.level??`info`}];return}this.extensionDialog=e;return;case`mcpAuth`:this.mcpSignIn={name:e.name,url:e.url};return;case`result`:if(e.sessionPath){this.transcript=wi();let t=Zi(e.sessionPath);if(this.metrics={...Hi(),last:t},this.measuredOn=t?.model??null,this.#L=null,this.#F=0,this.conversationId=e.conversationId,this.sessionPath=e.sessionPath,this.extensionNotes=[],this.extensionDialog=void 0,this.interruptedAt=e.interrupted?.at,this.#I=this.sessions.some(t=>t.path===e.sessionPath),e.conversationId&&this.send({type:`resume`,conversationId:e.conversationId,afterSeq:0}),this.showDebug(),this.listSessions(),this.#R&&e.conversationId&&this.#R!==e.sessionPath){let t=this.#R;this.#R=void 0,this.request({type:`switchSession`,conversationId:e.conversationId,sessionPath:t,requestId:oa()})}}e.sessions&&(this.sessions=e.sessions),e.config&&(e.requestId&&this.#H.delete(e.requestId),this.config=e.config,this.configError=void 0,this.mcpStatus=void 0),e.debug&&(this.debug=e.debug,this.#V(Xi(e.debug))),e.scheduler&&(this.scheduler=e.scheduler),e.secrets&&(e.requestId&&this.#U.delete(e.requestId),this.secrets=e.secrets,this.secretsError=void 0),e.revealed&&(e.requestId&&this.#U.delete(e.requestId),this.revealed=e.revealed),e.memory&&(e.requestId&&this.#W.delete(e.requestId),this.memories=e.memory,this.memoryError=void 0),e.mcpStatus&&(e.requestId&&this.#H.delete(e.requestId),this.mcpStatus=e.mcpStatus,this.mcpChecking=!1,this.mcpSignIn=void 0,this.mcpSigningIn=!1),e.pi&&(e.requestId&&this.#H.delete(e.requestId),this.piVersions=e.pi,this.piBusy=!1),e.packages&&(e.requestId&&this.#H.delete(e.requestId),this.packages=e.packages,this.packagesBusy=!1,this.configError=void 0),this.#z.get(e.requestId)?.(e),this.#z.delete(e.requestId);return;case`error`:if(e.requestId&&this.#B.delete(e.requestId)){this.updateError=e.message,this.updateInstalling=!1;return}if(e.requestId&&this.#G.delete(e.requestId)){this.schedulerError=e.message;return}if(this.lastError=e.message,e.requestId&&this.#H.delete(e.requestId)){this.configError=e.message,this.mcpChecking=!1,this.mcpSignIn=void 0,this.mcpSigningIn=!1,this.packagesBusy=!1,this.piBusy=!1;return}e.requestId&&this.#U.delete(e.requestId)&&(this.secretsError=e.message,this.revealed=void 0),e.requestId&&this.#W.delete(e.requestId)&&(this.memoryError=e.message),this.conversationId&&e.conversationId===this.conversationId&&/^unknown conversation /.test(e.message)&&(this.#R=this.sessionPath,this.newSession());return}}},aa=0;function oa(){return`ui-${++aa}`}var sa=`flypi.theme`;function ca(){let e=document.documentElement.dataset.theme;return e===`light`||e===`dark`?e:null}function la(e){document.documentElement.dataset.theme=e;try{localStorage.setItem(sa,e)}catch{}}function ua(){let e=localStorage.getItem(sa);la(e===`light`||e===`dark`?e:matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`)}var da=W(`<span class="port">· new</span>`),fa=Er(`<svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="4"></circle><path d="M12 2v2m0 16v2M2 12h2m16 0h2M4.9 4.9l1.4 1.4m11.4 11.4 1.4 1.4m0-14.2-1.4 1.4M6.3 17.7l-1.4 1.4" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"></path></svg>`),pa=Er(`<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M21 13.1A8.5 8.5 0 1 1 10.9 3a7.5 7.5 0 0 0 10.1 10.1Z" fill="currentColor"></path></svg>`),ma=W(`<p class="update error" data-role="update-error"> </p>`),ha=W(`<p class="update" data-role="update"> <button type="button" class="icon" data-role="install-update"> </button></p> <!>`,1),ga=W(`<p class="update" data-role="pi-version"> </p>`),_a=W(`<input class="name current" placeholder="New session" aria-label="Session name"/>`),va=W(`<button type="button" class="session"> </button>`),ya=W(`<li><!> <button type="button" class="icon remove" title="Delete this session"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 7h16M9 7V4.5h6V7M6.5 7l.8 12.5h9.4L17.5 7M10.2 10.5v6m3.6-6v6" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"></path></svg></button></li>`),ba=W(`<aside class="sidebar"><header class="panel-head"><img class="logo" alt=""/> <h1>flypi<!></h1></header> <div class="panel-actions"><button type="button" class="icon" aria-label="New session" title="New session"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 5v14M5 12h14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"></path></svg></button> <button type="button" class="icon"><!></button> <button type="button" class="icon" data-role="memory" aria-label="Memory" title="Memory — what is remembered, and why"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4.5 6.2h6.2c1 0 1.8.8 1.8 1.8v9.6c0-1 .8-1.8 1.8-1.8h5.2V6.2H4.5Z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"></path><path d="M12.5 17.6c0-1 .8-1.8 1.8-1.8h5.2" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"></path></svg></button> <button type="button" class="icon" data-role="secrets" aria-label="Secrets" title="Secrets — the encrypted vault"><svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="7.8" cy="7.8" r="3.6" fill="none" stroke="currentColor" stroke-width="1.8"></circle><path d="M10.4 10.4 19.5 19.5M15.4 15.4l2.4-2.4M12.9 12.9l2-2" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"></path></svg></button> <button type="button" class="icon" data-role="settings" aria-label="Model endpoints and MCP servers" title="Model endpoints and MCP servers"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 7h16M4 12h16M4 17h16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path><circle cx="9" cy="7" r="2" fill="currentColor"></circle><circle cx="15" cy="12" r="2" fill="currentColor"></circle><circle cx="11" cy="17" r="2" fill="currentColor"></circle></svg></button></div> <!> <!> <ul class="sessions"></ul></aside>`);function xa(e,t){He(t,!0);let n=N(Kt(ca()??`light`));function r(){P(n,H(n)===`dark`?`light`:`dark`,!0),la(H(n))}function i(e){return e.name||e.firstMessage}function a(e){return i(e)||e.path}function o(e,n){let r=n.currentTarget.value.trim();r&&r!==e.trim()&&t.app.rename(r)}function s(e){t.app.deleteSession(e.path)}var c=ba(),l=F(c),u=F(l),d=R(u,2),f=R(F(d)),p=e=>{G(e,da())};q(f,e=>{t.app.sessionPath||e(p)}),k(d),k(l);var m=R(l,2),h=F(m),g=R(h,2),_=F(g),v=e=>{G(e,fa())},y=e=>{G(e,pa())};q(_,e=>{H(n)===`dark`?e(v):e(y,-1)}),k(g);var b=R(g,2),x=R(b,2),S=R(x,2);k(m);var ee=R(m,2),te=e=>{var n=ha(),r=I(n),i=F(r),a=R(i),o=L(a,!0);k(r);var s=R(r,2),c=e=>{var n=ma(),r=L(n,!0);z(()=>K(r,t.app.updateError)),G(e,n)};q(s,e=>{t.app.updateError&&e(c)}),z(()=>{K(i,`flypi ${t.update.version??``} ${t.update.ready?`is downloaded — it installs when nothing is running`:`is available`} `),a.disabled=t.app.updateInstalling,X(a,`title`,`Install ${t.update.version??``} now — the daemon restarts to run it`),K(o,t.app.updateInstalling?`installing…`:`install now`)}),U(`click`,a,()=>t.app.installUpdate()),G(e,n)};q(ee,e=>{t.update&&e(te)});var C=R(ee,2),ne=e=>{var n=ga(),r=L(n,!0);z(()=>K(r,`pi ${t.app.pi.version}${t.app.pi.pinned?` (pinned)`:``}${t.app.pi.bundled?` · installed tree holds ${t.app.pi.bundled}`:``}`)),G(e,n)};q(C,e=>{t.app.pi&&e(ne)});var w=R(C,2);J(w,21,()=>t.app.sessions,e=>e.path,(e,n)=>{var r=ya(),c=F(r),l=e=>{var t=_a();Y(t),z(e=>mi(t,e),[()=>i(H(n))]),gr(`blur`,t,e=>o(i(H(n)),e)),U(`keydown`,t,e=>{e.key===`Enter`?o(i(H(n)),e):e.key===`Escape`&&(e.currentTarget.value=i(H(n)))}),G(e,t)},u=e=>{var r=va(),i=L(r,!0);z(e=>K(i,e),[()=>a(H(n))]),U(`click`,r,()=>{t.app.openChat(),t.app.openSession(H(n).path)}),G(e,r)};q(c,e=>{H(n).path===t.app.sessionPath?e(l):e(u,-1)});var d=R(c,2);k(r),z(e=>X(d,`aria-label`,`Delete ${e??``}`),[()=>a(H(n))]),U(`click`,d,()=>s(H(n))),G(e,r)}),k(w),k(c),z(()=>{X(u,`src`,H(n)===`dark`?`/flypi-logo-dark.jpeg`:`/flypi-logo-light.jpeg`),X(g,`aria-label`,`Switch to ${H(n)===`dark`?`light`:`dark`} theme`),X(g,`title`,`Switch to ${H(n)===`dark`?`light`:`dark`} theme`),X(b,`aria-pressed`,t.app.view===`memory`),X(x,`aria-pressed`,t.app.view===`secrets`),X(S,`aria-pressed`,t.app.view===`settings`)}),U(`click`,h,()=>{t.app.openChat(),t.app.newSession()}),U(`click`,g,r),U(`click`,b,()=>t.app.toggleMemory()),U(`click`,x,()=>t.app.toggleSecrets()),U(`click`,S,()=>t.app.toggleSettings()),G(e,c),Ue()}_r([`click`,`keydown`]);var Sa=4194304;function Ca(e){return e.mimeType.startsWith(`image/`)}function wa(e){let t=new Uint8Array(e),n=``;for(let e=0;e<t.length;e+=32768)n+=String.fromCharCode(...t.subarray(e,e+32768));return btoa(n)}function Ta(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var Ea=Ta();function Da(e){Ea=e}var Oa={exec:()=>null};function ka(e){let t=[];return n=>{let r=Math.max(0,Math.min(3,n-1)),i=t[r];return i||(i=e(r),t[r]=i),i}}function Q(e,t=``){let n=typeof e==`string`?e:e.source,r={replace:(e,t)=>{let i=typeof t==`string`?t:t.source;return i=i.replace(ja.caret,`$1`),n=n.replace(e,i),r},getRegex:()=>new RegExp(n,t)};return r}var Aa=((e=``)=>{try{return!!RegExp(`(?<=1)(?<!1)`+e)}catch{return!1}})(),ja={codeRemoveIndent:/^(?: {1,4}| {0,3}\t)/gm,outputLinkReplace:/\\([\[\]])/g,indentCodeCompensation:/^(\s+)(?:```)/,beginningSpace:/^\s+/,endingHash:/#$/,startingSpaceChar:/^ /,endingSpaceChar:/ $/,nonSpaceChar:/[^ ]/,newLineCharGlobal:/\n/g,tabCharGlobal:/\t/g,multipleSpaceGlobal:/\s+/g,blankLine:/^[ \t]*$/,doubleBlankLine:/\n[ \t]*\n[ \t]*$/,blockquoteStart:/^ {0,3}>/,blockquoteSetextReplace:/\n {0,3}((?:=+|-+) *)(?=\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \t]?/gm,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\[[ xX]\] +\S/,listReplaceTask:/^\[[ xX]\] +/,listTaskCheckbox:/\[[ xX]\]/,anyLine:/\n.*\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\||\| *$/g,tableRowBlankLine:/\n[ \t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^<a /i,endATag:/^<\/a>/i,startPreScriptTag:/^<(pre|code|kbd|script)(\s|>)/i,endPreScriptTag:/^<\/(pre|code|kbd|script)(\s|>)/i,startAngleBracket:/^</,endAngleBracket:/>$/,pedanticHrefTitle:/^([^'"]*[^\s])\s+(['"])(.*)\2/,unicodeAlphaNumeric:/[\p{L}\p{N}]/u,escapeTest:/[&<>"']/,escapeReplace:/[&<>"']/g,escapeTestNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,escapeReplaceNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g,caret:/(^|[^\[])\^/g,percentDecode:/%25/g,findPipe:/\|/g,splitPipe:/ \|/,slashPipe:/\\\|/g,carriageReturn:/\r\n|\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\S*/,endingNewline:/\n$/,listItemRegex:e=>RegExp(`^( {0,3}${e})((?:[ ][^\\n]*)?(?:\\n|$))`),nextBulletRegex:ka(e=>RegExp(`^ {0,${e}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`)),hrRegex:ka(e=>RegExp(`^ {0,${e}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`)),fencesBeginRegex:ka(e=>RegExp(`^ {0,${e}}(?:\`\`\`|~~~)`)),headingBeginRegex:ka(e=>RegExp(`^ {0,${e}}#`)),htmlBeginRegex:ka(e=>RegExp(`^ {0,${e}}<(?:[a-z].*>|!--)`,`i`)),blockquoteBeginRegex:ka(e=>RegExp(`^ {0,${e}}>`))},Ma=/^(?:[ \t]*(?:\n|$))+/,Na=/^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/,Pa=/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,Fa=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,Ia=/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,La=/ {0,3}(?:[*+-]|\d{1,9}[.)])/,Ra=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,za=Q(Ra).replace(/bull/g,La).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}(?:\s|$)/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/\|table/g,``).getRegex(),Ba=Q(Ra).replace(/bull/g,La).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}(?:\s|$)/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/table/g,/ {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex(),Va=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table|[ \t]+\n)[^\n]+)*)/,Ha=/^[^\n]+/,Ua=/(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/,Wa=Q(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace(`label`,Ua).replace(`title`,/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),Ga=Q(/^(bull)([ \t][^\n]*?)?(?:\n|$)/).replace(/bull/g,La).getRegex(),Ka=`address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul`,qa=/<!--(?:-?>|[\s\S]*?(?:-->|$))/,Ja=Q(`^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n*|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>[^\\n]*\\n*|$)|<![A-Z][\\s\\S]*?(?:>[^\\n]*\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>[^\\n]*\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))`,`i`).replace(`comment`,qa).replace(`tag`,Ka).replace(`attribute`,/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),Ya=e=>Q(Va).replace(`hr`,Fa).replace(`heading`,` {0,3}#{1,6}(?:\\s|$)`).replace(`|lheading`,``).replace(`|table`,``).replace(`blockquote`,` {0,3}>`).replace(`fences`," {0,3}(?:`{3,}(?=[^`\\n]*(?:\\n|$))|~~~)[^\\n]*(?:\\n|$)").replace(`list`,e).replace(`html`,`</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)`).replace(`tag`,Ka).getRegex(),Xa=Ya(/ {0,3}(?:[*+-]|1[.)])[ \t]+[^ \t\n]/),Za=Ya(/ {0,3}(?:[*+-]|\d{1,9}[.)])(?:[ \t]|\n|$)/),Qa={blockquote:Q(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace(`paragraph`,Za).getRegex(),code:Na,def:Wa,fences:Pa,heading:Ia,hr:Fa,html:Ja,lheading:za,list:Ga,newline:Ma,paragraph:Xa,table:Oa,text:Ha},$a=Q(`^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)`).replace(`hr`,Fa).replace(`heading`,` {0,3}#{1,6}(?:\\s|$)`).replace(`blockquote`,` {0,3}>`).replace(`code`,`(?: {4}| {0,3} )[^\\n]`).replace(`fences`," {0,3}(?:`{3,}(?=[^`\\n]*(?:\\n|$))|~~~)[^\\n]*(?:\\n|$)").replace(`list`,` {0,3}(?:[*+-]|1[.)])[ \\t]`).replace(`html`,`</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)`).replace(`tag`,Ka).getRegex(),eo={...Qa,lheading:Ba,table:$a,paragraph:Q(Va).replace(`hr`,Fa).replace(`heading`,` {0,3}#{1,6}(?:\\s|$)`).replace(`|lheading`,``).replace(`table`,$a).replace(`blockquote`,` {0,3}>`).replace(`fences`," {0,3}(?:`{3,}(?=[^`\\n]*(?:\\n|$))|~~~)[^\\n]*(?:\\n|$)").replace(`list`,` {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]`).replace(`html`,`</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)`).replace(`tag`,Ka).getRegex()},to={...Qa,html:Q(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace(`comment`,qa).replace(/tag/g,`(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b`).getRegex(),def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:Oa,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:Q(Va).replace(`hr`,Fa).replace(`heading`,` *#{1,6} *[^
|
|
3
|
+
`);if(e&&typeof e==`object`){let t=e;return`content`in t?ji(t.content):`text`in t&&typeof t.text==`string`?t.text:JSON.stringify(e,null,2)}return``}function Mi(e,t){return{input:e.input+t.input,output:e.output+t.output,cacheRead:e.cacheRead+t.cacheRead,cacheWrite:e.cacheWrite+t.cacheWrite,totalTokens:e.totalTokens+t.totalTokens,cost:e.cost+t.cost}}function Ni(e,t,n=Date.now,r){switch(t.type){case`agent_start`:return{...e,running:!0,turn:Ti()};case`agent_settled`:return{...e,running:!1,streaming:null,queue:{steering:[],followUp:[]}};case`message_start`:return Pi(t.message)?{...e,streaming:Ei(t.message)}:e;case`message_update`:{let n=t.assistantMessageEvent;return n?.partial?{...e,streaming:Ei(n.partial)}:e}case`message_end`:{let n=Ei(t.message);if(n.role===`system`||n.role===`custom`)return e;if(n.role===`toolResult`){let t=n.blocks[0],r=e.tools[t.id];if(r)return{...e,tools:{...e.tools,[t.id]:{...r,output:t.output,state:t.isError?`error`:`done`}}}}r!==void 0&&(n.seq=r);let i=n.usage?Mi(e.turn,n.usage):e.turn,a={...e.tools};for(let e of n.blocks)e.kind===`tool-call`&&!a[e.id]&&(a[e.id]={id:e.id,name:e.name,args:e.args,output:``,state:`pending`});return{...e,messages:[...e.messages,n],streaming:null,tools:a,turn:i,total:n.usage?Mi(e.total,n.usage):e.total}}case`tool_execution_start`:{let r=t,i=e.tools[r.toolCallId];return{...e,tools:{...e.tools,[r.toolCallId]:{id:r.toolCallId,name:r.toolName,args:r.args,output:i?.output??``,state:`running`,startedAt:i?.startedAt??n()}}}}case`tool_execution_update`:{let n=t,r=e.tools[n.toolCallId];return r?{...e,tools:{...e.tools,[n.toolCallId]:{...r,output:ji(n.partialResult)}}}:e}case`tool_execution_end`:{let r=t,i=e.tools[r.toolCallId],a={id:r.toolCallId,name:r.toolName,args:i?.args,output:ji(r.result),state:r.isError?`error`:`done`,startedAt:i?.startedAt??n(),endedAt:n()};return{...e,tools:{...e.tools,[r.toolCallId]:a}}}case`queue_update`:{let n=t;return{...e,queue:{steering:[...n.steering],followUp:[...n.followUp]}}}default:return e}}function Pi(e){return e?.role===`assistant`}function Fi(e){return e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function Ii(e){return`${`${Fi(e.input)} in / ${Fi(e.output)} out`}${e.cacheRead?` / ${Fi(e.cacheRead)} cached`:``} · $${e.cost.toFixed(4)}`}function Li(e){return e.input+e.cacheRead+e.cacheWrite}function Ri(e){let t=Li(e);return t?`${Fi(e.cacheRead)} read / ${Fi(e.cacheWrite)} write · ${Math.round(e.cacheRead/t*100)}% of the prompt from cache`:`the provider reported no usage`}var zi=new Set([`text_start`,`text_delta`,`thinking_start`,`thinking_delta`,`toolcall_start`,`toolcall_delta`]),Bi={promptTokens:0,outputTokens:0,prefillMs:0,decodeMs:0};function Vi(e){return e!==null&&(e.promptTokens>0||e.outputTokens>0)}function Hi(){return{live:null,last:null,run:{...Bi}}}function Ui(e,t,n=Date.now){switch(t.type){case`agent_start`:return{...e,pendingStart:void 0,live:null,run:{...Bi}};case`turn_start`:return{...e,pendingStart:n()};case`message_start`:return Pi(t.message)?{...e,pendingStart:void 0,live:{requestStart:e.pendingStart??n(),firstTokenAt:null,promptTokens:0,outputTokens:0}}:e;case`message_update`:{if(!e.live)return e;let r=t.assistantMessageEvent,i=Oi(r?.partial?.usage);return{...e,live:{...e.live,firstTokenAt:e.live.firstTokenAt??(zi.has(r?.type??``)?n():null),promptTokens:i?Li(i):e.live.promptTokens,outputTokens:i&&i.output>0?i.output:e.live.outputTokens}}}case`message_end`:{let r=t.message;if(!Pi(r)||!e.live)return e;let i=Oi(r.usage),a=e.live.firstTokenAt,o=i?Li(i):0,s=i?.output??0,c={promptTokens:o,outputTokens:s,prefillMs:a===null?0:Ki(o,a-e.live.requestStart),decodeMs:a===null?0:Ki(s,n()-a)};return{...e,pendingStart:void 0,live:null,last:Vi(c)?c:e.last,run:a===null?e.run:Gi(e.run,c)}}case`agent_settled`:return{...e,pendingStart:void 0,live:null};default:return e}}function Wi(e,t){let n=e.live,r=n?.firstTokenAt==null?e.run:Gi(e.run,{promptTokens:n.promptTokens,outputTokens:n.outputTokens,prefillMs:Ki(n.promptTokens,n.firstTokenAt-n.requestStart),decodeMs:Ki(n.outputTokens,t-n.firstTokenAt)});if(r.promptTokens===0&&r.outputTokens===0){let t=e.last;return t?{prefill:qi(t.promptTokens,t.prefillMs),decode:qi(t.outputTokens,t.decodeMs)}:{prefill:null,decode:null}}return{prefill:qi(r.promptTokens,r.prefillMs),decode:qi(r.outputTokens,r.decodeMs)}}function Gi(e,t){return{promptTokens:e.promptTokens+t.promptTokens,outputTokens:e.outputTokens+t.outputTokens,prefillMs:e.prefillMs+t.prefillMs,decodeMs:e.decodeMs+t.decodeMs}}function Ki(e,t){return e>0?t:0}function qi(e,t){return t>0&&e>0?e*1e3/t:null}function Ji(e){return e>=100?String(Math.round(e)):e.toFixed(1)}var Yi=`flypi.lastAnswers`;function Xi(e){return e.model?`${e.model.provider}/${e.model.modelId}`:null}function Zi(e){return ta()[e]??null}function Qi(e,t){let n=ta();n[e]=t,ea(n)}function $i(e){let t=ta();e in t&&(delete t[e],ea(t))}function ea(e){try{localStorage.setItem(Yi,JSON.stringify(e))}catch{}}function ta(){let e;try{e=JSON.parse(localStorage.getItem(Yi)??``)}catch{return{}}if(!e||typeof e!=`object`)return{};let t={};for(let[n,r]of Object.entries(e)){let e=na(r);e&&(t[n]=e)}return t}function na(e){let t=e;if(!t||typeof t!=`object`)return null;let{promptTokens:n,outputTokens:r,prefillMs:i,decodeMs:a}=t;return ra(n)&&ra(r)&&ra(i)&&ra(a)?{promptTokens:n,outputTokens:r,prefillMs:i,decodeMs:a,model:typeof t.model==`string`?t.model:null}:null}function ra(e){return Number.isFinite(e)}var ia=class{#e=N(Kt(wi()));get transcript(){return H(this.#e)}set transcript(e){P(this.#e,e,!0)}#t=N(Kt(Hi()));get metrics(){return H(this.#t)}set metrics(e){P(this.#t,e,!0)}#n=N(null);get measuredOn(){return H(this.#n)}set measuredOn(e){P(this.#n,e,!0)}#r=N(void 0);get conversationId(){return H(this.#r)}set conversationId(e){P(this.#r,e,!0)}#i=N(void 0);get sessionPath(){return H(this.#i)}set sessionPath(e){P(this.#i,e,!0)}#a=N(Kt([]));get sessions(){return H(this.#a)}set sessions(e){P(this.#a,e,!0)}#o=N(void 0);get debug(){return H(this.#o)}set debug(e){P(this.#o,e,!0)}#s=N(void 0);get scheduler(){return H(this.#s)}set scheduler(e){P(this.#s,e,!0)}#c=N(void 0);get interruptedAt(){return H(this.#c)}set interruptedAt(e){P(this.#c,e,!0)}#l=N(void 0);get config(){return H(this.#l)}set config(e){P(this.#l,e,!0)}#u=N(`chat`);get view(){return H(this.#u)}set view(e){P(this.#u,e,!0)}#d=N(!1);get connected(){return H(this.#d)}set connected(e){P(this.#d,e,!0)}#f=N(void 0);get lastError(){return H(this.#f)}set lastError(e){P(this.#f,e,!0)}#p=N(void 0);get configError(){return H(this.#p)}set configError(e){P(this.#p,e,!0)}#m=N(void 0);get mcpStatus(){return H(this.#m)}set mcpStatus(e){P(this.#m,e,!0)}#h=N(!1);get mcpChecking(){return H(this.#h)}set mcpChecking(e){P(this.#h,e,!0)}#g=N(void 0);get mcpSignIn(){return H(this.#g)}set mcpSignIn(e){P(this.#g,e,!0)}#_=N(!1);get mcpSigningIn(){return H(this.#_)}set mcpSigningIn(e){P(this.#_,e,!0)}#v=N(void 0);get packages(){return H(this.#v)}set packages(e){P(this.#v,e,!0)}#y=N(!1);get packagesBusy(){return H(this.#y)}set packagesBusy(e){P(this.#y,e,!0)}#b=N(void 0);get schedulerError(){return H(this.#b)}set schedulerError(e){P(this.#b,e,!0)}#x=N(!1);get updateInstalling(){return H(this.#x)}set updateInstalling(e){P(this.#x,e,!0)}#S=N(void 0);get updateError(){return H(this.#S)}set updateError(e){P(this.#S,e,!0)}#C=N(void 0);get secrets(){return H(this.#C)}set secrets(e){P(this.#C,e,!0)}#w=N(void 0);get secretsError(){return H(this.#w)}set secretsError(e){P(this.#w,e,!0)}#T=N(void 0);get revealed(){return H(this.#T)}set revealed(e){P(this.#T,e,!0)}#E=N(void 0);get memories(){return H(this.#E)}set memories(e){P(this.#E,e,!0)}#D=N(void 0);get memoryError(){return H(this.#D)}set memoryError(e){P(this.#D,e,!0)}#O=N(Kt([]));get extensionNotes(){return H(this.#O)}set extensionNotes(e){P(this.#O,e,!0)}#k=N(void 0);get extensionDialog(){return H(this.#k)}set extensionDialog(e){P(this.#k,e,!0)}#A=N(void 0);get protocolMismatch(){return H(this.#A)}set protocolMismatch(e){P(this.#A,e,!0)}#j=N(void 0);get pi(){return H(this.#j)}set pi(e){P(this.#j,e,!0)}#M=N(void 0);get piVersions(){return H(this.#M)}set piVersions(e){P(this.#M,e,!0)}#N=N(!1);get piBusy(){return H(this.#N)}set piBusy(e){P(this.#N,e,!0)}#P;#F=0;#I=!1;#L=null;#R;#z=new Map;#B=new Set;constructor(e){this.#P=e}watch(){return this.#P.on(e=>{if(e.type===`connected`){this.connected=!0,this.conversationId?this.send({type:`resume`,conversationId:this.conversationId,afterSeq:this.#F}):this.newSession(),this.view===`chat`&&this.showConfig();return}if(e.type===`disconnected`){this.connected=!1;return}this.handleFrame(e)})}send(e){this.#P.send(e)}async request(e){return new Promise(t=>{this.#z.set(e.requestId,t),this.send(e)})}newSession(){this.request({type:`newSession`,requestId:oa()})}prompt(e,t=`steer`,n=[]){this.conversationId&&this.send({type:`prompt`,conversationId:this.conversationId,text:e,...n.length?{attachments:n}:{},mode:t})}abort(){this.conversationId&&this.send({type:`abort`,conversationId:this.conversationId})}fork(e){this.conversationId&&this.request({type:`fork`,conversationId:this.conversationId,messageSeq:e,requestId:oa()})}listSessions(){this.request({type:`listSessions`,requestId:oa()})}openSession(e){this.conversationId&&this.request({type:`switchSession`,conversationId:this.conversationId,sessionPath:e,requestId:oa()})}rename(e){this.conversationId&&this.send({type:`renameSession`,conversationId:this.conversationId,name:e})}deleteSession(e){let t=e===this.sessionPath;$i(e),this.request({type:`deleteSession`,sessionPath:e,requestId:oa()}).then(()=>{t&&this.newSession()})}setModel(e,t){this.conversationId&&(this.send({type:`setModel`,conversationId:this.conversationId,provider:e,modelId:t}),this.#V(`${e}/${t}`))}#V(e){if(!e||(this.#L=e,!this.sessionPath||this.measuredOn===e))return;if(!this.measuredOn&&(Vi(this.metrics.run)||Vi(this.metrics.last))){this.measuredOn=e,Vi(this.metrics.run)&&Qi(this.sessionPath,{...this.metrics.run,model:e});return}let t=Zi(this.sessionPath),n=t&&t.model===e?t:null;this.metrics={...Hi(),last:n},this.measuredOn=n?e:null}setThinkingLevel(e){this.conversationId&&this.send({type:`setThinkingLevel`,conversationId:this.conversationId,level:e})}answerExtension(e,t){this.conversationId&&(this.send({type:`extensionReply`,conversationId:this.conversationId,dialogId:e,value:t}),this.extensionDialog=void 0)}showDebug(){this.conversationId&&this.request({type:`debug`,conversationId:this.conversationId,requestId:oa()})}loadScheduler(){let e=oa();this.#G.add(e),this.request({type:`scheduler`,requestId:e})}installUpdate(){let e=oa();this.#B.add(e),this.updateError=void 0,this.updateInstalling=!0,this.request({type:`installUpdate`,requestId:e})}openChat(){this.revealed=void 0,this.view=`chat`,this.config||this.showConfig()}openSettings(){this.revealed=void 0,this.view=`settings`}openSecrets(){this.view=`secrets`}openMemory(){this.revealed=void 0,this.view=`memory`}toggleSettings(){this.view===`settings`?this.openChat():this.openSettings()}toggleSecrets(){this.view===`secrets`?this.openChat():this.openSecrets()}toggleMemory(){this.view===`memory`?this.openChat():this.openMemory()}showConfig(){this.request({type:`getConfig`,requestId:this.#K()})}saveConfig(e){this.request({type:`saveConfig`,...e,requestId:this.#K()})}showPackages(){this.request({type:`packages`,requestId:this.#K()})}savePackages(e){this.packagesBusy=!0,this.request({type:`savePackages`,...e,requestId:this.#K()})}showPiVersions(){this.request({type:`piVersions`,requestId:this.#K()})}checkPi(){this.request({type:`piCheck`,requestId:this.#K()})}usePi(e){this.piBusy=!0,this.request({type:`usePi`,version:e,requestId:this.#K()})}checkMcp(){this.mcpChecking=!0,this.request({type:`mcpStatus`,requestId:this.#K()})}signInMcp(e){this.mcpSigningIn=!0,this.request({type:`mcpSignIn`,name:e,requestId:this.#K()})}submitMcpRedirect(e,t){this.send({type:`mcpRedirect`,name:e,url:t})}showSecrets(){this.request({type:`secrets`,requestId:this.#q()})}saveSecrets(e){this.request({type:`saveSecrets`,secrets:e,requestId:this.#q()})}revealSecret(e){this.request({type:`revealSecret`,name:e,requestId:this.#q()})}showMemories(){this.request({type:`memory`,requestId:this.#J()})}saveMemories(e){this.request({type:`saveMemory`,memories:e,requestId:this.#J()})}hideSecret(){this.revealed=void 0}#H=new Set;#U=new Set;#W=new Set;#G=new Set;#K(){let e=oa();return this.#H.add(e),e}#q(){let e=oa();return this.#U.add(e),e}#J(){let e=oa();return this.#W.add(e),e}handleFrame(e){switch(e.type){case`hello`:e.protocolVersion!==1&&(this.protocolMismatch=`server speaks protocol v${e.protocolVersion}, this UI speaks v1`),this.pi=e.pi;return;case`event`:{if(this.conversationId&&e.conversationId!==this.conversationId)return;this.#F=Math.max(this.#F,e.seq);let t=e.event;if(this.transcript=Ni(this.transcript,t,()=>Date.now(),e.seq),this.metrics=Ui(this.metrics,t,()=>Date.now()),t.type===`message_end`&&Vi(this.metrics.run)&&this.sessionPath){let e=this.#L;e&&(this.measuredOn=e),Qi(this.sessionPath,{...this.metrics.run,model:e})}t.type===`agent_settled`&&this.showDebug(),!this.#I&&this.transcript.messages.some(e=>e.role===`user`)&&(this.#I=!0,this.listSessions());return}case`extensionUi`:if(this.conversationId&&e.conversationId!==this.conversationId)return;if(e.kind===`notify`){this.extensionNotes=[...this.extensionNotes.slice(-49),{message:e.message,level:e.level??`info`}];return}this.extensionDialog=e;return;case`mcpAuth`:this.mcpSignIn={name:e.name,url:e.url};return;case`result`:if(e.sessionPath){this.transcript=wi();let t=Zi(e.sessionPath);if(this.metrics={...Hi(),last:t},this.measuredOn=t?.model??null,this.#L=null,this.#F=0,this.conversationId=e.conversationId,this.sessionPath=e.sessionPath,this.extensionNotes=[],this.extensionDialog=void 0,this.interruptedAt=e.interrupted?.at,this.#I=this.sessions.some(t=>t.path===e.sessionPath),e.conversationId&&this.send({type:`resume`,conversationId:e.conversationId,afterSeq:0}),this.showDebug(),this.listSessions(),this.#R&&e.conversationId&&this.#R!==e.sessionPath){let t=this.#R;this.#R=void 0,this.request({type:`switchSession`,conversationId:e.conversationId,sessionPath:t,requestId:oa()})}}e.sessions&&(this.sessions=e.sessions),e.config&&(e.requestId&&this.#H.delete(e.requestId),this.config=e.config,this.configError=void 0,this.mcpStatus=void 0),e.debug&&(this.debug=e.debug,this.#V(Xi(e.debug))),e.scheduler&&(this.scheduler=e.scheduler),e.secrets&&(e.requestId&&this.#U.delete(e.requestId),this.secrets=e.secrets,this.secretsError=void 0),e.revealed&&(e.requestId&&this.#U.delete(e.requestId),this.revealed=e.revealed),e.memory&&(e.requestId&&this.#W.delete(e.requestId),this.memories=e.memory,this.memoryError=void 0),e.mcpStatus&&(e.requestId&&this.#H.delete(e.requestId),this.mcpStatus=e.mcpStatus,this.mcpChecking=!1,this.mcpSignIn=void 0,this.mcpSigningIn=!1),e.pi&&(e.requestId&&this.#H.delete(e.requestId),this.piVersions=e.pi,this.piBusy=!1),e.packages&&(e.requestId&&this.#H.delete(e.requestId),this.packages=e.packages,this.packagesBusy=!1,this.configError=void 0),this.#z.get(e.requestId)?.(e),this.#z.delete(e.requestId);return;case`error`:if(e.requestId&&this.#B.delete(e.requestId)){this.updateError=e.message,this.updateInstalling=!1;return}if(e.requestId&&this.#G.delete(e.requestId)){this.schedulerError=e.message;return}if(this.conversationId&&e.conversationId===this.conversationId&&e.code===`unknownConversation`){this.#R=this.sessionPath,this.newSession();return}if(this.lastError=e.message,e.requestId&&this.#H.delete(e.requestId)){this.configError=e.message,this.mcpChecking=!1,this.mcpSignIn=void 0,this.mcpSigningIn=!1,this.packagesBusy=!1,this.piBusy=!1;return}e.requestId&&this.#U.delete(e.requestId)&&(this.secretsError=e.message,this.revealed=void 0),e.requestId&&this.#W.delete(e.requestId)&&(this.memoryError=e.message);return}}},aa=0;function oa(){return`ui-${++aa}`}var sa=`flypi.theme`;function ca(){let e=document.documentElement.dataset.theme;return e===`light`||e===`dark`?e:null}function la(e){document.documentElement.dataset.theme=e;try{localStorage.setItem(sa,e)}catch{}}function ua(){let e=localStorage.getItem(sa);la(e===`light`||e===`dark`?e:matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`)}var da=W(`<span class="port">· new</span>`),fa=Er(`<svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="4"></circle><path d="M12 2v2m0 16v2M2 12h2m16 0h2M4.9 4.9l1.4 1.4m11.4 11.4 1.4 1.4m0-14.2-1.4 1.4M6.3 17.7l-1.4 1.4" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"></path></svg>`),pa=Er(`<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M21 13.1A8.5 8.5 0 1 1 10.9 3a7.5 7.5 0 0 0 10.1 10.1Z" fill="currentColor"></path></svg>`),ma=W(`<p class="update error" data-role="update-error"> </p>`),ha=W(`<p class="update" data-role="update"> <button type="button" class="icon" data-role="install-update"> </button></p> <!>`,1),ga=W(`<p class="update" data-role="pi-version"> </p>`),_a=W(`<input class="name current" placeholder="New session" aria-label="Session name"/>`),va=W(`<button type="button" class="session"> </button>`),ya=W(`<li><!> <button type="button" class="icon remove" title="Delete this session"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 7h16M9 7V4.5h6V7M6.5 7l.8 12.5h9.4L17.5 7M10.2 10.5v6m3.6-6v6" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"></path></svg></button></li>`),ba=W(`<aside class="sidebar"><header class="panel-head"><img class="logo" alt=""/> <h1>flypi<!></h1></header> <div class="panel-actions"><button type="button" class="icon" aria-label="New session" title="New session"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 5v14M5 12h14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"></path></svg></button> <button type="button" class="icon"><!></button> <button type="button" class="icon" data-role="memory" aria-label="Memory" title="Memory — what is remembered, and why"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4.5 6.2h6.2c1 0 1.8.8 1.8 1.8v9.6c0-1 .8-1.8 1.8-1.8h5.2V6.2H4.5Z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"></path><path d="M12.5 17.6c0-1 .8-1.8 1.8-1.8h5.2" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"></path></svg></button> <button type="button" class="icon" data-role="secrets" aria-label="Secrets" title="Secrets — the encrypted vault"><svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="7.8" cy="7.8" r="3.6" fill="none" stroke="currentColor" stroke-width="1.8"></circle><path d="M10.4 10.4 19.5 19.5M15.4 15.4l2.4-2.4M12.9 12.9l2-2" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"></path></svg></button> <button type="button" class="icon" data-role="settings" aria-label="Model endpoints and MCP servers" title="Model endpoints and MCP servers"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 7h16M4 12h16M4 17h16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path><circle cx="9" cy="7" r="2" fill="currentColor"></circle><circle cx="15" cy="12" r="2" fill="currentColor"></circle><circle cx="11" cy="17" r="2" fill="currentColor"></circle></svg></button></div> <!> <!> <ul class="sessions"></ul></aside>`);function xa(e,t){He(t,!0);let n=N(Kt(ca()??`light`));function r(){P(n,H(n)===`dark`?`light`:`dark`,!0),la(H(n))}function i(e){return e.name||e.firstMessage}function a(e){return i(e)||e.path}function o(e,n){let r=n.currentTarget.value.trim();r&&r!==e.trim()&&t.app.rename(r)}function s(e){t.app.deleteSession(e.path)}var c=ba(),l=F(c),u=F(l),d=R(u,2),f=R(F(d)),p=e=>{G(e,da())};q(f,e=>{t.app.sessionPath||e(p)}),k(d),k(l);var m=R(l,2),h=F(m),g=R(h,2),_=F(g),v=e=>{G(e,fa())},y=e=>{G(e,pa())};q(_,e=>{H(n)===`dark`?e(v):e(y,-1)}),k(g);var b=R(g,2),x=R(b,2),S=R(x,2);k(m);var ee=R(m,2),te=e=>{var n=ha(),r=I(n),i=F(r),a=R(i),o=L(a,!0);k(r);var s=R(r,2),c=e=>{var n=ma(),r=L(n,!0);z(()=>K(r,t.app.updateError)),G(e,n)};q(s,e=>{t.app.updateError&&e(c)}),z(()=>{K(i,`flypi ${t.update.version??``} ${t.update.ready?`is downloaded — it installs when nothing is running`:`is available`} `),a.disabled=t.app.updateInstalling,X(a,`title`,`Install ${t.update.version??``} now — the daemon restarts to run it`),K(o,t.app.updateInstalling?`installing…`:`install now`)}),U(`click`,a,()=>t.app.installUpdate()),G(e,n)};q(ee,e=>{t.update&&e(te)});var C=R(ee,2),ne=e=>{var n=ga(),r=L(n,!0);z(()=>K(r,`pi ${t.app.pi.version}${t.app.pi.pinned?` (pinned)`:``}${t.app.pi.bundled?` · installed tree holds ${t.app.pi.bundled}`:``}`)),G(e,n)};q(C,e=>{t.app.pi&&e(ne)});var w=R(C,2);J(w,21,()=>t.app.sessions,e=>e.path,(e,n)=>{var r=ya(),c=F(r),l=e=>{var t=_a();Y(t),z(e=>mi(t,e),[()=>i(H(n))]),gr(`blur`,t,e=>o(i(H(n)),e)),U(`keydown`,t,e=>{e.key===`Enter`?o(i(H(n)),e):e.key===`Escape`&&(e.currentTarget.value=i(H(n)))}),G(e,t)},u=e=>{var r=va(),i=L(r,!0);z(e=>K(i,e),[()=>a(H(n))]),U(`click`,r,()=>{t.app.openChat(),t.app.openSession(H(n).path)}),G(e,r)};q(c,e=>{H(n).path===t.app.sessionPath?e(l):e(u,-1)});var d=R(c,2);k(r),z(e=>X(d,`aria-label`,`Delete ${e??``}`),[()=>a(H(n))]),U(`click`,d,()=>s(H(n))),G(e,r)}),k(w),k(c),z(()=>{X(u,`src`,H(n)===`dark`?`/flypi-logo-dark.jpeg`:`/flypi-logo-light.jpeg`),X(g,`aria-label`,`Switch to ${H(n)===`dark`?`light`:`dark`} theme`),X(g,`title`,`Switch to ${H(n)===`dark`?`light`:`dark`} theme`),X(b,`aria-pressed`,t.app.view===`memory`),X(x,`aria-pressed`,t.app.view===`secrets`),X(S,`aria-pressed`,t.app.view===`settings`)}),U(`click`,h,()=>{t.app.openChat(),t.app.newSession()}),U(`click`,g,r),U(`click`,b,()=>t.app.toggleMemory()),U(`click`,x,()=>t.app.toggleSecrets()),U(`click`,S,()=>t.app.toggleSettings()),G(e,c),Ue()}_r([`click`,`keydown`]);var Sa=4194304;function Ca(e){return e.mimeType.startsWith(`image/`)}function wa(e){let t=new Uint8Array(e),n=``;for(let e=0;e<t.length;e+=32768)n+=String.fromCharCode(...t.subarray(e,e+32768));return btoa(n)}function Ta(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var Ea=Ta();function Da(e){Ea=e}var Oa={exec:()=>null};function ka(e){let t=[];return n=>{let r=Math.max(0,Math.min(3,n-1)),i=t[r];return i||(i=e(r),t[r]=i),i}}function Q(e,t=``){let n=typeof e==`string`?e:e.source,r={replace:(e,t)=>{let i=typeof t==`string`?t:t.source;return i=i.replace(ja.caret,`$1`),n=n.replace(e,i),r},getRegex:()=>new RegExp(n,t)};return r}var Aa=((e=``)=>{try{return!!RegExp(`(?<=1)(?<!1)`+e)}catch{return!1}})(),ja={codeRemoveIndent:/^(?: {1,4}| {0,3}\t)/gm,outputLinkReplace:/\\([\[\]])/g,indentCodeCompensation:/^(\s+)(?:```)/,beginningSpace:/^\s+/,endingHash:/#$/,startingSpaceChar:/^ /,endingSpaceChar:/ $/,nonSpaceChar:/[^ ]/,newLineCharGlobal:/\n/g,tabCharGlobal:/\t/g,multipleSpaceGlobal:/\s+/g,blankLine:/^[ \t]*$/,doubleBlankLine:/\n[ \t]*\n[ \t]*$/,blockquoteStart:/^ {0,3}>/,blockquoteSetextReplace:/\n {0,3}((?:=+|-+) *)(?=\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \t]?/gm,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\[[ xX]\] +\S/,listReplaceTask:/^\[[ xX]\] +/,listTaskCheckbox:/\[[ xX]\]/,anyLine:/\n.*\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\||\| *$/g,tableRowBlankLine:/\n[ \t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^<a /i,endATag:/^<\/a>/i,startPreScriptTag:/^<(pre|code|kbd|script)(\s|>)/i,endPreScriptTag:/^<\/(pre|code|kbd|script)(\s|>)/i,startAngleBracket:/^</,endAngleBracket:/>$/,pedanticHrefTitle:/^([^'"]*[^\s])\s+(['"])(.*)\2/,unicodeAlphaNumeric:/[\p{L}\p{N}]/u,escapeTest:/[&<>"']/,escapeReplace:/[&<>"']/g,escapeTestNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,escapeReplaceNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g,caret:/(^|[^\[])\^/g,percentDecode:/%25/g,findPipe:/\|/g,splitPipe:/ \|/,slashPipe:/\\\|/g,carriageReturn:/\r\n|\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\S*/,endingNewline:/\n$/,listItemRegex:e=>RegExp(`^( {0,3}${e})((?:[ ][^\\n]*)?(?:\\n|$))`),nextBulletRegex:ka(e=>RegExp(`^ {0,${e}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`)),hrRegex:ka(e=>RegExp(`^ {0,${e}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`)),fencesBeginRegex:ka(e=>RegExp(`^ {0,${e}}(?:\`\`\`|~~~)`)),headingBeginRegex:ka(e=>RegExp(`^ {0,${e}}#`)),htmlBeginRegex:ka(e=>RegExp(`^ {0,${e}}<(?:[a-z].*>|!--)`,`i`)),blockquoteBeginRegex:ka(e=>RegExp(`^ {0,${e}}>`))},Ma=/^(?:[ \t]*(?:\n|$))+/,Na=/^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/,Pa=/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,Fa=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,Ia=/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,La=/ {0,3}(?:[*+-]|\d{1,9}[.)])/,Ra=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,za=Q(Ra).replace(/bull/g,La).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}(?:\s|$)/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/\|table/g,``).getRegex(),Ba=Q(Ra).replace(/bull/g,La).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}(?:\s|$)/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/table/g,/ {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex(),Va=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table|[ \t]+\n)[^\n]+)*)/,Ha=/^[^\n]+/,Ua=/(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/,Wa=Q(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace(`label`,Ua).replace(`title`,/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),Ga=Q(/^(bull)([ \t][^\n]*?)?(?:\n|$)/).replace(/bull/g,La).getRegex(),Ka=`address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul`,qa=/<!--(?:-?>|[\s\S]*?(?:-->|$))/,Ja=Q(`^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n*|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>[^\\n]*\\n*|$)|<![A-Z][\\s\\S]*?(?:>[^\\n]*\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>[^\\n]*\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))`,`i`).replace(`comment`,qa).replace(`tag`,Ka).replace(`attribute`,/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),Ya=e=>Q(Va).replace(`hr`,Fa).replace(`heading`,` {0,3}#{1,6}(?:\\s|$)`).replace(`|lheading`,``).replace(`|table`,``).replace(`blockquote`,` {0,3}>`).replace(`fences`," {0,3}(?:`{3,}(?=[^`\\n]*(?:\\n|$))|~~~)[^\\n]*(?:\\n|$)").replace(`list`,e).replace(`html`,`</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)`).replace(`tag`,Ka).getRegex(),Xa=Ya(/ {0,3}(?:[*+-]|1[.)])[ \t]+[^ \t\n]/),Za=Ya(/ {0,3}(?:[*+-]|\d{1,9}[.)])(?:[ \t]|\n|$)/),Qa={blockquote:Q(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace(`paragraph`,Za).getRegex(),code:Na,def:Wa,fences:Pa,heading:Ia,hr:Fa,html:Ja,lheading:za,list:Ga,newline:Ma,paragraph:Xa,table:Oa,text:Ha},$a=Q(`^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)`).replace(`hr`,Fa).replace(`heading`,` {0,3}#{1,6}(?:\\s|$)`).replace(`blockquote`,` {0,3}>`).replace(`code`,`(?: {4}| {0,3} )[^\\n]`).replace(`fences`," {0,3}(?:`{3,}(?=[^`\\n]*(?:\\n|$))|~~~)[^\\n]*(?:\\n|$)").replace(`list`,` {0,3}(?:[*+-]|1[.)])[ \\t]`).replace(`html`,`</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)`).replace(`tag`,Ka).getRegex(),eo={...Qa,lheading:Ba,table:$a,paragraph:Q(Va).replace(`hr`,Fa).replace(`heading`,` {0,3}#{1,6}(?:\\s|$)`).replace(`|lheading`,``).replace(`table`,$a).replace(`blockquote`,` {0,3}>`).replace(`fences`," {0,3}(?:`{3,}(?=[^`\\n]*(?:\\n|$))|~~~)[^\\n]*(?:\\n|$)").replace(`list`,` {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]`).replace(`html`,`</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)`).replace(`tag`,Ka).getRegex()},to={...Qa,html:Q(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace(`comment`,qa).replace(/tag/g,`(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b`).getRegex(),def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:Oa,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:Q(Va).replace(`hr`,Fa).replace(`heading`,` *#{1,6} *[^
|
|
4
4
|
]`).replace(`lheading`,za).replace(`|table`,``).replace(`blockquote`,` {0,3}>`).replace(`|fences`,``).replace(`|list`,``).replace(`|html`,``).replace(`|tag`,``).getRegex()},no=/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,ro=/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,io=/^( {2,}|\\)\n(?!\s*$)/,ao=/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,oo=/[\p{P}\p{S}]/u,so=/[\s\p{P}\p{S}]/u,co=/[^\s\p{P}\p{S}]/u,lo=Q(/^((?![*_])punctSpace)/,`u`).replace(/punctSpace/g,so).getRegex(),uo=/[\p{Pi}\p{Ps}"']/u,fo=/(?!~)[\p{P}\p{S}]/u,po=/(?!~)[\s\p{P}\p{S}]/u,mo=/(?:[^\s\p{P}\p{S}]|~)/u,ho=Q(/link|precode-code|html/,`g`).replace(`link`,/\[(?:[^\[\]`]|(?<a>`+)[^`]+\k<a>(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace(`precode-`,Aa?"(?<!`)()":"(^^|[^`])").replace(`code`,/(?<b>`+)[^`]+\k<b>(?!`)/).replace(`html`,/<(?! )[^<>]*?>/).getRegex(),go=/^(?:\*+(?:((?!\*)punct)|([^\s*]))?)|^_+(?:((?!_)punct)|([^\s_]))?/,_o=Q(go,`u`).replace(/punct/g,oo).getRegex(),vo=Q(go,`u`).replace(/punct/g,fo).getRegex(),yo=Q(/^(?:\*+(?:((?!\*)(?!openQuote)punct)|([^\s*]))?)|^_+(?:((?!_)(?!openQuote)punct)|([^\s_]))?/,`u`).replace(/openQuote/g,uo).replace(/punct/g,oo).getRegex(),bo=`^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)`,xo=Q(bo,`gu`).replace(/notPunctSpace/g,co).replace(/punctSpace/g,so).replace(/punct/g,oo).getRegex(),So=Q(bo,`gu`).replace(/notPunctSpace/g,mo).replace(/punctSpace/g,po).replace(/punct/g,fo).getRegex(),Co=Q(`^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)[\\s](\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|(?:(?!\\*)punct|notPunctSpace)(\\*+)(?!\\*)(?=notPunctSpace)`,`gu`).replace(/notPunctSpace/g,co).replace(/punctSpace/g,so).replace(/punct/g,oo).getRegex(),wo=Q(`^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)`,`gu`).replace(/notPunctSpace/g,co).replace(/punctSpace/g,so).replace(/punct/g,oo).getRegex(),To=Q(`^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)[\\s](_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)|(?:(?!_)punct|notPunctSpace)(_+)(?!_)(?=notPunctSpace)`,`gu`).replace(/notPunctSpace/g,co).replace(/punctSpace/g,so).replace(/punct/g,oo).getRegex(),Eo=Q(/^~~?(?:((?!~)punct)|[^\s~])/,`u`).replace(/punct/g,oo).getRegex(),Do=Q(`^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)`,`gu`).replace(/notPunctSpace/g,co).replace(/punctSpace/g,so).replace(/punct/g,oo).getRegex(),Oo=Q(/\\(punct)/,`gu`).replace(/punct/g,oo).getRegex(),ko=Q(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace(`scheme`,/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace(`email`,/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),Ao=Q(qa).replace(`(?:-->|$)`,`-->`).getRegex(),jo=Q(`^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>`).replace(`comment`,Ao).replace(`attribute`,/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(),Mo=/(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\])|[^\[\]\\`])*?/,No=Q(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]+(?:\n[ \t]*)?|\n[ \t]*)(title))?\s*\)/).replace(`label`,Mo).replace(`href`,/<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]+|(?=\))/).replace(`title`,/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(),Po=Q(/^!?\[(label)\]\[(ref)\]/).replace(`label`,Mo).replace(`ref`,Ua).getRegex(),Fo=Q(/^!?\[(ref)\](?:\[\])?/).replace(`ref`,Ua).getRegex(),Io=Q(`reflink|nolink(?!\\()`,`g`).replace(`reflink`,Po).replace(`nolink`,Fo).getRegex(),Lo=/[hH][tT][tT][pP][sS]?|[fF][tT][pP]/,Ro={_backpedal:Oa,anyPunctuation:Oo,autolink:ko,blockSkip:ho,br:io,code:ro,del:Oa,delLDelim:Oa,delRDelim:Oa,emStrongLDelim:_o,emStrongRDelimAst:xo,emStrongRDelimUnd:wo,escape:no,link:No,nolink:Fo,punctuation:lo,reflink:Po,reflinkSearch:Io,tag:jo,text:ao,url:Oa},zo={...Ro,emStrongLDelim:yo,emStrongRDelimAst:Co,emStrongRDelimUnd:To,link:Q(/^!?\[(label)\]\((.*?)\)/).replace(`label`,Mo).getRegex(),reflink:Q(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace(`label`,Mo).getRegex()},Bo={...Ro,emStrongRDelimAst:So,emStrongLDelim:vo,delLDelim:Eo,delRDelim:Do,url:Q(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace(`protocol`,Lo).replace(`email`,/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/,text:Q(/^(`+|~+|[^`~])(?:(?=[`~])|(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|protocol:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/).replace(`protocol`,Lo).getRegex()},Vo={...Bo,br:Q(io).replace(`{2,}`,`*`).getRegex(),text:Q(Bo.text).replace(`\\b_`,`\\b_| {2,}\\n`).replace(/\{2,\}/g,`*`).getRegex()},Ho={normal:Qa,gfm:eo,pedantic:to},Uo={normal:Ro,gfm:Bo,breaks:Vo,pedantic:zo},Wo={"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`},Go=e=>Wo[e];function Ko(e,t){if(t){if(ja.escapeTest.test(e))return e.replace(ja.escapeReplace,Go)}else if(ja.escapeTestNoEncode.test(e))return e.replace(ja.escapeReplaceNoEncode,Go);return e}function qo(e){try{e=encodeURI(e).replace(ja.percentDecode,`%`)}catch{return null}return e}function Jo(e,t){let n=e.replace(ja.findPipe,(e,t,n)=>{let r=!1,i=t;for(;--i>=0&&n[i]===`\\`;)r=!r;return r?`|`:` |`}).split(ja.splitPipe),r=0;if(n[0].trim()||n.shift(),n.length>0&&!n.at(-1)?.trim()&&n.pop(),t){if(n.length>t)n.splice(t);else for(;n.length<t;)n.push(``)}for(;r<n.length;r++)n[r]=n[r].trim().replace(ja.slashPipe,`|`);return n}function Yo(e,t,n){let r=e.length;if(r===0)return``;let i=0;for(;i<r;){let a=e.charAt(r-i-1);if(a===t&&!n)i++;else if(a!==t&&n)i++;else break}return e.slice(0,r-i)}function Xo(e){let t=e.split(`
|
|
5
5
|
`),n=t.length-1;for(;n>=0&&ja.blankLine.test(t[n]);)n--;return t.length-n<=2?e:t.slice(0,n+1).join(`
|
|
6
6
|
`)}function Zo(e,t){if(e.indexOf(t[1])===-1)return-1;let n=0;for(let r=0;r<e.length;r++)if(e[r]===`\\`)r++;else if(e[r]===t[0])n++;else if(e[r]===t[1]&&(n--,n<0))return r;return n>0?-2:-1}function Qo(e,t=0){let n=t,r=``;for(let t of e)if(t===` `){let e=4-n%4;r+=` `.repeat(e),n+=e}else r+=t,n++;return r}function $o(e,t,n,r,i){let a=t.href,o=t.title||null,s=e[1].replace(i.other.outputLinkReplace,`$1`),c=e[0].charAt(0)===`!`;r.state.inLink=!0;let l=r.state.linkEmitted,u=r.state.inRawBlock;r.state.linkEmitted=!1;let d=r.inlineTokens(s),f=r.state.linkEmitted;if(r.state.linkEmitted=l,r.state.inLink=!1,!c){if(f){r.state.inRawBlock=u;return}r.state.linkEmitted=!0}return{type:c?`image`:`link`,raw:n,href:a,title:o,text:s,tokens:d}}function es(e,t,n){let r=e.match(n.other.indentCodeCompensation);if(r===null)return t;let i=r[1];return t.split(`
|
package/dist/ui/index.html
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
one of the two files and there is no script in this document to do anything else. -->
|
|
9
9
|
<link rel="icon" href="/flypi-logo-light.jpeg" media="(prefers-color-scheme: light)" />
|
|
10
10
|
<link rel="icon" href="/flypi-logo-dark.jpeg" media="(prefers-color-scheme: dark)" />
|
|
11
|
-
<script type="module" crossorigin src="/assets/index-
|
|
11
|
+
<script type="module" crossorigin src="/assets/index-DmMmjg_M.js"></script>
|
|
12
12
|
<link rel="stylesheet" crossorigin href="/assets/index-CBuNmrDT.css">
|
|
13
13
|
</head>
|
|
14
14
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@makerstufferupper/flypi",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Local multi-model agent tool with a browser UI and a personal knowledge wiki, built on the pi SDK.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"probe:boundary": "tsx scripts/turn-boundary.ts",
|
|
30
30
|
"start": "node scripts/start.mjs",
|
|
31
31
|
"dev": "vite",
|
|
32
|
+
"dev:container": "node scripts/dev-container.mjs",
|
|
32
33
|
"models:warm": "tsx scripts/warm-models.ts",
|
|
33
34
|
"build": "vite build",
|
|
34
35
|
"prepublishOnly": "npm run typecheck && npm test && npm run build",
|
|
@@ -44,7 +45,8 @@
|
|
|
44
45
|
"serve": "tsx scripts/serve.ts",
|
|
45
46
|
"daemon": "tsx scripts/serve-daemon.ts",
|
|
46
47
|
"flypi": "node scripts/flypi.mjs",
|
|
47
|
-
"release": "node scripts/release.mjs"
|
|
48
|
+
"release": "node scripts/release.mjs",
|
|
49
|
+
"release:check": "node scripts/release-check.mjs"
|
|
48
50
|
},
|
|
49
51
|
"dependencies": {
|
|
50
52
|
"@earendil-works/pi-coding-agent": "^1.4.0",
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* The local dev container, rebuilt from the working tree (docs/release.md, "Deploying something that is
|
|
4
|
+
* *not* released"). One command for what used to be four.
|
|
5
|
+
*
|
|
6
|
+
* npm run dev:container
|
|
7
|
+
*
|
|
8
|
+
* build → pack → `docker build` with `docker/Dockerfile.local` and the tarball's directory as the build
|
|
9
|
+
* context (the repo's `.dockerignore` excludes `*.tgz`, so the repo is never the context) → replace the
|
|
10
|
+
* `flypi` container with one off the new image → wait for `/healthz`.
|
|
11
|
+
*
|
|
12
|
+
* It removes the `flypi` container and the `flypi:local-*` images older than the one it built. It never
|
|
13
|
+
* removes the `flypi-data` volume: that holds the memory models (~933 MB), and re-downloading them is the
|
|
14
|
+
* slowest part of the next start — which is also why the healthcheck gets a 15-minute start period.
|
|
15
|
+
*
|
|
16
|
+
* No gates here; `npm run release:check` is the rehearsal that runs them. This is the fast path, and it
|
|
17
|
+
* touches only the names above: never a published image, never a container this script did not build.
|
|
18
|
+
*/
|
|
19
|
+
import { spawnSync } from "node:child_process";
|
|
20
|
+
import { copyFileSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
21
|
+
import { tmpdir } from "node:os";
|
|
22
|
+
import { join } from "node:path";
|
|
23
|
+
|
|
24
|
+
const NAME = "flypi";
|
|
25
|
+
const PORT = 8791;
|
|
26
|
+
const VOLUME = "flypi-data";
|
|
27
|
+
|
|
28
|
+
if (process.argv.includes("--help") || process.argv.includes("-h")) {
|
|
29
|
+
console.log(`flypi dev container — docs/release.md "Deploying something that is *not* released"
|
|
30
|
+
|
|
31
|
+
npm run dev:container build → pack → image → replace the ${NAME} container on 127.0.0.1:${PORT}
|
|
32
|
+
|
|
33
|
+
Removes: the ${NAME} container, and flypi:local-* images older than the one it just built.
|
|
34
|
+
Keeps: the ${VOLUME} volume — the memory models live there, and this script never deletes a volume.
|
|
35
|
+
Tags: flypi:local-<commit sha>, plus -dirty if the tree is not clean, because the package version
|
|
36
|
+
inside such an image collides with the published one.
|
|
37
|
+
Stages: build → pack → image → replace → serve → prune`);
|
|
38
|
+
process.exit(0);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const version = JSON.parse(readFileSync("package.json", "utf8")).version;
|
|
42
|
+
const die = (message) => {
|
|
43
|
+
console.error(`dev:container: ${message}`);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
};
|
|
46
|
+
function git(args) {
|
|
47
|
+
const result = spawnSync("git", args, { encoding: "utf8" });
|
|
48
|
+
if (result.status !== 0) die(`git ${args.join(" ")}: ${result.stderr.trim()}`);
|
|
49
|
+
return result.stdout.trim();
|
|
50
|
+
}
|
|
51
|
+
/** One step. It stops at the first failure: a half-replaced dev container is worse than an old one. */
|
|
52
|
+
function run(command, args, { quiet = false } = {}) {
|
|
53
|
+
const result = spawnSync(command, args, { encoding: "utf8" });
|
|
54
|
+
if (result.status !== 0) {
|
|
55
|
+
die(`${command} ${args.join(" ")} exited ${result.status}${result.stderr ? `: ${result.stderr.trim().split("\n").slice(-3).join(" ")}` : ""}`);
|
|
56
|
+
}
|
|
57
|
+
if (!quiet && result.stdout) process.stdout.write(result.stdout);
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
const step = (what) => console.log(`\n${what}`);
|
|
61
|
+
|
|
62
|
+
const sha = git(["rev-parse", "--short", "HEAD"]);
|
|
63
|
+
const tag = `flypi:local-${sha}${git(["status", "--porcelain"]) ? "-dirty" : ""}`;
|
|
64
|
+
const packDir = mkdtempSync(join(tmpdir(), "flypi-dev-"));
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
step("build — dist/ui, which the tarball ships");
|
|
68
|
+
run("npm", ["run", "build"]);
|
|
69
|
+
|
|
70
|
+
step("pack — the same artifact npm would publish, installed by the image");
|
|
71
|
+
run("npm", ["pack", "--pack-destination", packDir]);
|
|
72
|
+
const tgz = `makerstufferupper-flypi-${version}.tgz`;
|
|
73
|
+
copyFileSync("docker/Dockerfile.local", join(packDir, "Dockerfile"));
|
|
74
|
+
|
|
75
|
+
step(`image — ${tag} from ${tgz}`);
|
|
76
|
+
run("docker", ["build", "-q", "--build-arg", `FLYPI_TGZ=${tgz}`, "-t", tag, packDir]);
|
|
77
|
+
|
|
78
|
+
step(`replace — container ${NAME} on 127.0.0.1:${PORT}, volume ${VOLUME} kept`);
|
|
79
|
+
// `rm -f` on a name that is not there exits 1; that is the normal first run, not a failure.
|
|
80
|
+
spawnSync("docker", ["rm", "-f", NAME], { encoding: "utf8" });
|
|
81
|
+
run("docker", [
|
|
82
|
+
"run",
|
|
83
|
+
"-d",
|
|
84
|
+
"--name",
|
|
85
|
+
NAME,
|
|
86
|
+
"-p",
|
|
87
|
+
`127.0.0.1:${PORT}:${PORT}`,
|
|
88
|
+
"-v",
|
|
89
|
+
`${VOLUME}:/data`,
|
|
90
|
+
"-e",
|
|
91
|
+
"FLYPI_ROOT=/data",
|
|
92
|
+
// The image's own CMD downloads the memory models on a fresh state root, so "unhealthy" for the
|
|
93
|
+
// first quarter hour is the download, not a broken build.
|
|
94
|
+
"--health-cmd",
|
|
95
|
+
`node -e "fetch('http://127.0.0.1:${PORT}/healthz').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"`,
|
|
96
|
+
"--health-interval",
|
|
97
|
+
"30s",
|
|
98
|
+
"--health-timeout",
|
|
99
|
+
"5s",
|
|
100
|
+
"--health-start-period",
|
|
101
|
+
"900s",
|
|
102
|
+
"--health-retries",
|
|
103
|
+
"3",
|
|
104
|
+
tag,
|
|
105
|
+
]);
|
|
106
|
+
|
|
107
|
+
step(`serve — waiting on http://127.0.0.1:${PORT}/healthz`);
|
|
108
|
+
const deadline = Date.now() + 180_000;
|
|
109
|
+
let body = null;
|
|
110
|
+
while (Date.now() < deadline && !body) {
|
|
111
|
+
try {
|
|
112
|
+
const response = await fetch(`http://127.0.0.1:${PORT}/healthz`);
|
|
113
|
+
if (response.ok) body = await response.json();
|
|
114
|
+
} catch {}
|
|
115
|
+
if (!body) await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
116
|
+
}
|
|
117
|
+
if (!body) die(`${NAME} never answered /healthz — docker logs ${NAME}`);
|
|
118
|
+
console.log(` ok flypi ${body.version} · pi ${body.pi?.version ?? "?"} · ${tag}`);
|
|
119
|
+
|
|
120
|
+
step("prune — the flypi:local-* images this replaces");
|
|
121
|
+
const stale = run("docker", ["image", "ls", "flypi:local-*", "--format", "{{.Repository}}:{{.Tag}}"], { quiet: true }).stdout
|
|
122
|
+
.split("\n")
|
|
123
|
+
.map((image) => image.trim())
|
|
124
|
+
.filter((image) => image && image !== tag);
|
|
125
|
+
for (const image of stale) run("docker", ["rmi", image], { quiet: true });
|
|
126
|
+
console.log(stale.length ? ` removed ${stale.join(", ")}` : " nothing older to remove");
|
|
127
|
+
|
|
128
|
+
console.log(`\n${NAME} is on http://127.0.0.1:${PORT} — docker logs -f ${NAME} to watch it`);
|
|
129
|
+
} finally {
|
|
130
|
+
rmSync(packDir, { recursive: true, force: true });
|
|
131
|
+
}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* The release rehearsal (docs/release-checks.md). It runs the checks that have to pass before a version goes
|
|
4
|
+
* to the registry, and with `--published` the ones that prove what landed there is what was built.
|
|
5
|
+
*
|
|
6
|
+
* node scripts/release-check.mjs # gates → pack → npm-install → image
|
|
7
|
+
* node scripts/release-check.mjs --published # registry + pushed image + run the published image
|
|
8
|
+
* node scripts/release-check.mjs --skip-gates # the docker half only
|
|
9
|
+
* node scripts/release-check.mjs --keep # leave the containers and volumes for a look
|
|
10
|
+
*
|
|
11
|
+
* It never publishes, pushes an image, or touches a container it did not create: everything it makes is named
|
|
12
|
+
* `flypi-check-*` on ports 8792/8793, so the serving `flypi` container on 8791 and its `flypi-data` volume are
|
|
13
|
+
* out of reach. Exit code is the number of failed checks.
|
|
14
|
+
*/
|
|
15
|
+
import { spawnSync } from "node:child_process";
|
|
16
|
+
import { copyFileSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
17
|
+
import { tmpdir } from "node:os";
|
|
18
|
+
import { join } from "node:path";
|
|
19
|
+
|
|
20
|
+
const argv = process.argv.slice(2);
|
|
21
|
+
const has = (flag) => argv.includes(flag);
|
|
22
|
+
const valueOf = (flag) => {
|
|
23
|
+
const at = argv.indexOf(flag);
|
|
24
|
+
return at === -1 ? undefined : argv[at + 1];
|
|
25
|
+
};
|
|
26
|
+
const version = valueOf("--version") ?? JSON.parse(readFileSync("package.json", "utf8")).version;
|
|
27
|
+
|
|
28
|
+
if (has("--help") || has("-h")) {
|
|
29
|
+
console.log(`flypi release rehearsal — docs/release-checks.md
|
|
30
|
+
|
|
31
|
+
npm run release:check gates → pack → npm-install → image
|
|
32
|
+
npm run release:check -- --published the registry and the pushed image, after the publish
|
|
33
|
+
npm run release:check -- --skip-gates the docker half only
|
|
34
|
+
npm run release:check -- --keep leave the containers and volumes for a look
|
|
35
|
+
npm run release:check -- --version <v> check a version other than package.json's
|
|
36
|
+
npm run release:check -- --help this list (-h is the same)
|
|
37
|
+
|
|
38
|
+
It never publishes or pushes, and only touches containers named flypi-check-*.`);
|
|
39
|
+
process.exit(0);
|
|
40
|
+
}
|
|
41
|
+
const IMAGE = "makerstufferupper/flypi";
|
|
42
|
+
const TARBALL_URL = `https://registry.npmjs.org/@makerstufferupper/flypi/-/flypi-${version}.tgz`;
|
|
43
|
+
|
|
44
|
+
let failures = 0;
|
|
45
|
+
const ok = (name, detail) => console.log(` ok ${name}${detail ? ` — ${detail}` : ""}`);
|
|
46
|
+
const bad = (name, detail) => {
|
|
47
|
+
failures++;
|
|
48
|
+
console.log(` FAIL ${name}${detail ? ` — ${detail}` : ""}`);
|
|
49
|
+
};
|
|
50
|
+
/** One check: run something, say whether it worked, keep going either way. */
|
|
51
|
+
function check(name, command, args, options = {}) {
|
|
52
|
+
const result = spawnSync(command, args, { encoding: "utf8", ...options });
|
|
53
|
+
if (result.status === 0) {
|
|
54
|
+
ok(name, options.show && result.stdout ? result.stdout.trim().split("\n").at(-1) : undefined);
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
bad(name, `${command} ${args.join(" ")} exited ${result.status}${result.stderr ? `: ${result.stderr.trim().split("\n")[0]}` : ""}`);
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const packDir = mkdtempSync(join(tmpdir(), "flypi-release-"));
|
|
62
|
+
const created = { containers: [], volumes: [], images: [] };
|
|
63
|
+
|
|
64
|
+
function docker(args, options = {}) {
|
|
65
|
+
return spawnSync("docker", args, { encoding: "utf8", ...options });
|
|
66
|
+
}
|
|
67
|
+
/** A container of our own, on a port and a volume nothing else is using. */
|
|
68
|
+
function freshContainer(name, image, port, volume, command) {
|
|
69
|
+
docker(["rm", "-f", name]);
|
|
70
|
+
docker(["volume", "rm", volume]);
|
|
71
|
+
created.containers.push(name);
|
|
72
|
+
created.volumes.push(volume);
|
|
73
|
+
const run = docker(["run", "-d", "--name", name, "-p", `127.0.0.1:${port}:${port}`, "-v", `${volume}:/data`, "-e", "FLYPI_ROOT=/data", image, ...command]);
|
|
74
|
+
return run.status === 0 ? name : (bad(`docker run ${image}`, run.stderr.trim().split("\n")[0]), null);
|
|
75
|
+
}
|
|
76
|
+
/** Poll /healthz — the first start of a fresh state root is not instant. */
|
|
77
|
+
async function health(port, seconds = 180) {
|
|
78
|
+
const deadline = Date.now() + seconds * 1000;
|
|
79
|
+
while (Date.now() < deadline) {
|
|
80
|
+
try {
|
|
81
|
+
const response = await fetch(`http://127.0.0.1:${port}/healthz`);
|
|
82
|
+
if (response.ok) return await response.json();
|
|
83
|
+
} catch {}
|
|
84
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
/** The three things every serving flypi owes: its own version, the pi it loaded, and a page. */
|
|
89
|
+
async function assertServing(name, port, expectVersion) {
|
|
90
|
+
const body = await health(port);
|
|
91
|
+
if (!body) return bad(`${name}: /healthz never answered`, `port ${port}`);
|
|
92
|
+
body.version === expectVersion
|
|
93
|
+
? ok(`${name}: /healthz reports flypi ${body.version}`)
|
|
94
|
+
: bad(`${name}: /healthz version`, `expected ${expectVersion}, got ${body.version}`);
|
|
95
|
+
body.pi?.version
|
|
96
|
+
? ok(`${name}: it loaded pi ${body.pi.version}`, body.pi.pinned ? "pinned" : "not pinned")
|
|
97
|
+
: bad(`${name}: /healthz names no pi`, "Phase 8.1 — the loaded version must be reported");
|
|
98
|
+
const page = spawnSync("curl", ["-s", "-o", "/dev/null", "-w", "%{http_code}", `http://127.0.0.1:${port}/`], { encoding: "utf8" });
|
|
99
|
+
page.stdout === "200" ? ok(`${name}: GET / is 200`) : bad(`${name}: GET /`, `got ${page.stdout || "no answer"}`);
|
|
100
|
+
return body;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The agent has a bash tool in here, so the tools a turn reaches for have to be present *and* working: git over
|
|
104
|
+
* https, git-lfs, curl, wget. Slim has none of them, and a git-lfs binary without its filters registered still
|
|
105
|
+
* checks in an LFS file's contents rather than a pointer — so this tracks one and reads the blob back out.
|
|
106
|
+
*/
|
|
107
|
+
function hasTools(name) {
|
|
108
|
+
const probe = docker([
|
|
109
|
+
"exec",
|
|
110
|
+
name,
|
|
111
|
+
"sh",
|
|
112
|
+
"-c",
|
|
113
|
+
"git --version >/dev/null && curl --version >/dev/null && wget --version >/dev/null" +
|
|
114
|
+
" && cd /tmp && rm -rf lfs-check && git init -q lfs-check && cd lfs-check && git lfs track '*.bin' >/dev/null" +
|
|
115
|
+
" && echo hello > a.bin && git -c user.email=flypi@example.com -c user.name=flypi add a.bin && git cat-file -p :a.bin",
|
|
116
|
+
]);
|
|
117
|
+
/git-lfs\.github\.com\/spec\/v1/.test(probe.stdout ?? "")
|
|
118
|
+
? ok(`${name}: it has git + git-lfs, curl and wget`)
|
|
119
|
+
: bad(`${name}: git + git-lfs, curl and wget`, `exit ${probe.status}: ${(probe.stderr || probe.stdout || "").trim().split("\n")[0]}`);
|
|
120
|
+
}
|
|
121
|
+
function cleanup() {
|
|
122
|
+
if (has("--keep")) return console.log(`\nkept: ${created.containers.join(", ")} · volumes ${created.volumes.join(", ")} · ${packDir}`);
|
|
123
|
+
for (const name of created.containers) docker(["rm", "-f", name]);
|
|
124
|
+
for (const volume of created.volumes) docker(["volume", "rm", volume]);
|
|
125
|
+
for (const image of created.images) docker(["rmi", image]);
|
|
126
|
+
rmSync(packDir, { recursive: true, force: true });
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ── stages ────────────────────────────────────────────────────────────────────────────────────────────────
|
|
130
|
+
|
|
131
|
+
function gates() {
|
|
132
|
+
console.log(`gates — the suite this version would be published with`);
|
|
133
|
+
check("tsc --noEmit", "npm", ["run", "typecheck"]);
|
|
134
|
+
check("npm test", "npm", ["test"]);
|
|
135
|
+
check("npm run smoke", "npm", ["run", "smoke"]);
|
|
136
|
+
check("npm run probe:pi", "npm", ["run", "probe:pi"]);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function pack() {
|
|
140
|
+
console.log(`\npack — the artifact, before anything installs it`);
|
|
141
|
+
check("npm run build (dist/ui)", "npm", ["run", "build"]);
|
|
142
|
+
check(`npm pack`, "npm", ["pack", "--pack-destination", packDir]);
|
|
143
|
+
const tgz = `makerstufferupper-flypi-${version}.tgz`;
|
|
144
|
+
const packed = spawnSync("tar", ["xzOf", join(packDir, tgz), "package/package.json"], { encoding: "utf8" });
|
|
145
|
+
if (packed.status !== 0) return bad(`read ${tgz}`, "npm pack produced nothing readable");
|
|
146
|
+
const pkg = JSON.parse(packed.stdout);
|
|
147
|
+
pkg.version === version ? ok(`tarball version ${pkg.version}`) : bad("tarball version", `package.json says ${pkg.version}`);
|
|
148
|
+
const self = Object.keys(pkg.dependencies).filter((d) => d.includes("makerstufferupper"));
|
|
149
|
+
self.length ? bad("no self-dependency", `${self.join(", ")} — flypi must not depend on flypi`) : ok("no self-dependency in dependencies");
|
|
150
|
+
const listed = spawnSync("tar", ["tzf", join(packDir, tgz)], { encoding: "utf8" }).stdout.split("\n");
|
|
151
|
+
for (const file of ["dist/ui/index.html", "bin/flypi.mjs", "src/daemon/pi.ts"]) {
|
|
152
|
+
listed.includes(`package/${file}`) ? ok(`ships ${file}`) : bad(`ships ${file}`, "missing from the tarball — check package.json `files`");
|
|
153
|
+
}
|
|
154
|
+
const stray = listed.filter((f) => /package\/(\.scratch|\.flypi|node_modules|coverage)\//.test(f));
|
|
155
|
+
stray.length ? bad("no stray files", stray.slice(0, 3).join(", ")) : ok("nothing stray (.scratch, .flypi, node_modules, coverage)");
|
|
156
|
+
return tgz;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async function npmInstall(tgz) {
|
|
160
|
+
console.log(`\nnpm-install — the tarball in a clean container, the way \`npm install -g\` does it`);
|
|
161
|
+
const name = "flypi-check-npm";
|
|
162
|
+
const container = freshContainer(name, "node:24-slim", 8792, "flypi-check-npm-data", ["sleep", "7200"]);
|
|
163
|
+
if (!container) return;
|
|
164
|
+
if (docker(["cp", join(packDir, tgz), `${name}:/tmp/flypi.tgz`]).status !== 0) return bad("docker cp the tarball");
|
|
165
|
+
check("npm i -g /tmp/flypi.tgz", "docker", ["exec", name, "npm", "i", "-g", "--no-audit", "--no-fund", "/tmp/flypi.tgz"]);
|
|
166
|
+
const installed = docker(["exec", name, "node", "-e", `console.log(require("/usr/local/lib/node_modules/@makerstufferupper/flypi/package.json").version)`]);
|
|
167
|
+
installed.stdout?.trim() === version ? ok(`installed package reports ${version}`) : bad("installed package version", installed.stdout?.trim() || installed.stderr?.trim());
|
|
168
|
+
docker(["exec", "-d", name, "flypi", "start", "--foreground", "--port", "8792", "--host", "0.0.0.0", "--embeddings", "none", "--judge", "none"]);
|
|
169
|
+
await assertServing(name, 8792, version);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
async function image(tgz) {
|
|
173
|
+
console.log(`\nimage — the published image's runtime shape, built from the same tarball`);
|
|
174
|
+
copyFileSync("docker/Dockerfile.local", join(packDir, "Dockerfile"));
|
|
175
|
+
const tag = `flypi-check:${version}`;
|
|
176
|
+
const built = docker(["build", "-q", "--build-arg", `FLYPI_TGZ=${tgz}`, "-t", tag, packDir]);
|
|
177
|
+
if (built.status !== 0) return bad("docker build", built.stderr.trim().split("\n").slice(-3).join(" "));
|
|
178
|
+
created.images.push(tag);
|
|
179
|
+
ok(`docker build ${tag}`);
|
|
180
|
+
const name = "flypi-check-image";
|
|
181
|
+
// Keyword-only memory: the image's own CMD would fetch ~900 MB of models into a volume that is deleted after.
|
|
182
|
+
const container = freshContainer(name, tag, 8793, "flypi-check-image-data", ["flypi", "start", "--foreground", "--port", "8793", "--host", "0.0.0.0", "--embeddings", "none", "--judge", "none"]);
|
|
183
|
+
if (!container) return;
|
|
184
|
+
await assertServing(name, 8793, version);
|
|
185
|
+
// The container must refuse to move pi in one sentence, not a stack trace (docs/pi-upgrades.md 8.3).
|
|
186
|
+
const refused = docker(["exec", name, "flypi", "pi", "use", "0.0.0"]);
|
|
187
|
+
/std|not writable|not the npm global/.test(`${refused.stdout}${refused.stderr}`) && refused.status !== 0
|
|
188
|
+
? ok("flypi pi use refuses in a container, in one sentence")
|
|
189
|
+
: bad("flypi pi use in a container", `exit ${refused.status}: ${(refused.stderr || refused.stdout).trim().split("\n")[0]}`);
|
|
190
|
+
const state = docker(["exec", name, "sh", "-c", "ls /data/.flypi/pi 2>&1"]);
|
|
191
|
+
/state/.test(state.stdout) ? bad("a refused switch leaves no pin behind", state.stdout.trim()) : ok("a refused switch left nothing behind");
|
|
192
|
+
hasTools(name);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
async function published() {
|
|
196
|
+
console.log(`\npublished — that ${version} is really in the registry, and the image installs it`);
|
|
197
|
+
// The metadata and the tarball propagate at different speeds: `npm view` can answer minutes before the
|
|
198
|
+
// tarball URL stops 404-ing, which is what kills a pinned image build. Poll the URL, not the tag.
|
|
199
|
+
let code = "000";
|
|
200
|
+
for (let i = 0; i < 30 && code !== "200"; i++) {
|
|
201
|
+
code = spawnSync("curl", ["-s", "-o", "/dev/null", "-w", "%{http_code}", TARBALL_URL], { encoding: "utf8" }).stdout;
|
|
202
|
+
if (code !== "200") await new Promise((resolve) => setTimeout(resolve, 10000));
|
|
203
|
+
}
|
|
204
|
+
code === "200" ? ok("the registry serves the tarball") : bad("the registry serves the tarball", `${code} after 5 min — ${TARBALL_URL}`);
|
|
205
|
+
const latest = spawnSync("npm", ["view", "@makerstufferupper/flypi", "version"], { encoding: "utf8" });
|
|
206
|
+
latest.stdout?.trim() === version ? ok(`npm's latest is ${version}`) : bad("npm's latest", `the registry answers ${latest.stdout?.trim() || "nothing"}`);
|
|
207
|
+
|
|
208
|
+
const inspect = docker(["buildx", "imagetools", "inspect", `${IMAGE}:${version}`]);
|
|
209
|
+
const platforms = ["linux/amd64", "linux/arm64"].filter((p) => inspect.stdout?.includes(p));
|
|
210
|
+
platforms.length === 2 ? ok("the pushed image carries both platforms") : bad("the pushed image's platforms", platforms.join(", ") || "the manifest was not readable");
|
|
211
|
+
|
|
212
|
+
const name = "flypi-check-published";
|
|
213
|
+
const container = freshContainer(name, `${IMAGE}:${version}`, 8793, "flypi-check-published-data", ["flypi", "start", "--foreground", "--port", "8793", "--host", "0.0.0.0", "--embeddings", "none", "--judge", "none"]);
|
|
214
|
+
if (!container) return;
|
|
215
|
+
await assertServing(name, 8793, version);
|
|
216
|
+
// A stale push is exactly what this stage exists to catch, and the tools come from the Dockerfile — so the
|
|
217
|
+
// image Docker Hub serves, not just the one built here, has to carry them.
|
|
218
|
+
hasTools(name);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// ── run ───────────────────────────────────────────────────────────────────────────────────────────────────
|
|
222
|
+
|
|
223
|
+
try {
|
|
224
|
+
if (has("--published")) {
|
|
225
|
+
await published();
|
|
226
|
+
} else {
|
|
227
|
+
if (!has("--skip-gates")) gates();
|
|
228
|
+
const tgz = pack();
|
|
229
|
+
if (tgz) {
|
|
230
|
+
await npmInstall(tgz);
|
|
231
|
+
await image(tgz);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
} finally {
|
|
235
|
+
cleanup();
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
console.log(failures ? `\n${failures} check(s) failed` : `\nall checks passed for ${version}`);
|
|
239
|
+
process.exit(failures ? 1 : 0);
|
package/src/server/index.ts
CHANGED
|
@@ -183,6 +183,16 @@ export async function startFlypiServer(options: FlypiServerOptions): Promise<Fly
|
|
|
183
183
|
|
|
184
184
|
/** Start (or keep) this socket's subscription to a conversation; `afterSeq` replays what it missed. */
|
|
185
185
|
const subscribe = (conversationId: string, afterSeq?: number) => {
|
|
186
|
+
// A page holds one conversation, so a socket follows one conversation. Everything it watched
|
|
187
|
+
// before is detached here: a turn started in the chat you left would otherwise keep streaming,
|
|
188
|
+
// and its frames would be folded into the transcript of the chat that replaced it. It also keeps
|
|
189
|
+
// the abandoned conversation attached forever, so `evictIdle` never sees it as idle.
|
|
190
|
+
for (const [watched, previous] of [...subscriptions]) {
|
|
191
|
+
if (watched === conversationId) continue;
|
|
192
|
+
previous.detach();
|
|
193
|
+
previous.detachUi();
|
|
194
|
+
subscriptions.delete(watched);
|
|
195
|
+
}
|
|
186
196
|
let subscription = subscriptions.get(conversationId);
|
|
187
197
|
if (!subscription) {
|
|
188
198
|
const state: Subscription = { lastSent: 0, detach: () => {}, detachUi: () => {} };
|
|
@@ -222,10 +232,10 @@ export async function startFlypiServer(options: FlypiServerOptions): Promise<Fly
|
|
|
222
232
|
const command = parsed.command;
|
|
223
233
|
const requestId = command.requestId;
|
|
224
234
|
const conversationId = "conversationId" in command ? command.conversationId : undefined;
|
|
225
|
-
const onError = (error: Error) => {
|
|
235
|
+
const onError = (error: Error & { code?: string }) => {
|
|
226
236
|
// What the page was told, in the dev log: an error frame alone leaves a stuck UI inexplicable.
|
|
227
237
|
console.error(`flypi: ${command.type} failed: ${error.message}${conversationId ? ` (conversation ${conversationId})` : ""}`);
|
|
228
|
-
fail(error.message, { requestId, conversationId });
|
|
238
|
+
fail(error.message, { ...(error.code ? { code: error.code } : {}), requestId, conversationId });
|
|
229
239
|
};
|
|
230
240
|
|
|
231
241
|
try {
|
|
@@ -126,11 +126,33 @@ export class SessionRegistry {
|
|
|
126
126
|
);
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
/**
|
|
129
|
+
/**
|
|
130
|
+
* Open an existing session for a client: the conversation already answering it when there is one, and
|
|
131
|
+
* otherwise this conversation moved onto it — or a new one, if this conversation is mid-turn.
|
|
132
|
+
*/
|
|
130
133
|
async switchSession(conversationId: string, sessionPath: string): Promise<Conversation> {
|
|
131
134
|
const conversation = this.get(conversationId);
|
|
132
135
|
const target = this.sessionFileIn(sessionPath);
|
|
136
|
+
// Already answering it: opening the file a second time would put a second writer on it, so the
|
|
137
|
+
// conversation the page is already on stays where it is. An idle one is reopened as asked — that is
|
|
138
|
+
// how a client reloads a session's history from disk.
|
|
139
|
+
if (conversation.session.sessionFile === target && !conversation.session.isIdle) return conversation;
|
|
140
|
+
// A session another conversation is already answering **is** that conversation, not a copy of it. Opening
|
|
141
|
+
// the file a second time would put a second writer on it and freeze the transcript at the moment of the
|
|
142
|
+
// switch, so the answer on its way would never reach the page that just asked for that session.
|
|
143
|
+
const live = [...this.conversations.values()].find((other) => other.id !== conversationId && other.session.sessionFile === target);
|
|
144
|
+
if (live) return live;
|
|
145
|
+
// Rebinding disposes the session this conversation is answering in, and a turn still running would be cut
|
|
146
|
+
// short: its answer would reach neither the page nor the session file. So a session with no conversation
|
|
147
|
+
// of its own is opened as one, and this conversation is left alone to finish (it stays in the map, and
|
|
148
|
+
// switching back to it returns it from the lookup above, log and all).
|
|
149
|
+
if (!conversation.session.isIdle) return this.bind(SessionManager.open(target, this.paths.sessionsDir));
|
|
133
150
|
this.teardown(conversation);
|
|
151
|
+
// The conversation lives on with a new session, so it is not disposed any more. Without this the
|
|
152
|
+
// exactly-once guard below stays set and the *new* session is never unsubscribed or disposed — it
|
|
153
|
+
// keeps streaming into this conversation's log (and its listeners) after the page moved on, keeps
|
|
154
|
+
// the conversation unevictable, and writes back any session file it is deleted out from under.
|
|
155
|
+
conversation.disposed = false;
|
|
134
156
|
conversation.session = await this.createSession({
|
|
135
157
|
sessionManager: SessionManager.open(target, this.paths.sessionsDir),
|
|
136
158
|
conversationId,
|
|
@@ -171,7 +193,9 @@ export class SessionRegistry {
|
|
|
171
193
|
|
|
172
194
|
get(conversationId: string): Conversation {
|
|
173
195
|
const conversation = this.conversations.get(conversationId);
|
|
174
|
-
|
|
196
|
+
// The code is what a page acts on: it holds a conversation id across reconnects, and after a restart
|
|
197
|
+
// every command it sends names a conversation this process never had (ui/lib/app-state.svelte.ts).
|
|
198
|
+
if (!conversation) throw Object.assign(new Error(`unknown conversation ${conversationId}`), { code: "unknownConversation" });
|
|
175
199
|
return conversation;
|
|
176
200
|
}
|
|
177
201
|
|