@openchambery/web 1.19.7-beta.25 → 1.19.7-beta.27
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/dist/assets/{AgentAvatar-DI2zs2WH.js → AgentAvatar-CX0a1rKE.js} +1 -1
- package/dist/assets/AssistantView-9etSTPqw.js +2 -0
- package/dist/assets/{DiagramView-DRIEYUNV.js → DiagramView-koXYlpfQ.js} +1 -1
- package/dist/assets/{FadeInOnReveal-BWJcUp5P.js → FadeInOnReveal-CK4asqVR.js} +1 -1
- package/dist/assets/{Icon-4My8YZwt.js → Icon-BYM02QyU.js} +1 -1
- package/dist/assets/{MarkdownLoadingSkeleton-Vezjvk9B.js → MarkdownLoadingSkeleton-DWs4Jg7b.js} +1 -1
- package/dist/assets/{MarkdownRenderer-SLKCbxwI.js → MarkdownRenderer-BCVKHQSh.js} +2 -2
- package/dist/assets/{MarkdownRendererImpl-D9kcSswH.js → MarkdownRendererImpl-S3YOBsZc.js} +1 -1
- package/dist/assets/MarkstreamRendererImpl-DMJCTUAT.js +1 -0
- package/dist/assets/{MobileDetailNavigation-C5lZVW1v.js → MobileDetailNavigation-Bm5gj-LJ.js} +1 -1
- package/dist/assets/MobileShareBridge-BUSF-056.js +4 -0
- package/dist/assets/{MobileSurface-CtMp7rI8.js → MobileSurface-C95K6asy.js} +1 -1
- package/dist/assets/{MultiRunWindow-6-E944pd.js → MultiRunWindow-By8SN8e2.js} +1 -1
- package/dist/assets/{OnboardingScreen-BNEtPmvw.js → OnboardingScreen-C3-wzeSX.js} +1 -1
- package/dist/assets/{OverlayScrollbar-BZB21Yp_.js → OverlayScrollbar-KUpvYHdv.js} +1 -1
- package/dist/assets/{SettingsView-Cy_D8K8y.js → SettingsView-VL1AQnH4.js} +5 -5
- package/dist/assets/{SettingsWindow-BA9QjT8d.js → SettingsWindow-C54OTcdE.js} +1 -1
- package/dist/assets/{TerminalView-izdQm4WZ.js → TerminalView-DTUxTQA6.js} +1 -1
- package/dist/assets/{ToolOutputDialog-CXbfvZ3M.js → ToolOutputDialog-BdDYanZA.js} +1 -1
- package/dist/assets/{appThemeRegistry-Eq3WEH-h.js → appThemeRegistry-Bre7MHDa.js} +1 -1
- package/dist/assets/{button-Or0daT9o.js → button-C0cth9tl.js} +1 -1
- package/dist/assets/{clipboard-BXxLshVq.js → clipboard-DJ4nQEuY.js} +1 -1
- package/dist/assets/{collapsible-C-kzSGkq.js → collapsible-DFT9cE80.js} +1 -1
- package/dist/assets/{context-menu-Dpjla5p4.js → context-menu-CAp74NfV.js} +1 -1
- package/dist/assets/desktopHosts-CWxex1c3.js +1 -0
- package/dist/assets/{desktopRelayRestore-BaKjk1kQ.js → desktopRelayRestore-9EbBYQ9s.js} +1 -1
- package/dist/assets/{diagram-D0mT3mo1.js → diagram-BryzMuta.js} +1 -1
- package/dist/assets/{dialog-BkhHBTd4.js → dialog-CgbV5ljg.js} +1 -1
- package/dist/assets/{fileQueries-DFY6Kiy1.js → fileQueries-BY-9OWzp.js} +1 -1
- package/dist/assets/{fileReferenceActions-Di_DoDex.js → fileReferenceActions-BJJtX_S5.js} +1 -1
- package/dist/assets/{gitApi-SIviXHpZ.js → gitApi-CUGT34gW.js} +1 -1
- package/dist/assets/{input-BUsGnzwe.js → input-DFLpqjGR.js} +1 -1
- package/dist/assets/{insertionBoundaries-q72MeGLB.js → insertionBoundaries-BvRP83JP.js} +1 -1
- package/dist/assets/{main-Ct6J19qT.js → main-CFs9ZjGz.js} +2 -2
- package/dist/assets/{main-VXSSCHDb.js → main-Dkmkv4Lp.js} +11 -11
- package/dist/assets/{markdownTheme-CVS01wHf.js → markdownTheme-CzZm3riB.js} +1 -1
- package/dist/assets/{miniChat-D_SEWy1a.js → miniChat-C590b4rQ.js} +2 -2
- package/dist/assets/{mobile-Cx032aiN.js → mobile-CF2VLQTo.js} +2 -2
- package/dist/assets/{multirun-BKGQQeek.js → multirun-Cs3rEyOv.js} +1 -1
- package/dist/assets/{outsideFileGrants-BB4GPvCq.js → outsideFileGrants-DnplRxr-.js} +1 -1
- package/dist/assets/persistence-DdUac14I.js +3 -0
- package/dist/assets/platform-B4KKLnZ5.js +2 -0
- package/dist/assets/{projectMeta-yRCsEkJK.js → projectMeta-DaXQ-jtY.js} +1 -1
- package/dist/assets/{renderElectronMiniChatApp-BnDRaSFx.js → renderElectronMiniChatApp-DUdwGn52.js} +2 -2
- package/dist/assets/{renderMobileApp-BAGhZKMW.js → renderMobileApp-B0czsaKl.js} +7 -7
- package/dist/assets/{runtimeConfig-D5H05aTj.js → runtimeConfig-9_0HQLm2.js} +1 -1
- package/dist/assets/{runtimeEndpointReset-BwSh51Vc.js → runtimeEndpointReset-B6IvKLrw.js} +1 -1
- package/dist/assets/{sessionChangeSummary-CX2MJIkc.js → sessionChangeSummary-DOq8EN_H.js} +1 -1
- package/dist/assets/{sessionLookup-CSkeoKrV.js → sessionLookup-B2hi1Ihk.js} +1 -1
- package/dist/assets/{sortable-tabs-strip-C5gGnikj.js → sortable-tabs-strip-C8_9kHqu.js} +1 -1
- package/dist/assets/{terminalApi-CIIs9vFx.js → terminalApi-947l7Ra3.js} +1 -1
- package/dist/assets/{textarea-CIO34TZz.js → textarea-Cgo_nWUU.js} +1 -1
- package/dist/assets/{tooltip-BSrJYYYc.js → tooltip-BifLJ8o0.js} +1 -1
- package/dist/assets/{url-CE_gAfNa.js → url-Pk6tQ1EZ.js} +1 -1
- package/dist/assets/{useAppFontEffects-Dh_NwW5O.js → useAppFontEffects-0g5MBolQ.js} +6 -6
- package/dist/assets/{useAssistantUIStore-BHacrxe_.js → useAssistantUIStore-me6s63b2.js} +1 -1
- package/dist/assets/{useDesktopWindowControlsLayout-CV96SEmA.js → useDesktopWindowControlsLayout-DoKmTYzZ.js} +1 -1
- package/dist/assets/{useEffectiveDirectory-XSKpr7Fy.js → useEffectiveDirectory-CjEJa0jg.js} +1 -1
- package/dist/assets/{useFontPreferences-BxOHKuVw.js → useFontPreferences-BCOBlaAd.js} +1 -1
- package/dist/assets/useMobileNavigationStore-BflVzhUK.js +413 -0
- package/dist/assets/{useSessionAutoCleanup-Da5ILm3s.js → useSessionAutoCleanup-CUU4X2MO.js} +1 -1
- package/dist/assets/useUIStore-CuaA8-Hp.js +1 -0
- package/dist/assets/{useWorkerHighlightedLines-dC60TMnO.js → useWorkerHighlightedLines-BLg6m3sH.js} +1 -1
- package/dist/assets/{utils-B0mQXN9L.js → utils-BiK3tBGM.js} +1 -1
- package/dist/index.html +8 -8
- package/dist/mini-chat.html +8 -8
- package/dist/mobile.html +8 -8
- package/package.json +1 -1
- package/server/lib/assistants/DOCUMENTATION.md +3 -3
- package/server/lib/assistants/contact-tools.js +7 -4
- package/server/lib/assistants/contact-tools.test.js +18 -9
- package/server/lib/assistants/harness.js +117 -93
- package/server/lib/assistants/harness.test.js +93 -3
- package/server/lib/assistants/pi-tools.js +118 -0
- package/server/lib/assistants/pi-tools.test.js +114 -0
- package/server/lib/assistants/service.test.js +1 -1
- package/server/lib/event-stream/DOCUMENTATION.md +12 -1
- package/server/lib/event-stream/directory-ws-bridge.js +11 -2
- package/server/lib/event-stream/global-ws-bridge.js +19 -3
- package/server/lib/event-stream/protocol.js +11 -1
- package/server/lib/event-stream/reasoning-projection.js +425 -0
- package/server/lib/event-stream/reasoning-projection.test.js +300 -0
- package/server/lib/event-stream/runtime.js +10 -0
- package/server/lib/event-stream/runtime.test.js +53 -0
- package/server/lib/opencode/DOCUMENTATION.md +2 -1
- package/server/lib/opencode/proxy.js +103 -9
- package/server/lib/opencode/proxy.test.js +177 -1
- package/server/lib/relay/reasoning-projection.e2e.test.ts +529 -0
- package/server/lib/session-turn-pages/DOCUMENTATION.md +2 -1
- package/server/lib/session-turn-pages/routes.js +22 -3
- package/server/lib/session-turn-pages/routes.test.js +43 -0
- package/server/lib/transcript-cache/DOCUMENTATION.md +2 -2
- package/server/lib/transcript-cache/routes.js +9 -2
- package/server/lib/transcript-cache/routes.test.js +32 -0
- package/dist/assets/AssistantView-BdZ8qKY7.js +0 -2
- package/dist/assets/MarkstreamRendererImpl-DnjoP9Et.js +0 -1
- package/dist/assets/MobileShareBridge-BeYYag96.js +0 -4
- package/dist/assets/desktopHosts-BzSE0sK7.js +0 -1
- package/dist/assets/persistence-CSZp1CNB.js +0 -3
- package/dist/assets/platform-CenlWqxu.js +0 -2
- package/dist/assets/useMobileNavigationStore-BrQwx0Jz.js +0 -412
- package/dist/assets/useUIStore-CqqO11ZI.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,i as t,r as n}from"./vendor-zustand-B4dlGEM2.js";var r=`openchamber-relay-v1`,i=65526,a={HttpRequest:1,HttpBody:2,HttpResponse:3,StreamEnd:4,StreamAbort:5,WsOpen:6,WsOpened:7,WsText:8,WsBinary:9,WsClose:10,Ping:11,Pong:12},o=new Set(Object.values(a)),s=e=>o.has(e),c={ControlReplaced:4001,DuplicateClient:4002,StuckControlReset:4003,HostUnavailable:4008,AuthFailed:4010,LimitExceeded:4029,HostWentAway:1012,RekeyMismatch:1008,ChannelFailure:1011},l=globalThis.crypto.subtle,u={name:`ECDH`,namedCurve:`P-256`},d=16,f=32,p=16,m=4,h=8,g=class extends Error{constructor(e){super(e),this.name=`RelayCryptoError`}},ee=()=>l.generateKey(u,!0,[`deriveBits`]),_=async e=>{let t=await l.exportKey(`jwk`,e);return{kty:t.kty,crv:t.crv,x:t.x,y:t.y}},v=async e=>{if(e.kty!==`EC`||e.crv!==`P-256`||typeof e.x!=`string`||typeof e.y!=`string`)throw new g(`invalid ECDH public key JWK`);try{return await l.importKey(`jwk`,{kty:e.kty,crv:e.crv,x:e.x,y:e.y,ext:!0},u,!0,[])}catch{throw new g(`invalid ECDH public key JWK`)}},y=()=>{let e=new Uint8Array(d);return globalThis.crypto.getRandomValues(e),e},b=async(e,t,n)=>{if(n.length!==d)throw new g(`invalid handshake nonce length`);let i=await l.deriveBits({name:`ECDH`,public:t},e,256),a=await l.importKey(`raw`,i,`HKDF`,!1,[`deriveBits`]),o=new Uint8Array(await l.deriveBits({name:`HKDF`,hash:`SHA-256`,salt:n,info:new TextEncoder().encode(r)},a,512)),s=(e,t)=>l.importKey(`raw`,e,{name:`AES-GCM`},!1,t);return{clientToHost:await s(o.slice(0,f),[`encrypt`,`decrypt`]),hostToClient:await s(o.slice(f),[`encrypt`,`decrypt`])}},x=(e,t,n)=>{for(let r=7;r>=0;--r)e[t+r]=Number(n&255n),n>>=8n},S=(e,t)=>{let n=0n;for(let r=0;r<h;r+=1)n=n<<8n|BigInt(e[t+r]);return n},te=e=>{let t=new Uint8Array(m);globalThis.crypto.getRandomValues(t);let n=0n;return{async encrypt(r){if(r.length>65536)throw new g(`plaintext frame exceeds maximum size`);n+=1n;let i=new Uint8Array(12);i.set(t,0),x(i,m,n);let a=new Uint8Array(await l.encrypt({name:`AES-GCM`,iv:i},e,r)),o=new Uint8Array(13+a.length);return o[0]=1,o.set(i,1),o.set(a,13),o}}},ne=e=>{let t=0n;return{async decrypt(n){if(n.length<13+p)throw new g(`encrypted frame too short`);if(n[0]!==1)throw new g(`unsupported encrypted frame version`);let r=n.slice(1,13),i=S(r,m);if(i<=t)throw new g(`frame counter regression`);let a;try{a=await l.decrypt({name:`AES-GCM`,iv:r},e,n.slice(13))}catch{throw new g(`frame decryption failed`)}return t=i,new Uint8Array(a)}}},C=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_`,re=e=>{let t=``;for(let n=0;n<e.length;n+=3){let r=e[n],i=n+1<e.length?e[n+1]:void 0,a=n+2<e.length?e[n+2]:void 0;t+=C[r>>2],t+=C[(r&3)<<4|(i??0)>>4],i!==void 0&&(t+=C[(i&15)<<2|(a??0)>>6]),a!==void 0&&(t+=C[a&63])}return t},w=e=>{let t;try{t=JSON.parse(e)}catch{return null}if(typeof t!=`object`||!t)return null;let n=t;if(n.v!==1)return null;let r=n.batch===!0;return n.t===`ready`?{t:`ready`,v:1,batch:r}:n.t===`hello`&&typeof n.nonce==`string`&&typeof n.clientPubJwk==`object`&&n.clientPubJwk!==null?{t:`hello`,v:1,clientPubJwk:n.clientPubJwk,nonce:n.nonce,batch:r}:null},T=e=>({type:`fail`,closeCode:c.ChannelFailure,reason:e}),ie=async(e,t={})=>{let n=t.batch!==!1,r=await v(e),i=await ee(),a=y(),o={t:`hello`,v:1,clientPubJwk:await _(i.publicKey),nonce:re(a),...n?{batch:!0}:{}},s=!1;return{helloText:JSON.stringify(o),get established(){return s},async handleText(e){if(s)return w(e)?.t===`ready`?{type:`ignore`}:T(`plaintext frame on established channel`);let t=w(e);if(t?.t!==`ready`)return{type:`ignore`};let o=await b(i.privateKey,r,a);return s=!0,{type:`established`,batch:n&&t.batch===!0,channel:{encryptor:te(o.clientToHost),decryptor:ne(o.hostToClient)}}}}},E=4294967295,D=class extends Error{constructor(e){super(e),this.name=`TunnelCodecError`}},O=(e,t,n,r=!1)=>{if(!Number.isInteger(t)||t<0||t>E)throw new D(`invalid stream id`);if(n.length>65526)throw new D(`tunnel payload exceeds maximum size`);let i=new Uint8Array(5+n.length);return i[0]=r?e|128:e,i[1]=t>>>24&255,i[2]=t>>>16&255,i[3]=t>>>8&255,i[4]=t&255,i.set(n,5),i},ae=e=>{if(e.length<5)throw new D(`tunnel frame too short`);let t=e[0],n=!!(t&128),r=t&-129;if(!s(r))throw new D(`unknown tunnel frame type ${r}`);return{frameType:r,streamId:(e[1]<<24|e[2]<<16|e[3]<<8|e[4])>>>0,payload:e.slice(5),hasMoreFragments:n}},oe=new TextEncoder,se=new TextDecoder,k=e=>oe.encode(JSON.stringify(e)),A=(e,t)=>{let n;try{n=JSON.parse(se.decode(e))}catch{throw new D(`malformed JSON tunnel payload`)}if(!t(n))throw new D(`unexpected JSON tunnel payload shape`);return n},j=(e,t=i)=>{if(t<=0||t>65526)throw new D(`invalid chunk size`);if(e.length===0)return[new Uint8Array];let n=[];for(let r=0;r<e.length;r+=t)n.push(e.slice(r,r+t));return n},ce=(e,t,n)=>{let r=j(n);return r.map((n,i)=>O(e,t,n,i<r.length-1))},le=(e=16777216)=>{let t=new Map;return{push(n){let r=`${n.streamId}:${n.frameType}`,i=t.get(r);if(!n.hasMoreFragments&&!i)return n.payload;let a=i?.chunks??[],o=(i?.totalBytes??0)+n.payload.length;if(o>e)throw t.delete(r),new D(`fragmented message exceeds maximum size`);if(a.push(n.payload),n.hasMoreFragments)return t.set(r,{chunks:a,totalBytes:o}),null;t.delete(r);let s=new Uint8Array(o),c=0;for(let e of a)s.set(e,c),c+=e.length;return s},dropStream(e){for(let n of t.keys())n.startsWith(`${e}:`)&&t.delete(n)}}},M=e=>{if(e.length===0)throw new D(`cannot encode an empty frame batch`);if(e.length===1){let t=e[0],n=new Uint8Array(1+t.length);if(n[0]=0,n.set(t,1),n.length>65536)throw new D(`frame batch exceeds maximum plaintext size`);return n}let t=1;for(let n of e)t+=4+n.length;if(t>65536)throw new D(`frame batch exceeds maximum plaintext size`);let n=new Uint8Array(t);n[0]=1;let r=1;for(let t of e)n[r]=t.length>>>24&255,n[r+1]=t.length>>>16&255,n[r+2]=t.length>>>8&255,n[r+3]=t.length&255,r+=4,n.set(t,r),r+=t.length;return n},ue=e=>{if(e.length<1)throw new D(`empty batch plaintext`);let t=e[0];if(t===0)return[e.slice(1)];if(t!==1)throw new D(`unknown batch container tag ${t}`);let n=[],r=1;for(;r<e.length;){if(r+4>e.length)throw new D(`truncated batch frame length`);let t=(e[r]<<24|e[r+1]<<16|e[r+2]<<8|e[r+3])>>>0;if(r+=4,r+t>e.length)throw new D(`truncated batch frame body`);n.push(e.slice(r,r+t)),r+=t}if(n.length===0)throw new D(`empty frame batch`);return n},N=new Set([a.HttpBody,a.WsText,a.WsBinary]),de=e=>{let t=e.windowMs??150,n=e.maxBatchBytes??24576,r=e.maxBatchFrames??32,i=e.now??(()=>Date.now()),a=e.setTimer??((e,t)=>setTimeout(e,t)),o=e.clearTimer??(e=>clearTimeout(e)),s=[],c=0,l=null,u=0,d=!1,f=()=>{l!==null&&(o(l),l=null)},p=()=>{if(f(),s.length===0)return;let t=s;s=[],c=0,u=i(),e.sendBatch(M(t))};return{enqueue:e=>{if(d)return;let o=e[0]&-129;if(!N.has(o)){s.push(e),p();return}let f=i();if(s.length===0&&f-u>=t){s.push(e),p();return}let m=4+e.length;if(s.length>0&&1+c+m>65536&&p(),s.push(e),c+=m,c>=n||s.length>=r){p();return}l===null&&(l=a(p,t))},flush:p,dispose(){d=!0,f(),s=[],c=0}}},fe=()=>{let e=1;return{next(){if(e>E)throw new D(`stream id space exhausted`);let t=e;return e+=2,t}}},P=e=>typeof e==`object`&&!!e&&!Array.isArray(e),pe=e=>P(e)&&Object.values(e).every(e=>typeof e==`string`),me=e=>P(e)&&typeof e.status==`number`&&pe(e.headers),he=e=>P(e)&&typeof e.reason==`string`,ge=e=>P(e)&&typeof e.code==`number`&&typeof e.reason==`string`,_e=/^[a-z][a-z\d+.-]*:\/\//i,ve=`http://tunnel.invalid`,ye=e=>{try{let t=_e.test(e)?new URL(e):new URL(e,ve);return`${t.pathname}${t.search}`}catch{return e}},be=e=>({async*[Symbol.asyncIterator](){yield e}}),xe=e=>({async*[Symbol.asyncIterator](){let t=e.getReader();try{for(;;){let{done:e,value:n}=await t.read();if(e)return;n&&(yield n)}}finally{t.releaseLock()}}}),Se=e=>{let t=new Uint8Array(e.byteLength);return t.set(new Uint8Array(e.buffer,e.byteOffset,e.byteLength)),t},Ce=async e=>{if(e==null)return{body:null};if(e instanceof ReadableStream)return{body:xe(e)};if(typeof e==`string`)return{body:be(new TextEncoder().encode(e))};if(e instanceof ArrayBuffer)return{body:be(new Uint8Array(e.slice(0)))};if(ArrayBuffer.isView(e))return{body:be(Se(e))};let t=new Response(e),n=t.headers.get(`content-type`)??void 0;return{body:be(new Uint8Array(await t.arrayBuffer())),contentType:n}},we=async(e,t)=>{let n,r=new Headers,i=`GET`,a=null,o;e instanceof Request?(n=e.url,i=e.method,e.headers.forEach((e,t)=>r.set(t,e)),o=e.signal,a=e.body):n=e.toString(),t&&(t.method&&(i=t.method),t.headers&&new Headers(t.headers).forEach((e,t)=>r.set(t,e)),t.body!==void 0&&(a=t.body),t.signal&&(o=t.signal));let s=_e.test(n)?new URL(n):new URL(n,ve),{body:c,contentType:l}=await Ce(a);l&&!r.has(`content-type`)&&r.set(`content-type`,l);let u={};return r.forEach((e,t)=>{u[t]=e}),{method:i.toUpperCase(),path:s.pathname,query:s.search.startsWith(`?`)?s.search.slice(1):s.search,headers:u,body:c,signal:o}},Te=new Uint8Array,Ee=new TextEncoder,De=new TextDecoder,F=e=>e instanceof Error?e:Error(String(e)),Oe=()=>new DOMException(`The operation was aborted.`,`AbortError`),ke=e=>{e.binaryType=`arraybuffer`;let t={get readyState(){return e.readyState},send(t){e.send(t)},close(t,n){e.close(t,n)},onopen:null,onmessage:null,onclose:null,onerror:null};return e.onopen=()=>t.onopen?.(),e.onmessage=e=>t.onmessage?.({data:e.data}),e.onclose=e=>t.onclose?.({code:e.code,reason:e.reason}),e.onerror=()=>t.onerror?.(),t},Ae=e=>{let t={get readyState(){return e.readyState},get binaryType(){return e.binaryType},set binaryType(t){t&&(e.binaryType=t)},onopen:null,onmessage:null,onerror:null,onclose:null,send(t){e.send(t)},close(t,n){e.close(t,n)}};return e.onopen=()=>t.onopen?.(),e.onmessage=e=>{let n=e.data;(typeof n==`string`||n instanceof ArrayBuffer)&&t.onmessage?.({data:n})},e.onerror=()=>t.onerror?.(),e.onclose=e=>t.onclose?.({code:e.code,reason:e.reason}),t},je=0,Me=1,Ne=2,Pe=3,Fe=new Set([c.AuthFailed,c.DuplicateClient,c.LimitExceeded]),Ie={[c.AuthFailed]:`relay authentication failed`,[c.DuplicateClient]:`relay connection replaced by another client`,[c.LimitExceeded]:`relay connection limit reached`},Le=()=>{let e=typeof navigator<`u`&&navigator.onLine===!1,t=typeof document<`u`&&document.visibilityState===`hidden`;return e||t},Re=e=>{let t=e.helloRetryMs??1e3,n=e.helloTimeoutMs??3e4,r=e.pingIntervalMs??3e4,i=e.pingTimeoutMs??15e3,o=e.batchWindowMs??150,s=e.batch!==!1,c=e.reconnectBaseDelayMs??1e3,l=e.reconnectMaxDelayMs??3e4,u=e.hiddenOrOfflineMaxDelayMs??6e4,d=e.createWireSocket??(e=>ke(new WebSocket(e))),f=!1,p={state:`idle`},m=new Set,h=null,g=null,ee=null,_=0,v=0,y=null,b=[],x=!1,S=e=>{if(p.state!==e.state||p.lastError!==e.lastError){p=e;for(let e of m)try{e(p)}catch{}}},te=e=>{let t=b;b=[];for(let n of t)n.reject(e)},ne=e=>{let t=b;b=[];for(let n of t)n.resolve(e)},C=(e,t)=>{e.dead=!0;let n=Array.from(e.streams.values());e.streams.clear();for(let e of n)try{e.fail(t)}catch{}},re=()=>{y!==null&&(clearTimeout(y),y=null)},w=()=>{f||y===null||Le()||(re(),D(),M())},T=()=>{typeof document<`u`&&document.visibilityState===`visible`&&w()},E=()=>{x||typeof window>`u`||(x=!0,window.addEventListener(`online`,w),typeof document<`u`&&document.addEventListener(`visibilitychange`,T))},D=()=>{!x||typeof window>`u`||(x=!1,window.removeEventListener(`online`,w),typeof document<`u`&&document.removeEventListener(`visibilitychange`,T))},oe=()=>{if(f||y!==null)return;let e=Math.max(0,v-1),t=c*2**Math.min(e,10),n=Le()?u:l,r=Math.min(n,t);E(),y=setTimeout(()=>{y=null,D(),M()},r)},se=()=>{let t=new URL(e.relayUrl);return t.searchParams.set(`v`,`1`),t.searchParams.set(`role`,`client`),t.searchParams.set(`serverId`,e.serverId),e.grant&&t.searchParams.set(`grant`,e.grant),t.toString()},M=async()=>{if(f)return;re(),_+=1;let c=_;S({state:v>0?`reconnecting`:`connecting`,lastError:p.lastError});let l;try{l=await ie(e.hostEncPubJwk,{batch:s})}catch(e){if(c!==_||f)return;me(c,F(e),!0);return}if(c!==_||f)return;let u;try{u=d(se())}catch(e){me(c,F(e));return}g=u;let m=!1,y=null,b=null,x=null,w=null,T=Promise.resolve(),E=null,D=null,k=!1,A=null,j=Date.now(),ce=()=>{y!==null&&(clearInterval(y),y=null),b!==null&&(clearTimeout(b),b=null),x!==null&&(clearInterval(x),x=null),w!==null&&(clearTimeout(w),w=null),A!==null&&(A.dispose(),A=null)};ee=ce;function M(e,t=!1,n=!1){if(!(m||c!==_)){m=!0,ce(),E&&(h=null,C(E,Error(`relay tunnel reset: ${e.message}`))),te(e);try{u.close()}catch{}if(g===u&&(g=null),!f){if(v+=1,n){S({state:`error`,lastError:e.message});return}S({state:t?`error`:`reconnecting`,lastError:e.message}),oe()}}}let N=()=>{try{u.send(l.helloText)}catch{}},P=(e,t)=>{D=e,k=t,y!==null&&(clearInterval(y),y=null),b!==null&&(clearTimeout(b),b=null);let n=new Map,s=fe(),c=le(),l=Promise.resolve(),d=t=>{l=l.then(async()=>{if(p.dead)return;let n=await e.encryptor.encrypt(t);u.send(n)}).catch(()=>{})},f=t?de({windowMs:o,sendBatch:d}):null;A=f;let p={streams:n,assembler:c,nextStreamId:()=>s.next(),dead:!1,send(e){if(p.dead)return;let t=e[0]&-129;t!==a.Ping&&t!==a.Pong&&(j=Date.now()),f?f.enqueue(e):d(e)}};E=p,h=p,v=0,j=Date.now(),S({state:`connected`}),ne(p),x=setInterval(()=>{Date.now()-j<r||(p.send(O(a.Ping,0,Te)),w===null&&(w=setTimeout(()=>{w=null,M(Error(`relay keepalive timeout`))},i)))},r)},pe=(e,t)=>{let n;try{n=ae(t)}catch(e){M(F(e));return}if(w!==null&&(clearTimeout(w),w=null),n.frameType===a.Ping){e.send(O(a.Pong,n.streamId,Te));return}if(n.frameType===a.Pong)return;j=Date.now();let r=n.payload;if(n.frameType===a.WsText||n.frameType===a.WsBinary){let t;try{t=e.assembler.push(n)}catch(e){M(F(e));return}if(t===null)return;r=t}else if(n.hasMoreFragments){M(Error(`unexpected fragmented tunnel frame`));return}let i=e.streams.get(n.streamId);i&&i.handleFrame(n.frameType,r)};u.onopen=()=>{m||c!==_||(N(),y=setInterval(N,t))},u.onmessage=e=>{if(m||c!==_)return;let t=e.data;if(typeof t==`string`){T=T.then(async()=>{if(m||c!==_)return;let e=await l.handleText(t);if(e.type===`established`){if(D)return;P(e.channel,e.batch)}else e.type===`fail`&&M(Error(`relay handshake failed: ${e.reason}`))}).catch(e=>{M(F(e))});return}let n=t instanceof ArrayBuffer?new Uint8Array(t):t instanceof Uint8Array?t:null;n&&(T=T.then(async()=>{if(m||c!==_)return;let e=E,t=D;if(!e||!t){M(Error(`encrypted frame before handshake completed`));return}let r;try{r=await t.decryptor.decrypt(n)}catch(e){M(F(e));return}if(k){let t;try{t=ue(r)}catch(e){M(F(e));return}for(let n of t){if(m||c!==_||e.dead)return;pe(e,n)}return}pe(e,r)}).catch(e=>{M(F(e))}))},u.onclose=e=>{let t=Fe.has(e.code);M(Error(Ie[e.code]??`relay socket closed (code ${e.code})`),t,t)},u.onerror=()=>{},b=setTimeout(()=>{b=null,M(Error(`relay handshake timeout`),!0)},n);function me(e,t,n=!1){e!==_||f||(te(t),v+=1,S({state:n?`error`:`reconnecting`,lastError:t.message}),oe())}},N=e=>f?Promise.reject(Error(`relay tunnel closed`)):e?.aborted?Promise.reject(Oe()):h&&!h.dead?Promise.resolve(h):new Promise((t,n)=>{let r=null,i={resolve(n){r&&e&&e.removeEventListener(`abort`,r),t(n)},reject(t){r&&e&&e.removeEventListener(`abort`,r),n(t)}};e&&(r=()=>{b=b.filter(e=>e!==i),n(Oe())},e.addEventListener(`abort`,r,{once:!0})),b.push(i)}),P=async(e,t)=>{let n=await we(e,t),r=n.signal;if(r?.aborted)throw Oe();let i=await N(r),o=i.nextStreamId();return await new Promise((e,t)=>{let s=!1,c=!1,l=null,u=null,d=()=>{i.streams.delete(o),i.assembler.dropStream(o),u&&r&&r.removeEventListener(`abort`,u)},f=e=>{if(!c){if(c=!0,d(),!s){t(e);return}try{l?.error(e)}catch{}}},p=e=>{i.dead||i.send(O(a.StreamAbort,o,k({reason:e})))};u=()=>{p(`aborted`),f(Oe())},i.streams.set(o,{handleFrame(t,n){if(t===a.HttpResponse){if(s||c)return;let t;try{t=A(n,me)}catch(e){p(`malformed response head`),f(F(e));return}let r=t.status===204||t.status===205||t.status===304,i=null;r||(i=new ReadableStream({start(e){l=e},cancel(){c||(c=!0,d(),p(`response body cancelled`))}})),s=!0,e(new Response(i,{status:t.status,headers:t.headers})),r&&(c=!0,d());return}if(t===a.HttpBody){if(!s||c)return;try{l?.enqueue(n)}catch{}return}if(t===a.StreamEnd){if(c)return;if(!s){f(Error(`tunnel stream ended before response head`));return}c=!0,d();try{l?.close()}catch{}return}if(t===a.StreamAbort){let e=`stream aborted by host`;try{e=A(n,he).reason}catch{}f(Error(e))}},fail(e){f(e)}}),r&&r.addEventListener(`abort`,u,{once:!0});let m={method:n.method,path:n.path,query:n.query,headers:n.headers};i.send(O(a.HttpRequest,o,k(m))),(async()=>{try{if(n.body)for await(let e of n.body){if(c||i.dead)return;for(let t of j(e))i.send(O(a.HttpBody,o,t))}!c&&!i.dead&&i.send(O(a.StreamEnd,o,Te))}catch(e){p(`request body failed`),f(F(e))}})()})},pe=e=>{let t=e.indexOf(`?`);return t===-1?{path:e,query:``}:{path:e.slice(0,t),query:e.slice(t+1)}};return M(),{fetch:P,openWebSocket:(e,t,n)=>{let r=je,i=null,o=0,s=!1,c={get readyState(){return r},onopen:null,onmessage:null,onerror:null,onclose:null,send(e){if(r!==Me||!i||i.dead)throw Error(`relay tunnel socket is not open`);if(typeof e==`string`){for(let t of ce(a.WsText,o,Ee.encode(e)))i.send(t);return}let t=e instanceof ArrayBuffer?new Uint8Array(e.slice(0)):(()=>{let t=new Uint8Array(e.byteLength);return t.set(new Uint8Array(e.buffer,e.byteOffset,e.byteLength)),t})();for(let e of ce(a.WsBinary,o,t))i.send(e)},close(e=1e3,t=``){r!==Pe&&r!==Ne&&(r===Me&&i&&!i.dead&&(r=Ne,i.send(O(a.WsClose,o,k({code:e,reason:t})))),l(e,t))}},l=(e,t,n=!1)=>{if(!s){if(s=!0,i&&(i.streams.delete(o),i.assembler.dropStream(o)),r=Pe,n)try{c.onerror?.()}catch{}try{c.onclose?.({code:e,reason:t})}catch{}}};return(async()=>{let u;try{u=await N()}catch(e){l(1006,F(e).message,!0);return}if(s)return;i=u,o=u.nextStreamId(),u.streams.set(o,{handleFrame(e,t){if(e===a.WsOpened){if(r===je){r=Me;try{c.onopen?.()}catch{}}return}if(e===a.WsText){try{c.onmessage?.({data:De.decode(t)})}catch{}return}if(e===a.WsBinary){let e=new ArrayBuffer(t.byteLength);new Uint8Array(e).set(t);try{c.onmessage?.({data:e})}catch{}return}if(e===a.WsClose){let e=1e3,n=``;try{let r=A(t,ge);e=r.code,n=r.reason}catch{}l(e,n);return}if(e===a.StreamAbort){let e=`stream aborted`;try{e=A(t,he).reason}catch{}l(1006,e,!0)}},fail(e){l(1012,e.message,!0)}});let{path:d,query:f}=pe(e),p={path:d,query:f,...t&&t.length>0?{protocols:t}:{},...n&&Object.keys(n).length>0?{headers:n}:{}};u.send(O(a.WsOpen,o,k(p)))})(),c},getStatus:()=>p,subscribeStatus(e){return m.add(e),()=>{m.delete(e)}},close:()=>{if(f)return;f=!0,_+=1,re(),D(),ee?.(),ee=null;let e=h;h=null;let t=Error(`relay tunnel closed`);e&&C(e,t),te(t);try{g?.close()}catch{}g=null,S({state:`idle`})}}},I=null,L=null,ze=(e,t)=>e.relayUrl===t.relayUrl&&e.serverId===t.serverId&&e.grant===t.grant&&JSON.stringify(e.hostEncPubJwk)===JSON.stringify(t.hostEncPubJwk),Be=()=>I,Ve=()=>L,He=()=>I!==null,Ue=()=>I?.getStatus().state===`connected`,We=e=>I&&L&&ze(L,e)?I:(I?.close(),L=e,I=Re(e),I),Ge=(e,t)=>{I!==t&&(I?.close(),L=e,I=t)},Ke=()=>{I?.close(),I=null,L=null},qe=()=>null,Je=``,Ye={},R=``,z=0,B=null,V=``,H=0,U=null,W=0,Xe=1e4,Ze=()=>W,Qe=e=>e.toLowerCase()===`authorization`,$e=e=>{let t={};for(let[n,r]of Object.entries(e||{})){let e=n.trim(),i=r.trim();e&&i&&!Qe(e)&&(t[e]=i)}return t},et=(e,t)=>{let n=Object.entries(e);return n.length===Object.keys(t).length&&n.every(([e,n])=>t[e]===n)},tt=e=>typeof e==`string`?e.trim():``,nt=()=>{if(typeof window>`u`)return``;let e=window.__OPENCHAMBER_CLIENT_TOKEN__;return tt(e)},rt=()=>{if(typeof window>`u`)return``;let e=window.__OPENCHAMBER_API_BASE_URL__;return typeof e==`string`?e.trim():``},it=(e,t)=>{let n=typeof e==`string`&&e.trim()?e.trim():rt();if(!n)return t;try{return new URL(t,`${n.replace(/\/+$/,``)}/`).toString()}catch{return t}},G=()=>{R=``,z=0,V=``,H=0},at=()=>{W+=1,B=null,G(),Et()},ot=e=>{let t=tt(e),n=t===lt();Je=t,qe=()=>t?{type:`bearer`,token:t}:null,!n&&at()},st=e=>{let t=$e(e);et(Ye,t)||(Ye=t,at())},ct=()=>{if(Object.keys(Ye).length>0)return Ye;if(typeof window>`u`)return{};let e=window.__OPENCHAMBER_RUNTIME_HEADERS__;return e&&typeof e==`object`?$e(e):{}},lt=()=>Je||nt(),ut=(e,t)=>{let n=tt(e);if(!n||typeof t!=`number`||!Number.isFinite(t)){G();return}let r=R;R=n,z=t,r&&r!==n&&wt()},dt=()=>!R||z<=Date.now()+Xe?(G(),``):R,ft=()=>!V||H<=Date.now()+Xe?(V=``,H=0,``):V,pt=()=>{let e=dt();return!e&&(lt()||typeof window<`u`)&&vt().catch(()=>{}),e},mt=e=>{let t=ft();return!t&&e&&typeof window<`u`&&yt(e).catch(()=>{}),t},ht=async()=>{let e=await qe(),t=e?.type===`bearer`?tt(e.token):lt();return t?{type:`bearer`,token:t}:null},gt=e=>{if(B)return B;let t=W,n=(async()=>{let n=await ht(),r=new Headers;for(let[e,t]of Object.entries(ct()))r.set(e,t);n?.type===`bearer`&&r.set(`Authorization`,`Bearer ${n.token}`);let i=Be(),a=i?await i.fetch(`/auth/url-token`,{method:`POST`,headers:r}):await fetch(it(e,`/auth/url-token`),{method:`POST`,headers:r,credentials:`include`});if(!a.ok)throw t===W&&G(),Error(`Failed to mint runtime URL auth token (${a.status})`);let o=await a.json().catch(()=>null),s=typeof o?.token==`string`?o.token.trim():``,c=typeof o?.expiresAt==`number`?o.expiresAt:0;if(t!==W)throw Error(`Runtime URL auth token response is stale`);if(ut(s,c),!R)throw Error(`Runtime URL auth token response was invalid`);return R})().finally(()=>{B===n&&(B=null)});return B=n,B},_t=e=>{if(U)return U;let t=(async()=>{let t=await fetch(it(e,`/auth/url-token`),{method:`POST`,credentials:`include`});if(!t.ok)throw V=``,H=0,Error(`Failed to mint local runtime URL auth token (${t.status})`);let n=await t.json().catch(()=>null),r=typeof n?.token==`string`?n.token.trim():``,i=typeof n?.expiresAt==`number`?n.expiresAt:0;if(!r||!Number.isFinite(i))throw Error(`Local runtime URL auth token response was invalid`);return V=r,H=i,r})().finally(()=>{U===t&&(U=null)});return U=t,U},vt=async e=>dt()||gt(e),yt=async e=>ft()||_t(e),K=0,bt=null,xt=null,St=new Set,Ct=5e3,wt=()=>{for(let e of St)try{e()}catch{}},Tt=()=>{bt!==null&&(clearTimeout(bt),bt=null)},Et=()=>{if(Tt(),K<=0||typeof window>`u`)return;let e=z-Xe-Ct,t=z>0?Math.max(0,e-Date.now()):0;bt=setTimeout(()=>{bt=null,!(K<=0)&>(xt).catch(()=>{}).finally(()=>{Et()})},t)},Dt=e=>{typeof e==`string`&&e.trim()&&(xt=e.trim()),K+=1,Et();let t=!1;return()=>{t||(t=!0,K=Math.max(0,K-1),K===0&&Tt())}},Ot=e=>(St.add(e),()=>{St.delete(e)}),kt=async e=>{let t=new Headers(e);for(let[e,n]of Object.entries(ct()))t.has(e)||t.set(e,n);if(t.has(`Authorization`))return t;let n=await ht();return n?.type===`bearer`&&t.set(`Authorization`,`Bearer ${n.token}`),t},At=!0,jt=0,Mt=new Set;function Nt(){return At}function Pt(){return jt}function Ft(e){if(At!==e){At=e,jt+=1;for(let e of Mt)try{e()}catch{}}}function It(e){return Mt.add(e),()=>{Mt.delete(e)}}var Lt=/^[a-z][a-z\d+.-]*:\/\//i,Rt=e=>{let t=e.trim();return t?t.startsWith(`/`)?t:`/${t}`:`/`},zt=e=>typeof e==`string`?e.trim().replace(/\/+$/,``):``,Bt=()=>{if(typeof window>`u`)return``;let e=window.__OPENCHAMBER_API_BASE_URL__;return zt(e)},Vt=()=>{if(typeof window>`u`)return``;let e=window.__OPENCHAMBER_LOCAL_ORIGIN__;return zt(e)},Ht=()=>Object.keys(ct()).length>0,Ut=e=>e.currentHref?.()||(typeof window<`u`?window.location.href||window.location.origin:``),Wt=(e,t)=>{if(!t)return;let n=t instanceof URLSearchParams?Array.from(t.entries()):Object.entries(t);for(let[t,r]of n)r!=null&&e.searchParams.set(t,String(r))},Gt=(e,t)=>{if(!t)return e;let n=new URLSearchParams;Wt({searchParams:n},t);let r=n.toString();return r?e.includes(`?`)?`${e}&${r}`:`${e}?${r}`:e},Kt=(e,t,n)=>{if(Lt.test(t)){let e=new URL(t);return Wt(e,n),e.toString()}let r=Rt(t);if(!e)return Gt(r,n);let i=new URL(r,`${e}/`);return Wt(i,n),i.toString()},qt=e=>{let t=pt();if(!t)return e;let n=Lt.test(e)?new URL(e):new URL(e,`http://openchamber.local`);return n.searchParams.set(`oc_url_token`,t),Lt.test(e)?n.toString():`${n.pathname}${n.search}${n.hash}`},Jt=(e,t)=>{let n=Lt.test(e)?new URL(e):new URL(e,Ut(t));return n.protocol===`ws:`||n.protocol===`wss:`||(n.protocol=n.protocol===`https:`?`wss:`:`ws:`),n.toString()},Yt=(e,t,n)=>{if(!Ht())return null;let r=Vt();if(!r)return null;try{let i=new URL(`/api/openchamber/realtime-proxy/${e===`sse`?`sse`:`ws`}`,`${r}/`);i.searchParams.set(`url`,t);let a=mt(r);return a&&i.searchParams.set(`oc_url_token`,a),e===`ws`?(i.protocol=i.protocol===`https:`?`wss:`:`ws:`,Jt(i.toString(),n)):i.toString()}catch{return null}},Xt=(e={})=>{let t=zt(e.apiBaseUrl),n=zt(e.realtimeBaseUrl),r=()=>t||Bt(),i=()=>n||r(),a=(e,t)=>Kt(r(),e,t),o=(e,t)=>Kt(i(),e,t);return{api:a,authenticatedAsset:(e,t)=>qt(a(e,t)),auth:a,health:e=>a(`/health`,e),rawFile:(e,t)=>a(`/api/fs/raw`,{path:e,download:t?.download===!0||void 0,allowOutsideWorkspace:t?.allowOutsideWorkspace===!0||void 0,outsideFileGrant:t?.outsideFileGrant}),sse:(t,n)=>{let r=qt(o(t,n));return Yt(`sse`,r,e)||r},websocket:(t,n)=>{let r=Jt(qt(o(t,n)),e);return Yt(`ws`,r,e)||r}}},Zt=Xt(),Qt=()=>Zt,$t=e=>{Zt=e},en=e=>(Zt=Xt(e),Zt),tn=`openchamber:runtime-endpoint-changed`,nn=``,rn=``,an=``,on=``,sn=0,cn=e=>Array.isArray(e)?`[${e.map(cn).join(`,`)}]`:e&&typeof e==`object`?`{${Object.entries(e).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${JSON.stringify(e)}:${cn(t)}`).join(`,`)}}`:JSON.stringify(e)??`undefined`,ln=e=>e?Object.entries(e).map(([e,t])=>[e.trim().toLowerCase(),t]).filter(([e])=>e.length>0).sort(([e],[t])=>e.localeCompare(t)):[],un=e=>cn({apiBaseUrl:e.apiBaseUrl.replace(/\/+$/,``),clientToken:e.clientToken||null,runtimeKey:e.runtimeKey,requestHeaders:ln(e.requestHeaders),relay:e.relay??null}),dn=(e,t,n)=>{try{e[t]=n}catch{}},q=e=>{try{let t=new URL(e);return t.hash=``,t.search=``,t.pathname=t.pathname.replace(/\/+$/,``)||`/`,`url:${t.toString().replace(/\/+$/,``)}`}catch{return`url:${e.trim().replace(/\/+$/,``)||`default`}`}},fn=(e,t)=>t?`relay:${cn({relayUrl:t.relayUrl,serverId:t.serverId,hostEncPubJwk:t.hostEncPubJwk})}`:`direct:${q(e)}`,pn=e=>e.transportIdentityChanged??q(e.apiBaseUrl)!==q(e.previousApiBaseUrl),mn=e=>e.runtimeKey!==e.previousRuntimeKey,hn=()=>{if(typeof window>`u`)return``;let e=window.__OPENCHAMBER_API_BASE_URL__;return typeof e==`string`?e.trim():``},gn=()=>{if(typeof window>`u`)return``;let e=window.__OPENCHAMBER_LOCAL_ORIGIN__;return typeof e==`string`?e.trim():``},_n=(e,t)=>{if(!e||!t)return!1;try{return new URL(e).origin===new URL(t).origin}catch{return!1}},vn=()=>nn||hn(),yn=()=>on||fn(vn()),bn=()=>sn,xn=()=>{if(rn)return rn;let e=vn();return _n(e,gn())?`local`:q(e)},Sn=(e={})=>{if(nn||rn)return;let t=e.apiBaseUrl?.trim()||hn();t&&(nn=t,rn=e.runtimeKey?.trim()||(_n(t,gn())?`local`:q(t)),on=fn(t,null))},Cn=e=>{let t=e.apiBaseUrl.trim(),n=vn(),r=xn(),i=q(t)===q(n),a=e.runtimeKey?.trim()||(i?r:q(t)),o=un({...e,apiBaseUrl:t,runtimeKey:a});if(o===an)return;let s=yn(),c=fn(t,e.relay),l=c!==s;if(an=o,on=c,l&&(sn+=1),nn=t,rn=a,typeof window<`u`){let n=window;dn(n,`__OPENCHAMBER_API_BASE_URL__`,t),dn(n,`__OPENCHAMBER_CLIENT_TOKEN__`,e.clientToken||void 0),dn(n,`__OPENCHAMBER_RUNTIME_HEADERS__`,e.requestHeaders||void 0)}en({apiBaseUrl:t,realtimeBaseUrl:t}),st(e.requestHeaders||null),ot(e.clientToken||null),e.relay?We(e.relay):Be()&&(console.warn(`[runtime-switch] dropping active relay transport`,{runtimeKey:a,previousRuntimeKey:r,apiBaseUrl:t,relayServerId:Ve()?.serverId??null},Error(`relay dropped here`).stack),Ke()),vt(t).catch(()=>{}),typeof window<`u`&&window.dispatchEvent(new CustomEvent(tn,{detail:{apiBaseUrl:t,previousApiBaseUrl:n,runtimeKey:a,previousRuntimeKey:r,transportIdentityChanged:l}}))},wn=e=>{if(typeof window>`u`)return()=>{};let t=t=>{e(t.detail)};return window.addEventListener(tn,t),()=>window.removeEventListener(tn,t)},Tn=null,En=null,Dn=null,On=new Set,kn=!1,An=e=>{if(On.add(e),kn||typeof window>`u`)return;kn=!0;let t=()=>{for(let e of On)e()};try{window.addEventListener(`pagehide`,t,{capture:!0}),window.addEventListener(`beforeunload`,t,{capture:!0}),window.addEventListener(`visibilitychange`,()=>{typeof document<`u`&&document.visibilityState===`hidden`&&t()}),window.addEventListener(`freeze`,t)}catch{}},jn=(e,t)=>{let n;try{n=e()}catch{return}let r=new Map,i=new Set,a,o=()=>{if(a=void 0,r.size===0&&i.size===0)return!0;let e=Array.from(r.entries()),o=Array.from(i);r.clear(),i.clear();let c=!0;for(let[i,a]of e)try{n.setItem(i,JSON.stringify(a,t?.replacer))}catch(e){console.error(`Failed to persist deferred storage value`,e),r.set(i,a),c=!1}for(let e of o)try{n.removeItem(e)}catch(t){console.error(`Failed to remove deferred storage value`,t),i.add(e),c=!1}return c||s(),c},s=()=>{a===void 0&&(a=setTimeout(o,0))};return An(o),{getItem:e=>{if(r.has(e))return r.get(e)??null;if(i.has(e))return null;let a=e=>e===null?null:JSON.parse(e,t?.reviver),o=n.getItem(e);return o instanceof Promise?o.then(a):a(o)},setItem:(e,t)=>{r.set(e,t),i.delete(e),s()},removeItem:e=>{r.delete(e),i.add(e),s()},flush:o}},Mn=e=>jn(()=>Ln(),e),Nn=e=>{let t=new Map,n=new Set,r,i=()=>{if(r=void 0,t.size===0&&n.size===0)return;let i=Array.from(t.entries()),a=Array.from(n);t.clear(),n.clear();for(let[t,n]of i)try{e.setItem(t,n)}catch(e){console.error(`Failed to persist deferred storage value`,e)}for(let t of a)try{e.removeItem(t)}catch(e){console.error(`Failed to remove deferred storage value`,e)}},a=()=>{r===void 0&&(r=setTimeout(i,0))};return An(i),{getItem:r=>t.has(r)?t.get(r)??null:n.has(r)?null:e.getItem(r),setItem:(e,r)=>{t.set(e,r),n.delete(e),a()},removeItem:e=>{t.delete(e),n.add(e),a()},clear:()=>{t.clear(),n.clear(),r!==void 0&&(clearTimeout(r),r=void 0),e.clear()},key:t=>e.key(t),get length(){return e.length}}},Pn=e=>{if(typeof window>`u`)return null;try{return window[e]??null}catch{return null}},Fn=()=>{let e=new Map;return{getItem:t=>e.get(t)??null,setItem:(t,n)=>{e.set(t,n)},removeItem:t=>{e.delete(t)},clear:()=>{e.clear()},key:t=>Array.from(e.keys())[t]??null,get length(){return e.size}}},In=()=>{let e=Pn(`localStorage`);if(!e)return Fn();let t=Fn(),n=!0,r=()=>{n=!1};return{getItem:i=>{if(n)try{let t=e.getItem(i);if(t!==null)return t}catch{r()}return t.getItem(i)},setItem:(i,a)=>{if(n)try{e.setItem(i,a),t.removeItem(i);return}catch{r();try{e.removeItem(i)}catch{}}t.setItem(i,a)},removeItem:n=>{try{e.removeItem(n)}catch{r()}t.removeItem(n)},clear:()=>{try{e.clear()}catch{r()}t.clear()},key:i=>{if(n)try{return e.key(i)}catch{r()}return t.key(i)},get length(){if(n)try{return e.length+t.length}catch{r()}return t.length}}},Ln=()=>(Tn||=In(),Tn),Rn=()=>(Dn||=Nn(Ln()),Dn),zn=()=>{let e=Pn(`sessionStorage`);if(!e)return Fn();let t=Fn(),n=!0,r=()=>{n=!1};return{getItem:i=>{if(n)try{let t=e.getItem(i);if(t!==null)return t}catch{r()}return t.getItem(i)},setItem:(i,a)=>{if(n)try{e.setItem(i,a),t.removeItem(i);return}catch{r();try{e.removeItem(i)}catch{}}t.setItem(i,a)},removeItem:n=>{try{e.removeItem(n)}catch{r()}t.removeItem(n)},clear:()=>{try{e.clear()}catch{r()}t.clear()},key:i=>{if(n)try{return e.key(i)}catch{r()}return t.key(i)},get length(){if(n)try{return e.length+t.length}catch{r()}return t.length}}},Bn=()=>(En||=zn(),En);function Vn(e,t){return t>=12?e:(e.chatRenderMode===`live`&&(e.chatRenderMode=`sorted`),e.activityRenderMode===`summary`&&(e.activityRenderMode=`collapsed`),e.showTurnChangedFiles===!1&&(e.showTurnChangedFiles=!0),e)}var Hn={markdown:`0.875rem`,code:`0.75rem`,uiHeader:`0.9375rem`,uiLabel:`0.8750rem`,meta:`0.875rem`,micro:`0.875rem`},Un={markdown:`0.9375rem`,code:`0.8125rem`,uiHeader:`0.875rem`,uiLabel:`0.8125rem`,meta:`0.8125rem`,micro:`0.75rem`},Wn={markdown:`0.9063rem`,code:`0.8750rem`,uiHeader:`0.9063rem`,uiLabel:`0.8438rem`,meta:`0.8438rem`,micro:`0.7813rem`};function Gn(e){return`--text-${e.replace(/([A-Z])/g,`-$1`).toLowerCase()}`}function Kn(e=document.documentElement){return e.classList.contains(`mobile-pointer`)&&!e.classList.contains(`desktop-runtime`)}function qn(e,t){return t?.mobile?Un[e]:Hn[e]}var Jn={semanticMarkdown:{fontSize:`var(--text-markdown)`},semanticCode:{fontSize:`var(--text-code)`},uiHeader:{fontSize:`var(--text-ui-header)`},uiLabel:{fontSize:`var(--text-ui-label)`},meta:{fontSize:`var(--text-meta)`},micro:{fontSize:`var(--text-micro)`},ui:{button:{fontSize:`var(--text-ui-label)`,lineHeight:`var(--ui-button-line-height)`,letterSpacing:`var(--ui-button-letter-spacing)`,fontWeight:`var(--ui-button-font-weight)`},buttonSmall:{fontSize:`var(--text-meta)`,lineHeight:`var(--ui-button-small-line-height)`,letterSpacing:`var(--ui-button-small-letter-spacing)`,fontWeight:`var(--ui-button-small-font-weight)`},buttonLarge:{fontSize:`var(--text-ui-label)`,lineHeight:`var(--ui-button-large-line-height)`,letterSpacing:`var(--ui-button-large-letter-spacing)`,fontWeight:`var(--ui-button-large-font-weight)`},label:{fontSize:`var(--text-meta)`,lineHeight:`var(--ui-label-line-height)`,letterSpacing:`var(--ui-label-letter-spacing)`,fontWeight:`var(--ui-label-font-weight)`},caption:{fontSize:`var(--text-micro)`,lineHeight:`var(--ui-caption-line-height)`,letterSpacing:`var(--ui-caption-letter-spacing)`,fontWeight:`var(--ui-caption-font-weight)`},badge:{fontSize:`var(--text-micro)`,lineHeight:`var(--ui-badge-line-height)`,letterSpacing:`var(--ui-badge-letter-spacing)`,fontWeight:`var(--ui-badge-font-weight)`},tooltip:{fontSize:`var(--text-micro)`,lineHeight:`var(--ui-tooltip-line-height)`,letterSpacing:`var(--ui-tooltip-letter-spacing)`,fontWeight:`var(--ui-tooltip-font-weight)`},input:{fontSize:`var(--text-ui-label)`,lineHeight:`var(--ui-input-line-height)`,letterSpacing:`var(--ui-input-letter-spacing)`,fontWeight:`var(--ui-input-font-weight)`},helperText:{fontSize:`var(--text-meta)`,lineHeight:`var(--ui-helper-text-line-height)`,letterSpacing:`var(--ui-helper-text-letter-spacing)`,fontWeight:`var(--ui-helper-text-font-weight)`}},code:{inline:{fontSize:`var(--text-code)`,lineHeight:`var(--code-inline-line-height)`,letterSpacing:`var(--code-inline-letter-spacing)`,fontWeight:`var(--code-inline-font-weight)`},block:{fontSize:`var(--text-code)`,lineHeight:`var(--code-block-line-height)`,letterSpacing:`var(--code-block-letter-spacing)`,fontWeight:`var(--code-block-font-weight)`},lineNumbers:{fontSize:`var(--text-micro)`,lineHeight:`var(--code-line-numbers-line-height)`,letterSpacing:`var(--code-line-numbers-letter-spacing)`,fontWeight:`var(--code-line-numbers-font-weight)`}},markdown:{body:{fontSize:`var(--text-markdown)`,lineHeight:`var(--markdown-body-line-height)`,letterSpacing:`var(--markdown-body-letter-spacing)`,fontWeight:`var(--markdown-body-font-weight)`},bodySmall:{fontSize:`var(--text-meta)`,lineHeight:`var(--markdown-body-small-line-height)`,letterSpacing:`var(--markdown-body-small-letter-spacing)`,fontWeight:`var(--markdown-body-small-font-weight)`},bodyLarge:{fontSize:`var(--text-markdown)`,lineHeight:`var(--markdown-body-large-line-height)`,letterSpacing:`var(--markdown-body-large-letter-spacing)`,fontWeight:`var(--markdown-body-large-font-weight)`},blockquote:{fontSize:`var(--text-markdown)`,lineHeight:`var(--markdown-blockquote-line-height)`,letterSpacing:`var(--markdown-blockquote-letter-spacing)`,fontWeight:`var(--markdown-blockquote-font-weight)`},list:{fontSize:`var(--text-markdown)`,lineHeight:`var(--markdown-list-line-height)`,letterSpacing:`var(--markdown-list-letter-spacing)`,fontWeight:`var(--markdown-list-font-weight)`},link:{fontSize:`var(--text-markdown)`,lineHeight:`var(--markdown-link-line-height)`,letterSpacing:`var(--markdown-link-letter-spacing)`,fontWeight:`var(--markdown-link-font-weight)`},code:{fontSize:`var(--text-code)`,lineHeight:`var(--markdown-code-line-height)`,letterSpacing:`var(--markdown-code-letter-spacing)`,fontWeight:`var(--markdown-code-font-weight)`},codeBlock:{fontSize:`var(--text-code)`,lineHeight:`var(--markdown-code-block-line-height)`,letterSpacing:`var(--markdown-code-block-letter-spacing)`,fontWeight:`var(--markdown-code-block-font-weight)`}},tool:{collapsed:{fontSize:`var(--text-code)`,lineHeight:`var(--code-block-line-height)`,letterSpacing:`var(--code-block-letter-spacing)`,fontWeight:`var(--code-block-font-weight)`},popup:{fontSize:`var(--text-code)`,lineHeight:`var(--code-block-line-height)`,letterSpacing:`var(--code-block-letter-spacing)`,fontWeight:`var(--code-block-font-weight)`},inline:{fontSize:`var(--text-code)`,lineHeight:`var(--code-inline-line-height)`,letterSpacing:`var(--code-inline-letter-spacing)`,fontWeight:`var(--code-inline-font-weight)`}}},Yn={padding:{collapsed:`0.375rem`,popup:`0.75rem`,popupContainer:`1rem`},backgroundOpacity:{muted:`30`,mutedAlt:`50`},getCollapsedStyles:()=>({...Jn.tool.collapsed,background:`transparent`,backgroundColor:`transparent`,margin:0,padding:Yn.padding.collapsed,borderRadius:0}),getPopupStyles:()=>({...Jn.tool.popup,background:`transparent`,backgroundColor:`transparent`,margin:0,padding:Yn.padding.popup,borderRadius:`0.75rem`}),getPopupContainerStyles:()=>({...Jn.tool.popup,background:`transparent`,backgroundColor:`transparent`,margin:0,padding:Yn.padding.popupContainer,borderRadius:`0.5rem`,overflowX:`auto`}),getInlineStyles:()=>({...Jn.tool.inline})},Xn=[{id:`inter`,label:`Inter`,description:`Modern UI sans with excellent readability at small sizes.`,stack:`"Inter", "SF Pro Text", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`,source:{family:`Inter`,packageName:`@fontsource/inter`,filePrefix:`inter`,weights:[400,500,600]}},{id:`geist-sans`,label:`Geist Sans`,description:`Crisp sans-serif with a technical interface feel.`,stack:`"Geist Sans", "SF Pro Text", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`,source:{family:`Geist Sans`,packageName:`@fontsource/geist-sans`,filePrefix:`geist-sans`,weights:[400,500,600]}},{id:`atkinson-hyperlegible`,label:`Atkinson Hyperlegible`,description:`Accessibility-focused sans-serif optimized for character distinction.`,stack:`"Atkinson Hyperlegible", "SF Pro Text", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`,source:{family:`Atkinson Hyperlegible`,packageName:`@fontsource/atkinson-hyperlegible`,filePrefix:`atkinson-hyperlegible`,weights:[400,700]}},{id:`source-sans-3`,label:`Source Sans 3`,description:`Adobe sans-serif tuned for clean, readable interfaces.`,stack:`"Source Sans 3", "SF Pro Text", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`,source:{family:`Source Sans 3`,packageName:`@fontsource/source-sans-3`,filePrefix:`source-sans-3`,weights:[400,500,600]}},{id:`roboto`,label:`Roboto`,description:`Familiar Material-style sans-serif with broad UI usage.`,stack:`"Roboto", "SF Pro Text", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`,source:{family:`Roboto`,packageName:`@fontsource/roboto`,filePrefix:`roboto`,weights:[400,500,600]}},{id:`noto-sans`,label:`Noto Sans`,description:`Readable sans-serif with strong international coverage.`,stack:`"Noto Sans", "SF Pro Text", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`,source:{family:`Noto Sans`,packageName:`@fontsource/noto-sans`,filePrefix:`noto-sans`,weights:[400,500,600]}},{id:`dm-sans`,label:`DM Sans`,description:`Modern product UI sans-serif with friendly proportions.`,stack:`"DM Sans", "SF Pro Text", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`,source:{family:`DM Sans`,packageName:`@fontsource/dm-sans`,filePrefix:`dm-sans`,weights:[400,500,600]}},{id:`manrope`,label:`Manrope`,description:`Polished geometric sans-serif for modern app interfaces.`,stack:`"Manrope", "SF Pro Text", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`,source:{family:`Manrope`,packageName:`@fontsource/manrope`,filePrefix:`manrope`,weights:[400,500,600]}},{id:`system`,label:`System`,description:`Native operating system interface font.`,stack:`-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif`}],Zn=[{id:`jetbrains-mono`,label:`JetBrains Mono`,description:`Developer-focused monospace with strong punctuation clarity.`,stack:`"JetBrains Mono", "SFMono-Regular", "Menlo", monospace`,source:{family:`JetBrains Mono`,packageName:`@fontsource/jetbrains-mono`,filePrefix:`jetbrains-mono`,weights:[400,500,600]}},{id:`fira-code`,label:`Fira Code`,description:`Readable coding font with ligature support.`,stack:`"Fira Code", "SFMono-Regular", "Menlo", monospace`,source:{family:`Fira Code`,packageName:`@fontsource/fira-code`,filePrefix:`fira-code`,weights:[400,500,600]}},{id:`geist-mono`,label:`Geist Mono`,description:`Sharp monospace pair for Geist Sans.`,stack:`"Geist Mono", "SFMono-Regular", "Menlo", monospace`,source:{family:`Geist Mono`,packageName:`@fontsource/geist-mono`,filePrefix:`geist-mono`,weights:[400,500,600]}},{id:`commit-mono`,label:`Commit Mono`,description:`Code-oriented monospace with polished editor ergonomics.`,stack:`"Commit Mono", "SFMono-Regular", "Menlo", monospace`,source:{family:`Commit Mono`,packageName:`@fontsource/commit-mono`,filePrefix:`commit-mono`,weights:[400,500,600]}},{id:`source-code-pro`,label:`Source Code Pro`,description:`Adobe monospace designed for source code readability.`,stack:`"Source Code Pro", "SFMono-Regular", "Menlo", monospace`,source:{family:`Source Code Pro`,packageName:`@fontsource/source-code-pro`,filePrefix:`source-code-pro`,weights:[400,500,600]}},{id:`cascadia-code`,label:`Cascadia Code`,description:`Microsoft coding font popular in terminals and editors.`,stack:`"Cascadia Code", "SFMono-Regular", "Menlo", monospace`,source:{family:`Cascadia Code`,packageName:`@fontsource/cascadia-code`,filePrefix:`cascadia-code`,weights:[400,500,600]}},{id:`roboto-mono`,label:`Roboto Mono`,description:`Neutral monospace companion to Roboto.`,stack:`"Roboto Mono", "SFMono-Regular", "Menlo", monospace`,source:{family:`Roboto Mono`,packageName:`@fontsource/roboto-mono`,filePrefix:`roboto-mono`,weights:[400,500,600]}},{id:`iosevka`,label:`Iosevka`,description:`Compact monospace for dense code and terminal layouts.`,stack:`"Iosevka", "SFMono-Regular", "Menlo", monospace`,source:{family:`Iosevka`,packageName:`@fontsource/iosevka`,filePrefix:`iosevka`,weights:[400,500,600]}},{id:`system-mono`,label:`System Mono`,description:`Native operating system monospace font.`,stack:`ui-monospace, "SFMono-Regular", "SF Mono", Menlo, Consolas, "Liberation Mono", monospace`}],Qn=e=>Object.fromEntries(e.map(e=>[e.id,e])),$n=Qn(Xn),er=Qn(Zn),tr=`system`,nr=`system-mono`,rr=e=>typeof e==`string`&&e in $n,ir=e=>typeof e==`string`&&e in er,ar=`openchamber.mobileKeyboardMode`,or=`meta[name="viewport"]`,sr=`width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover`,cr=()=>!0;function lr(e,t=`resize-content`){return e===`native`||e===`resize-content`?e:t}var ur=e=>lr(e)===`resize-content`?`${sr}, interactive-widget=resizes-content`:sr,dr=()=>{if(typeof window>`u`)return`resize-content`;try{return lr(localStorage.getItem(ar))}catch{return`resize-content`}},fr=e=>{let t=lr(e);if(typeof window<`u`)try{t===`resize-content`?localStorage.removeItem(ar):localStorage.setItem(ar,t)}catch{}return t},pr=e=>{let t=fr(e);if(typeof document>`u`)return t;document.documentElement.setAttribute(`data-oc-mobile-keyboard-mode`,t);let n=document.querySelector(or);if(n instanceof HTMLMetaElement){let e=ur(t);n.getAttribute(`content`)!==e&&n.setAttribute(`content`,e)}return t};function mr(e){return e===`vim`?`vim`:`default`}var hr={completion:{title:`{agent_name} is ready`,message:`{last_message}`},error:{title:`Tool error`,message:`{last_message}`},question:{title:`{agent_name} needs input`,message:`{last_message}`},subtask:{title:`Subtask complete`,message:`{last_message}`}},gr={completion:{title:`Task completed`,message:`{session_name}`},error:{title:`Something went wrong`,message:`{session_name}`},question:{title:`Needs your answer`,message:`{session_name}`},subtask:{title:`Task completed`,message:`{session_name}`}},_r={completion:{title:`{agent_name} is ready`,message:`{model_name} completed the task`},error:{title:`Tool error`,message:`{last_message}`},question:{title:`Input needed`,message:`{last_message}`},subtask:{title:`{agent_name} is ready`,message:`{model_name} completed the task`}},J={completion:{title:``,message:``},error:{title:``,message:``},question:{title:``,message:``},subtask:{title:``,message:``}},vr=(e,t)=>e?e.title===t.title&&e.message===t.message:!1,yr=e=>{if(!e||typeof e!=`object`)return!1;let t=e,n=e=>vr(t.completion,e.completion)&&vr(t.error,e.error)&&vr(t.question,e.question)&&vr(t.subtask,e.subtask);return n(hr)||n(gr)||n(_r)},br=380,xr=380,Sr=1400,Cr=12,wr=40,Tr=120,Y=260,Er=new Map,Dr=e=>(e??xn()).trim()||`default`,X=e=>{if(!e)return``;let t=e.replace(/\\/g,`/`),n=t.startsWith(`//`),r=t.replace(/\/+$/g,``);return r=r.replace(/\/+/g,`/`),n&&!r.startsWith(`//`)&&(r=`/${r}`),r===``?t.startsWith(`/`)?`/`:``:r},Or=e=>Number.isFinite(e)?Math.min(Sr,Math.max(xr,Math.round(e))):br,kr=e=>{if(typeof e!=`string`)return null;let t=e.trim();return t?t.replace(/\\/g,`/`):null},Ar=e=>{if(typeof e!=`string`)return null;let t=e.trim();return t?t.length>Tr?t.slice(0,Tr):t:null},jr=e=>e===`working`||e===`staged`||e===`turn`?e:null,Mr=e=>typeof e==`string`&&e.trim()||null,Nr=e=>typeof e==`string`&&e.trim()||null,Pr=(e,t)=>(e===`file`||e===`preview`)&&t||e,Fr=(e,t,n)=>{if(e===`diff`||e===`file-diff`)return e;if(typeof n==`string`){let e=n.trim();if(e)return e}return Pr(e,t)},Ir=(e,t)=>t===e?e:`${e}:${t}`,Lr=e=>e===`turn-diff-outside-workspace`?e:null,Rr=e=>{let t=kr(e.targetPath),n=Fr(e.mode,t,e.dedupeKey);return{id:Ir(e.mode,n),mode:e.mode,targetPath:t,dedupeKey:n,label:Ar(e.label),sessionTitleFallback:Ar(e.sessionTitleFallback),readOnly:e.readOnly===!0,stagedDiff:e.stagedDiff===!0,diffScope:jr(e.diffScope)??(e.stagedDiff===!0?`staged`:`working`),diffTargetLine:typeof e.diffTargetLine==`number`&&Number.isFinite(e.diffTargetLine)?Math.max(1,Math.trunc(e.diffTargetLine)):null,diffTurnMessageId:Mr(e.diffTurnMessageId),diffSessionId:Nr(e.diffSessionId),fileNotice:e.mode===`file`?Lr(e.fileNotice):null,touchedAt:Date.now()}},zr=(e,t,n)=>{if(e.length<=t)return e;let r=[...e].sort((e,t)=>e.touchedAt-t.touchedAt).filter(e=>e.id!==n),i=e.length-t;if(i<=0||r.length===0)return e.slice(-t);let a=new Set(r.slice(0,i).map(e=>e.id));return e.filter(e=>!a.has(e.id))},Br=e=>{if(!Array.isArray(e))return[];let t=[],n=new Set;for(let r of e){if(!r||typeof r!=`object`)continue;let e=r;if(e.mode!==`diff`&&e.mode!==`file-diff`&&e.mode!==`file`&&e.mode!==`context`&&e.mode!==`chat`&&e.mode!==`preview`&&e.mode!==`browser`)continue;let i=kr(typeof e.targetPath==`string`?e.targetPath:null),a=Fr(e.mode,i,typeof e.dedupeKey==`string`?e.dedupeKey:null),o=Ir(e.mode,a);!o||n.has(o)||(n.add(o),t.push({id:o,mode:e.mode,targetPath:i,dedupeKey:a,label:Ar(typeof e.label==`string`?e.label:null),sessionTitleFallback:Ar(typeof e.sessionTitleFallback==`string`?e.sessionTitleFallback:null),readOnly:e.readOnly===!0,stagedDiff:e.stagedDiff===!0,diffScope:jr(e.diffScope)??(e.stagedDiff===!0?`staged`:`working`),diffTargetLine:typeof e.diffTargetLine==`number`&&Number.isFinite(e.diffTargetLine)?Math.max(1,Math.trunc(e.diffTargetLine)):null,diffTurnMessageId:Mr(e.diffTurnMessageId),diffSessionId:Nr(e.diffSessionId),fileNotice:e.mode===`file`?Lr(e.fileNotice):null,touchedAt:typeof e.touchedAt==`number`&&Number.isFinite(e.touchedAt)?e.touchedAt:Date.now()}))}return t},Z=(e,t)=>t&&e.some(e=>e.id===t)?t:e.length===0?null:e[e.length-1].id,Q=e=>{if(e){let t=Br(e.tabs),n=Z(t,e.activeTabId);return{...e,tabs:t,activeTabId:n,touchedAt:Date.now()}}return{isOpen:!1,expanded:!1,tabs:[],activeTabId:null,width:br,touchedAt:Date.now()}},Vr=(e,t)=>{let n=Rr(t),r=e.tabs.findIndex(e=>e.id===n.id),i=r===-1?[...e.tabs,n]:e.tabs.map((e,t)=>t===r?{...e,diffTargetLine:n.diffTargetLine,diffTurnMessageId:n.diffTurnMessageId,diffSessionId:n.diffSessionId,mode:n.mode,targetPath:n.targetPath||e.targetPath,dedupeKey:n.dedupeKey,label:n.label,sessionTitleFallback:n.sessionTitleFallback||e.sessionTitleFallback,stagedDiff:n.stagedDiff,diffScope:n.diffScope,readOnly:n.readOnly,fileNotice:n.mode===`file`?n.fileNotice:null,touchedAt:Date.now()}:e),a=n.id,o=zr(i,Cr,a);return{...e,isOpen:!0,tabs:o,activeTabId:Z(o,a),touchedAt:Date.now()}},Hr=(e,t)=>{let n=e.tabs.filter(e=>e.id!==t),r=e.activeTabId===t?n[n.length-1]?.id??null:Z(n,e.activeTabId);return{...e,tabs:n,activeTabId:r,isOpen:n.length>0&&e.isOpen,touchedAt:Date.now()}},Ur=(e,t,n)=>{if(t===n)return e;let r=e.tabs.findIndex(e=>e.id===t),i=e.tabs.findIndex(e=>e.id===n);if(r===-1||i===-1)return e;let a=[...e.tabs],[o]=a.splice(r,1);return o?(a.splice(i,0,o),{...e,tabs:a,touchedAt:Date.now()}):e},Wr=(e,t,n)=>({...e,tabs:e.tabs.map(e=>e.id===t?{...e,targetPath:n}:e)}),Gr=e=>{if(!e||typeof e!=`object`)return{};let t=e,n={};for(let[e,r]of Object.entries(t)){let t=X(e);if(!t||!r||typeof r!=`object`)continue;let i=r,a=Br(i.tabs),o=typeof i.activeTabId==`string`?i.activeTabId:null;a.length===0&&(i.mode===`diff`||i.mode===`file-diff`||i.mode===`file`||i.mode===`context`||i.mode===`chat`)&&(a=[Rr({mode:i.mode,targetPath:typeof i.targetPath==`string`?i.targetPath:null,dedupeKey:typeof i.dedupeKey==`string`?i.dedupeKey:null,label:typeof i.label==`string`?i.label:null})],o=a[0]?.id??null);let s=Z(a,o),c=zr(a,Cr,s);n[t]={isOpen:i.isOpen===!0,expanded:i.expanded===!0,tabs:c,activeTabId:Z(c,s),width:Or(typeof i.width==`number`?i.width:br),touchedAt:typeof i.touchedAt==`number`&&Number.isFinite(i.touchedAt)?i.touchedAt:Date.now()}}return n},$=(e,t)=>{let n=Object.entries(e);if(n.length<=t)return e;n.sort((e,t)=>(t[1]?.touchedAt??0)-(e[1]?.touchedAt??0));let r={};for(let[e,i]of n.slice(0,t))r[e]=i;return r},Kr=(e,t)=>{let n=Object.entries(e);if(n.length<=t)return e;n.sort((e,t)=>(t[1]?.touchedAt??0)-(e[1]?.touchedAt??0));let r={};for(let[e,i]of n.slice(0,t))r[e]=i;return r},qr=(e,t)=>{let n=X((t||``).trim())||null,r=n?e.contextPanelByDirectory[n]:void 0;return{isRightSidebarOpen:e.isRightSidebarOpen,rightSidebarTab:e.rightSidebarTab,contextPanelDirectory:n,contextPanelIsOpen:!!(r?.isOpen&&r.tabs.length>0),contextPanelActiveTabId:r?.activeTabId??null,contextPanelExpanded:!!r?.expanded,touchedAt:Date.now()}},Jr=(e,t,n)=>{let r=X((t||``).trim());if(!r)return e;let i=e[r];if(!i)return e;let a=!!(n?.contextPanelIsOpen&&n.contextPanelDirectory===r&&i.tabs.length>0),o=a?Z(i.tabs,n?.contextPanelActiveTabId??i.activeTabId):i.activeTabId,s=a?!!n?.contextPanelExpanded:i.expanded;return i.isOpen===a&&i.activeTabId===o&&i.expanded===s?e:{...e,[r]:{...i,isOpen:a,activeTabId:o,expanded:s,touchedAt:Date.now()}}},Yr=e()(n(t((e,t)=>({theme:`system`,isMultiRunLauncherOpen:!1,isSidebarOpen:!0,sidebarWidth:Y,hasManuallyResizedLeftSidebar:!1,isRightSidebarOpen:!1,rightSidebarWidth:360,hasManuallyResizedRightSidebar:!1,rightSidebarTab:`git`,contextPanelByDirectory:{},contextToolDiffByDirectory:{},sessionWorkspacePanelById:{},contextPanelsOpenBeforeRightSidebarCollapse:[],isBottomTerminalOpen:!1,isBottomTerminalExpanded:!1,bottomTerminalHeight:300,hasManuallyResizedBottomTerminal:!1,isSessionSwitcherOpen:!1,isSessionDropdownOpen:!1,activeMainTab:`chat`,mainTabGuard:null,sidebarOpenBeforeFullscreenTab:null,pendingDiffFile:null,pendingDiffStaged:!1,pendingDiffScope:null,pendingDiffLine:null,pendingDiagramFile:null,pendingFileNavigation:null,pendingFileFocusPath:null,pendingFileViewerMode:null,isMobile:!1,isCommandPaletteOpen:!1,isHelpDialogOpen:!1,isAboutDialogOpen:!1,isOpenCodeStatusDialogOpen:!1,openCodeStatusText:``,isSessionCreateDialogOpen:!1,isScheduledTasksDialogOpen:!1,isArchivedSessionsDialogOpen:!1,isSettingsDialogOpen:!1,isNewWorktreeDialogOpen:!1,isModelSelectorOpen:!1,isAgentSelectorOpen:!1,isModelSelectorInstant:!1,isAgentSelectorInstant:!1,sidebarSection:`sessions`,settingsPage:`home`,settingsHasOpenedOnce:!1,settingsProjectsSelectedId:null,settingsRemoteInstancesSelectedId:null,eventStreamStatus:`idle`,eventStreamHint:null,showReasoningTraces:!0,sessionTitleRefreshEnabled:!0,sessionGoalEnabled:!0,sessionGoalDefaultBudgetEnabled:!1,sessionGoalDefaultBudget:2e5,collapsibleThinkingBlocks:!0,chatRenderMode:`sorted`,activityRenderMode:`collapsed`,showDeletionDialog:!0,autoDeleteEnabled:!1,autoDeleteAfterDays:30,sessionRetentionAction:`archive`,autoDeleteLastRunAt:null,messageLimit:200,fontSize:100,codeFontSize:100,globalDraftStarters:null,terminalFontSize:13,editorFontSize:13,uiFont:tr,monoFont:nr,padding:100,cornerRadius:18,inputBarOffset:0,mobileKeyboardMode:dr(),favoriteModels:[],hiddenModels:[],providerOrder:[],collapsedModelProviders:[],recentModels:[],recentAgents:[],recentEfforts:{},diffLayoutPreference:`inline`,diffFileLayout:{},diffWrapLines:!1,gitChangesViewMode:`tree`,isTimelineDialogOpen:!1,isPromptNavigatorPanelOpen:!1,isImagePreviewOpen:!1,nativeNotificationsEnabled:!1,notificationMode:`hidden-only`,notifyOnSubtasks:!1,dockBadgeEnabled:!0,notifyOnCompletion:!0,notifyOnError:!0,notifyOnQuestion:!0,notificationTemplates:{completion:{...J.completion},error:{...J.error},question:{...J.question},subtask:{...J.subtask}},summarizeLastMessage:!1,summaryThreshold:200,summaryLength:100,maxLastMessageLength:250,showTerminalQuickKeysOnDesktop:!1,persistChatDraft:!0,showOpenCodeUpdateNotifications:!0,inputSpellcheckEnabled:!1,wideChatLayoutEnabled:!1,codeBlockLineWrap:!0,showToolFileIcons:!0,showTurnChangedFiles:!0,showExpandedBashTools:!1,showSubagentTaskDetails:!1,timeFormatPreference:`auto`,weekStartPreference:`auto`,desktopWindowControlsPosition:`auto`,mermaidRenderingMode:`svg`,userMessageRenderingMode:`markdown`,collapsibleUserMessages:!0,stickyUserHeader:!1,promptNavigatorEnabled:!1,expandedEditorToolbar:!1,showSplitAssistantMessageActions:!1,showAssistantTps:!0,allowPromptingSubagentSessions:!1,isMobileSessionStatusBarCollapsed:!1,mobileSessionPanelOpen:!1,mobileSessionFilterProjectId:null,otaChannelOverride:null,isExpandedInput:!1,reportUsage:!1,shortcutOverrides:{},fileEditorKeymap:`default`,setTheme:n=>{e({theme:n}),t().applyTheme()},toggleSidebar:()=>{e(e=>{let t=!e.isSidebarOpen;return t&&!e.hasManuallyResizedLeftSidebar?{isSidebarOpen:t,sidebarWidth:Y}:{isSidebarOpen:t}})},setSidebarOpen:t=>{e(e=>e.isSidebarOpen===t?t&&!e.hasManuallyResizedLeftSidebar&&e.sidebarWidth!==Y?{isSidebarOpen:t,sidebarWidth:Y}:e:t&&!e.hasManuallyResizedLeftSidebar?{isSidebarOpen:t,sidebarWidth:Y}:{isSidebarOpen:t})},setSidebarWidth:t=>{e({sidebarWidth:t,hasManuallyResizedLeftSidebar:!0})},toggleRightSidebar:()=>{e(e=>{if(e.isRightSidebarOpen){let t=Object.entries(e.contextPanelByDirectory).filter(([,e])=>e.isOpen&&e.tabs.length>0).map(([e])=>e);return{isRightSidebarOpen:!1,contextPanelByDirectory:t.length===0?e.contextPanelByDirectory:Object.fromEntries(Object.entries(e.contextPanelByDirectory).map(([e,n])=>[e,t.includes(e)?{...n,isOpen:!1}:n])),contextPanelsOpenBeforeRightSidebarCollapse:t}}let t=e.contextPanelsOpenBeforeRightSidebarCollapse.length===0?e.contextPanelByDirectory:Object.fromEntries(Object.entries(e.contextPanelByDirectory).map(([t,n])=>[t,e.contextPanelsOpenBeforeRightSidebarCollapse.includes(t)&&n.tabs.length>0?{...n,isOpen:!0}:n]));return e.hasManuallyResizedRightSidebar?{isRightSidebarOpen:!0,contextPanelByDirectory:t,contextPanelsOpenBeforeRightSidebarCollapse:[]}:{isRightSidebarOpen:!0,rightSidebarWidth:360,contextPanelByDirectory:t,contextPanelsOpenBeforeRightSidebarCollapse:[]}})},setRightSidebarOpen:t=>{e(e=>e.isRightSidebarOpen===t?e:{isRightSidebarOpen:t,rightSidebarWidth:t&&!e.hasManuallyResizedRightSidebar&&e.rightSidebarWidth!==360?360:e.rightSidebarWidth})},setRightSidebarWidth:t=>{e({rightSidebarWidth:Math.min(860,Math.max(360,t)),hasManuallyResizedRightSidebar:!0})},setRightSidebarTab:t=>{e({rightSidebarTab:t})},syncWorkspacePanelsForSessionSwitch:({previousSessionId:t,previousDirectory:n,nextSessionId:r,nextDirectory:i})=>{let a=typeof t==`string`?t.trim():``,o=typeof r==`string`?r.trim():``;a!==o&&e(e=>{let t=e.sessionWorkspacePanelById;a&&(t={...t,[a]:qr(e,n)});let r=o?t[o]:void 0,s=Jr(e.contextPanelByDirectory,i,r),c=X((n||``).trim()),l=X((i||``).trim()),u=s;if(c&&c!==l){let e=u[c];e?.isOpen&&(u={...u,[c]:{...e,isOpen:!1,touchedAt:Date.now()}})}let d=r?r.isRightSidebarOpen:!1,f=r?.rightSidebarTab??e.rightSidebarTab;return{sessionWorkspacePanelById:Kr(t,wr),contextPanelByDirectory:u,isRightSidebarOpen:d,rightSidebarTab:f,contextPanelsOpenBeforeRightSidebarCollapse:[]}})},openContextPanelTab:(t,n)=>{let r=X((t||``).trim());r&&e(e=>{let t=e.contextPanelByDirectory[r],i=Q(t),a={...e.contextPanelByDirectory,[r]:Vr(i,n)};if(n.mode===`diff`||n.mode===`file-diff`){let t={...e.contextToolDiffByDirectory};return delete t[r],{contextPanelByDirectory:$(a,20),contextToolDiffByDirectory:t}}return{contextPanelByDirectory:$(a,20)}})},openContextDiff:(e,n,r=!1,i=null,a,o,s)=>{let c=X((e||``).trim()),l=(n||``).trim();if(!c||!l)return;let u=jr(i)??(r?`staged`:`working`);t().openContextPanelTab(c,{mode:`diff`,targetPath:l,stagedDiff:u===`staged`,diffScope:u,diffTargetLine:a,diffTurnMessageId:o,diffSessionId:s})},openContextToolDiff:(t,n,r,i,a,o)=>{let s=X((t||``).trim()),c=(n||``).trim(),l=r.flatMap(e=>{let t=kr(e.path),n=typeof e.patch==`string`?e.patch:``;return t&&n.trim()?[{path:t,patch:n}]:[]});if(!s||!c||l.length===0)return;let u={mode:`diff`,targetPath:c,stagedDiff:!1,diffScope:`turn`,diffTargetLine:i,diffTurnMessageId:a,diffSessionId:o};e(e=>{let t=e.contextPanelByDirectory[s],n=Q(t),r=$({...e.contextPanelByDirectory,[s]:Vr(n,u)},20),i=new Set(Object.keys(r)),o=Object.fromEntries(Object.entries(e.contextToolDiffByDirectory).filter(([e])=>i.has(e)));return o[s]={targetPath:c,patches:l,turnMessageId:Mr(a)},{contextPanelByDirectory:r,contextToolDiffByDirectory:o}})},openContextFileDiff:(e,n,r=!1,i=null)=>{let a=X((e||``).trim()),o=(n||``).trim();if(!a||!o)return;let s=jr(i)??(r?`staged`:`working`);t().openContextPanelTab(a,{mode:`file-diff`,targetPath:o,stagedDiff:s===`staged`,diffScope:s})},openContextFile:(e,n,r)=>{let i=X((e||``).trim()),a=kr(n);!i||!a||(t().openContextPanelTab(i,{mode:`file`,targetPath:a,fileNotice:Lr(r?.fileNotice)}),t().setPendingFileFocusPath(a),t().setPendingFileNavigation(null),t().setPendingFileViewerMode(r?.viewerMode??null))},openContextFileAtLine:(e,n,r,i)=>{let a=X((e||``).trim()),o=kr(n),s=Number.isFinite(r)?Math.max(1,Math.trunc(r)):1,c=Number.isFinite(i)?Math.max(1,Math.trunc(i)):1;!a||!o||(t().openContextPanelTab(a,{mode:`file`,targetPath:o}),t().setPendingFileFocusPath(null),t().setPendingFileNavigation({path:o,line:s,column:c}))},openContextOverview:e=>{let n=X((e||``).trim());n&&t().openContextPanelTab(n,{mode:`context`})},openContextPreview:(e,n)=>{let r=X((e||``).trim()),i=(n||``).trim();if(!r||!i)return;let a=null;try{let e=new URL(i);(e.protocol===`http:`||e.protocol===`https:`)&&(a=e.host||e.hostname||`Preview`)}catch{}t().openContextPanelTab(r,{mode:`preview`,targetPath:i,dedupeKey:i,label:a})},openContextBrowser:(e,n=``)=>{let r=X((e||``).trim());if(!r)return;let i=typeof n==`string`&&n.trim().length>0?n.trim():``;t().openContextPanelTab(r,{mode:`browser`,targetPath:i,dedupeKey:`desktop-browser`,label:`Browser`})},setContextPanelTabTargetPath:(t,n,r)=>{let i=X((t||``).trim()),a=(n||``).trim();!i||!a||e(e=>{let t=e.contextPanelByDirectory[i];return t?{contextPanelByDirectory:{...e.contextPanelByDirectory,[i]:Wr(t,a,r)}}:e})},setActiveContextPanelTab:(t,n)=>{let r=X((t||``).trim()),i=(n||``).trim();!r||!i||e(e=>{let t=e.contextPanelByDirectory[r],n=Q(t);return!n.tabs.some(e=>e.id===i)||n.activeTabId===i&&n.isOpen?e:{contextPanelByDirectory:$({...e.contextPanelByDirectory,[r]:{...n,isOpen:!0,activeTabId:i,touchedAt:Date.now(),tabs:n.tabs.map(e=>e.id===i?{...e,touchedAt:Date.now()}:e)}},20)}})},reorderContextPanelTabs:(t,n,r)=>{let i=X((t||``).trim()),a=(n||``).trim(),o=(r||``).trim();!i||!a||!o||e(e=>{let t=e.contextPanelByDirectory[i],n=Q(t);if(!n.tabs.some(e=>e.id===a)||!n.tabs.some(e=>e.id===o))return e;let r=Ur(n,a,o);return r.tabs===n.tabs?e:{contextPanelByDirectory:$({...e.contextPanelByDirectory,[i]:r},20)}})},closeContextPanelTab:(t,n)=>{let r=X((t||``).trim()),i=(n||``).trim();!r||!i||e(e=>{let t=e.contextPanelByDirectory[r],n=Q(t);if(!n.tabs.some(e=>e.id===i))return e;let a={...e.contextPanelByDirectory,[r]:Hr(n,i)};if(i===`diff`){let t={...e.contextToolDiffByDirectory};return delete t[r],{contextPanelByDirectory:$(a,20),contextToolDiffByDirectory:t}}return{contextPanelByDirectory:$(a,20)}})},closeActiveContextPanelTab:e=>{let n=X((e||``).trim());if(!n)return!1;let r=t().contextPanelByDirectory[n];if(!r?.isOpen||r.tabs.length===0)return!1;let i=Z(r.tabs,r.activeTabId);return i?(t().closeContextPanelTab(n,i),!0):!1},closeContextPanel:t=>{let n=X((t||``).trim());n&&e(e=>{let t=e.contextPanelByDirectory[n];return!t||!t.isOpen?e:{contextPanelByDirectory:$({...e.contextPanelByDirectory,[n]:{...Q(t),isOpen:!1}},20)}})},toggleContextPanelExpanded:t=>{let n=X((t||``).trim());n&&e(e=>{let t=e.contextPanelByDirectory[n],r=Q(t);return{contextPanelByDirectory:$({...e.contextPanelByDirectory,[n]:{...r,expanded:!r.expanded}},20)}})},setContextPanelWidth:(t,n)=>{let r=X((t||``).trim());r&&e(e=>{let t=e.contextPanelByDirectory[r],i=Q(t);return{contextPanelByDirectory:$({...e.contextPanelByDirectory,[r]:{...i,width:Or(n)}},20)}})},toggleBottomTerminal:()=>{e(e=>{let t=!e.isBottomTerminalOpen;return t&&typeof window<`u`?{isBottomTerminalOpen:t,bottomTerminalHeight:Math.floor(window.innerHeight*.32),hasManuallyResizedBottomTerminal:!1}:{isBottomTerminalOpen:t}})},setBottomTerminalOpen:t=>{e(e=>{if(e.isBottomTerminalOpen===t){if(!t)return e;if(!e.hasManuallyResizedBottomTerminal&&typeof window<`u`){let n=Math.floor(window.innerHeight*.32);return e.bottomTerminalHeight===n&&e.hasManuallyResizedBottomTerminal===!1?e:{isBottomTerminalOpen:t,bottomTerminalHeight:n,hasManuallyResizedBottomTerminal:!1}}return e}return t&&typeof window<`u`?{isBottomTerminalOpen:t,bottomTerminalHeight:Math.floor(window.innerHeight*.32),hasManuallyResizedBottomTerminal:!1}:{isBottomTerminalOpen:t}})},setBottomTerminalExpanded:t=>{e({isBottomTerminalExpanded:t})},setBottomTerminalHeight:t=>{e({bottomTerminalHeight:t,hasManuallyResizedBottomTerminal:!0})},setSessionSwitcherOpen:n=>{t().isSessionSwitcherOpen!==n&&e({isSessionSwitcherOpen:n})},setSessionDropdownOpen:n=>{t().isSessionDropdownOpen!==n&&e({isSessionDropdownOpen:n})},setMainTabGuard:n=>{t().mainTabGuard!==n&&e({mainTabGuard:n})},setActiveMainTab:n=>{let r=t().mainTabGuard;return r&&!r(n)?!1:(Er.set(Dr(),n),e({activeMainTab:n}),!0)},prepareForRuntimeSwitch:n=>{Er.set(Dr(n),t().activeMainTab),e({contextToolDiffByDirectory:{}})},restoreForRuntimeSwitch:t=>{e({activeMainTab:Er.get(Dr(t))??`chat`})},setPendingDiffFile:(t,n=!1,r=null,i)=>{e({pendingDiffFile:t,pendingDiffStaged:t?n:!1,pendingDiffScope:t?r:null,pendingDiffLine:t&&typeof i==`number`&&Number.isFinite(i)?Math.max(1,Math.trunc(i)):null})},setPendingDiagramFile:t=>{e({pendingDiagramFile:t})},setPendingFileNavigation:t=>{e({pendingFileNavigation:t})},setPendingFileFocusPath:t=>{e({pendingFileFocusPath:t})},setPendingFileViewerMode:t=>{e({pendingFileViewerMode:t})},navigateToDiff:(n,r=!1,i=null,a)=>{let o=t().mainTabGuard;o&&!o(`diff`)||e({pendingDiffFile:n,pendingDiffStaged:r,pendingDiffScope:i,pendingDiffLine:typeof a==`number`&&Number.isFinite(a)?Math.max(1,Math.trunc(a)):null,activeMainTab:`diff`})},consumePendingDiffFile:()=>{let{pendingDiffFile:n}=t();return n&&e({pendingDiffFile:null,pendingDiffStaged:!1,pendingDiffScope:null,pendingDiffLine:null}),n},navigateToDiagram:n=>{let r=t().mainTabGuard;r&&!r(`diagram`)||e({pendingDiagramFile:n,activeMainTab:`diagram`})},consumePendingDiagramFile:()=>{let{pendingDiagramFile:n}=t();return n&&e({pendingDiagramFile:null}),n},setIsMobile:t=>{e({isMobile:t})},toggleCommandPalette:()=>{e(e=>({isCommandPaletteOpen:!e.isCommandPaletteOpen}))},setCommandPaletteOpen:t=>{e({isCommandPaletteOpen:t})},toggleHelpDialog:()=>{e(e=>({isHelpDialogOpen:!e.isHelpDialogOpen}))},setHelpDialogOpen:t=>{e({isHelpDialogOpen:t})},setAboutDialogOpen:t=>{e({isAboutDialogOpen:t})},setOpenCodeStatusDialogOpen:t=>{e({isOpenCodeStatusDialogOpen:t})},setOpenCodeStatusText:t=>{e({openCodeStatusText:t})},setSessionCreateDialogOpen:t=>{e({isSessionCreateDialogOpen:t})},setScheduledTasksDialogOpen:t=>{e({isScheduledTasksDialogOpen:t})},setArchivedSessionsDialogOpen:t=>{e({isArchivedSessionsDialogOpen:t})},setSettingsDialogOpen:t=>{e(e=>t?e.settingsHasOpenedOnce?{isSettingsDialogOpen:!0}:{isSettingsDialogOpen:!0,settingsHasOpenedOnce:!0}:{isSettingsDialogOpen:!1})},setNewWorktreeDialogOpen:t=>{e({isNewWorktreeDialogOpen:t})},setModelSelectorOpen:(t,n)=>{e(e=>t?{isModelSelectorOpen:!0,isAgentSelectorOpen:!1,isModelSelectorInstant:n?.instant===!0}:{isModelSelectorOpen:!1,isModelSelectorInstant:n?.instant===!0||n?.instant!==!1&&e.isModelSelectorInstant})},setAgentSelectorOpen:(t,n)=>{e(e=>t?{isAgentSelectorOpen:!0,isModelSelectorOpen:!1,isAgentSelectorInstant:n?.instant===!0}:{isAgentSelectorOpen:!1,isAgentSelectorInstant:n?.instant!==!1&&e.isAgentSelectorInstant})},setSidebarSection:t=>{e({sidebarSection:t})},setSettingsPage:t=>{e({settingsPage:t})},setSettingsProjectsSelectedId:t=>{e({settingsProjectsSelectedId:t})},setSettingsRemoteInstancesSelectedId:t=>{e({settingsRemoteInstancesSelectedId:t})},setEventStreamStatus:(t,n)=>{e({eventStreamStatus:t,eventStreamHint:n??null})},setShowReasoningTraces:t=>{e({showReasoningTraces:t}),Ft(t)},setSessionTitleRefreshEnabled:t=>{e({sessionTitleRefreshEnabled:t})},setSessionGoalEnabled:t=>{e({sessionGoalEnabled:t})},setSessionGoalDefaultBudgetEnabled:t=>{e({sessionGoalDefaultBudgetEnabled:t})},setSessionGoalDefaultBudget:t=>{e({sessionGoalDefaultBudget:t})},setCollapsibleThinkingBlocks:t=>{e({collapsibleThinkingBlocks:t})},setChatRenderMode:t=>{e({chatRenderMode:t})},setActivityRenderMode:t=>{e({activityRenderMode:t})},setShowDeletionDialog:t=>{e({showDeletionDialog:t})},setAutoDeleteEnabled:t=>{e({autoDeleteEnabled:t})},setAutoDeleteAfterDays:t=>{e({autoDeleteAfterDays:Math.max(1,Math.min(365,t))})},setSessionRetentionAction:t=>{e({sessionRetentionAction:t})},setAutoDeleteLastRunAt:t=>{e({autoDeleteLastRunAt:t})},setMessageLimit:t=>{e({messageLimit:Math.max(10,Math.min(500,Math.round(t)))})},setFontSize:n=>{e({fontSize:Math.max(50,Math.min(200,n))}),t().applyTypography()},setCodeFontSize:n=>{e({codeFontSize:Math.max(50,Math.min(200,n))}),t().applyTypography()},setGlobalDraftStarters:t=>{e({globalDraftStarters:t})},setTerminalFontSize:t=>{e({terminalFontSize:Math.max(9,Math.min(52,Math.round(t)))})},setEditorFontSize:t=>{e({editorFontSize:Math.max(9,Math.min(32,Math.round(t)))})},setUiFont:t=>{e({uiFont:t})},setMonoFont:t=>{e({monoFont:t})},setPadding:n=>{e({padding:Math.max(50,Math.min(200,n))}),t().applyPadding()},setCornerRadius:t=>{e({cornerRadius:t})},applyTypography:()=>{let{fontSize:e,codeFontSize:n}=t(),r=document.documentElement,i=e/100,a=n/100,o=typeof document<`u`&&Kn(r),s=Object.keys(Hn);if(i===1&&a===1){for(let e of s)r.style.removeProperty(Gn(e));return}for(let e of s){let t=qn(e,{mobile:o}),n=parseFloat(t);if(!Number.isFinite(n))continue;let s=e===`code`?a:i;if(s===1){r.style.removeProperty(Gn(e));continue}if(o){let t=n*16*s;r.style.setProperty(Gn(e),`calc(${Math.round(t*1e3)/1e3} * var(--dpt))`)}else r.style.setProperty(Gn(e),`${n*s}rem`)}},applyPadding:()=>{let{padding:e}=t(),n=document.documentElement,r=e/100;if(r===1){n.style.removeProperty(`--user-padding-scale`),n.style.removeProperty(`--line-height-tight`),n.style.removeProperty(`--line-height-normal`),n.style.removeProperty(`--line-height-relaxed`),n.style.removeProperty(`--line-height-loose`);return}let i=Math.sqrt(r);n.style.setProperty(`--user-padding-scale`,i.toString());let a=1+(r-1)*.15;n.style.setProperty(`--line-height-tight`,(1.25*a).toFixed(3)),n.style.setProperty(`--line-height-normal`,(1.5*a).toFixed(3)),n.style.setProperty(`--line-height-relaxed`,(1.625*a).toFixed(3)),n.style.setProperty(`--line-height-loose`,(2*a).toFixed(3))},setDiffLayoutPreference:t=>{e({diffLayoutPreference:t})},setDiffFileLayout:(t,n)=>{e(e=>({diffFileLayout:{...e.diffFileLayout,[t]:n}}))},setDiffWrapLines:t=>{e({diffWrapLines:t})},setGitChangesViewMode:t=>{e({gitChangesViewMode:t})},setInputBarOffset:t=>{e({inputBarOffset:t})},setMobileKeyboardMode:t=>{e(e=>e.mobileKeyboardMode===t?e:{mobileKeyboardMode:t})},toggleFavoriteModel:(t,n,r)=>{e(e=>e.favoriteModels.some(e=>e.providerID===t&&e.modelID===n)?{favoriteModels:e.favoriteModels.filter(e=>e.providerID!==t||e.modelID!==n)}:{favoriteModels:[r===void 0?{providerID:t,modelID:n}:{providerID:t,modelID:n,variant:r},...e.favoriteModels]})},reorderFavoriteModel:(t,n,r,i)=>{e(e=>{let a=e.favoriteModels.findIndex(e=>e.providerID===t&&e.modelID===n),o=e.favoriteModels.findIndex(e=>e.providerID===r&&e.modelID===i);if(a===-1||o===-1||a===o)return e;let s=e.favoriteModels.slice(),[c]=s.splice(a,1);return c?(s.splice(o,0,c),{favoriteModels:s}):e})},setProviderOrder:t=>{e(e=>{let n=t.filter(e=>typeof e==`string`&&e.length>0),r=e.providerOrder;return r.length===n.length&&r.every((e,t)=>e===n[t])?e:{providerOrder:n}})},toggleHiddenModel:(t,n)=>{e(e=>e.hiddenModels.some(e=>e.providerID===t&&e.modelID===n)?{hiddenModels:e.hiddenModels.filter(e=>e.providerID!==t||e.modelID!==n)}:{hiddenModels:[{providerID:t,modelID:n},...e.hiddenModels]})},isHiddenModel:(e,n)=>{let{hiddenModels:r}=t();return r.some(t=>t.providerID===e&&t.modelID===n)},hideAllModels:(t,n)=>{e(e=>{let r=e.hiddenModels.filter(e=>e.providerID!==t);return{hiddenModels:[...n.filter(e=>typeof e==`string`&&e.length>0).map(e=>({providerID:t,modelID:e})),...r]}})},showAllModels:t=>{e(e=>({hiddenModels:e.hiddenModels.filter(e=>e.providerID!==t)}))},toggleModelProviderCollapsed:t=>{let n=typeof t==`string`?t.trim():``;n&&e(e=>e.collapsedModelProviders.includes(n)?{collapsedModelProviders:e.collapsedModelProviders.filter(e=>e!==n)}:{collapsedModelProviders:[...e.collapsedModelProviders,n]})},setModelProvidersCollapsed:(t,n)=>{let r=Array.from(new Set(t.filter(e=>typeof e==`string`).map(e=>e.trim()).filter(Boolean)));r.length!==0&&e(e=>{let t=new Set(r),i=e.collapsedModelProviders.filter(e=>!t.has(e));return{collapsedModelProviders:n?[...i,...r]:i}})},isFavoriteModel:(e,n)=>{let{favoriteModels:r}=t();return r.some(t=>t.providerID===e&&t.modelID===n)},addRecentModel:(t,n,r)=>{e(e=>{let i=[r===void 0?{providerID:t,modelID:n}:{providerID:t,modelID:n,variant:r},...e.recentModels.filter(e=>e.providerID!==t||e.modelID!==n)].slice(0,5),a=e.favoriteModels.findIndex(e=>e.providerID===t&&e.modelID===n);if(a===-1)return{recentModels:i};let o=e.favoriteModels[a];if(o.variant===r)return{recentModels:i};let s=r===void 0?{providerID:o.providerID,modelID:o.modelID}:{providerID:o.providerID,modelID:o.modelID,variant:r},c=e.favoriteModels.slice();return c[a]=s,{recentModels:i,favoriteModels:c}})},addRecentAgent:t=>{let n=typeof t==`string`?t.trim():``;n&&e(e=>{if(e.recentAgents.includes(n))return e;let t=e.recentAgents;return{recentAgents:[n,...t].slice(0,5)}})},addRecentEffort:(t,n,r)=>{let i=typeof t==`string`?t.trim():``,a=typeof n==`string`?n.trim():``;if(!i||!a)return;let o=`${i}/${a}`,s=typeof r==`string`&&r.trim().length>0?r.trim():`default`;e(e=>{let t=e.recentEfforts[o]??[];if(t.includes(s))return e;let n=t;return{recentEfforts:{...e.recentEfforts,[o]:[s,...n].slice(0,5)}}})},updateProportionalSidebarWidths:()=>{typeof window>`u`||e(e=>{let t={};if(e.isBottomTerminalOpen&&!e.hasManuallyResizedBottomTerminal){let n=Math.floor(window.innerHeight*.32);e.bottomTerminalHeight!==n&&(t.bottomTerminalHeight=n)}return Object.keys(t).length>0?t:e})},applyTheme:()=>{let{theme:e}=t(),n=document.documentElement;if(n.classList.remove(`light`,`dark`),e===`system`){let e=window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`;n.classList.add(e)}else n.classList.add(e)},setMultiRunLauncherOpen:t=>{e({isMultiRunLauncherOpen:t})},openMultiRunLauncher:()=>{e({isMultiRunLauncherOpen:!0,isSessionSwitcherOpen:!1})},setTimelineDialogOpen:t=>{e({isTimelineDialogOpen:t})},setPromptNavigatorPanelOpen:t=>{e({isPromptNavigatorPanelOpen:t})},togglePromptNavigatorPanel:()=>{e(e=>({isPromptNavigatorPanelOpen:!e.isPromptNavigatorPanelOpen}))},setImagePreviewOpen:t=>{e({isImagePreviewOpen:t})},setNativeNotificationsEnabled:t=>{e({nativeNotificationsEnabled:t})},setNotificationMode:t=>{e({notificationMode:t})},setShowTerminalQuickKeysOnDesktop:t=>{e({showTerminalQuickKeysOnDesktop:t})},setNotifyOnSubtasks:t=>{e({notifyOnSubtasks:t})},setDockBadgeEnabled:t=>{e({dockBadgeEnabled:t})},setNotifyOnCompletion:t=>{e({notifyOnCompletion:t})},setNotifyOnError:t=>{e({notifyOnError:t})},setNotifyOnQuestion:t=>{e({notifyOnQuestion:t})},setNotificationTemplates:t=>{e({notificationTemplates:t})},setSummarizeLastMessage:t=>{e({summarizeLastMessage:t})},setSummaryThreshold:t=>{e({summaryThreshold:t})},setSummaryLength:t=>{e({summaryLength:t})},setMaxLastMessageLength:t=>{e({maxLastMessageLength:t})},setPersistChatDraft:t=>{e({persistChatDraft:t})},setShowOpenCodeUpdateNotifications:t=>{e({showOpenCodeUpdateNotifications:t})},setInputSpellcheckEnabled:t=>{e({inputSpellcheckEnabled:t})},setWideChatLayoutEnabled:t=>{e({wideChatLayoutEnabled:t})},setCodeBlockLineWrap:t=>{e({codeBlockLineWrap:t})},setShowToolFileIcons:t=>{e({showToolFileIcons:t})},setShowTurnChangedFiles:t=>{e({showTurnChangedFiles:t})},setShowExpandedBashTools:t=>{e({showExpandedBashTools:t})},setShowSubagentTaskDetails:t=>{e({showSubagentTaskDetails:t})},setTimeFormatPreference:t=>{e({timeFormatPreference:t})},setWeekStartPreference:t=>{e({weekStartPreference:t})},setDesktopWindowControlsPosition:t=>{e({desktopWindowControlsPosition:t})},setMermaidRenderingMode:t=>{e({mermaidRenderingMode:t})},setUserMessageRenderingMode:t=>{e({userMessageRenderingMode:t})},setCollapsibleUserMessages:t=>{e({collapsibleUserMessages:t})},setStickyUserHeader:t=>{e({stickyUserHeader:t})},setPromptNavigatorEnabled:t=>{e({promptNavigatorEnabled:t})},setExpandedEditorToolbar:t=>{e({expandedEditorToolbar:t})},setShowSplitAssistantMessageActions:t=>{e({showSplitAssistantMessageActions:t})},setShowAssistantTps:t=>{e({showAssistantTps:t})},setAllowPromptingSubagentSessions:t=>{e({allowPromptingSubagentSessions:t})},setIsMobileSessionStatusBarCollapsed:t=>{e({isMobileSessionStatusBarCollapsed:t})},setMobileSessionPanelOpen:t=>{e({mobileSessionPanelOpen:t})},setMobileSessionFilterProjectId:t=>{e({mobileSessionFilterProjectId:t})},setOtaChannelOverride:t=>{e({otaChannelOverride:t})},setReportUsage:t=>{e({reportUsage:t})},viewPagerPage:`center`,setViewPagerPage:t=>{e({viewPagerPage:t}),e(t===`left`?{isSessionSwitcherOpen:!0,isRightSidebarOpen:!1}:t===`right`?{isRightSidebarOpen:!0,isSessionSwitcherOpen:!1}:{isSessionSwitcherOpen:!1,isRightSidebarOpen:!1})},setShortcutOverride:(t,n)=>{e(e=>({shortcutOverrides:{...e.shortcutOverrides,[t]:n}}))},clearShortcutOverride:t=>{e(e=>{let n={...e.shortcutOverrides};return delete n[t],{shortcutOverrides:n}})},resetAllShortcutOverrides:()=>{e({shortcutOverrides:{}})},setFileEditorKeymap:t=>{e({fileEditorKeymap:mr(t)})},toggleExpandedInput:()=>{e(e=>({isExpandedInput:!e.isExpandedInput}))},setExpandedInput:t=>{e({isExpandedInput:t})}}),{name:`ui-store`,storage:Mn(),version:13,migrate:(e,t)=>{if(!e||typeof e!=`object`)return e;let n=e;if(Vn(n,t),t<11&&n.sidebarWidth===280&&(n.sidebarWidth=Y),t<10&&delete n.diffViewMode,t<13&&(delete n.notesPanelHeight,delete n.todoPanelHeight,(n.activeMainTab===`plan`||n.activeMainTab===`context`)&&(n.activeMainTab=`chat`),n.rightSidebarTab===`context`&&(n.rightSidebarTab=`files`)),t<1&&yr(n.notificationTemplates)&&(n.notificationTemplates={completion:{...J.completion},error:{...J.error},question:{...J.question},subtask:{...J.subtask}}),t<3){let e=new Set([90,120,180,220]),t=n.memoryLimitHistorical,r=n.memoryLimitActiveSession;typeof t==`number`&&!e.has(t)?n.messageLimit=t:typeof r==`number`&&!e.has(r)&&(n.messageLimit=r),delete n.memoryLimitHistorical,delete n.memoryLimitViewport,delete n.memoryLimitActiveSession}if((typeof n.rightSidebarTab!=`string`||n.rightSidebarTab!==`git`&&n.rightSidebarTab!==`files`)&&(n.rightSidebarTab=`files`),n.contextPanelByDirectory=Gr(n.contextPanelByDirectory),t<5)if(!n.shortcutOverrides||typeof n.shortcutOverrides!=`object`)n.shortcutOverrides={};else{let e=n.shortcutOverrides,t={};for(let[n,r]of Object.entries(e))typeof n==`string`&&typeof r==`string`&&(t[n]=r);n.shortcutOverrides=t}return t<6&&(n.contextPanelByDirectory=Gr(n.contextPanelByDirectory)),t<7&&(n.contextPanelByDirectory=Gr(n.contextPanelByDirectory)),t<8&&n.gitChangesViewMode!==`flat`&&n.gitChangesViewMode!==`tree`&&(n.gitChangesViewMode=`tree`),n.fileEditorKeymap=mr(n.fileEditorKeymap),n},partialize:e=>({theme:e.theme,isSidebarOpen:e.isSidebarOpen,sidebarWidth:e.sidebarWidth,isRightSidebarOpen:e.isRightSidebarOpen,rightSidebarWidth:e.rightSidebarWidth,rightSidebarTab:e.rightSidebarTab,contextPanelByDirectory:e.contextPanelByDirectory,isBottomTerminalOpen:e.isBottomTerminalOpen,isBottomTerminalExpanded:e.isBottomTerminalExpanded,bottomTerminalHeight:e.bottomTerminalHeight,isSessionSwitcherOpen:e.isSessionSwitcherOpen,activeMainTab:e.activeMainTab,sidebarSection:e.sidebarSection,settingsPage:e.settingsPage,settingsHasOpenedOnce:e.settingsHasOpenedOnce,settingsProjectsSelectedId:e.settingsProjectsSelectedId,settingsRemoteInstancesSelectedId:e.settingsRemoteInstancesSelectedId,isSessionCreateDialogOpen:e.isSessionCreateDialogOpen,showReasoningTraces:e.showReasoningTraces,sessionTitleRefreshEnabled:e.sessionTitleRefreshEnabled,sessionGoalEnabled:e.sessionGoalEnabled,sessionGoalDefaultBudgetEnabled:e.sessionGoalDefaultBudgetEnabled,sessionGoalDefaultBudget:e.sessionGoalDefaultBudget,collapsibleThinkingBlocks:e.collapsibleThinkingBlocks,chatRenderMode:e.chatRenderMode,activityRenderMode:e.activityRenderMode,showDeletionDialog:e.showDeletionDialog,autoDeleteEnabled:e.autoDeleteEnabled,autoDeleteAfterDays:e.autoDeleteAfterDays,sessionRetentionAction:e.sessionRetentionAction,autoDeleteLastRunAt:e.autoDeleteLastRunAt,messageLimit:e.messageLimit,fontSize:e.fontSize,codeFontSize:e.codeFontSize,globalDraftStarters:e.globalDraftStarters,terminalFontSize:e.terminalFontSize,editorFontSize:e.editorFontSize,uiFont:e.uiFont,monoFont:e.monoFont,padding:e.padding,cornerRadius:e.cornerRadius,favoriteModels:e.favoriteModels,hiddenModels:e.hiddenModels,providerOrder:e.providerOrder,collapsedModelProviders:e.collapsedModelProviders,recentModels:e.recentModels,recentAgents:e.recentAgents,recentEfforts:e.recentEfforts,diffLayoutPreference:e.diffLayoutPreference,diffWrapLines:e.diffWrapLines,gitChangesViewMode:e.gitChangesViewMode,nativeNotificationsEnabled:e.nativeNotificationsEnabled,notificationMode:e.notificationMode,showTerminalQuickKeysOnDesktop:e.showTerminalQuickKeysOnDesktop,notifyOnSubtasks:e.notifyOnSubtasks,dockBadgeEnabled:e.dockBadgeEnabled,notifyOnCompletion:e.notifyOnCompletion,notifyOnError:e.notifyOnError,notifyOnQuestion:e.notifyOnQuestion,notificationTemplates:e.notificationTemplates,summarizeLastMessage:e.summarizeLastMessage,summaryThreshold:e.summaryThreshold,summaryLength:e.summaryLength,maxLastMessageLength:e.maxLastMessageLength,persistChatDraft:e.persistChatDraft,showOpenCodeUpdateNotifications:e.showOpenCodeUpdateNotifications,inputSpellcheckEnabled:e.inputSpellcheckEnabled,wideChatLayoutEnabled:e.wideChatLayoutEnabled,codeBlockLineWrap:e.codeBlockLineWrap,showToolFileIcons:e.showToolFileIcons,showTurnChangedFiles:e.showTurnChangedFiles,showExpandedBashTools:e.showExpandedBashTools,showSubagentTaskDetails:e.showSubagentTaskDetails,timeFormatPreference:e.timeFormatPreference,weekStartPreference:e.weekStartPreference,desktopWindowControlsPosition:e.desktopWindowControlsPosition,mermaidRenderingMode:e.mermaidRenderingMode,userMessageRenderingMode:e.userMessageRenderingMode,collapsibleUserMessages:e.collapsibleUserMessages,stickyUserHeader:e.stickyUserHeader,promptNavigatorEnabled:e.promptNavigatorEnabled,expandedEditorToolbar:e.expandedEditorToolbar,showSplitAssistantMessageActions:e.showSplitAssistantMessageActions,showAssistantTps:e.showAssistantTps,allowPromptingSubagentSessions:e.allowPromptingSubagentSessions,isMobileSessionStatusBarCollapsed:e.isMobileSessionStatusBarCollapsed,mobileSessionFilterProjectId:e.mobileSessionFilterProjectId,otaChannelOverride:e.otaChannelOverride,shortcutOverrides:e.shortcutOverrides,fileEditorKeymap:e.fileEditorKeymap})}),{name:`ui-store`}));Ft(Yr.getState().showReasoningTraces);var Xr=Yr.persist;Xr?.hasHydrated?.()&&Ft(Yr.getState().showReasoningTraces),typeof Xr?.onFinishHydration==`function`&&Xr.onFinishHydration(()=>{Ft(Yr.getState().showReasoningTraces)});export{He as $,wn as A,kt as B,vn as C,Sn as D,yn as E,$t as F,yt as G,Ze as H,Nt as I,st as J,vt as K,Pt as L,en as M,Xt as N,pn as O,Qt as P,Be as Q,It as R,Ln as S,xn as T,lt as U,G as V,ct as W,Ge as X,Ot as Y,Ve as Z,Jn as _,cr as a,Rn as b,nr as c,$n as d,Ue as et,ir as f,Yn as g,Wn as h,fr as i,ye as it,Cn as j,mn as k,tr as l,Hn as m,pr as n,Ae as nt,Zn as o,rr as p,ot as q,lr as r,ve as rt,er as s,Yr as t,Re as tt,Xn as u,Kn as v,bn as w,Bn as x,Mn as y,Dt as z};
|
package/dist/assets/{useWorkerHighlightedLines-dC60TMnO.js → useWorkerHighlightedLines-BLg6m3sH.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{o as e}from"./rolldown-runtime-C0FnF6B9.js";import{_ as t}from"./useUIStore-CqqO11ZI.js";import{$t as n,kn as r,xn as i}from"./persistence-CSZp1CNB.js";import{nt as a,rt as o}from"./vendor-base-ui-CnHfUmDN.js";import{n as s}from"./platform-CenlWqxu.js";import{a as c,n as l}from"./vendor-aparajita-capacitor-secure-storage-CjQdwfjS.js";import{n as u}from"./vendor-react-DLPElpoQ.js";import{n as d}from"./clipboard-BXxLshVq.js";import{t as f}from"./utils-B0mQXN9L.js";import{n as p}from"./Icon-4My8YZwt.js";import{t as m}from"./button-Or0daT9o.js";import{i as h,n as g,t as _}from"./tooltip-BSrJYYYc.js";import{n as v}from"./useThemeSystem-DMzWVJaW.js";import{c as y,n as b,o as x,r as S,s as C}from"./markdownTheme-CVS01wHf.js";import{n as w}from"./MarkdownRenderer-SLKCbxwI.js";import{n as T,t as E}from"./toolHelpers-DEvVP9U0.js";import{t as D}from"./vendor-tanstack-react-virtual-tlDgH6PG.js";import{n as ee,t as te}from"./markdown-worker-BuveaH3O.js";var O=e(o(),1),k=u(),A=a(),ne=`w-[min(30rem,calc(100cqw-1rem))] min-w-[280px] max-w-full overflow-hidden rounded-xl shadow-[inset_0_1px_0_0_rgba(255,255,255,0.8),inset_0_0_0_1px_rgba(0,0,0,0.04),0_0_0_1px_rgba(0,0,0,0.10),0_1px_2px_-0.5px_rgba(0,0,0,0.08),0_4px_8px_-2px_rgba(0,0,0,0.08),0_12px_20px_-4px_rgba(0,0,0,0.08)] dark:shadow-[inset_0_1px_0_0_rgba(255,255,255,0.12),inset_0_0_0_1px_rgba(255,255,255,0.08),0_0_0_1px_rgba(0,0,0,0.36),0_1px_1px_-0.5px_rgba(0,0,0,0.22),0_3px_3px_-1.5px_rgba(0,0,0,0.20),0_6px_6px_-3px_rgba(0,0,0,0.16)]`,j={maxWidth:`min(28rem, calc(100cqw - 4ch))`,backgroundColor:`var(--surface-elevated)`,color:`var(--surface-elevated-foreground)`},M=`flex items-center justify-between gap-3 border-b border-[var(--surface-subtle)] px-3 py-2.5`,N=`text-xs font-medium leading-4 text-foreground md:text-[0.8125rem] md:leading-5`,re=`text-xs tabular-nums leading-4 text-muted-foreground md:text-[0.8125rem] md:leading-5`,P=`m-0 list-none divide-y divide-[var(--surface-subtle)] p-0`,F=`${P} max-h-[min(22rem,50vh)] overflow-y-auto`,ie=`${P} w-full`,ae={className:`p-0 rounded-none`,maxHeightClass:`max-h-[46vh]`,disableHorizontal:!0},I=`px-2.5 py-1.5 text-xs leading-4 md:py-2 md:text-[0.8125rem] md:leading-5`,oe=`flex min-w-0 items-center gap-1 text-xs leading-4 text-muted-foreground md:gap-1.5 md:text-[0.8125rem] md:leading-5`,se=`min-w-0 truncate text-xs leading-4 text-foreground md:text-[0.8125rem] md:leading-5`,ce=`inline-flex shrink-0 items-center gap-1 text-xs leading-4 tabular-nums text-muted-foreground md:text-[0.8125rem] md:leading-5`,le=`h-3 w-3 shrink-0 md:h-3.5 md:w-3.5`,ue={in_progress:`text-foreground`,pending:`text-foreground`,completed:`text-muted-foreground line-through`,cancelled:`text-muted-foreground line-through`},L={in_progress:`chat.statusRow.todo.status.inProgress`,pending:`chat.statusRow.todo.status.pending`,completed:`chat.statusRow.todo.status.completed`,cancelled:`chat.statusRow.todo.status.cancelled`},R=e=>{let t=(0,k.c)(26),{todo:n,isActive:r,activeRef:i}=e,{t:a}=d(),o=z.has(n.status)?n.status:`pending`,s=L[o],c;t[0]!==a||t[1]!==s?(c=a(s),t[0]=a,t[1]=s,t[2]=c):c=t[2];let l=c,u;t[3]===o?u=t[4]:(u=o===`in_progress`?(0,A.jsx)(p,{name:`record-circle`,className:`h-3.5 w-3.5 text-[var(--status-info)]`,"aria-hidden":`true`}):o===`completed`?(0,A.jsx)(p,{name:`checkbox-circle`,className:`h-3.5 w-3.5 text-[var(--status-success)]`,"aria-hidden":`true`}):(0,A.jsx)(p,{name:`time`,className:`h-3.5 w-3.5 text-muted-foreground`,"aria-hidden":`true`}),t[3]=o,t[4]=u);let m=u,v=r?`step`:void 0,y=r&&`bg-[var(--surface-muted)] before:absolute before:inset-y-2 before:left-0 before:w-0.5 before:rounded-full before:bg-[var(--status-info)]`,b;t[5]===y?b=t[6]:(b=f(`group relative grid min-w-0 grid-cols-[1rem_minmax(0,1fr)] items-start gap-2.5`,I,y),t[5]=y,t[6]=b);let x;t[7]!==m||t[8]!==l?(x=(0,A.jsx)(h,{asChild:!0,children:(0,A.jsx)(`span`,{className:`flex size-4 items-center justify-center`,"aria-label":l,children:m})}),t[7]=m,t[8]=l,t[9]=x):x=t[9];let S;t[10]===l?S=t[11]:(S=(0,A.jsx)(g,{side:`left`,sideOffset:6,children:l}),t[10]=l,t[11]=S);let C;t[12]!==x||t[13]!==S?(C=(0,A.jsxs)(_,{children:[x,S]}),t[12]=x,t[13]=S,t[14]=C):C=t[14];let w=ue[o],T;t[15]===w?T=t[16]:(T=f(`block whitespace-normal break-words`,w),t[15]=w,t[16]=T);let E;t[17]!==T||t[18]!==n.content?(E=(0,A.jsx)(`span`,{className:`min-w-0 flex-1`,children:(0,A.jsx)(`span`,{className:T,children:n.content})}),t[17]=T,t[18]=n.content,t[19]=E):E=t[19];let D;return t[20]!==i||t[21]!==E||t[22]!==v||t[23]!==b||t[24]!==C?(D=(0,A.jsxs)(`li`,{ref:i,"aria-current":v,className:b,children:[C,E]}),t[20]=i,t[21]=E,t[22]=v,t[23]=b,t[24]=C,t[25]=D):D=t[25],D},z=new Set([`in_progress`,`pending`,`completed`,`cancelled`]),B=`image/png`,V=c(`OpenChamberMedia`),H=e=>{let t=e.toLowerCase().split(`;`)[0]?.trim()||B;if(t===`image/jpeg`||t===`image/jpg`)return`jpg`;if(t===`image/webp`)return`webp`;if(t===`image/gif`)return`gif`;if(t===`image/svg+xml`)return`svg`;if(t===`image/png`)return`png`;let n=t.split(`/`)[1];return n&&/^[a-z0-9.+-]+$/i.test(n)?n:`png`},U=(e,t)=>{let n=`image.${H(t)}`,r=(((e||``).trim()||n).split(/[\\/]/).pop()||n).replace(/[^\w.\- ()[\]]+/g,`_`).replace(/^\.+/,``);return r?/\.[a-z0-9]{1,8}$/i.test(r)?r:`${r}.${H(t)}`:n},W=e=>new Promise((t,n)=>{let r=new FileReader;r.onload=()=>{if(typeof r.result==`string`){t(r.result);return}n(Error(`Failed to encode image`))},r.onerror=()=>n(r.error??Error(`Failed to encode image`)),r.readAsDataURL(e)}),de=async e=>{let t=await W(e),n=t.indexOf(`,`);return n>=0?t.slice(n+1):t},fe=(e,t)=>{let n=URL.createObjectURL(e),r=document.createElement(`a`);r.href=n,r.download=t,document.body.appendChild(r),r.click(),document.body.removeChild(r),window.setTimeout(()=>URL.revokeObjectURL(n),1e3)},G=async(e,t)=>{let n=await fetch(e,{signal:t,cache:`no-store`});if(!n.ok)throw Error(`Image fetch failed (${n.status})`);return n.blob()},pe=async(e,t=B)=>{if(!e.naturalWidth||!e.naturalHeight)return null;let n=e.currentSrc||e.src;if(n&&(/^(?:blob:|data:|openchamber-asset:)/i.test(n)||/^https?:/i.test(n)||/^\/api(?=\/|[?#]|$)/.test(n)))try{let e=await G(n);if(e.size>0)return e}catch{}try{let n=document.createElement(`canvas`);n.width=e.naturalWidth,n.height=e.naturalHeight;let r=n.getContext(`2d`);if(!r)return null;r.drawImage(e,0,0);let i=t.startsWith(`image/`)?t:B,a=await new Promise(e=>{n.toBlob(t=>e(t),i===`image/jpg`?`image/jpeg`:i)});return a&&a.size>0?a:null}catch{return null}},me=async(e,t)=>{let n=``;try{return n=await S(e,t??new AbortController().signal),await G(n,t)}finally{n&&C(n)}},he=async(e,t)=>{let n=e.effectiveDirectory??``,i=null;e.prefetchedBlob&&e.prefetchedBlob.size>0&&(i=e.prefetchedBlob);let a=e.displayUrl?.trim();if(!i&&a)try{i=await G(a,t)}catch{i=null}if(!i){let a=e.sourceUrl.trim();if(!a)throw Error(`Image source is empty`);if(/^(?:data|blob):/i.test(a)||/^https?:/i.test(a)||/^\/api(?=\/|[?#]|$)/.test(a))i=await G(a,t);else{let e=y(a,n);if(x(e))try{i=await me(e.path,t)}catch{let n=await r(`/api/fs/raw`,{method:`GET`,cache:`no-store`,query:{path:e.path},signal:t});if(!n.ok)throw Error(`Image source request failed with status ${n.status}`);i=await n.blob()}else i=await G(e.source,t)}}if(!i||i.size<=0)throw Error(`Image is empty`);let o=(e.mimeType||(i.type&&i.type.startsWith(`image/`)?i.type:``)||B).split(`;`)[0].trim()||B;return{blob:i,filename:U(e.filename,o),mimeType:o}},ge=()=>!s()||l===void 0?!1:l.isPluginAvailable(`OpenChamberMedia`),_e=async(e,t)=>{let{blob:r,filename:a,mimeType:o}=await he(e,t);if(ge()){let e=await de(r);return await V.saveImage({dataBase64:e,mimeType:o,filename:a}),`saved`}if(n()){let e=i()?.vscode;if(e?.saveImage){let t=await W(r);return await e.saveImage({fileName:a,dataUrl:t}),`saved`}}return fe(r,a),`downloaded`},ve=e=>e.replace(/&/g,`&`).replace(/</g,`<`).replace(/>/g,`>`).replace(/"/g,`"`).replace(/'/g,`'`),ye=e=>e?Object.entries(e).map(([e,t])=>t==null?``:`${e.startsWith(`--`)?e:e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}:${typeof t==`number`?`${t}px`:t};`).join(``):``,K=(e,t,n)=>{let r=e.querySelector(`pre`);r&&(r.style.margin=`0`,r.style.background=`transparent`,r.style.whiteSpace=t?`pre-wrap`:`pre`,t&&(r.style.wordBreak=`break-word`,r.style.overflowWrap=`break-word`));let i=e.querySelector(`code`);if(i){let e=ye(n);e&&i.setAttribute(`style`,`${i.getAttribute(`style`)??``}${e}`)}},be=e=>`<pre><code>${ve(e)}</code></pre>`,xe=e=>{let t=(0,k.c)(21),{code:n,language:r,className:i,style:a,codeStyle:o,wrap:s}=e,c=s!==void 0&&s,{currentTheme:l}=v(),u=O.useRef(null),d;t[0]===l?d=t[1]:(d=b(l),t[0]=l,t[1]=d);let p=d,m,h;t[2]!==n||t[3]!==o||t[4]!==c?(m=()=>{let e=u.current;e&&(e.innerHTML=be(n),K(e,c,o))},h=[n,c,o],t[2]=n,t[3]=o,t[4]=c,t[5]=m,t[6]=h):(m=t[5],h=t[6]),O.useLayoutEffect(m,h);let g,_;t[7]!==n||t[8]!==o||t[9]!==r||t[10]!==c?(g=()=>{let e=u.current;if(!e)return;let t=!0,i=new AbortController;return te(n,(r||`text`).toLowerCase(),{signal:i.signal,priority:`visible`}).then(n=>{!t||!e||!n||(e.innerHTML=n,K(e,c,o))}),()=>{t=!1,i.abort()}},_=[n,r,c,o],t[7]=n,t[8]=o,t[9]=r,t[10]=c,t[11]=g,t[12]=_):(g=t[11],_=t[12]),O.useEffect(g,_);let y;t[13]===i?y=t[14]:(y=f(`typography-code`,i),t[13]=i,t[14]=y);let x=p,S;t[15]!==a||t[16]!==x?(S={...x,...a},t[15]=a,t[16]=x,t[17]=S):S=t[17];let C;return t[18]!==y||t[19]!==S?(C=(0,A.jsx)(`div`,{ref:u,className:y,style:S}),t[18]=y,t[19]=S,t[20]=C):C=t[20],C},Se=e=>{let t=e.replace(/^<file>\s*\n?/,``).replace(/\n?<\/file>\s*$/,``);return t=t.replace(/^\s*\d{5}\|\s?/gm,``),t.trim()},Ce=(e,t=``)=>{if(typeof e==`string`)return e;if(e==null)return t;if(typeof e==`number`||typeof e==`boolean`||typeof e==`bigint`)return String(e);try{return JSON.stringify(e)}catch{return t}},we=e=>e?e.includes(`<diagnostics`)||e.includes(`<file_diagnostics>`)||e.includes(`LSP errors detected`)||e.includes(`This file has errors`):!1,Te=e=>e?e.replace(/\n{0,2}LSP errors detected[\s\S]*?<diagnostics[^>]*>[\s\S]*?<\/diagnostics>/g,``).replace(/\n{0,2}This file has errors[\s\S]*?<\/file_diagnostics>/g,``).replace(/<diagnostics[^>]*>[\s\S]*?<\/diagnostics>/g,``).replace(/<file_diagnostics>[\s\S]*?<\/file_diagnostics>/g,``).trim():``,Ee=(e,t)=>!e||typeof e!=`object`?String(e):T(e,t||``),q=e=>{if(typeof e==`string`){let t=e.trim();return t.length>0?t:void 0}if(e&&typeof e==`object`){let t=e.patch;if(typeof t==`string`){let e=t.trim();return e.length>0?e:void 0}}},De=e=>{if(!e||typeof e!=`object`)return;let t=q(e.patch)??q(e.diff);if(t)return t;let n=Array.isArray(e.files)?e.files:[];for(let e of n){if(!e||typeof e!=`object`)continue;let t=q(e.patch)??q(e.diff);if(t)return t}},Oe=e=>{if(!e||typeof e!=`string`)return{data:null,isJson:!1};let t=e.trim();if(!t.startsWith(`{`)&&!t.startsWith(`[`)||!t.endsWith(`}`)&&!t.endsWith(`]`)||t.length<2)return{data:null,isJson:!1};try{let e=JSON.parse(t);return typeof e==`object`&&e?{data:e,isJson:!0}:{data:null,isJson:!1}}catch{return{data:null,isJson:!1}}},ke=(e,t,n)=>{let r=Se(e);if((t===`edit`||t===`multiedit`||t===`write`||t===`apply_patch`)&&we(r)&&(r=Te(r)),(t===`edit`||t===`multiedit`||t===`apply_patch`)&&r.trim().length===0){let e=De(n);if(e)return e}return r},Ae=e=>{let t=e.match(/<type>(file|directory)<\/type>/i)?.[1]?.toLowerCase()??`unknown`,n=(e.match(/<content>([\s\S]*?)<\/content>/i)?.[1]??e).replace(/\r\n/g,`
|
|
1
|
+
import{o as e}from"./rolldown-runtime-C0FnF6B9.js";import{_ as t}from"./useUIStore-CuaA8-Hp.js";import{$t as n,kn as r,xn as i}from"./persistence-DdUac14I.js";import{nt as a,rt as o}from"./vendor-base-ui-CnHfUmDN.js";import{n as s}from"./platform-B4KKLnZ5.js";import{a as c,n as l}from"./vendor-aparajita-capacitor-secure-storage-CjQdwfjS.js";import{n as u}from"./vendor-react-DLPElpoQ.js";import{n as d}from"./clipboard-DJ4nQEuY.js";import{t as f}from"./utils-BiK3tBGM.js";import{n as p}from"./Icon-BYM02QyU.js";import{t as m}from"./button-C0cth9tl.js";import{i as h,n as g,t as _}from"./tooltip-BifLJ8o0.js";import{n as v}from"./useThemeSystem-DMzWVJaW.js";import{c as y,n as b,o as x,r as S,s as C}from"./markdownTheme-CzZm3riB.js";import{n as w}from"./MarkdownRenderer-BCVKHQSh.js";import{n as T,t as E}from"./toolHelpers-DEvVP9U0.js";import{t as D}from"./vendor-tanstack-react-virtual-tlDgH6PG.js";import{n as ee,t as te}from"./markdown-worker-BuveaH3O.js";var O=e(o(),1),k=u(),A=a(),ne=`w-[min(30rem,calc(100cqw-1rem))] min-w-[280px] max-w-full overflow-hidden rounded-xl shadow-[inset_0_1px_0_0_rgba(255,255,255,0.8),inset_0_0_0_1px_rgba(0,0,0,0.04),0_0_0_1px_rgba(0,0,0,0.10),0_1px_2px_-0.5px_rgba(0,0,0,0.08),0_4px_8px_-2px_rgba(0,0,0,0.08),0_12px_20px_-4px_rgba(0,0,0,0.08)] dark:shadow-[inset_0_1px_0_0_rgba(255,255,255,0.12),inset_0_0_0_1px_rgba(255,255,255,0.08),0_0_0_1px_rgba(0,0,0,0.36),0_1px_1px_-0.5px_rgba(0,0,0,0.22),0_3px_3px_-1.5px_rgba(0,0,0,0.20),0_6px_6px_-3px_rgba(0,0,0,0.16)]`,j={maxWidth:`min(28rem, calc(100cqw - 4ch))`,backgroundColor:`var(--surface-elevated)`,color:`var(--surface-elevated-foreground)`},M=`flex items-center justify-between gap-3 border-b border-[var(--surface-subtle)] px-3 py-2.5`,N=`text-xs font-medium leading-4 text-foreground md:text-[0.8125rem] md:leading-5`,re=`text-xs tabular-nums leading-4 text-muted-foreground md:text-[0.8125rem] md:leading-5`,P=`m-0 list-none divide-y divide-[var(--surface-subtle)] p-0`,F=`${P} max-h-[min(22rem,50vh)] overflow-y-auto`,ie=`${P} w-full`,ae={className:`p-0 rounded-none`,maxHeightClass:`max-h-[46vh]`,disableHorizontal:!0},I=`px-2.5 py-1.5 text-xs leading-4 md:py-2 md:text-[0.8125rem] md:leading-5`,oe=`flex min-w-0 items-center gap-1 text-xs leading-4 text-muted-foreground md:gap-1.5 md:text-[0.8125rem] md:leading-5`,se=`min-w-0 truncate text-xs leading-4 text-foreground md:text-[0.8125rem] md:leading-5`,ce=`inline-flex shrink-0 items-center gap-1 text-xs leading-4 tabular-nums text-muted-foreground md:text-[0.8125rem] md:leading-5`,le=`h-3 w-3 shrink-0 md:h-3.5 md:w-3.5`,ue={in_progress:`text-foreground`,pending:`text-foreground`,completed:`text-muted-foreground line-through`,cancelled:`text-muted-foreground line-through`},L={in_progress:`chat.statusRow.todo.status.inProgress`,pending:`chat.statusRow.todo.status.pending`,completed:`chat.statusRow.todo.status.completed`,cancelled:`chat.statusRow.todo.status.cancelled`},R=e=>{let t=(0,k.c)(26),{todo:n,isActive:r,activeRef:i}=e,{t:a}=d(),o=z.has(n.status)?n.status:`pending`,s=L[o],c;t[0]!==a||t[1]!==s?(c=a(s),t[0]=a,t[1]=s,t[2]=c):c=t[2];let l=c,u;t[3]===o?u=t[4]:(u=o===`in_progress`?(0,A.jsx)(p,{name:`record-circle`,className:`h-3.5 w-3.5 text-[var(--status-info)]`,"aria-hidden":`true`}):o===`completed`?(0,A.jsx)(p,{name:`checkbox-circle`,className:`h-3.5 w-3.5 text-[var(--status-success)]`,"aria-hidden":`true`}):(0,A.jsx)(p,{name:`time`,className:`h-3.5 w-3.5 text-muted-foreground`,"aria-hidden":`true`}),t[3]=o,t[4]=u);let m=u,v=r?`step`:void 0,y=r&&`bg-[var(--surface-muted)] before:absolute before:inset-y-2 before:left-0 before:w-0.5 before:rounded-full before:bg-[var(--status-info)]`,b;t[5]===y?b=t[6]:(b=f(`group relative grid min-w-0 grid-cols-[1rem_minmax(0,1fr)] items-start gap-2.5`,I,y),t[5]=y,t[6]=b);let x;t[7]!==m||t[8]!==l?(x=(0,A.jsx)(h,{asChild:!0,children:(0,A.jsx)(`span`,{className:`flex size-4 items-center justify-center`,"aria-label":l,children:m})}),t[7]=m,t[8]=l,t[9]=x):x=t[9];let S;t[10]===l?S=t[11]:(S=(0,A.jsx)(g,{side:`left`,sideOffset:6,children:l}),t[10]=l,t[11]=S);let C;t[12]!==x||t[13]!==S?(C=(0,A.jsxs)(_,{children:[x,S]}),t[12]=x,t[13]=S,t[14]=C):C=t[14];let w=ue[o],T;t[15]===w?T=t[16]:(T=f(`block whitespace-normal break-words`,w),t[15]=w,t[16]=T);let E;t[17]!==T||t[18]!==n.content?(E=(0,A.jsx)(`span`,{className:`min-w-0 flex-1`,children:(0,A.jsx)(`span`,{className:T,children:n.content})}),t[17]=T,t[18]=n.content,t[19]=E):E=t[19];let D;return t[20]!==i||t[21]!==E||t[22]!==v||t[23]!==b||t[24]!==C?(D=(0,A.jsxs)(`li`,{ref:i,"aria-current":v,className:b,children:[C,E]}),t[20]=i,t[21]=E,t[22]=v,t[23]=b,t[24]=C,t[25]=D):D=t[25],D},z=new Set([`in_progress`,`pending`,`completed`,`cancelled`]),B=`image/png`,V=c(`OpenChamberMedia`),H=e=>{let t=e.toLowerCase().split(`;`)[0]?.trim()||B;if(t===`image/jpeg`||t===`image/jpg`)return`jpg`;if(t===`image/webp`)return`webp`;if(t===`image/gif`)return`gif`;if(t===`image/svg+xml`)return`svg`;if(t===`image/png`)return`png`;let n=t.split(`/`)[1];return n&&/^[a-z0-9.+-]+$/i.test(n)?n:`png`},U=(e,t)=>{let n=`image.${H(t)}`,r=(((e||``).trim()||n).split(/[\\/]/).pop()||n).replace(/[^\w.\- ()[\]]+/g,`_`).replace(/^\.+/,``);return r?/\.[a-z0-9]{1,8}$/i.test(r)?r:`${r}.${H(t)}`:n},W=e=>new Promise((t,n)=>{let r=new FileReader;r.onload=()=>{if(typeof r.result==`string`){t(r.result);return}n(Error(`Failed to encode image`))},r.onerror=()=>n(r.error??Error(`Failed to encode image`)),r.readAsDataURL(e)}),de=async e=>{let t=await W(e),n=t.indexOf(`,`);return n>=0?t.slice(n+1):t},fe=(e,t)=>{let n=URL.createObjectURL(e),r=document.createElement(`a`);r.href=n,r.download=t,document.body.appendChild(r),r.click(),document.body.removeChild(r),window.setTimeout(()=>URL.revokeObjectURL(n),1e3)},G=async(e,t)=>{let n=await fetch(e,{signal:t,cache:`no-store`});if(!n.ok)throw Error(`Image fetch failed (${n.status})`);return n.blob()},pe=async(e,t=B)=>{if(!e.naturalWidth||!e.naturalHeight)return null;let n=e.currentSrc||e.src;if(n&&(/^(?:blob:|data:|openchamber-asset:)/i.test(n)||/^https?:/i.test(n)||/^\/api(?=\/|[?#]|$)/.test(n)))try{let e=await G(n);if(e.size>0)return e}catch{}try{let n=document.createElement(`canvas`);n.width=e.naturalWidth,n.height=e.naturalHeight;let r=n.getContext(`2d`);if(!r)return null;r.drawImage(e,0,0);let i=t.startsWith(`image/`)?t:B,a=await new Promise(e=>{n.toBlob(t=>e(t),i===`image/jpg`?`image/jpeg`:i)});return a&&a.size>0?a:null}catch{return null}},me=async(e,t)=>{let n=``;try{return n=await S(e,t??new AbortController().signal),await G(n,t)}finally{n&&C(n)}},he=async(e,t)=>{let n=e.effectiveDirectory??``,i=null;e.prefetchedBlob&&e.prefetchedBlob.size>0&&(i=e.prefetchedBlob);let a=e.displayUrl?.trim();if(!i&&a)try{i=await G(a,t)}catch{i=null}if(!i){let a=e.sourceUrl.trim();if(!a)throw Error(`Image source is empty`);if(/^(?:data|blob):/i.test(a)||/^https?:/i.test(a)||/^\/api(?=\/|[?#]|$)/.test(a))i=await G(a,t);else{let e=y(a,n);if(x(e))try{i=await me(e.path,t)}catch{let n=await r(`/api/fs/raw`,{method:`GET`,cache:`no-store`,query:{path:e.path},signal:t});if(!n.ok)throw Error(`Image source request failed with status ${n.status}`);i=await n.blob()}else i=await G(e.source,t)}}if(!i||i.size<=0)throw Error(`Image is empty`);let o=(e.mimeType||(i.type&&i.type.startsWith(`image/`)?i.type:``)||B).split(`;`)[0].trim()||B;return{blob:i,filename:U(e.filename,o),mimeType:o}},ge=()=>!s()||l===void 0?!1:l.isPluginAvailable(`OpenChamberMedia`),_e=async(e,t)=>{let{blob:r,filename:a,mimeType:o}=await he(e,t);if(ge()){let e=await de(r);return await V.saveImage({dataBase64:e,mimeType:o,filename:a}),`saved`}if(n()){let e=i()?.vscode;if(e?.saveImage){let t=await W(r);return await e.saveImage({fileName:a,dataUrl:t}),`saved`}}return fe(r,a),`downloaded`},ve=e=>e.replace(/&/g,`&`).replace(/</g,`<`).replace(/>/g,`>`).replace(/"/g,`"`).replace(/'/g,`'`),ye=e=>e?Object.entries(e).map(([e,t])=>t==null?``:`${e.startsWith(`--`)?e:e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}:${typeof t==`number`?`${t}px`:t};`).join(``):``,K=(e,t,n)=>{let r=e.querySelector(`pre`);r&&(r.style.margin=`0`,r.style.background=`transparent`,r.style.whiteSpace=t?`pre-wrap`:`pre`,t&&(r.style.wordBreak=`break-word`,r.style.overflowWrap=`break-word`));let i=e.querySelector(`code`);if(i){let e=ye(n);e&&i.setAttribute(`style`,`${i.getAttribute(`style`)??``}${e}`)}},be=e=>`<pre><code>${ve(e)}</code></pre>`,xe=e=>{let t=(0,k.c)(21),{code:n,language:r,className:i,style:a,codeStyle:o,wrap:s}=e,c=s!==void 0&&s,{currentTheme:l}=v(),u=O.useRef(null),d;t[0]===l?d=t[1]:(d=b(l),t[0]=l,t[1]=d);let p=d,m,h;t[2]!==n||t[3]!==o||t[4]!==c?(m=()=>{let e=u.current;e&&(e.innerHTML=be(n),K(e,c,o))},h=[n,c,o],t[2]=n,t[3]=o,t[4]=c,t[5]=m,t[6]=h):(m=t[5],h=t[6]),O.useLayoutEffect(m,h);let g,_;t[7]!==n||t[8]!==o||t[9]!==r||t[10]!==c?(g=()=>{let e=u.current;if(!e)return;let t=!0,i=new AbortController;return te(n,(r||`text`).toLowerCase(),{signal:i.signal,priority:`visible`}).then(n=>{!t||!e||!n||(e.innerHTML=n,K(e,c,o))}),()=>{t=!1,i.abort()}},_=[n,r,c,o],t[7]=n,t[8]=o,t[9]=r,t[10]=c,t[11]=g,t[12]=_):(g=t[11],_=t[12]),O.useEffect(g,_);let y;t[13]===i?y=t[14]:(y=f(`typography-code`,i),t[13]=i,t[14]=y);let x=p,S;t[15]!==a||t[16]!==x?(S={...x,...a},t[15]=a,t[16]=x,t[17]=S):S=t[17];let C;return t[18]!==y||t[19]!==S?(C=(0,A.jsx)(`div`,{ref:u,className:y,style:S}),t[18]=y,t[19]=S,t[20]=C):C=t[20],C},Se=e=>{let t=e.replace(/^<file>\s*\n?/,``).replace(/\n?<\/file>\s*$/,``);return t=t.replace(/^\s*\d{5}\|\s?/gm,``),t.trim()},Ce=(e,t=``)=>{if(typeof e==`string`)return e;if(e==null)return t;if(typeof e==`number`||typeof e==`boolean`||typeof e==`bigint`)return String(e);try{return JSON.stringify(e)}catch{return t}},we=e=>e?e.includes(`<diagnostics`)||e.includes(`<file_diagnostics>`)||e.includes(`LSP errors detected`)||e.includes(`This file has errors`):!1,Te=e=>e?e.replace(/\n{0,2}LSP errors detected[\s\S]*?<diagnostics[^>]*>[\s\S]*?<\/diagnostics>/g,``).replace(/\n{0,2}This file has errors[\s\S]*?<\/file_diagnostics>/g,``).replace(/<diagnostics[^>]*>[\s\S]*?<\/diagnostics>/g,``).replace(/<file_diagnostics>[\s\S]*?<\/file_diagnostics>/g,``).trim():``,Ee=(e,t)=>!e||typeof e!=`object`?String(e):T(e,t||``),q=e=>{if(typeof e==`string`){let t=e.trim();return t.length>0?t:void 0}if(e&&typeof e==`object`){let t=e.patch;if(typeof t==`string`){let e=t.trim();return e.length>0?e:void 0}}},De=e=>{if(!e||typeof e!=`object`)return;let t=q(e.patch)??q(e.diff);if(t)return t;let n=Array.isArray(e.files)?e.files:[];for(let e of n){if(!e||typeof e!=`object`)continue;let t=q(e.patch)??q(e.diff);if(t)return t}},Oe=e=>{if(!e||typeof e!=`string`)return{data:null,isJson:!1};let t=e.trim();if(!t.startsWith(`{`)&&!t.startsWith(`[`)||!t.endsWith(`}`)&&!t.endsWith(`]`)||t.length<2)return{data:null,isJson:!1};try{let e=JSON.parse(t);return typeof e==`object`&&e?{data:e,isJson:!0}:{data:null,isJson:!1}}catch{return{data:null,isJson:!1}}},ke=(e,t,n)=>{let r=Se(e);if((t===`edit`||t===`multiedit`||t===`write`||t===`apply_patch`)&&we(r)&&(r=Te(r)),(t===`edit`||t===`multiedit`||t===`apply_patch`)&&r.trim().length===0){let e=De(n);if(e)return e}return r},Ae=e=>{let t=e.match(/<type>(file|directory)<\/type>/i)?.[1]?.toLowerCase()??`unknown`,n=(e.match(/<content>([\s\S]*?)<\/content>/i)?.[1]??e).replace(/\r\n/g,`
|
|
2
2
|
`).split(`
|
|
3
3
|
`),r=e=>/\(\s*File has more lines\..*offset.*\)/i.test(e.trim());return{type:t,lines:n.map(e=>{let n=e.trim(),i=n.startsWith(`(`)&&n.endsWith(`)`)||r(n);if(t!==`directory`){let t=e.match(/^(\d+):\s?(.*)$/);if(t){let e=t[2],n=e.trim(),i=n.startsWith(`(`)&&n.endsWith(`)`)||r(n);return{lineNumber:i?null:Number(t[1]),text:e,isInfo:i}}}return{lineNumber:null,text:e,isInfo:i}}).filter((e,t,n)=>{if(e.text.trim().length>0)return!0;let r=n[t-1],i=n[t+1],a=!!(r?.isInfo||i?.isInfo),o=e.lineNumber!==null;return!(a&&o)})}},je=(e,n)=>{try{let r=e.trim().split(`
|
|
4
4
|
`).filter(Boolean);if(r.length===0)return null;let i=[];return r.forEach(e=>{let t=e.match(/^(\s*)(.+)$/);if(t){let[,e,n]=t,r=Math.floor(e.length/2),a=!n.endsWith(`/`);i.push({name:n.replace(/\/$/,``),depth:r,isFile:a})}}),(0,A.jsx)(`div`,{className:f(`w-full min-w-0 font-mono space-y-0.5`,n?.unstyled?null:`p-3 bg-muted/20 rounded-xl border border-border/30`),style:t.tool.popup,children:i.map((e,t)=>(0,A.jsx)(`div`,{className:`min-w-0`,style:{paddingLeft:`${e.depth*20}px`},children:e.isFile?(0,A.jsx)(`span`,{className:`text-foreground/90 block truncate`,children:e.name}):(0,A.jsxs)(`span`,{className:`font-semibold text-foreground block truncate`,children:[e.name,`/`]})},t))})}catch{return null}},Me={backgroundColor:`var(--status-info)`,opacity:.6},Ne=(e,n,r)=>{try{let i=e.trim().split(`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Xt as e}from"./persistence-
|
|
1
|
+
import{Xt as e}from"./persistence-DdUac14I.js";import{n as t}from"./vendor-class-variance-authority-BLUaYARZ.js";import{t as n}from"./vendor-tailwind-merge-BicNWLTg.js";function r(...e){return n(t(e))}var i=()=>typeof navigator>`u`?!1:/Macintosh|Mac OS X/.test(navigator.userAgent||``),a=()=>typeof navigator>`u`?!1:/Windows/.test(navigator.userAgent||``),o=()=>i()?`common.revealPath.finder`:a()?`common.revealPath.fileExplorer`:`common.revealPath.fileManager`,s=t=>i()&&e()?t.metaKey:t.ctrlKey,c=()=>i()&&e()?`⌘`:`Ctrl`,l=(e,t)=>{let n=e??``,r=Math.max(16,t?.maxLength??45);if(n.length<=r)return n;let i=n.split(`/`);if(i.length<=1)return n;let a=i.pop()??``;if(!a)return n;let o=Math.max(0,r-(a.length+2));if(o<=0)return`…/${a}`;let s=``;for(let e of i){if(!e)continue;let t=s?`${s}/${e}`:e;if(t.length>o)break;s=t}if(!s){let e=i[0]??``;s=e?e.slice(0,o):``}return s?`${s}…/${a}`:`…/${a}`},u=e=>e?e===`/`?`/`:e.replace(/\/+$/,``):``;function d(e,t){if(!e)return``;let n=u(e);if(n===`/`)return`/`;let r=t?u(t):void 0;if(r&&r!==`/`){if(n===r)return`~`;if(n.startsWith(`${r}/`)){let e=n.slice(r.length+1);return e?`~/${e}`:`~`}}return n}function f(e,t){if(!e)return`/`;let n=u(e);if(!n||n===`/`)return`/`;let r=t?u(t):void 0;return r&&r!==`/`&&n===r?`~`:n.split(`/`).pop()||n||`/`}export{o as a,l as c,c as i,f as n,s as o,d as r,i as s,r as t};
|
package/dist/index.html
CHANGED
|
@@ -552,24 +552,24 @@
|
|
|
552
552
|
opacity: 0.72;
|
|
553
553
|
}
|
|
554
554
|
</style>
|
|
555
|
-
<script type="module" crossorigin src="/assets/main-
|
|
555
|
+
<script type="module" crossorigin src="/assets/main-CFs9ZjGz.js"></script>
|
|
556
556
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-C0FnF6B9.js">
|
|
557
557
|
<link rel="modulepreload" crossorigin href="/assets/vendor-base-ui-CnHfUmDN.js">
|
|
558
558
|
<link rel="modulepreload" crossorigin href="/assets/vendor-zustand-B4dlGEM2.js">
|
|
559
|
-
<link rel="modulepreload" crossorigin href="/assets/useUIStore-
|
|
559
|
+
<link rel="modulepreload" crossorigin href="/assets/useUIStore-CuaA8-Hp.js">
|
|
560
560
|
<link rel="modulepreload" crossorigin href="/assets/vendor-pathe-vBmvQE8f.js">
|
|
561
561
|
<link rel="modulepreload" crossorigin href="/assets/vendor-react-DLPElpoQ.js">
|
|
562
562
|
<link rel="modulepreload" crossorigin href="/assets/vendor-tanstack-query-core-BWz0ose6.js">
|
|
563
|
-
<link rel="modulepreload" crossorigin href="/assets/persistence-
|
|
564
|
-
<link rel="modulepreload" crossorigin href="/assets/desktopHosts-
|
|
565
|
-
<link rel="modulepreload" crossorigin href="/assets/desktopRelayRestore-
|
|
563
|
+
<link rel="modulepreload" crossorigin href="/assets/persistence-DdUac14I.js">
|
|
564
|
+
<link rel="modulepreload" crossorigin href="/assets/desktopHosts-CWxex1c3.js">
|
|
565
|
+
<link rel="modulepreload" crossorigin href="/assets/desktopRelayRestore-9EbBYQ9s.js">
|
|
566
566
|
<link rel="modulepreload" crossorigin href="/assets/vendor-opencode-sdk-C07HQypa.js">
|
|
567
567
|
<link rel="modulepreload" crossorigin href="/assets/vendor-aparajita-capacitor-secure-storage-CjQdwfjS.js">
|
|
568
|
-
<link rel="modulepreload" crossorigin href="/assets/platform-
|
|
569
|
-
<link rel="modulepreload" crossorigin href="/assets/terminalApi-
|
|
568
|
+
<link rel="modulepreload" crossorigin href="/assets/platform-B4KKLnZ5.js">
|
|
569
|
+
<link rel="modulepreload" crossorigin href="/assets/terminalApi-947l7Ra3.js">
|
|
570
570
|
<link rel="modulepreload" crossorigin href="/assets/types-BuiqMmh_.js">
|
|
571
571
|
<link rel="modulepreload" crossorigin href="/assets/capgoAdapter-DCowZ2ab.js">
|
|
572
|
-
<link rel="modulepreload" crossorigin href="/assets/runtimeConfig-
|
|
572
|
+
<link rel="modulepreload" crossorigin href="/assets/runtimeConfig-9_0HQLm2.js">
|
|
573
573
|
<link rel="stylesheet" crossorigin href="/assets/src-DasvfkEg.css">
|
|
574
574
|
</head>
|
|
575
575
|
<body class="h-full bg-background text-foreground">
|
package/dist/mini-chat.html
CHANGED
|
@@ -74,24 +74,24 @@
|
|
|
74
74
|
}
|
|
75
75
|
</style>
|
|
76
76
|
|
|
77
|
-
<script type="module" crossorigin src="/assets/miniChat-
|
|
77
|
+
<script type="module" crossorigin src="/assets/miniChat-C590b4rQ.js"></script>
|
|
78
78
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-C0FnF6B9.js">
|
|
79
79
|
<link rel="modulepreload" crossorigin href="/assets/vendor-base-ui-CnHfUmDN.js">
|
|
80
80
|
<link rel="modulepreload" crossorigin href="/assets/vendor-zustand-B4dlGEM2.js">
|
|
81
|
-
<link rel="modulepreload" crossorigin href="/assets/useUIStore-
|
|
81
|
+
<link rel="modulepreload" crossorigin href="/assets/useUIStore-CuaA8-Hp.js">
|
|
82
82
|
<link rel="modulepreload" crossorigin href="/assets/vendor-pathe-vBmvQE8f.js">
|
|
83
83
|
<link rel="modulepreload" crossorigin href="/assets/vendor-react-DLPElpoQ.js">
|
|
84
84
|
<link rel="modulepreload" crossorigin href="/assets/vendor-tanstack-query-core-BWz0ose6.js">
|
|
85
|
-
<link rel="modulepreload" crossorigin href="/assets/persistence-
|
|
86
|
-
<link rel="modulepreload" crossorigin href="/assets/desktopHosts-
|
|
87
|
-
<link rel="modulepreload" crossorigin href="/assets/desktopRelayRestore-
|
|
85
|
+
<link rel="modulepreload" crossorigin href="/assets/persistence-DdUac14I.js">
|
|
86
|
+
<link rel="modulepreload" crossorigin href="/assets/desktopHosts-CWxex1c3.js">
|
|
87
|
+
<link rel="modulepreload" crossorigin href="/assets/desktopRelayRestore-9EbBYQ9s.js">
|
|
88
88
|
<link rel="modulepreload" crossorigin href="/assets/vendor-opencode-sdk-C07HQypa.js">
|
|
89
89
|
<link rel="modulepreload" crossorigin href="/assets/vendor-aparajita-capacitor-secure-storage-CjQdwfjS.js">
|
|
90
|
-
<link rel="modulepreload" crossorigin href="/assets/platform-
|
|
91
|
-
<link rel="modulepreload" crossorigin href="/assets/terminalApi-
|
|
90
|
+
<link rel="modulepreload" crossorigin href="/assets/platform-B4KKLnZ5.js">
|
|
91
|
+
<link rel="modulepreload" crossorigin href="/assets/terminalApi-947l7Ra3.js">
|
|
92
92
|
<link rel="modulepreload" crossorigin href="/assets/types-BuiqMmh_.js">
|
|
93
93
|
<link rel="modulepreload" crossorigin href="/assets/capgoAdapter-DCowZ2ab.js">
|
|
94
|
-
<link rel="modulepreload" crossorigin href="/assets/runtimeConfig-
|
|
94
|
+
<link rel="modulepreload" crossorigin href="/assets/runtimeConfig-9_0HQLm2.js">
|
|
95
95
|
<link rel="stylesheet" crossorigin href="/assets/src-DasvfkEg.css">
|
|
96
96
|
</head>
|
|
97
97
|
<body class="h-full bg-background text-foreground">
|
package/dist/mobile.html
CHANGED
|
@@ -63,24 +63,24 @@
|
|
|
63
63
|
})();
|
|
64
64
|
</script>
|
|
65
65
|
|
|
66
|
-
<script type="module" crossorigin src="/assets/mobile-
|
|
66
|
+
<script type="module" crossorigin src="/assets/mobile-CF2VLQTo.js"></script>
|
|
67
67
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-C0FnF6B9.js">
|
|
68
68
|
<link rel="modulepreload" crossorigin href="/assets/vendor-base-ui-CnHfUmDN.js">
|
|
69
69
|
<link rel="modulepreload" crossorigin href="/assets/vendor-zustand-B4dlGEM2.js">
|
|
70
|
-
<link rel="modulepreload" crossorigin href="/assets/useUIStore-
|
|
70
|
+
<link rel="modulepreload" crossorigin href="/assets/useUIStore-CuaA8-Hp.js">
|
|
71
71
|
<link rel="modulepreload" crossorigin href="/assets/vendor-pathe-vBmvQE8f.js">
|
|
72
72
|
<link rel="modulepreload" crossorigin href="/assets/vendor-react-DLPElpoQ.js">
|
|
73
73
|
<link rel="modulepreload" crossorigin href="/assets/vendor-tanstack-query-core-BWz0ose6.js">
|
|
74
|
-
<link rel="modulepreload" crossorigin href="/assets/persistence-
|
|
75
|
-
<link rel="modulepreload" crossorigin href="/assets/desktopHosts-
|
|
76
|
-
<link rel="modulepreload" crossorigin href="/assets/desktopRelayRestore-
|
|
74
|
+
<link rel="modulepreload" crossorigin href="/assets/persistence-DdUac14I.js">
|
|
75
|
+
<link rel="modulepreload" crossorigin href="/assets/desktopHosts-CWxex1c3.js">
|
|
76
|
+
<link rel="modulepreload" crossorigin href="/assets/desktopRelayRestore-9EbBYQ9s.js">
|
|
77
77
|
<link rel="modulepreload" crossorigin href="/assets/vendor-opencode-sdk-C07HQypa.js">
|
|
78
78
|
<link rel="modulepreload" crossorigin href="/assets/vendor-aparajita-capacitor-secure-storage-CjQdwfjS.js">
|
|
79
|
-
<link rel="modulepreload" crossorigin href="/assets/platform-
|
|
80
|
-
<link rel="modulepreload" crossorigin href="/assets/terminalApi-
|
|
79
|
+
<link rel="modulepreload" crossorigin href="/assets/platform-B4KKLnZ5.js">
|
|
80
|
+
<link rel="modulepreload" crossorigin href="/assets/terminalApi-947l7Ra3.js">
|
|
81
81
|
<link rel="modulepreload" crossorigin href="/assets/types-BuiqMmh_.js">
|
|
82
82
|
<link rel="modulepreload" crossorigin href="/assets/capgoAdapter-DCowZ2ab.js">
|
|
83
|
-
<link rel="modulepreload" crossorigin href="/assets/runtimeConfig-
|
|
83
|
+
<link rel="modulepreload" crossorigin href="/assets/runtimeConfig-9_0HQLm2.js">
|
|
84
84
|
<link rel="stylesheet" crossorigin href="/assets/src-DasvfkEg.css">
|
|
85
85
|
</head>
|
|
86
86
|
<body class="h-full bg-background text-foreground">
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Acceptance criteria
|
|
4
4
|
|
|
5
|
-
The in-app Assistant is an OpenChamber-owned **contact**. OpenCode is only the LLM gateway (`POST /api/openchamber/llm/chat/completions`) using already-connected `{providerID, modelID}`. Composer send runs `@earendil-works/pi-agent-core` with `thinkingLevel: 'off'` and OpenChamber API tools
|
|
5
|
+
The in-app Assistant is an OpenChamber-owned **contact**. OpenCode is only the LLM gateway (`POST /api/openchamber/llm/chat/completions`) using already-connected `{providerID, modelID}`. Composer send runs `@earendil-works/pi-agent-core` with `thinkingLevel: 'off'`. When the assistant has an effective workspace, the harness attaches pi's four coding tools (`read`, `write`, `edit`, `bash`) via `NodeExecutionEnv` in that directory, applies `defaultPrompt`, and merges skills from `~/.claude/skills`, `~/.agents/skills`, plus the project's `.claude/skills` and `.agents/skills` (project wins on name). OpenChamber API tools remain (`new_conversation`, `list_projects`, `list_sessions`, `create_assistant`, `schedule_task`, `message_assistant`, `assign_session`). It does not use `SessionPrompt` / `promptAsync` as the conversation engine. The LLM gateway throwaway session still denies OpenCode tools; file and shell work runs in-process through pi.
|
|
6
6
|
|
|
7
7
|
**Session cards (this PR)**
|
|
8
8
|
|
|
@@ -83,7 +83,7 @@ Snapshots expose the latest 50 `historySessionIDs` in chronological order and `h
|
|
|
83
83
|
- In-process tests use `whenContactTurnSettled(messageID)` (not part of the HTTP JSON body).
|
|
84
84
|
- Completions: public `POST /llm/chat/completions` still rejects `stream:true`. In-process contact harness passes `onTextDelta` + `globalEventHub` through `boundCompletion` → `createChatCompletion` → throwaway generate for real tokens only.
|
|
85
85
|
|
|
86
|
-
Composer messages carry a client message ID. The service accepts the existing OpenCode delivery parts (`{ type: 'text' }` and `{ type: 'file', mime, url, filename? }` data URLs — not a second attachment store), extracts text (`[attachment]` when the send is file-only), admits the user at 202, then runs the contact harness asynchronously (`runContactTurn` / pi-agent-core, thinking off, OpenChamber tools `new_conversation` / `list_projects` / `list_sessions` / `create_assistant` / `schedule_task` / `message_assistant` / `assign_session`
|
|
86
|
+
Composer messages carry a client message ID. The service accepts the existing OpenCode delivery parts (`{ type: 'text' }` and `{ type: 'file', mime, url, filename? }` data URLs — not a second attachment store), extracts text (`[attachment]` when the send is file-only), admits the user at 202, then runs the contact harness asynchronously (`runContactTurn` / pi-agent-core, thinking off, pi `read` / `write` / `edit` / `bash` in the assistant workspace, OpenChamber tools `new_conversation` / `list_projects` / `list_sessions` / `create_assistant` / `schedule_task` / `message_assistant` / `assign_session`, merged `.agents`/`.claude` skills, plus the registered-projects catalog each turn) through the OpenChamber completions gateway (public HTTP non-streaming; in-process `onTextDelta` for contact SSE). Assistant bubbles and tool cards persist at turn end. File parts survive `GET /:id/contact/messages`. The harness forwards those file parts to the completions gateway. Image data URLs reach `promptAsync` only when the connected catalog marks the model as vision-capable; otherwise generate keeps the `[image: …]` description and text-file bytes so a non-vision model cannot stall the contact turn. Gateway 502 responses include `{ error, message }` so the composer can show the OpenCode error string. OpenCode `promptAsync` is not the contact conversation engine; assign uses it only on the **worker** session. Share and queued delivery still use it on Assistant bindings. OpenCode `204` is an admitted empty response. A 404 restores one generation-scoped binding before retrying. Ambiguous network errors preserve the client message ID without another send. Every committed Assistant revision publishes `openchamber:assistants-changed` only after its SQLite transaction completes; clients use the tip to reload the authoritative snapshot after worker-driven stateless binding changes. `POST /:id/session/abort` requires the same `{ sessionID, sessionGeneration }`, returns the binding and `aborted: true`, reports a changed binding as `revision_conflict`, and preserves upstream missing-session `not_found` semantics.
|
|
87
87
|
|
|
88
88
|
`GET /api/openchamber/assistants/:assistantID/messages?before=&limit=` returns archived and current bindings as `{ entries: [{ sessionID, directory, info, parts }], nextCursor, complete }`. It reads assistant-owned mirror rows in chronological session and message order, pages toward older rows with an opaque stable cursor, and preserves the raw OpenCode `info` and `part` JSON. `directory` is the effective workspace for that source session and is nullable for legacy archived rows with an unknown workspace. `complete === (nextCursor === null)` marks arrival at the oldest available history. The service reads the latest persisted `limit + 1` rows first, then demand-backfills one page at a time from the newest incomplete archived session covered by the cursor; a request performs at most three upstream pages and reuses persisted pages without upstream access. Backfill page commits are independent. Each `session.messages` page attempt retries only transient 5xx/network-class SDK failures up to three times with short backoff; persistent failures still throw `upstream_error`. An authoritative OpenCode 404 for an archived or old binding marks that session's backfill complete via the `session-missing` reducer path, deletes only its uncovered event mirrors, preserves covered/admitted rows, and continues scanning other incomplete sessions so one deleted session cannot permanently block Assistant history. Successful backfill pages upsert authoritative rows without clearing provisional mirrors missing from that snapshot. Concurrent ensure that replaces a missing current binding archives the old ID and creates a new one; 404 completion never deletes covered history under either identity. A required-page failure surfaces as an upstream error only when the current request's `pageRows()` is empty; when the current range already has covered or provisional rows, the service returns that partial result and keeps the incomplete cursor retryable. Provisional event mirrors stay readable as `covered=0` fallbacks until a shrink-whitelist signal or a later authoritative upsert elevates them. Current-session live sync overrides the matching SQLite message identity in the UI.
|
|
89
89
|
|
|
@@ -93,4 +93,4 @@ Share operations persist operation identity, Assistant identity, payload hash, p
|
|
|
93
93
|
|
|
94
94
|
Schema v2 migrates legacy Inbox bindings once. It prefers the legacy Inbox session, then the latest successful operation or turn session. Schema v5 makes `workspace_path` nullable and migrates stored managed paths under `dataDir/assistant-workspaces/<assistantID>` to `NULL`. Schema v7 adds `mode` (`continuous` | `stateless`, default `continuous`) and preserves legacy `assistant.mode` during Inbox migration. Schema v10 establishes demand-driven history backfill semantics; existing mirror rows remain partial until a complete backfill state is persisted. New records use `assistant_v2` and carry no legacy topic field. Legacy topic, turn, operation, and assistant tables remain migration sources and compatibility backups. Runtime code never reads or writes them. Migration retains OpenCode sessions and messages.
|
|
95
95
|
|
|
96
|
-
Assistant workspaces resolve only under the Assistant workspace root or configured project roots. DTO serialization resolves and creates the managed target through the same containment checks, so project-configured Assistants expose a ready canonical destination for a future managed switch. Managed workspace creation resolves and creates `dataDir/assistant-workspaces/<assistantID>` before a session switch creates its OpenCode session and commits the configuration CAS. Route registration refreshes the authoritative project roots for each request. Each OpenCode session, prompt, message lookup, and skill discovery uses the effective workspace directory, so OpenCode applies its standard workspace skill discovery and configuration.
|
|
96
|
+
Assistant workspaces resolve only under the Assistant workspace root or configured project roots. DTO serialization resolves and creates the managed target through the same containment checks, so project-configured Assistants expose a ready canonical destination for a future managed switch. Managed workspace creation resolves and creates `dataDir/assistant-workspaces/<assistantID>` before a session switch creates its OpenCode session and commits the configuration CAS. Route registration refreshes the authoritative project roots for each request. Each OpenCode session, prompt, message lookup, and skill discovery uses the effective workspace directory, so OpenCode applies its standard workspace skill discovery and configuration. Contact turns additionally merge `~/.claude/skills`, `~/.agents/skills`, and the workspace `.claude/skills` plus `.agents/skills` into the pi system prompt (project wins on name) and append `defaultPrompt`. `skill_roots` is a legacy schema field; migration removes it from `assistant_v2`, and runtime DTOs, input payloads, and writes omit it. `close()` clears the share-retention scheduler and closes SQLite.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AssignError, PROJECT_REQUIRED_MESSAGE } from './assign.js';
|
|
2
2
|
import { createAssistantCardPart, createScheduleCardPart, createSessionCardPart } from './cards.js';
|
|
3
|
+
import { isPiCodingToolName } from './pi-tools.js';
|
|
3
4
|
|
|
4
5
|
const typeboxString = (description) => {
|
|
5
6
|
const schema = { type: 'string', description };
|
|
@@ -34,7 +35,7 @@ export const NEW_CONVERSATION_CONFIRM_BUBBLE = 'Started a new conversation. Prev
|
|
|
34
35
|
const LIST_SESSIONS_LIMIT_DEFAULT = 20;
|
|
35
36
|
const LIST_SESSIONS_LIMIT_MAX = 50;
|
|
36
37
|
|
|
37
|
-
const DENIED_CODING_TOOLS = new Set(['
|
|
38
|
+
const DENIED_CODING_TOOLS = new Set(['glob', 'grep', 'shell', 'find', 'ls', 'powershell']);
|
|
38
39
|
|
|
39
40
|
const FENCE = new RegExp(`\`\`\`${CONTACT_TOOL_FENCE}\\s*([\\s\\S]*?)\`\`\``, 'u');
|
|
40
41
|
export const MISSED_FENCE_RETRY_USER_TEXT = 'emit the fence now, do not claim success.';
|
|
@@ -42,7 +43,7 @@ export const MISSED_TOOL_FAILURE_BUBBLE = 'I could not complete that. No tool ra
|
|
|
42
43
|
|
|
43
44
|
const CREATE_ASSISTANT_INTENT = /建助理|新建[^。\n!]{0,24}助理|创建[^。\n!]{0,24}助理|加一个助理|create (?:an |a new )?assistant|new assistant/iu;
|
|
44
45
|
const SCHEDULE_TASK_INTENT = /排定时任务|排个?定时任务|定时任务|schedule (?:a )?(?:daily )?(?:task|ping)|scheduled task|排个?(?:每日)?(?:任务|ping)/iu;
|
|
45
|
-
const ASSIGN_SESSION_INTENT = /建会话|开会话|开(?:一个)?(?:编码\s*)?(?:session|会话)|open (?:a )?(?:coding )?session|assign_session
|
|
46
|
+
const ASSIGN_SESSION_INTENT = /建会话|开会话|开(?:一个)?(?:编码\s*)?(?:session|会话)|open (?:a )?(?:coding )?session|assign_session/giu;
|
|
46
47
|
const MESSAGE_ASSISTANT_INTENT = /给[^。\n]{1,40}说(?:一声)?|跟[^。\n]{1,24}说(?:一声)?|告诉(?!我)[^。\n]{1,40}|说一声|message (?:the )?(?:assistant|peer)|(?:tell|message)\s+[A-Za-z0-9._-]+|send (?:a )?message to/iu;
|
|
47
48
|
const NEW_CONVERSATION_INTENT = /开新对话|新对话|清空(?:聊天|对话)|clear chat|new conversation|start over/iu;
|
|
48
49
|
const LIST_PROJECTS_INTENT = /找项目|查项目|看看项目|有哪些项目|项目列表|list projects|find project|registered project|which project/iu;
|
|
@@ -387,7 +388,9 @@ export function resolvePeerAssistant(params = {}, assistants = [], currentAssist
|
|
|
387
388
|
}
|
|
388
389
|
|
|
389
390
|
export function formatContactToolsPrompt(tools) {
|
|
390
|
-
const list = Array.isArray(tools)
|
|
391
|
+
const list = Array.isArray(tools)
|
|
392
|
+
? tools.filter((tool) => tool?.name && !DENIED_CODING_TOOLS.has(tool.name) && !isPiCodingToolName(tool.name))
|
|
393
|
+
: [];
|
|
391
394
|
if (list.length === 0) return '';
|
|
392
395
|
return [
|
|
393
396
|
'The user talks in natural language (including Chinese). Never ask them to type slash commands.',
|
|
@@ -395,7 +398,7 @@ export function formatContactToolsPrompt(tools) {
|
|
|
395
398
|
'When they want to find a registered project (找项目 / list projects / "openchamber yee"), call list_projects or use the Registered projects block already in context.',
|
|
396
399
|
'When they want existing conversations in a project (现有对话 / list sessions), call list_sessions.',
|
|
397
400
|
'When they want another assistant (建助理 / create an assistant), call create_assistant.',
|
|
398
|
-
'When they want
|
|
401
|
+
'When they want a separate Chat coding session (建会话 / open a session / 开个新会话), call assign_session after matching the project. File and shell work in this assistant\'s working directory uses read, write, edit, and bash — not assign_session.',
|
|
399
402
|
'When they want a scheduled task (排定时任务 / schedule daily ping), call schedule_task.',
|
|
400
403
|
'When they want to tell another assistant (给 PeerQA 说一声 / message PeerQA), call message_assistant.',
|
|
401
404
|
`Call exactly one tool per reply by emitting one fenced JSON block:`,
|
|
@@ -90,6 +90,8 @@ describe('contact tool protocol', () => {
|
|
|
90
90
|
]);
|
|
91
91
|
expect(detectRequestedContactTools('每天 18:00 排一个 ping 定时任务', tools)).toEqual([SCHEDULE_TASK_TOOL_NAME]);
|
|
92
92
|
expect(detectRequestedContactTools('建会话写一个文件', tools)).toEqual([ASSIGN_SESSION_TOOL_NAME]);
|
|
93
|
+
expect(detectRequestedContactTools('写一个文件', tools)).toEqual([]);
|
|
94
|
+
expect(detectRequestedContactTools('pwd', tools)).toEqual([]);
|
|
93
95
|
expect(detectRequestedContactTools('给 PeerQA 说一声 hello-from-assistant 写好了', tools)).toEqual([
|
|
94
96
|
MESSAGE_ASSISTANT_TOOL_NAME,
|
|
95
97
|
]);
|
|
@@ -103,9 +105,16 @@ describe('contact tool protocol', () => {
|
|
|
103
105
|
expect(detectRequestedContactTools('不要开编码 session', tools)).toEqual([]);
|
|
104
106
|
});
|
|
105
107
|
|
|
106
|
-
it('
|
|
107
|
-
const text = '```openchamber-tool\n{"name":"bash","arguments":{"command":"
|
|
108
|
-
expect(parseContactToolCalls(text, ['bash', ASSIGN_SESSION_TOOL_NAME]).toolCall).
|
|
108
|
+
it('parses bash fences when the pi coding tools are allowed', () => {
|
|
109
|
+
const text = '```openchamber-tool\n{"name":"bash","arguments":{"command":"pwd"}}\n```';
|
|
110
|
+
expect(parseContactToolCalls(text, ['bash', ASSIGN_SESSION_TOOL_NAME]).toolCall).toEqual({
|
|
111
|
+
name: 'bash',
|
|
112
|
+
arguments: { command: 'pwd' },
|
|
113
|
+
});
|
|
114
|
+
expect(parseContactToolCalls(
|
|
115
|
+
'```openchamber-tool\n{"name":"glob","arguments":{"pattern":"*"}}\n```',
|
|
116
|
+
['glob', 'bash'],
|
|
117
|
+
).toolCall).toBeNull();
|
|
109
118
|
});
|
|
110
119
|
|
|
111
120
|
it('tells DeepSeek to call tools from natural language, not slash commands', () => {
|
|
@@ -132,12 +141,12 @@ describe('contact tool protocol', () => {
|
|
|
132
141
|
});
|
|
133
142
|
|
|
134
143
|
it('fuzzy-matches project labels like openchamber yee / openchamer yee', () => {
|
|
135
|
-
const project = { id: 'p1', path: '/Users/me/Code/
|
|
144
|
+
const project = { id: 'p1', path: '/Users/me/Code/sample-app', label: 'OpenChamber Yee' };
|
|
136
145
|
expect(matchesProjectQuery(project, 'openchamber yee')).toBe(true);
|
|
137
146
|
expect(matchesProjectQuery(project, 'openchamer yee')).toBe(true);
|
|
138
147
|
expect(matchesProjectQuery(project, 'missing')).toBe(false);
|
|
139
148
|
expect(filterRegisteredProjects([project, { id: 'p2', path: '/other' }], 'openchamber')).toEqual([
|
|
140
|
-
{ id: 'p1', path: '/Users/me/Code/
|
|
149
|
+
{ id: 'p1', path: '/Users/me/Code/sample-app', label: 'OpenChamber Yee' },
|
|
141
150
|
]);
|
|
142
151
|
expect(formatRegisteredProjectsPrompt([project])).toContain('OpenChamber Yee');
|
|
143
152
|
expect(formatRegisteredProjectsPrompt([project])).toContain('never say you cannot see registered projects');
|
|
@@ -276,12 +285,12 @@ describe('createContactTools', () => {
|
|
|
276
285
|
it('lists projects and sessions and surfaces list_sessions failure', async () => {
|
|
277
286
|
const tools = createContactTools({
|
|
278
287
|
listProjects: async () => [
|
|
279
|
-
{ id: 'proj_yee', path: '/repo/
|
|
288
|
+
{ id: 'proj_yee', path: '/repo/sample-app', label: 'OpenChamber Yee' },
|
|
280
289
|
{ id: 'proj_other', path: '/repo/other', label: 'Other' },
|
|
281
290
|
],
|
|
282
291
|
listSessions: async () => ({
|
|
283
292
|
sessions: [
|
|
284
|
-
{ sessionID: 'ses_1', title: 'Login fix', directory: '/repo/
|
|
293
|
+
{ sessionID: 'ses_1', title: 'Login fix', directory: '/repo/sample-app', updatedAt: 2 },
|
|
285
294
|
],
|
|
286
295
|
truncated: false,
|
|
287
296
|
}),
|
|
@@ -290,10 +299,10 @@ describe('createContactTools', () => {
|
|
|
290
299
|
query: 'openchamer yee',
|
|
291
300
|
});
|
|
292
301
|
expect(listed.details.projects).toEqual([
|
|
293
|
-
{ id: 'proj_yee', path: '/repo/
|
|
302
|
+
{ id: 'proj_yee', path: '/repo/sample-app', label: 'OpenChamber Yee' },
|
|
294
303
|
]);
|
|
295
304
|
const sessions = await tools.find((tool) => tool.name === LIST_SESSIONS_TOOL_NAME).execute('call_s', {
|
|
296
|
-
projectPath: '/repo/
|
|
305
|
+
projectPath: '/repo/sample-app',
|
|
297
306
|
});
|
|
298
307
|
expect(sessions.details.sessions).toEqual([
|
|
299
308
|
expect.objectContaining({ sessionID: 'ses_1', title: 'Login fix' }),
|