@av-pi-studio/web-client 0.0.13 → 0.0.15

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.
Files changed (26) hide show
  1. package/dist/web/assets/{BinaryFallbackViewer-DA3AdHMQ.js → BinaryFallbackViewer-7hheIZ3A.js} +2 -2
  2. package/dist/web/assets/{BinaryFallbackViewer-DA3AdHMQ.js.map → BinaryFallbackViewer-7hheIZ3A.js.map} +1 -1
  3. package/dist/web/assets/{ChatPanel-BPn7-j3E.js → ChatPanel-Bdmo4cj3.js} +2 -2
  4. package/dist/web/assets/{ChatPanel-BPn7-j3E.js.map → ChatPanel-Bdmo4cj3.js.map} +1 -1
  5. package/dist/web/assets/{CodeView-D1Mr31Vt.js → CodeView-CWsgotY-.js} +2 -2
  6. package/dist/web/assets/{CodeView-D1Mr31Vt.js.map → CodeView-CWsgotY-.js.map} +1 -1
  7. package/dist/web/assets/{FilePanel-rWWLYKHq.js → FilePanel-Cqx_l8-d.js} +3 -3
  8. package/dist/web/assets/{FilePanel-rWWLYKHq.js.map → FilePanel-Cqx_l8-d.js.map} +1 -1
  9. package/dist/web/assets/{ImageViewer-DOWlnLVh.js → ImageViewer-C9GKTpDu.js} +2 -2
  10. package/dist/web/assets/{ImageViewer-DOWlnLVh.js.map → ImageViewer-C9GKTpDu.js.map} +1 -1
  11. package/dist/web/assets/{MarkdownFileViewer-BWNEncBa.js → MarkdownFileViewer-D_ASYsM9.js} +2 -2
  12. package/dist/web/assets/{MarkdownFileViewer-BWNEncBa.js.map → MarkdownFileViewer-D_ASYsM9.js.map} +1 -1
  13. package/dist/web/assets/{TerminalPanel-BqceIOgb.js → TerminalPanel-CibwHc1w.js} +2 -2
  14. package/dist/web/assets/{TerminalPanel-BqceIOgb.js.map → TerminalPanel-CibwHc1w.js.map} +1 -1
  15. package/dist/web/assets/{TextViewer-ZRCymlC7.js → TextViewer-pkJbRjc7.js} +2 -2
  16. package/dist/web/assets/{TextViewer-ZRCymlC7.js.map → TextViewer-pkJbRjc7.js.map} +1 -1
  17. package/dist/web/assets/{VideoViewer-Bk2r-nwy.js → VideoViewer-DT5TCxYZ.js} +2 -2
  18. package/dist/web/assets/{VideoViewer-Bk2r-nwy.js.map → VideoViewer-DT5TCxYZ.js.map} +1 -1
  19. package/dist/web/assets/index-D7FFhNyf.js +3 -0
  20. package/dist/web/assets/index-D7FFhNyf.js.map +1 -0
  21. package/dist/web/assets/{use-file-download-DCDpzMZs.js → use-file-download-BwcSg8H8.js} +2 -2
  22. package/dist/web/assets/{use-file-download-DCDpzMZs.js.map → use-file-download-BwcSg8H8.js.map} +1 -1
  23. package/dist/web/index.html +1 -1
  24. package/package.json +3 -3
  25. package/dist/web/assets/index-DnLvR47L.js +0 -3
  26. package/dist/web/assets/index-DnLvR47L.js.map +0 -1
