@openchambery/web 1.18.2-beta.2 → 1.18.2-beta.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{AgentAvatar-B2kZjgaf.js → AgentAvatar-B4fj9PIe.js} +1 -1
- package/dist/assets/{AssistantView-DvoyOGkx.js → AssistantView-C00aiEHK.js} +1 -1
- package/dist/assets/{ChatContainer-D6yfuigV.js → ChatContainer-BDFeDKu-.js} +39 -39
- package/dist/assets/{DiagramView-MGGo9iME.js → DiagramView-CUfSFI3e.js} +1 -1
- package/dist/assets/{FadeInOnReveal-aeWlaqVB.js → FadeInOnReveal-CKKU6fKI.js} +1 -1
- package/dist/assets/{Icon-AXqa-fYB.js → Icon-DiIuWOuC.js} +1 -1
- package/dist/assets/{MarkdownRendererImpl-jVOkZkyX.js → MarkdownRendererImpl-Cen6E9Lj.js} +2 -2
- package/dist/assets/{MobileDetailNavigation-Q2IzHqGA.js → MobileDetailNavigation-DILi0tN7.js} +1 -1
- package/dist/assets/{MobileShareBridge-apXM34Lb.js → MobileShareBridge-PZMRiieI.js} +1 -1
- package/dist/assets/MobileSurface-BLYcR0tO.js +2 -0
- package/dist/assets/{MultiRunWindow-B-l_O-bd.js → MultiRunWindow-D_2mWZyv.js} +1 -1
- package/dist/assets/{OnboardingScreen-CUsgwt4y.js → OnboardingScreen-CYeRZznl.js} +1 -1
- package/dist/assets/{OverlayScrollbar-D6NySAxi.js → OverlayScrollbar-BgMLtMIq.js} +1 -1
- package/dist/assets/SettingsView-CbDBfQp1.js +25 -0
- package/dist/assets/{SettingsWindow-DfVgTQ4I.js → SettingsWindow-Br7XLcSd.js} +1 -1
- package/dist/assets/{TerminalView-DNyjfkvT.js → TerminalView-CM5jRKlj.js} +1 -1
- package/dist/assets/{ToolOutputDialog-DLG1iThm.js → ToolOutputDialog-D3U6aTZ4.js} +1 -1
- package/dist/assets/appThemeRegistry-CDxBJNNB.js +2 -0
- package/dist/assets/assistant-guide-hero-BeUHQcxE.jpg +0 -0
- package/dist/assets/{button-CDvMVaiO.js → button-DaAoVF4X.js} +1 -1
- package/dist/assets/{clipboard-BW7nk_Cx.js → clipboard-BnElHSnO.js} +1 -1
- package/dist/assets/{collapsible-C2aamDvD.js → collapsible-BmuQu0dq.js} +1 -1
- package/dist/assets/{context-menu-BaxmodD8.js → context-menu-DBOMervd.js} +1 -1
- package/dist/assets/{desktopHosts-CBoBpJ1Z.js → desktopHosts-ZK_vkdzL.js} +1 -1
- package/dist/assets/{desktopRelayRestore-l2R9muux.js → desktopRelayRestore-CewM6-g5.js} +1 -1
- package/dist/assets/{diagram-CEon0BQs.js → diagram-DAE4CZy2.js} +1 -1
- package/dist/assets/{dialog-DjYfj1Sn.js → dialog-COrLBm9O.js} +1 -1
- package/dist/assets/{es-5Lhudh0n.js → es-DIVYdoxi.js} +1 -1
- package/dist/assets/{fileQueries-CE_DaZWQ.js → fileQueries-CmWYnRVz.js} +1 -1
- package/dist/assets/{fr-Q_UhFmKT.js → fr-CNTlVypq.js} +2 -2
- package/dist/assets/{gitApi-BYxg_qGJ.js → gitApi-BQT3QXD2.js} +1 -1
- package/dist/assets/gitApiHttp-BxGAFLTf.js +2 -0
- package/dist/assets/{input-k9DGGyZ6.js → input-XiL2-2gG.js} +1 -1
- package/dist/assets/insertionBoundaries-9a0RuIDc.js +1 -0
- package/dist/assets/{ja-CzMPz7bT.js → ja-C_eW5ZM8.js} +1 -1
- package/dist/assets/{ko-B-EslUsR.js → ko-CE3cOv7v.js} +1 -1
- package/dist/assets/{main-LDphyc-v.js → main-BGfX81Y9.js} +20 -20
- package/dist/assets/{main-CO6z5yRB.js → main-CEqSDnE2.js} +2 -2
- package/dist/assets/{markdown-worker-DkeWiER6.js → markdown-worker-BDyY0vt6.js} +1 -1
- package/dist/assets/{markdownTheme-DNT93i5L.js → markdownTheme-D-aLQZaM.js} +1 -1
- package/dist/assets/{miniChat-BZQwTZpx.js → miniChat-CKucSAhg.js} +2 -2
- package/dist/assets/mobile-C4bTWKry.js +2 -0
- package/dist/assets/{multirun-ZlwlkIy5.js → multirun-DeNtSkgb.js} +1 -1
- package/dist/assets/{persistence-DPNMIbF5.js → persistence-D1lIuyqO.js} +1 -1
- package/dist/assets/{pl-Dnea6Ppc.js → pl-BZKZOE99.js} +1 -1
- package/dist/assets/projectMeta-BunN9pH5.js +3 -0
- package/dist/assets/{pt-BR-Ca6QTem7.js → pt-BR-DHDgp8S3.js} +1 -1
- package/dist/assets/{radio-CJuhbQ5a.js → radio-Bziafaje.js} +1 -1
- package/dist/assets/renderElectronMiniChatApp-D8-FDgWE.js +2 -0
- package/dist/assets/renderMobileApp-CdU0aJ-e.js +23 -0
- package/dist/assets/{runtimeConfig-BtWi74Pm.js → runtimeConfig-BXCt7ZsQ.js} +1 -1
- package/dist/assets/runtimeEndpointReset-CK1GhIsm.js +145 -0
- package/dist/assets/{sortable-tabs-strip-D8JHUI0z.js → sortable-tabs-strip-pWlBorwQ.js} +1 -1
- package/dist/assets/src-8kQFmtjw.css +2 -0
- package/dist/assets/{store-wa1ersRf.js → store-CUWqzRt7.js} +2 -2
- package/dist/assets/{terminalApi-tB3qLcfa.js → terminalApi-DpiAJlil.js} +1 -1
- package/dist/assets/{tooltip-DMNR5rN0.js → tooltip-BLugzWq-.js} +1 -1
- package/dist/assets/{uk-xGc9Pzge.js → uk-CfQK6cz1.js} +1 -1
- package/dist/assets/{url-7MqoLs9X.js → url-DMs_PgIC.js} +1 -1
- package/dist/assets/useAppFontEffects-IEUQDvE8.js +7 -0
- package/dist/assets/useDesktopWindowControlsLayout-MlqJX89k.js +1 -0
- package/dist/assets/{useEffectiveDirectory-aUC3zzl_.js → useEffectiveDirectory-GbhkdO6m.js} +1 -1
- package/dist/assets/{useFontPreferences-CIurCeNv.js → useFontPreferences-92Qg-98H.js} +1 -1
- package/dist/assets/useMobileNavigationStore-DQHF_ETu.js +476 -0
- package/dist/assets/useSessionAutoCleanup-BuU_S_Sh.js +1 -0
- package/dist/assets/{useWorkerHighlightedLines-CiYQjBe6.js → useWorkerHighlightedLines-Ca6OgNHF.js} +1 -1
- package/dist/assets/{utils-Co19EJEL.js → utils-BxJEIWv5.js} +1 -1
- package/dist/assets/{zh-CN-sL4ktGB3.js → zh-CN-DvY2fKWp.js} +1 -1
- package/dist/assets/{zh-TW-Cfxps4gq.js → zh-TW-eWe0lm3-.js} +1 -1
- package/dist/index.html +8 -8
- package/dist/mini-chat.html +8 -8
- package/dist/mobile.html +8 -8
- package/package.json +1 -1
- package/server/index.d.ts +6 -0
- package/server/index.js +13 -0
- package/server/lib/config-sync/DOCUMENTATION.md +70 -0
- package/server/lib/config-sync/config-sync.test.js +197 -0
- package/server/lib/config-sync/constants.js +39 -0
- package/server/lib/config-sync/contract.js +130 -0
- package/server/lib/config-sync/credential-auth.js +39 -0
- package/server/lib/config-sync/engine.js +108 -0
- package/server/lib/config-sync/index.js +67 -0
- package/server/lib/config-sync/local-backup.js +171 -0
- package/server/lib/config-sync/plan.js +318 -0
- package/server/lib/config-sync/receiver.js +330 -0
- package/server/lib/config-sync/routes.js +141 -0
- package/server/lib/config-sync/routes.test.js +154 -0
- package/server/lib/config-sync/scripts.js +264 -0
- package/server/lib/config-sync/selections.js +112 -0
- package/server/lib/config-sync/tar.js +35 -0
- package/server/lib/config-sync/target-id.js +24 -0
- package/server/lib/event-stream/DOCUMENTATION.md +2 -2
- package/server/lib/event-stream/diff-summary.js +39 -11
- package/server/lib/event-stream/diff-summary.test.js +73 -6
- package/server/lib/event-stream/protocol.test.js +70 -7
- package/server/lib/notifications/DOCUMENTATION.md +2 -2
- package/server/lib/notifications/runtime.js +68 -27
- package/server/lib/notifications/runtime.test.js +176 -0
- package/server/lib/opencode/DOCUMENTATION.md +4 -1
- package/server/lib/opencode/bootstrap-runtime.js +2 -0
- package/server/lib/opencode/core-routes.js +1 -0
- package/server/lib/opencode/feature-routes-runtime.test.js +10 -1
- package/server/lib/opencode/openchamber-routes.js +7 -0
- package/server/lib/opencode/settings-runtime.js +82 -51
- package/server/lib/opencode/settings-runtime.test.js +42 -0
- package/server/lib/relay/DOCUMENTATION.md +1 -1
- package/server/lib/session-index/DOCUMENTATION.md +12 -6
- package/server/lib/session-index/routes.js +34 -0
- package/server/lib/session-index/routes.test.js +76 -0
- package/server/lib/session-index/service.js +53 -4
- package/server/lib/session-index/service.test.js +72 -2
- package/server/lib/session-title/DOCUMENTATION.md +19 -14
- package/server/lib/session-title/runtime.js +8 -8
- package/server/lib/session-title/runtime.test.js +231 -0
- package/server/lib/session-turn-pages/DOCUMENTATION.md +26 -6
- package/server/lib/session-turn-pages/changes.service.js +156 -0
- package/server/lib/session-turn-pages/changes.service.test.js +188 -0
- package/server/lib/session-turn-pages/reconcile.routes.test.js +52 -0
- package/server/lib/session-turn-pages/reconcile.service.js +3 -1
- package/server/lib/session-turn-pages/reconcile.service.test.js +44 -0
- package/server/lib/session-turn-pages/routes.js +273 -12
- package/server/lib/session-turn-pages/routes.test.js +387 -0
- package/server/lib/session-turn-pages/service.js +31 -7
- package/server/lib/session-turn-pages/service.test.js +40 -0
- package/server/lib/small-model/DOCUMENTATION.md +93 -38
- package/server/lib/small-model/catalog.js +10 -2
- package/server/lib/small-model/catalog.test.js +3 -1
- package/server/lib/small-model/index.js +52 -28
- package/server/lib/small-model/opencode-session.js +339 -0
- package/server/lib/small-model/opencode-session.test.js +177 -0
- package/server/lib/small-model/resolve.js +116 -5
- package/server/lib/small-model/resolve.test.js +76 -10
- package/server/lib/small-model/summary-settings.test.js +60 -3
- package/dist/assets/MobileSurface-htGkf7Ua.js +0 -2
- package/dist/assets/SettingsView-DxMpVLlt.js +0 -25
- package/dist/assets/appThemeRegistry-CgfOR_0L.js +0 -2
- package/dist/assets/gitApiHttp-D8j1qRH4.js +0 -2
- package/dist/assets/insertionBoundaries-DzXMTleb.js +0 -1
- package/dist/assets/mobile-BktO3_4R.js +0 -2
- package/dist/assets/projectMeta-v-LP2mzz.js +0 -3
- package/dist/assets/renderElectronMiniChatApp-Db8uO-6q.js +0 -2
- package/dist/assets/renderMobileApp-BCV81Ryl.js +0 -23
- package/dist/assets/runtimeEndpointReset-Dg3DMy9v.js +0 -145
- package/dist/assets/src-oHrYIqHF.css +0 -2
- package/dist/assets/useAppFontEffects-CM0VKsdo.js +0 -7
- package/dist/assets/useDesktopWindowControlsLayout-Cq-r4Hcb.js +0 -1
- package/dist/assets/useMobileNavigationStore-DnzT4jO2.js +0 -475
- package/dist/assets/useSessionAutoCleanup-DxZeceKO.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{F as e,G as t,H as n,I as r,K as i,N as a,O as o,P as s,U as c,W as ee}from"./useUIStore-5agS8bsW.js";import{On as te,kn as l}from"./persistence-DPNMIbF5.js";import{t as u}from"./desktopRelayRestore-l2R9muux.js";import{A as d,B as ne,C as re,D as ie,E as ae,F as oe,G as f,J as se,K as ce,L as le,M as ue,N as de,O as fe,P as pe,Q as me,R as he,S as ge,U as p,V as m,W as h,X as g,Y as _,Z as v,_ as y,a as b,at as x,c as S,ct as C,d as w,dt as T,f as E,ft as D,g as O,gt as k,h as A,ht as j,i as M,it as N,j as P,k as F,l as I,lt as L,m as _e,mt as ve,n as ye,nt as be,o as xe,ot as Se,p as Ce,pt as we,q as Te,r as Ee,rt as De,s as Oe,st as ke,t as Ae,tt as je,u as Me,ut as Ne,v as R,w as Pe,y as Fe,yt as Ie,z as Le}from"./gitApiHttp-D8j1qRH4.js";import{a as Re,c as ze,l as Be,n as Ve,r as He,s as Ue,t as We}from"./terminalApi-tB3qLcfa.js";(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var Ge=e=>{let t=e?.retry;return{maxRetries:t?.maxRetries??3,initialRetryDelay:t?.initialDelayMs??1e3,maxRetryDelay:t?.maxDelayMs??8e3,connectionTimeout:e?.connectionTimeoutMs??1e4}},Ke=()=>({async createSession(e){return He(e)},connect(e,t,n){let r=Ve(e,t.onEvent,t.onError,Ge(n));return{close:()=>r()}},async sendInput(e,t){await Be(e,t)},async resize(e){await Ue(e.sessionId,e.cols,e.rows)},async close(e){await We(e)},async restartSession(e,t){return ze(e,{cwd:t.cwd??``,cols:t.cols,rows:t.rows})},async forceKill(e){await Re(e)}}),qe=()=>({checkIsGitRepository:b,getGitStatus:pe,getGitDiff:d,getGitFileDiff:P,revertGitFile:be,stageGitFile:x,stageGitFiles:Se,unstageGitFile:T,unstageGitFiles:D,stageGitHunk:ke,unstageGitHunk:we,revertGitHunk:De,isLinkedWorktree:p,getGitBranches:F,deleteGitBranch:O,deleteRemoteBranch:Fe,removeRemote:g,generateCommitMessage:re,generatePullRequestDescription:Pe,listGitWorktrees:f,validateGitWorktree:j,createGitWorktree:A,deleteGitWorktree:R,validateWorktreeDirectory:k,canonicalizeWorktreeState:M,createGitCommit(e,t,n){return Ce(e,t,n)},gitPush:ne,gitPull:Le,gitFetch:he,listGitStashes:h,countGitStashFiles:w,stashGitChanges:L,applyGitStash:Ee,popGitStash:Te,dropGitStash:ge,checkoutBranch:xe,createBranch:E,renameBranch:v,getGitLog(e,t){return de(e,t)},getCommitFiles:ae,getCurrentGitIdentity:fe,hasLocalIdentity:m,setGitIdentity:N,getGitIdentities:ue,createGitIdentity:_e,updateGitIdentity:ve,deleteGitIdentity:y,getRemotes:le,rebase:_,abortRebase:ye,continueRebase:Me,merge:ce,abortMerge:Ae,continueMerge:I,checkoutCommit:Oe,cherryPick:S,revertCommit:je,resetToCommit:me,stash:C,stashPop:Ne,getConflictDetails:ie,worktree:{list:f,validate:j,bootstrapStatus:oe,preview:se,create:A,remove:R}}),z=e=>e.replace(/\\/g,`/`),Je=(e,t)=>({directory:z(t?.directory||t?.path||e),entries:(Array.isArray(t?.entries)?t.entries:[]).filter(e=>!!(e&&typeof e.name==`string`&&typeof e.path==`string`)).map(e=>({name:e.name,path:z(e.path),isDirectory:!!e.isDirectory}))}),B=(e,t)=>{let n=t||e?.();return n?{"x-opencode-directory":n}:void 0},Ye=({getDirectory:e})=>({async listDirectory(t,n){let r=z(t),i=new URLSearchParams;r&&i.set(`path`,r),n?.respectGitignore&&i.set(`respectGitignore`,`true`);let a=await l(`/api/fs/list`,{query:i,headers:B(e)});if(!a.ok){let e=await a.json().catch(()=>({error:a.statusText}));throw Error(e.error||`Failed to list directory`)}return Je(r,await a.json())},async search(t){let n=new URLSearchParams,r=z(t.directory);r&&n.set(`directory`,r),n.set(`query`,t.query),n.set(`dirs`,`false`),n.set(`type`,`file`),typeof t.maxResults==`number`&&Number.isFinite(t.maxResults)&&n.set(`limit`,String(t.maxResults));let i=await l(`/api/find/file`,{query:n,headers:B(e)});if(!i.ok){let e=await i.json().catch(()=>({error:i.statusText}));throw Error(e.error||`Failed to search files`)}let a=await i.json();return(Array.isArray(a)?a:[]).map(e=>({path:z(`${r}/${e}`),preview:[z(e)]}))},async createDirectory(t){let n=z(t),r=await l(`/api/fs/mkdir`,{method:`POST`,headers:{"Content-Type":`application/json`,...B(e)},body:JSON.stringify({path:n})});if(!r.ok){let e=await r.json().catch(()=>({error:r.statusText}));throw Error(e.error||`Failed to create directory`)}let i=await r.json();return{success:!!i?.success,path:typeof i?.path==`string`?z(i.path):n}},async statFile(t,n){let r=z(t),i=new URLSearchParams({path:r});n?.allowOutsideWorkspace&&i.set(`allowOutsideWorkspace`,`true`),n?.outsideFileGrant&&i.set(`outsideFileGrant`,n.outsideFileGrant);let a=await l(`/api/fs/stat`,{query:i,headers:B(e,n?.directory)});if(!a.ok){let e=await a.json().catch(()=>({error:a.statusText}));throw Error(e.error||`Failed to stat file`)}let o=await a.json().catch(()=>({}));return{path:typeof o.path==`string`?z(o.path):r,isFile:!!o.isFile,size:typeof o.size==`number`?o.size:0,mtimeMs:typeof o.mtimeMs==`number`?o.mtimeMs:void 0,isBinary:typeof o.isBinary==`boolean`?o.isBinary:void 0}},async readFile(t,n){let r=z(t),i=new URLSearchParams({path:r});n?.allowOutsideWorkspace&&i.set(`allowOutsideWorkspace`,`true`),n?.outsideFileGrant&&i.set(`outsideFileGrant`,n.outsideFileGrant),n?.optional&&i.set(`optional`,`true`);let a=await l(`/api/fs/read`,{query:i,cache:n?.optional?`no-store`:`default`,headers:B(e,n?.directory)});if(!a.ok){let e=await a.json().catch(()=>({error:a.statusText}));throw Error(e.error||`Failed to read file`)}let o=await a.text();if(n?.optional){let e=a.headers.get(`x-openchamber-file-exists`);if(e!==`true`&&e!==`false`)throw Error(`Optional file read requires an existence response header`);return{content:o,path:r,exists:e===`true`}}return{content:o,path:r,exists:!0}},async writeFile(t,n){let r=z(t),i=await l(`/api/fs/write`,{method:`POST`,headers:{"Content-Type":`application/json`,...B(e)},body:JSON.stringify({path:r,content:n})});if(!i.ok){let e=await i.json().catch(()=>({error:i.statusText}));throw Error(e.error||`Failed to write file`)}let a=await i.json().catch(()=>({}));return{success:!!a.success,path:typeof a.path==`string`?z(a.path):r}},async delete(t){let n=z(t),r=await l(`/api/fs/delete`,{method:`POST`,headers:{"Content-Type":`application/json`,...B(e)},body:JSON.stringify({path:n})});if(!r.ok){let e=await r.json().catch(()=>({error:r.statusText}));throw Error(e.error||`Failed to delete file`)}return{success:!!(await r.json().catch(()=>({}))).success}},async rename(t,n){let r=await l(`/api/fs/rename`,{method:`POST`,headers:{"Content-Type":`application/json`,...B(e)},body:JSON.stringify({oldPath:t,newPath:n})});if(!r.ok){let e=await r.json().catch(()=>({error:r.statusText}));throw Error(e.error||`Failed to rename file`)}let i=await r.json().catch(()=>({}));return{success:!!i.success,path:typeof i.path==`string`?z(i.path):n}},async revealPath(t){let n=await l(`/api/fs/reveal`,{method:`POST`,headers:{"Content-Type":`application/json`,...B(e)},body:JSON.stringify({path:z(t)})});if(!n.ok){let e=await n.json().catch(()=>({error:n.statusText}));throw Error(e.error||`Failed to reveal path`)}return{success:!!(await n.json().catch(()=>({}))).success}},async downloadFile(t){let n=z(t),r=await l(`/api/fs/raw`,{query:{path:n,download:!0},headers:B(e)});if(!r.ok)throw Error(`Download failed (${r.status})`);let i=await r.blob(),a=URL.createObjectURL(i),o=document.createElement(`a`);o.href=a,o.download=n.split(`/`).pop()||`file`,document.body.appendChild(o),o.click(),document.body.removeChild(o),setTimeout(()=>URL.revokeObjectURL(a),100)}}),V=`/api/config/settings`,Xe=`/api/config/reload`,H=e=>!e||typeof e!=`object`?{}:e,Ze=()=>({async load(){let e=await l(V,{method:`GET`,headers:{Accept:`application/json`}});if(!e.ok)throw Error(`Failed to load settings: ${e.statusText}`);return{settings:H(await e.json().catch(()=>({}))),source:`web`}},async save(e){let t=await l(V,{method:`PUT`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify(e)});if(!t.ok){let e=await t.json().catch(()=>({error:t.statusText}));throw Error(e.error||`Failed to save settings`)}return H(await t.json().catch(()=>({})))},async restartOpenCode(){let e=await l(Xe,{method:`POST`});if(!e.ok){let t=await e.json().catch(()=>({error:e.statusText}));throw Error(t.error||`Failed to restart OpenCode`)}return{restarted:!0}}}),Qe=()=>({async requestDirectoryAccess(e){return{success:!0,path:e.path}},async startAccessingDirectory(e){return{success:!0}},async stopAccessingDirectory(e){return{success:!0}}}),$e=1500,U=5e3,et=`openchamber-notification-claim:`,W=new Map,tt=()=>typeof document>`u`||document.visibilityState===`visible`&&document.hasFocus(),nt=e=>(typeof e?.tag==`string`?e.tag.trim():``)||[e?.sessionId,e?.kind,e?.title,e?.body].filter(e=>typeof e==`string`&&e.trim().length>0).map(e=>e.trim()).join(`|`),rt=e=>{for(let[t,n]of W)e-n>U&&W.delete(t)},it=e=>{let t=nt(e);if(!t)return!0;let n=Date.now();if(rt(n),n-(W.get(t)??0)<U)return!1;try{if(typeof window<`u`&&window.localStorage){let e=`${et}${t}`,r=Number(window.localStorage.getItem(e)??`0`);if(Number.isFinite(r)&&n-r<U)return W.set(t,r),!1;Number.isFinite(r)&&r>0&&window.localStorage.removeItem(e),window.localStorage.setItem(e,String(n))}}catch{}return W.set(t,n),!0},G=async()=>{if(typeof navigator>`u`||!(`serviceWorker`in navigator))return null;let e=null;try{e=await navigator.serviceWorker.getRegistration()??null}catch{e=null}if(e?.active)return e;if(!e)return null;try{return await Promise.race([navigator.serviceWorker.ready,new Promise(e=>{setTimeout(()=>e(null),$e)})])??e}catch{return e}},at=async e=>{let t=await G();if(!t||typeof t.showNotification!=`function`)return!1;try{return await t.showNotification(e?.title??`OpenChamber`,{body:e?.body,tag:e?.tag}),!0}catch(e){return console.warn(`Failed to send notification via service worker`,e),!1}},ot=async()=>{let e=await G();if(!e||!(`pushManager`in e)||!e.pushManager)return!1;try{return!!await e.pushManager.getSubscription()}catch{return!1}},st=async e=>{if(e?.requireHidden&&typeof document<`u`&&document.hasFocus())return!0;if(typeof Notification>`u`)return!1;if(Notification.permission==="default"&&await Notification.requestPermission()!==`granted`||Notification.permission!==`granted`)return console.warn(`Notification permission not granted`),!1;if(!tt()&&await ot()||!it(e))return!0;try{return await at(e)||new Notification(e?.title??`OpenChamber`,{body:e?.body,tag:e?.tag}),!0}catch(e){return console.warn(`Failed to send notification`,e),!1}},ct=async e=>{if(typeof window>`u`)return!1;let t=window.__OPENCHAMBER_DESKTOP__;if(!t?.invoke)return!1;try{return await t.invoke(`desktop_notify`,{payload:{title:e?.title,body:e?.body,tag:e?.tag,kind:e?.kind,sessionId:e?.sessionId,directory:e?.directory,requireHidden:e?.requireHidden}}),!0}catch(e){return console.warn(`Failed to send native notification (desktop)`,e),!1}},K=()=>({async notifyAgentCompletion(e){return await ct(e)||await st(e)},canNotify:()=>typeof window<`u`&&window.__OPENCHAMBER_DESKTOP__?.invoke?!0:typeof Notification<`u`&&Notification.permission===`granted`}),lt=()=>({async getAvailableTools(){let e=await l(`/api/experimental/tool/ids`);if(!e.ok)throw Error(`Tools API returned ${e.status} ${e.statusText}`);let t=await e.json();if(!Array.isArray(t))throw Error(`Tools API returned invalid data format`);return t.filter(e=>typeof e==`string`&&e!==`invalid`).sort()}}),q=async(e,t)=>{try{let n=await l(e,{...t,credentials:`include`,headers:{Accept:`application/json`,...t?.headers??{}}});return n.ok?await n.json():null}catch{return null}},ut=()=>({async getVapidPublicKey(){return q(`/api/push/vapid-public-key`)},async subscribe(e){return q(`/api/push/subscribe`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)})},async unsubscribe(e){return q(`/api/push/subscribe`,{method:`DELETE`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)})},async setVisibility(e){return q(`/api/push/visibility`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e),keepalive:!0})},async registerApnsToken(e){return q(`/api/push/apns-token`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)})},async unregisterApnsToken(e){return q(`/api/push/apns-token`,{method:`DELETE`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)})}}),J=async e=>await e.json().catch(()=>null),dt=({urls:e})=>({async authStatus(){let e=await l(`/api/github/auth/status`,{method:`GET`,headers:{Accept:`application/json`}}),t=await J(e);if(!e.ok||!t)throw Error(t?.error||e.statusText||`Failed to load GitHub status`);return t},async authStart(){let e=await l(`/api/github/auth/start`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify({})}),t=await J(e);if(!e.ok||!t||!(`deviceCode`in t))throw Error(t?.error||e.statusText||`Failed to start GitHub auth`);return t},async authComplete(e){let t=await l(`/api/github/auth/complete`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify({deviceCode:e})}),n=await J(t);if(!t.ok||!n)throw Error(n?.error||t.statusText||`Failed to complete GitHub auth`);return n},async authDisconnect(){let e=await l(`/api/github/auth`,{method:`DELETE`,headers:{Accept:`application/json`}}),t=await J(e);if(!e.ok)throw Error(t?.error||e.statusText||`Failed to disconnect GitHub`);return{removed:!!t?.removed}},async authActivate(e){let t=await l(`/api/github/auth/activate`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify({accountId:e})}),n=await J(t);if(!t.ok||!n)throw Error(n?.error||t.statusText||`Failed to activate GitHub account`);return n},async authSetGhCliDisabled(e){let t=await l(`/api/github/auth/gh-cli`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify({disabled:e})}),n=await J(t);if(!t.ok||!n)throw Error(n?.error||t.statusText||`Failed to update gh CLI setting`);return{disabled:!!n.disabled}},async me(){let e=await l(`/api/github/me`,{method:`GET`,headers:{Accept:`application/json`}}),t=await J(e);if(!e.ok||!t)throw Error(t?.error||e.statusText||`Failed to fetch GitHub user`);return t},async prStatus(e,t,n,r){let i=new URLSearchParams({directory:e,branch:t,...n?{remote:n}:{},...r?.force?{force:`true`}:{}}),a=await l(`/api/github/pr/status?${i.toString()}`,{method:`GET`,headers:{Accept:`application/json`}}),o=await J(a);if(!a.ok||!o)throw Error(o?.error||a.statusText||`Failed to load PR status`);return o},async prCreate(e){let t=await l(`/api/github/pr/create`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify(e)}),n=await J(t);if(!t.ok||!n)throw Error(n?.error||t.statusText||`Failed to create PR`);return n},async prUpdate(e){let t=await l(`/api/github/pr/update`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify(e)}),n=await J(t);if(!t.ok||!n)throw Error(n?.error||t.statusText||`Failed to update PR`);return n},async prMerge(e){let t=await l(`/api/github/pr/merge`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify(e)}),n=await J(t);if(!t.ok||!n)throw Error(n?.error||t.statusText||`Failed to merge PR`);return n},async prReady(e){let t=await l(`/api/github/pr/ready`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify(e)}),n=await J(t);if(!t.ok||!n)throw Error(n?.error||t.statusText||`Failed to mark PR ready`);return n},async repoUpstream(e){let t=await l(`/api/github/repo/upstream?directory=${encodeURIComponent(e)}`,{method:`GET`,headers:{Accept:`application/json`}}),n=await J(t);if(!t.ok||!n)throw Error(n?.error||t.statusText||`Failed to detect upstream repo`);return n},async repoBranches(e,t){let n=await l(`/api/github/repo/branches?owner=${encodeURIComponent(e)}&repo=${encodeURIComponent(t)}`,{method:`GET`,headers:{Accept:`application/json`}}),r=await J(n);if(!n.ok||!r)throw Error(r?.error||n.statusText||`Failed to fetch repo branches`);return r.branches??[]},async prsList(e,t){let n=t?.page??1,r=new URLSearchParams({directory:e,page:String(n)});t?.query&&r.set(`query`,t.query);let i=await l(`/api/github/pulls/list?${r.toString()}`,{method:`GET`,headers:{Accept:`application/json`}}),a=await J(i);if(!i.ok||!a)throw Error(a?.error||i.statusText||`Failed to load pull requests`);return a},async prContext(t,n,r){let i=new URLSearchParams({directory:t,number:String(n)});r?.includeDiff&&i.set(`diff`,`1`),r?.includeCheckDetails&&i.set(`checkDetails`,`1`),r?.sourceRepo?.owner&&r.sourceRepo.repo&&(i.set(`owner`,r.sourceRepo.owner),i.set(`repo`,r.sourceRepo.repo));let a=await l(e.api(`/api/github/pulls/context`,i),{method:`GET`,headers:{Accept:`application/json`}}),o=await J(a);if(!a.ok||!o)throw Error(o?.error||a.statusText||`Failed to load pull request context`);return o},async issuesList(e,t){let n=t?.page??1,r=new URLSearchParams({directory:e,page:String(n)});t?.query&&r.set(`query`,t.query);let i=await l(`/api/github/issues/list?${r.toString()}`,{method:`GET`,headers:{Accept:`application/json`}}),a=await J(i);if(!i.ok||!a)throw Error(a?.error||i.statusText||`Failed to load issues`);return a},async issueGet(t,n,r){let i=new URLSearchParams({directory:t,number:String(n)});r?.sourceRepo?.owner&&r.sourceRepo.repo&&(i.set(`owner`,r.sourceRepo.owner),i.set(`repo`,r.sourceRepo.repo));let a=await l(e.api(`/api/github/issues/get`,i),{method:`GET`,headers:{Accept:`application/json`}}),o=await J(a);if(!a.ok||!o)throw Error(o?.error||a.statusText||`Failed to load issue`);return o},async issueComments(t,n,r){let i=new URLSearchParams({directory:t,number:String(n)});r?.sourceRepo?.owner&&r.sourceRepo.repo&&(i.set(`owner`,r.sourceRepo.owner),i.set(`repo`,r.sourceRepo.repo));let a=await l(e.api(`/api/github/issues/comments`,i),{method:`GET`,headers:{Accept:`application/json`}}),o=await J(a);if(!a.ok||!o)throw Error(o?.error||a.statusText||`Failed to load issue comments`);return o}}),Y=async e=>await e.json().catch(()=>null),ft=()=>({async listClients(){let e=await l(`/api/client-auth/clients`,{method:`GET`,headers:{Accept:`application/json`}}),t=await Y(e);if(!e.ok||!t)throw Error(t?.error||e.statusText||`Failed to load remote clients`);return Array.isArray(t.clients)?t.clients:[]},async createClient(e={}){let t=await l(`/api/client-auth/clients`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify({label:e.label??``})}),n=await Y(t);if(!t.ok||!n?.client||typeof n.token!=`string`)throw Error(n?.error||t.statusText||`Failed to create remote client token`);return n},async createPairingSession(e={}){let t=await l(`/api/client-auth/pairing/sessions`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify({label:e.label??``,...e.allowedClientKinds?{allowedClientKinds:e.allowedClientKinds}:{},...e.serverUrl?{serverUrl:e.serverUrl}:{},...typeof e.includeRelay==`boolean`?{includeRelay:e.includeRelay}:{},...typeof e.includeDirect==`boolean`?{includeDirect:e.includeDirect}:{},...e.relayUrl?{relayUrl:e.relayUrl}:{},...e.sshHostId?{sshHostId:e.sshHostId}:{}})}),n=await Y(t);if(!t.ok||typeof n?.pairing?.secret!=`string`||!n?.server)throw Error(n?.error||t.statusText||`Failed to create pairing session`);return n},async listPendingPairings(){let e=await l(`/api/client-auth/pairing/sessions`,{method:`GET`,headers:{Accept:`application/json`}}),t=await Y(e);if(!e.ok||!t)throw Error(t?.error||e.statusText||`Failed to load pending pairings`);return Array.isArray(t.pending)?t.pending:[]},async getPairingTransports(){let e=await l(`/api/client-auth/pairing/transports`,{method:`GET`,headers:{Accept:`application/json`}}),t=await Y(e);if(!e.ok||!t)throw Error(t?.error||e.statusText||`Failed to load pairing transports`);return{local:t.local??null,lan:t.lan??null,relayAvailable:t.relayAvailable===!0,...typeof t.relayUrl==`string`?{relayUrl:t.relayUrl}:{},...typeof t.relayUrlLocked==`boolean`?{relayUrlLocked:t.relayUrlLocked}:{}}},async cancelPairing(e){let t=await l(`/api/client-auth/pairing/sessions/${encodeURIComponent(e)}`,{method:`DELETE`,headers:{Accept:`application/json`}}),n=await Y(t);if(!t.ok||!n)throw Error(n?.error||t.statusText||`Failed to cancel pairing`);return{cancelled:n.cancelled===!0}},async revokeClient(e){let t=await l(`/api/client-auth/clients/${encodeURIComponent(e)}`,{method:`DELETE`,headers:{Accept:`application/json`}}),n=await Y(t);if(!t.ok||!n)throw Error(n?.error||t.statusText||`Failed to revoke remote client`);return n},async purgeRevokedClients(){let e=await l(`/api/client-auth/clients`,{method:`DELETE`,headers:{Accept:`application/json`}}),t=await Y(e);if(!e.ok||!t)throw Error(t?.error||e.statusText||`Failed to clear revoked clients`);return t}}),X=e=>typeof e==`object`&&!!e&&!Array.isArray(e),Z=e=>typeof e==`number`&&Number.isFinite(e),pt=e=>{if(!X(e)||typeof e.ok!=`boolean`)return!1;if(e.ok===!0)return X(e.session)&&typeof e.session.id==`string`&&typeof e.messageID==`string`;let t=e.phase;if(typeof t!=`string`)return!1;switch(t){case`validate`:return typeof e.error==`string`&&Array.isArray(e.errors)&&e.errors.every(e=>typeof e==`string`);case`create`:return!(typeof e.error!=`string`||`status`in e&&e.status!==void 0&&!Z(e.status));case`prompt`:return X(e.session)&&typeof e.session.id==`string`&&typeof e.messageID==`string`&&typeof e.ambiguous==`boolean`&&typeof e.error==`string`&&(!(`status`in e)||e.status===void 0||Z(e.status));case`conflict`:return typeof e.error==`string`;case`unavailable`:return typeof e.error==`string`;case`internal`:return typeof e.error==`string`;default:return!1}},mt=()=>({async createWithPrompt(e,t){let n;try{n=await l(`/api/openchamber/conversations`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e),signal:t})}catch{throw Error(`Conversation request failed`)}let r;try{r=await n.json()}catch{throw Error(`Unexpected server response: invalid JSON`)}if(!pt(r))throw Error(`Unexpected server response: result shape mismatch`);return r}}),ht=()=>({api:(...t)=>e().api(...t),authenticatedAsset:(...t)=>e().authenticatedAsset(...t),auth:(...t)=>e().auth(...t),health:(...t)=>e().health(...t),rawFile:(...t)=>e().rawFile(...t),sse:(...t)=>e().sse(...t),websocket:(...t)=>e().websocket(...t)}),gt=(e={})=>{let t=e.urls??s();r(t);let n=ht();return{runtime:{platform:`web`,isDesktop:!1,isVSCode:!1,label:`web`},terminal:Ke(),git:qe(),files:Ye({urls:n,getDirectory:()=>Ie.getState().currentDirectory}),settings:Ze(),permissions:Qe(),notifications:K(),github:dt({urls:n}),push:ut(),clientAuth:ft(),tools:lt(),conversations:mt()}},Q=(e,t)=>{if(!e||!t)return!1;try{return new URL(e).origin===new URL(t).origin}catch{return!1}},$=Promise.resolve(),_t=()=>$,vt=()=>{let e=typeof window.__OPENCHAMBER_API_BASE_URL__==`string`?window.__OPENCHAMBER_API_BASE_URL__.trim():``,r=typeof window.__OPENCHAMBER_CLIENT_TOKEN__==`string`?window.__OPENCHAMBER_CLIENT_TOKEN__.trim():``,s=typeof window.__OPENCHAMBER_LOCAL_ORIGIN__==`string`?window.__OPENCHAMBER_LOCAL_ORIGIN__.trim():``,l=a({apiBaseUrl:e||void 0,realtimeBaseUrl:e||void 0});o({apiBaseUrl:e,runtimeKey:Q(e,s)?`local`:null}),t(r||null),i(window.__OPENCHAMBER_RUNTIME_HEADERS__||null),ee(e||void 0).catch(()=>{}),s&&!Q(e,s)&&Object.keys(n()).length>0&&c(s).catch(()=>{}),te();let d=window.__OPENCHAMBER_RELAY_HOST_ID__;return $=Promise.race([u(typeof d==`string`&&d?d:void 0).catch(()=>{}),new Promise(e=>{window.setTimeout(e,1e4)})]),gt({urls:l})};export{_t as n,vt as t};
|
|
1
|
+
import{F as e,G as t,H as n,I as r,K as i,N as a,O as o,P as s,U as c,W as ee}from"./useUIStore-5agS8bsW.js";import{On as te,kn as l}from"./persistence-D1lIuyqO.js";import{t as u}from"./desktopRelayRestore-CewM6-g5.js";import{A as d,B as ne,C as re,D as ie,E as ae,F as oe,G as f,J as se,K as ce,L as le,M as ue,N as de,O as fe,P as pe,Q as me,R as he,S as ge,U as p,V as m,W as h,X as g,Y as _,Z as v,_ as y,a as b,at as x,c as S,ct as C,d as w,dt as T,f as E,ft as D,g as O,gt as k,h as A,ht as j,i as M,it as N,j as P,k as F,l as I,lt as L,m as _e,mt as ve,n as ye,nt as be,o as xe,ot as Se,p as Ce,pt as we,q as Te,r as Ee,rt as De,s as Oe,st as ke,t as Ae,tt as je,u as Me,ut as Ne,v as R,w as Pe,y as Fe,yt as Ie,z as Le}from"./gitApiHttp-BxGAFLTf.js";import{a as Re,c as ze,l as Be,n as Ve,r as He,s as Ue,t as We}from"./terminalApi-DpiAJlil.js";(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var Ge=e=>{let t=e?.retry;return{maxRetries:t?.maxRetries??3,initialRetryDelay:t?.initialDelayMs??1e3,maxRetryDelay:t?.maxDelayMs??8e3,connectionTimeout:e?.connectionTimeoutMs??1e4}},Ke=()=>({async createSession(e){return He(e)},connect(e,t,n){let r=Ve(e,t.onEvent,t.onError,Ge(n));return{close:()=>r()}},async sendInput(e,t){await Be(e,t)},async resize(e){await Ue(e.sessionId,e.cols,e.rows)},async close(e){await We(e)},async restartSession(e,t){return ze(e,{cwd:t.cwd??``,cols:t.cols,rows:t.rows})},async forceKill(e){await Re(e)}}),qe=()=>({checkIsGitRepository:b,getGitStatus:pe,getGitDiff:d,getGitFileDiff:P,revertGitFile:be,stageGitFile:x,stageGitFiles:Se,unstageGitFile:T,unstageGitFiles:D,stageGitHunk:ke,unstageGitHunk:we,revertGitHunk:De,isLinkedWorktree:p,getGitBranches:F,deleteGitBranch:O,deleteRemoteBranch:Fe,removeRemote:g,generateCommitMessage:re,generatePullRequestDescription:Pe,listGitWorktrees:f,validateGitWorktree:j,createGitWorktree:A,deleteGitWorktree:R,validateWorktreeDirectory:k,canonicalizeWorktreeState:M,createGitCommit(e,t,n){return Ce(e,t,n)},gitPush:ne,gitPull:Le,gitFetch:he,listGitStashes:h,countGitStashFiles:w,stashGitChanges:L,applyGitStash:Ee,popGitStash:Te,dropGitStash:ge,checkoutBranch:xe,createBranch:E,renameBranch:v,getGitLog(e,t){return de(e,t)},getCommitFiles:ae,getCurrentGitIdentity:fe,hasLocalIdentity:m,setGitIdentity:N,getGitIdentities:ue,createGitIdentity:_e,updateGitIdentity:ve,deleteGitIdentity:y,getRemotes:le,rebase:_,abortRebase:ye,continueRebase:Me,merge:ce,abortMerge:Ae,continueMerge:I,checkoutCommit:Oe,cherryPick:S,revertCommit:je,resetToCommit:me,stash:C,stashPop:Ne,getConflictDetails:ie,worktree:{list:f,validate:j,bootstrapStatus:oe,preview:se,create:A,remove:R}}),z=e=>e.replace(/\\/g,`/`),Je=(e,t)=>({directory:z(t?.directory||t?.path||e),entries:(Array.isArray(t?.entries)?t.entries:[]).filter(e=>!!(e&&typeof e.name==`string`&&typeof e.path==`string`)).map(e=>({name:e.name,path:z(e.path),isDirectory:!!e.isDirectory}))}),B=(e,t)=>{let n=t||e?.();return n?{"x-opencode-directory":n}:void 0},Ye=({getDirectory:e})=>({async listDirectory(t,n){let r=z(t),i=new URLSearchParams;r&&i.set(`path`,r),n?.respectGitignore&&i.set(`respectGitignore`,`true`);let a=await l(`/api/fs/list`,{query:i,headers:B(e)});if(!a.ok){let e=await a.json().catch(()=>({error:a.statusText}));throw Error(e.error||`Failed to list directory`)}return Je(r,await a.json())},async search(t){let n=new URLSearchParams,r=z(t.directory);r&&n.set(`directory`,r),n.set(`query`,t.query),n.set(`dirs`,`false`),n.set(`type`,`file`),typeof t.maxResults==`number`&&Number.isFinite(t.maxResults)&&n.set(`limit`,String(t.maxResults));let i=await l(`/api/find/file`,{query:n,headers:B(e)});if(!i.ok){let e=await i.json().catch(()=>({error:i.statusText}));throw Error(e.error||`Failed to search files`)}let a=await i.json();return(Array.isArray(a)?a:[]).map(e=>({path:z(`${r}/${e}`),preview:[z(e)]}))},async createDirectory(t){let n=z(t),r=await l(`/api/fs/mkdir`,{method:`POST`,headers:{"Content-Type":`application/json`,...B(e)},body:JSON.stringify({path:n})});if(!r.ok){let e=await r.json().catch(()=>({error:r.statusText}));throw Error(e.error||`Failed to create directory`)}let i=await r.json();return{success:!!i?.success,path:typeof i?.path==`string`?z(i.path):n}},async statFile(t,n){let r=z(t),i=new URLSearchParams({path:r});n?.allowOutsideWorkspace&&i.set(`allowOutsideWorkspace`,`true`),n?.outsideFileGrant&&i.set(`outsideFileGrant`,n.outsideFileGrant);let a=await l(`/api/fs/stat`,{query:i,headers:B(e,n?.directory)});if(!a.ok){let e=await a.json().catch(()=>({error:a.statusText}));throw Error(e.error||`Failed to stat file`)}let o=await a.json().catch(()=>({}));return{path:typeof o.path==`string`?z(o.path):r,isFile:!!o.isFile,size:typeof o.size==`number`?o.size:0,mtimeMs:typeof o.mtimeMs==`number`?o.mtimeMs:void 0,isBinary:typeof o.isBinary==`boolean`?o.isBinary:void 0}},async readFile(t,n){let r=z(t),i=new URLSearchParams({path:r});n?.allowOutsideWorkspace&&i.set(`allowOutsideWorkspace`,`true`),n?.outsideFileGrant&&i.set(`outsideFileGrant`,n.outsideFileGrant),n?.optional&&i.set(`optional`,`true`);let a=await l(`/api/fs/read`,{query:i,cache:n?.optional?`no-store`:`default`,headers:B(e,n?.directory)});if(!a.ok){let e=await a.json().catch(()=>({error:a.statusText}));throw Error(e.error||`Failed to read file`)}let o=await a.text();if(n?.optional){let e=a.headers.get(`x-openchamber-file-exists`);if(e!==`true`&&e!==`false`)throw Error(`Optional file read requires an existence response header`);return{content:o,path:r,exists:e===`true`}}return{content:o,path:r,exists:!0}},async writeFile(t,n){let r=z(t),i=await l(`/api/fs/write`,{method:`POST`,headers:{"Content-Type":`application/json`,...B(e)},body:JSON.stringify({path:r,content:n})});if(!i.ok){let e=await i.json().catch(()=>({error:i.statusText}));throw Error(e.error||`Failed to write file`)}let a=await i.json().catch(()=>({}));return{success:!!a.success,path:typeof a.path==`string`?z(a.path):r}},async delete(t){let n=z(t),r=await l(`/api/fs/delete`,{method:`POST`,headers:{"Content-Type":`application/json`,...B(e)},body:JSON.stringify({path:n})});if(!r.ok){let e=await r.json().catch(()=>({error:r.statusText}));throw Error(e.error||`Failed to delete file`)}return{success:!!(await r.json().catch(()=>({}))).success}},async rename(t,n){let r=await l(`/api/fs/rename`,{method:`POST`,headers:{"Content-Type":`application/json`,...B(e)},body:JSON.stringify({oldPath:t,newPath:n})});if(!r.ok){let e=await r.json().catch(()=>({error:r.statusText}));throw Error(e.error||`Failed to rename file`)}let i=await r.json().catch(()=>({}));return{success:!!i.success,path:typeof i.path==`string`?z(i.path):n}},async revealPath(t){let n=await l(`/api/fs/reveal`,{method:`POST`,headers:{"Content-Type":`application/json`,...B(e)},body:JSON.stringify({path:z(t)})});if(!n.ok){let e=await n.json().catch(()=>({error:n.statusText}));throw Error(e.error||`Failed to reveal path`)}return{success:!!(await n.json().catch(()=>({}))).success}},async downloadFile(t){let n=z(t),r=await l(`/api/fs/raw`,{query:{path:n,download:!0},headers:B(e)});if(!r.ok)throw Error(`Download failed (${r.status})`);let i=await r.blob(),a=URL.createObjectURL(i),o=document.createElement(`a`);o.href=a,o.download=n.split(`/`).pop()||`file`,document.body.appendChild(o),o.click(),document.body.removeChild(o),setTimeout(()=>URL.revokeObjectURL(a),100)}}),V=`/api/config/settings`,Xe=`/api/config/reload`,H=e=>!e||typeof e!=`object`?{}:e,Ze=()=>({async load(){let e=await l(V,{method:`GET`,headers:{Accept:`application/json`}});if(!e.ok)throw Error(`Failed to load settings: ${e.statusText}`);return{settings:H(await e.json().catch(()=>({}))),source:`web`}},async save(e){let t=await l(V,{method:`PUT`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify(e)});if(!t.ok){let e=await t.json().catch(()=>({error:t.statusText}));throw Error(e.error||`Failed to save settings`)}return H(await t.json().catch(()=>({})))},async restartOpenCode(){let e=await l(Xe,{method:`POST`});if(!e.ok){let t=await e.json().catch(()=>({error:e.statusText}));throw Error(t.error||`Failed to restart OpenCode`)}return{restarted:!0}}}),Qe=()=>({async requestDirectoryAccess(e){return{success:!0,path:e.path}},async startAccessingDirectory(e){return{success:!0}},async stopAccessingDirectory(e){return{success:!0}}}),$e=1500,U=5e3,et=`openchamber-notification-claim:`,W=new Map,tt=()=>typeof document>`u`||document.visibilityState===`visible`&&document.hasFocus(),nt=e=>(typeof e?.tag==`string`?e.tag.trim():``)||[e?.sessionId,e?.kind,e?.title,e?.body].filter(e=>typeof e==`string`&&e.trim().length>0).map(e=>e.trim()).join(`|`),rt=e=>{for(let[t,n]of W)e-n>U&&W.delete(t)},it=e=>{let t=nt(e);if(!t)return!0;let n=Date.now();if(rt(n),n-(W.get(t)??0)<U)return!1;try{if(typeof window<`u`&&window.localStorage){let e=`${et}${t}`,r=Number(window.localStorage.getItem(e)??`0`);if(Number.isFinite(r)&&n-r<U)return W.set(t,r),!1;Number.isFinite(r)&&r>0&&window.localStorage.removeItem(e),window.localStorage.setItem(e,String(n))}}catch{}return W.set(t,n),!0},G=async()=>{if(typeof navigator>`u`||!(`serviceWorker`in navigator))return null;let e=null;try{e=await navigator.serviceWorker.getRegistration()??null}catch{e=null}if(e?.active)return e;if(!e)return null;try{return await Promise.race([navigator.serviceWorker.ready,new Promise(e=>{setTimeout(()=>e(null),$e)})])??e}catch{return e}},at=async e=>{let t=await G();if(!t||typeof t.showNotification!=`function`)return!1;try{return await t.showNotification(e?.title??`OpenChamber`,{body:e?.body,tag:e?.tag}),!0}catch(e){return console.warn(`Failed to send notification via service worker`,e),!1}},ot=async()=>{let e=await G();if(!e||!(`pushManager`in e)||!e.pushManager)return!1;try{return!!await e.pushManager.getSubscription()}catch{return!1}},st=async e=>{if(e?.requireHidden&&typeof document<`u`&&document.hasFocus())return!0;if(typeof Notification>`u`)return!1;if(Notification.permission==="default"&&await Notification.requestPermission()!==`granted`||Notification.permission!==`granted`)return console.warn(`Notification permission not granted`),!1;if(!tt()&&await ot()||!it(e))return!0;try{return await at(e)||new Notification(e?.title??`OpenChamber`,{body:e?.body,tag:e?.tag}),!0}catch(e){return console.warn(`Failed to send notification`,e),!1}},ct=async e=>{if(typeof window>`u`)return!1;let t=window.__OPENCHAMBER_DESKTOP__;if(!t?.invoke)return!1;try{return await t.invoke(`desktop_notify`,{payload:{title:e?.title,body:e?.body,tag:e?.tag,kind:e?.kind,sessionId:e?.sessionId,directory:e?.directory,requireHidden:e?.requireHidden}}),!0}catch(e){return console.warn(`Failed to send native notification (desktop)`,e),!1}},K=()=>({async notifyAgentCompletion(e){return await ct(e)||await st(e)},canNotify:()=>typeof window<`u`&&window.__OPENCHAMBER_DESKTOP__?.invoke?!0:typeof Notification<`u`&&Notification.permission===`granted`}),lt=()=>({async getAvailableTools(){let e=await l(`/api/experimental/tool/ids`);if(!e.ok)throw Error(`Tools API returned ${e.status} ${e.statusText}`);let t=await e.json();if(!Array.isArray(t))throw Error(`Tools API returned invalid data format`);return t.filter(e=>typeof e==`string`&&e!==`invalid`).sort()}}),q=async(e,t)=>{try{let n=await l(e,{...t,credentials:`include`,headers:{Accept:`application/json`,...t?.headers??{}}});return n.ok?await n.json():null}catch{return null}},ut=()=>({async getVapidPublicKey(){return q(`/api/push/vapid-public-key`)},async subscribe(e){return q(`/api/push/subscribe`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)})},async unsubscribe(e){return q(`/api/push/subscribe`,{method:`DELETE`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)})},async setVisibility(e){return q(`/api/push/visibility`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e),keepalive:!0})},async registerApnsToken(e){return q(`/api/push/apns-token`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)})},async unregisterApnsToken(e){return q(`/api/push/apns-token`,{method:`DELETE`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)})}}),J=async e=>await e.json().catch(()=>null),dt=({urls:e})=>({async authStatus(){let e=await l(`/api/github/auth/status`,{method:`GET`,headers:{Accept:`application/json`}}),t=await J(e);if(!e.ok||!t)throw Error(t?.error||e.statusText||`Failed to load GitHub status`);return t},async authStart(){let e=await l(`/api/github/auth/start`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify({})}),t=await J(e);if(!e.ok||!t||!(`deviceCode`in t))throw Error(t?.error||e.statusText||`Failed to start GitHub auth`);return t},async authComplete(e){let t=await l(`/api/github/auth/complete`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify({deviceCode:e})}),n=await J(t);if(!t.ok||!n)throw Error(n?.error||t.statusText||`Failed to complete GitHub auth`);return n},async authDisconnect(){let e=await l(`/api/github/auth`,{method:`DELETE`,headers:{Accept:`application/json`}}),t=await J(e);if(!e.ok)throw Error(t?.error||e.statusText||`Failed to disconnect GitHub`);return{removed:!!t?.removed}},async authActivate(e){let t=await l(`/api/github/auth/activate`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify({accountId:e})}),n=await J(t);if(!t.ok||!n)throw Error(n?.error||t.statusText||`Failed to activate GitHub account`);return n},async authSetGhCliDisabled(e){let t=await l(`/api/github/auth/gh-cli`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify({disabled:e})}),n=await J(t);if(!t.ok||!n)throw Error(n?.error||t.statusText||`Failed to update gh CLI setting`);return{disabled:!!n.disabled}},async me(){let e=await l(`/api/github/me`,{method:`GET`,headers:{Accept:`application/json`}}),t=await J(e);if(!e.ok||!t)throw Error(t?.error||e.statusText||`Failed to fetch GitHub user`);return t},async prStatus(e,t,n,r){let i=new URLSearchParams({directory:e,branch:t,...n?{remote:n}:{},...r?.force?{force:`true`}:{}}),a=await l(`/api/github/pr/status?${i.toString()}`,{method:`GET`,headers:{Accept:`application/json`}}),o=await J(a);if(!a.ok||!o)throw Error(o?.error||a.statusText||`Failed to load PR status`);return o},async prCreate(e){let t=await l(`/api/github/pr/create`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify(e)}),n=await J(t);if(!t.ok||!n)throw Error(n?.error||t.statusText||`Failed to create PR`);return n},async prUpdate(e){let t=await l(`/api/github/pr/update`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify(e)}),n=await J(t);if(!t.ok||!n)throw Error(n?.error||t.statusText||`Failed to update PR`);return n},async prMerge(e){let t=await l(`/api/github/pr/merge`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify(e)}),n=await J(t);if(!t.ok||!n)throw Error(n?.error||t.statusText||`Failed to merge PR`);return n},async prReady(e){let t=await l(`/api/github/pr/ready`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify(e)}),n=await J(t);if(!t.ok||!n)throw Error(n?.error||t.statusText||`Failed to mark PR ready`);return n},async repoUpstream(e){let t=await l(`/api/github/repo/upstream?directory=${encodeURIComponent(e)}`,{method:`GET`,headers:{Accept:`application/json`}}),n=await J(t);if(!t.ok||!n)throw Error(n?.error||t.statusText||`Failed to detect upstream repo`);return n},async repoBranches(e,t){let n=await l(`/api/github/repo/branches?owner=${encodeURIComponent(e)}&repo=${encodeURIComponent(t)}`,{method:`GET`,headers:{Accept:`application/json`}}),r=await J(n);if(!n.ok||!r)throw Error(r?.error||n.statusText||`Failed to fetch repo branches`);return r.branches??[]},async prsList(e,t){let n=t?.page??1,r=new URLSearchParams({directory:e,page:String(n)});t?.query&&r.set(`query`,t.query);let i=await l(`/api/github/pulls/list?${r.toString()}`,{method:`GET`,headers:{Accept:`application/json`}}),a=await J(i);if(!i.ok||!a)throw Error(a?.error||i.statusText||`Failed to load pull requests`);return a},async prContext(t,n,r){let i=new URLSearchParams({directory:t,number:String(n)});r?.includeDiff&&i.set(`diff`,`1`),r?.includeCheckDetails&&i.set(`checkDetails`,`1`),r?.sourceRepo?.owner&&r.sourceRepo.repo&&(i.set(`owner`,r.sourceRepo.owner),i.set(`repo`,r.sourceRepo.repo));let a=await l(e.api(`/api/github/pulls/context`,i),{method:`GET`,headers:{Accept:`application/json`}}),o=await J(a);if(!a.ok||!o)throw Error(o?.error||a.statusText||`Failed to load pull request context`);return o},async issuesList(e,t){let n=t?.page??1,r=new URLSearchParams({directory:e,page:String(n)});t?.query&&r.set(`query`,t.query);let i=await l(`/api/github/issues/list?${r.toString()}`,{method:`GET`,headers:{Accept:`application/json`}}),a=await J(i);if(!i.ok||!a)throw Error(a?.error||i.statusText||`Failed to load issues`);return a},async issueGet(t,n,r){let i=new URLSearchParams({directory:t,number:String(n)});r?.sourceRepo?.owner&&r.sourceRepo.repo&&(i.set(`owner`,r.sourceRepo.owner),i.set(`repo`,r.sourceRepo.repo));let a=await l(e.api(`/api/github/issues/get`,i),{method:`GET`,headers:{Accept:`application/json`}}),o=await J(a);if(!a.ok||!o)throw Error(o?.error||a.statusText||`Failed to load issue`);return o},async issueComments(t,n,r){let i=new URLSearchParams({directory:t,number:String(n)});r?.sourceRepo?.owner&&r.sourceRepo.repo&&(i.set(`owner`,r.sourceRepo.owner),i.set(`repo`,r.sourceRepo.repo));let a=await l(e.api(`/api/github/issues/comments`,i),{method:`GET`,headers:{Accept:`application/json`}}),o=await J(a);if(!a.ok||!o)throw Error(o?.error||a.statusText||`Failed to load issue comments`);return o}}),Y=async e=>await e.json().catch(()=>null),ft=()=>({async listClients(){let e=await l(`/api/client-auth/clients`,{method:`GET`,headers:{Accept:`application/json`}}),t=await Y(e);if(!e.ok||!t)throw Error(t?.error||e.statusText||`Failed to load remote clients`);return Array.isArray(t.clients)?t.clients:[]},async createClient(e={}){let t=await l(`/api/client-auth/clients`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify({label:e.label??``})}),n=await Y(t);if(!t.ok||!n?.client||typeof n.token!=`string`)throw Error(n?.error||t.statusText||`Failed to create remote client token`);return n},async createPairingSession(e={}){let t=await l(`/api/client-auth/pairing/sessions`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify({label:e.label??``,...e.allowedClientKinds?{allowedClientKinds:e.allowedClientKinds}:{},...e.serverUrl?{serverUrl:e.serverUrl}:{},...typeof e.includeRelay==`boolean`?{includeRelay:e.includeRelay}:{},...typeof e.includeDirect==`boolean`?{includeDirect:e.includeDirect}:{},...e.relayUrl?{relayUrl:e.relayUrl}:{},...e.sshHostId?{sshHostId:e.sshHostId}:{}})}),n=await Y(t);if(!t.ok||typeof n?.pairing?.secret!=`string`||!n?.server)throw Error(n?.error||t.statusText||`Failed to create pairing session`);return n},async listPendingPairings(){let e=await l(`/api/client-auth/pairing/sessions`,{method:`GET`,headers:{Accept:`application/json`}}),t=await Y(e);if(!e.ok||!t)throw Error(t?.error||e.statusText||`Failed to load pending pairings`);return Array.isArray(t.pending)?t.pending:[]},async getPairingTransports(){let e=await l(`/api/client-auth/pairing/transports`,{method:`GET`,headers:{Accept:`application/json`}}),t=await Y(e);if(!e.ok||!t)throw Error(t?.error||e.statusText||`Failed to load pairing transports`);return{local:t.local??null,lan:t.lan??null,relayAvailable:t.relayAvailable===!0,...typeof t.relayUrl==`string`?{relayUrl:t.relayUrl}:{},...typeof t.relayUrlLocked==`boolean`?{relayUrlLocked:t.relayUrlLocked}:{}}},async cancelPairing(e){let t=await l(`/api/client-auth/pairing/sessions/${encodeURIComponent(e)}`,{method:`DELETE`,headers:{Accept:`application/json`}}),n=await Y(t);if(!t.ok||!n)throw Error(n?.error||t.statusText||`Failed to cancel pairing`);return{cancelled:n.cancelled===!0}},async revokeClient(e){let t=await l(`/api/client-auth/clients/${encodeURIComponent(e)}`,{method:`DELETE`,headers:{Accept:`application/json`}}),n=await Y(t);if(!t.ok||!n)throw Error(n?.error||t.statusText||`Failed to revoke remote client`);return n},async purgeRevokedClients(){let e=await l(`/api/client-auth/clients`,{method:`DELETE`,headers:{Accept:`application/json`}}),t=await Y(e);if(!e.ok||!t)throw Error(t?.error||e.statusText||`Failed to clear revoked clients`);return t}}),X=e=>typeof e==`object`&&!!e&&!Array.isArray(e),Z=e=>typeof e==`number`&&Number.isFinite(e),pt=e=>{if(!X(e)||typeof e.ok!=`boolean`)return!1;if(e.ok===!0)return X(e.session)&&typeof e.session.id==`string`&&typeof e.messageID==`string`;let t=e.phase;if(typeof t!=`string`)return!1;switch(t){case`validate`:return typeof e.error==`string`&&Array.isArray(e.errors)&&e.errors.every(e=>typeof e==`string`);case`create`:return!(typeof e.error!=`string`||`status`in e&&e.status!==void 0&&!Z(e.status));case`prompt`:return X(e.session)&&typeof e.session.id==`string`&&typeof e.messageID==`string`&&typeof e.ambiguous==`boolean`&&typeof e.error==`string`&&(!(`status`in e)||e.status===void 0||Z(e.status));case`conflict`:return typeof e.error==`string`;case`unavailable`:return typeof e.error==`string`;case`internal`:return typeof e.error==`string`;default:return!1}},mt=()=>({async createWithPrompt(e,t){let n;try{n=await l(`/api/openchamber/conversations`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e),signal:t})}catch{throw Error(`Conversation request failed`)}let r;try{r=await n.json()}catch{throw Error(`Unexpected server response: invalid JSON`)}if(!pt(r))throw Error(`Unexpected server response: result shape mismatch`);return r}}),ht=()=>({api:(...t)=>e().api(...t),authenticatedAsset:(...t)=>e().authenticatedAsset(...t),auth:(...t)=>e().auth(...t),health:(...t)=>e().health(...t),rawFile:(...t)=>e().rawFile(...t),sse:(...t)=>e().sse(...t),websocket:(...t)=>e().websocket(...t)}),gt=(e={})=>{let t=e.urls??s();r(t);let n=ht();return{runtime:{platform:`web`,isDesktop:!1,isVSCode:!1,label:`web`},terminal:Ke(),git:qe(),files:Ye({urls:n,getDirectory:()=>Ie.getState().currentDirectory}),settings:Ze(),permissions:Qe(),notifications:K(),github:dt({urls:n}),push:ut(),clientAuth:ft(),tools:lt(),conversations:mt()}},Q=(e,t)=>{if(!e||!t)return!1;try{return new URL(e).origin===new URL(t).origin}catch{return!1}},$=Promise.resolve(),_t=()=>$,vt=()=>{let e=typeof window.__OPENCHAMBER_API_BASE_URL__==`string`?window.__OPENCHAMBER_API_BASE_URL__.trim():``,r=typeof window.__OPENCHAMBER_CLIENT_TOKEN__==`string`?window.__OPENCHAMBER_CLIENT_TOKEN__.trim():``,s=typeof window.__OPENCHAMBER_LOCAL_ORIGIN__==`string`?window.__OPENCHAMBER_LOCAL_ORIGIN__.trim():``,l=a({apiBaseUrl:e||void 0,realtimeBaseUrl:e||void 0});o({apiBaseUrl:e,runtimeKey:Q(e,s)?`local`:null}),t(r||null),i(window.__OPENCHAMBER_RUNTIME_HEADERS__||null),ee(e||void 0).catch(()=>{}),s&&!Q(e,s)&&Object.keys(n()).length>0&&c(s).catch(()=>{}),te();let d=window.__OPENCHAMBER_RELAY_HOST_ID__;return $=Promise.race([u(typeof d==`string`&&d?d:void 0).catch(()=>{}),new Promise(e=>{window.setTimeout(e,1e4)})]),gt({urls:l})};export{_t as n,vt as t};
|