antechamber 1.0.40 → 2.0.1
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/CHANGELOG.md +126 -0
- package/README.md +88 -141
- package/bin/opencode-antechamber +14 -4
- package/dist/approvals.d.ts +9 -1
- package/dist/approvals.js +10 -2
- package/dist/catalog.d.ts +13 -2
- package/dist/catalog.js +88 -52
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +1 -1
- package/dist/commands/context.d.ts +5 -2
- package/dist/commands/context.js +8 -4
- package/dist/commands/doctor.js +4 -3
- package/dist/commands/setup.js +9 -28
- package/dist/config.d.ts +6 -2
- package/dist/config.js +18 -4
- package/dist/file-watch.d.ts +35 -0
- package/dist/file-watch.js +163 -0
- package/dist/latency.d.ts +10 -0
- package/dist/latency.js +115 -0
- package/dist/misc-routes.js +14 -12
- package/dist/pi-event-translation.js +44 -2
- package/dist/route-services.d.ts +8 -3
- package/dist/routes-v1.d.ts +1 -1
- package/dist/routes-v1.js +29 -418
- package/dist/routes-v2.js +252 -34
- package/dist/self-update.d.ts +2 -1
- package/dist/self-update.js +5 -1
- package/dist/server.d.ts +17 -3
- package/dist/server.js +191 -18
- package/dist/session-commands.d.ts +3 -1
- package/dist/session-commands.js +13 -7
- package/dist/session-history.js +3 -0
- package/dist/session-store.d.ts +19 -10
- package/dist/session-store.js +266 -128
- package/dist/session-tree.d.ts +15 -1
- package/dist/session-tree.js +2 -2
- package/dist/sessions.d.ts +85 -1
- package/dist/sessions.js +238 -10
- package/dist/sse.d.ts +0 -2
- package/dist/sse.js +13 -46
- package/dist/text-generation.d.ts +20 -0
- package/dist/text-generation.js +93 -0
- package/dist/tool-map.js +1 -3
- package/dist/types.d.ts +60 -0
- package/dist/v2.d.ts +8 -1
- package/dist/v2.js +24 -4
- package/dist/work-status.js +1 -1
- package/extensions/antechamber/README.md +100 -0
- package/extensions/antechamber/bin/opencode-antechamber +42 -0
- package/extensions/{omo-dag/docs/DESIGN.md → antechamber/docs/GRAPH.md} +5 -5
- package/extensions/{omo-work/docs/DESIGN.md → antechamber/docs/WORK.md} +3 -3
- package/extensions/antechamber/package.json +60 -0
- package/extensions/{omo-dag → antechamber}/panel/index.html +8 -1
- package/extensions/antechamber/panel/main.js +261 -0
- package/extensions/antechamber/runtime/launcher.js +201 -0
- package/extensions/antechamber/service/main.js +884 -0
- package/package.json +75 -26
- package/extensions/omo-compat/README.md +0 -48
- package/extensions/omo-compat/icon.svg +0 -1
- package/extensions/omo-compat/package.json +0 -43
- package/extensions/omo-dag/README.md +0 -167
- package/extensions/omo-dag/package.json +0 -33
- package/extensions/omo-dag/panel/main.js +0 -176
- package/extensions/omo-dag/service/main.js +0 -457
- package/extensions/omo-work/README.md +0 -88
- package/extensions/omo-work/package.json +0 -30
- package/extensions/omo-work/service/main.js +0 -149
- /package/extensions/{omo-dag → antechamber}/icon.svg +0 -0
- /package/extensions/{omo-work → antechamber}/status/index.html +0 -0
- /package/extensions/{omo-work → antechamber}/status/main.js +0 -0
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
"use strict";(()=>{var S="openchamber.sdk";var Ne="data-oc-scrolling",it=`
|
|
2
|
+
:root {
|
|
3
|
+
/* Quiet at rest like the app's own thumbs; hover gives a clear grab target. */
|
|
4
|
+
--oc-scrollbar-thumb: color-mix(in srgb, var(--oc-muted, currentColor) 18%, transparent);
|
|
5
|
+
--oc-scrollbar-thumb-hover: color-mix(in srgb, var(--oc-muted, currentColor) 36%, transparent);
|
|
6
|
+
scrollbar-gutter: stable;
|
|
7
|
+
}
|
|
8
|
+
* {
|
|
9
|
+
scrollbar-width: thin;
|
|
10
|
+
scrollbar-color: transparent transparent;
|
|
11
|
+
}
|
|
12
|
+
:hover, [${Ne}] {
|
|
13
|
+
scrollbar-color: var(--oc-scrollbar-thumb) transparent;
|
|
14
|
+
}
|
|
15
|
+
/* Chromium's standard scrollbar properties otherwise override its pseudo-elements. */
|
|
16
|
+
@supports selector(::-webkit-scrollbar) {
|
|
17
|
+
*, :hover, [${Ne}] { scrollbar-width: auto; scrollbar-color: auto; }
|
|
18
|
+
::-webkit-scrollbar { width: 6px; height: 6px; background: transparent; }
|
|
19
|
+
::-webkit-scrollbar-track { background: transparent; }
|
|
20
|
+
::-webkit-scrollbar-thumb {
|
|
21
|
+
background: transparent;
|
|
22
|
+
border-radius: 999px;
|
|
23
|
+
min-width: 24px;
|
|
24
|
+
min-height: 24px;
|
|
25
|
+
}
|
|
26
|
+
:hover::-webkit-scrollbar-thumb, [${Ne}]::-webkit-scrollbar-thumb { background: var(--oc-scrollbar-thumb); }
|
|
27
|
+
::-webkit-scrollbar-thumb:hover { background: var(--oc-scrollbar-thumb-hover); }
|
|
28
|
+
::-webkit-scrollbar-corner { background: transparent; }
|
|
29
|
+
::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
|
|
30
|
+
}
|
|
31
|
+
@media (forced-colors: active) {
|
|
32
|
+
*, :hover, [${Ne}] { scrollbar-color: auto; }
|
|
33
|
+
::-webkit-scrollbar-thumb, ::-webkit-scrollbar-thumb:hover { background: CanvasText; }
|
|
34
|
+
}
|
|
35
|
+
`;function fo(e){let t=e.documentElement;if(t.hasAttribute("data-oc-scrollbar-activity"))return;t.setAttribute("data-oc-scrollbar-activity","");let r=new WeakMap;e.addEventListener("scroll",s=>{let c=s.target===e?t:s.target;if(!(c instanceof Element))return;c.hasAttribute("data-oc-scrolling")||c.setAttribute("data-oc-scrolling","");let u=r.get(c);u!==void 0&&clearTimeout(u),r.set(c,setTimeout(()=>{r.delete(c),c.removeAttribute("data-oc-scrolling")},1e3))},{capture:!0,passive:!0})}var En=`(${fo.toString()})(document);`;var _o=/^[a-z][a-z0-9-]{0,39}$/;var Eo=e=>Object(e)===e&&!Array.isArray(e),at=(e,t)=>Object.keys(e).every(r=>t.includes(r)),ho=e=>String(e)===e&&e.length>=1&&e.length<=60,mo=e=>String(e)===e&&e.length>=1&&e.length<=80,So=e=>{if(!Array.isArray(e)||e.length>4)return!1;let t=new Set;for(let r of e){if(!Eo(r)||!_o.test(r.id)||!ho(r.label)||r.disabled!==void 0&&r.disabled!==!0&&r.disabled!==!1||t.has(r.id))return!1;if(t.add(r.id),r.kind==="button"){if(!at(r,["kind","id","label","disabled"]))return!1;continue}if(r.kind!=="select"||!at(r,["kind","id","label","value","options","disabled"])||!mo(r.value)||!Array.isArray(r.options)||r.options.length<1||r.options.length>16)return!1;let s=new Set;for(let c of r.options){if(!Eo(c)||!at(c,["value","label"])||!mo(c.value)||!ho(c.label)||s.has(c.value))return!1;s.add(c.value)}if(!s.has(r.value))return!1}return!0};var ct=e=>"bytes"in e?e.bytes.byteLength:e.content.length,To=(e,t)=>{if(e.path!==t.path||e.readOnly!==t.readOnly)return!1;if(e.encoding==="text"||t.encoding==="text")return e.encoding==="text"&&t.encoding==="text"&&e.content===t.content;if(e.bytes.byteLength!==t.bytes.byteLength)return!1;for(let r=0;r<e.bytes.byteLength;r+=1)if(e.bytes[r]!==t.bytes[r])return!1;return!0};var go=/^[A-Za-z0-9_-]{1,80}$/;var xo=["left","right","top","bottom"];var bo=(e,t=0,r={remaining:16e3})=>{if(--r.remaining<0||t>=32)return!1;if(e===null)return!0;let s=Array.isArray(e)?e:Object(e)===e?Object.values(e):[];for(let c of s)if(!bo(c,t+1,r))return!1;return!0},dt=e=>{if(e===null||e===!0||e===!1)return!0;if(Array.isArray(e))return Object.keys(e).every(t=>/^(0|[1-9]\d*)$/.test(t)&&Number(t)<e.length)&&e.every(dt);if(Object(e)===e){let t=Object.getPrototypeOf(e);return(t===null||t===Object.prototype)&&Object.values(e).every(dt)}return String(e)===e||Number.isFinite(e)},lt=e=>{try{return String(e.id)!==e.id||!go.test(e.id)||!Number.isFinite(e.anchor.x)||Math.abs(e.anchor.x)>1e5||!Number.isFinite(e.anchor.y)||Math.abs(e.anchor.y)>1e5||!Number.isFinite(e.anchor.width)||!Number.isFinite(e.anchor.height)||e.anchor.width<=0||e.anchor.height<=0||e.anchor.width>1e5||e.anchor.height>1e5||!Number.isInteger(e.width)||e.width<160||e.width>640||!Number.isInteger(e.height)||e.height<48||e.height>480||e.side!==void 0&&!xo.includes(e.side)||e.focus!==void 0&&e.focus!==!0&&e.focus!==!1||!bo(e.data)||!dt(e.data)?!1:JSON.stringify(e.data).length<=16e3}catch{return!1}};var ko=["file","directory","other","missing"],ut=e=>!!(e&&"sessionId"in e),ft=e=>!!(e&&"sent"in e&&!("sessionId"in e));var yo=/^[0-9a-f]{7,64}$/i,Et=e=>yo.test(e),Pe=500,De=32e3,Oo=16e3,vo=128,wo=200,Ro=2e3,Lo=16e3,Mo=80,Io=200,Co=16e3;var Uo=2e3;var ht=2e4,He=1024,$e=2e6;var Fe=64e3,Xe=8e3,mt=4e3;var _t=96e4,hn=60*6e4;var Go=999,No=1e4,be=500,Po=["HOST_UNAVAILABLE","HOST_TIMEOUT","HOST_REJECTED","DISCONNECTED","DISABLED","BAD_PATH","NO_INTEGRATION","NO_SERVICE","SERVICE_FAILED","REQUEST_FAILED","RESPONSE_TOO_LARGE","NO_SESSION","SESSION_BUSY","NOT_GRANTED","NO_DIRECTORY","NOT_FOUND","FILE_TOO_LARGE","DENIED","NO_MODEL","MODEL_FAILED","UNSUPPORTED"],Do=["stopped","starting","ready","failed"],mn=new Set(Po),Ho=e=>mn.has(e),$o=e=>e&&Ho(e)?e:"HOST_REJECTED",le=e=>e===void 0?!1:e===null||e===!0||e===!1||String(e)===e?!0:Number(e)===e?Number.isFinite(e):Array.isArray(e)?e.every(le):Object(e)===e?Object.values(e).every(le):!1,Fo=e=>le(e)&&JSON.stringify(e).length<=Co,Ao=e=>e?.trim().slice(0,Io)??"",pe=e=>{let t=e.id.trim().slice(0,vo),r=e.title.trim().slice(0,wo),s=e.url.trim().slice(0,Ro),c=e.text?.trim().slice(0,Lo),u=e.author?.trim().slice(0,Mo),i=e.kind==="pull"?"pull":"issue",f={providerId:e.providerId.trim(),id:t,title:r||t,url:s,kind:i};if(c&&(f.text=c),u&&(f.author=u),i==="pull"){let x=Ao(e.branches?.head),w=Ao(e.branches?.base);x&&w&&(f.branches={head:x,base:w})}return Fo(e.data)&&(f.data=e.data),f},St=e=>{let t=pe(e);return e.projectId&&(t.projectId=e.projectId),e.navigation&&(t.navigation=e.navigation),e.worktree&&(t.worktree=e.worktree),t},Tt=e=>{let t={text:e.text.trim().slice(0,Oo)};return e.send&&(t.send=!0),t},gt=e=>e===null||!Number.isFinite(e)?null:Math.min(Go,Math.max(0,Math.round(e))),xt=e=>Number.isFinite(e)?Math.min(No,Math.max(0,Math.ceil(e))):0;var ue=e=>e.length>0&&e.length<=He&&!e.includes("\0")&&!e.includes("\\");var Be=e=>!e.startsWith("/")||e.includes("\0")||e.includes("\\")||e.includes("://")||e.length>Uo?!1:!e.split("/").some(r=>r==="."||r===".."),_n=new Set(Do),bt=e=>!!(e&&"status"in e&&_n.has(String(e.status))&&!("body"in e)),Ve=e=>!!(e&&"status"in e&&"body"in e&&Number.isInteger(e.status)),At=e=>!!(e&&"content"in e&&String(e.content)===e.content),kt=e=>!!(e&&"written"in e&&e.written===!0),yt=e=>!!(e&&"entries"in e&&Array.isArray(e.entries)),Sn=new Set(ko),Ot=e=>!!(e&&"kind"in e&&"size"in e&&Sn.has(String(e.kind))&&Number.isFinite(e.size)),vt=e=>!!(e&&"text"in e&&String(e.text)===e.text&&!("status"in e)),Tn=new Set(["workspace","shells","ready","directory","session","connection","settings","session-lifecycle","item","resolve","action","status-control-event","popover-closed","file-open","file-snapshot","file-saved","generate-late"]),gn=e=>Object(e)===e?e:null,pt=e=>String(e)===e&&e.length>0,xn=e=>{if(!pt(e.id))return null;if(e.ok===!0){let t={channel:S,v:1,type:"result",id:e.id,ok:!0};return Object(e.payload)===e.payload&&(t.payload=e.payload),t}return e.ok===!1&&pt(e.error)?{channel:S,v:1,type:"result",id:e.id,ok:!1,error:e.error,code:$o(pt(e.code)?e.code:void 0)}:null},wt=e=>{let t=gn(e);return!t||t.channel!==S||t.v!==1?null:t.type==="result"?xn(t):!Tn.has(String(t.type))||Object(t.payload)!==t.payload?null:t};var Xo=e=>"key"in e&&"metaKey"in e&&"ctrlKey"in e,bn=e=>(e.metaKey||e.ctrlKey)&&!e.altKey&&!e.shiftKey&&e.key.toLowerCase()==="s",p=class extends Error{code;constructor(t,r){super(r),this.name="HostRequestError",this.code=t}},Bo=()=>Promise.reject(new p("BAD_PATH",'Request path must start with "/" and stay on the declared origin.')),ze=()=>Promise.reject(new p("BAD_PATH",`File path must be 1 to ${He} characters without NUL or backslash.`)),je=e=>{if(e!==void 0){if(Object(e)!==e||Array.isArray(e)||e.scope!==void 0&&e.scope!=="instance"&&e.scope!=="device")throw new p("HOST_REJECTED",'Storage scope must be "instance" or "device".');return e.scope==="device"?"device":void 0}},_=e=>(e.value+=1,`oc-${e.value}`),Ct=(e={})=>{let t=e.target??("window"in globalThis?window:null);if(!t)throw new p("HOST_UNAVAILABLE","No window. connectHost runs in a browser frame.");let r=e.acceptSource??(o=>o===t.parent),s=e.requestTimeoutMs??ht,c=new Set,u=new Set,i=new Set,f=new Set,x=new Set,w=new Set,a=new Set,b=new Set,g=new Set,A=new Set,z=[],oe=null,re=null,Me=new Set,Ie=new Set,Se=null,Te=null,ot=!1,ae=new Map,ce=new Map,de=new Map,J=!1,m={value:0},E=null,q=null,ge=!1,xe=!1,eo=null,to=o=>o?{sessionId:o.id,phase:o.busy?"started":"completed"}:null,V=o=>{t.parent.postMessage(o,"*")},oo=()=>{J||t.parent===t||A.size===0||E?.features?.lateGenerateResults!==!0||V({channel:S,v:1,type:"generate-late-listen"})},I=(o,n)=>{for(let d of o)try{d(n)}catch(l){console.error(l)}},no=o=>{if(!(o instanceof MessageEvent)||!r(o.source))return;let n=wt(o.data);if(!n)return;if(n.type==="workspace"){let l=ce.get(n.payload.subscriptionId);l&&I([l],n.payload.snapshot);return}if(n.type==="shells"){let l=de.get(n.payload.subscriptionId);l&&I([l],n.payload.snapshot);return}if(n.type==="ready"){E=n.payload,q=to(n.payload.session),I(c,n.payload),I(u,n.payload.directory),I(i,n.payload.session),q&&I(f,q),I(x,n.payload.connection),I(w,n.payload.settings),I(a,n.payload.item),oo();return}if(n.type==="generate-late"){A.size===0?z.push(n.payload):I(A,n.payload);return}if(n.type==="directory"){E&&(E={...E,directory:n.payload.directory}),I(u,n.payload.directory);return}if(n.type==="session"){E&&(E={...E,session:n.payload.session}),n.payload.session?q?.sessionId!==n.payload.session.id&&(q=to(n.payload.session)):q=null,I(i,n.payload.session);return}if(n.type==="session-lifecycle"){q=n.payload,I(f,n.payload);return}if(n.type==="connection"){E&&(E={...E,connection:n.payload.connection}),I(x,n.payload.connection);return}if(n.type==="settings"){E&&(E={...E,settings:n.payload.settings}),I(w,n.payload.settings);return}if(n.type==="item"){E&&(E={...E,item:n.payload.item}),I(a,n.payload.item);return}if(n.type==="status-control-event"){I(b,n.payload);return}if(n.type==="popover-closed"){I(g,n.payload);return}if(n.type==="action"){let l=O=>{J||V({channel:S,v:1,type:"action-result",id:n.id,payload:O})},v=re;if(!v){l({ok:!1,error:"This extension does not handle background actions."});return}Promise.resolve().then(()=>v(n.payload)).then(()=>l({ok:!0}),O=>{let N=(O instanceof Error?O.message:String(O)).trim();l({ok:!1,error:(N||"Action failed.").slice(0,be)})});return}if(n.type==="file-open"){let l=n.payload;if(Te&&To(Te,l))return;Te=l,I(Me,n.payload);return}if(n.type==="file-saved"){I(Ie,n.payload.version);return}if(n.type==="file-snapshot"){let l=N=>{J||V({channel:S,v:1,type:"file-snapshot-result",id:n.id,payload:N})},v=N=>l({error:(N.trim()||"Could not read the edited file.").slice(0,be)}),O=Se;if(!O){v("This extension does not edit files.");return}Promise.resolve().then(()=>O(n.payload.purpose)).then(N=>{if(ct(N)>2e7){v(`The file is over ${2e7} ${"bytes"in N?"bytes":"characters"}.`);return}if(N.version.length>256){v(`The snapshot version is over ${256} characters.`);return}l({snapshot:"bytes"in N?{bytes:N.bytes,version:N.version}:{content:N.content,version:N.version}})},N=>v(N instanceof Error?N.message:String(N)));return}if(n.type==="resolve"){let l=O=>{V({channel:S,v:1,type:"resolve-result",id:n.id,payload:O})},v=oe;if(!v){l({error:"This extension does not resolve commands."});return}Promise.resolve().then(()=>v(n.payload)).then(O=>l({item:O?pe(O):null}),O=>{let N=(O instanceof Error?O.message:String(O)).trim();l({error:(N||"Command failed.").slice(0,be)})});return}let d=ae.get(n.id);if(d){if(clearTimeout(d.timer),ae.delete(n.id),n.ok){d.resolve(n.payload);return}d.reject(new p(n.code,n.error))}};t.addEventListener("message",no),V({channel:S,v:1,type:"hello"});let H=(o,n=s)=>J||t.parent===t?Promise.reject(new p("HOST_UNAVAILABLE","No host frame. This page is not in an iframe.")):new Promise((d,l)=>{let v=setTimeout(()=>{ae.delete(o.id),l(new p("HOST_TIMEOUT","Host did not answer in time."))},n);ae.set(o.id,{resolve:d,reject:l,timer:v}),V(o)}),U=o=>H(o).then(()=>{}),G={channel:S,v:1},nt=o=>{!J&&t.parent!==t&&V(o)},ro=()=>nt({...G,type:"file-save"}),so=o=>{!Xo(o)||!bn(o)||(o.preventDefault(),ro())},io=o=>{!Xo(o)||o.key!=="Escape"||E?.surface!=="popover"||!E.popover||(o.preventDefault(),po(E.popover.id,"escape").catch(()=>{}))},Ce=()=>{let o=E?.surface==="popover"?E.popover:void 0;if(!o)return;let n=ge||xe;eo!==n&&(eo=n,uo(o.id,n).catch(()=>{}))},Ue=()=>{E?.surface!=="popover"||ge||(ge=!0,Ce())},ao=o=>{E?.surface!=="popover"||o.relatedTarget!==null||!ge||(ge=!1,Ce())},co=()=>{E?.surface!=="popover"||xe||(xe=!0,Ce())},lo=()=>{E?.surface!=="popover"||!xe||(xe=!1,Ce())},K=(o,n=1024)=>{if(!o.trim()||o.length>n)throw new p("HOST_REJECTED",`Identity must contain 1 to ${n} characters.`)},rt=async o=>{o.kind!=="projects"&&K(o.projectId);let n=await H({...G,type:"workspace-read",id:_(m),payload:o});if(!n||!("kind"in n)||!("state"in n)||n.kind!==o.kind)throw new p("HOST_REJECTED","Host did not return workspace data.");return n},st=async(o,n)=>{o.kind!=="projects"&&K(o.projectId);let d=_(m);ce.set(d,n);try{await U({...G,type:"workspace-subscribe",id:_(m),payload:{subscriptionId:d,query:o}})}catch(l){throw ce.delete(d),J||V({...G,type:"workspace-unsubscribe",id:_(m),payload:{subscriptionId:d}}),l}return()=>{!ce.delete(d)||J||V({...G,type:"workspace-unsubscribe",id:_(m),payload:{subscriptionId:d}})}},fn=async(o,n)=>{o.kind==="session"&&K(o.sessionId),o.kind==="project"&&K(o.projectId);let d=_(m);de.set(d,n);try{await U({...G,type:"shells-subscribe",id:_(m),payload:{subscriptionId:d,scope:o}})}catch(l){throw de.delete(d),J||V({...G,type:"shells-unsubscribe",id:_(m),payload:{subscriptionId:d}}),l}return()=>{!de.delete(d)||J||V({...G,type:"shells-unsubscribe",id:_(m),payload:{subscriptionId:d}})}},Ge=async o=>{if("key"in o&&(o.key.length===0||o.key.length>128))throw new p("HOST_REJECTED","Storage key must contain 1 to 128 characters.");if(o.op==="set"&&!le(o.value))throw new p("HOST_REJECTED","Storage values must be JSON.");if(o.op==="set"&&new TextEncoder().encode(JSON.stringify(o.value)).length>65536)throw new p("HOST_REJECTED","Storage value exceeds 64 KiB.");if(o.scope==="device"&&E?.features?.deviceStorage!==!0)throw new p("UNSUPPORTED","This host does not support device storage.");let n=await H({...G,type:"storage",id:_(m),payload:o});if(!n||!("storage"in n)||n.op!==o.op)throw new p("HOST_REJECTED","Host did not return storage data.");return n},po=(o,n)=>E?.features?.popovers!==!0&&!(E?.surface==="popover"&&E.popover?.id===o)?Promise.reject(new p("UNSUPPORTED","This host does not support popovers.")):U({...G,type:"popover-close",id:_(m),payload:n?{id:o,reason:n}:{id:o}}),uo=(o,n)=>E?.features?.popovers!==!0&&!(E?.surface==="popover"&&E.popover?.id===o)?Promise.reject(new p("UNSUPPORTED","This host does not support popovers.")):U({...G,type:"popover-anchor",id:_(m),payload:{id:o,active:n}});return t.addEventListener("keydown",io,!0),t.addEventListener("pointerover",Ue),t.addEventListener("pointermove",Ue),t.addEventListener("pointerout",ao),t.addEventListener("focus",co),t.addEventListener("blur",lo),{onAction:o=>(re=o,()=>{re===o&&(re=null)}),listProjects:async()=>{let o=await rt({kind:"projects"});if(o.kind!=="projects")throw new p("HOST_REJECTED","Expected projects.");return o},listWorktrees:async o=>{let n=await rt({kind:"worktrees",projectId:o});if(n.kind!=="worktrees")throw new p("HOST_REJECTED","Expected worktrees.");return n},listSessions:async o=>{let n=await rt({kind:"sessions",projectId:o});if(n.kind!=="sessions")throw new p("HOST_REJECTED","Expected sessions.");return n},onProjects:o=>st({kind:"projects"},n=>{n.kind==="projects"&&o(n)}),onWorktrees:(o,n)=>st({kind:"worktrees",projectId:o},d=>{d.kind==="worktrees"&&n(d)}),onSessions:(o,n)=>st({kind:"sessions",projectId:o},d=>{d.kind==="sessions"&&n(d)}),onRunningShells:(o,n)=>fn(o,n),readShellOutput:async(o,n)=>{K(o,128);let d=n?.cursor;if(d!==void 0&&(!Number.isInteger(d)||d<0))throw new p("HOST_REJECTED","Shell output cursor must be a non-negative integer.");let l=n?.tailBytes;if(l!==void 0&&(!Number.isInteger(l)||l<1||l>65536))throw new p("HOST_REJECTED",`Shell output tailBytes must be an integer between 1 and ${65536}.`);let O=await H({...G,type:"shell-output",id:_(m),payload:{shellId:o,cursor:d,tailBytes:l}});if(!O||typeof O.output!="string"||!Number.isFinite(O.cursor))throw new p("HOST_REJECTED","Host did not return shell output.");return O},stopShell:async o=>{if(K(o,128),(await H({...G,type:"shell-stop",id:_(m),payload:{shellId:o}}))?.stopped!==!0)throw new p("HOST_REJECTED","Host did not stop the shell.");return{stopped:!0}},openSession:async o=>{K(o),await U({...G,type:"open-session",id:_(m),payload:{sessionId:o}})},storage:{get:async(o,n)=>{let d=je(n),l={op:"get",key:o};d&&(l.scope=d);let v=await Ge(l);return v.op==="get"&&v.found?v.value:void 0},set:async(o,n,d)=>{let l=je(d),v={op:"set",key:o,value:n};l&&(v.scope=l),await Ge(v)},delete:async(o,n)=>{let d=je(n),l={op:"delete",key:o};d&&(l.scope=d),await Ge(l)},keys:async o=>{let n=je(o),d={op:"keys"};n&&(d.scope=n);let l=await Ge(d);if(l.op!=="keys")throw new p("HOST_REJECTED","Expected storage keys.");return l.keys}},onReady:o=>(c.add(o),E&&o(E),()=>{c.delete(o)}),onDirectory:o=>(u.add(o),E&&o(E.directory),()=>{u.delete(o)}),onSession:o=>(i.add(o),E&&o(E.session),()=>{i.delete(o)}),onSessionLifecycle:o=>(f.add(o),q&&o(q),()=>{f.delete(o)}),onConnection:o=>(x.add(o),E&&o(E.connection),()=>{x.delete(o)}),onSettings:o=>(w.add(o),E&&o(E.settings),()=>{w.delete(o)}),onItem:o=>(a.add(o),E&&o(E.item),()=>{a.delete(o)}),onStatusControl:o=>(b.add(o),()=>{b.delete(o)}),onPopoverClosed:o=>(g.add(o),()=>{g.delete(o)}),setStatusControls:o=>E?.features?.statusControls!==!0?Promise.reject(new p("UNSUPPORTED","This host does not support status controls.")):So(o)?U({...G,type:"status-controls",id:_(m),payload:{controls:o}}):Promise.reject(new p("HOST_REJECTED","Status controls must have unique bounded ids and valid selected options.")),openPopover:o=>E?.features?.popovers!==!0?Promise.reject(new p("UNSUPPORTED","This host does not support popovers.")):lt(o)?U({...G,type:"popover-open",id:_(m),payload:o}):Promise.reject(new p("HOST_REJECTED","Popover requests need bounded geometry and JSON data.")),closePopover:po,setPopoverAnchorActive:uo,onResolve:o=>(oe=o,()=>{oe===o&&(oe=null)}),toast:o=>{let n=o.message.trim();return!n||n.length>Pe?Promise.reject(new p("HOST_REJECTED",`Toast message must contain 1 to ${Pe} characters.`)):o.copy&&o.copy!==!0&&(!o.copy.text.length||o.copy.text.length>De)?Promise.reject(new p("HOST_REJECTED",`Toast copy text must contain 1 to ${De} characters.`)):U({channel:S,v:1,type:"toast",id:_(m),payload:{...o,message:n}})},openUrl:o=>U({channel:S,v:1,type:"open-url",id:_(m),payload:{url:o}}),openCommit:o=>Et(o)?U({channel:S,v:1,type:"open-commit",id:_(m),payload:{sha:o}}):Promise.reject(new p("HOST_REJECTED","Commit id must be 7 to 64 hex characters.")),openSurface:o=>U({channel:S,v:1,type:"open-surface",id:_(m),payload:{surfaceId:o}}),writeClipboard:o=>U({channel:S,v:1,type:"clipboard-write",id:_(m),payload:{text:o}}),compose:o=>U({channel:S,v:1,type:"compose",id:_(m),payload:o}),attach:o=>U({channel:S,v:1,type:"attach",id:_(m),payload:pe(o)}),startSession:async o=>{o.projectId!==void 0&&K(o.projectId);let n=o.worktree;n&&n!==!0&&(n.kind==="existing"?K(n.directory):(n.name!==void 0&&K(n.name,200),n.baseBranch!==void 0&&K(n.baseBranch,200)));let d=await H({channel:S,v:1,type:"start-session",id:_(m),payload:St(o)},e.requestTimeoutMs??18e4);if(!ut(d))throw new p("HOST_REJECTED","Host did not return a session.");return d},prompt:o=>H({channel:S,v:1,type:"prompt",id:_(m),payload:Tt(o)}).then(n=>{if(!ft(n))throw new p("HOST_REJECTED","Host did not return a prompt result.");return n}),sessionLink:o=>U({channel:S,v:1,type:"session-link",id:_(m),payload:pe(o)}),close:()=>U({channel:S,v:1,type:"close",id:_(m)}),oauthStart:()=>U({channel:S,v:1,type:"oauth-start",id:_(m)}),oauthDisconnect:()=>U({channel:S,v:1,type:"oauth-disconnect",id:_(m)}),request:o=>(Be(o.path)?H({channel:S,v:1,type:"request",id:_(m),payload:o}):Bo()).then(n=>{if(!Ve(n))throw new p("HOST_REJECTED","Host request result was empty.");return n}),serviceRequest:o=>(Be(o.path)?H({channel:S,v:1,type:"service-request",id:_(m),payload:o}):Bo()).then(n=>{if(!Ve(n))throw new p("HOST_REJECTED","Host service request result was empty.");return n}),serviceStatus:()=>H({channel:S,v:1,type:"service-status",id:_(m)}).then(o=>{if(!bt(o))throw new p("HOST_REJECTED","Host did not return service status.");return o}),readFile:o=>(ue(o)?H({channel:S,v:1,type:"file-read",id:_(m),payload:{path:o}}):ze()).then(n=>{if(!At(n))throw new p("HOST_REJECTED","Host did not return file content.");return n}),writeFile:(o,n)=>ue(o)?n.length>$e?Promise.reject(new p("FILE_TOO_LARGE",`Content is over ${$e} characters.`)):H({channel:S,v:1,type:"file-write",id:_(m),payload:{path:o,content:n}}).then(d=>{if(!kt(d))throw new p("HOST_REJECTED","Host did not confirm the write.");return d}):ze(),listDir:o=>(ue(o)?H({channel:S,v:1,type:"file-list",id:_(m),payload:{path:o}}):ze()).then(n=>{if(!yt(n))throw new p("HOST_REJECTED","Host did not return directory entries.");return n}),stat:o=>(ue(o)?H({channel:S,v:1,type:"file-stat",id:_(m),payload:{path:o}}):ze()).then(n=>{if(!Ot(n))throw new p("HOST_REJECTED","Host did not return file status.");return n}),generate:o=>{let n=o.prompt.trim(),d=o.system?.trim();if(n.length===0||n.length>Fe)return Promise.reject(new p("HOST_REJECTED",`Prompt must be 1 to ${Fe} characters.`));if(d!==void 0&&(d.length===0||d.length>Xe))return Promise.reject(new p("HOST_REJECTED",`System prompt must be 1 to ${Xe} characters.`));let l=o.maxOutputTokens===void 0?void 0:Math.min(mt,Math.max(1,Math.floor(o.maxOutputTokens)));if(l!==void 0&&!Number.isFinite(l))return Promise.reject(new p("HOST_REJECTED","maxOutputTokens must be a number."));let v={prompt:n};return d!==void 0&&(v.system=d),l!==void 0&&(v.maxOutputTokens=l),H({channel:S,v:1,type:"generate",id:_(m),payload:v},e.requestTimeoutMs??_t).then(O=>{if(!vt(O))throw new p("HOST_REJECTED","Host did not return generated text.");return O})},onLateGenerateResult:o=>{A.add(o);for(let n of z.splice(0))I([o],n);return oo(),()=>{A.delete(o)}},setBadge:o=>U({channel:S,v:1,type:"badge",id:_(m),payload:{count:gt(o)}}),setHeight:o=>U({channel:S,v:1,type:"resize",id:_(m),payload:{height:xt(o)}}),onFileOpen:o=>(Me.add(o),ot||(ot=!0,t.addEventListener("keydown",so,!0)),Te&&o(Te),()=>{Me.delete(o)}),onFileSnapshot:o=>(Se=o,()=>{Se===o&&(Se=null)}),onFileSaved:o=>(Ie.add(o),()=>{Ie.delete(o)}),reportFileChange:o=>nt({...G,type:"file-change",payload:{dirty:o.dirty,edited:o.edited}}),requestFileSave:ro,reportFileUnsupported:()=>nt({...G,type:"file-unsupported"}),dispose:()=>{for(let o of ce.keys())V({...G,type:"workspace-unsubscribe",id:_(m),payload:{subscriptionId:o}});ce.clear();for(let o of de.keys())V({...G,type:"shells-unsubscribe",id:_(m),payload:{subscriptionId:o}});de.clear(),J=!0,oe=null,re=null,Se=null,Me.clear(),Ie.clear(),ot&&t.removeEventListener("keydown",so,!0),t.removeEventListener("message",no),t.removeEventListener("keydown",io,!0),t.removeEventListener("pointerover",Ue),t.removeEventListener("pointermove",Ue),t.removeEventListener("pointerout",ao),t.removeEventListener("focus",co),t.removeEventListener("blur",lo);for(let o of ae.values())clearTimeout(o.timer),o.reject(new p("HOST_UNAVAILABLE","Host client was disposed."));ae.clear(),c.clear(),u.clear(),i.clear(),f.clear(),x.clear(),w.clear(),a.clear(),b.clear(),g.clear(),A.clear(),z.length=0}}};var jo=["browser.open","browser.snapshot","browser.click","browser.type","browser.scroll","browser.back","browser.forward","browser.inspect","browser.capture","browser.resize","browser.close"];var Tr=new Set(jo);var Ko=["none","agent","user"];var xr=new Set(Ko);var An=[["--oc-bg","background"],["--oc-elevated","elevated"],["--oc-fg","foreground"],["--oc-muted","muted"],["--oc-subtle","subtle"],["--oc-border","border"],["--oc-hover","hover"],["--oc-selection","selection"],["--oc-focus","focus"],["--oc-primary","primary"],["--oc-muted-surface","mutedSurface"],["--oc-elevated-fg","elevatedForeground"],["--oc-active","active"],["--oc-selection-fg","selectionForeground"],["--oc-primary-fg","primaryForeground"],["--oc-primary-text","primaryText"],["--oc-success-text","successText"],["--oc-warning-text","warningText"],["--oc-error-text","errorText"],["--oc-info-text","infoText"],["--oc-success","success"],["--oc-warning","warning"],["--oc-error","error"],["--oc-info","info"],["--oc-font","font"],["--oc-mono","mono"],["--oc-radius","radius"],["--surface-background","background"],["--surface-elevated","elevated"],["--surface-foreground","foreground"],["--surface-muted-foreground","muted"],["--surface-subtle","subtle"],["--interactive-border","border"],["--interactive-hover","hover"],["--interactive-selection","selection"],["--interactive-focus-ring","focus"],["--primary","primary"],["--surface-muted","mutedSurface"],["--surface-elevated-foreground","elevatedForeground"],["--interactive-active","active"],["--interactive-selection-foreground","selectionForeground"],["--primary-foreground","primaryForeground"],["--primary-text","primaryText"],["--success-text","successText"],["--warning-text","warningText"],["--error-text","errorText"],["--info-text","infoText"],["--status-success","success"],["--status-warning","warning"],["--status-error","error"],["--status-info","info"],["--font-sans","font"],["--font-mono","mono"],["--radius","radius"]],kn=[["--oc-syntax-keyword","--syntax-keyword","syntaxKeyword"],["--oc-syntax-string","--syntax-string","syntaxString"],["--oc-syntax-number","--syntax-number","syntaxNumber"],["--oc-syntax-function","--syntax-function","syntaxFunction"],["--oc-syntax-type","--syntax-type","syntaxType"],["--oc-syntax-comment","--syntax-comment","syntaxComment"],["--oc-syntax-variable","--syntax-variable","syntaxVariable"],["--oc-syntax-operator","--syntax-operator","syntaxOperator"]],Wo=(e,t)=>{t.style.colorScheme=e.mode;for(let[r,s]of An)t.style.setProperty(r,e.tokens[s]);for(let[r,s,c]of kn){let u=e.tokens[c]??"";t.style.setProperty(r,u),t.style.setProperty(s,u)}t.style.setProperty("font-family",e.tokens.font),t.style.setProperty("font-size","0.875rem"),t.style.setProperty("line-height","1.45"),t.style.setProperty("color",e.tokens.foreground)},Ut=(e,t)=>{Wo(e.theme,t),t.dataset&&(t.dataset.ocSurface=e.surface,t.dataset.ocTheme=e.theme.mode)};var yn={"surface-background":"bg","surface-elevated":"elevated","surface-elevated-foreground":"elevated-fg","surface-foreground":"fg","surface-muted-foreground":"muted","surface-muted":"muted-surface","surface-subtle":"subtle","interactive-border":"border","interactive-hover":"hover","interactive-active":"active","interactive-selection":"selection","interactive-selection-foreground":"selection-fg","interactive-focus-ring":"focus",primary:"primary","primary-foreground":"primary-fg","primary-text":"primary-text","success-text":"success-text","warning-text":"warning-text","error-text":"error-text","info-text":"info-text","status-success":"success","status-warning":"warning","status-error":"error","status-info":"info","font-sans":"font","font-mono":"mono",radius:"radius"},L=(e,t)=>`var(--${e}, var(--oc-${yn[e]}, ${t}))`,Z=L("surface-background","transparent"),We=L("surface-elevated","transparent"),fe=L("surface-elevated-foreground","inherit"),j=L("surface-foreground","inherit"),R=L("surface-muted-foreground","gray"),On=L("surface-muted","transparent"),ne=L("interactive-border","currentColor"),$=L("interactive-hover","transparent"),se=L("interactive-active","transparent"),Gt=L("interactive-selection","transparent"),Nt=L("interactive-selection-foreground","inherit"),Q=L("primary","currentColor"),Pt=L("primary-text","inherit"),Dt=L("error-text","inherit"),vn=L("font-sans","inherit"),Ht=L("font-mono","monospace"),Zo=L("radius","9px"),$t=`calc(${Zo} - 2px)`,Jo=`calc(${Zo} - 4px)`,C=(e,t,r="transparent")=>`color-mix(in srgb, ${e} ${t}%, ${r})`,Yo=`background-image: linear-gradient(${$}, ${$});`,Ft=e=>`box-shadow: inset 0 0 0 1px ${e}, var(--oc-sdk-field-lift);`,Xt="box-shadow: inset 0 0 0 1px var(--oc-sdk-edge), var(--oc-sdk-raised-lift);",qo="box-shadow: var(--oc-sdk-lit);",Qo=`inset 0 1px 0 0 ${C(j,1.5)}, 0 1px 1px 0 rgb(0 0 0 / 0.28), 0 2px 3px -2px rgb(0 0 0 / 0.2)`,wn=`
|
|
36
|
+
:root {
|
|
37
|
+
--oc-sdk-edge: ${C(j,10)};
|
|
38
|
+
--oc-sdk-field-bg: ${We};
|
|
39
|
+
--oc-sdk-raised-bg: ${Z};
|
|
40
|
+
--oc-sdk-field-lift: inset 0 1px 2px 0 rgb(0 0 0 / 0.04);
|
|
41
|
+
--oc-sdk-raised-lift: 0 1px 2px 0 rgb(0 0 0 / 0.06);
|
|
42
|
+
--oc-sdk-lit: inset 0 1px 0 0 rgb(255 255 255 / 0.45), 0 1px 2px 0 rgb(0 0 0 / 0.08);
|
|
43
|
+
--oc-sdk-float: inset 0 1px 0 0 rgb(255 255 255 / 0.8), inset 0 0 0 1px rgb(0 0 0 / 0.04), 0 0 0 1px rgb(0 0 0 / 0.1), 0 1px 2px -0.5px rgb(0 0 0 / 0.08), 0 4px 8px -2px rgb(0 0 0 / 0.08), 0 12px 20px -4px rgb(0 0 0 / 0.08);
|
|
44
|
+
}
|
|
45
|
+
:root[data-oc-theme="dark"] {
|
|
46
|
+
--oc-sdk-edge: ${C(j,6)};
|
|
47
|
+
--oc-sdk-field-bg: ${C(Z,50,We)};
|
|
48
|
+
--oc-sdk-raised-bg: ${We};
|
|
49
|
+
--oc-sdk-field-lift: ${Qo};
|
|
50
|
+
--oc-sdk-raised-lift: ${Qo};
|
|
51
|
+
--oc-sdk-lit: inset 0 1px 0 0 ${C(j,1.5)}, 0 1px 1px 0 rgb(0 0 0 / 0.28), 0 2px 3px -2px rgb(0 0 0 / 0.2);
|
|
52
|
+
--oc-sdk-float: inset 0 1px 0 0 rgb(255 255 255 / 0.06), inset 0 0 0 1px rgb(255 255 255 / 0.08), 0 0 0 1px rgb(0 0 0 / 0.36), 0 1px 1px -0.5px rgb(0 0 0 / 0.22), 0 3px 3px -1.5px rgb(0 0 0 / 0.2), 0 6px 6px -3px rgb(0 0 0 / 0.16);
|
|
53
|
+
}`,Ke=e=>{let t=L(`status-${e}`,"currentColor");return`
|
|
54
|
+
.oc-sdk[data-tone="${e}"], .oc-sdk [data-tone="${e}"] { --oc-sdk-tone: ${t}; --oc-sdk-tone-text: ${L(`${e}-text`,"inherit")}; }`},Rn=`
|
|
55
|
+
.oc-sdk { box-sizing: border-box; font-size: 0.875rem; line-height: 1.45; }
|
|
56
|
+
.oc-sdk *, .oc-sdk *::before, .oc-sdk *::after { box-sizing: border-box; }
|
|
57
|
+
/* :where() keeps the reset at zero specificity so every primitive class below overrides it. */
|
|
58
|
+
:where(.oc-sdk) :where(button, input, textarea), :where(button.oc-sdk, input.oc-sdk, textarea.oc-sdk) { font: inherit; color: inherit; margin: 0; }
|
|
59
|
+
:where(.oc-sdk) :where(button), :where(button.oc-sdk) { cursor: pointer; background: none; border: 0; padding: 0; }
|
|
60
|
+
.oc-sdk button:disabled, button.oc-sdk:disabled, .oc-sdk[aria-disabled="true"], .oc-sdk [aria-disabled="true"] { opacity: .5; pointer-events: none; }
|
|
61
|
+
|
|
62
|
+
.oc-sdk-btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 32px; padding: 0 12px; border: 1px solid transparent; font-size: 0.875rem; font-weight: 500; line-height: 1; white-space: nowrap; }
|
|
63
|
+
.oc-sdk-btn[data-size="sm"] { gap: 6px; height: 28px; padding: 0 10px; font-size: 0.8125rem; }
|
|
64
|
+
.oc-sdk-btn[data-size="xs"] { gap: 4px; height: 24px; padding: 0 8px; font-size: 0.75rem; }
|
|
65
|
+
.oc-sdk-btn[data-loading="true"] { opacity: .5; pointer-events: none; }
|
|
66
|
+
.oc-sdk-btn > .oc-sdk-spinner-ring { width: 14px; height: 14px; }
|
|
67
|
+
|
|
68
|
+
.oc-sdk-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
|
|
69
|
+
.oc-sdk-field-label { font-size: 0.8125rem; font-weight: 500; }
|
|
70
|
+
.oc-sdk-field-note { font-size: 0.75rem; }
|
|
71
|
+
.oc-sdk-input { display: block; width: 100%; min-width: 0; height: 32px; padding: 0 10px; border: 0; font-size: 0.875rem; line-height: 1.45; appearance: none; }
|
|
72
|
+
textarea.oc-sdk-input { height: auto; padding: 8px 10px; resize: vertical; }
|
|
73
|
+
|
|
74
|
+
.oc-sdk-search { position: relative; min-width: 0; }
|
|
75
|
+
.oc-sdk-search .oc-sdk-input { padding-left: 34px; padding-right: 34px; }
|
|
76
|
+
.oc-sdk-search-icon { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); pointer-events: none; }
|
|
77
|
+
.oc-sdk-search-clear { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); display: none; align-items: center; justify-content: center; width: 24px; height: 24px; }
|
|
78
|
+
.oc-sdk-search[data-active="true"] .oc-sdk-search-clear { display: inline-flex; }
|
|
79
|
+
|
|
80
|
+
.oc-sdk-select { position: relative; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
|
|
81
|
+
.oc-sdk-trigger { display: inline-flex; align-items: center; gap: 6px; align-self: flex-start; width: auto; max-width: 100%; min-width: 0; height: 28px; padding: 0 10px; border: 1px solid transparent; font-size: 0.8125rem; text-align: left; }
|
|
82
|
+
.oc-sdk-trigger-value { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
83
|
+
.oc-sdk-trigger-chevron { flex: 0 0 auto; }
|
|
84
|
+
.oc-sdk-popup { position: fixed; z-index: 50; display: flex; flex-direction: column; gap: 2px; min-width: 160px; max-width: calc(100vw - 16px); max-height: min(320px, calc(100vh - 16px)); overflow: auto; padding: 4px; border: 1px solid transparent; }
|
|
85
|
+
.oc-sdk-popup-search { flex: 0 0 auto; padding: 2px 2px 4px; }
|
|
86
|
+
.oc-sdk-popup-search .oc-sdk-input { height: 28px; font-size: 0.8125rem; }
|
|
87
|
+
.oc-sdk-option { display: flex; align-items: center; gap: 8px; width: 100%; padding: 6px 8px; font-size: 0.8125rem; text-align: left; }
|
|
88
|
+
.oc-sdk-option-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
89
|
+
.oc-sdk-option-hint { flex: 0 0 auto; font-size: 0.75rem; }
|
|
90
|
+
.oc-sdk-option-check { flex: 0 0 auto; display: inline-flex; width: 14px; visibility: hidden; }
|
|
91
|
+
.oc-sdk-option[aria-selected="true"] > .oc-sdk-option-check { visibility: visible; }
|
|
92
|
+
.oc-sdk-popup-empty { padding: 8px; font-size: 0.8125rem; }
|
|
93
|
+
|
|
94
|
+
.oc-sdk-check { display: inline-flex; align-items: flex-start; gap: 8px; width: 100%; text-align: left; }
|
|
95
|
+
.oc-sdk-check-box { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; margin-top: 3px; border: 1px solid transparent; }
|
|
96
|
+
.oc-sdk-check-box > svg { display: none; }
|
|
97
|
+
.oc-sdk-check[aria-checked="true"] .oc-sdk-check-box > svg { display: block; }
|
|
98
|
+
.oc-sdk-check-thumb { flex: 0 0 auto; position: relative; width: 36px; height: 20px; }
|
|
99
|
+
.oc-sdk-check-thumb::after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; }
|
|
100
|
+
.oc-sdk-check-text { display: flex; flex-direction: column; min-width: 0; }
|
|
101
|
+
.oc-sdk-check-label { font-size: 0.875rem; }
|
|
102
|
+
.oc-sdk-check-desc { font-size: 0.75rem; }
|
|
103
|
+
|
|
104
|
+
.oc-sdk-tabs { display: inline-flex; gap: 2px; padding: 2px; max-width: 100%; overflow: auto; }
|
|
105
|
+
.oc-sdk-tab { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; border: 1px solid transparent; font-size: 0.8125rem; font-weight: 500; white-space: nowrap; }
|
|
106
|
+
.oc-sdk-tab-count { font-size: 0.75rem; font-variant-numeric: tabular-nums; }
|
|
107
|
+
|
|
108
|
+
.oc-sdk-badge { display: inline-flex; align-items: center; padding: 1px 6px; font-size: 11px; font-weight: 500; line-height: 16px; white-space: nowrap; }
|
|
109
|
+
|
|
110
|
+
.oc-sdk-list { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
|
|
111
|
+
.oc-sdk-row { display: flex; align-items: center; gap: 8px; width: 100%; padding: 6px 8px; text-align: left; }
|
|
112
|
+
.oc-sdk-row-lead { flex: 0 0 auto; width: 64px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.75rem; }
|
|
113
|
+
.oc-sdk-row-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
|
|
114
|
+
.oc-sdk-row-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
115
|
+
.oc-sdk-row-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.75rem; }
|
|
116
|
+
.oc-sdk-row-meta { flex: 0 0 auto; font-size: 0.75rem; font-variant-numeric: tabular-nums; }
|
|
117
|
+
.oc-sdk-list-empty { padding: 16px 8px; text-align: center; font-size: 0.8125rem; }
|
|
118
|
+
|
|
119
|
+
.oc-sdk-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; padding: 40px 16px; text-align: center; }
|
|
120
|
+
.oc-sdk-empty-title { margin: 0; font-size: 0.8125rem; font-weight: 600; }
|
|
121
|
+
.oc-sdk-empty-body { margin: 0; max-width: 32rem; font-size: 0.8125rem; }
|
|
122
|
+
.oc-sdk-empty-action { margin-top: 12px; }
|
|
123
|
+
|
|
124
|
+
@keyframes oc-sdk-spin { to { transform: rotate(360deg); } }
|
|
125
|
+
.oc-sdk-spinner { display: inline-flex; align-items: center; gap: 8px; font-size: 0.8125rem; }
|
|
126
|
+
.oc-sdk-spinner-ring { width: 16px; height: 16px; border: 2px solid transparent; animation: oc-sdk-spin .8s linear infinite; }
|
|
127
|
+
.oc-sdk-spinner[data-size="sm"] .oc-sdk-spinner-ring { width: 12px; height: 12px; }
|
|
128
|
+
|
|
129
|
+
.oc-sdk-banner { display: flex; align-items: flex-start; gap: 12px; padding: 8px 12px; border: 1px solid transparent; }
|
|
130
|
+
.oc-sdk-banner-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
|
|
131
|
+
.oc-sdk-banner-title { font-size: 0.8125rem; font-weight: 500; }
|
|
132
|
+
.oc-sdk-banner-body { font-size: 0.8125rem; }
|
|
133
|
+
.oc-sdk-banner-action { flex: 0 0 auto; }
|
|
134
|
+
|
|
135
|
+
.oc-sdk-separator { display: flex; align-items: center; gap: 8px; width: 100%; margin: 8px 0; font-size: 0.75rem; }
|
|
136
|
+
.oc-sdk-separator::before, .oc-sdk-separator::after { content: ""; flex: 1 1 auto; height: 1px; }
|
|
137
|
+
.oc-sdk-separator[data-labeled="false"]::after { display: none; }
|
|
138
|
+
.oc-sdk-popup > .oc-sdk-separator { margin: 4px 0; }
|
|
139
|
+
|
|
140
|
+
.oc-sdk-progress { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
|
|
141
|
+
.oc-sdk-progress-label { display: flex; justify-content: space-between; font-size: 0.75rem; font-variant-numeric: tabular-nums; }
|
|
142
|
+
.oc-sdk-progress-track { height: 6px; overflow: hidden; }
|
|
143
|
+
.oc-sdk-progress-fill { height: 100%; transform-origin: left; transition: transform 200ms ease-out; }
|
|
144
|
+
|
|
145
|
+
.oc-sdk-menu { position: relative; display: inline-flex; }
|
|
146
|
+
|
|
147
|
+
.oc-sdk-text { white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
148
|
+
.oc-sdk-text img { display: block; max-width: 100%; margin: 8px 0; }
|
|
149
|
+
`,en=`${wn}
|
|
150
|
+
.oc-sdk { color: ${j}; font-family: ${vn}; }
|
|
151
|
+
.oc-sdk :focus-visible, .oc-sdk:focus-visible { outline: none; }
|
|
152
|
+
.oc-sdk :where(button, a[href], [role="button"], [role="tab"], [role="option"]):focus-visible, button.oc-sdk:focus-visible { ${Yo} }
|
|
153
|
+
.oc-sdk-mono { font-family: ${Ht}; }
|
|
154
|
+
.oc-sdk-muted { color: ${R}; }
|
|
155
|
+
${Ke("success")}${Ke("warning")}${Ke("error")}${Ke("info")}
|
|
156
|
+
.oc-sdk[data-tone="primary"], .oc-sdk [data-tone="primary"] { --oc-sdk-tone: ${Q}; --oc-sdk-tone-text: ${Pt}; }
|
|
157
|
+
|
|
158
|
+
.oc-sdk-btn { border-radius: ${$t}; transition: background 150ms ease-out, color 150ms ease-out; }
|
|
159
|
+
.oc-sdk-btn[data-size="xs"] { border-radius: ${Jo}; }
|
|
160
|
+
.oc-sdk-btn[data-variant="default"] { color: ${Pt}; background: ${C(Q,10,Z)}; border-color: ${C(Q,12)}; ${qo} }
|
|
161
|
+
.oc-sdk-btn[data-variant="default"]:hover { background: ${C(Q,16,Z)}; }
|
|
162
|
+
.oc-sdk-btn[data-variant="default"]:active { background: ${C(Q,22,Z)}; box-shadow: none; }
|
|
163
|
+
.oc-sdk-btn[data-variant="secondary"] { background: ${On}; color: var(--oc-fg); }
|
|
164
|
+
.oc-sdk-btn[data-variant="secondary"]:hover { background-image: linear-gradient(${$}, ${$}); }
|
|
165
|
+
.oc-sdk-btn[data-variant="secondary"]:active { background-image: linear-gradient(${se}, ${se}); }
|
|
166
|
+
.oc-sdk-btn[data-variant="outline"] { background: var(--oc-sdk-raised-bg); color: ${fe}; border-color: transparent; ${Xt} }
|
|
167
|
+
.oc-sdk-btn[data-variant="outline"]:hover { background-image: linear-gradient(${$}, ${$}); }
|
|
168
|
+
.oc-sdk-btn[data-variant="outline"]:active { background-image: linear-gradient(${se}, ${se}); box-shadow: inset 0 0 0 1px var(--oc-sdk-edge); }
|
|
169
|
+
.oc-sdk-btn[data-variant="ghost"] { background: transparent; }
|
|
170
|
+
.oc-sdk-btn[data-variant="ghost"]:hover { background: ${$}; }
|
|
171
|
+
.oc-sdk-btn[data-variant="ghost"]:active { background: ${se}; }
|
|
172
|
+
.oc-sdk-btn[data-variant="destructive"] { --oc-sdk-tone: ${L("status-error","red")}; color: ${Dt}; background: ${C("var(--oc-sdk-tone)",7,Z)}; border-color: ${C("var(--oc-sdk-tone)",12)}; ${qo} }
|
|
173
|
+
.oc-sdk-btn[data-variant="destructive"]:hover { background: ${C("var(--oc-sdk-tone)",9,Z)}; }
|
|
174
|
+
.oc-sdk-btn[data-variant="destructive"]:active { background: ${C("var(--oc-sdk-tone)",11,Z)}; box-shadow: none; }
|
|
175
|
+
|
|
176
|
+
.oc-sdk-field-note { color: ${R}; }
|
|
177
|
+
.oc-sdk-field[data-invalid="true"] .oc-sdk-field-note { color: ${Dt}; }
|
|
178
|
+
.oc-sdk-input { border-radius: ${$t}; background: var(--oc-sdk-field-bg); color: ${fe}; ${Ft("var(--oc-sdk-edge)")} transition: background 150ms ease-out; }
|
|
179
|
+
.oc-sdk-input::placeholder { color: ${R}; }
|
|
180
|
+
.oc-sdk-input:hover:not(:focus) { background-image: linear-gradient(${$}, ${$}); }
|
|
181
|
+
.oc-sdk-input:focus, .oc-sdk-input:focus-visible { ${Ft(C(j,26))} }
|
|
182
|
+
.oc-sdk-field[data-invalid="true"] .oc-sdk-input, .oc-sdk-field[data-invalid="true"] .oc-sdk-input:focus { ${Ft(L("status-error","red"))} }
|
|
183
|
+
.oc-sdk-input[data-mono="true"] { font-family: ${Ht}; }
|
|
184
|
+
|
|
185
|
+
.oc-sdk-search-icon { color: ${R}; }
|
|
186
|
+
.oc-sdk-search[data-active="true"] .oc-sdk-search-icon { color: ${Q}; }
|
|
187
|
+
.oc-sdk-search-clear { border-radius: ${Jo}; color: ${R}; }
|
|
188
|
+
.oc-sdk-search-clear:hover { background: ${$}; color: ${j}; }
|
|
189
|
+
|
|
190
|
+
.oc-sdk-trigger { border-color: transparent; border-radius: ${$t}; background: var(--oc-sdk-raised-bg); color: ${fe}; ${Xt} transition: background 150ms ease-out; }
|
|
191
|
+
.oc-sdk-trigger:hover { background-image: linear-gradient(${$}, ${$}); }
|
|
192
|
+
.oc-sdk-trigger[aria-expanded="true"] { background-image: linear-gradient(${se}, ${se}); }
|
|
193
|
+
.oc-sdk-trigger-value[data-empty="true"] { color: ${R}; }
|
|
194
|
+
.oc-sdk-trigger-chevron { color: ${R}; }
|
|
195
|
+
/* The app's dropdown light: lit top, hairline rings and a layered shadow, no border. */
|
|
196
|
+
.oc-sdk-popup { --surface-foreground: ${fe}; border-color: transparent; border-radius: 12px; background: ${We}; color: ${fe}; box-shadow: var(--oc-sdk-float); }
|
|
197
|
+
.oc-sdk-option { border-radius: 8px; }
|
|
198
|
+
.oc-sdk-option[data-active="true"] { background: ${$}; }
|
|
199
|
+
/* A selected option shows a check mark in the text colour, like the app's own pickers. Options without the mark come
|
|
200
|
+
from bundles built before it existed and keep the selection fill as their only sign of the choice. */
|
|
201
|
+
.oc-sdk-option[aria-selected="true"]:not([data-mark]) { background: ${Gt}; color: ${Nt}; }
|
|
202
|
+
.oc-sdk-option-check { color: ${j}; }
|
|
203
|
+
.oc-sdk-option[data-destructive="true"] { color: ${Dt}; }
|
|
204
|
+
.oc-sdk-option[data-destructive="true"][data-active="true"] { background: ${C(L("status-error","red"),10)}; }
|
|
205
|
+
.oc-sdk-option-hint { color: ${R}; }
|
|
206
|
+
.oc-sdk-popup-empty { color: ${R}; }
|
|
207
|
+
|
|
208
|
+
/* Checked stays neutral: the mark carries the state, and the primary colour stays with primary actions. */
|
|
209
|
+
.oc-sdk-check-box { border-color: ${ne}; border-radius: 4px; color: ${j}; transition: border-color 150ms ease-out; }
|
|
210
|
+
.oc-sdk-check[aria-checked="true"] .oc-sdk-check-box { border-color: ${C(j,60,ne)}; }
|
|
211
|
+
.oc-sdk-check-thumb { border-radius: 9999px; background: ${ne}; transition: background 150ms ease-out; }
|
|
212
|
+
.oc-sdk-check-thumb::after { border-radius: 9999px; background: ${Z}; transition: transform 150ms ease-out; }
|
|
213
|
+
.oc-sdk-check[aria-checked="true"] .oc-sdk-check-thumb { background: ${Q}; }
|
|
214
|
+
.oc-sdk-check[aria-checked="true"] .oc-sdk-check-thumb::after { transform: translateX(16px); }
|
|
215
|
+
.oc-sdk-check:focus-visible { box-shadow: none; }
|
|
216
|
+
.oc-sdk-check:focus-visible .oc-sdk-check-box, .oc-sdk-check:focus-visible .oc-sdk-check-thumb { ${Yo} }
|
|
217
|
+
.oc-sdk-check-desc { color: ${R}; }
|
|
218
|
+
|
|
219
|
+
.oc-sdk-tabs { border-radius: 10px; }
|
|
220
|
+
.oc-sdk-tabs[data-track="true"] { background: ${C(j,4)}; box-shadow: inset 0 1px 2px 0 rgb(0 0 0 / 0.16); }
|
|
221
|
+
.oc-sdk-tab { border-radius: 8px; color: ${R}; transition: color 150ms ease-out, background 150ms ease-out; }
|
|
222
|
+
.oc-sdk-tab:hover { color: ${j}; }
|
|
223
|
+
.oc-sdk-tab[aria-selected="true"] { color: ${Nt}; background: ${Gt}; border-color: ${ne}; }
|
|
224
|
+
.oc-sdk-tabs[data-track="true"] .oc-sdk-tab[aria-selected="true"] { color: ${fe}; background: var(--oc-sdk-raised-bg); border-color: transparent; ${Xt} }
|
|
225
|
+
.oc-sdk-tab-count { color: ${R}; }
|
|
226
|
+
|
|
227
|
+
.oc-sdk-badge { border-radius: 9999px; background: ${$}; color: ${R}; }
|
|
228
|
+
.oc-sdk-badge[data-tone] { color: var(--oc-sdk-tone-text, var(--oc-sdk-tone)); background: ${C("var(--oc-sdk-tone)",15)}; }
|
|
229
|
+
|
|
230
|
+
.oc-sdk-row { border-radius: 6px; transition: background 120ms ease-out; }
|
|
231
|
+
.oc-sdk-row:hover, .oc-sdk-row[data-active="true"] { background: ${$}; }
|
|
232
|
+
.oc-sdk-row[aria-selected="true"] { background: ${Gt}; color: ${Nt}; }
|
|
233
|
+
.oc-sdk-row-lead { font-family: ${Ht}; color: ${R}; }
|
|
234
|
+
.oc-sdk-row-sub { color: ${R}; }
|
|
235
|
+
.oc-sdk-row-meta { color: ${R}; }
|
|
236
|
+
.oc-sdk-row[aria-selected="true"] .oc-sdk-row-lead, .oc-sdk-row[aria-selected="true"] .oc-sdk-row-sub, .oc-sdk-row[aria-selected="true"] .oc-sdk-row-meta { color: inherit; opacity: .75; }
|
|
237
|
+
.oc-sdk-list-empty { color: ${R}; }
|
|
238
|
+
|
|
239
|
+
.oc-sdk-empty-body { color: ${R}; }
|
|
240
|
+
|
|
241
|
+
.oc-sdk-spinner { color: ${R}; }
|
|
242
|
+
.oc-sdk-spinner-ring { border-color: ${ne}; border-top-color: ${Q}; border-radius: 9999px; }
|
|
243
|
+
|
|
244
|
+
/* Set apart by its tint alone, like the app's banners. */
|
|
245
|
+
.oc-sdk-banner { border-color: transparent; border-radius: 8px; background: ${C("var(--oc-sdk-tone)",10)}; }
|
|
246
|
+
.oc-sdk-banner-title { color: var(--oc-sdk-tone-text, var(--oc-sdk-tone)); }
|
|
247
|
+
.oc-sdk-banner-body { color: ${R}; }
|
|
248
|
+
|
|
249
|
+
.oc-sdk-separator { color: ${R}; }
|
|
250
|
+
.oc-sdk-separator::before, .oc-sdk-separator::after { background: ${C(ne,40)}; }
|
|
251
|
+
|
|
252
|
+
.oc-sdk-progress-label { color: ${R}; }
|
|
253
|
+
.oc-sdk-progress-track { border-radius: 9999px; background: ${ne}; }
|
|
254
|
+
.oc-sdk-progress-fill { border-radius: 9999px; background: var(--oc-sdk-tone, ${Q}); }
|
|
255
|
+
|
|
256
|
+
.oc-sdk-text a { color: ${Pt}; text-decoration: underline; text-underline-offset: 2px; }
|
|
257
|
+
.oc-sdk-text img { border-radius: 8px; border: 1px solid ${C(ne,60)}; }
|
|
258
|
+
`,F=`
|
|
259
|
+
${it}
|
|
260
|
+
${Rn}
|
|
261
|
+
${en}`;var Un=e=>24+e*308;function on(e){let t=new Map,r=new Map;for(let a of e.nodes)r.set(a.column,[...r.get(a.column)??[],a]);let s=[...r.keys()].sort((a,b)=>a-b),c=new Map(s.map(a=>[a,Un(a)])),u=new Map,i=0;for(let a of s)(r.get(a)??[]).slice().sort((g,A)=>(u.get(g.parentId??"")??-1)-(u.get(A.parentId??"")??-1)||(g.createdAt??0)-(A.createdAt??0)||g.id.localeCompare(A.id)).forEach((g,A)=>{let z=58+A*94;t.set(g.id,{x:c.get(a)??0,y:z}),u.set(g.id,u.size),i=Math.max(i,z+80+24)});let f=t.get(e.rootId),x=e.nodes.filter(a=>a.parentId===e.rootId).map(a=>t.get(a.id)).filter(a=>a!==void 0);if(f&&x.length>0&&(r.get(0)?.length??0)===1){let a=Math.min(...x.map(g=>g.y)),b=Math.max(...x.map(g=>g.y));f.y=Math.round((a+b)/2)}let w=24+(Math.max(0,...s)+1)*308-76+24;return{boxes:t,edges:Gn(e.edges,t),columnX:c,width:w,height:Math.max(i,162)}}function tn(e,t){if(t<=1)return 80/2;let r=Math.min(12,80*.44/(t-1));return 80/2+(e-(t-1)/2)*r}function Gn(e,t){let r=e.filter(i=>t.has(i.from)&&t.has(i.to)),s=i=>(t.get(i)?.y??0)+80/2,c=new Map,u=new Map;for(let i of r)c.set(i.from,[...c.get(i.from)??[],i]),u.set(i.to,[...u.get(i.to)??[],i]);for(let i of c.values())i.sort((f,x)=>s(f.to)-s(x.to));for(let i of u.values())i.sort((f,x)=>s(f.from)-s(x.from));return r.map(i=>{let f=t.get(i.from),x=t.get(i.to),w=c.get(i.from)??[],a=u.get(i.to)??[],b=f.x+232,g=f.y+tn(w.indexOf(i),w.length),A=x.x,z=x.y+tn(a.indexOf(i),a.length),oe=A>b?Math.max(32,(A-b)*.5):90,re=`M ${b} ${g} C ${b+oe} ${g}, ${A-oe} ${z}, ${A} ${z}`;return{...i,d:re,sx:b,sy:g,tx:A,ty:z}})}function zt(e,t,r){let s=new Set,c=[t];for(;c.length>0;){let u=c.pop();for(let i of e){let f=r==="down"?i.from===u?i.to:void 0:i.to===u?i.from:void 0;f!==void 0&&!s.has(f)&&f!==t&&(s.add(f),c.push(f))}}return s}function nn(e){let t=Math.max(0,Math.round(e/1e3));if(t<60)return`${t}s`;let r=Math.floor(t/60);return r<60?`${r}m ${String(t%60).padStart(2,"0")}s`:`${Math.floor(r/60)}h ${String(r%60).padStart(2,"0")}m`}function jt(e){if(e)return e.includes("/")?e.slice(e.indexOf("/")+1):e}function rn(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(e>=1e4?0:1)}k`:String(e)}var Nn={running:"running",queued:"queued",completed:"completed",failed:"failed",cancelled:"cancelled",idle:"idle"};function Ae(e,t){if(e.kind==="root")return e.rawStatus;let r=e.rawStatus===e.state?Nn[e.state]:e.rawStatus,s=e.startedAt;return s===void 0?r:e.state==="running"?`${r} \xB7 ${nn(t-s)}`:e.endedAt!==void 0?`${r} \xB7 ${nn(e.endedAt-s)}`:r}var Ze=class{drag;get active(){return this.drag!==void 0}down(t,r){t.button===0&&(this.drag={id:t.pointerId,x:t.clientX,y:t.clientY,vx:r.x,vy:r.y,moved:!1})}move(t){let r=this.drag;if(!r||t.pointerId!==r.id)return;if((t.buttons&1)===0)return"end";let s=t.clientX-r.x,c=t.clientY-r.y;if(!r.moved&&Math.hypot(s,c)<4)return;let u=!r.moved;return r.moved=!0,{x:r.vx+s,y:r.vy+c,started:u}}end(t){let r=this.drag;return!r||t!==void 0&&t!==r.id?!1:(this.drag=void 0,r.moved)}};var Pn=new Set(["running","queued","completed","failed","cancelled","idle"]),ye=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),te=e=>typeof e=="number"&&Number.isFinite(e),ke=e=>e===void 0||typeof e=="string",he=e=>e===void 0||te(e),Dn=e=>typeof e=="string"&&Pn.has(e);function Hn(e){return ye(e)?typeof e.id=="string"&&(e.kind==="root"||e.kind==="task")&&typeof e.sessionId=="string"&&typeof e.title=="string"&&Dn(e.state)&&typeof e.rawStatus=="string"&&ke(e.agent)&&ke(e.model)&&he(e.createdAt)&&he(e.startedAt)&&he(e.endedAt)&&ke(e.summary)&&ke(e.error)&&he(e.tokens)&&he(e.costUsd)&&he(e.toolCalls)&&ke(e.parentId)&&te(e.column)&&te(e.wave):!1}function $n(e){return ye(e)&&typeof e.id=="string"&&typeof e.from=="string"&&typeof e.to=="string"&&(e.kind==="spawn"||e.kind==="uses")}function Fn(e){return ye(e)&&te(e.column)&&te(e.total)&&te(e.done)&&te(e.running)}function Xn(e){return ye(e)&&te(e.omittedNodes)&&Number.isInteger(e.omittedNodes)&&e.omittedNodes>=0}function Bn(e){return ye(e)&&(e.status==="ok"||e.status==="unknown-session")&&typeof e.rootId=="string"&&typeof e.focusId=="string"&&typeof e.title=="string"&&Array.isArray(e.nodes)&&e.nodes.every(Hn)&&Array.isArray(e.edges)&&e.edges.every($n)&&Array.isArray(e.columns)&&e.columns.every(Fn)&&te(e.models)&&(e.truncated===void 0||Xn(e.truncated))}function Vn(e){let t=JSON.parse(e);if(!Bn(t))throw new Error("service answered with an unexpected graph shape");return t}var et=class{constructor(t){this.deps=t}deps;session=void 0;generation=0;inFlight=!1;pending=!1;signature="";setSession(t){t!==this.session&&(this.session=t,this.invalidate())}invalidate(){this.generation++,this.signature="",this.refresh()}async refresh(){let t=this.session;if(t===void 0)return;if(t===null){this.signature="",this.deps.show({kind:"no-session"});return}if(this.deps.isHidden()){this.deps.schedule(5e3,()=>{this.refresh()});return}if(this.inFlight){this.pending=!0;return}this.inFlight=!0;let r=this.generation;try{let s=await this.deps.fetch(t);if(r!==this.generation)return;if(s.status!==200)throw new Error(`service answered HTTP ${s.status}: ${s.body.slice(0,200)}`);let c=Vn(s.body);c.status!=="ok"||c.nodes.length<=1?(this.signature="",this.deps.show({kind:"empty"})):s.body!==this.signature&&(this.signature=s.body,this.deps.show({kind:"graph",graph:c}));let u=c.nodes.some(i=>i.state==="running"||i.state==="queued");this.deps.schedule(u?1500:5e3,()=>{this.refresh()})}catch(s){if(r!==this.generation)return;this.signature="",this.deps.show({kind:"error",error:s}),this.deps.schedule(1e4,()=>{this.refresh()})}finally{this.inFlight=!1,(this.pending||r!==this.generation)&&(this.pending=!1,this.refresh())}}};var sn="http://www.w3.org/2000/svg";document.documentElement.style.setProperty("--node-card-width",`${232}px`);document.documentElement.style.setProperty("--node-card-height",`${80}px`);var W=Ct(),P=e=>document.querySelector(e),h={app:P("#app"),title:P("#title"),titleDot:P("#title-dot"),meta:P("#meta"),viewport:P("#viewport"),world:P("#world"),edges:P("#edges"),bands:P("#bands"),nodes:P("#nodes"),empty:P("#empty"),inspector:P("#inspector"),settings:P("#settings")},ve=null,pn=!1,M,D,an="",Y,ie={},Kt,y={x:0,y:0,k:1},me=new Map;function k(e,t="",r=""){let s=document.createElement(e);return t&&(s.className=t),r&&(s.textContent=r),s}function Wt(e,t=""){h.empty.replaceChildren(k("strong","",e),...t?[k("p","",t)]:[]),h.empty.hidden=!1,h.world.hidden=!0,h.inspector.hidden=!0}function Qt(e){return e instanceof p?e.code==="NO_SERVICE"?["Local service not allowed yet","Approve OmO Graph in Settings \u2192 Extensions so it can read the OmO task store."]:e.code==="SERVICE_FAILED"?["The local service did not start","Check Settings \u2192 Extensions; the next refresh retries it."]:e.code==="DISABLED"?["OmO Graph is paused","Resume it in Settings \u2192 Extensions."]:[`Request failed (${e.code})`,e.message]:["Request failed",e instanceof Error?e.message:String(e)]}function _e(){h.world.style.transform=`translate(${y.x}px, ${y.y}px) scale(${y.k})`,h.app.style.setProperty("--zoom",String(y.k))}function tt(){if(!D)return;let e=h.viewport.clientWidth,t=h.viewport.clientHeight,r=Math.min(1,Math.max(.62,Math.min((e-16)/D.width,(t-16)/D.height)));y.k=r,y.x=Math.round(D.width*r<=e?(e-D.width*r)/2:8),y.y=Math.round(Math.max(8,(t-D.height*r)/2)),_e()}function un(e){let t=e?D?.boxes.get(e):void 0;if(!t)return tt();y.k=Math.max(y.k,.8),y.x=Math.round(h.viewport.clientWidth/2-(t.x+232/2)*y.k),y.y=Math.round(h.viewport.clientHeight/2-(t.y+80/2)*y.k),_e()}function Re(e,t=h.viewport.clientWidth/2,r=h.viewport.clientHeight/2){let s=Math.min(2,Math.max(.2,y.k*e));y.x=t-(t-y.x)*s/y.k,y.y=r-(r-y.y)*s/y.k,y.k=s,_e()}var we=new Ze,Jt=!1;function Zt(e,t=!1){if(!we.active)return;let r=we.end(e);we.active||(r&&t&&(Jt=!0,setTimeout(()=>{Jt=!1},0)),h.app.classList.remove("is-panning"))}h.viewport.addEventListener("pointerdown",e=>we.down(e,y));window.addEventListener("pointermove",e=>{let t=we.move(e);if(t==="end")return Zt(e.pointerId);t&&(t.started&&(h.viewport.setPointerCapture?.(e.pointerId),h.app.classList.add("is-panning")),y.x=t.x,y.y=t.y,_e())});window.addEventListener("pointerup",e=>Zt(e.pointerId,!0));window.addEventListener("pointercancel",e=>Zt(e.pointerId));h.viewport.addEventListener("dragstart",e=>e.preventDefault());h.viewport.addEventListener("wheel",e=>{e.preventDefault();let t=h.viewport.getBoundingClientRect();e.ctrlKey||e.metaKey||Math.abs(e.deltaY)>Math.abs(e.deltaX)*2&&!e.shiftKey?Re(Math.exp(-e.deltaY*(e.ctrlKey?.01:.0015)),e.clientX-t.left,e.clientY-t.top):(y.x-=e.deltaX||(e.shiftKey?e.deltaY:0),y.y-=e.shiftKey?0:e.deltaY,_e())},{passive:!1});P("#btn-fit").addEventListener("click",tt);P("#btn-locate").addEventListener("click",()=>{let e=M?.nodes.find(t=>t.kind==="task"&&t.state==="running");un(M?.focusId!==M?.rootId?M?.focusId:e?.id??M?.rootId)});P("#btn-in").addEventListener("click",()=>Re(1.2));P("#btn-out").addEventListener("click",()=>Re(1/1.2));window.addEventListener("keydown",e=>{e.target instanceof HTMLInputElement||(e.key==="0"?tt():e.key==="+"||e.key==="="?Re(1.2):e.key==="-"&&Re(1/1.2))});function Oe(e){if(Y=e,!M)return;let t=M.edges,r=new Set(e?t.filter(i=>i.to===e).map(i=>i.from):[]),s=new Set(e?t.filter(i=>i.from===e).map(i=>i.to):[]),c=e?zt(t,e,"up"):new Set,u=e?zt(t,e,"down"):new Set;h.app.classList.toggle("has-hover",e!==void 0);for(let[i,f]of me)f.classList.toggle("is-hover",i===e),f.classList.toggle("is-input",r.has(i)),f.classList.toggle("is-output",s.has(i)),f.classList.toggle("is-reach",c.has(i)||u.has(i));for(let i of h.edges.querySelectorAll("path[data-edge]")){let f=i.dataset.from??"",x=i.dataset.to??"";i.classList.toggle("is-in",e!==void 0&&x===e),i.classList.toggle("is-out",e!==void 0&&f===e),i.classList.toggle("is-reach",e!==void 0&&(c.has(f)&&(c.has(x)||x===e)||u.has(x)&&(u.has(f)||f===e)))}zn()}function zn(){let e=M?.nodes.find(w=>w.id===(Y??(M?.focusId!==M?.rootId?M?.focusId:void 0)));if(!e||!M){h.inspector.hidden=!0;return}let t=M.edges.filter(w=>w.to===e.id).length,r=M.edges.filter(w=>w.from===e.id).length,s=[Ae(e,Date.now())];e.agent&&s.push(e.agent);let c=jt(e.model);c&&s.push(c),e.toolCalls!==void 0&&s.push(`${e.toolCalls} tools`),e.tokens!==void 0&&s.push(`${rn(e.tokens)} tok`),e.costUsd!==void 0&&s.push(`$${e.costUsd.toFixed(2)}`);let u=k("div","i-head");u.append(k("span",`dot s-${e.state}`),k("strong","",e.title));let i=k("div","i-flow");i.append(k("span","i-in",`\u2190 ${t} input${t===1?"":"s"}`),k("span","i-out",`${r} output${r===1?"":"s"} \u2192`));let f=[u,k("div","i-facts",s.join(" \xB7 ")),i],x=e.error??e.summary;x&&f.push(k("p",e.error?"i-text is-error":"i-text",x)),f.push(k("div","i-hint",e.kind==="root"?"Click to open the orchestrating session":"Click to open this sub-agent's session")),h.inspector.replaceChildren(...f),h.inspector.hidden=!1}function jn(e){let t=me.get(e.id);return t||(t=k("button","node"),t.type="button",t.dataset.id=e.id,t.append(k("div","n-head"),k("div","n-status"),k("div","n-meta"),k("div","n-sub")),t.querySelector(".n-head")?.append(k("span","dot"),k("span","n-title")),t.addEventListener("pointerenter",()=>Oe(e.id)),t.addEventListener("pointerleave",()=>{Y===e.id&&Oe(void 0)}),t.addEventListener("focus",()=>Oe(e.id)),t.addEventListener("blur",()=>{Y===e.id&&Oe(void 0)}),t.addEventListener("click",()=>{Jt||Yn(e.id)}),me.set(e.id,t),h.nodes.append(t)),t}function Kn(e,t,r){e.className=`node k-${t.kind} s-${t.state}${M?.focusId===t.id&&t.kind==="task"?" is-current":""}`,Y===t.id&&e.classList.add("is-hover"),e.setAttribute("aria-label",`${t.title}, ${Ae(t,r)}. Open session.`);let s=(c,u)=>{let i=e.querySelector(c);i&&i.textContent!==u&&(i.textContent=u)};s(".n-title",t.title),s(".n-status",Ae(t,r)),s(".n-meta",t.kind==="root"?`${M?.nodes.length?M.nodes.length-1:0} sub-agents`:[t.agent,jt(t.model)].filter(Boolean).join(" \xB7 ")),s(".n-sub",t.error??t.summary??""),e.querySelector(".dot")?.setAttribute("class",`dot s-${t.state}`)}function Wn(e){M=e,D=on(e),h.world.hidden=!1,h.empty.hidden=!0,h.world.style.width=`${D.width}px`,h.world.style.height=`${D.height}px`,h.edges.setAttribute("width",String(D.width)),h.edges.setAttribute("height",String(D.height)),h.edges.setAttribute("viewBox",`0 0 ${D.width} ${D.height}`);let t=new Map(e.nodes.map(a=>[a.id,a.state])),r=document.createDocumentFragment();for(let a of D.edges){let b=document.createElementNS(sn,"path");b.setAttribute("d",a.d),b.dataset.edge=a.id,b.dataset.from=a.from,b.dataset.to=a.to;let g=t.get(a.to)==="running"||t.get(a.to)==="queued";if(b.setAttribute("class",`edge k-${a.kind}${g?" is-live":""}`),b.setAttribute("marker-end","url(#arrow)"),r.append(b),g){let A=document.createElementNS(sn,"path");A.setAttribute("d",a.d),A.setAttribute("class","flow"),A.setAttribute("pathLength","1"),r.append(A)}}h.edges.querySelectorAll("path.edge, path.flow").forEach(a=>a.remove()),h.edges.append(r),h.bands.replaceChildren(...[...D.columnX].map(([a,b])=>{let g=k("div","band");g.style.left=`${b}px`,g.style.width=`${232}px`;let A=e.columns.find(z=>z.column===a);return a===0?g.textContent="Orchestrator":A&&(g.textContent=`Wave ${a} \xB7 ${A.done}/${A.total} done${A.running?` \xB7 ${A.running} running`:""}`),A?.running&&g.classList.add("is-live"),g}));let s=Date.now(),c=new Set;for(let a of e.nodes){let b=jn(a),g=D.boxes.get(a.id);g&&(b.style.transform=`translate(${g.x}px, ${g.y}px)`),Kn(b,a,s),c.add(a.id)}for(let[a,b]of me)c.has(a)||(b.remove(),me.delete(a));let u=e.nodes.filter(a=>a.kind==="task"),i=u.filter(a=>a.state==="completed"||a.state==="failed"||a.state==="cancelled").length,f=u.filter(a=>a.state==="running").length,x=e.columns.length,w=e.columns.find(a=>a.running>0||a.done<a.total)?.column;h.title.textContent=e.title,h.titleDot.className=`dot s-${f>0?"running":u.some(a=>a.state==="failed")?"failed":i===u.length?"completed":"idle"}`,h.meta.textContent=[w!==void 0?`wave ${w}/${x}`:`${x} wave${x===1?"":"s"}`,`${i}/${u.length} done`,...f?[`${f} running`]:[],...e.models?[`${e.models} model${e.models===1?"":"s"}`]:[],...e.truncated?[`${e.truncated.omittedNodes} omitted`]:[]].join(" \xB7 "),W.setBadge(f>0?f:null).catch(()=>{}),an!==e.rootId&&(an=e.rootId,requestAnimationFrame(()=>e.focusId!==e.rootId?un(e.focusId):tt())),Y&&!e.nodes.some(a=>a.id===Y)&&(Y=void 0),Oe(Y)}function Jn(){if(!M)return;let e=Date.now();for(let t of M.nodes){if(t.state!=="running")continue;let s=me.get(t.id)?.querySelector(".n-status");s&&(s.textContent=Ae(t,e))}}setInterval(Jn,1e3);async function Yn(e){let t=M?.nodes.find(r=>r.id===e);if(t)try{await W.openSession(t.sessionId)}catch(r){let[s,c]=Qt(r);await W.toast({kind:"error",message:`${s}: ${c}`}).catch(()=>{})}}var Le=new et({fetch:e=>{let t={session:e};return ie.agentDir&&(t.agentDir=ie.agentDir),ie.stateDir&&(t.stateDir=ie.stateDir),W.serviceRequest({method:"GET",path:"/graph",query:t})},show:e=>{if(e.kind==="graph"){Wn(e.graph);return}M=void 0,W.setBadge(null).catch(()=>{}),e.kind==="no-session"?Wt("No session open","Open a chat to see the OmO agents working behind it."):e.kind==="empty"?Wt("No sub-agents yet","When this session launches OmO tasks or workflows, they appear here as a live graph."):Wt(...Qt(e.error))},schedule:(e,t)=>{Kt&&clearTimeout(Kt),Kt=setTimeout(t,e)},isHidden:()=>document.hidden});function qn(e){return e.state==="ready"?`antechamber ${e.antechamber}${e.omo?` with OmO ${e.omo}`:""} is installed.`:e.state==="installing"?`Installing antechamber ${e.spec} and its OmO with Bun\u2026`:e.state==="failed"?`Install failed: ${e.error??"unknown error"}`:`antechamber ${e.spec} is not installed yet.`}async function Yt(e=!1){let t=P("#runtime");try{let r=await W.serviceRequest({method:e?"POST":"GET",path:e?"/runtime/install":"/runtime"}),s=JSON.parse(r.body);t.dataset.state=s.state;let c=k("button","",s.state==="failed"?"Retry install":"Install now");c.type="button",c.addEventListener("click",()=>{Yt(!0)});let u=[k("strong","","Runtime"),k("span","",qn(s)),k("span","","OpenCode CLI path for Settings \u2192 OpenCode CLI:"),k("code","",s.launcher)];if(s.state==="missing"||s.state==="failed"){let i=k("div","row");i.append(c),u.push(i)}t.replaceChildren(...u),s.state==="installing"&&setTimeout(()=>{Yt()},2e3)}catch(r){t.dataset.state="failed",t.replaceChildren(k("strong","","Runtime"),k("span","",Qt(r).join(": ")))}}var cn=P("#btn-settings");cn.addEventListener("click",()=>{h.settings.hidden=!h.settings.hidden,cn.setAttribute("aria-expanded",String(!h.settings.hidden)),h.settings.hidden||(Yt(),h.settings.querySelector("input")?.focus())});P("#btn-save").addEventListener("click",()=>{let e=new FormData(h.settings),t={},r=String(e.get("agentDir")??"").trim(),s=String(e.get("stateDir")??"").trim();r&&(t.agentDir=r),s&&(t.stateDir=s),ie=t,h.settings.hidden=!0,W.storage.set("paths",t).catch(()=>{}),Le.invalidate()});function Qn(){for(let e of["agentDir","stateDir"]){let t=h.settings.querySelector(`input[name="${e}"]`);t&&(t.value=ie[e]??"")}}var dn=!1;W.onReady(e=>{Ut(e,document.documentElement),h.app.dataset.surface=e.surface,!dn&&(dn=!0,ve=e.session?.id??ve,W.storage.get("paths").then(t=>{if(t&&typeof t=="object"&&!Array.isArray(t)){let r=t;ie={...typeof r.agentDir=="string"?{agentDir:r.agentDir}:{},...typeof r.stateDir=="string"?{stateDir:r.stateDir}:{}}}Qn()}).catch(()=>{}).finally(()=>{pn=!0,Le.setSession(ve)}))});W.onSession(e=>{let t=e?.id??null;t!==ve&&(Y=void 0),ve=t,pn&&Le.setSession(t)});W.onSessionLifecycle(()=>{Le.refresh()});document.addEventListener("visibilitychange",()=>{document.hidden||Le.refresh()});window.addEventListener("resize",()=>{D&&y.k<=1&&_e()});})();
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
// extensions/antechamber/src/runtime/launcher.ts
|
|
2
|
+
import { readFileSync as readFileSync2 } from "node:fs";
|
|
3
|
+
import { dirname, join as join2, resolve as resolve2 } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
// extensions/antechamber/src/runtime/runtime.ts
|
|
7
|
+
import { spawn } from "node:child_process";
|
|
8
|
+
import { createHash } from "node:crypto";
|
|
9
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
10
|
+
import { homedir } from "node:os";
|
|
11
|
+
import { delimiter, isAbsolute, join, resolve } from "node:path";
|
|
12
|
+
var STALE_LOCK_MS = 15 * 6e4;
|
|
13
|
+
var INSTALL_TIMEOUT_MS = 10 * 6e4;
|
|
14
|
+
var READY = ".ready.json";
|
|
15
|
+
var ERROR_TAIL_CHARS = 2e3;
|
|
16
|
+
function defaultEnv() {
|
|
17
|
+
return { env: process.env, home: homedir() };
|
|
18
|
+
}
|
|
19
|
+
function runtimeRoot({ env, home }) {
|
|
20
|
+
const configured = env.ANTECHAMBER_RUNTIME_DIR?.trim();
|
|
21
|
+
return configured ? resolve(configured) : join(home, ".antechamber", "runtime");
|
|
22
|
+
}
|
|
23
|
+
function runtimePaths(version, runtime) {
|
|
24
|
+
const root = runtimeRoot(runtime);
|
|
25
|
+
const override = runtime.env.ANTECHAMBER_RUNTIME_SPEC?.trim();
|
|
26
|
+
if (!override) return { root, spec: version, key: version, dir: join(root, version) };
|
|
27
|
+
const spec = isAbsolute(override) ? override : resolve(override);
|
|
28
|
+
const stamp = existsSync(spec) ? `${statSync(spec).mtimeMs}:${statSync(spec).size}` : "";
|
|
29
|
+
const key = `local-${createHash("sha256").update(`${spec}
|
|
30
|
+
${stamp}`).digest("hex").slice(0, 12)}`;
|
|
31
|
+
return { root, spec: `file:${spec}`, key, dir: join(root, key) };
|
|
32
|
+
}
|
|
33
|
+
function findBun({ env, home }, exists = existsSync) {
|
|
34
|
+
for (const dir of (env.PATH ?? "").split(delimiter)) {
|
|
35
|
+
if (dir && exists(join(dir, "bun"))) return join(dir, "bun");
|
|
36
|
+
}
|
|
37
|
+
for (const candidate of [
|
|
38
|
+
join(env.BUN_INSTALL ?? join(home, ".bun"), "bin", "bun"),
|
|
39
|
+
join(home, ".bun", "bin", "bun")
|
|
40
|
+
]) {
|
|
41
|
+
if (exists(candidate)) return candidate;
|
|
42
|
+
}
|
|
43
|
+
return void 0;
|
|
44
|
+
}
|
|
45
|
+
function readJson(path) {
|
|
46
|
+
try {
|
|
47
|
+
const value = JSON.parse(readFileSync(path, "utf8"));
|
|
48
|
+
return typeof value === "object" && value !== null ? value : void 0;
|
|
49
|
+
} catch {
|
|
50
|
+
return void 0;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function installed(dir) {
|
|
54
|
+
if (!existsSync(join(dir, READY))) return void 0;
|
|
55
|
+
const cli = join(dir, "node_modules", "antechamber", "dist", "cli.js");
|
|
56
|
+
const antechamber = readJson(join(dir, "node_modules", "antechamber", "package.json"))?.version;
|
|
57
|
+
if (!existsSync(cli) || typeof antechamber !== "string") return void 0;
|
|
58
|
+
const omo = readJson(join(dir, "node_modules", "omo-ai", "package.json"))?.version;
|
|
59
|
+
return { dir, cli, antechamber, omo: typeof omo === "string" ? omo : void 0 };
|
|
60
|
+
}
|
|
61
|
+
function lockHeld(lock, deps) {
|
|
62
|
+
let mtime;
|
|
63
|
+
try {
|
|
64
|
+
mtime = statSync(lock).mtimeMs;
|
|
65
|
+
} catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
const pid = Number.parseInt(readFileSync(join(lock, "pid"), { encoding: "utf8", flag: "a+" }), 10);
|
|
69
|
+
if (deps.now() - mtime > STALE_LOCK_MS) return false;
|
|
70
|
+
return !Number.isInteger(pid) || deps.pidAlive(pid);
|
|
71
|
+
}
|
|
72
|
+
function tryLock(lock, deps) {
|
|
73
|
+
try {
|
|
74
|
+
mkdirSync(lock);
|
|
75
|
+
} catch (error) {
|
|
76
|
+
if (error.code !== "EEXIST") throw error;
|
|
77
|
+
if (lockHeld(lock, deps)) return false;
|
|
78
|
+
rmSync(lock, { recursive: true, force: true });
|
|
79
|
+
return tryLock(lock, deps);
|
|
80
|
+
}
|
|
81
|
+
writeFileSync(join(lock, "pid"), String(process.pid));
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
function prune(paths) {
|
|
85
|
+
const others = readdirSync(paths.root, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name !== paths.key && !/\.(lock|tmp-.*)$/.test(entry.name)).map((entry) => join(paths.root, entry.name)).filter((dir) => existsSync(join(dir, READY)) && !existsSync(`${dir}.lock`)).map((dir) => ({ dir, at: Number(readJson(join(dir, READY))?.installedAt ?? 0) })).sort((a, b) => b.at - a.at);
|
|
86
|
+
for (const { dir } of others.slice(1)) rmSync(dir, { recursive: true, force: true });
|
|
87
|
+
}
|
|
88
|
+
async function installOnce(paths, bun, deps) {
|
|
89
|
+
const staging = `${paths.dir}.tmp-${process.pid}-${deps.now()}`;
|
|
90
|
+
mkdirSync(staging, { recursive: true });
|
|
91
|
+
try {
|
|
92
|
+
const manifest = {
|
|
93
|
+
name: "antechamber-runtime",
|
|
94
|
+
private: true,
|
|
95
|
+
dependencies: { antechamber: paths.spec },
|
|
96
|
+
// omo-ai's postinstall prepares its engine; Bun skips dependency scripts unless trusted.
|
|
97
|
+
trustedDependencies: ["omo-ai"]
|
|
98
|
+
};
|
|
99
|
+
writeFileSync(join(staging, "package.json"), `${JSON.stringify(manifest, null, 2)}
|
|
100
|
+
`);
|
|
101
|
+
await deps.install(bun, staging);
|
|
102
|
+
writeFileSync(join(staging, READY), `${JSON.stringify({ spec: paths.spec, installedAt: deps.now() })}
|
|
103
|
+
`);
|
|
104
|
+
if (!installed(staging)) throw new Error(`bun install did not produce node_modules/antechamber/dist/cli.js`);
|
|
105
|
+
rmSync(paths.dir, { recursive: true, force: true });
|
|
106
|
+
renameSync(staging, paths.dir);
|
|
107
|
+
} catch (error) {
|
|
108
|
+
rmSync(staging, { recursive: true, force: true });
|
|
109
|
+
throw error;
|
|
110
|
+
}
|
|
111
|
+
const runtime = installed(paths.dir);
|
|
112
|
+
if (!runtime) throw new Error(`runtime vanished from ${paths.dir}`);
|
|
113
|
+
return runtime;
|
|
114
|
+
}
|
|
115
|
+
async function ensureRuntime(paths, bun, deps = defaultDeps()) {
|
|
116
|
+
const lock = `${paths.dir}.lock`;
|
|
117
|
+
for (; ; ) {
|
|
118
|
+
const ready = installed(paths.dir);
|
|
119
|
+
if (ready) return ready;
|
|
120
|
+
if (!bun) throw new Error("bun not found on PATH or in ~/.bun/bin; install it from https://bun.sh");
|
|
121
|
+
mkdirSync(paths.root, { recursive: true });
|
|
122
|
+
if (!tryLock(lock, deps)) {
|
|
123
|
+
await deps.pause();
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
const raced = installed(paths.dir);
|
|
128
|
+
if (raced) return raced;
|
|
129
|
+
const runtime = await installOnce(paths, bun, deps);
|
|
130
|
+
rmSync(`${paths.dir}.error`, { force: true });
|
|
131
|
+
prune(paths);
|
|
132
|
+
return runtime;
|
|
133
|
+
} catch (error) {
|
|
134
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
135
|
+
writeFileSync(`${paths.dir}.error`, message.slice(-ERROR_TAIL_CHARS));
|
|
136
|
+
throw error;
|
|
137
|
+
} finally {
|
|
138
|
+
rmSync(lock, { recursive: true, force: true });
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function bunInstall(bun, cwd) {
|
|
143
|
+
return new Promise((resolvePromise, reject) => {
|
|
144
|
+
const child = spawn(bun, ["install", "--production", "--no-progress"], {
|
|
145
|
+
cwd,
|
|
146
|
+
env: process.env,
|
|
147
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
148
|
+
});
|
|
149
|
+
let output = "";
|
|
150
|
+
const keep = (chunk) => {
|
|
151
|
+
output = (output + chunk.toString("utf8")).slice(-ERROR_TAIL_CHARS);
|
|
152
|
+
};
|
|
153
|
+
child.stdout.on("data", keep);
|
|
154
|
+
child.stderr.on("data", keep);
|
|
155
|
+
const timer = setTimeout(() => child.kill("SIGTERM"), INSTALL_TIMEOUT_MS);
|
|
156
|
+
child.on("error", (error) => {
|
|
157
|
+
clearTimeout(timer);
|
|
158
|
+
reject(error);
|
|
159
|
+
});
|
|
160
|
+
child.on("close", (code, signal) => {
|
|
161
|
+
clearTimeout(timer);
|
|
162
|
+
if (code === 0) resolvePromise();
|
|
163
|
+
else reject(new Error(`bun install failed (${signal ?? `exit ${code}`}): ${output.trim()}`));
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
function defaultDeps() {
|
|
168
|
+
return {
|
|
169
|
+
install: bunInstall,
|
|
170
|
+
pause: () => new Promise((done) => setTimeout(done, 500)),
|
|
171
|
+
now: Date.now,
|
|
172
|
+
pidAlive: (pid) => {
|
|
173
|
+
try {
|
|
174
|
+
process.kill(pid, 0);
|
|
175
|
+
return true;
|
|
176
|
+
} catch (error) {
|
|
177
|
+
return error.code === "EPERM";
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// extensions/antechamber/src/runtime/launcher.ts
|
|
184
|
+
var extensionDir = resolve2(dirname(fileURLToPath(import.meta.url)), "..");
|
|
185
|
+
var command = process.argv[2];
|
|
186
|
+
if (command === "version") {
|
|
187
|
+
console.log(`opencode v${"2.999.0"}`);
|
|
188
|
+
} else if (command === "resolve") {
|
|
189
|
+
const { version } = JSON.parse(readFileSync2(join2(extensionDir, "package.json"), "utf8"));
|
|
190
|
+
const env = defaultEnv();
|
|
191
|
+
try {
|
|
192
|
+
const runtime = await ensureRuntime(runtimePaths(version, env), findBun(env) ?? process.execPath);
|
|
193
|
+
console.log(runtime.cli);
|
|
194
|
+
} catch (error) {
|
|
195
|
+
console.error(`opencode-antechamber: ${error instanceof Error ? error.message : String(error)}`);
|
|
196
|
+
process.exit(1);
|
|
197
|
+
}
|
|
198
|
+
} else {
|
|
199
|
+
console.error(`opencode-antechamber: unknown launcher command '${command ?? ""}'`);
|
|
200
|
+
process.exit(2);
|
|
201
|
+
}
|