@@ -1,2 +1,2 @@
1
- var m=Object.defineProperty;var p=(n,e,t)=>e in n?m(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var l=(n,e,t)=>p(n,typeof e!="symbol"?e+"":e,t);import{r as u}from"./vendor-react-BoIQBqDW.js";import{u as h}from"./vendor-query-CAh-Aqig.js";import{a as d,r as w}from"./index-DnLvR47L.js";import"./vendor--os7hw7d.js";function y(n){const e=n.reduce((i,s)=>i+s.length,0),t=new Uint8Array(e);let o=0;for(const i of n)t.set(i,o),o+=i.length;return t}class g{constructor(e){l(this,"pending",new Map);l(this,"nextStream",1);l(this,"detach",null);this.daemon=e}start(){this.detach||(this.detach=this.daemon.onFileTransferFrame(e=>this.dispatch(e)))}stop(){var e;(e=this.detach)==null||e.call(this),this.detach=null;for(const[t,o]of this.pending)o.reject(new Error("file transfer router stopped")),this.pending.delete(t)}async download(e){const t=await this.daemon.request("file_download_token_request",{path:e});if(!t.ok||!t.token)throw new Error(t.error??"failed to issue download token");const o=this.nextStream++,i=new Promise((a,r)=>{this.pending.set(o,{chunks:[],meta:{},resolve:a,reject:r})}),s=await this.daemon.request("file_download_request",{token:t.token,stream:o});if(!s.ok)throw this.pending.delete(o),new Error(s.error??"download request failed");return i}dispatch(e){const t=this.pending.get(e.stream);if(t)switch(e.opcode){case"Begin":t.meta.fileName=e.meta.fileName,t.meta.mimeType=e.meta.mimeType;return;case"Chunk":t.chunks.push(e.data);return;case"End":this.pending.delete(e.stream),e.ok?t.resolve({bytes:y(t.chunks),...t.meta}):t.reject(new Error("download failed"));return;case"Error":this.pending.delete(e.stream),t.reject(new Error(e.message));return}}}const f=new WeakMap;function k(n){let e=f.get(n);return e||(e=new g(n),e.start(),f.set(n,e)),e}function q(n,e=!0){var a;const t=d(r=>r.client),o=d(r=>r.daemon),i=h({queryKey:w.fileDownload(n),queryFn:async()=>{if(!t||!o)throw new Error("not connected");const r=await k(o).download(n),c=new Blob([Uint8Array.from(r.bytes)],{type:r.mimeType||"application/octet-stream"});return{objectUrl:URL.createObjectURL(c),mimeType:r.mimeType,fileName:r.fileName}},enabled:!!t&&!!o&&!!n&&e,staleTime:1/0,gcTime:0}),s=u.useRef(null);return u.useEffect(()=>{var c;const r=((c=i.data)==null?void 0:c.objectUrl)??null;r&&s.current&&s.current!==r&&URL.revokeObjectURL(s.current),s.current=r},[(a=i.data)==null?void 0:a.objectUrl]),u.useEffect(()=>()=>{s.current&&URL.revokeObjectURL(s.current)},[]),i}export{q as u};
2
- //# sourceMappingURL=use-file-download-DCDpzMZs.js.map
1
+ var m=Object.defineProperty;var p=(n,e,t)=>e in n?m(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var l=(n,e,t)=>p(n,typeof e!="symbol"?e+"":e,t);import{r as u}from"./vendor-react-BoIQBqDW.js";import{u as h}from"./vendor-query-CAh-Aqig.js";import{a as d,r as w}from"./index-D7FFhNyf.js";import"./vendor--os7hw7d.js";function y(n){const e=n.reduce((i,s)=>i+s.length,0),t=new Uint8Array(e);let o=0;for(const i of n)t.set(i,o),o+=i.length;return t}class g{constructor(e){l(this,"pending",new Map);l(this,"nextStream",1);l(this,"detach",null);this.daemon=e}start(){this.detach||(this.detach=this.daemon.onFileTransferFrame(e=>this.dispatch(e)))}stop(){var e;(e=this.detach)==null||e.call(this),this.detach=null;for(const[t,o]of this.pending)o.reject(new Error("file transfer router stopped")),this.pending.delete(t)}async download(e){const t=await this.daemon.request("file_download_token_request",{path:e});if(!t.ok||!t.token)throw new Error(t.error??"failed to issue download token");const o=this.nextStream++,i=new Promise((a,r)=>{this.pending.set(o,{chunks:[],meta:{},resolve:a,reject:r})}),s=await this.daemon.request("file_download_request",{token:t.token,stream:o});if(!s.ok)throw this.pending.delete(o),new Error(s.error??"download request failed");return i}dispatch(e){const t=this.pending.get(e.stream);if(t)switch(e.opcode){case"Begin":t.meta.fileName=e.meta.fileName,t.meta.mimeType=e.meta.mimeType;return;case"Chunk":t.chunks.push(e.data);return;case"End":this.pending.delete(e.stream),e.ok?t.resolve({bytes:y(t.chunks),...t.meta}):t.reject(new Error("download failed"));return;case"Error":this.pending.delete(e.stream),t.reject(new Error(e.message));return}}}const f=new WeakMap;function k(n){let e=f.get(n);return e||(e=new g(n),e.start(),f.set(n,e)),e}function q(n,e=!0){var a;const t=d(r=>r.client),o=d(r=>r.daemon),i=h({queryKey:w.fileDownload(n),queryFn:async()=>{if(!t||!o)throw new Error("not connected");const r=await k(o).download(n),c=new Blob([Uint8Array.from(r.bytes)],{type:r.mimeType||"application/octet-stream"});return{objectUrl:URL.createObjectURL(c),mimeType:r.mimeType,fileName:r.fileName}},enabled:!!t&&!!o&&!!n&&e,staleTime:1/0,gcTime:0}),s=u.useRef(null);return u.useEffect(()=>{var c;const r=((c=i.data)==null?void 0:c.objectUrl)??null;r&&s.current&&s.current!==r&&URL.revokeObjectURL(s.current),s.current=r},[(a=i.data)==null?void 0:a.objectUrl]),u.useEffect(()=>()=>{s.current&&URL.revokeObjectURL(s.current)},[]),i}export{q as u};
2
+ //# sourceMappingURL=use-file-download-BwcSg8H8.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-file-download-DCDpzMZs.js","sources":["../../../../client/src/file-transfer-client.ts","../../../src/hooks/use-file-download.ts"],"sourcesContent":["import { type FileTransferFrame } from \"@av-pi-studio/protocol\";\n\nimport type { DaemonClient } from \"./daemon-client.js\";\n\n/**\n * Client-side demux + assembly for binary file downloads (features/file-explorer-transfer.md\n * § Binary transfer frames). Mirrors `TerminalStreamRouter`'s inbound-frame-routing shape, but a\n * download is a one-shot request/response rather than a persistent per-slot subscription: request\n * a token, request the download, await the assembled bytes.\n */\n\nexport interface DownloadedFile {\n bytes: Uint8Array;\n fileName?: string;\n mimeType?: string;\n}\n\ninterface PendingDownload {\n chunks: Uint8Array[];\n meta: { fileName?: string; mimeType?: string };\n resolve: (file: DownloadedFile) => void;\n reject: (error: Error) => void;\n}\n\ninterface TokenResponse {\n ok: boolean;\n token?: string;\n error?: string;\n}\n\ninterface DownloadRequestResponse {\n ok: boolean;\n error?: string;\n}\n\nfunction concat(chunks: Uint8Array[]): Uint8Array {\n const total = chunks.reduce((sum, c) => sum + c.length, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n out.set(chunk, offset);\n offset += chunk.length;\n }\n return out;\n}\n\nexport class FileTransferClient {\n private readonly pending = new Map<number, PendingDownload>();\n private nextStream = 1;\n private detach: (() => void) | null = null;\n\n constructor(private readonly daemon: DaemonClient) {}\n\n /** Begin routing inbound file-transfer frames. Idempotent. */\n start(): void {\n if (this.detach) return;\n this.detach = this.daemon.onFileTransferFrame((frame) => this.dispatch(frame));\n }\n\n /** Stop routing inbound frames. Any downloads still pending are rejected. */\n stop(): void {\n this.detach?.();\n this.detach = null;\n for (const [stream, pending] of this.pending) {\n pending.reject(new Error(\"file transfer router stopped\"));\n this.pending.delete(stream);\n }\n }\n\n /**\n * Download the file at `path`: requests a single-use token, then requests the chunked\n * transfer, assembling `Begin → Chunk* → End` frames into one buffer.\n */\n async download(path: string): Promise<DownloadedFile> {\n const tokenResponse = await this.daemon.request<TokenResponse>(\n \"file_download_token_request\",\n { path },\n );\n if (!tokenResponse.ok || !tokenResponse.token) {\n throw new Error(tokenResponse.error ?? \"failed to issue download token\");\n }\n\n const stream = this.nextStream++;\n const result = new Promise<DownloadedFile>((resolve, reject) => {\n this.pending.set(stream, { chunks: [], meta: {}, resolve, reject });\n });\n\n const requestResponse = await this.daemon.request<DownloadRequestResponse>(\n \"file_download_request\",\n { token: tokenResponse.token, stream },\n );\n if (!requestResponse.ok) {\n this.pending.delete(stream);\n throw new Error(requestResponse.error ?? \"download request failed\");\n }\n\n return result;\n }\n\n private dispatch(frame: FileTransferFrame): void {\n const pending = this.pending.get(frame.stream);\n if (!pending) return; // not a download stream we're tracking (e.g. an upload) — ignore\n switch (frame.opcode) {\n case \"Begin\":\n pending.meta.fileName = frame.meta.fileName;\n pending.meta.mimeType = frame.meta.mimeType;\n return;\n case \"Chunk\":\n pending.chunks.push(frame.data);\n return;\n case \"End\":\n this.pending.delete(frame.stream);\n if (frame.ok) {\n pending.resolve({ bytes: concat(pending.chunks), ...pending.meta });\n } else {\n pending.reject(new Error(\"download failed\"));\n }\n return;\n case \"Error\":\n this.pending.delete(frame.stream);\n pending.reject(new Error(frame.message));\n return;\n }\n }\n}\n","/**\n * `use-file-download` — TanStack Query wrapper over the binary file-transfer download path\n * (`file_download_token_request` → `file_download_request` → chunked `Begin`/`Chunk`/`End`\n * binary frames), for viewers that need raw bytes rather than the UTF-8 preview\n * `file_read_request` returns (images, video — POC_TO_APP_PLAN_UI.md §4.5 follow-up: modular\n * file preview). Resolves to an object URL, revoked once superseded by a new one or once this\n * consumer unmounts.\n */\n\nimport { useEffect, useRef } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { DaemonClient } from \"@av-pi-studio/client\";\nimport { FileTransferClient } from \"@av-pi-studio/client\";\nimport { useConnectionStore } from \"@pi-studio-ui/lib/connection/connection-store.js\";\nimport { rpcKeys } from \"@pi-studio-ui/lib/connection/rpc-keys.js\";\n\n// One FileTransferClient per daemon connection — mirrors `TerminalPanel.tsx`'s `routerFor`\n// (multiple viewers share the one frame demuxer over the shared socket).\nconst transferByDaemon = new WeakMap<DaemonClient, FileTransferClient>();\n\nfunction transferFor(daemon: DaemonClient): FileTransferClient {\n let transfer = transferByDaemon.get(daemon);\n if (!transfer) {\n transfer = new FileTransferClient(daemon);\n transfer.start();\n transferByDaemon.set(daemon, transfer);\n }\n return transfer;\n}\n\nexport interface FileDownload {\n objectUrl: string;\n mimeType?: string;\n fileName?: string;\n}\n\nexport function useFileDownload(path: string, enabled = true) {\n const client = useConnectionStore((s) => s.client);\n const daemon = useConnectionStore((s) => s.daemon);\n\n const query = useQuery({\n queryKey: rpcKeys.fileDownload(path),\n queryFn: async (): Promise<FileDownload> => {\n if (!client || !daemon) throw new Error(\"not connected\");\n const file = await transferFor(daemon).download(path);\n // `Blob`'s DOM typings require an `ArrayBuffer`-backed view; the assembled `Uint8Array`'s\n // `ArrayBufferLike` backing (a decode-time implementation detail) doesn't satisfy that on\n // its own, so copy into a plain `ArrayBuffer`-backed `Uint8Array` first.\n const blob = new Blob([Uint8Array.from(file.bytes)], {\n type: file.mimeType || \"application/octet-stream\",\n });\n return { objectUrl: URL.createObjectURL(blob), mimeType: file.mimeType, fileName: file.fileName };\n },\n enabled: Boolean(client) && Boolean(daemon) && Boolean(path) && enabled,\n // Object URLs are process-local, non-serializable browser resources — never persist them or\n // silently refetch behind this hook's back (that would leak the previous blob's URL).\n staleTime: Infinity,\n gcTime: 0,\n });\n\n // Revoke the previous object URL once a new one supersedes it, and the current one on unmount\n // — TanStack Query's cache has no notion that this value owns a browser resource to release.\n const urlRef = useRef<string | null>(null);\n useEffect(() => {\n const nextUrl = query.data?.objectUrl ?? null;\n if (nextUrl && urlRef.current && urlRef.current !== nextUrl) {\n URL.revokeObjectURL(urlRef.current);\n }\n urlRef.current = nextUrl;\n }, [query.data?.objectUrl]);\n\n useEffect(() => {\n return () => {\n if (urlRef.current) URL.revokeObjectURL(urlRef.current);\n };\n }, []);\n\n return query;\n}\n"],"names":["concat","chunks","total","sum","c","out","offset","chunk","FileTransferClient","daemon","__publicField","frame","_a","stream","pending","path","tokenResponse","result","resolve","reject","requestResponse","transferByDaemon","transferFor","transfer","useFileDownload","enabled","client","useConnectionStore","s","query","useQuery","rpcKeys","file","blob","urlRef","useRef","useEffect","nextUrl"],"mappings":"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"}
1
+ {"version":3,"file":"use-file-download-BwcSg8H8.js","sources":["../../../../client/src/file-transfer-client.ts","../../../src/hooks/use-file-download.ts"],"sourcesContent":["import { type FileTransferFrame } from \"@av-pi-studio/protocol\";\n\nimport type { DaemonClient } from \"./daemon-client.js\";\n\n/**\n * Client-side demux + assembly for binary file downloads (features/file-explorer-transfer.md\n * § Binary transfer frames). Mirrors `TerminalStreamRouter`'s inbound-frame-routing shape, but a\n * download is a one-shot request/response rather than a persistent per-slot subscription: request\n * a token, request the download, await the assembled bytes.\n */\n\nexport interface DownloadedFile {\n bytes: Uint8Array;\n fileName?: string;\n mimeType?: string;\n}\n\ninterface PendingDownload {\n chunks: Uint8Array[];\n meta: { fileName?: string; mimeType?: string };\n resolve: (file: DownloadedFile) => void;\n reject: (error: Error) => void;\n}\n\ninterface TokenResponse {\n ok: boolean;\n token?: string;\n error?: string;\n}\n\ninterface DownloadRequestResponse {\n ok: boolean;\n error?: string;\n}\n\nfunction concat(chunks: Uint8Array[]): Uint8Array {\n const total = chunks.reduce((sum, c) => sum + c.length, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n out.set(chunk, offset);\n offset += chunk.length;\n }\n return out;\n}\n\nexport class FileTransferClient {\n private readonly pending = new Map<number, PendingDownload>();\n private nextStream = 1;\n private detach: (() => void) | null = null;\n\n constructor(private readonly daemon: DaemonClient) {}\n\n /** Begin routing inbound file-transfer frames. Idempotent. */\n start(): void {\n if (this.detach) return;\n this.detach = this.daemon.onFileTransferFrame((frame) => this.dispatch(frame));\n }\n\n /** Stop routing inbound frames. Any downloads still pending are rejected. */\n stop(): void {\n this.detach?.();\n this.detach = null;\n for (const [stream, pending] of this.pending) {\n pending.reject(new Error(\"file transfer router stopped\"));\n this.pending.delete(stream);\n }\n }\n\n /**\n * Download the file at `path`: requests a single-use token, then requests the chunked\n * transfer, assembling `Begin → Chunk* → End` frames into one buffer.\n */\n async download(path: string): Promise<DownloadedFile> {\n const tokenResponse = await this.daemon.request<TokenResponse>(\n \"file_download_token_request\",\n { path },\n );\n if (!tokenResponse.ok || !tokenResponse.token) {\n throw new Error(tokenResponse.error ?? \"failed to issue download token\");\n }\n\n const stream = this.nextStream++;\n const result = new Promise<DownloadedFile>((resolve, reject) => {\n this.pending.set(stream, { chunks: [], meta: {}, resolve, reject });\n });\n\n const requestResponse = await this.daemon.request<DownloadRequestResponse>(\n \"file_download_request\",\n { token: tokenResponse.token, stream },\n );\n if (!requestResponse.ok) {\n this.pending.delete(stream);\n throw new Error(requestResponse.error ?? \"download request failed\");\n }\n\n return result;\n }\n\n private dispatch(frame: FileTransferFrame): void {\n const pending = this.pending.get(frame.stream);\n if (!pending) return; // not a download stream we're tracking (e.g. an upload) — ignore\n switch (frame.opcode) {\n case \"Begin\":\n pending.meta.fileName = frame.meta.fileName;\n pending.meta.mimeType = frame.meta.mimeType;\n return;\n case \"Chunk\":\n pending.chunks.push(frame.data);\n return;\n case \"End\":\n this.pending.delete(frame.stream);\n if (frame.ok) {\n pending.resolve({ bytes: concat(pending.chunks), ...pending.meta });\n } else {\n pending.reject(new Error(\"download failed\"));\n }\n return;\n case \"Error\":\n this.pending.delete(frame.stream);\n pending.reject(new Error(frame.message));\n return;\n }\n }\n}\n","/**\n * `use-file-download` — TanStack Query wrapper over the binary file-transfer download path\n * (`file_download_token_request` → `file_download_request` → chunked `Begin`/`Chunk`/`End`\n * binary frames), for viewers that need raw bytes rather than the UTF-8 preview\n * `file_read_request` returns (images, video — POC_TO_APP_PLAN_UI.md §4.5 follow-up: modular\n * file preview). Resolves to an object URL, revoked once superseded by a new one or once this\n * consumer unmounts.\n */\n\nimport { useEffect, useRef } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { DaemonClient } from \"@av-pi-studio/client\";\nimport { FileTransferClient } from \"@av-pi-studio/client\";\nimport { useConnectionStore } from \"@pi-studio-ui/lib/connection/connection-store.js\";\nimport { rpcKeys } from \"@pi-studio-ui/lib/connection/rpc-keys.js\";\n\n// One FileTransferClient per daemon connection — mirrors `TerminalPanel.tsx`'s `routerFor`\n// (multiple viewers share the one frame demuxer over the shared socket).\nconst transferByDaemon = new WeakMap<DaemonClient, FileTransferClient>();\n\nfunction transferFor(daemon: DaemonClient): FileTransferClient {\n let transfer = transferByDaemon.get(daemon);\n if (!transfer) {\n transfer = new FileTransferClient(daemon);\n transfer.start();\n transferByDaemon.set(daemon, transfer);\n }\n return transfer;\n}\n\nexport interface FileDownload {\n objectUrl: string;\n mimeType?: string;\n fileName?: string;\n}\n\nexport function useFileDownload(path: string, enabled = true) {\n const client = useConnectionStore((s) => s.client);\n const daemon = useConnectionStore((s) => s.daemon);\n\n const query = useQuery({\n queryKey: rpcKeys.fileDownload(path),\n queryFn: async (): Promise<FileDownload> => {\n if (!client || !daemon) throw new Error(\"not connected\");\n const file = await transferFor(daemon).download(path);\n // `Blob`'s DOM typings require an `ArrayBuffer`-backed view; the assembled `Uint8Array`'s\n // `ArrayBufferLike` backing (a decode-time implementation detail) doesn't satisfy that on\n // its own, so copy into a plain `ArrayBuffer`-backed `Uint8Array` first.\n const blob = new Blob([Uint8Array.from(file.bytes)], {\n type: file.mimeType || \"application/octet-stream\",\n });\n return { objectUrl: URL.createObjectURL(blob), mimeType: file.mimeType, fileName: file.fileName };\n },\n enabled: Boolean(client) && Boolean(daemon) && Boolean(path) && enabled,\n // Object URLs are process-local, non-serializable browser resources — never persist them or\n // silently refetch behind this hook's back (that would leak the previous blob's URL).\n staleTime: Infinity,\n gcTime: 0,\n });\n\n // Revoke the previous object URL once a new one supersedes it, and the current one on unmount\n // — TanStack Query's cache has no notion that this value owns a browser resource to release.\n const urlRef = useRef<string | null>(null);\n useEffect(() => {\n const nextUrl = query.data?.objectUrl ?? null;\n if (nextUrl && urlRef.current && urlRef.current !== nextUrl) {\n URL.revokeObjectURL(urlRef.current);\n }\n urlRef.current = nextUrl;\n }, [query.data?.objectUrl]);\n\n useEffect(() => {\n return () => {\n if (urlRef.current) URL.revokeObjectURL(urlRef.current);\n };\n }, []);\n\n return query;\n}\n"],"names":["concat","chunks","total","sum","c","out","offset","chunk","FileTransferClient","daemon","__publicField","frame","_a","stream","pending","path","tokenResponse","result","resolve","reject","requestResponse","transferByDaemon","transferFor","transfer","useFileDownload","enabled","client","useConnectionStore","s","query","useQuery","rpcKeys","file","blob","urlRef","useRef","useEffect","nextUrl"],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
  <meta charset="utf-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
6
  <title>Pi-Studio</title>
7
- <script type="module" crossorigin src="/assets/index-DnLvR47L.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-D7FFhNyf.js"></script>
8
8
  <link rel="modulepreload" crossorigin href="/assets/vendor-react-BoIQBqDW.js">
9
9
  <link rel="modulepreload" crossorigin href="/assets/vendor-query-CAh-Aqig.js">
10
10
  <link rel="modulepreload" crossorigin href="/assets/vendor-markdown-B8HSIhaA.js">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@av-pi-studio/web-client",
3
- "version": "0.0.13",
3
+ "version": "0.0.15",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"
@@ -14,8 +14,8 @@
14
14
  "clean": "rm -rf dist *.tsbuildinfo"
15
15
  },
16
16
  "dependencies": {
17
- "@av-pi-studio/client": "^0.0.13",
18
- "@av-pi-studio/protocol": "^0.0.13",
17
+ "@av-pi-studio/client": "^0.0.15",
18
+ "@av-pi-studio/protocol": "^0.0.15",
19
19
  "@codemirror/language": "^6.12.4",
20
20
  "@codemirror/language-data": "^6.5.2",
21
21
  "@codemirror/state": "^6.7.1",
@@ -1,3 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ChatPanel-BPn7-j3E.js","assets/vendor-react-BoIQBqDW.js","assets/vendor-query-CAh-Aqig.js","assets/vendor-icons-DUloQbkI.js","assets/markdown-D9FuaV1m.js","assets/vendor-highlight-DCzuSv8g.js","assets/vendor-markdown-B8HSIhaA.js","assets/vendor--os7hw7d.js","assets/markdown-BQwXm0MF.css","assets/DiffView-DlVCPvLc.js","assets/DiffView-CRbeRztO.css","assets/vendor-overlays-UwLNGk04.js","assets/vendor-dnd-D9kA7FgH.js","assets/ChatPanel-Cz7YoXXW.css","assets/FilePanel-rWWLYKHq.js","assets/FilePanel-DIInFr3h.css","assets/TerminalPanel-BqceIOgb.js","assets/vendor-terminal-BhzX2_ts.js","assets/vendor-terminal-DYP7pi_n.css","assets/TerminalPanel-BQj62G6N.css"])))=>i.map(i=>d[i]);
2
- var Ct=Object.defineProperty;var Tt=(t,e,n)=>e in t?Ct(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var I=(t,e,n)=>Tt(t,typeof e!="symbol"?e+"":e,n);import{r as v,j as i,d as jt}from"./vendor-react-BoIQBqDW.js";import{Q as Nt,a as Et,u as Rt,b as Bt}from"./vendor-query-CAh-Aqig.js";import{A as d,B as g,C as R,D as Ve,E as q,F as de,G as z,H as N,I as w,J as A,K as L,L as ye,M as te,N as X}from"./vendor--os7hw7d.js";import{L as At,P as $t,a as Mt,b as Pt,c as Dt,E as qt,C as Ot,d as Ft,F as Ht,e as Ge,f as Wt,S as zt,G as Lt,g as Ut,M as Kt,X as _e,A as Je,h as Xe,i as Vt,T as Gt,R as Jt,j as Xt}from"./vendor-icons-DUloQbkI.js";import{R as Yt,T as Zt,P as Qt,C as en,I as ue,S as tn,D as nn,a as sn,b as rn,c as on,d as $e,e as ve}from"./vendor-overlays-UwLNGk04.js";import{u as an,a as cn,D as ln,c as dn,S as un,h as fn,P as pn,b as hn,C as mn}from"./vendor-dnd-D9kA7FgH.js";import{_ as Ee}from"./vendor-highlight-DCzuSv8g.js";import"./vendor-markdown-B8HSIhaA.js";(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))s(r);new MutationObserver(r=>{for(const o of r)if(o.type==="childList")for(const a of o.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&s(a)}).observe(document,{childList:!0,subtree:!0});function n(r){const o={};return r.integrity&&(o.integrity=r.integrity),r.referrerPolicy&&(o.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?o.credentials="include":r.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function s(r){if(r.ep)return;r.ep=!0;const o=n(r);fetch(r.href,o)}})();const gn=new Nt;function Ye(t){const e=t.trim().replace(/^#/,""),n=e.length===3?e.split("").map(s=>s+s).join(""):e;if(n.length!==6||/[^0-9a-fA-F]/.test(n))throw new Error(`Invalid hex color: ${t}`);return{r:parseInt(n.slice(0,2),16),g:parseInt(n.slice(2,4),16),b:parseInt(n.slice(4,6),16)}}function bn(t){return Math.max(0,Math.min(255,Math.round(t)))}function _n({r:t,g:e,b:n}){const s=r=>bn(r).toString(16).padStart(2,"0");return`#${s(t)}${s(e)}${s(n)}`}function yn(t){const{r:e,g:n,b:s}=Ye(t),r=o=>{const a=o/255;return a<=.03928?a/12.92:((a+.055)/1.055)**2.4};return .2126*r(e)+.7152*r(n)+.0722*r(s)}function Re(t,e="#18181b",n="#ffffff"){return yn(t)>.45?e:n}function wn(t,e){const{r:n,g:s,b:r}=Ye(t),o=Math.max(0,Math.min(1,e));return _n({r:n+(255-n)*o,g:s+(255-s)*o,b:r+(255-r)*o})}function fe(t){const e=t.trim().replace(/^#/,"");return(e.length===3||e.length===6)&&!/[^0-9a-fA-F]/.test(e)}const D=(t,e,n,s,r,o,a,l,c,u,h)=>({50:t,100:e,200:n,300:s,400:r,500:o,600:a,700:l,800:c,900:u,950:h}),m={zinc:D("#fafafa","#f4f4f5","#e4e4e7","#d4d4d8","#a1a1aa","#71717a","#52525b","#3f3f46","#27272a","#18181b","#09090b"),gray:D("#f9fafb","#f3f4f6","#e5e7eb","#d1d5db","#9ca3af","#6b7280","#4b5563","#374151","#1f2937","#111827","#030712"),slate:D("#f8fafc","#f1f5f9","#e2e8f0","#cbd5e1","#94a3b8","#64748b","#475569","#334155","#1e293b","#0f172a","#020617"),blue:D("#eff6ff","#dbeafe","#bfdbfe","#93c5fd","#60a5fa","#3b82f6","#2563eb","#1d4ed8","#1e40af","#1e3a8a","#172554"),green:D("#f0fdf4","#dcfce7","#bbf7d0","#86efac","#4ade80","#22c55e","#16a34a","#15803d","#166534","#14532d","#052e16"),red:D("#fef2f2","#fee2e2","#fecaca","#fca5a5","#f87171","#ef4444","#dc2626","#b91c1c","#991b1b","#7f1d1d","#450a0a"),teal:D("#f0fdfa","#ccfbf1","#99f6e4","#5eead4","#2dd4bf","#14b8a6","#0d9488","#0f766e","#115e59","#134e4a","#042f2e"),amber:D("#fffbeb","#fef3c7","#fde68a","#fcd34d","#fbbf24","#f59e0b","#d97706","#b45309","#92400e","#78350f","#451a03"),yellow:D("#fefce8","#fef9c3","#fef08a","#fde047","#facc15","#eab308","#ca8a04","#a16207","#854d0e","#713f12","#422006"),purple:D("#faf5ff","#f3e8ff","#e9d5ff","#d8b4fe","#c084fc","#a855f7","#9333ea","#7e22ce","#6b21a8","#581c87","#3b0764"),orange:D("#fff7ed","#ffedd5","#fed7aa","#fdba74","#fb923c","#f97316","#ea580c","#c2410c","#9a3412","#7c2d12","#431407"),white:"#ffffff",black:"#000000"},Sn={statusSuccess:"#16a34a",statusDanger:"#dc2626",statusWarning:"#f59e0b",statusMerged:"#9333ea"},xn={statusSuccess:"#15803d",statusDanger:"#b91c1c",statusWarning:"#d97706",statusMerged:"#7c3aed"};function vn(){return{keyword:m.purple[300],string:m.green[300],number:m.orange[300],boolean:m.orange[300],comment:m.zinc[500],function:m.blue[300],variable:m.zinc[200],type:m.teal[300],class:m.amber[300],constant:m.orange[300],operator:m.zinc[400],punctuation:m.zinc[400],tag:m.red[300],attribute:m.amber[300],property:m.blue[200],regexp:m.teal[300],escape:m.orange[200],heading:m.blue[300],link:m.blue[400],deleted:m.red[400],inserted:m.green[400]}}function kn(){return{keyword:m.purple[700],string:m.green[700],number:m.orange[700],boolean:m.orange[700],comment:m.zinc[500],function:m.blue[700],variable:m.zinc[800],type:m.teal[700],class:m.amber[700],constant:m.orange[700],operator:m.zinc[600],punctuation:m.zinc[600],tag:m.red[700],attribute:m.amber[700],property:m.blue[700],regexp:m.teal[700],escape:m.orange[700],heading:m.blue[700],link:m.blue[600],deleted:m.red[700],inserted:m.green[700]}}function Ze(t,e,n){return{background:t,foreground:e,cursor:n,cursorAccent:t,selectionBackground:"rgba(255,255,255,0.18)",black:m.zinc[900],red:m.red[500],green:m.green[500],yellow:m.amber[500],blue:m.blue[500],magenta:m.purple[500],cyan:m.teal[500],white:m.zinc[300],brightBlack:m.zinc[600],brightRed:m.red[400],brightGreen:m.green[400],brightYellow:m.amber[400],brightBlue:m.blue[400],brightMagenta:m.purple[400],brightCyan:m.teal[400],brightWhite:m.zinc[50]}}function se(t){const e=m.zinc[50],n=Re(t.accent);return{surface0:t.surface0,surface1:t.surface1,surface2:t.surface2,surface3:t.surface3,surface4:t.surface4,surfaceDiffEmpty:t.surfaceDiffEmpty,surfaceSidebar:t.surfaceSidebar,surfaceSidebarHover:t.surfaceSidebarHover,surfaceWorkspace:t.surface1,foreground:e,foregroundMuted:t.mutedForeground,accent:t.accent,accentBright:t.accentBright,accentForeground:n,destructive:t.destructive,destructiveForeground:m.white,success:t.accent,successForeground:m.white,border:t.border,borderAccent:t.borderAccent,...Sn,diffAddition:m.green[400],diffDeletion:m.red[500],scrollbarHandle:t.scrollbarHandle,background:t.surface0,popover:t.surface2,popoverForeground:e,primary:t.accent,secondary:t.surface2,muted:t.surface2,mutedForeground:t.mutedForeground,input:t.surface2,ring:t.accent,palette:m,syntax:vn(),terminal:Ze(t.surface0,e,t.accent)}}function In(){const t="#1a1a1e",e="#253e6f";return{surface0:"#ffffff",surface1:"#fafafa",surface2:"#f4f4f5",surface3:"#e4e4e7",surface4:"#d4d4d8",surfaceDiffEmpty:"#f6f6f6",surfaceSidebar:"#f4f4f5",surfaceSidebarHover:"#e9e9ec",surfaceWorkspace:"#ffffff",foreground:t,foregroundMuted:"#71717a",accent:e,accentBright:"#2f4f8e",accentForeground:Re(e),destructive:"#b04138",destructiveForeground:"#ffffff",success:e,successForeground:"#ffffff",border:"#e4e4e7",borderAccent:"#ececf1",...xn,diffAddition:"#15803d",diffDeletion:"#b91c1c",scrollbarHandle:"#3f3f46",background:"#ffffff",popover:"#ffffff",popoverForeground:t,primary:e,secondary:"#f4f4f5",muted:"#f4f4f5",mutedForeground:"#71717a",input:"#f4f4f5",ring:e,palette:m,syntax:kn(),terminal:{...Ze("#ffffff",t,e),selectionBackground:"rgba(0,0,0,0.15)",white:"#ffffff",brightWhite:"#fafafa"}}}const Cn={light:"#ffffff",dark:"#3b62b0",zinc:"#808080",midnight:"#4A6BA8",claude:"#D97757",ghostty:"#8caaee"},Qe=["light","dark","zinc","midnight","claude","ghostty"];function Tn(t){if(t==="light")return In();switch(t){case"dark":return se({surface0:"#181B1A",surface1:"#1E2120",surface2:"#272A29",surface3:"#434645",surface4:"#595B5B",surfaceDiffEmpty:"#252827",surfaceSidebar:"#141716",surfaceSidebarHover:"#1c1f1e",mutedForeground:"#A1A5A4",scrollbarHandle:"#717574",border:"#252B2A",borderAccent:"#2f3135",accent:"#2e5cb8",accentBright:"#a2b4d7",destructive:"#c64f43"});case"zinc":return se({surface0:"#18181b",surface1:"#1f1f22",surface2:"#27272a",surface3:"#3f3f46",surface4:"#52525b",surfaceDiffEmpty:"#242427",surfaceSidebar:"#131316",surfaceSidebarHover:"#1b1b1e",mutedForeground:"#a1a1aa",scrollbarHandle:"#71717a",border:"#27272a",borderAccent:"#303036",accent:"#e4e4e7",accentBright:"#fafafa",destructive:"#c44a4a"});case"midnight":return se({surface0:"#161820",surface1:"#1c1e27",surface2:"#252731",surface3:"#3c3e4c",surface4:"#535564",surfaceDiffEmpty:"#222430",surfaceSidebar:"#121420",surfaceSidebarHover:"#1a1c28",mutedForeground:"#9a9db0",scrollbarHandle:"#6b6e82",border:"#242636",borderAccent:"#2e3040",accent:"#3b6fcf",accentBright:"#7eaaeb",destructive:"#c44a52"});case"claude":return se({surface0:"#1f1f1e",surface1:"#262523",surface2:"#2f2d2b",surface3:"#4a4745",surface4:"#605d5b",surfaceDiffEmpty:"#2a2826",surfaceSidebar:"#1a1918",surfaceSidebarHover:"#222120",mutedForeground:"#ada9a5",scrollbarHandle:"#78746f",border:"#2c2a27",borderAccent:"#36332f",accent:"#d97757",accentBright:"#e89a7f",destructive:"#cf513e"});case"ghostty":return se({surface0:"#282c34",surface1:"#2f333d",surface2:"#383c48",surface3:"#4a4f5e",surface4:"#5b6175",surfaceDiffEmpty:"#323643",surfaceSidebar:"#21252d",surfaceSidebarHover:"#292d36",mutedForeground:"#c8ccd8",scrollbarHandle:"#a0a4b2",border:"#353a47",borderAccent:"#3f4454",accent:"#89b4fa",accentBright:"#b4d0fc",destructive:"#c44a55"})}}const et={};for(const t of Qe){const e=t==="light"?"light":"dark";et[t]={name:t,colorScheme:e,colors:Tn(t),swatch:Cn[t]}}const jn=et,Nn={0:0,1:4,"1.5":6,2:8,3:12,4:16,6:24,8:32,12:48,16:64,20:80,24:96,32:128},tt={xs:12,code:12,sm:14,base:16,lg:18,xl:20,"2xl":22,"3xl":26,"4xl":34},En={normal:"400",medium:"500",semibold:"600",bold:"700"},Rn={none:0,sm:2,base:4,md:6,lg:8,xl:12,"2xl":16,full:9999},Bn={0:0,1:1,2:2},An={0:0,50:.5,100:1},$n={xs:12,sm:14,md:16,lg:20},Mn={diff:22},nt='system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',st='ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace';function Pn(t){const e=t==="dark"?"rgba(0,0,0,0.55)":"rgba(24,24,27,0.12)";return{sm:{color:e,offsetX:0,offsetY:1,radius:2,elevation:1},md:{color:e,offsetX:0,offsetY:3,radius:8,elevation:4},lg:{color:e,offsetX:0,offsetY:10,radius:24,elevation:12}}}function rt(t){const e=jn[t];return{name:t,colorScheme:e.colorScheme,colors:e.colors,spacing:Nn,fontSize:{...tt},fontFamily:{ui:nt,mono:st},lineHeight:{...Mn},iconSize:$n,fontWeight:En,borderRadius:Rn,borderWidth:Bn,opacity:An,shadow:Pn(e.colorScheme),swatch:e.swatch}}const Dn=16,qn=10,On=24;function Fn(t,e){const n=e.themeName??t.name,s=rt(n),r=e.uiFont&&e.uiFont.trim()!==""?e.uiFont:nt,o=e.monoFont&&e.monoFont.trim()!==""?e.monoFont:st;let a={...s.fontSize};if(e.fontSize!=null){const c=Math.max(qn,Math.min(On,e.fontSize))/Dn,u=["xs","code","sm","base","lg","xl","2xl","3xl","4xl"];for(const h of u){const f=tt[h];a[h]=Math.round(f*c)}}return{...s,fontSize:a,fontFamily:{ui:r,mono:o}}}function Hn(t){return rt(t)}const Wn="dark";function zn(t){const e={};Ln(t.colors,e);for(const[n,s]of Object.entries(t.spacing))e[`--pi-spacing-${n}`]=`${s}px`;for(const[n,s]of Object.entries(t.fontSize))e[`--pi-font-size-${n}`]=`${s}px`;e["--pi-font-ui"]=t.fontFamily.ui,e["--pi-font-mono"]=t.fontFamily.mono,e["--pi-line-height-diff"]=`${t.lineHeight.diff}px`;for(const[n,s]of Object.entries(t.iconSize))e[`--pi-icon-size-${n}`]=`${s}px`;for(const[n,s]of Object.entries(t.fontWeight))e[`--pi-font-weight-${n}`]=String(s);for(const[n,s]of Object.entries(t.borderRadius))e[`--pi-radius-${n}`]=s===9999?"9999px":`${s}px`;for(const[n,s]of Object.entries(t.borderWidth))e[`--pi-border-width-${n}`]=`${s}px`;for(const[n,s]of Object.entries(t.opacity))e[`--pi-opacity-${n}`]=String(s);for(const[n,s]of Object.entries(t.shadow))if(typeof s=="string")e[`--pi-shadow-${n}`]=s;else if(s&&typeof s=="object"){const r=s;e[`--pi-shadow-${n}`]=`${r.offsetX}px ${r.offsetY}px ${r.radius}px ${r.color}`}return e["--pi-color-scheme"]=t.colorScheme,e}function Ln(t,e){const{palette:n,syntax:s,terminal:r,...o}=t;for(const[a,l]of Object.entries(o))typeof l=="string"&&(e[`--pi-color-${a}`]=l);s&&Un(s,e),r&&(e["--pi-terminal-bg"]=r.background,e["--pi-terminal-fg"]=r.foreground)}function Un(t,e){for(const[n,s]of Object.entries(t))typeof s=="string"&&(e[`--syntax-${Kn(n)}`]=s)}function Kn(t){return t.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}function Vn(t){if(typeof document>"u")return;const e=document.documentElement.style;for(const[s,r]of Object.entries(t))e.setProperty(s,r);const n=t["--pi-color-scheme"];n&&document.documentElement.style.setProperty("color-scheme",n)}function Gn(t){const e=zn(t);Vn(e)}const re=d().min(1,"Asset path must not be empty"),Jn=g({accent:d().refine(fe,{message:"accent must be a valid #rrggbb hex color"}),accentBright:d().refine(fe,{message:"accentBright must be a valid #rrggbb hex color"}).optional(),accentForeground:d().refine(fe,{message:"accentForeground must be a valid #rrggbb hex color"}).optional(),swatch:d().refine(fe,{message:"swatch must be a valid #rrggbb hex color"}).optional()}),Xn=g({logoLight:re,logoDark:re,logoMark:re.optional(),icon:re,splash:re.optional()}),Yn=g({docs:d().url().optional(),support:d().url().optional(),issues:d().url().optional(),website:d().url().optional()}).optional(),Zn=g({copyright:d().optional(),companyName:d().optional()}).optional();g({productName:d().min(1,"productName is required"),shortName:d().optional(),tagline:d().optional(),colors:Jn,assets:Xn,links:Yn,legal:Zn});function Qn(t){const e=t.accent,n=t.accentBright??wn(e,.35),s=t.accentForeground??Re(e),r=t.swatch??e;return{accent:e,accentBright:n,accentForeground:s,swatch:r}}function es(t,e){return{...t,colors:{...t.colors,accent:e.accent,accentBright:e.accentBright,accentForeground:e.accentForeground,primary:e.accent,ring:e.accent},swatch:e.swatch}}const Me="pi-studio-appearance";function ts(t,e){let n=l(t),s=null;function r(h){return h==="system"?typeof window<"u"&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":h}function o(h,f){const p=r(h),x=Hn(p);let y=Fn(x,{...f,themeName:p});if(e!=null&&e.colors){const b=Qn(e.colors);y=es(y,b)}return y}function a(){const h=JSON.stringify({mode:n.mode,settings:n.settings});t.set(Me,h)}function l(h){const f=h.get(Me);let p=Wn,x={};if(f)try{const b=JSON.parse(f);b.mode&&(Qe.includes(b.mode)||b.mode==="system")&&(p=b.mode),b.settings&&typeof b.settings=="object"&&(x=b.settings)}catch{}const y=o(p,x);return{mode:p,settings:x,resolvedTheme:y}}function c(){n={...n,resolvedTheme:o(n.mode,n.settings)},a()}const u={getState(){return n},setMode(h){n={...n,mode:h},c(),u.apply()},updateSettings(h){n={...n,settings:{...n.settings,...h}},c(),u.apply()},apply(){Gn(n.resolvedTheme)},listen(){if(typeof window>"u")return()=>{};const h=window.matchMedia("(prefers-color-scheme: dark)"),f=()=>{n.mode==="system"&&(c(),u.apply())};return h.addEventListener("change",f),s=()=>h.removeEventListener("change",f),s}};return u}function ns({store:t,brandConfig:e,children:n}){const s=v.useRef(null);return s.current||(s.current=ts(t,e),s.current.apply()),v.useEffect(()=>s.current.listen(),[]),i.jsx(i.Fragment,{children:n})}const ss={get(t){var e;try{return((e=globalThis.localStorage)==null?void 0:e.getItem(t))??null}catch{return null}},set(t,e){var n;try{(n=globalThis.localStorage)==null||n.setItem(t,e)}catch{}}};function rs({children:t}){return i.jsx(ns,{store:ss,children:i.jsx(Et,{client:gn,children:t})})}const os="_btn_1chbg_4",as="_secondary_1chbg_44",is="_outline_1chbg_53",cs="_ghost_1chbg_62",ls="_destructive_1chbg_72",ds="_iconOnly_1chbg_82",us="_loadingSpinner_1chbg_89",fs="_piSpin_1chbg_1",pe={btn:os,default:"_default_1chbg_35",secondary:as,outline:is,ghost:cs,destructive:ls,iconOnly:ds,loadingSpinner:us,piSpin:fs},Pe={xs:28,sm:32,md:36,lg:40},ps={xs:12,sm:14,md:16,lg:20},De={xs:8,sm:10,md:12,lg:16},hs={xs:12,sm:13,md:14,lg:15};function ms(t){const{disabled:e,loading:n}=t;return e||n?{opacity:.5,isGhostHover:!1}:{opacity:1,isGhostHover:!1}}function P({variant:t="default",size:e="md",loading:n=!1,disabled:s=!1,leftIcon:r,trailing:o,iconOnly:a=!1,children:l,style:c,className:u,...h}){const{opacity:f}=ms({disabled:s??!1,loading:n}),p=s||n,x=ps[e];return i.jsxs("button",{className:R(pe.btn,pe[t],a&&pe.iconOnly,u),disabled:p,"aria-busy":n||void 0,style:{minHeight:Pe[e],paddingLeft:a?void 0:De[e],paddingRight:a?void 0:De[e],fontSize:hs[e],opacity:f,...a?{width:Pe[e]}:{},...c},...h,children:[n?i.jsx(At,{className:pe.loadingSpinner,size:x,"aria-hidden":!0}):r?i.jsx("span",{"aria-hidden":!0,style:{display:"flex",alignItems:"center",flexShrink:0},children:r}):null,l,o&&!n&&i.jsx("span",{"aria-hidden":!0,style:{display:"flex",alignItems:"center",flexShrink:0},children:o})]})}const gs="_input_a7qyq_3",bs="_textarea_a7qyq_32",ke={input:gs,textarea:bs},Ie=v.forwardRef(function({className:e,...n},s){return i.jsx("input",{ref:s,className:R(ke.input,e),...n})}),ic=v.forwardRef(function({className:e,...n},s){return i.jsx("textarea",{ref:s,className:R(ke.input,ke.textarea,e),...n})}),ot=d().datetime({offset:!0});d().uuid();d().regex(/^[A-Za-z0-9_-]+$/,"expected base64url");const le=Ve([q(),ot]),_s=de(["mobile","browser","cli","mcp"]),ys=g({type:w("hello"),clientId:d(),clientType:_s,protocolVersion:q(),appVersion:d().optional(),capabilities:z(d(),N()).optional()}),ws=g({status:w("server_info"),serverId:d(),hostname:d().optional(),version:d().optional(),capabilities:z(d(),A()),features:z(d(),A())}),Ss=g({type:w("status"),payload:ws}),xs=g({type:w("ping"),requestId:d(),clientSentAt:le.optional()}),vs=g({type:w("pong"),requestId:d(),clientSentAt:le.optional(),serverReceivedAt:le,serverSentAt:le}),at=de(["initializing","idle","running","error","closed"]),it=g({mimeType:d().optional(),data:d().optional()}).passthrough(),ks=g({prs:L(A()).optional(),issues:L(A()).optional()}).passthrough(),Is=g({provider:d(),cwd:d(),modeId:d().optional(),model:d().optional(),thinkingOptionId:d().optional(),featureValues:z(d(),A()).optional(),title:d().nullable().optional(),approvalPolicy:d().optional(),sandboxMode:d().optional(),networkAccess:N().optional(),webSearch:N().optional(),extra:g({pi:A().optional()}).passthrough().optional(),systemPrompt:d().optional(),mcpServers:z(d(),A()).optional()}),Cs=g({type:w("create_agent_request"),requestId:d(),config:Is,env:z(d(),d()).optional(),workspaceId:d().optional(),worktreeName:d().optional(),initialPrompt:d().optional(),clientMessageId:d().optional(),outputSchema:z(d(),A()).optional(),images:L(it).optional(),attachments:ks.optional(),git:A().optional(),worktree:A().optional(),autoArchive:N().optional(),labels:z(d(),d()).default({})}),Ts=g({type:w("create_agent_response"),requestId:d(),payload:g({agentId:d()}).passthrough()}),js=g({type:w("agent_update"),agentId:d(),status:at.optional(),title:d().nullable().optional(),labels:z(d(),d()).optional()}),Ns=g({type:w("agent_status"),agentId:d(),status:at}),Es=g({type:w("agent_list"),agents:L(g({id:d()}).passthrough())}),Rs=g({type:w("agent_deleted"),agentId:d()}),Bs=g({type:w("agent_archived"),agentId:d(),archivedAt:ot.optional()}),ct=ye("kind",[g({kind:w("shell"),command:d().optional(),output:d().optional()}),g({kind:w("read"),path:d().optional(),output:d().optional()}),g({kind:w("edit"),path:d().optional(),diff:d().optional(),output:d().optional()}),g({kind:w("write"),path:d().optional(),output:d().optional()}),g({kind:w("search"),query:d().optional(),output:d().optional()}),g({kind:w("fetch"),url:d().optional(),output:d().optional()}),g({kind:w("task"),description:d().optional(),output:d().optional()})]),As=ye("kind",[g({kind:w("user_message"),messageId:d().optional(),text:d().optional(),images:L(it).optional()}),g({kind:w("assistant_message"),messageId:d().optional(),text:d().optional()}),g({kind:w("reasoning"),text:d().optional()}),g({kind:w("tool_call"),callId:d().optional(),tool:ct,status:d().optional()}),g({kind:w("turn_started"),turnId:d().optional()}),g({kind:w("turn_completed"),turnId:d().optional()}),g({kind:w("turn_failed"),turnId:d().optional(),error:d().optional()}),g({kind:w("turn_canceled"),turnId:d().optional()}),g({kind:w("error"),message:d().optional()})]),$s=g({type:w("agent_stream"),agentId:d(),seq:q().optional(),timestamp:le.optional(),event:As}),Ms=de(["before","after"]),Ps=g({start:q(),end:q()}),Ds=g({type:w("fetch_agent_timeline_request"),requestId:d(),agentId:d(),cursor:d().nullable().optional(),direction:Ms,limit:q().optional()}),qs=g({type:w("fetch_agent_timeline_response"),requestId:d(),agentId:d().optional(),items:L(A()),seqStart:q(),seqEnd:q(),sourceSeqRanges:L(Ps),collapsed:N(),hasNewer:N(),startCursor:d().nullable().optional(),endCursor:d().nullable().optional()}),Os=g({type:w("agent_permission_request"),requestId:d(),agentId:d(),toolName:d().optional(),tool:ct.optional(),action:A().optional(),responses:L(d()).optional()}),Fs=g({type:w("agent_permission_resolved"),requestId:d(),agentId:d(),decision:d().optional()}),Hs=g({type:w("agent.permission.respond.request"),requestId:d(),permissionRequestId:d(),response:A()}),Ws=g({type:w("agent.permission.respond.response"),requestId:d(),payload:g({resolved:N()}).passthrough()}),zs=g({type:w("respond_to_permission"),requestId:d(),permissionRequestId:d(),response:A()}),lt=de(["conversation","files","both"]),Ls=g({type:w("agent.rewind.request"),requestId:d(),agentId:d(),messageId:d(),mode:lt}).passthrough(),Us=g({type:w("agent.rewind.response"),requestId:d(),payload:g({agentId:d(),messageId:d(),mode:lt,truncatedAt:d().optional()}).passthrough()}).passthrough(),Ks=g({type:w("rpc_error"),requestId:d(),code:d().optional(),message:d().optional(),error:d().optional()}),Vs=ye("type",[Cs,Ts,js,Ns,Es,Rs,Bs,$s,Ds,qs,Os,Fs,Hs,Ws,zs,Ls,Us,Ks]),Gs=g({type:d()}).passthrough(),Js=g({type:w("session"),message:Ve([Vs,Gs])});ye("type",[ys,Ss,xs,vs,Js]);const Y={Output:1,Input:2,Resize:3,Snapshot:4,Restore:5},Xs=Object.fromEntries(Object.entries(Y).map(([t,e])=>[e,t])),dt=g({rows:q().int().nonnegative(),cols:q().int().nonnegative()});class ie extends Error{constructor(e){super(e),this.name="TerminalFrameError"}}const Ys=new TextEncoder,Zs=new TextDecoder;function Qs(t){if(!Number.isInteger(t)||t<0||t>255)throw new ie(`slot must be an integer 0–255, got ${t}`)}function oe(t,e,n){const s=new Uint8Array(2+n.length);return s[0]=t,s[1]=e,s.set(n,2),s}function cc(t){switch(Qs(t.slot),t.opcode){case"Output":return oe(Y.Output,t.slot,t.data);case"Input":return oe(Y.Input,t.slot,t.data);case"Snapshot":return oe(Y.Snapshot,t.slot,t.data);case"Restore":return oe(Y.Restore,t.slot,t.data);case"Resize":{const e=JSON.stringify(dt.parse({rows:t.rows,cols:t.cols}));return oe(Y.Resize,t.slot,Ys.encode(e))}}}function er(t){if(t.length<2)throw new ie(`frame too short: ${t.length} bytes (need ≥ 2)`);const e=t[0],n=t[1],s=Xs[e];if(!s)throw new ie(`unknown terminal opcode 0x${e.toString(16)}`);const r=t.subarray(2);if(s==="Resize"){let o;try{o=JSON.parse(Zs.decode(r))}catch{throw new ie("resize payload is not valid JSON")}const a=dt.safeParse(o);if(!a.success)throw new ie("resize payload is not { rows, cols }");return{opcode:"Resize",slot:n,rows:a.data.rows,cols:a.data.cols}}return{opcode:s,slot:n,data:r.slice()}}const ut={Begin:16,Chunk:17,End:18,Error:19},tr=Object.fromEntries(Object.entries(ut).map(([t,e])=>[e,t])),nr=g({transferId:d(),fileName:d().optional(),mimeType:d().optional(),totalBytes:q().int().nonnegative().optional()});class he extends Error{constructor(e){super(e),this.name="FileTransferFrameError"}}new TextEncoder;const qe=new TextDecoder;function sr(t){if(t.length<2)throw new he(`frame too short: ${t.length} bytes (need ≥ 2)`);const e=t[0],n=t[1],s=tr[e];if(!s)throw new he(`unknown file-transfer opcode 0x${e.toString(16)}`);const r=t.subarray(2);switch(s){case"Begin":{let o;try{o=JSON.parse(qe.decode(r))}catch{throw new he("begin payload is not valid JSON")}const a=nr.safeParse(o);if(!a.success)throw new he("begin payload is not a valid transfer header");return{opcode:"Begin",stream:n,meta:a.data}}case"Chunk":return{opcode:"Chunk",stream:n,data:r.slice()};case"End":return{opcode:"End",stream:n,ok:(r[0]??1)!==0};case"Error":return{opcode:"Error",stream:n,message:qe.decode(r)}}}function rr(t){try{return sr(t)}catch{return null}}const or=d().regex(/^[a-z][a-z0-9-]*$/,"invalid provider id"),ar=de(["safe","moderate","dangerous","planning"]),ir=g({supportsStreaming:N(),supportsSessionPersistence:N(),supportsDynamicModes:N(),supportsMcpServers:N(),supportsReasoningStream:N(),supportsToolInvocations:N(),supportsRewindConversation:N().optional(),supportsRewindFiles:N().optional(),supportsRewindBoth:N().optional()}).passthrough(),cr=g({id:d(),label:d().optional(),description:d().optional(),icon:d().optional(),colorTier:ar});g({id:or,label:d(),description:d().optional(),extends:d().optional(),modes:L(cr),capabilities:ir});function Ce(t){return typeof t=="string"?t:t instanceof Uint8Array||Buffer.isBuffer(t)?t.toString("utf8"):String(t??"")}function ft(t){let e=null;const n={onMessage:null,onClose:null,onError:null,get isOpen(){return e!==null&&e.readyState===1},connect(s){return new Promise((r,o)=>{const a=t??(()=>new WebSocket(s));try{e=t?a(s):new WebSocket(s)}catch(l){o(l);return}e.onopen=()=>r(),e.onerror=l=>{var c;(e==null?void 0:e.readyState)!==1&&o(l),(c=n.onError)==null||c.call(n,l)},e.onclose=l=>{var c;(c=n.onClose)==null||c.call(n,l.code,Ce(l.reason))},e.onmessage=l=>{var u,h,f,p;const{data:c}=l;c instanceof ArrayBuffer||c instanceof Uint8Array?(u=n.onMessage)==null||u.call(n,c):typeof c=="string"?(h=n.onMessage)==null||h.call(n,c):typeof Blob<"u"&&c instanceof Blob?(f=n.onMessage)==null||f.call(n,c):Buffer.isBuffer(c)&&((p=n.onMessage)==null||p.call(n,c.buffer.slice(c.byteOffset,c.byteOffset+c.byteLength)))}})},sendText(s){e==null||e.send(s)},sendBinary(s){e==null||e.send(s)},close(s=1e3,r=""){e==null||e.close(s,r),e=null}};return n}const ce="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function pt(t){let e="";for(let n=0;n<t.length;n+=3){const s=t[n],r=n+1<t.length,o=n+2<t.length,a=r?t[n+1]:0,l=o?t[n+2]:0;e+=ce[s>>2],e+=ce[(s&3)<<4|a>>4],e+=r?ce[(a&15)<<2|l>>6]:"=",e+=o?ce[l&63]:"="}return e}function ht(t){const e=t.replace(/=+$/,""),n=[];let s=0,r=0;for(const o of e){const a=ce.indexOf(o);if(a===-1)throw new Error(`invalid base64 character: ${JSON.stringify(o)}`);s=s<<6|a,r+=6,r>=8&&(r-=8,n.push(s>>r&255))}return new Uint8Array(n)}function lr(t){try{const e=JSON.parse(t);return!e||typeof e.type!="string"?null:e}catch{return null}}const be=24;function mt(t,e){const n=te.randomBytes(be),s=te.box.after(t,n,e),r=new Uint8Array(n.length+s.length);return r.set(n,0),r.set(s,n.length),pt(r)}function gt(t,e){let n;try{n=ht(t)}catch{return null}if(n.length<be)return null;const s=n.slice(0,be),r=n.slice(be);return te.box.open.after(r,s,e)}function dr(t,e){return mt(new TextEncoder().encode(t),e)}function ur(t,e){const n=gt(t,e);return n?new TextDecoder().decode(n):null}function fr(t,e,n,s,r,o){let a=!1;return n.onClose(l=>{var c;a=!0,(c=s.onClose)==null||c.call(s,l)}),{handleAppFrame(l){var h,f;if(a)return;const c=r();if(!o()||!c)return;const u=ur(l.frame,c);if(u===null){(h=s.onAuthError)==null||h.call(s,new Error(`relay ${t} channel: message failed authentication`));return}(f=s.onMessage)==null||f.call(s,u)},handleBinaryFrame(l){var h,f;if(a)return;const c=r();if(!o()||!c)return;const u=gt(l.frame,c);if(u===null){(h=s.onAuthError)==null||h.call(s,new Error(`relay ${t} channel: binary message failed authentication`));return}(f=s.onBinaryMessage)==null||f.call(s,u)},send(l){if(a)throw new Error(`relay ${t} channel: cannot send after close()`);const c=r();if(!o()||!c)throw new Error(`relay ${t} channel: cannot send before the E2EE handshake completes`);n.send(JSON.stringify({type:"e2ee_app",frame:dr(l,c)}))},sendBinary(l){if(a)throw new Error(`relay ${t} channel: cannot send after close()`);const c=r();if(!o()||!c)throw new Error(`relay ${t} channel: cannot send before the E2EE handshake completes`);n.send(JSON.stringify({type:"e2ee_bin",frame:mt(l,c)}))},close(){a||(a=!0,n.close())}}}function pr(t){const{transport:e,attachment:n,daemonPublicKey:s}=t,r=t.events??{},o=te.box.keyPair(),a=te.box.before(s,o.secretKey);let l=!1;const c=fr("client",n,e,r,()=>a,()=>l);return e.onMessage(u=>{var f;const h=lr(u);if(h){if(h.type==="e2ee_ready"){if(l)return;l=!0,(f=r.onReady)==null||f.call(r);return}if(h.type==="e2ee_app"){c.handleAppFrame(h);return}h.type==="e2ee_bin"&&c.handleBinaryFrame(h)}}),e.send(JSON.stringify({type:"e2ee_hello",ephemeralPublicKey:pt(o.publicKey)})),{role:"client",attachment:n,get ready(){return l},send:c.send,sendBinary:c.sendBinary,close:c.close}}const hr=16;function mr(t){const e=te.hash(t);let n="";for(let s=0;s<hr;s++)n+=e[s].toString(16).padStart(2,"0");return n}function gr(t){const e=t.useTls?"wss":"ws",n=t.endpoint.replace(/^wss?:\/\//,"").replace(/\/+$/,"");return`${e}://${n}`}function br(t){let e=null,n=null;const s=t.sessionId??mr(t.daemonPublicKey),r={onMessage:null,onClose:null,onError:null,get isOpen(){return e!==null&&e.readyState===1&&n!==null&&n.ready},connect(o){return new Promise((a,l)=>{const c=t.factory??(()=>new WebSocket(o));try{e=t.factory?c(o):new WebSocket(o)}catch(p){l(p);return}const u=e,h=[],f=[];u.onopen=()=>{u.send(JSON.stringify({type:"relay_register",sessionId:s})),n=pr({transport:{send:p=>u.send(p),onMessage:p=>h.push(p),onClose:p=>f.push(p),close:()=>u.close()},attachment:{sessionId:s},daemonPublicKey:t.daemonPublicKey,events:{onReady:()=>a(),onMessage:p=>{var x;return(x=r.onMessage)==null?void 0:x.call(r,p)},onBinaryMessage:p=>{var x;return(x=r.onMessage)==null?void 0:x.call(r,p.slice().buffer)},onAuthError:p=>{var x;return(x=r.onError)==null?void 0:x.call(r,p)}}})},u.onerror=p=>{var x;u.readyState!==1&&l(p),(x=r.onError)==null||x.call(r,p)},u.onclose=p=>{var x;for(const y of f)y(Ce(p.reason));(x=r.onClose)==null||x.call(r,p.code,Ce(p.reason))},u.onmessage=p=>{const{data:x}=p;if(typeof x=="string")for(const y of h)y(x)}})},sendText(o){if(!n||!n.ready)throw new Error("relay transport: cannot send before the E2EE handshake completes");n.send(o)},sendBinary(o){if(!n||!n.ready)throw new Error("relay transport: cannot send before the E2EE handshake completes");n.sendBinary(o)},close(o=1e3,a=""){n==null||n.close(),n=null,e==null||e.close(o,a),e=null}};return r}function _r(t){const e=t.indexOf("#"),n=e===-1?t:t.slice(e+1),s=new URLSearchParams(n),r=s.get("offer");if(!r)return null;let o;try{o=ht(r)}catch{return null}const a=s.get("relay");if(a){const c={endpoint:a,useTls:s.get("relayTls")==="1"};return{publicKeyB64:r,publicKey:o,relay:c}}const l=s.get("host")??void 0;return{publicKeyB64:r,publicKey:o,...l?{host:l}:{}}}const yr=1;function Oe(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`req-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}class wr extends Error{constructor(e,n,s){super(e),this.requestId=n,this.code=s,this.name="RpcError"}}class Fe extends Error{constructor(e){super(`RPC ${e} timed out`),this.requestId=e,this.name="RpcTimeoutError"}}class Sr{constructor(e){I(this,"transport");I(this,"rpcTimeoutMs");I(this,"now");I(this,"_state","idle");I(this,"_serverId",null);I(this,"_features",{});I(this,"_serverCapabilities",{});I(this,"pending",new Map);I(this,"sessionHandlers",new Set);I(this,"terminalHandlers",new Set);I(this,"fileTransferHandlers",new Set);I(this,"stateHandlers",new Set);I(this,"helloResolve",null);I(this,"helloReject",null);this.options=e,this.transport=e.transport??ft(),this.rpcTimeoutMs=e.rpcTimeoutMs??3e4,this.now=e.now??(()=>Date.now()),this.transport.onMessage=n=>this.handleIncoming(n),this.transport.onClose=(n,s)=>this.handleClose(n,s),this.transport.onError=()=>{}}get state(){return this._state}get serverId(){return this._serverId}get features(){return this._features}get serverCapabilities(){return this._serverCapabilities}hasFeature(e){return!!this._features[e]}async connect(){this.setState("connecting"),await this.transport.connect(this.options.url);const e=new Promise((s,r)=>{this.helloResolve=s,this.helloReject=r});this.transport.sendText(JSON.stringify({type:"hello",clientId:this.options.clientId,clientType:this.options.clientType,protocolVersion:this.options.protocolVersion??yr,appVersion:this.options.appVersion,capabilities:this.options.capabilities}));const n=await e;return this._serverId=n.serverId,this._features=n.features,this._serverCapabilities=n.capabilities,this.setState("open"),n}close(e=1e3,n=""){this.setState("closing"),this.transport.close(e,n)}request(e,n={},s){const r=n.requestId??Oe();return new Promise((o,a)=>{const l=s??this.rpcTimeoutMs,c=l>0?setTimeout(()=>{this.pending.delete(r),a(new Fe(r))},l):null;this.pending.set(r,{resolve:u=>o(u),reject:a,timer:c}),this.sendSession({type:e,...n,requestId:r})})}sendSession(e){this.transport.sendText(JSON.stringify({type:"session",message:e}))}sendBinary(e){this.transport.sendBinary(e)}ping(e=1e4){const n=Oe();return new Promise((s,r)=>{const o=e>0?setTimeout(()=>{this.pending.delete(n),r(new Fe(n))},e):null;this.pending.set(n,{resolve:()=>s(),reject:r,timer:o}),this.transport.sendText(JSON.stringify({type:"ping",requestId:n,clientSentAt:this.now()}))})}onSessionMessage(e){return this.sessionHandlers.add(e),()=>this.sessionHandlers.delete(e)}onTerminalFrame(e){return this.terminalHandlers.add(e),()=>this.terminalHandlers.delete(e)}onFileTransferFrame(e){return this.fileTransferHandlers.add(e),()=>this.fileTransferHandlers.delete(e)}onStateChange(e){return this.stateHandlers.add(e),()=>this.stateHandlers.delete(e)}setState(e){if(this._state!==e){this._state=e;for(const n of this.stateHandlers)n(e)}}handleClose(e,n){this.helloReject&&(this.helloReject(new Error(`socket closed during handshake: ${n}`)),this.helloResolve=null,this.helloReject=null);for(const[,s]of this.pending)s.timer&&clearTimeout(s.timer),s.reject(new Error(`socket closed: ${n}`));this.pending.clear(),this.setState("closed")}handleIncoming(e){if(typeof e=="string"){this.handleTextFrame(e);return}if(e instanceof ArrayBuffer){this.handleBinaryFrame(new Uint8Array(e));return}typeof e.arrayBuffer=="function"&&e.arrayBuffer().then(n=>this.handleBinaryFrame(new Uint8Array(n)))}handleBinaryFrame(e){const n=e[0];if(n!==void 0&&Object.values(ut).includes(n)){const o=rr(e);if(!o)return;for(const a of this.fileTransferHandlers)a(o);return}const r=er(e);for(const o of this.terminalHandlers)o(r)}handleTextFrame(e){let n;try{n=JSON.parse(e)}catch{return}const s=n;switch(s.type){case"status":this.handleStatus(s);return;case"pong":this.resolvePending(s.requestId,void 0);return;case"ping":this.transport.sendText(JSON.stringify({type:"pong",requestId:s.requestId,serverReceivedAt:this.now(),serverSentAt:this.now()}));return;case"session":this.handleSession(s.message);return;default:return}}handleStatus(e){const n=e.payload;(n==null?void 0:n.status)==="server_info"&&this.helloResolve&&(this.helloResolve(n),this.helloResolve=null,this.helloReject=null)}handleSession(e){if(!e||typeof e!="object")return;const n=e;if(n.type==="rpc_error"&&typeof n.requestId=="string"){const s=this.pending.get(n.requestId);s&&(s.timer&&clearTimeout(s.timer),this.pending.delete(n.requestId),s.reject(new wr(n.message??n.error??"RPC failed",n.requestId,n.code)));return}if(typeof n.requestId=="string"&&this.pending.has(n.requestId)){const s="payload"in n?n.payload:n;this.resolvePending(n.requestId,s)}for(const s of this.sessionHandlers)s(e)}resolvePending(e,n){const s=this.pending.get(e);s&&(s.timer&&clearTimeout(s.timer),this.pending.delete(e),s.resolve(n))}}class xr{constructor(e){this.daemon=e}get connection(){return this.daemon}async createAgent(e){return await this.daemon.request("create_agent_request",{...e})}agent(e){return new kr(this.daemon,e)}workspace(e){return new Ir(this.daemon,e)}get providers(){return new Cr(this.daemon)}onAgentUpdate(e){return this.daemon.onSessionMessage(n=>{n.type==="agent_update"&&e(n)})}onWorkspaceUpdate(e){return this.daemon.onSessionMessage(n=>{n.type==="workspace_update"&&e(n)})}}class vr{constructor(e,n){this.daemon=e,this.agentId=n}fetch(e={}){return this.daemon.request("fetch_agent_timeline_request",{agentId:this.agentId,cursor:e.cursor,direction:e.direction,limit:e.limit})}subscribe(e){return this.daemon.onSessionMessage(n=>{const s=n;s.type==="agent_stream"&&s.agentId===this.agentId&&s.event&&e(s.event)})}}class kr{constructor(e,n){I(this,"timeline");this.daemon=e,this.agentId=n,this.timeline=new vr(e,n)}send(e,n={}){return this.daemon.request("send_agent_prompt",{agentId:this.agentId,prompt:e,clientMessageId:n.clientMessageId,images:n.images})}run(e,n){return this.send(e,n)}interrupt(){return this.daemon.request("interrupt_agent",{agentId:this.agentId})}update(e){return this.daemon.request("update_agent",{agentId:this.agentId,...e})}resume(){return this.daemon.request("resume_agent",{agentId:this.agentId})}archive(){return this.daemon.request("archive_agent",{agentId:this.agentId})}delete(){return this.daemon.request("delete_agent",{agentId:this.agentId})}onUpdate(e){return this.daemon.onSessionMessage(n=>{const s=n;s.type==="agent_update"&&s.agentId===this.agentId&&e(s)})}}class Ir{constructor(e,n){this.daemon=e,this.workspaceId=n}onUpdate(e){return this.daemon.onSessionMessage(n=>{const s=n;s.type==="workspace_update"&&s.workspaceId===this.workspaceId&&e(s)})}}class Cr{constructor(e){this.daemon=e}listProviders(){return this.daemon.request("list_providers",{})}listModels(e){return this.daemon.request("list_provider_models",{provider:e})}listModes(e){return this.daemon.request("list_provider_modes",{provider:e})}refreshSnapshot(){return this.daemon.request("providers.snapshot.refresh.request",{})}}class Tr{constructor(e,n={}){I(this,"initialDelayMs");I(this,"maxDelayMs");I(this,"factor");I(this,"jitter");I(this,"maxAttempts");I(this,"setTimer");I(this,"clearTimer");I(this,"random");I(this,"attempt",0);I(this,"timer",null);I(this,"active",!1);I(this,"detachState",null);I(this,"reconnectedHandlers",new Set);I(this,"failedHandlers",new Set);this.daemon=e,this.initialDelayMs=n.initialDelayMs??500,this.maxDelayMs=n.maxDelayMs??3e4,this.factor=n.factor??2,this.jitter=n.jitter??.2,this.maxAttempts=n.maxAttempts??Number.POSITIVE_INFINITY,this.setTimer=n.setTimer??((s,r)=>setTimeout(s,r)),this.clearTimer=n.clearTimer??(s=>clearTimeout(s)),this.random=n.random??Math.random}delayForAttempt(e){const n=Math.min(this.maxDelayMs,this.initialDelayMs*this.factor**(e-1)),s=n*this.jitter*(this.random()*2-1);return Math.max(0,Math.round(n+s))}onReconnected(e){return this.reconnectedHandlers.add(e),()=>this.reconnectedHandlers.delete(e)}onReconnectFailed(e){return this.failedHandlers.add(e),()=>this.failedHandlers.delete(e)}start(){this.active||(this.active=!0,this.detachState=this.daemon.onStateChange(e=>{e==="closed"&&this.active&&this.scheduleReconnect(),e==="open"&&(this.attempt=0)}))}stop(){var e;this.active=!1,this.timer&&this.clearTimer(this.timer),this.timer=null,(e=this.detachState)==null||e.call(this),this.detachState=null}get attemptCount(){return this.attempt}scheduleReconnect(){if(!this.active||this.attempt>=this.maxAttempts)return;this.attempt+=1;const e=this.delayForAttempt(this.attempt);this.timer=this.setTimer(()=>{this.timer=null,this.tryReconnect()},e)}async tryReconnect(){if(!this.active)return;const e=this.attempt;try{await this.daemon.connect();for(const n of this.reconnectedHandlers)n({attempt:e,serverId:this.daemon.serverId})}catch(n){for(const s of this.failedHandlers)s(n,e);this.scheduleReconnect()}}}function He(t){const e=t.trim();if(e==="")return e;const n=e.match(/^([a-z][a-z0-9+.-]*):\/\//i);if(!n)return`ws://${e.replace(/\/+$/,"")}`;const s=n[1].toLowerCase(),r=e.slice(n[0].length).replace(/\/+$/,"");switch(s){case"http":return`ws://${r}`;case"https":return`wss://${r}`;case"ws":case"wss":return`${s}://${r}`;default:return e}}function jr(t){const e=_r(t);return e!=null&&e.relay?{mode:"relay",url:gr(e.relay),daemonPublicKey:e.publicKey}:e!=null&&e.host?{mode:"direct",url:He(e.host)}:{mode:"direct",url:He(t)}}function Nr(){return"web-"+Math.random().toString(36).slice(2,10)}const T=X()((t,e)=>({status:"idle",serverInfo:null,error:null,daemon:null,client:null,reconnection:null,async connect(n){e().disconnect();const s=jr(n.url);let r;s.mode==="relay"?r=br({daemonPublicKey:s.daemonPublicKey}):n.password&&(r=ft(c=>new WebSocket(c,[`pi-studio.bearer.${n.password}`])));const o=new Sr({url:s.url,clientId:n.clientId??Nr(),clientType:"browser",capabilities:{},transport:r,rpcTimeoutMs:1800*1e3}),a=new xr(o),l=new Tr(o);o.onStateChange(c=>t({status:c})),l.onReconnected(()=>t({error:null})),l.onReconnectFailed(c=>{t({error:c instanceof Error?c.message:String(c)})}),t({daemon:o,client:a,reconnection:l,error:null,status:"connecting"});try{const c=await o.connect();t({serverInfo:c}),l.start()}catch(c){throw t({error:c instanceof Error?c.message:String(c)}),c}},disconnect(){const{daemon:n,reconnection:s}=e();s==null||s.stop(),n==null||n.close(),t({status:"idle",serverInfo:null,daemon:null,client:null,reconnection:null})}})),Er=100,Rr=480,Br=220,Ar=280;function me(t){return Math.min(Rr,Math.max(Er,t))}const k=X()(t=>({host:"ws://127.0.0.1:6767",password:"",cwd:"~",cwdPickerOpen:!1,sessionMenu:null,rightSidebarTab:"files",collapsedWorkspaces:new Set,leftSidebarCollapsed:!1,rightSidebarCollapsed:!1,leftSidebarWidth:Br,rightSidebarWidth:Ar,setHost:e=>t({host:e}),setPassword:e=>t({password:e}),setCwd:e=>t({cwd:e}),openCwdPicker:()=>t({cwdPickerOpen:!0}),closeCwdPicker:()=>t({cwdPickerOpen:!1}),openSessionMenu:(e,n,s)=>t({sessionMenu:{sessionId:e,x:n,y:s}}),closeSessionMenu:()=>t({sessionMenu:null}),setRightSidebarTab:e=>t({rightSidebarTab:e}),toggleWorkspaceCollapsed:e=>t(n=>{const s=new Set(n.collapsedWorkspaces);return s.has(e)?s.delete(e):s.add(e),{collapsedWorkspaces:s}}),toggleLeftSidebar:()=>t(e=>({leftSidebarCollapsed:!e.leftSidebarCollapsed})),toggleRightSidebar:()=>t(e=>({rightSidebarCollapsed:!e.rightSidebarCollapsed})),setLeftSidebarWidth:e=>t({leftSidebarWidth:me(e)}),setRightSidebarWidth:e=>t({rightSidebarWidth:me(e)}),resizeLeftSidebar:e=>t(n=>({leftSidebarWidth:me(n.leftSidebarWidth+e)})),resizeRightSidebar:e=>t(n=>({rightSidebarWidth:me(n.rightSidebarWidth+e)}))})),$r="_wrap_emmus_1",Mr="_dot_emmus_8",Pr="_open_emmus_15",Dr="_connecting_emmus_18",qr="_closed_emmus_21",Or="_idle_emmus_22",Fr="_closing_emmus_23",we={wrap:$r,dot:Mr,open:Pr,connecting:Dr,closed:qr,idle:Or,closing:Fr},Hr={idle:"disconnected",connecting:"connecting…",open:"connected",closing:"disconnecting…",closed:"disconnected"};function Wr(){const t=T(n=>n.status),e=T(n=>n.error);return i.jsxs("span",{className:we.wrap,title:e??void 0,children:[i.jsx("span",{className:R(we.dot,we[t])}),Hr[t]??t]})}const zr="_toolbar_i9hmh_1",Lr="_brand_i9hmh_10",Ur="_version_i9hmh_16",Kr="_sep_i9hmh_22",Vr="_host_i9hmh_28",Gr="_password_i9hmh_31",Jr="_sidebarToggles_i9hmh_34",V={toolbar:zr,brand:Lr,version:Ur,sep:Kr,host:Vr,password:Gr,sidebarToggles:Jr};function Xr(){const t=T(p=>p.status),e=T(p=>p.connect),n=T(p=>p.disconnect),s=k(p=>p.host),r=k(p=>p.setHost),o=k(p=>p.password),a=k(p=>p.setPassword),l=k(p=>p.leftSidebarCollapsed),c=k(p=>p.toggleLeftSidebar),u=k(p=>p.rightSidebarCollapsed),h=k(p=>p.toggleRightSidebar),f=t==="open"||t==="connecting";return i.jsxs("div",{className:V.toolbar,children:[i.jsx("span",{className:V.brand,children:"Pi-Studio"}),i.jsxs("span",{className:V.version,children:["v","0.0.13"]}),i.jsx(Wr,{}),i.jsx("div",{className:V.sep}),i.jsx(Ie,{className:V.host,value:s,onChange:p=>r(p.target.value),placeholder:"host:port, ws://…/http://…, or a pasted pairing link",disabled:f}),i.jsx(Ie,{className:V.password,type:"password",value:o,onChange:p=>a(p.target.value),placeholder:"password",disabled:f}),t==="open"||t==="connecting"||t==="closing"?i.jsx(P,{size:"sm",onClick:()=>n(),children:"Disconnect"}):i.jsx(P,{size:"sm",variant:"default",onClick:()=>void e({url:s,password:o||void 0}),children:"Connect"}),i.jsxs("div",{className:V.sidebarToggles,children:[i.jsx(P,{size:"sm",variant:"ghost",iconOnly:!0,title:l?"Show sessions sidebar":"Hide sessions sidebar",onClick:()=>c(),children:l?i.jsx($t,{size:16}):i.jsx(Mt,{size:16})}),i.jsx(P,{size:"sm",variant:"ghost",iconOnly:!0,title:u?"Show files/changes sidebar":"Hide files/changes sidebar",onClick:()=>h(),children:u?i.jsx(Pt,{size:16}):i.jsx(Dt,{size:16})})]})]})}const Te={rows:[],streamingAssistantIndex:null,streamingReasoningIndex:null,toolIndexByCallId:{}};let We=0;function K(){return We+=1,`row-${We}`}function Yr(t){switch(t.kind){case"shell":return t.command??"";case"read":case"write":return t.path??"";case"edit":return t.path??"";case"search":return t.query??"";case"fetch":return t.url??"";case"task":return t.description??"";default:return""}}function Zr(t,e){return t??`${e.kind}:${Yr(e)}`}function Qr(t){return{...t,streamingAssistantIndex:null,streamingReasoningIndex:null}}function eo(t,e){var o;const n=t.rows.slice();let s=t.streamingAssistantIndex;if(s===null||((o=n[s])==null?void 0:o.kind)!=="assistant"){const a={kind:"assistant",id:K(),text:"",streaming:!0};n.push(a),s=n.length-1}const r=n[s];return!r||r.kind!=="assistant"?t:(n[s]={...r,text:r.text+e},{...t,rows:n,streamingAssistantIndex:s,streamingReasoningIndex:null})}function to(t,e){var o;const n=t.rows.slice();let s=t.streamingReasoningIndex;if(s===null||((o=n[s])==null?void 0:o.kind)!=="reasoning"){const a={kind:"reasoning",id:K(),text:"",streaming:!0};n.push(a),s=n.length-1}const r=n[s];return!r||r.kind!=="reasoning"?t:(n[s]={...r,text:r.text+e},{...t,rows:n,streamingReasoningIndex:s,streamingAssistantIndex:null})}function no(t,e){if(t.kind!==e.kind)return e;const n={...t};for(const[s,r]of Object.entries(e))r!==void 0&&r!==""&&(n[s]=r);return n}function so(t,e){var l;const n=Zr(e.callId,e.tool),s=e.status==="completed"||e.status==="error"?e.status:"running",r=t.toolIndexByCallId[n],o=t.rows.slice();if(r!==void 0&&((l=o[r])==null?void 0:l.kind)==="tool"){const c=o[r];return c.kind!=="tool"?t:(o[r]={...c,tool:no(c.tool,e.tool),status:s},{...t,rows:o,streamingAssistantIndex:null,streamingReasoningIndex:null})}const a={kind:"tool",id:K(),callId:n,tool:e.tool,status:s};return o.push(a),{...t,rows:o,toolIndexByCallId:{...t.toolIndexByCallId,[n]:o.length-1},streamingAssistantIndex:null,streamingReasoningIndex:null}}function Be(t){const e=t.rows.slice();if(t.streamingAssistantIndex!==null){const n=e[t.streamingAssistantIndex];(n==null?void 0:n.kind)==="assistant"&&(e[t.streamingAssistantIndex]={...n,streaming:!1})}if(t.streamingReasoningIndex!==null){const n=e[t.streamingReasoningIndex];(n==null?void 0:n.kind)==="reasoning"&&(e[t.streamingReasoningIndex]={...n,streaming:!1})}return{...t,rows:e,streamingAssistantIndex:null,streamingReasoningIndex:null}}function ro(t,e){const n=Be(t),s={kind:"error",id:K(),text:e||"turn failed"};return{...n,rows:[...n.rows,s]}}function oo(t){const e=Be(t),n={kind:"system",id:K(),text:"(canceled)"};return{...e,rows:[...e.rows,n]}}function ao(t,e){const n={kind:"error",id:K(),text:e||"error"};return{...t,rows:[...t.rows,n]}}function io(t,e,n,s){if(s!==void 0){const o=t.rows.findIndex(a=>a.kind==="user"&&a.pending&&a.clientMessageId===s);if(o!==-1){const a=t.rows.slice(),l=a[o];if((l==null?void 0:l.kind)==="user")return a[o]={...l,text:e,images:n,pending:!1},{...t,rows:a}}}const r={kind:"user",id:K(),text:e,images:n,clientMessageId:s};return{...t,rows:[...t.rows,r]}}function bt(t,e){switch(e.kind){case"turn_started":return Qr(t);case"user_message":return io(t,e.text??"",e.images,e.messageId);case"assistant_message":return eo(t,e.text??"");case"reasoning":return to(t,e.text??"");case"tool_call":return so(t,e);case"turn_completed":return Be(t);case"turn_failed":return ro(t,e.error);case"turn_canceled":return oo(t);case"error":return ao(t,e.message);default:return t}}function co(t,e,n,s){const r={kind:"user",id:K(),text:n,images:s,clientMessageId:e,pending:!0};return{...t,rows:[...t.rows,r]}}function lo(t,e){const n=t.rows.findIndex(o=>o.kind==="user"&&o.pending&&o.clientMessageId===e);if(n===-1)return t;const s=t.rows.slice(),r=s[n];return(r==null?void 0:r.kind)!=="user"?t:(s[n]={...r,pending:!1,failed:!0},{...t,rows:s})}let ze=0;function uo(){return ze+=1,`s-${Date.now().toString(36)}-${ze}`}const B=X()((t,e)=>({sessions:{},order:[],activeSessionId:null,createSession(n){const s=uo(),r={id:s,agentId:null,title:"New chat",status:"idle",cwd:n,timeline:Te,userMessageCount:0};return t(o=>({sessions:{...o.sessions,[s]:r},order:[s,...o.order],activeSessionId:s})),s},hydrate(n){t(s=>s.sessions[n.id]?s:{sessions:{...s.sessions,[n.id]:n},order:[...s.order,n.id]})},bindAgent(n,s){t(r=>{const o=r.sessions[n];return o?{sessions:{...r.sessions,[n]:{...o,agentId:s}}}:r})},setStatus(n,s){t(r=>{const o=r.sessions[n];return o?{sessions:{...r.sessions,[n]:{...o,status:s}}}:r})},setStatusByAgentId(n,s){const r=e().findByAgentId(n);r&&e().setStatus(r.id,s)},setTitle(n,s){t(r=>{const o=r.sessions[n];return o?{sessions:{...r.sessions,[n]:{...o,title:s}}}:r})},setCwd(n,s){t(r=>{const o=r.sessions[n];return o?{sessions:{...r.sessions,[n]:{...o,cwd:s}}}:r})},applyStreamEvent(n,s){t(r=>{const o=r.sessions[n];if(!o)return r;const a=bt(o.timeline,s);let l=o.title;if(s.kind==="turn_completed"&&l==="New chat"){const c=a.rows.slice().reverse().find(u=>u.kind==="assistant");c&&c.kind==="assistant"&&c.text&&(l=c.text.slice(0,40)+(c.text.length>40?"…":""))}return{sessions:{...r.sessions,[n]:{...o,timeline:a,title:l}}}})},addOptimisticUserMessage(n,s,r,o){t(a=>{const l=a.sessions[n];if(!l)return a;const c=co(l.timeline,s,r,o);return{sessions:{...a.sessions,[n]:{...l,timeline:c,userMessageCount:l.userMessageCount+1}}}})},markUserMessageFailed(n,s){t(r=>{const o=r.sessions[n];if(!o)return r;const a=lo(o.timeline,s);return{sessions:{...r.sessions,[n]:{...o,timeline:a}}}})},activate(n){t({activeSessionId:n})},remove(n){t(s=>{const{[n]:r,...o}=s.sessions,a=s.order.filter(c=>c!==n),l=s.activeSessionId===n?a[0]??null:s.activeSessionId;return{sessions:o,order:a,activeSessionId:l}})},findByAgentId(n){return Object.values(e().sessions).find(s=>s.agentId===n)}}));function Se(t,e){return t.filter(n=>n.workspaceCwd===e)}const C=X()((t,e)=>({tabs:[],activeTabId:null,activeWorkspaceCwd:null,lastActiveTabByWorkspace:{},open(n){const s=e().tabs.find(r=>r.id===n.id);if(s){e().activate(s.id);return}t(r=>({tabs:[...r.tabs,n],activeTabId:n.id,activeWorkspaceCwd:n.workspaceCwd,lastActiveTabByWorkspace:{...r.lastActiveTabByWorkspace,[n.workspaceCwd]:n.id}}))},close(n){t(s=>{const r=s.tabs.find(u=>u.id===n);if(!r)return s;const o=s.tabs.findIndex(u=>u.id===n),a=s.tabs.filter(u=>u.id!==n);let l=s.activeTabId;const c={...s.lastActiveTabByWorkspace};if(l===n){const u=Se(a,r.workspaceCwd),h=Math.min(o,u.length-1),f=u[h];l=(f==null?void 0:f.id)??null}if(c[r.workspaceCwd]===n){const u=Se(a,r.workspaceCwd)[0];u?c[r.workspaceCwd]=u.id:delete c[r.workspaceCwd]}return{tabs:a,activeTabId:l,lastActiveTabByWorkspace:c}})},activate(n){t(s=>{const r=s.tabs.find(o=>o.id===n);return r?{activeTabId:n,activeWorkspaceCwd:r.workspaceCwd,lastActiveTabByWorkspace:{...s.lastActiveTabByWorkspace,[r.workspaceCwd]:n}}:s})},switchWorkspace(n){t(s=>{var c;const r=Se(s.tabs,n),o=s.lastActiveTabByWorkspace[n],l=o&&r.some(u=>u.id===o)?o:((c=r[0])==null?void 0:c.id)??null;return{activeWorkspaceCwd:n,activeTabId:l,lastActiveTabByWorkspace:l?{...s.lastActiveTabByWorkspace,[n]:l}:s.lastActiveTabByWorkspace}})},reorder(n,s){t(r=>{const o=r.tabs.findIndex(u=>u.id===n),a=r.tabs.findIndex(u=>u.id===s);if(o===-1||a===-1||o===a)return r;const l=r.tabs.slice(),[c]=l.splice(o,1);return c?(l.splice(a,0,c),{tabs:l}):r})},updateLabel(n,s){t(r=>({tabs:r.tabs.map(o=>o.id===n?{...o,label:s}:o)}))},updateData(n,s){t(r=>({tabs:r.tabs.map(o=>o.id===n?{...o,data:{...o.data,...s}}:o)}))}})),O={chat:t=>`chat-${t}`,file:t=>`file-${t}`,diff:(t,e)=>`diff-${t}${e?"-staged":""}`,terminal:t=>`term-${t}`};let xe=0;function _t(t){xe+=1,C.getState().open({id:O.terminal(`new-${xe}`),kind:"terminal",label:`Terminal ${xe}`,closable:!0,data:{slot:null,cwd:t},workspaceCwd:t})}const Z=X()((t,e)=>({currentPath:"",rootPath:"",setRoot:n=>t({rootPath:n,currentPath:n}),setPath:n=>t({currentPath:n}),goUp:()=>{const{currentPath:n,rootPath:s}=e();if(!s||n===s)return;const r=n.split("/").slice(0,-1).join("/")||"/",o=r.length<s.length||!r.startsWith(s)?s:r;t({currentPath:o})}}));let Q=null;const je=new Set;function fo(t){return je.add(t),()=>je.delete(t)}async function Ae(t){var e;if(Q)return Q;try{const n=await t.connection.request("file_explorer_request",{path:"/home"}),r=(((e=n.result)==null?void 0:e.entries)??n.entries??[]).find(o=>o.kind==="directory"||o.type==="directory");Q="/home/"+((r==null?void 0:r.name)||"user")}catch{return"/tmp"}for(const n of je)n(Q);return Q}function po(){return Q}async function ho(t,e){return e==="~"||e.startsWith("~/")?await Ae(t)+e.slice(1):e}function yt(){const t=T(r=>r.client),e=T(r=>r.status),[n,s]=v.useState(po());return v.useEffect(()=>fo(s),[]),v.useEffect(()=>{!t||e!=="open"||n||Ae(t)},[t,e,n]),n}const mo="_dot_202py_3",go={dot:mo};function bo(t){const{status:e,requiresAttention:n,attentionReason:s,showInactive:r}=t;if(!e)return null;if(n)switch(s){case"permission":return"statusWarning";case"error":return"statusDanger";case"finished":default:return"statusSuccess"}switch(e){case"running":case"queued":return"accent";case"waiting":return"statusWarning";case"finished":return"statusSuccess";case"error":return"statusDanger";case"idle":case"archived":return r?"foregroundMuted":null}}const Le=8,_o={accent:"var(--pi-color-accent)",statusSuccess:"var(--pi-color-statusSuccess)",statusDanger:"var(--pi-color-statusDanger)",statusWarning:"var(--pi-color-statusWarning)",foregroundMuted:"var(--pi-color-foregroundMuted)"};function yo({className:t,...e}){const n=bo(e);return n?i.jsx("span",{className:`${go.dot}${t?` ${t}`:""}`,style:{width:Le,height:Le,backgroundColor:_o[n]??"currentColor"},role:"presentation"}):null}const wo={initializing:"queued",idle:"idle",running:"running",error:"error",closed:"finished"};function So(t){return wo[t]??"idle"}const xo="_wrap_sqws5_1",vo="_header_sqws5_7",ko="_list_sqws5_23",Io="_item_sqws5_28",Co="_active_sqws5_37",To="_title_sqws5_40",jo="_meta_sqws5_49",No="_menuBtn_sqws5_57",Eo="_workspaceGroup_sqws5_75",Ro="_workspaceHeader_sqws5_78",Bo="_workspaceChevron_sqws5_91",Ao="_workspaceIcon_sqws5_102",$o="_workspaceLabel_sqws5_106",Mo="_workspaceCount_sqws5_112",Po="_newSessionBtn_sqws5_117",Do="_workspaceSessions_sqws5_129",E={wrap:xo,header:vo,list:ko,item:Io,active:Co,title:To,meta:jo,menuBtn:No,workspaceGroup:Eo,workspaceHeader:Ro,workspaceChevron:Bo,workspaceIcon:Ao,workspaceLabel:$o,workspaceCount:Mo,newSessionBtn:Po,workspaceSessions:Do};function qo({session:t,active:e,onSelect:n,onOpenMenu:s}){return i.jsxs("div",{className:R(E.item,e&&E.active),onClick:n,onContextMenu:r=>{r.preventDefault(),s(r.clientX,r.clientY)},children:[i.jsxs("div",{className:E.title,children:[i.jsx(yo,{status:So(t.status),showInactive:!0}),i.jsx("span",{children:t.title})]}),i.jsxs("div",{className:E.meta,children:[t.cwd||"~"," · ",t.agentId?t.agentId.slice(0,8):"new"," ·"," ",t.userMessageCount," msgs"]}),i.jsx("button",{type:"button",className:E.menuBtn,title:"Actions",onClick:r=>{r.stopPropagation();const o=r.currentTarget.getBoundingClientRect();s(o.left,o.bottom)},children:i.jsx(qt,{size:14})})]})}const Oo="_trigger_16o4s_1",Fo="_content_16o4s_7",Ho="_item_16o4s_16",Wo="_danger_16o4s_33",zo="_sep_16o4s_36",W={trigger:Oo,content:Fo,item:Ho,danger:Wo,sep:zo};function Lo(){const t=k(y=>y.sessionMenu),e=k(y=>y.closeSessionMenu),n=T(y=>y.client),s=v.useRef(null),[r,o]=v.useState(!1);v.useEffect(()=>{o(t!==null)},[t]);const a=B(y=>t?y.sessions[t.sessionId]:void 0);if(!t)return null;const l=!!(a!=null&&a.agentId)&&(a==null?void 0:a.status)==="running";function c(y){o(y),y||e()}function u(){if(!a)return;const y=window.prompt("Rename:",a.title);if(y!=null&&y.trim()){const b=y.trim();B.getState().setTitle(a.id,b),C.getState().updateLabel(O.chat(a.id),b),a.agentId&&(n==null||n.agent(a.agentId).update({title:b}).catch(()=>{}))}e()}function h(){a!=null&&a.agentId&&(n==null||n.agent(a.agentId).interrupt().catch(()=>{})),e()}function f(y){B.getState().remove(y),C.getState().close(O.chat(y))}async function p(){if(a){if(!window.confirm("Archive this agent? It can be resumed later."))return e();if(e(),!a.agentId){f(a.id);return}if(!n){window.alert("Not connected — cannot archive remotely.");return}try{await n.agent(a.agentId).archive(),f(a.id)}catch(y){window.alert(`Failed to archive: ${y instanceof Error?y.message:String(y)}`)}}}async function x(){if(a){if(!window.confirm("Permanently delete this agent? This cannot be undone."))return e();if(e(),!a.agentId){f(a.id);return}if(!n){window.alert("Not connected — cannot delete remotely.");return}try{await n.agent(a.agentId).delete(),f(a.id)}catch(y){window.alert(`Failed to delete: ${y instanceof Error?y.message:String(y)}`)}}}return i.jsxs(Yt,{open:r,onOpenChange:c,modal:!1,children:[i.jsx(Zt,{asChild:!0,children:i.jsx("button",{ref:s,type:"button",className:W.trigger,style:{left:t.x,top:t.y},"aria-hidden":!0,tabIndex:-1})}),i.jsx(Qt,{children:i.jsxs(en,{className:W.content,align:"start",sideOffset:2,children:[i.jsx(ue,{className:W.item,onSelect:u,children:"Rename"}),i.jsx(ue,{className:W.item,disabled:!l,onSelect:h,children:"Stop agent"}),i.jsx(tn,{className:W.sep}),i.jsx(ue,{className:`${W.item} ${W.danger}`,onSelect:p,children:"Archive"}),i.jsx(ue,{className:`${W.item} ${W.danger}`,onSelect:x,children:"Delete permanently"})]})})]})}function Uo({label:t,cwd:e,sessionCount:n,collapsed:s,onToggleCollapsed:r,onNewSession:o}){return i.jsxs("div",{className:E.workspaceHeader,onClick:r,title:e,children:[i.jsx("button",{type:"button",className:E.workspaceChevron,"aria-label":s?"Expand workspace":"Collapse workspace",onClick:a=>{a.stopPropagation(),r()},children:s?i.jsx(Ot,{size:13}):i.jsx(Ft,{size:13})}),i.jsx(Ht,{size:13,className:R(E.workspaceIcon)}),i.jsx("span",{className:E.workspaceLabel,children:t}),i.jsx("span",{className:E.workspaceCount,children:n}),i.jsx(P,{size:"xs",variant:"ghost",iconOnly:!0,title:"New conversation",className:E.newSessionBtn,onClick:a=>{a.stopPropagation(),o()},children:i.jsx(Ge,{size:13})})]})}function ne(t,e){return e&&(t==="~"||t.startsWith("~/"))?e+t.slice(1):t}function wt(t,e,n){const s=new Map;for(const r of t){const o=e[r];if(!o)continue;const a=ne(o.cwd||"~",n),l=s.get(a);l?l.push(o):s.set(a,[o])}return Array.from(s,([r,o])=>({cwd:r,sessions:o}))}function Ko(t){return!t||t==="~"?"~":t.split("/").filter(Boolean).pop()||t}function Vo(){const t=B(_=>_.order),e=B(_=>_.sessions),n=B(_=>_.activeSessionId),s=B(_=>_.activate),r=B(_=>_.createSession),o=C(_=>_.open),a=T(_=>_.status),l=k(_=>_.openSessionMenu),c=k(_=>_.setCwd),u=k(_=>_.openCwdPicker),h=k(_=>_.collapsedWorkspaces),f=k(_=>_.toggleWorkspaceCollapsed),p=yt();function x(_){const j=ne(_||"~",p),S=r(j);o({id:O.chat(S),kind:"chat",label:"New chat",closable:!0,data:{sessionId:S},workspaceCwd:j})}function y(_){s(_);const j=e[_],S=ne((j==null?void 0:j.cwd)||"~",p);j!=null&&j.cwd&&c(j.cwd),o({id:O.chat(_),kind:"chat",label:(j==null?void 0:j.title)??"Chat",closable:!0,data:{sessionId:_},workspaceCwd:S})}const b=wt(t,e,p);return i.jsxs("div",{className:E.wrap,children:[i.jsxs("div",{className:E.header,children:[i.jsx("h3",{children:"Workspaces"}),i.jsx(P,{size:"xs",variant:"ghost",iconOnly:!0,title:a!=="open"?"Connect to open a workspace":"Open a workspace folder",disabled:a!=="open",onClick:()=>u(),children:i.jsx(Wt,{size:14})})]}),i.jsx("div",{className:E.list,children:b.map(_=>{const j=h.has(_.cwd);return i.jsxs("div",{className:E.workspaceGroup,children:[i.jsx(Uo,{label:Ko(_.cwd),cwd:_.cwd,sessionCount:_.sessions.length,collapsed:j,onToggleCollapsed:()=>f(_.cwd),onNewSession:()=>x(_.cwd)}),!j&&i.jsx("div",{className:E.workspaceSessions,children:_.sessions.map(S=>i.jsx(qo,{session:S,active:S.id===n,onSelect:()=>y(S.id),onOpenMenu:(kt,It)=>l(S.id,kt,It)},S.id))})]},_.cwd)})}),i.jsx(Lo,{})]})}const Go="_strip_cnwks_1",Jo="_tab_cnwks_10",Xo="_active_cnwks_26",Yo="_icon_cnwks_30",Zo="_label_cnwks_35",Qo="_close_cnwks_40",ee={strip:Go,tab:Jo,active:Xo,icon:Yo,label:Zo,close:Qo},ea={chat:Kt,file:Ut,diff:Lt,terminal:zt};function ta({tab:t}){const e=C(f=>f.activeTabId),n=C(f=>f.activate),s=C(f=>f.close),r=ea[t.kind],{attributes:o,listeners:a,setNodeRef:l,transform:c,transition:u,isDragging:h}=hn({id:t.id});return i.jsxs("div",{ref:l,className:R(ee.tab,t.id===e&&ee.active),style:{transform:mn.Transform.toString(c),transition:u,opacity:h?.5:1},onClick:()=>n(t.id),onAuxClick:f=>{f.button===1&&t.closable&&s(t.id)},title:t.label,...o,...a,children:[i.jsx("span",{className:ee.icon,children:i.jsx(r,{size:13})}),i.jsx("span",{className:ee.label,children:t.label}),t.closable&&i.jsx("span",{className:ee.close,onClick:f=>{f.stopPropagation(),s(t.id)},children:i.jsx(_e,{size:12})})]})}function na(){const t=C(a=>a.tabs),e=C(a=>a.activeWorkspaceCwd),n=C(a=>a.reorder),s=t.filter(a=>a.workspaceCwd===e),r=an(cn(pn,{activationConstraint:{distance:4}}));function o(a){const{active:l,over:c}=a;!c||l.id===c.id||n(String(l.id),String(c.id))}return i.jsx(ln,{sensors:r,collisionDetection:dn,onDragEnd:o,children:i.jsx(un,{items:s.map(a=>a.id),strategy:fn,children:i.jsx("div",{className:ee.strip,children:s.map(a=>i.jsx(ta,{tab:a},a.id))})})})}const sa="_spinner_1tgzp_3",ra={spinner:sa},oa={xs:12,sm:16,md:20,lg:24},aa={xs:1,sm:2,md:2,lg:3};function ia({size:t="md",color:e="currentColor",className:n,"aria-label":s="Loading"}){const r=typeof t=="number"?t:oa[t],o=typeof t=="number"?2:aa[t];return i.jsx("span",{className:`${ra.spinner}${n?` ${n}`:""}`,role:"status","aria-label":s,style:{width:r,height:r,borderWidth:o,color:e}})}const ca=v.lazy(()=>Ee(()=>import("./ChatPanel-BPn7-j3E.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13])).then(t=>({default:t.ChatPanel}))),Ue=v.lazy(()=>Ee(()=>import("./FilePanel-rWWLYKHq.js").then(t=>t.F),__vite__mapDeps([14,1,7,6,5,2,9,10,15])).then(t=>({default:t.FilePanel}))),la=v.lazy(()=>Ee(()=>import("./TerminalPanel-BqceIOgb.js"),__vite__mapDeps([16,1,17,18,7,6,5,2,3,11,12,19])).then(t=>({default:t.TerminalPanel}))),da={chat:ca,file:Ue,diff:Ue,terminal:la},ua="_area_1vzxd_1",fa="_panel_1vzxd_7",pa="_active_1vzxd_14",ha="_empty_1vzxd_17",ae={area:ua,panel:fa,active:pa,empty:ha};function ma(){const t=C(r=>r.tabs),e=C(r=>r.activeTabId),n=C(r=>r.activeWorkspaceCwd);return t.some(r=>r.workspaceCwd===n)?i.jsx("div",{className:ae.area,children:t.map(r=>{const o=da[r.kind];return i.jsx("div",{className:R(ae.panel,r.id===e&&ae.active),children:i.jsx(v.Suspense,{fallback:i.jsx(ia,{size:"md"}),children:i.jsx(o,{tab:r})})},r.id)})}):i.jsx("div",{className:ae.area,children:i.jsx("div",{className:ae.empty,children:"No open tabs in this workspace"})})}const ga={fileRead:t=>["file","read",t],fileDownload:t=>["file","download",t],fileDiff:(t,e,n)=>["file","diff",t,e,n],explorer:t=>["explorer",t],agentList:()=>["agents","list"],agentTimeline:t=>["agents","timeline",t]};function ba(t){const e=t.kind==="directory"||t.type==="directory"?"directory":"file";return{name:t.name??"",kind:e,size:t.size,mtimeMs:t.mtimeMs}}function _a(t){return t.slice().sort((e,n)=>e.kind!==n.kind?e.kind==="directory"?-1:1:e.name.localeCompare(n.name))}function St(t,e=!0){const n=T(s=>s.client);return Rt({queryKey:ga.explorer(t),queryFn:async()=>{if(!n)throw new Error("not connected");const r=(await n.connection.request("file_explorer_request",{path:t})).result;if(!r||r.ok===!1)throw new Error(r&&"error"in r?r.error:"explorer request failed");const o="entries"in r?r.entries??[]:[];return{path:r.resolvedPath??t,entries:_a(o.map(ba))}},enabled:!!n&&!!t&&e})}const ya="_list_1o67b_1",wa="_upRow_1o67b_4",Sa="_item_1o67b_24",xa="_icon_1o67b_36",va="_name_1o67b_43",ka="_dirName_1o67b_48",Ia="_emptyState_1o67b_54",F={list:ya,upRow:wa,item:Sa,icon:xa,name:va,dirName:ka,emptyState:Ia};function Ca(){const t=T(b=>b.client),e=Z(b=>b.currentPath),n=Z(b=>b.rootPath),s=Z(b=>b.setPath),r=Z(b=>b.setRoot),o=Z(b=>b.goUp),a=C(b=>b.activeWorkspaceCwd),l=C(b=>b.open),c=v.useRef(null);v.useEffect(()=>{if(!t)return;const b=a||"~";c.current!==b&&(c.current=b,ho(t,b).then(_=>r(_)))},[t,a,r]);const{data:u,isLoading:h,isError:f,error:p}=St(e,!!t);function x(b){s(e?`${e}/${b}`:b)}function y(b){const _=e?`${e}/${b}`:b;l({id:O.file(_),kind:"file",label:_.split("/").pop()||_,closable:!0,data:{path:_},workspaceCwd:a||"~"})}return t?h?i.jsx("div",{className:F.emptyState,children:"Loading..."}):f?i.jsxs("div",{className:F.emptyState,children:["Error: ",p instanceof Error?p.message:"unknown error"]}):!u||u.entries.length===0?i.jsx("div",{className:F.emptyState,children:"No files loaded"}):i.jsxs("div",{className:F.list,children:[e&&e!==n&&i.jsxs("div",{className:F.upRow,onClick:()=>o(),children:[i.jsx(Je,{size:12}),i.jsx("span",{children:e})]}),u.entries.map(b=>i.jsxs("div",{className:F.item,onClick:()=>b.kind==="directory"?x(b.name):y(b.name),children:[i.jsx("span",{className:F.icon,children:b.kind==="directory"?i.jsx(Xe,{size:14}):i.jsx(Vt,{size:14})}),i.jsx("span",{className:b.kind==="directory"?F.dirName:F.name,children:b.name})]},b.name))]}):i.jsx("div",{className:F.emptyState,children:"Connect to browse files"})}const Ne=X()(t=>({subscribedCwd:null,changes:[],setSubscribedCwd:e=>t({subscribedCwd:e}),applyProjection:e=>{if(!e||!e.available){t({changes:[]});return}const n=[];for(const s of e.staged)n.push({path:s.path,status:s.indexStatus==="A"?"added":s.indexStatus==="D"?"deleted":"modified",staged:!0});for(const s of e.unstaged)n.push({path:s.path,status:s.worktreeStatus==="D"?"deleted":"modified",staged:!1});for(const s of e.untracked)n.push({path:s,status:"added",staged:!1});t({changes:n})}}));function Ta(t){return typeof t=="object"&&t!==null&&"type"in t&&t.type==="checkout_status_update"&&"cwd"in t&&typeof t.cwd=="string"&&"projection"in t&&typeof t.projection=="object"&&t.projection!==null}function ja(t){const e=T(o=>o.client),n=Ne(o=>o.applyProjection),s=Ne(o=>o.setSubscribedCwd),r=v.useRef(e);return r.current=e,v.useEffect(()=>{if(!e||!t)return;let o=!1;e.connection.request("checkout_status_subscribe",{cwd:t}).catch(()=>{}),s(t);const a=e.connection.onSessionMessage(l=>{if(o)return;const c=l;Ta(c)&&c.cwd===t&&n(c.projection)});return e.connection.request("checkout_refresh_request",{cwd:t}).catch(()=>{}),()=>{o=!0,a(),e.connection.request("checkout_status_unsubscribe",{cwd:t}).catch(()=>{}),s(null)}},[e,t,n,s]),{refresh(){const o=r.current;!o||!t||o.connection.request("checkout_refresh_request",{cwd:t}).catch(()=>{})}}}const Na="_list_1pgby_1",Ea="_summary_1pgby_4",Ra="_item_1pgby_11",Ba="_badge_1pgby_23",Aa="_added_1pgby_30",$a="_modified_1pgby_34",Ma="_deleted_1pgby_38",Pa="_name_1pgby_42",Da="_emptyState_1pgby_47",G={list:Na,summary:Ea,item:Ra,badge:Ba,added:Aa,modified:$a,deleted:Ma,name:Pa,emptyState:Da},qa={added:"A",modified:"M",deleted:"D"};function Oa(){const e=C(o=>o.activeWorkspaceCwd)||"~";ja(e);const n=Ne(o=>o.changes),s=C(o=>o.open);function r(o,a){s({id:O.diff(o,a),kind:"diff",label:o.split("/").pop()||o,closable:!0,data:{path:o,staged:a},workspaceCwd:e})}return n.length===0?i.jsx("div",{className:G.emptyState,children:"No changes detected"}):i.jsxs("div",{className:G.list,children:[i.jsxs("div",{className:G.summary,children:[n.length," changed file",n.length===1?"":"s"]}),n.map((o,a)=>i.jsxs("div",{className:G.item,onClick:()=>r(o.path,o.staged),children:[i.jsx("span",{className:R(G.badge,G[o.status]),children:qa[o.status]}),i.jsx("span",{className:G.name,children:o.path})]},`${o.path}-${o.staged}-${a}`))]})}const xt=X()(t=>({terminals:[],setTerminals:e=>t({terminals:e})}));function Fa(t){return typeof t=="object"&&t!==null&&"type"in t&&t.type==="terminals_update"&&"terminals"in t&&Array.isArray(t.terminals)}function Ha(){const t=T(n=>n.client),e=xt(n=>n.setTerminals);v.useEffect(()=>{if(!t){e([]);return}let n=!1;t.connection.request("subscribe_terminals_request",{}).then(r=>{n||e(r.terminals??[])}).catch(()=>{});const s=t.connection.onSessionMessage(r=>{if(n)return;const o=r;Fa(o)&&e(o.terminals)});return()=>{n=!0,s(),t.connection.request("unsubscribe_terminals_request",{}).catch(()=>{})}},[t,e])}const Wa="_wrap_sx7p7_1",za="_newTerminal_sx7p7_5",La="_list_sx7p7_10",Ua="_summary_sx7p7_13",Ka="_item_sx7p7_20",Va="_reattach_sx7p7_30",Ga="_icon_sx7p7_45",Ja="_name_sx7p7_49",Xa="_openBadge_sx7p7_54",Ya="_kill_sx7p7_62",Za="_emptyState_sx7p7_80",$={wrap:Wa,newTerminal:za,list:La,summary:Ua,item:Ka,reattach:Va,icon:Ga,name:Ja,openBadge:Xa,kill:Ya,emptyState:Za};function Qa(){Ha();const t=T(f=>f.client),e=xt(f=>f.terminals),n=C(f=>f.tabs),s=C(f=>f.activeWorkspaceCwd),r=C(f=>f.open),o=C(f=>f.activate),a=C(f=>f.close);function l(f){return n.find(p=>p.kind==="terminal"&&p.data.slot===f)}function c(f,p,x){const y=l(f);if(y){o(y.id);return}const b=x||"~";r({id:O.terminal(f),kind:"terminal",label:p,closable:!0,data:{slot:f,cwd:b},workspaceCwd:b})}function u(f){const p=l(f);if(p){a(p.id);return}t&&t.connection.request("kill_terminal_request",{slot:f}).catch(()=>{})}const h=i.jsx(P,{variant:"secondary",size:"sm",leftIcon:i.jsx(Ge,{size:14}),className:$.newTerminal,onClick:()=>_t(s||"~"),children:"New terminal"});return e.length===0?i.jsxs("div",{className:$.wrap,children:[h,i.jsx("div",{className:$.emptyState,children:"No terminals running"})]}):i.jsxs("div",{className:$.wrap,children:[h,i.jsxs("div",{className:$.list,children:[i.jsxs("div",{className:$.summary,children:[e.length," terminal",e.length===1?"":"s"," running"]}),e.map(f=>{const p=l(f.slot)!==void 0;return i.jsxs("div",{className:$.item,children:[i.jsxs("button",{type:"button",className:$.reattach,onClick:()=>c(f.slot,f.name,f.cwd),title:f.cwd,children:[i.jsx(Gt,{size:13,className:$.icon}),i.jsx("span",{className:$.name,children:f.name}),p&&i.jsx("span",{className:$.openBadge,children:"open"})]}),i.jsx("button",{type:"button",className:$.kill,onClick:()=>u(f.slot),title:"Kill terminal",children:i.jsx(_e,{size:13})})]},f.slot)})]})]})}const ei="_wrap_r37ok_1",ti="_tabBar_r37ok_7",ni="_tabBtn_r37ok_13",si="_active_r37ok_26",ri="_refreshBtn_r37ok_30",oi="_content_r37ok_34",H={wrap:ei,tabBar:ti,tabBtn:ni,active:si,refreshBtn:ri,content:oi};function ai(){const t=k(c=>c.rightSidebarTab),e=k(c=>c.setRightSidebarTab),n=Z(c=>c.currentPath),r=C(c=>c.activeWorkspaceCwd)||"~",o=T(c=>c.client),a=Bt();function l(){a.invalidateQueries({queryKey:["explorer",n]}),o&&r&&o.connection.request("checkout_refresh_request",{cwd:r}).catch(()=>{})}return i.jsxs("div",{className:H.wrap,children:[i.jsxs("div",{className:H.tabBar,children:[i.jsx("button",{type:"button",className:R(H.tabBtn,t==="files"&&H.active),onClick:()=>e("files"),children:"Files"}),i.jsx("button",{type:"button",className:R(H.tabBtn,t==="changes"&&H.active),onClick:()=>e("changes"),children:"Changes"}),i.jsx("button",{type:"button",className:R(H.tabBtn,t==="terminals"&&H.active),onClick:()=>e("terminals"),children:"Terminals"}),t!=="terminals"&&i.jsx(P,{size:"xs",variant:"ghost",iconOnly:!0,title:"Refresh",className:H.refreshBtn,onClick:l,children:i.jsx(Jt,{size:13})})]}),i.jsx("div",{className:H.content,children:t==="files"?i.jsx(Ca,{}):t==="changes"?i.jsx(Oa,{}):i.jsx(Qa,{})})]})}const ii="_wrapper_131x2_3",ci="_box_131x2_18",li="_checkmark_131x2_36",di="_nativeInput_131x2_41",ge={wrapper:ii,box:ci,checkmark:li,nativeInput:di};v.forwardRef(function({label:e,checked:n=!1,disabled:s,className:r,onChange:o,...a},l){return i.jsxs("label",{className:ge.wrapper,"data-disabled":s||void 0,children:[i.jsx("input",{ref:l,type:"checkbox",className:ge.nativeInput,checked:n,disabled:s,onChange:o,...a}),i.jsx("span",{className:ge.box,"data-checked":n,"aria-hidden":!0,children:n&&i.jsx(Xt,{size:12,className:ge.checkmark})}),e&&i.jsx("span",{children:e})]})});const ui="_select_vj45v_3",fi={select:ui};v.forwardRef(function({options:e,placeholder:n,className:s,...r},o){return i.jsxs("select",{ref:o,className:R(fi.select,s),...r,children:[n&&i.jsx("option",{value:"",disabled:!0,children:n}),e.map(a=>i.jsx("option",{value:a.value,children:a.label},a.value))]})});const pi="_overlay_1yaef_1",hi="_contentWrapper_1yaef_7",mi="_dialog_1yaef_16",gi="_header_1yaef_28",bi="_title_1yaef_36",_i="_closeBtn_1yaef_43",yi="_body_1yaef_57",wi="_footer_1yaef_63",Si="_bare_1yaef_72",xi="_bareBody_1yaef_78",vi="_bareCloseBtn_1yaef_82",ki="_visuallyHidden_1yaef_101",M={overlay:pi,contentWrapper:hi,dialog:mi,header:gi,title:bi,closeBtn:_i,body:yi,footer:wi,bare:Si,bareBody:xi,bareCloseBtn:vi,visuallyHidden:ki},Ii=ve;function Ci({open:t,onOpenChange:e,title:n,children:s,footer:r,width:o,className:a,bare:l=!1}){return i.jsx(nn,{open:t,onOpenChange:e,children:i.jsxs(sn,{children:[i.jsx(rn,{className:M.overlay}),i.jsx("div",{className:M.contentWrapper,children:i.jsxs(on,{className:R(M.dialog,l&&M.bare,a),style:o!==void 0?{width:o}:void 0,children:[l?i.jsx($e,{className:M.visuallyHidden,children:n}):i.jsxs("div",{className:M.header,children:[i.jsx($e,{className:M.title,children:n}),i.jsx(ve,{asChild:!0,children:i.jsx("button",{type:"button",className:M.closeBtn,"aria-label":"Close",children:i.jsx(_e,{size:16})})})]}),i.jsx("div",{className:R(M.body,l&&M.bareBody),children:s}),l&&i.jsx(ve,{asChild:!0,children:i.jsx("button",{type:"button",className:M.bareCloseBtn,"aria-label":"Close",children:i.jsx(_e,{size:16})})}),r&&i.jsx("div",{className:M.footer,children:r})]})})]})})}const Ti="_handle_1ocv1_1",ji={handle:Ti};function Ke({side:t,onResize:e,className:n}){const s=v.useRef(0),r=v.useCallback(l=>{const c=l.clientX-s.current;s.current=l.clientX,e(t==="left"?c:-c)},[e,t]),o=v.useCallback(l=>{var c,u;window.removeEventListener("pointermove",r),window.removeEventListener("pointerup",o),document.body.style.cursor="",document.body.style.userSelect="",(u=(c=l.target)==null?void 0:c.releasePointerCapture)==null||u.call(c,l.pointerId)},[r]);function a(l){l.preventDefault(),s.current=l.clientX,document.body.style.cursor="col-resize",document.body.style.userSelect="none",window.addEventListener("pointermove",r),window.addEventListener("pointerup",o)}return i.jsx("div",{className:R(ji.handle,n),onPointerDown:a,role:"separator","aria-orientation":"vertical"})}function Ni(t,e){var h;const{order:n,sessions:s,createSession:r,activate:o}=B.getState(),l=wt(n,s,e).find(f=>f.cwd===t),c=((h=l==null?void 0:l.sessions[0])==null?void 0:h.id)??r(t);o(c);const u=B.getState().sessions[c];C.getState().open({id:O.chat(c),kind:"chat",label:(u==null?void 0:u.title)??"New chat",closable:!0,data:{sessionId:c},workspaceCwd:t}),k.getState().setCwd(t)}const Ei="_pathRow_9xphl_1",Ri="_pathInput_9xphl_9",Bi="_list_9xphl_13",Ai="_item_9xphl_20",$i="_name_9xphl_32",Mi="_emptyState_9xphl_37",U={pathRow:Ei,pathInput:Ri,list:Bi,item:Ai,name:$i,emptyState:Mi};function Pi(){const t=k(S=>S.cwdPickerOpen),e=k(S=>S.closeCwdPicker),n=C(S=>S.activeWorkspaceCwd),s=T(S=>S.client),r=yt(),[o,a]=v.useState("/"),[l,c]=v.useState("/");v.useEffect(()=>{if(!t)return;const S=ne(n||"~",r);a(S),c(S)},[t,s,n]);const{data:u,isLoading:h,isError:f,error:p}=St(o,t&&!!s),x=((u==null?void 0:u.entries)??[]).filter(S=>S.kind==="directory");function y(S){a(S),c(S)}function b(){y(o.split("/").slice(0,-1).join("/")||"/")}function _(){y(l.trim())}function j(){Ni(o,r),e()}return i.jsxs(Ci,{open:t,onOpenChange:S=>!S&&e(),title:"Open Workspace",footer:i.jsxs(i.Fragment,{children:[i.jsx(Ii,{asChild:!0,children:i.jsx(P,{size:"sm",variant:"secondary",children:"Cancel"})}),i.jsx(P,{size:"sm",onClick:j,children:"Open this folder"})]}),children:[i.jsxs("div",{className:U.pathRow,children:[i.jsx(P,{size:"xs",variant:"ghost",iconOnly:!0,title:"Up",onClick:b,children:i.jsx(Je,{size:13})}),i.jsx(Ie,{className:U.pathInput,value:l,onChange:S=>c(S.target.value),onKeyDown:S=>{S.key==="Enter"&&(S.preventDefault(),_())}}),i.jsx(P,{size:"xs",onClick:_,children:"Go"})]}),i.jsx("div",{className:U.list,children:h?i.jsx("div",{className:U.emptyState,children:"Loading..."}):f?i.jsxs("div",{className:U.emptyState,children:["Error: ",p instanceof Error?p.message:"unknown error"]}):x.length===0?i.jsx("div",{className:U.emptyState,children:"No subdirectories"}):x.map(S=>i.jsxs("div",{className:U.item,onClick:()=>y(o==="/"?`/${S.name}`:`${o}/${S.name}`),children:[i.jsx(Xe,{size:14}),i.jsx("span",{className:U.name,children:S.name})]},S.name))})]})}const Di="_shell_1m1nv_1",qi="_main_1m1nv_7",Oi="_sidebarLeft_1m1nv_13",Fi="_leftHandle_1m1nv_21",Hi="_center_1m1nv_24",Wi="_sidebarRight_1m1nv_31",zi="_rightHandle_1m1nv_39",J={shell:Di,main:qi,sidebarLeft:Oi,leftHandle:Fi,center:Hi,sidebarRight:Wi,rightHandle:zi};function Li(){const t=k(a=>a.leftSidebarCollapsed),e=k(a=>a.rightSidebarCollapsed),n=k(a=>a.leftSidebarWidth),s=k(a=>a.rightSidebarWidth),r=k(a=>a.resizeLeftSidebar),o=k(a=>a.resizeRightSidebar);return i.jsxs("div",{className:J.shell,children:[i.jsx(Xr,{}),i.jsxs("div",{className:J.main,children:[!t&&i.jsxs("aside",{className:J.sidebarLeft,style:{width:n},children:[i.jsx(Vo,{}),i.jsx(Ke,{side:"left",className:J.leftHandle,onResize:r})]}),i.jsxs("div",{className:J.center,children:[i.jsx(na,{}),i.jsx(ma,{})]}),!e&&i.jsxs("aside",{className:J.sidebarRight,style:{width:s},children:[i.jsx(Ke,{side:"right",className:J.rightHandle,onResize:o}),i.jsx(ai,{})]})]}),i.jsx(Pi,{})]})}function Ui(){const t=v.useRef(!1);v.useEffect(()=>{if(t.current)return;if(t.current=!0,window.location.hash.includes("offer=")){const c=window.location.href;k.getState().setHost(c),T.getState().connect({url:c});return}const e=new URLSearchParams(window.location.search),n=e.get("host"),s=e.get("pair"),r=e.get("password"),o=e.get("cwd"),a=e.get("connect")==="1",l=k.getState();if(s?l.setHost(s):n&&l.setHost(n),r&&l.setPassword(r),o&&l.setCwd(o),s)T.getState().connect({url:s});else if(a){const{host:c,password:u}=k.getState();T.getState().connect({url:c,password:u||void 0})}},[])}function Ki(t){return typeof t=="object"&&t!==null&&"kind"in t}function Vi(t){const e=[];for(const n of t)if(Ki(n))if(n.kind==="other")n.event&&e.push(n.event);else for(const s of n.events??[])e.push(s);return e}function Gi(){const t=T(s=>s.client),e=T(s=>s.status),n=v.useRef(!1);v.useEffect(()=>{e!=="open"||!t||n.current||(n.current=!0,(async()=>{var c;let s=[];try{s=(await t.connection.request("list_agents_request",{all:!1})).agents??[]}catch{s=[]}s.sort((u,h)=>(h.lastActivity??0)-(u.lastActivity??0));const r=B.getState();for(const u of s){if(r.findByAgentId(u.agentId))continue;let h=Te;try{const f=await t.agent(u.agentId).timeline.fetch({direction:"after",limit:200});h=Vi(f.items).reduce(bt,Te)}catch{}r.hydrate({id:`s-${u.agentId.slice(0,12)}`,agentId:u.agentId,title:u.title||((c=u.cwd)==null?void 0:c.split("/").pop())||"Restored",status:u.status??"idle",cwd:u.cwd||"~",timeline:h,userMessageCount:h.rows.filter(f=>f.kind==="user").length})}const o=await Ae(t).catch(()=>null),{order:a,sessions:l}=B.getState();if(a.length>0){const u=l[a[0]??""];if(u){const h=ne(u.cwd||"~",o);B.getState().activate(u.id),k.getState().setCwd(u.cwd),C.getState().open({id:O.chat(u.id),kind:"chat",label:u.title,closable:!0,data:{sessionId:u.id},workspaceCwd:h})}}else{const u=k.getState().cwd||"~",h=ne(u,o),f=B.getState().createSession(u);C.getState().open({id:O.chat(f),kind:"chat",label:"New chat",closable:!0,data:{sessionId:f},workspaceCwd:h})}})())},[e,t])}function Ji(){v.useEffect(()=>{function t(e){const n=k.getState();if(e.key==="Escape"){n.closeCwdPicker(),n.closeSessionMenu();return}const s=e.ctrlKey||e.metaKey;if(s&&e.key.toLowerCase()==="t"){e.preventDefault(),_t(C.getState().activeWorkspaceCwd||"~");return}if(s&&e.key.toLowerCase()==="w"){const{activeTabId:r,tabs:o,close:a}=C.getState();if(!r)return;const l=o.find(c=>c.id===r);(l==null?void 0:l.closable)!==!1&&(e.preventDefault(),a(r))}}return document.addEventListener("keydown",t),()=>document.removeEventListener("keydown",t)},[])}function Xi(){return Ui(),Gi(),Ji(),null}function Yi(){return i.jsxs(rs,{children:[i.jsx(Xi,{}),i.jsx(Li,{})]})}const vt=document.getElementById("root");if(!vt)throw new Error("Missing #root element");jt.createRoot(vt).render(i.jsx(v.StrictMode,{children:i.jsx(Yi,{})}));export{P as B,Ci as D,ia as S,ic as T,T as a,C as b,cc as e,ga as r,Yr as t,B as u};
3
- //# sourceMappingURL=index-DnLvR47L.js.map