antechamber 0.1.1 → 0.2.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.
Files changed (59) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +24 -14
  3. package/bin/opencode-antechamber +14 -1
  4. package/bin/opencode-pi +11 -1
  5. package/dist/approvals.d.ts +4 -1
  6. package/dist/approvals.js +51 -33
  7. package/dist/catalog.d.ts +1 -1
  8. package/dist/catalog.js +1 -1
  9. package/dist/commands/context.d.ts +0 -1
  10. package/dist/commands/context.js +1 -1
  11. package/dist/commands/doctor.d.ts +3 -2
  12. package/dist/commands/serve.d.ts +2 -1
  13. package/dist/commands/setup.d.ts +2 -3
  14. package/dist/commands/setup.js +16 -4
  15. package/dist/http.d.ts +8 -1
  16. package/dist/http.js +42 -19
  17. package/dist/pi-event-translation.d.ts +10 -6
  18. package/dist/pi-event-translation.js +237 -80
  19. package/dist/pi-rpc.d.ts +20 -2
  20. package/dist/pi-rpc.js +96 -29
  21. package/dist/prompt-parts.d.ts +40 -0
  22. package/dist/prompt-parts.js +157 -0
  23. package/dist/route-services.d.ts +45 -2
  24. package/dist/route-services.js +70 -3
  25. package/dist/routes-v1.js +113 -65
  26. package/dist/routes-v2.js +407 -95
  27. package/dist/server.d.ts +9 -1
  28. package/dist/server.js +109 -9
  29. package/dist/session-commands.d.ts +12 -15
  30. package/dist/session-commands.js +54 -13
  31. package/dist/session-diff.d.ts +1 -1
  32. package/dist/session-diff.js +10 -2
  33. package/dist/session-history.d.ts +1 -1
  34. package/dist/session-history.js +110 -44
  35. package/dist/session-hosts.js +2 -2
  36. package/dist/session-store.d.ts +8 -4
  37. package/dist/session-store.js +191 -38
  38. package/dist/session-tree.d.ts +10 -2
  39. package/dist/session-tree.js +55 -26
  40. package/dist/sessions.d.ts +32 -5
  41. package/dist/sessions.js +331 -120
  42. package/dist/sse.d.ts +16 -6
  43. package/dist/sse.js +77 -21
  44. package/dist/subagents.d.ts +5 -0
  45. package/dist/subagents.js +84 -71
  46. package/dist/tool-map.d.ts +3 -2
  47. package/dist/types.d.ts +152 -1
  48. package/dist/v2.d.ts +18 -4
  49. package/dist/v2.js +128 -44
  50. package/dist/vcs.d.ts +5 -0
  51. package/dist/vcs.js +199 -0
  52. package/dist/version.d.ts +1 -1
  53. package/dist/version.js +1 -1
  54. package/extensions/omo-dag/README.md +2 -0
  55. package/extensions/omo-dag/docs/DESIGN.md +10 -1
  56. package/extensions/omo-dag/panel/index.html +1 -1
  57. package/extensions/omo-dag/panel/main.js +60 -60
  58. package/extensions/omo-dag/service/main.js +72 -8
  59. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- "use strict";(()=>{var x="openchamber.sdk";var De=`
1
+ "use strict";(()=>{var k="openchamber.sdk";var Be=`
2
2
  :root {
3
3
  --oc-scrollbar-thumb: color-mix(in srgb, var(--oc-muted, currentColor) 40%, transparent);
4
4
  --oc-scrollbar-thumb-hover: color-mix(in srgb, var(--oc-muted, currentColor) 65%, transparent);
@@ -28,82 +28,82 @@
28
28
  * { scrollbar-color: auto; }
29
29
  ::-webkit-scrollbar-thumb, ::-webkit-scrollbar-thumb:hover { background: CanvasText; }
30
30
  }
31
- `;var Et=["file","directory","other","missing"],Pe=e=>!!(e&&"sessionId"in e),Xe=e=>!!(e&&"sent"in e&&!("sessionId"in e));var Ee=500,xe=32e3,xt=16e3,kt=128,bt=200,Tt=2e3,St=16e3,_t=80,yt=200,At=16e3;var vt=2e3;var Be=2e4,ke=1024,be=2e6;var Te=64e3,Se=8e3,Fe=4e3;var ze=9e4;var wt=999,_e=500,Mt=["HOST_UNAVAILABLE","HOST_TIMEOUT","HOST_REJECTED","DISCONNECTED","DISABLED","BAD_PATH","NO_INTEGRATION","NO_SERVICE","SERVICE_FAILED","NO_SESSION","SESSION_BUSY","NOT_GRANTED","NO_DIRECTORY","NOT_FOUND","FILE_TOO_LARGE","DENIED","NO_MODEL","MODEL_FAILED"],Ot=["stopped","starting","ready","failed"],Zt=new Set(Mt),Lt=e=>Zt.has(e),Ct=e=>e&&Lt(e)?e:"HOST_REJECTED",ne=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(ne):Object(e)===e?Object.values(e).every(ne):!1,Rt=e=>ne(e)&&JSON.stringify(e).length<=At,gt=e=>e?.trim().slice(0,yt)??"",re=e=>{let t=e.id.trim().slice(0,kt),r=e.title.trim().slice(0,bt),a=e.url.trim().slice(0,Tt),l=e.text?.trim().slice(0,St),p=e.author?.trim().slice(0,_t),s=e.kind==="pull"?"pull":"issue",c={providerId:e.providerId.trim(),id:t,title:r||t,url:a,kind:s};if(l&&(c.text=l),p&&(c.author=p),s==="pull"){let h=gt(e.branches?.head),A=gt(e.branches?.base);h&&A&&(c.branches={head:h,base:A})}return Rt(e.data)&&(c.data=e.data),c},Ke=e=>{let t=re(e);return e.projectId&&(t.projectId=e.projectId),e.navigation&&(t.navigation=e.navigation),e.worktree&&(t.worktree=e.worktree),t},je=e=>{let t={text:e.text.trim().slice(0,xt)};return e.send&&(t.send=!0),t},Ve=e=>e===null||!Number.isFinite(e)?null:Math.min(wt,Math.max(0,Math.round(e)));var se=e=>e.length>0&&e.length<=ke&&!e.includes("\0")&&!e.includes("\\");var ye=e=>!e.startsWith("/")||e.includes("\0")||e.includes("\\")||e.includes("://")||e.length>vt?!1:!e.split("/").some(r=>r==="."||r===".."),eo=new Set(Ot),Ye=e=>!!(e&&"status"in e&&eo.has(String(e.status))&&!("body"in e)),Ae=e=>!!(e&&"status"in e&&"body"in e&&Number.isInteger(e.status)),qe=e=>!!(e&&"content"in e&&String(e.content)===e.content),Je=e=>!!(e&&"written"in e&&e.written===!0),We=e=>!!(e&&"entries"in e&&Array.isArray(e.entries)),to=new Set(Et),Qe=e=>!!(e&&"kind"in e&&"size"in e&&to.has(String(e.kind))&&Number.isFinite(e.size)),Ze=e=>!!(e&&"text"in e&&String(e.text)===e.text&&!("status"in e)),oo=new Set(["workspace","ready","directory","session","connection","settings","session-lifecycle","item","resolve","action"]),no=e=>Object(e)===e?e:null,He=e=>String(e)===e&&e.length>0,ro=e=>{if(!He(e.id))return null;if(e.ok===!0){let t={channel:x,v:1,type:"result",id:e.id,ok:!0};return Object(e.payload)===e.payload&&(t.payload=e.payload),t}return e.ok===!1&&He(e.error)?{channel:x,v:1,type:"result",id:e.id,ok:!1,error:e.error,code:Ct(He(e.code)?e.code:void 0)}:null},et=e=>{let t=no(e);return!t||t.channel!==x||t.v!==1?null:t.type==="result"?ro(t):!oo.has(String(t.type))||Object(t.payload)!==t.payload?null:t};var u=class extends Error{code;constructor(t,r){super(r),this.name="HostRequestError",this.code=t}},Gt=()=>Promise.reject(new u("BAD_PATH",'Request path must start with "/" and stay on the declared origin.')),ve=()=>Promise.reject(new u("BAD_PATH",`File path must be 1 to ${ke} characters without NUL or backslash.`)),T=e=>(e.value+=1,`oc-${e.value}`),tt=(e={})=>{let t=e.target??("window"in globalThis?window:null);if(!t)throw new u("HOST_UNAVAILABLE","No window. connectHost runs in a browser frame.");let r=e.acceptSource??(o=>o===t.parent),a=e.requestTimeoutMs??Be,l=new Set,p=new Set,s=new Set,c=new Set,h=new Set,A=new Set,i=new Set,g=null,f=null,k=new Map,I=new Map,J=!1,E={value:0},S=null,Y=null,mt=o=>o?{sessionId:o.id,phase:o.busy?"started":"completed"}:null,W=o=>{t.parent.postMessage(o,"*")},U=(o,n)=>{for(let m of o)try{m(n)}catch(v){console.error(v)}},ht=o=>{if(!(o instanceof MessageEvent)||!r(o.source))return;let n=et(o.data);if(!n)return;if(n.type==="workspace"){let v=I.get(n.payload.subscriptionId);v&&U([v],n.payload.snapshot);return}if(n.type==="ready"){S=n.payload,Y=mt(n.payload.session),U(l,n.payload),U(p,n.payload.directory),U(s,n.payload.session),Y&&U(c,Y),U(h,n.payload.connection),U(A,n.payload.settings),U(i,n.payload.item);return}if(n.type==="directory"){S&&(S={...S,directory:n.payload.directory}),U(p,n.payload.directory);return}if(n.type==="session"){S&&(S={...S,session:n.payload.session}),n.payload.session?Y?.sessionId!==n.payload.session.id&&(Y=mt(n.payload.session)):Y=null,U(s,n.payload.session);return}if(n.type==="session-lifecycle"){Y=n.payload,U(c,n.payload);return}if(n.type==="connection"){S&&(S={...S,connection:n.payload.connection}),U(h,n.payload.connection);return}if(n.type==="settings"){S&&(S={...S,settings:n.payload.settings}),U(A,n.payload.settings);return}if(n.type==="item"){S&&(S={...S,item:n.payload.item}),U(i,n.payload.item);return}if(n.type==="action"){let v=R=>{J||W({channel:x,v:1,type:"action-result",id:n.id,payload:R})},F=f;if(!F){v({ok:!1,error:"This extension does not handle background actions."});return}Promise.resolve().then(()=>F(n.payload)).then(()=>v({ok:!0}),R=>{let Ne=(R instanceof Error?R.message:String(R)).trim();v({ok:!1,error:(Ne||"Action failed.").slice(0,_e)})});return}if(n.type==="resolve"){let v=R=>{W({channel:x,v:1,type:"resolve-result",id:n.id,payload:R})},F=g;if(!F){v({error:"This extension does not resolve commands."});return}Promise.resolve().then(()=>F(n.payload)).then(R=>v({item:R?re(R):null}),R=>{let Ne=(R instanceof Error?R.message:String(R)).trim();v({error:(Ne||"Command failed.").slice(0,_e)})});return}let m=k.get(n.id);if(m){if(clearTimeout(m.timer),k.delete(n.id),n.ok){m.resolve(n.payload);return}m.reject(new u(n.code,n.error))}};t.addEventListener("message",ht),W({channel:x,v:1,type:"hello"});let H=(o,n=a)=>J||t.parent===t?Promise.reject(new u("HOST_UNAVAILABLE","No host frame. This page is not in an iframe.")):new Promise((m,v)=>{let F=setTimeout(()=>{k.delete(o.id),v(new u("HOST_TIMEOUT","Host did not answer in time."))},n);k.set(o.id,{resolve:m,reject:v,timer:F}),W(o)}),P=o=>H(o).then(()=>{}),Q={channel:x,v:1},Z=(o,n=1024)=>{if(!o.trim()||o.length>n)throw new u("HOST_REJECTED",`Identity must contain 1 to ${n} characters.`)},$e=async o=>{o.kind!=="projects"&&Z(o.projectId);let n=await H({...Q,type:"workspace-read",id:T(E),payload:o});if(!n||!("kind"in n)||!("state"in n)||n.kind!==o.kind)throw new u("HOST_REJECTED","Host did not return workspace data.");return n},Ue=async(o,n)=>{o.kind!=="projects"&&Z(o.projectId);let m=T(E);I.set(m,n);try{await P({...Q,type:"workspace-subscribe",id:T(E),payload:{subscriptionId:m,query:o}})}catch(v){throw I.delete(m),J||W({...Q,type:"workspace-unsubscribe",id:T(E),payload:{subscriptionId:m}}),v}return()=>{!I.delete(m)||J||W({...Q,type:"workspace-unsubscribe",id:T(E),payload:{subscriptionId:m}})}},ge=async o=>{if("key"in o&&(o.key.length===0||o.key.length>128))throw new u("HOST_REJECTED","Storage key must contain 1 to 128 characters.");if(o.op==="set"&&!ne(o.value))throw new u("HOST_REJECTED","Storage values must be JSON.");if(o.op==="set"&&new TextEncoder().encode(JSON.stringify(o.value)).length>65536)throw new u("HOST_REJECTED","Storage value exceeds 64 KiB.");let n=await H({...Q,type:"storage",id:T(E),payload:o});if(!n||!("storage"in n)||n.op!==o.op)throw new u("HOST_REJECTED","Host did not return storage data.");return n};return{onAction:o=>(f=o,()=>{f===o&&(f=null)}),listProjects:async()=>{let o=await $e({kind:"projects"});if(o.kind!=="projects")throw new u("HOST_REJECTED","Expected projects.");return o},listWorktrees:async o=>{let n=await $e({kind:"worktrees",projectId:o});if(n.kind!=="worktrees")throw new u("HOST_REJECTED","Expected worktrees.");return n},listSessions:async o=>{let n=await $e({kind:"sessions",projectId:o});if(n.kind!=="sessions")throw new u("HOST_REJECTED","Expected sessions.");return n},onProjects:o=>Ue({kind:"projects"},n=>{n.kind==="projects"&&o(n)}),onWorktrees:(o,n)=>Ue({kind:"worktrees",projectId:o},m=>{m.kind==="worktrees"&&n(m)}),onSessions:(o,n)=>Ue({kind:"sessions",projectId:o},m=>{m.kind==="sessions"&&n(m)}),openSession:async o=>{Z(o),await P({...Q,type:"open-session",id:T(E),payload:{sessionId:o}})},storage:{get:async o=>{let n=await ge({op:"get",key:o});return n.op==="get"&&n.found?n.value:void 0},set:async(o,n)=>{await ge({op:"set",key:o,value:n})},delete:async o=>{await ge({op:"delete",key:o})},keys:async()=>{let o=await ge({op:"keys"});if(o.op!=="keys")throw new u("HOST_REJECTED","Expected storage keys.");return o.keys}},onReady:o=>(l.add(o),S&&o(S),()=>{l.delete(o)}),onDirectory:o=>(p.add(o),S&&o(S.directory),()=>{p.delete(o)}),onSession:o=>(s.add(o),S&&o(S.session),()=>{s.delete(o)}),onSessionLifecycle:o=>(c.add(o),Y&&o(Y),()=>{c.delete(o)}),onConnection:o=>(h.add(o),S&&o(S.connection),()=>{h.delete(o)}),onSettings:o=>(A.add(o),S&&o(S.settings),()=>{A.delete(o)}),onItem:o=>(i.add(o),S&&o(S.item),()=>{i.delete(o)}),onResolve:o=>(g=o,()=>{g===o&&(g=null)}),toast:o=>{let n=o.message.trim();return!n||n.length>Ee?Promise.reject(new u("HOST_REJECTED",`Toast message must contain 1 to ${Ee} characters.`)):o.copy&&o.copy!==!0&&(!o.copy.text.length||o.copy.text.length>xe)?Promise.reject(new u("HOST_REJECTED",`Toast copy text must contain 1 to ${xe} characters.`)):P({channel:x,v:1,type:"toast",id:T(E),payload:{...o,message:n}})},openUrl:o=>P({channel:x,v:1,type:"open-url",id:T(E),payload:{url:o}}),openSurface:o=>P({channel:x,v:1,type:"open-surface",id:T(E),payload:{surfaceId:o}}),writeClipboard:o=>P({channel:x,v:1,type:"clipboard-write",id:T(E),payload:{text:o}}),compose:o=>P({channel:x,v:1,type:"compose",id:T(E),payload:o}),attach:o=>P({channel:x,v:1,type:"attach",id:T(E),payload:re(o)}),startSession:async o=>{o.projectId!==void 0&&Z(o.projectId);let n=o.worktree;n&&n!==!0&&(n.kind==="existing"?Z(n.directory):(n.name!==void 0&&Z(n.name,200),n.baseBranch!==void 0&&Z(n.baseBranch,200)));let m=await H({channel:x,v:1,type:"start-session",id:T(E),payload:Ke(o)},e.requestTimeoutMs??18e4);if(!Pe(m))throw new u("HOST_REJECTED","Host did not return a session.");return m},prompt:o=>H({channel:x,v:1,type:"prompt",id:T(E),payload:je(o)}).then(n=>{if(!Xe(n))throw new u("HOST_REJECTED","Host did not return a prompt result.");return n}),sessionLink:o=>P({channel:x,v:1,type:"session-link",id:T(E),payload:re(o)}),close:()=>P({channel:x,v:1,type:"close",id:T(E)}),oauthStart:()=>P({channel:x,v:1,type:"oauth-start",id:T(E)}),oauthDisconnect:()=>P({channel:x,v:1,type:"oauth-disconnect",id:T(E)}),request:o=>(ye(o.path)?H({channel:x,v:1,type:"request",id:T(E),payload:o}):Gt()).then(n=>{if(!Ae(n))throw new u("HOST_REJECTED","Host request result was empty.");return n}),serviceRequest:o=>(ye(o.path)?H({channel:x,v:1,type:"service-request",id:T(E),payload:o}):Gt()).then(n=>{if(!Ae(n))throw new u("HOST_REJECTED","Host service request result was empty.");return n}),serviceStatus:()=>H({channel:x,v:1,type:"service-status",id:T(E)}).then(o=>{if(!Ye(o))throw new u("HOST_REJECTED","Host did not return service status.");return o}),readFile:o=>(se(o)?H({channel:x,v:1,type:"file-read",id:T(E),payload:{path:o}}):ve()).then(n=>{if(!qe(n))throw new u("HOST_REJECTED","Host did not return file content.");return n}),writeFile:(o,n)=>se(o)?n.length>be?Promise.reject(new u("FILE_TOO_LARGE",`Content is over ${be} characters.`)):H({channel:x,v:1,type:"file-write",id:T(E),payload:{path:o,content:n}}).then(m=>{if(!Je(m))throw new u("HOST_REJECTED","Host did not confirm the write.");return m}):ve(),listDir:o=>(se(o)?H({channel:x,v:1,type:"file-list",id:T(E),payload:{path:o}}):ve()).then(n=>{if(!We(n))throw new u("HOST_REJECTED","Host did not return directory entries.");return n}),stat:o=>(se(o)?H({channel:x,v:1,type:"file-stat",id:T(E),payload:{path:o}}):ve()).then(n=>{if(!Qe(n))throw new u("HOST_REJECTED","Host did not return file status.");return n}),generate:o=>{let n=o.prompt.trim(),m=o.system?.trim();if(n.length===0||n.length>Te)return Promise.reject(new u("HOST_REJECTED",`Prompt must be 1 to ${Te} characters.`));if(m!==void 0&&(m.length===0||m.length>Se))return Promise.reject(new u("HOST_REJECTED",`System prompt must be 1 to ${Se} characters.`));let v=o.maxOutputTokens===void 0?void 0:Math.min(Fe,Math.max(1,Math.floor(o.maxOutputTokens)));if(v!==void 0&&!Number.isFinite(v))return Promise.reject(new u("HOST_REJECTED","maxOutputTokens must be a number."));let F={prompt:n};return m!==void 0&&(F.system=m),v!==void 0&&(F.maxOutputTokens=v),H({channel:x,v:1,type:"generate",id:T(E),payload:F},e.requestTimeoutMs??ze).then(R=>{if(!Ze(R))throw new u("HOST_REJECTED","Host did not return generated text.");return R})},setBadge:o=>P({channel:x,v:1,type:"badge",id:T(E),payload:{count:Ve(o)}}),dispose:()=>{for(let o of I.keys())W({...Q,type:"workspace-unsubscribe",id:T(E),payload:{subscriptionId:o}});I.clear(),J=!0,g=null,f=null,t.removeEventListener("message",ht);for(let o of k.values())clearTimeout(o.timer),o.reject(new u("HOST_UNAVAILABLE","Host client was disposed."));k.clear(),l.clear(),p.clear(),s.clear(),c.clear(),h.clear(),A.clear(),i.clear()}}};var so=[["--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"]],Ut=(e,t)=>{t.style.colorScheme=e.mode;for(let[r,a]of so)t.style.setProperty(r,e.tokens[a]);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)},ot=(e,t)=>{Ut(e.theme,t),t.dataset&&(t.dataset.ocSurface=e.surface,t.dataset.ocTheme=e.theme.mode)};var io={"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"},y=(e,t)=>`var(--${e}, var(--oc-${io[e]}, ${t}))`,ee=y("surface-background","transparent"),we=y("surface-elevated","transparent"),de=y("surface-elevated-foreground","inherit"),le=y("surface-foreground","inherit"),w=y("surface-muted-foreground","gray"),ao=y("surface-muted","transparent"),B=y("interactive-border","currentColor"),X=y("interactive-hover","transparent"),te=y("interactive-active","transparent"),nt=y("interactive-selection","transparent"),rt=y("interactive-selection-foreground","inherit"),Ht=y("interactive-focus-ring","currentColor"),z=y("primary","currentColor"),st=y("primary-text","inherit"),it=y("error-text","inherit"),co=y("font-sans","inherit"),at=y("font-mono","monospace"),Nt=y("radius","9px"),O=(e,t,r="transparent")=>`color-mix(in srgb, ${e} ${t}%, ${r})`,Dt=`box-shadow: 0 0 0 2px ${Ht};`,Me=e=>{let t=y(`status-${e}`,"currentColor");return`
31
+ `;var Tt=["file","directory","other","missing"],ze=e=>!!(e&&"sessionId"in e),Ke=e=>!!(e&&"sent"in e&&!("sessionId"in e));var Se=500,Te=32e3,_t=16e3,yt=128,At=200,wt=2e3,vt=16e3,Mt=80,Ot=200,Lt=16e3;var Ct=2e3;var Ve=2e4,_e=1024,ye=2e6;var Ae=64e3,we=8e3,je=4e3;var qe=9e4;var Rt=999,ve=500,Gt=["HOST_UNAVAILABLE","HOST_TIMEOUT","HOST_REJECTED","DISCONNECTED","DISABLED","BAD_PATH","NO_INTEGRATION","NO_SERVICE","SERVICE_FAILED","NO_SESSION","SESSION_BUSY","NOT_GRANTED","NO_DIRECTORY","NOT_FOUND","FILE_TOO_LARGE","DENIED","NO_MODEL","MODEL_FAILED"],It=["stopped","starting","ready","failed"],ro=new Set(Gt),$t=e=>ro.has(e),Nt=e=>e&&$t(e)?e:"HOST_REJECTED",re=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(re):Object(e)===e?Object.values(e).every(re):!1,Ut=e=>re(e)&&JSON.stringify(e).length<=Lt,St=e=>e?.trim().slice(0,Ot)??"",se=e=>{let t=e.id.trim().slice(0,yt),r=e.title.trim().slice(0,At),a=e.url.trim().slice(0,wt),l=e.text?.trim().slice(0,vt),p=e.author?.trim().slice(0,Mt),s=e.kind==="pull"?"pull":"issue",c={providerId:e.providerId.trim(),id:t,title:r||t,url:a,kind:s};if(l&&(c.text=l),p&&(c.author=p),s==="pull"){let h=St(e.branches?.head),A=St(e.branches?.base);h&&A&&(c.branches={head:h,base:A})}return Ut(e.data)&&(c.data=e.data),c},Ye=e=>{let t=se(e);return e.projectId&&(t.projectId=e.projectId),e.navigation&&(t.navigation=e.navigation),e.worktree&&(t.worktree=e.worktree),t},Je=e=>{let t={text:e.text.trim().slice(0,_t)};return e.send&&(t.send=!0),t},We=e=>e===null||!Number.isFinite(e)?null:Math.min(Rt,Math.max(0,Math.round(e)));var ie=e=>e.length>0&&e.length<=_e&&!e.includes("\0")&&!e.includes("\\");var Me=e=>!e.startsWith("/")||e.includes("\0")||e.includes("\\")||e.includes("://")||e.length>Ct?!1:!e.split("/").some(r=>r==="."||r===".."),so=new Set(It),Qe=e=>!!(e&&"status"in e&&so.has(String(e.status))&&!("body"in e)),Oe=e=>!!(e&&"status"in e&&"body"in e&&Number.isInteger(e.status)),Ze=e=>!!(e&&"content"in e&&String(e.content)===e.content),et=e=>!!(e&&"written"in e&&e.written===!0),tt=e=>!!(e&&"entries"in e&&Array.isArray(e.entries)),io=new Set(Tt),ot=e=>!!(e&&"kind"in e&&"size"in e&&io.has(String(e.kind))&&Number.isFinite(e.size)),nt=e=>!!(e&&"text"in e&&String(e.text)===e.text&&!("status"in e)),ao=new Set(["workspace","ready","directory","session","connection","settings","session-lifecycle","item","resolve","action"]),co=e=>Object(e)===e?e:null,Fe=e=>String(e)===e&&e.length>0,lo=e=>{if(!Fe(e.id))return null;if(e.ok===!0){let t={channel:k,v:1,type:"result",id:e.id,ok:!0};return Object(e.payload)===e.payload&&(t.payload=e.payload),t}return e.ok===!1&&Fe(e.error)?{channel:k,v:1,type:"result",id:e.id,ok:!1,error:e.error,code:Nt(Fe(e.code)?e.code:void 0)}:null},rt=e=>{let t=co(e);return!t||t.channel!==k||t.v!==1?null:t.type==="result"?lo(t):!ao.has(String(t.type))||Object(t.payload)!==t.payload?null:t};var u=class extends Error{code;constructor(t,r){super(r),this.name="HostRequestError",this.code=t}},Dt=()=>Promise.reject(new u("BAD_PATH",'Request path must start with "/" and stay on the declared origin.')),Le=()=>Promise.reject(new u("BAD_PATH",`File path must be 1 to ${_e} characters without NUL or backslash.`)),S=e=>(e.value+=1,`oc-${e.value}`),st=(e={})=>{let t=e.target??("window"in globalThis?window:null);if(!t)throw new u("HOST_UNAVAILABLE","No window. connectHost runs in a browser frame.");let r=e.acceptSource??(o=>o===t.parent),a=e.requestTimeoutMs??Ve,l=new Set,p=new Set,s=new Set,c=new Set,h=new Set,A=new Set,i=new Set,g=null,f=null,x=new Map,I=new Map,W=!1,E={value:0},T=null,q=null,xt=o=>o?{sessionId:o.id,phase:o.busy?"started":"completed"}:null,Q=o=>{t.parent.postMessage(o,"*")},N=(o,n)=>{for(let m of o)try{m(n)}catch(w){console.error(w)}},bt=o=>{if(!(o instanceof MessageEvent)||!r(o.source))return;let n=rt(o.data);if(!n)return;if(n.type==="workspace"){let w=I.get(n.payload.subscriptionId);w&&N([w],n.payload.snapshot);return}if(n.type==="ready"){T=n.payload,q=xt(n.payload.session),N(l,n.payload),N(p,n.payload.directory),N(s,n.payload.session),q&&N(c,q),N(h,n.payload.connection),N(A,n.payload.settings),N(i,n.payload.item);return}if(n.type==="directory"){T&&(T={...T,directory:n.payload.directory}),N(p,n.payload.directory);return}if(n.type==="session"){T&&(T={...T,session:n.payload.session}),n.payload.session?q?.sessionId!==n.payload.session.id&&(q=xt(n.payload.session)):q=null,N(s,n.payload.session);return}if(n.type==="session-lifecycle"){q=n.payload,N(c,n.payload);return}if(n.type==="connection"){T&&(T={...T,connection:n.payload.connection}),N(h,n.payload.connection);return}if(n.type==="settings"){T&&(T={...T,settings:n.payload.settings}),N(A,n.payload.settings);return}if(n.type==="item"){T&&(T={...T,item:n.payload.item}),N(i,n.payload.item);return}if(n.type==="action"){let w=R=>{W||Q({channel:k,v:1,type:"action-result",id:n.id,payload:R})},F=f;if(!F){w({ok:!1,error:"This extension does not handle background actions."});return}Promise.resolve().then(()=>F(n.payload)).then(()=>w({ok:!0}),R=>{let Xe=(R instanceof Error?R.message:String(R)).trim();w({ok:!1,error:(Xe||"Action failed.").slice(0,ve)})});return}if(n.type==="resolve"){let w=R=>{Q({channel:k,v:1,type:"resolve-result",id:n.id,payload:R})},F=g;if(!F){w({error:"This extension does not resolve commands."});return}Promise.resolve().then(()=>F(n.payload)).then(R=>w({item:R?se(R):null}),R=>{let Xe=(R instanceof Error?R.message:String(R)).trim();w({error:(Xe||"Command failed.").slice(0,ve)})});return}let m=x.get(n.id);if(m){if(clearTimeout(m.timer),x.delete(n.id),n.ok){m.resolve(n.payload);return}m.reject(new u(n.code,n.error))}};t.addEventListener("message",bt),Q({channel:k,v:1,type:"hello"});let H=(o,n=a)=>W||t.parent===t?Promise.reject(new u("HOST_UNAVAILABLE","No host frame. This page is not in an iframe.")):new Promise((m,w)=>{let F=setTimeout(()=>{x.delete(o.id),w(new u("HOST_TIMEOUT","Host did not answer in time."))},n);x.set(o.id,{resolve:m,reject:w,timer:F}),Q(o)}),P=o=>H(o).then(()=>{}),Z={channel:k,v:1},ee=(o,n=1024)=>{if(!o.trim()||o.length>n)throw new u("HOST_REJECTED",`Identity must contain 1 to ${n} characters.`)},He=async o=>{o.kind!=="projects"&&ee(o.projectId);let n=await H({...Z,type:"workspace-read",id:S(E),payload:o});if(!n||!("kind"in n)||!("state"in n)||n.kind!==o.kind)throw new u("HOST_REJECTED","Host did not return workspace data.");return n},Pe=async(o,n)=>{o.kind!=="projects"&&ee(o.projectId);let m=S(E);I.set(m,n);try{await P({...Z,type:"workspace-subscribe",id:S(E),payload:{subscriptionId:m,query:o}})}catch(w){throw I.delete(m),W||Q({...Z,type:"workspace-unsubscribe",id:S(E),payload:{subscriptionId:m}}),w}return()=>{!I.delete(m)||W||Q({...Z,type:"workspace-unsubscribe",id:S(E),payload:{subscriptionId:m}})}},be=async o=>{if("key"in o&&(o.key.length===0||o.key.length>128))throw new u("HOST_REJECTED","Storage key must contain 1 to 128 characters.");if(o.op==="set"&&!re(o.value))throw new u("HOST_REJECTED","Storage values must be JSON.");if(o.op==="set"&&new TextEncoder().encode(JSON.stringify(o.value)).length>65536)throw new u("HOST_REJECTED","Storage value exceeds 64 KiB.");let n=await H({...Z,type:"storage",id:S(E),payload:o});if(!n||!("storage"in n)||n.op!==o.op)throw new u("HOST_REJECTED","Host did not return storage data.");return n};return{onAction:o=>(f=o,()=>{f===o&&(f=null)}),listProjects:async()=>{let o=await He({kind:"projects"});if(o.kind!=="projects")throw new u("HOST_REJECTED","Expected projects.");return o},listWorktrees:async o=>{let n=await He({kind:"worktrees",projectId:o});if(n.kind!=="worktrees")throw new u("HOST_REJECTED","Expected worktrees.");return n},listSessions:async o=>{let n=await He({kind:"sessions",projectId:o});if(n.kind!=="sessions")throw new u("HOST_REJECTED","Expected sessions.");return n},onProjects:o=>Pe({kind:"projects"},n=>{n.kind==="projects"&&o(n)}),onWorktrees:(o,n)=>Pe({kind:"worktrees",projectId:o},m=>{m.kind==="worktrees"&&n(m)}),onSessions:(o,n)=>Pe({kind:"sessions",projectId:o},m=>{m.kind==="sessions"&&n(m)}),openSession:async o=>{ee(o),await P({...Z,type:"open-session",id:S(E),payload:{sessionId:o}})},storage:{get:async o=>{let n=await be({op:"get",key:o});return n.op==="get"&&n.found?n.value:void 0},set:async(o,n)=>{await be({op:"set",key:o,value:n})},delete:async o=>{await be({op:"delete",key:o})},keys:async()=>{let o=await be({op:"keys"});if(o.op!=="keys")throw new u("HOST_REJECTED","Expected storage keys.");return o.keys}},onReady:o=>(l.add(o),T&&o(T),()=>{l.delete(o)}),onDirectory:o=>(p.add(o),T&&o(T.directory),()=>{p.delete(o)}),onSession:o=>(s.add(o),T&&o(T.session),()=>{s.delete(o)}),onSessionLifecycle:o=>(c.add(o),q&&o(q),()=>{c.delete(o)}),onConnection:o=>(h.add(o),T&&o(T.connection),()=>{h.delete(o)}),onSettings:o=>(A.add(o),T&&o(T.settings),()=>{A.delete(o)}),onItem:o=>(i.add(o),T&&o(T.item),()=>{i.delete(o)}),onResolve:o=>(g=o,()=>{g===o&&(g=null)}),toast:o=>{let n=o.message.trim();return!n||n.length>Se?Promise.reject(new u("HOST_REJECTED",`Toast message must contain 1 to ${Se} characters.`)):o.copy&&o.copy!==!0&&(!o.copy.text.length||o.copy.text.length>Te)?Promise.reject(new u("HOST_REJECTED",`Toast copy text must contain 1 to ${Te} characters.`)):P({channel:k,v:1,type:"toast",id:S(E),payload:{...o,message:n}})},openUrl:o=>P({channel:k,v:1,type:"open-url",id:S(E),payload:{url:o}}),openSurface:o=>P({channel:k,v:1,type:"open-surface",id:S(E),payload:{surfaceId:o}}),writeClipboard:o=>P({channel:k,v:1,type:"clipboard-write",id:S(E),payload:{text:o}}),compose:o=>P({channel:k,v:1,type:"compose",id:S(E),payload:o}),attach:o=>P({channel:k,v:1,type:"attach",id:S(E),payload:se(o)}),startSession:async o=>{o.projectId!==void 0&&ee(o.projectId);let n=o.worktree;n&&n!==!0&&(n.kind==="existing"?ee(n.directory):(n.name!==void 0&&ee(n.name,200),n.baseBranch!==void 0&&ee(n.baseBranch,200)));let m=await H({channel:k,v:1,type:"start-session",id:S(E),payload:Ye(o)},e.requestTimeoutMs??18e4);if(!ze(m))throw new u("HOST_REJECTED","Host did not return a session.");return m},prompt:o=>H({channel:k,v:1,type:"prompt",id:S(E),payload:Je(o)}).then(n=>{if(!Ke(n))throw new u("HOST_REJECTED","Host did not return a prompt result.");return n}),sessionLink:o=>P({channel:k,v:1,type:"session-link",id:S(E),payload:se(o)}),close:()=>P({channel:k,v:1,type:"close",id:S(E)}),oauthStart:()=>P({channel:k,v:1,type:"oauth-start",id:S(E)}),oauthDisconnect:()=>P({channel:k,v:1,type:"oauth-disconnect",id:S(E)}),request:o=>(Me(o.path)?H({channel:k,v:1,type:"request",id:S(E),payload:o}):Dt()).then(n=>{if(!Oe(n))throw new u("HOST_REJECTED","Host request result was empty.");return n}),serviceRequest:o=>(Me(o.path)?H({channel:k,v:1,type:"service-request",id:S(E),payload:o}):Dt()).then(n=>{if(!Oe(n))throw new u("HOST_REJECTED","Host service request result was empty.");return n}),serviceStatus:()=>H({channel:k,v:1,type:"service-status",id:S(E)}).then(o=>{if(!Qe(o))throw new u("HOST_REJECTED","Host did not return service status.");return o}),readFile:o=>(ie(o)?H({channel:k,v:1,type:"file-read",id:S(E),payload:{path:o}}):Le()).then(n=>{if(!Ze(n))throw new u("HOST_REJECTED","Host did not return file content.");return n}),writeFile:(o,n)=>ie(o)?n.length>ye?Promise.reject(new u("FILE_TOO_LARGE",`Content is over ${ye} characters.`)):H({channel:k,v:1,type:"file-write",id:S(E),payload:{path:o,content:n}}).then(m=>{if(!et(m))throw new u("HOST_REJECTED","Host did not confirm the write.");return m}):Le(),listDir:o=>(ie(o)?H({channel:k,v:1,type:"file-list",id:S(E),payload:{path:o}}):Le()).then(n=>{if(!tt(n))throw new u("HOST_REJECTED","Host did not return directory entries.");return n}),stat:o=>(ie(o)?H({channel:k,v:1,type:"file-stat",id:S(E),payload:{path:o}}):Le()).then(n=>{if(!ot(n))throw new u("HOST_REJECTED","Host did not return file status.");return n}),generate:o=>{let n=o.prompt.trim(),m=o.system?.trim();if(n.length===0||n.length>Ae)return Promise.reject(new u("HOST_REJECTED",`Prompt must be 1 to ${Ae} characters.`));if(m!==void 0&&(m.length===0||m.length>we))return Promise.reject(new u("HOST_REJECTED",`System prompt must be 1 to ${we} characters.`));let w=o.maxOutputTokens===void 0?void 0:Math.min(je,Math.max(1,Math.floor(o.maxOutputTokens)));if(w!==void 0&&!Number.isFinite(w))return Promise.reject(new u("HOST_REJECTED","maxOutputTokens must be a number."));let F={prompt:n};return m!==void 0&&(F.system=m),w!==void 0&&(F.maxOutputTokens=w),H({channel:k,v:1,type:"generate",id:S(E),payload:F},e.requestTimeoutMs??qe).then(R=>{if(!nt(R))throw new u("HOST_REJECTED","Host did not return generated text.");return R})},setBadge:o=>P({channel:k,v:1,type:"badge",id:S(E),payload:{count:We(o)}}),dispose:()=>{for(let o of I.keys())Q({...Z,type:"workspace-unsubscribe",id:S(E),payload:{subscriptionId:o}});I.clear(),W=!0,g=null,f=null,t.removeEventListener("message",bt);for(let o of x.values())clearTimeout(o.timer),o.reject(new u("HOST_UNAVAILABLE","Host client was disposed."));x.clear(),l.clear(),p.clear(),s.clear(),c.clear(),h.clear(),A.clear(),i.clear()}}};var po=[["--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"]],Xt=(e,t)=>{t.style.colorScheme=e.mode;for(let[r,a]of po)t.style.setProperty(r,e.tokens[a]);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)},it=(e,t)=>{Xt(e.theme,t),t.dataset&&(t.dataset.ocSurface=e.surface,t.dataset.ocTheme=e.theme.mode)};var uo={"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"},y=(e,t)=>`var(--${e}, var(--oc-${uo[e]}, ${t}))`,te=y("surface-background","transparent"),Ce=y("surface-elevated","transparent"),pe=y("surface-elevated-foreground","inherit"),ue=y("surface-foreground","inherit"),v=y("surface-muted-foreground","gray"),fo=y("surface-muted","transparent"),B=y("interactive-border","currentColor"),X=y("interactive-hover","transparent"),oe=y("interactive-active","transparent"),at=y("interactive-selection","transparent"),ct=y("interactive-selection-foreground","inherit"),zt=y("interactive-focus-ring","currentColor"),z=y("primary","currentColor"),dt=y("primary-text","inherit"),lt=y("error-text","inherit"),mo=y("font-sans","inherit"),pt=y("font-mono","monospace"),Bt=y("radius","9px"),O=(e,t,r="transparent")=>`color-mix(in srgb, ${e} ${t}%, ${r})`,Ft=`box-shadow: 0 0 0 2px ${zt};`,Re=e=>{let t=y(`status-${e}`,"currentColor");return`
32
32
  .oc-sdk[data-tone="${e}"], .oc-sdk [data-tone="${e}"] { --oc-sdk-tone: ${t}; --oc-sdk-tone-text: ${y(`${e}-text`,"inherit")}; }`},$=`
33
- ${De}
34
- .oc-sdk { box-sizing: border-box; color: ${le}; font-family: ${co}; font-size: 0.875rem; line-height: 1.45; }
33
+ ${Be}
34
+ .oc-sdk { box-sizing: border-box; color: ${ue}; font-family: ${mo}; font-size: 0.875rem; line-height: 1.45; }
35
35
  .oc-sdk *, .oc-sdk *::before, .oc-sdk *::after { box-sizing: border-box; }
36
36
  /* :where() keeps the reset at zero specificity so every primitive class below overrides it. */
37
37
  :where(.oc-sdk) :where(button, input, textarea), :where(button.oc-sdk, input.oc-sdk, textarea.oc-sdk) { font: inherit; color: inherit; margin: 0; }
38
38
  :where(.oc-sdk) :where(button), :where(button.oc-sdk) { cursor: pointer; background: none; border: 0; padding: 0; }
39
39
  .oc-sdk button:disabled, button.oc-sdk:disabled, .oc-sdk[aria-disabled="true"], .oc-sdk [aria-disabled="true"] { opacity: .5; pointer-events: none; }
40
- .oc-sdk :focus-visible { outline: none; ${Dt} }
41
- .oc-sdk-mono { font-family: ${at}; }
42
- .oc-sdk-muted { color: ${w}; }
43
- ${Me("success")}${Me("warning")}${Me("error")}${Me("info")}
44
- .oc-sdk[data-tone="primary"], .oc-sdk [data-tone="primary"] { --oc-sdk-tone: ${z}; --oc-sdk-tone-text: ${st}; }
40
+ .oc-sdk :focus-visible { outline: none; ${Ft} }
41
+ .oc-sdk-mono { font-family: ${pt}; }
42
+ .oc-sdk-muted { color: ${v}; }
43
+ ${Re("success")}${Re("warning")}${Re("error")}${Re("info")}
44
+ .oc-sdk[data-tone="primary"], .oc-sdk [data-tone="primary"] { --oc-sdk-tone: ${z}; --oc-sdk-tone-text: ${dt}; }
45
45
 
46
- .oc-sdk-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: 36px; padding: 0 14px; border: 1px solid transparent; border-radius: ${Nt}; font-size: 0.875rem; font-weight: 500; line-height: 1; white-space: nowrap; transition: background 150ms ease-out, color 150ms ease-out; }
46
+ .oc-sdk-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: 36px; padding: 0 14px; border: 1px solid transparent; border-radius: ${Bt}; font-size: 0.875rem; font-weight: 500; line-height: 1; white-space: nowrap; transition: background 150ms ease-out, color 150ms ease-out; }
47
47
  .oc-sdk-btn[data-size="sm"] { height: 32px; padding: 0 10px; font-size: 0.8125rem; }
48
48
  .oc-sdk-btn[data-size="xs"] { height: 24px; padding: 0 8px; font-size: 0.75rem; border-radius: 6px; }
49
- .oc-sdk-btn[data-variant="default"] { color: ${st}; background: ${O(z,10,ee)}; border-color: ${O(z,12)}; }
50
- .oc-sdk-btn[data-variant="default"]:hover { background: ${O(z,16,ee)}; }
51
- .oc-sdk-btn[data-variant="default"]:active { background: ${O(z,22,ee)}; }
52
- .oc-sdk-btn[data-variant="secondary"] { background: ${ao}; color: var(--oc-fg); }
49
+ .oc-sdk-btn[data-variant="default"] { color: ${dt}; background: ${O(z,10,te)}; border-color: ${O(z,12)}; }
50
+ .oc-sdk-btn[data-variant="default"]:hover { background: ${O(z,16,te)}; }
51
+ .oc-sdk-btn[data-variant="default"]:active { background: ${O(z,22,te)}; }
52
+ .oc-sdk-btn[data-variant="secondary"] { background: ${fo}; color: var(--oc-fg); }
53
53
  .oc-sdk-btn[data-variant="secondary"]:hover { background-image: linear-gradient(${X}, ${X}); }
54
- .oc-sdk-btn[data-variant="secondary"]:active { background-image: linear-gradient(${te}, ${te}); }
55
- .oc-sdk-btn[data-variant="outline"] { background: ${we}; color: ${de}; border-color: ${B}; }
54
+ .oc-sdk-btn[data-variant="secondary"]:active { background-image: linear-gradient(${oe}, ${oe}); }
55
+ .oc-sdk-btn[data-variant="outline"] { background: ${Ce}; color: ${pe}; border-color: ${B}; }
56
56
  .oc-sdk-btn[data-variant="outline"]:hover { background-image: linear-gradient(${X}, ${X}); }
57
- .oc-sdk-btn[data-variant="outline"]:active { background-image: linear-gradient(${te}, ${te}); }
57
+ .oc-sdk-btn[data-variant="outline"]:active { background-image: linear-gradient(${oe}, ${oe}); }
58
58
  .oc-sdk-btn[data-variant="ghost"] { background: transparent; }
59
59
  .oc-sdk-btn[data-variant="ghost"]:hover { background: ${X}; }
60
- .oc-sdk-btn[data-variant="ghost"]:active { background: ${te}; }
61
- .oc-sdk-btn[data-variant="destructive"] { --oc-sdk-tone: ${y("status-error","red")}; color: ${it}; background: ${O("var(--oc-sdk-tone)",7,ee)}; border-color: ${O("var(--oc-sdk-tone)",12)}; }
62
- .oc-sdk-btn[data-variant="destructive"]:hover { background: ${O("var(--oc-sdk-tone)",9,ee)}; }
63
- .oc-sdk-btn[data-variant="destructive"]:active { background: ${O("var(--oc-sdk-tone)",11,ee)}; }
60
+ .oc-sdk-btn[data-variant="ghost"]:active { background: ${oe}; }
61
+ .oc-sdk-btn[data-variant="destructive"] { --oc-sdk-tone: ${y("status-error","red")}; color: ${lt}; background: ${O("var(--oc-sdk-tone)",7,te)}; border-color: ${O("var(--oc-sdk-tone)",12)}; }
62
+ .oc-sdk-btn[data-variant="destructive"]:hover { background: ${O("var(--oc-sdk-tone)",9,te)}; }
63
+ .oc-sdk-btn[data-variant="destructive"]:active { background: ${O("var(--oc-sdk-tone)",11,te)}; }
64
64
  .oc-sdk-btn[data-loading="true"] { opacity: .5; pointer-events: none; }
65
65
  .oc-sdk-btn > .oc-sdk-spinner-ring { width: 14px; height: 14px; }
66
66
 
67
67
  .oc-sdk-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
68
68
  .oc-sdk-field-label { font-size: 0.8125rem; font-weight: 500; }
69
- .oc-sdk-field-note { font-size: 0.75rem; color: ${w}; }
70
- .oc-sdk-field[data-invalid="true"] .oc-sdk-field-note { color: ${it}; }
71
- .oc-sdk-input { display: block; width: 100%; min-width: 0; height: 36px; padding: 0 12px; border: 0; border-radius: ${Nt}; background: ${we}; color: ${de}; font-size: 0.875rem; line-height: 1.45; appearance: none; box-shadow: inset 0 0 0 1px ${O(B,60)}; transition: background 150ms ease-out, box-shadow 150ms ease-out; }
69
+ .oc-sdk-field-note { font-size: 0.75rem; color: ${v}; }
70
+ .oc-sdk-field[data-invalid="true"] .oc-sdk-field-note { color: ${lt}; }
71
+ .oc-sdk-input { display: block; width: 100%; min-width: 0; height: 36px; padding: 0 12px; border: 0; border-radius: ${Bt}; background: ${Ce}; color: ${pe}; font-size: 0.875rem; line-height: 1.45; appearance: none; box-shadow: inset 0 0 0 1px ${O(B,60)}; transition: background 150ms ease-out, box-shadow 150ms ease-out; }
72
72
  textarea.oc-sdk-input { height: auto; padding: 8px 12px; resize: vertical; }
73
- .oc-sdk-input::placeholder { color: ${w}; }
73
+ .oc-sdk-input::placeholder { color: ${v}; }
74
74
  .oc-sdk-input:hover:not(:focus) { background-image: linear-gradient(${X}, ${X}); }
75
- .oc-sdk-input:focus, .oc-sdk-input:focus-visible { box-shadow: inset 0 0 0 2px ${Ht}; }
75
+ .oc-sdk-input:focus, .oc-sdk-input:focus-visible { box-shadow: inset 0 0 0 2px ${zt}; }
76
76
  .oc-sdk-field[data-invalid="true"] .oc-sdk-input { box-shadow: inset 0 0 0 1px ${y("status-error","red")}; }
77
77
  .oc-sdk-field[data-invalid="true"] .oc-sdk-input:focus { box-shadow: inset 0 0 0 2px ${y("status-error","red")}; }
78
- .oc-sdk-input[data-mono="true"] { font-family: ${at}; }
78
+ .oc-sdk-input[data-mono="true"] { font-family: ${pt}; }
79
79
 
80
80
  .oc-sdk-search { position: relative; min-width: 0; }
81
81
  .oc-sdk-search .oc-sdk-input { padding-left: 34px; padding-right: 34px; }
82
- .oc-sdk-search-icon { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: ${w}; pointer-events: none; }
82
+ .oc-sdk-search-icon { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: ${v}; pointer-events: none; }
83
83
  .oc-sdk-search[data-active="true"] .oc-sdk-search-icon { color: ${z}; }
84
- .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; border-radius: 6px; color: ${w}; }
84
+ .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; border-radius: 6px; color: ${v}; }
85
85
  .oc-sdk-search[data-active="true"] .oc-sdk-search-clear { display: inline-flex; }
86
- .oc-sdk-search-clear:hover { background: ${X}; color: ${le}; }
86
+ .oc-sdk-search-clear:hover { background: ${X}; color: ${ue}; }
87
87
 
88
88
  .oc-sdk-select { position: relative; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
89
- .oc-sdk-trigger { display: inline-flex; align-items: center; gap: 6px; width: 100%; min-width: 0; height: 32px; padding: 0 8px 0 10px; border: 1px solid ${B}; border-radius: 6px; background: ${we}; color: ${de}; font-size: 0.8125rem; text-align: left; transition: background 150ms ease-out; }
89
+ .oc-sdk-trigger { display: inline-flex; align-items: center; gap: 6px; width: 100%; min-width: 0; height: 32px; padding: 0 8px 0 10px; border: 1px solid ${B}; border-radius: 6px; background: ${Ce}; color: ${pe}; font-size: 0.8125rem; text-align: left; transition: background 150ms ease-out; }
90
90
  .oc-sdk-trigger:hover { background-image: linear-gradient(${X}, ${X}); }
91
- .oc-sdk-trigger[aria-expanded="true"] { background-image: linear-gradient(${te}, ${te}); }
91
+ .oc-sdk-trigger[aria-expanded="true"] { background-image: linear-gradient(${oe}, ${oe}); }
92
92
  .oc-sdk-trigger-value { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
93
- .oc-sdk-trigger-value[data-empty="true"] { color: ${w}; }
94
- .oc-sdk-trigger-chevron { flex: 0 0 auto; color: ${w}; }
95
- .oc-sdk-popup { --surface-foreground: ${de}; 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 ${O(B,60)}; border-radius: 12px; background: ${we}; color: ${de}; box-shadow: 0 8px 24px ${O(le,12)}; }
93
+ .oc-sdk-trigger-value[data-empty="true"] { color: ${v}; }
94
+ .oc-sdk-trigger-chevron { flex: 0 0 auto; color: ${v}; }
95
+ .oc-sdk-popup { --surface-foreground: ${pe}; 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 ${O(B,60)}; border-radius: 12px; background: ${Ce}; color: ${pe}; box-shadow: 0 8px 24px ${O(ue,12)}; }
96
96
  .oc-sdk-popup-search { flex: 0 0 auto; padding: 2px 2px 4px; }
97
97
  .oc-sdk-popup-search .oc-sdk-input { height: 32px; font-size: 0.8125rem; }
98
98
  .oc-sdk-option { display: flex; align-items: center; gap: 8px; width: 100%; padding: 6px 8px; border-radius: 8px; font-size: 0.8125rem; text-align: left; }
99
99
  .oc-sdk-option[data-active="true"] { background: ${X}; }
100
- .oc-sdk-option[aria-selected="true"] { background: ${nt}; color: ${rt}; }
101
- .oc-sdk-option[data-destructive="true"] { color: ${it}; }
100
+ .oc-sdk-option[aria-selected="true"] { background: ${at}; color: ${ct}; }
101
+ .oc-sdk-option[data-destructive="true"] { color: ${lt}; }
102
102
  .oc-sdk-option[data-destructive="true"][data-active="true"] { background: ${O(y("status-error","red"),10)}; }
103
103
  .oc-sdk-option-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
104
- .oc-sdk-option-hint { flex: 0 0 auto; font-size: 0.75rem; color: ${w}; }
104
+ .oc-sdk-option-hint { flex: 0 0 auto; font-size: 0.75rem; color: ${v}; }
105
105
  .oc-sdk-option-check { flex: 0 0 auto; width: 12px; }
106
- .oc-sdk-popup-empty { padding: 8px; font-size: 0.8125rem; color: ${w}; }
106
+ .oc-sdk-popup-empty { padding: 8px; font-size: 0.8125rem; color: ${v}; }
107
107
 
108
108
  .oc-sdk-check { display: inline-flex; align-items: flex-start; gap: 8px; width: 100%; text-align: left; }
109
109
  .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 ${B}; border-radius: 4px; color: ${z}; transition: border-color 150ms ease-out; }
@@ -111,66 +111,66 @@ textarea.oc-sdk-input { height: auto; padding: 8px 12px; resize: vertical; }
111
111
  .oc-sdk-check-box > svg { display: none; }
112
112
  .oc-sdk-check[aria-checked="true"] .oc-sdk-check-box > svg { display: block; }
113
113
  .oc-sdk-check-thumb { flex: 0 0 auto; position: relative; width: 36px; height: 20px; border-radius: 9999px; background: ${B}; transition: background 150ms ease-out; }
114
- .oc-sdk-check-thumb::after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 9999px; background: ${ee}; transition: transform 150ms ease-out; }
114
+ .oc-sdk-check-thumb::after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 9999px; background: ${te}; transition: transform 150ms ease-out; }
115
115
  .oc-sdk-check[aria-checked="true"] .oc-sdk-check-thumb { background: ${z}; }
116
116
  .oc-sdk-check[aria-checked="true"] .oc-sdk-check-thumb::after { transform: translateX(16px); }
117
117
  .oc-sdk-check:focus-visible { box-shadow: none; }
118
- .oc-sdk-check:focus-visible .oc-sdk-check-box, .oc-sdk-check:focus-visible .oc-sdk-check-thumb { ${Dt} }
118
+ .oc-sdk-check:focus-visible .oc-sdk-check-box, .oc-sdk-check:focus-visible .oc-sdk-check-thumb { ${Ft} }
119
119
  .oc-sdk-check-text { display: flex; flex-direction: column; min-width: 0; }
120
120
  .oc-sdk-check-label { font-size: 0.875rem; }
121
- .oc-sdk-check-desc { font-size: 0.75rem; color: ${w}; }
121
+ .oc-sdk-check-desc { font-size: 0.75rem; color: ${v}; }
122
122
 
123
123
  .oc-sdk-tabs { display: inline-flex; gap: 2px; padding: 2px; border-radius: 10px; max-width: 100%; overflow: auto; }
124
- .oc-sdk-tabs[data-track="true"] { background: ${O(le,4)}; }
125
- .oc-sdk-tab { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; border: 1px solid transparent; border-radius: 8px; font-size: 0.8125rem; font-weight: 500; color: ${w}; white-space: nowrap; transition: color 150ms ease-out, background 150ms ease-out; }
126
- .oc-sdk-tab:hover { color: ${le}; }
127
- .oc-sdk-tab[aria-selected="true"] { color: ${rt}; background: ${nt}; border-color: ${B}; }
128
- .oc-sdk-tab-count { font-size: 0.75rem; font-variant-numeric: tabular-nums; color: ${w}; }
124
+ .oc-sdk-tabs[data-track="true"] { background: ${O(ue,4)}; }
125
+ .oc-sdk-tab { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; border: 1px solid transparent; border-radius: 8px; font-size: 0.8125rem; font-weight: 500; color: ${v}; white-space: nowrap; transition: color 150ms ease-out, background 150ms ease-out; }
126
+ .oc-sdk-tab:hover { color: ${ue}; }
127
+ .oc-sdk-tab[aria-selected="true"] { color: ${ct}; background: ${at}; border-color: ${B}; }
128
+ .oc-sdk-tab-count { font-size: 0.75rem; font-variant-numeric: tabular-nums; color: ${v}; }
129
129
 
130
- .oc-sdk-badge { display: inline-flex; align-items: center; padding: 1px 6px; border-radius: 9999px; font-size: 11px; font-weight: 500; line-height: 16px; white-space: nowrap; background: ${X}; color: ${w}; }
130
+ .oc-sdk-badge { display: inline-flex; align-items: center; padding: 1px 6px; border-radius: 9999px; font-size: 11px; font-weight: 500; line-height: 16px; white-space: nowrap; background: ${X}; color: ${v}; }
131
131
  .oc-sdk-badge[data-tone] { color: var(--oc-sdk-tone-text, var(--oc-sdk-tone)); background: ${O("var(--oc-sdk-tone)",15)}; }
132
132
 
133
133
  .oc-sdk-list { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
134
134
  .oc-sdk-row { display: flex; align-items: center; gap: 8px; width: 100%; padding: 6px 8px; border-radius: 6px; text-align: left; transition: background 120ms ease-out; }
135
135
  .oc-sdk-row:hover, .oc-sdk-row[data-active="true"] { background: ${X}; }
136
- .oc-sdk-row[aria-selected="true"] { background: ${nt}; color: ${rt}; }
137
- .oc-sdk-row-lead { flex: 0 0 auto; width: 64px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: ${at}; font-size: 0.75rem; color: ${w}; }
136
+ .oc-sdk-row[aria-selected="true"] { background: ${at}; color: ${ct}; }
137
+ .oc-sdk-row-lead { flex: 0 0 auto; width: 64px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: ${pt}; font-size: 0.75rem; color: ${v}; }
138
138
  .oc-sdk-row-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
139
139
  .oc-sdk-row-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
140
- .oc-sdk-row-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.75rem; color: ${w}; }
141
- .oc-sdk-row-meta { flex: 0 0 auto; font-size: 0.75rem; font-variant-numeric: tabular-nums; color: ${w}; }
140
+ .oc-sdk-row-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.75rem; color: ${v}; }
141
+ .oc-sdk-row-meta { flex: 0 0 auto; font-size: 0.75rem; font-variant-numeric: tabular-nums; color: ${v}; }
142
142
  .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; }
143
- .oc-sdk-list-empty { padding: 16px 8px; text-align: center; font-size: 0.8125rem; color: ${w}; }
143
+ .oc-sdk-list-empty { padding: 16px 8px; text-align: center; font-size: 0.8125rem; color: ${v}; }
144
144
 
145
145
  .oc-sdk-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; padding: 40px 16px; text-align: center; }
146
146
  .oc-sdk-empty-title { margin: 0; font-size: 0.8125rem; font-weight: 600; }
147
- .oc-sdk-empty-body { margin: 0; max-width: 32rem; font-size: 0.8125rem; color: ${w}; }
147
+ .oc-sdk-empty-body { margin: 0; max-width: 32rem; font-size: 0.8125rem; color: ${v}; }
148
148
  .oc-sdk-empty-action { margin-top: 12px; }
149
149
 
150
150
  @keyframes oc-sdk-spin { to { transform: rotate(360deg); } }
151
- .oc-sdk-spinner { display: inline-flex; align-items: center; gap: 8px; font-size: 0.8125rem; color: ${w}; }
151
+ .oc-sdk-spinner { display: inline-flex; align-items: center; gap: 8px; font-size: 0.8125rem; color: ${v}; }
152
152
  .oc-sdk-spinner-ring { width: 16px; height: 16px; border: 2px solid ${B}; border-top-color: ${z}; border-radius: 9999px; animation: oc-sdk-spin .8s linear infinite; }
153
153
  .oc-sdk-spinner[data-size="sm"] .oc-sdk-spinner-ring { width: 12px; height: 12px; }
154
154
 
155
155
  .oc-sdk-banner { display: flex; align-items: flex-start; gap: 12px; padding: 8px 12px; border: 1px solid ${O("var(--oc-sdk-tone)",40)}; border-radius: 8px; background: ${O("var(--oc-sdk-tone)",10)}; }
156
156
  .oc-sdk-banner-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
157
157
  .oc-sdk-banner-title { font-size: 0.8125rem; font-weight: 500; color: var(--oc-sdk-tone-text, var(--oc-sdk-tone)); }
158
- .oc-sdk-banner-body { font-size: 0.8125rem; color: ${w}; }
158
+ .oc-sdk-banner-body { font-size: 0.8125rem; color: ${v}; }
159
159
  .oc-sdk-banner-action { flex: 0 0 auto; }
160
160
 
161
- .oc-sdk-separator { display: flex; align-items: center; gap: 8px; width: 100%; margin: 8px 0; font-size: 0.75rem; color: ${w}; }
161
+ .oc-sdk-separator { display: flex; align-items: center; gap: 8px; width: 100%; margin: 8px 0; font-size: 0.75rem; color: ${v}; }
162
162
  .oc-sdk-separator::before, .oc-sdk-separator::after { content: ""; flex: 1 1 auto; height: 1px; background: ${O(B,40)}; }
163
163
  .oc-sdk-separator[data-labeled="false"]::after { display: none; }
164
164
  .oc-sdk-popup > .oc-sdk-separator { margin: 4px 0; }
165
165
 
166
166
  .oc-sdk-progress { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
167
- .oc-sdk-progress-label { display: flex; justify-content: space-between; font-size: 0.75rem; color: ${w}; font-variant-numeric: tabular-nums; }
167
+ .oc-sdk-progress-label { display: flex; justify-content: space-between; font-size: 0.75rem; color: ${v}; font-variant-numeric: tabular-nums; }
168
168
  .oc-sdk-progress-track { height: 6px; border-radius: 9999px; background: ${B}; overflow: hidden; }
169
169
  .oc-sdk-progress-fill { height: 100%; border-radius: 9999px; background: var(--oc-sdk-tone, ${z}); transform-origin: left; transition: transform 200ms ease-out; }
170
170
 
171
171
  .oc-sdk-menu { position: relative; display: inline-flex; }
172
172
 
173
173
  .oc-sdk-text { white-space: pre-wrap; overflow-wrap: anywhere; }
174
- .oc-sdk-text a { color: ${st}; text-decoration: underline; text-underline-offset: 2px; }
174
+ .oc-sdk-text a { color: ${dt}; text-decoration: underline; text-underline-offset: 2px; }
175
175
  .oc-sdk-text img { display: block; max-width: 100%; margin: 8px 0; border-radius: 8px; border: 1px solid ${O(B,60)}; }
176
- `;var mo=e=>24+e*308;function Bt(e){let t=new Map,r=new Map;for(let i of e.nodes)r.set(i.column,[...r.get(i.column)??[],i]);let a=[...r.keys()].sort((i,g)=>i-g),l=new Map(a.map(i=>[i,mo(i)])),p=new Map,s=0;for(let i of a)(r.get(i)??[]).slice().sort((f,k)=>(p.get(f.parentId??"")??-1)-(p.get(k.parentId??"")??-1)||(f.createdAt??0)-(k.createdAt??0)||f.id.localeCompare(k.id)).forEach((f,k)=>{let I=58+k*94;t.set(f.id,{x:l.get(i)??0,y:I}),p.set(f.id,p.size),s=Math.max(s,I+80+24)});let c=t.get(e.rootId),h=e.nodes.filter(i=>i.parentId===e.rootId).map(i=>t.get(i.id)).filter(i=>i!==void 0);if(c&&h.length>0&&(r.get(0)?.length??0)===1){let i=Math.min(...h.map(f=>f.y)),g=Math.max(...h.map(f=>f.y));c.y=Math.round((i+g)/2)}let A=24+(Math.max(0,...a)+1)*308-76+24;return{boxes:t,edges:ho(e.edges,t),columnX:l,width:A,height:Math.max(s,162)}}function Xt(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 ho(e,t){let r=e.filter(s=>t.has(s.from)&&t.has(s.to)),a=s=>(t.get(s)?.y??0)+80/2,l=new Map,p=new Map;for(let s of r)l.set(s.from,[...l.get(s.from)??[],s]),p.set(s.to,[...p.get(s.to)??[],s]);for(let s of l.values())s.sort((c,h)=>a(c.to)-a(h.to));for(let s of p.values())s.sort((c,h)=>a(c.from)-a(h.from));return r.map(s=>{let c=t.get(s.from),h=t.get(s.to),A=l.get(s.from)??[],i=p.get(s.to)??[],g=c.x+232,f=c.y+Xt(A.indexOf(s),A.length),k=h.x,I=h.y+Xt(i.indexOf(s),i.length),J=k>g?Math.max(32,(k-g)*.5):90,E=`M ${g} ${f} C ${g+J} ${f}, ${k-J} ${I}, ${k} ${I}`;return{...s,d:E,sx:g,sy:f,tx:k,ty:I}})}function dt(e,t,r){let a=new Set,l=[t];for(;l.length>0;){let p=l.pop();for(let s of e){let c=r==="down"?s.from===p?s.to:void 0:s.to===p?s.from:void 0;c!==void 0&&!a.has(c)&&c!==t&&(a.add(c),l.push(c))}}return a}function Ft(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 lt(e){if(e)return e.includes("/")?e.slice(e.indexOf("/")+1):e}function zt(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(e>=1e4?0:1)}k`:String(e)}var go={running:"running",queued:"queued",completed:"completed",failed:"failed",cancelled:"cancelled",idle:"idle"};function pe(e,t){if(e.kind==="root")return e.rawStatus;let r=e.rawStatus===e.state?go[e.state]:e.rawStatus,a=e.startedAt;return a===void 0?r:e.state==="running"?`${r} \xB7 ${Ft(t-a)}`:e.endedAt!==void 0?`${r} \xB7 ${Ft(e.endedAt-a)}`:r}function Eo(e){let t=JSON.parse(e);if(!(t!==null&&typeof t=="object"&&typeof t.status=="string"&&Array.isArray(t.nodes)&&Array.isArray(t.edges)&&Array.isArray(t.columns)&&t.nodes.every(a=>a!==null&&typeof a=="object"&&typeof a.id=="string")))throw new Error("service answered with an unexpected graph shape");return t}var Ge=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 a=await this.deps.fetch(t);if(r!==this.generation)return;if(a.status!==200)throw new Error(`service answered HTTP ${a.status}: ${a.body.slice(0,200)}`);let l=Eo(a.body);l.status!=="ok"||l.nodes.length<=1?(this.signature="",this.deps.show({kind:"empty"})):a.body!==this.signature&&(this.signature=a.body,this.deps.show({kind:"graph",graph:l}));let p=l.nodes.some(s=>s.state==="running"||s.state==="queued");this.deps.schedule(p?1500:5e3,()=>{this.refresh()})}catch(a){if(r!==this.generation)return;this.signature="",this.deps.show({kind:"error",error:a}),this.deps.schedule(1e4,()=>{this.refresh()})}finally{this.inFlight=!1,(this.pending||r!==this.generation)&&(this.pending=!1,this.refresh())}}};var Kt="http://www.w3.org/2000/svg",V=tt(),G=e=>document.querySelector(e),d={app:G("#app"),title:G("#title"),titleDot:G("#title-dot"),meta:G("#meta"),viewport:G("#viewport"),world:G("#world"),edges:G("#edges"),bands:G("#bands"),nodes:G("#nodes"),empty:G("#empty"),inspector:G("#inspector"),settings:G("#settings")},fe=null,Jt=!1,M,C,jt="",j,oe={},pt,_={x:0,y:0,k:1},ae=new Map;function L(e,t="",r=""){let a=document.createElement(e);return t&&(a.className=t),r&&(a.textContent=r),a}function ut(e,t=""){d.empty.replaceChildren(L("strong","",e),...t?[L("p","",t)]:[]),d.empty.hidden=!1,d.world.hidden=!0,d.inspector.hidden=!0}function Wt(e){return e instanceof u?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 ce(){d.world.style.transform=`translate(${_.x}px, ${_.y}px) scale(${_.k})`,d.app.style.setProperty("--zoom",String(_.k))}function Ie(){if(!C)return;let e=d.viewport.clientWidth,t=d.viewport.clientHeight,r=Math.min(1,Math.max(.62,Math.min((e-16)/C.width,(t-16)/C.height)));_.k=r,_.x=Math.round(C.width*r<=e?(e-C.width*r)/2:8),_.y=Math.round(Math.max(8,(t-C.height*r)/2)),ce()}function Qt(e){let t=e?C?.boxes.get(e):void 0;if(!t)return Ie();_.k=Math.max(_.k,.8),_.x=Math.round(d.viewport.clientWidth/2-(t.x+232/2)*_.k),_.y=Math.round(d.viewport.clientHeight/2-(t.y+80/2)*_.k),ce()}function me(e,t=d.viewport.clientWidth/2,r=d.viewport.clientHeight/2){let a=Math.min(2,Math.max(.2,_.k*e));_.x=t-(t-_.x)*a/_.k,_.y=r-(r-_.y)*a/_.k,_.k=a,ce()}var K,ft=!1;d.viewport.addEventListener("pointerdown",e=>{e.button===0&&(K={x:e.clientX,y:e.clientY,vx:_.x,vy:_.y,moved:!1})});window.addEventListener("pointermove",e=>{if(!K)return;let t=e.clientX-K.x,r=e.clientY-K.y;!K.moved&&Math.hypot(t,r)<4||(K.moved||(K.moved=!0,d.viewport.setPointerCapture?.(e.pointerId),d.app.classList.add("is-panning")),_.x=K.vx+t,_.y=K.vy+r,ce())});window.addEventListener("pointerup",()=>{K?.moved&&(ft=!0,setTimeout(()=>{ft=!1},0)),K=void 0,d.app.classList.remove("is-panning")});d.viewport.addEventListener("wheel",e=>{e.preventDefault();let t=d.viewport.getBoundingClientRect();e.ctrlKey||e.metaKey||Math.abs(e.deltaY)>Math.abs(e.deltaX)*2&&!e.shiftKey?me(Math.exp(-e.deltaY*(e.ctrlKey?.01:.0015)),e.clientX-t.left,e.clientY-t.top):(_.x-=e.deltaX||(e.shiftKey?e.deltaY:0),_.y-=e.shiftKey?0:e.deltaY,ce())},{passive:!1});G("#btn-fit").addEventListener("click",Ie);G("#btn-locate").addEventListener("click",()=>{let e=M?.nodes.find(t=>t.kind==="task"&&t.state==="running");Qt(M?.focusId!==M?.rootId?M?.focusId:e?.id??M?.rootId)});G("#btn-in").addEventListener("click",()=>me(1.2));G("#btn-out").addEventListener("click",()=>me(1/1.2));window.addEventListener("keydown",e=>{e.target instanceof HTMLInputElement||(e.key==="0"?Ie():e.key==="+"||e.key==="="?me(1.2):e.key==="-"&&me(1/1.2))});function ue(e){if(j=e,!M)return;let t=M.edges,r=new Set(e?t.filter(s=>s.to===e).map(s=>s.from):[]),a=new Set(e?t.filter(s=>s.from===e).map(s=>s.to):[]),l=e?dt(t,e,"up"):new Set,p=e?dt(t,e,"down"):new Set;d.app.classList.toggle("has-hover",e!==void 0);for(let[s,c]of ae)c.classList.toggle("is-hover",s===e),c.classList.toggle("is-input",r.has(s)),c.classList.toggle("is-output",a.has(s)),c.classList.toggle("is-reach",l.has(s)||p.has(s));for(let s of d.edges.querySelectorAll("path[data-edge]")){let c=s.dataset.from??"",h=s.dataset.to??"";s.classList.toggle("is-in",e!==void 0&&h===e),s.classList.toggle("is-out",e!==void 0&&c===e),s.classList.toggle("is-reach",e!==void 0&&(l.has(c)&&(l.has(h)||h===e)||p.has(h)&&(p.has(c)||c===e)))}ko()}function ko(){let e=M?.nodes.find(A=>A.id===(j??(M?.focusId!==M?.rootId?M?.focusId:void 0)));if(!e||!M){d.inspector.hidden=!0;return}let t=M.edges.filter(A=>A.to===e.id).length,r=M.edges.filter(A=>A.from===e.id).length,a=[pe(e,Date.now())];e.agent&&a.push(e.agent);let l=lt(e.model);l&&a.push(l),e.toolCalls!==void 0&&a.push(`${e.toolCalls} tools`),e.tokens!==void 0&&a.push(`${zt(e.tokens)} tok`),e.costUsd!==void 0&&a.push(`$${e.costUsd.toFixed(2)}`);let p=L("div","i-head");p.append(L("span",`dot s-${e.state}`),L("strong","",e.title));let s=L("div","i-flow");s.append(L("span","i-in",`\u2190 ${t} input${t===1?"":"s"}`),L("span","i-out",`${r} output${r===1?"":"s"} \u2192`));let c=[p,L("div","i-facts",a.join(" \xB7 ")),s],h=e.error??e.summary;h&&c.push(L("p",e.error?"i-text is-error":"i-text",h)),c.push(L("div","i-hint",e.kind==="root"?"Click to open the orchestrating session":"Click to open this sub-agent's session")),d.inspector.replaceChildren(...c),d.inspector.hidden=!1}function bo(e){let t=ae.get(e.id);return t||(t=L("button","node"),t.type="button",t.dataset.id=e.id,t.append(L("div","n-head"),L("div","n-status"),L("div","n-meta"),L("div","n-sub")),t.querySelector(".n-head")?.append(L("span","dot"),L("span","n-title")),t.addEventListener("pointerenter",()=>ue(e.id)),t.addEventListener("pointerleave",()=>{j===e.id&&ue(void 0)}),t.addEventListener("focus",()=>ue(e.id)),t.addEventListener("blur",()=>{j===e.id&&ue(void 0)}),t.addEventListener("click",()=>{ft||yo(e.id)}),ae.set(e.id,t),d.nodes.append(t)),t}function To(e,t,r){e.className=`node k-${t.kind} s-${t.state}${M?.focusId===t.id&&t.kind==="task"?" is-current":""}`,j===t.id&&e.classList.add("is-hover"),e.setAttribute("aria-label",`${t.title}, ${pe(t,r)}. Open session.`);let a=(l,p)=>{let s=e.querySelector(l);s&&s.textContent!==p&&(s.textContent=p)};a(".n-title",t.title),a(".n-status",pe(t,r)),a(".n-meta",t.kind==="root"?`${M?.nodes.length?M.nodes.length-1:0} sub-agents`:[t.agent,lt(t.model)].filter(Boolean).join(" \xB7 ")),a(".n-sub",t.error??t.summary??""),e.querySelector(".dot")?.setAttribute("class",`dot s-${t.state}`)}function So(e){M=e,C=Bt(e),d.world.hidden=!1,d.empty.hidden=!0,d.world.style.width=`${C.width}px`,d.world.style.height=`${C.height}px`,d.edges.setAttribute("width",String(C.width)),d.edges.setAttribute("height",String(C.height)),d.edges.setAttribute("viewBox",`0 0 ${C.width} ${C.height}`);let t=new Map(e.nodes.map(i=>[i.id,i.state])),r=document.createDocumentFragment();for(let i of C.edges){let g=document.createElementNS(Kt,"path");g.setAttribute("d",i.d),g.dataset.edge=i.id,g.dataset.from=i.from,g.dataset.to=i.to;let f=t.get(i.to)==="running"||t.get(i.to)==="queued";if(g.setAttribute("class",`edge k-${i.kind}${f?" is-live":""}`),g.setAttribute("marker-end","url(#arrow)"),r.append(g),f){let k=document.createElementNS(Kt,"path");k.setAttribute("d",i.d),k.setAttribute("class","flow"),k.setAttribute("pathLength","1"),r.append(k)}}d.edges.querySelectorAll("path.edge, path.flow").forEach(i=>i.remove()),d.edges.append(r),d.bands.replaceChildren(...[...C.columnX].map(([i,g])=>{let f=L("div","band");f.style.left=`${g}px`,f.style.width=`${232}px`;let k=e.columns.find(I=>I.column===i);return i===0?f.textContent="Orchestrator":k&&(f.textContent=`Wave ${i} \xB7 ${k.done}/${k.total} done${k.running?` \xB7 ${k.running} running`:""}`),k?.running&&f.classList.add("is-live"),f}));let a=Date.now(),l=new Set;for(let i of e.nodes){let g=bo(i),f=C.boxes.get(i.id);f&&(g.style.transform=`translate(${f.x}px, ${f.y}px)`),To(g,i,a),l.add(i.id)}for(let[i,g]of ae)l.has(i)||(g.remove(),ae.delete(i));let p=e.nodes.filter(i=>i.kind==="task"),s=p.filter(i=>i.state==="completed"||i.state==="failed"||i.state==="cancelled").length,c=p.filter(i=>i.state==="running").length,h=e.columns.length,A=e.columns.find(i=>i.running>0||i.done<i.total)?.column;d.title.textContent=e.title,d.titleDot.className=`dot s-${c>0?"running":p.some(i=>i.state==="failed")?"failed":s===p.length?"completed":"idle"}`,d.meta.textContent=[A!==void 0?`wave ${A}/${h}`:`${h} wave${h===1?"":"s"}`,`${s}/${p.length} done`,...c?[`${c} running`]:[],...e.models?[`${e.models} model${e.models===1?"":"s"}`]:[]].join(" \xB7 "),V.setBadge(c>0?c:null).catch(()=>{}),jt!==e.rootId&&(jt=e.rootId,requestAnimationFrame(()=>e.focusId!==e.rootId?Qt(e.focusId):Ie())),j&&!e.nodes.some(i=>i.id===j)&&(j=void 0),ue(j)}function _o(){if(!M)return;let e=Date.now();for(let t of M.nodes){if(t.state!=="running")continue;let a=ae.get(t.id)?.querySelector(".n-status");a&&(a.textContent=pe(t,e))}}setInterval(_o,1e3);async function yo(e){let t=M?.nodes.find(r=>r.id===e);if(t)try{await V.openSession(t.sessionId)}catch(r){let[a,l]=Wt(r);await V.toast({kind:"error",message:`${a}: ${l}`}).catch(()=>{})}}var he=new Ge({fetch:e=>{let t={session:e};return oe.agentDir&&(t.agentDir=oe.agentDir),oe.stateDir&&(t.stateDir=oe.stateDir),V.serviceRequest({method:"GET",path:"/graph",query:t})},show:e=>{if(e.kind==="graph"){So(e.graph);return}M=void 0,V.setBadge(null).catch(()=>{}),e.kind==="no-session"?ut("No session open","Open a chat to see the OmO agents working behind it."):e.kind==="empty"?ut("No sub-agents yet","When this session launches OmO tasks or workflows, they appear here as a live graph."):ut(...Wt(e.error))},schedule:(e,t)=>{pt&&clearTimeout(pt),pt=setTimeout(t,e)},isHidden:()=>document.hidden}),Vt=G("#btn-settings");Vt.addEventListener("click",()=>{d.settings.hidden=!d.settings.hidden,Vt.setAttribute("aria-expanded",String(!d.settings.hidden)),d.settings.hidden||d.settings.querySelector("input")?.focus()});d.settings.addEventListener("submit",e=>{e.preventDefault();let t=new FormData(d.settings),r={},a=String(t.get("agentDir")??"").trim(),l=String(t.get("stateDir")??"").trim();a&&(r.agentDir=a),l&&(r.stateDir=l),oe=r,d.settings.hidden=!0,V.storage.set("paths",r).catch(()=>{}),he.invalidate()});function Ao(){for(let e of["agentDir","stateDir"]){let t=d.settings.querySelector(`input[name="${e}"]`);t&&(t.value=oe[e]??"")}}var Yt=!1;V.onReady(e=>{ot(e,document.documentElement),d.app.dataset.surface=e.surface,!Yt&&(Yt=!0,fe=e.session?.id??fe,V.storage.get("paths").then(t=>{if(t&&typeof t=="object"&&!Array.isArray(t)){let r=t;oe={...typeof r.agentDir=="string"?{agentDir:r.agentDir}:{},...typeof r.stateDir=="string"?{stateDir:r.stateDir}:{}}}Ao()}).catch(()=>{}).finally(()=>{Jt=!0,he.setSession(fe)}))});V.onSession(e=>{let t=e?.id??null;t!==fe&&(j=void 0),fe=t,Jt&&he.setSession(t)});V.onSessionLifecycle(()=>{he.refresh()});document.addEventListener("visibilitychange",()=>{document.hidden||he.refresh()});window.addEventListener("resize",()=>{C&&_.k<=1&&ce()});})();
176
+ `;var xo=e=>24+e*308;function jt(e){let t=new Map,r=new Map;for(let i of e.nodes)r.set(i.column,[...r.get(i.column)??[],i]);let a=[...r.keys()].sort((i,g)=>i-g),l=new Map(a.map(i=>[i,xo(i)])),p=new Map,s=0;for(let i of a)(r.get(i)??[]).slice().sort((f,x)=>(p.get(f.parentId??"")??-1)-(p.get(x.parentId??"")??-1)||(f.createdAt??0)-(x.createdAt??0)||f.id.localeCompare(x.id)).forEach((f,x)=>{let I=58+x*94;t.set(f.id,{x:l.get(i)??0,y:I}),p.set(f.id,p.size),s=Math.max(s,I+80+24)});let c=t.get(e.rootId),h=e.nodes.filter(i=>i.parentId===e.rootId).map(i=>t.get(i.id)).filter(i=>i!==void 0);if(c&&h.length>0&&(r.get(0)?.length??0)===1){let i=Math.min(...h.map(f=>f.y)),g=Math.max(...h.map(f=>f.y));c.y=Math.round((i+g)/2)}let A=24+(Math.max(0,...a)+1)*308-76+24;return{boxes:t,edges:bo(e.edges,t),columnX:l,width:A,height:Math.max(s,162)}}function Vt(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 bo(e,t){let r=e.filter(s=>t.has(s.from)&&t.has(s.to)),a=s=>(t.get(s)?.y??0)+80/2,l=new Map,p=new Map;for(let s of r)l.set(s.from,[...l.get(s.from)??[],s]),p.set(s.to,[...p.get(s.to)??[],s]);for(let s of l.values())s.sort((c,h)=>a(c.to)-a(h.to));for(let s of p.values())s.sort((c,h)=>a(c.from)-a(h.from));return r.map(s=>{let c=t.get(s.from),h=t.get(s.to),A=l.get(s.from)??[],i=p.get(s.to)??[],g=c.x+232,f=c.y+Vt(A.indexOf(s),A.length),x=h.x,I=h.y+Vt(i.indexOf(s),i.length),W=x>g?Math.max(32,(x-g)*.5):90,E=`M ${g} ${f} C ${g+W} ${f}, ${x-W} ${I}, ${x} ${I}`;return{...s,d:E,sx:g,sy:f,tx:x,ty:I}})}function ft(e,t,r){let a=new Set,l=[t];for(;l.length>0;){let p=l.pop();for(let s of e){let c=r==="down"?s.from===p?s.to:void 0:s.to===p?s.from:void 0;c!==void 0&&!a.has(c)&&c!==t&&(a.add(c),l.push(c))}}return a}function qt(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 mt(e){if(e)return e.includes("/")?e.slice(e.indexOf("/")+1):e}function Yt(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(e>=1e4?0:1)}k`:String(e)}var So={running:"running",queued:"queued",completed:"completed",failed:"failed",cancelled:"cancelled",idle:"idle"};function fe(e,t){if(e.kind==="root")return e.rawStatus;let r=e.rawStatus===e.state?So[e.state]:e.rawStatus,a=e.startedAt;return a===void 0?r:e.state==="running"?`${r} \xB7 ${qt(t-a)}`:e.endedAt!==void 0?`${r} \xB7 ${qt(e.endedAt-a)}`:r}var To=new Set(["running","queued","completed","failed","cancelled","idle"]),he=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),J=e=>typeof e=="number"&&Number.isFinite(e),me=e=>e===void 0||typeof e=="string",ce=e=>e===void 0||J(e),_o=e=>typeof e=="string"&&To.has(e);function yo(e){return he(e)?typeof e.id=="string"&&(e.kind==="root"||e.kind==="task")&&typeof e.sessionId=="string"&&typeof e.title=="string"&&_o(e.state)&&typeof e.rawStatus=="string"&&me(e.agent)&&me(e.model)&&ce(e.createdAt)&&ce(e.startedAt)&&ce(e.endedAt)&&me(e.summary)&&me(e.error)&&ce(e.tokens)&&ce(e.costUsd)&&ce(e.toolCalls)&&me(e.parentId)&&J(e.column)&&J(e.wave):!1}function Ao(e){return he(e)&&typeof e.id=="string"&&typeof e.from=="string"&&typeof e.to=="string"&&(e.kind==="spawn"||e.kind==="uses")}function wo(e){return he(e)&&J(e.column)&&J(e.total)&&J(e.done)&&J(e.running)}function vo(e){return he(e)&&J(e.omittedNodes)&&Number.isInteger(e.omittedNodes)&&e.omittedNodes>=0}function Mo(e){return he(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(yo)&&Array.isArray(e.edges)&&e.edges.every(Ao)&&Array.isArray(e.columns)&&e.columns.every(wo)&&J(e.models)&&(e.truncated===void 0||vo(e.truncated))}function Oo(e){let t=JSON.parse(e);if(!Mo(t))throw new Error("service answered with an unexpected graph shape");return t}var Ue=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 a=await this.deps.fetch(t);if(r!==this.generation)return;if(a.status!==200)throw new Error(`service answered HTTP ${a.status}: ${a.body.slice(0,200)}`);let l=Oo(a.body);l.status!=="ok"||l.nodes.length<=1?(this.signature="",this.deps.show({kind:"empty"})):a.body!==this.signature&&(this.signature=a.body,this.deps.show({kind:"graph",graph:l}));let p=l.nodes.some(s=>s.state==="running"||s.state==="queued");this.deps.schedule(p?1500:5e3,()=>{this.refresh()})}catch(a){if(r!==this.generation)return;this.signature="",this.deps.show({kind:"error",error:a}),this.deps.schedule(1e4,()=>{this.refresh()})}finally{this.inFlight=!1,(this.pending||r!==this.generation)&&(this.pending=!1,this.refresh())}}};var Jt="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 j=st(),G=e=>document.querySelector(e),d={app:G("#app"),title:G("#title"),titleDot:G("#title-dot"),meta:G("#meta"),viewport:G("#viewport"),world:G("#world"),edges:G("#edges"),bands:G("#bands"),nodes:G("#nodes"),empty:G("#empty"),inspector:G("#inspector"),settings:G("#settings")},Ee=null,to=!1,M,C,Wt="",V,ne={},ht,_={x:0,y:0,k:1},de=new Map;function L(e,t="",r=""){let a=document.createElement(e);return t&&(a.className=t),r&&(a.textContent=r),a}function gt(e,t=""){d.empty.replaceChildren(L("strong","",e),...t?[L("p","",t)]:[]),d.empty.hidden=!1,d.world.hidden=!0,d.inspector.hidden=!0}function oo(e){return e instanceof u?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 le(){d.world.style.transform=`translate(${_.x}px, ${_.y}px) scale(${_.k})`,d.app.style.setProperty("--zoom",String(_.k))}function De(){if(!C)return;let e=d.viewport.clientWidth,t=d.viewport.clientHeight,r=Math.min(1,Math.max(.62,Math.min((e-16)/C.width,(t-16)/C.height)));_.k=r,_.x=Math.round(C.width*r<=e?(e-C.width*r)/2:8),_.y=Math.round(Math.max(8,(t-C.height*r)/2)),le()}function no(e){let t=e?C?.boxes.get(e):void 0;if(!t)return De();_.k=Math.max(_.k,.8),_.x=Math.round(d.viewport.clientWidth/2-(t.x+232/2)*_.k),_.y=Math.round(d.viewport.clientHeight/2-(t.y+80/2)*_.k),le()}function ke(e,t=d.viewport.clientWidth/2,r=d.viewport.clientHeight/2){let a=Math.min(2,Math.max(.2,_.k*e));_.x=t-(t-_.x)*a/_.k,_.y=r-(r-_.y)*a/_.k,_.k=a,le()}var K,Et=!1;d.viewport.addEventListener("pointerdown",e=>{e.button===0&&(K={x:e.clientX,y:e.clientY,vx:_.x,vy:_.y,moved:!1})});window.addEventListener("pointermove",e=>{if(!K)return;let t=e.clientX-K.x,r=e.clientY-K.y;!K.moved&&Math.hypot(t,r)<4||(K.moved||(K.moved=!0,d.viewport.setPointerCapture?.(e.pointerId),d.app.classList.add("is-panning")),_.x=K.vx+t,_.y=K.vy+r,le())});window.addEventListener("pointerup",()=>{K?.moved&&(Et=!0,setTimeout(()=>{Et=!1},0)),K=void 0,d.app.classList.remove("is-panning")});d.viewport.addEventListener("wheel",e=>{e.preventDefault();let t=d.viewport.getBoundingClientRect();e.ctrlKey||e.metaKey||Math.abs(e.deltaY)>Math.abs(e.deltaX)*2&&!e.shiftKey?ke(Math.exp(-e.deltaY*(e.ctrlKey?.01:.0015)),e.clientX-t.left,e.clientY-t.top):(_.x-=e.deltaX||(e.shiftKey?e.deltaY:0),_.y-=e.shiftKey?0:e.deltaY,le())},{passive:!1});G("#btn-fit").addEventListener("click",De);G("#btn-locate").addEventListener("click",()=>{let e=M?.nodes.find(t=>t.kind==="task"&&t.state==="running");no(M?.focusId!==M?.rootId?M?.focusId:e?.id??M?.rootId)});G("#btn-in").addEventListener("click",()=>ke(1.2));G("#btn-out").addEventListener("click",()=>ke(1/1.2));window.addEventListener("keydown",e=>{e.target instanceof HTMLInputElement||(e.key==="0"?De():e.key==="+"||e.key==="="?ke(1.2):e.key==="-"&&ke(1/1.2))});function ge(e){if(V=e,!M)return;let t=M.edges,r=new Set(e?t.filter(s=>s.to===e).map(s=>s.from):[]),a=new Set(e?t.filter(s=>s.from===e).map(s=>s.to):[]),l=e?ft(t,e,"up"):new Set,p=e?ft(t,e,"down"):new Set;d.app.classList.toggle("has-hover",e!==void 0);for(let[s,c]of de)c.classList.toggle("is-hover",s===e),c.classList.toggle("is-input",r.has(s)),c.classList.toggle("is-output",a.has(s)),c.classList.toggle("is-reach",l.has(s)||p.has(s));for(let s of d.edges.querySelectorAll("path[data-edge]")){let c=s.dataset.from??"",h=s.dataset.to??"";s.classList.toggle("is-in",e!==void 0&&h===e),s.classList.toggle("is-out",e!==void 0&&c===e),s.classList.toggle("is-reach",e!==void 0&&(l.has(c)&&(l.has(h)||h===e)||p.has(h)&&(p.has(c)||c===e)))}Lo()}function Lo(){let e=M?.nodes.find(A=>A.id===(V??(M?.focusId!==M?.rootId?M?.focusId:void 0)));if(!e||!M){d.inspector.hidden=!0;return}let t=M.edges.filter(A=>A.to===e.id).length,r=M.edges.filter(A=>A.from===e.id).length,a=[fe(e,Date.now())];e.agent&&a.push(e.agent);let l=mt(e.model);l&&a.push(l),e.toolCalls!==void 0&&a.push(`${e.toolCalls} tools`),e.tokens!==void 0&&a.push(`${Yt(e.tokens)} tok`),e.costUsd!==void 0&&a.push(`$${e.costUsd.toFixed(2)}`);let p=L("div","i-head");p.append(L("span",`dot s-${e.state}`),L("strong","",e.title));let s=L("div","i-flow");s.append(L("span","i-in",`\u2190 ${t} input${t===1?"":"s"}`),L("span","i-out",`${r} output${r===1?"":"s"} \u2192`));let c=[p,L("div","i-facts",a.join(" \xB7 ")),s],h=e.error??e.summary;h&&c.push(L("p",e.error?"i-text is-error":"i-text",h)),c.push(L("div","i-hint",e.kind==="root"?"Click to open the orchestrating session":"Click to open this sub-agent's session")),d.inspector.replaceChildren(...c),d.inspector.hidden=!1}function Co(e){let t=de.get(e.id);return t||(t=L("button","node"),t.type="button",t.dataset.id=e.id,t.append(L("div","n-head"),L("div","n-status"),L("div","n-meta"),L("div","n-sub")),t.querySelector(".n-head")?.append(L("span","dot"),L("span","n-title")),t.addEventListener("pointerenter",()=>ge(e.id)),t.addEventListener("pointerleave",()=>{V===e.id&&ge(void 0)}),t.addEventListener("focus",()=>ge(e.id)),t.addEventListener("blur",()=>{V===e.id&&ge(void 0)}),t.addEventListener("click",()=>{Et||$o(e.id)}),de.set(e.id,t),d.nodes.append(t)),t}function Ro(e,t,r){e.className=`node k-${t.kind} s-${t.state}${M?.focusId===t.id&&t.kind==="task"?" is-current":""}`,V===t.id&&e.classList.add("is-hover"),e.setAttribute("aria-label",`${t.title}, ${fe(t,r)}. Open session.`);let a=(l,p)=>{let s=e.querySelector(l);s&&s.textContent!==p&&(s.textContent=p)};a(".n-title",t.title),a(".n-status",fe(t,r)),a(".n-meta",t.kind==="root"?`${M?.nodes.length?M.nodes.length-1:0} sub-agents`:[t.agent,mt(t.model)].filter(Boolean).join(" \xB7 ")),a(".n-sub",t.error??t.summary??""),e.querySelector(".dot")?.setAttribute("class",`dot s-${t.state}`)}function Go(e){M=e,C=jt(e),d.world.hidden=!1,d.empty.hidden=!0,d.world.style.width=`${C.width}px`,d.world.style.height=`${C.height}px`,d.edges.setAttribute("width",String(C.width)),d.edges.setAttribute("height",String(C.height)),d.edges.setAttribute("viewBox",`0 0 ${C.width} ${C.height}`);let t=new Map(e.nodes.map(i=>[i.id,i.state])),r=document.createDocumentFragment();for(let i of C.edges){let g=document.createElementNS(Jt,"path");g.setAttribute("d",i.d),g.dataset.edge=i.id,g.dataset.from=i.from,g.dataset.to=i.to;let f=t.get(i.to)==="running"||t.get(i.to)==="queued";if(g.setAttribute("class",`edge k-${i.kind}${f?" is-live":""}`),g.setAttribute("marker-end","url(#arrow)"),r.append(g),f){let x=document.createElementNS(Jt,"path");x.setAttribute("d",i.d),x.setAttribute("class","flow"),x.setAttribute("pathLength","1"),r.append(x)}}d.edges.querySelectorAll("path.edge, path.flow").forEach(i=>i.remove()),d.edges.append(r),d.bands.replaceChildren(...[...C.columnX].map(([i,g])=>{let f=L("div","band");f.style.left=`${g}px`,f.style.width=`${232}px`;let x=e.columns.find(I=>I.column===i);return i===0?f.textContent="Orchestrator":x&&(f.textContent=`Wave ${i} \xB7 ${x.done}/${x.total} done${x.running?` \xB7 ${x.running} running`:""}`),x?.running&&f.classList.add("is-live"),f}));let a=Date.now(),l=new Set;for(let i of e.nodes){let g=Co(i),f=C.boxes.get(i.id);f&&(g.style.transform=`translate(${f.x}px, ${f.y}px)`),Ro(g,i,a),l.add(i.id)}for(let[i,g]of de)l.has(i)||(g.remove(),de.delete(i));let p=e.nodes.filter(i=>i.kind==="task"),s=p.filter(i=>i.state==="completed"||i.state==="failed"||i.state==="cancelled").length,c=p.filter(i=>i.state==="running").length,h=e.columns.length,A=e.columns.find(i=>i.running>0||i.done<i.total)?.column;d.title.textContent=e.title,d.titleDot.className=`dot s-${c>0?"running":p.some(i=>i.state==="failed")?"failed":s===p.length?"completed":"idle"}`,d.meta.textContent=[A!==void 0?`wave ${A}/${h}`:`${h} wave${h===1?"":"s"}`,`${s}/${p.length} done`,...c?[`${c} running`]:[],...e.models?[`${e.models} model${e.models===1?"":"s"}`]:[],...e.truncated?[`${e.truncated.omittedNodes} omitted`]:[]].join(" \xB7 "),j.setBadge(c>0?c:null).catch(()=>{}),Wt!==e.rootId&&(Wt=e.rootId,requestAnimationFrame(()=>e.focusId!==e.rootId?no(e.focusId):De())),V&&!e.nodes.some(i=>i.id===V)&&(V=void 0),ge(V)}function Io(){if(!M)return;let e=Date.now();for(let t of M.nodes){if(t.state!=="running")continue;let a=de.get(t.id)?.querySelector(".n-status");a&&(a.textContent=fe(t,e))}}setInterval(Io,1e3);async function $o(e){let t=M?.nodes.find(r=>r.id===e);if(t)try{await j.openSession(t.sessionId)}catch(r){let[a,l]=oo(r);await j.toast({kind:"error",message:`${a}: ${l}`}).catch(()=>{})}}var xe=new Ue({fetch:e=>{let t={session:e};return ne.agentDir&&(t.agentDir=ne.agentDir),ne.stateDir&&(t.stateDir=ne.stateDir),j.serviceRequest({method:"GET",path:"/graph",query:t})},show:e=>{if(e.kind==="graph"){Go(e.graph);return}M=void 0,j.setBadge(null).catch(()=>{}),e.kind==="no-session"?gt("No session open","Open a chat to see the OmO agents working behind it."):e.kind==="empty"?gt("No sub-agents yet","When this session launches OmO tasks or workflows, they appear here as a live graph."):gt(...oo(e.error))},schedule:(e,t)=>{ht&&clearTimeout(ht),ht=setTimeout(t,e)},isHidden:()=>document.hidden}),Qt=G("#btn-settings");Qt.addEventListener("click",()=>{d.settings.hidden=!d.settings.hidden,Qt.setAttribute("aria-expanded",String(!d.settings.hidden)),d.settings.hidden||d.settings.querySelector("input")?.focus()});d.settings.addEventListener("submit",e=>{e.preventDefault();let t=new FormData(d.settings),r={},a=String(t.get("agentDir")??"").trim(),l=String(t.get("stateDir")??"").trim();a&&(r.agentDir=a),l&&(r.stateDir=l),ne=r,d.settings.hidden=!0,j.storage.set("paths",r).catch(()=>{}),xe.invalidate()});function No(){for(let e of["agentDir","stateDir"]){let t=d.settings.querySelector(`input[name="${e}"]`);t&&(t.value=ne[e]??"")}}var Zt=!1;j.onReady(e=>{it(e,document.documentElement),d.app.dataset.surface=e.surface,!Zt&&(Zt=!0,Ee=e.session?.id??Ee,j.storage.get("paths").then(t=>{if(t&&typeof t=="object"&&!Array.isArray(t)){let r=t;ne={...typeof r.agentDir=="string"?{agentDir:r.agentDir}:{},...typeof r.stateDir=="string"?{stateDir:r.stateDir}:{}}}No()}).catch(()=>{}).finally(()=>{to=!0,xe.setSession(Ee)}))});j.onSession(e=>{let t=e?.id??null;t!==Ee&&(V=void 0),Ee=t,to&&xe.setSession(t)});j.onSessionLifecycle(()=>{xe.refresh()});document.addEventListener("visibilitychange",()=>{document.hidden||xe.refresh()});window.addEventListener("resize",()=>{C&&_.k<=1&&le()});})();
@@ -1,5 +1,6 @@
1
1
  // extensions/omo-dag/src/service.ts
2
2
  import http from "node:http";
3
+ import { resolve } from "node:path";
3
4
 
4
5
  // extensions/omo-dag/src/graph.ts
5
6
  import { createHash } from "node:crypto";
@@ -236,7 +237,7 @@ function buildGraph(sessionId, tasks, registry) {
236
237
  }
237
238
 
238
239
  // extensions/omo-dag/src/store.ts
239
- import { readdirSync, readFileSync, statSync } from "node:fs";
240
+ import { lstatSync, readdirSync, readFileSync, statSync } from "node:fs";
240
241
  import { homedir } from "node:os";
241
242
  import { join } from "node:path";
242
243
  function expandHome(path) {
@@ -261,6 +262,14 @@ function list(dir) {
261
262
  throw error;
262
263
  }
263
264
  }
265
+ function isRegularFile(path) {
266
+ try {
267
+ return lstatSync(path).isFile();
268
+ } catch (error) {
269
+ if (isMissing(error)) return false;
270
+ throw error;
271
+ }
272
+ }
264
273
  var JsonCache = class {
265
274
  entries = /* @__PURE__ */ new Map();
266
275
  read(path, accept) {
@@ -310,7 +319,9 @@ var TaskStore = class {
310
319
  for (const dir of this.storeDirs()) {
311
320
  for (const file of list(join(dir, "tasks"))) {
312
321
  if (!file.endsWith(".json")) continue;
313
- const task = this.tasks.read(join(dir, "tasks", file), normalizeTask);
322
+ const path = join(dir, "tasks", file);
323
+ if (!isRegularFile(path)) continue;
324
+ const task = this.tasks.read(path, normalizeTask);
314
325
  if (task) out.set(task.task_id, task);
315
326
  }
316
327
  }
@@ -327,21 +338,74 @@ var TaskStore = class {
327
338
  };
328
339
 
329
340
  // extensions/omo-dag/src/service.ts
341
+ var MAX_TASK_STORES = 32;
342
+ var MAX_GRAPH_BODY_CHARS = 24e4;
343
+ function canonicalRoots(roots) {
344
+ return {
345
+ agentDirs: roots.agentDirs.map((path) => resolve(expandHome(path))),
346
+ stateDirs: roots.stateDirs.map((path) => resolve(expandHome(path)))
347
+ };
348
+ }
349
+ function graphWithTaskLimit(graph, taskCount) {
350
+ const root = graph.nodes.find((node) => node.kind === "root");
351
+ if (!root) return graph;
352
+ const tasks = graph.nodes.filter((node) => node.kind === "task");
353
+ const shown = [root, ...tasks.slice(0, taskCount)];
354
+ const shownIds = new Set(shown.map((node) => node.id));
355
+ const columns = /* @__PURE__ */ new Map();
356
+ for (const node of shown) {
357
+ if (node.kind === "root") continue;
358
+ const column = columns.get(node.column) ?? { column: node.column, total: 0, done: 0, running: 0 };
359
+ column.total++;
360
+ if (node.state === "completed" || node.state === "failed" || node.state === "cancelled") column.done++;
361
+ if (node.state === "running") column.running++;
362
+ columns.set(node.column, column);
363
+ }
364
+ return {
365
+ ...graph,
366
+ nodes: shown,
367
+ edges: graph.edges.filter((edge) => shownIds.has(edge.from) && shownIds.has(edge.to)),
368
+ columns: [...columns.values()].sort((a, b) => a.column - b.column),
369
+ ...taskCount < tasks.length ? { truncated: { omittedNodes: tasks.length - taskCount } } : {}
370
+ };
371
+ }
372
+ function boundedGraph(graph) {
373
+ if (JSON.stringify(graph).length <= MAX_GRAPH_BODY_CHARS) return graph;
374
+ const totalTasks = graph.nodes.filter((node) => node.kind === "task").length;
375
+ let low = 0;
376
+ let high = totalTasks;
377
+ while (low < high) {
378
+ const count = Math.ceil((low + high) / 2);
379
+ if (JSON.stringify(graphWithTaskLimit(graph, count)).length <= MAX_GRAPH_BODY_CHARS) low = count;
380
+ else high = count - 1;
381
+ }
382
+ return graphWithTaskLimit(graph, low);
383
+ }
330
384
  function rootsFrom(query, fallback = defaultRoots()) {
331
385
  const pick = (key, base) => {
332
386
  const value = query.get(key)?.trim();
333
387
  return value ? [expandHome(value)] : base;
334
388
  };
335
- return { agentDirs: pick("agentDir", fallback.agentDirs), stateDirs: pick("stateDir", fallback.stateDirs) };
389
+ return canonicalRoots({
390
+ agentDirs: pick("agentDir", fallback.agentDirs),
391
+ stateDirs: pick("stateDir", fallback.stateDirs)
392
+ });
336
393
  }
337
394
  function createServer(token2, makeStore = (r) => new TaskStore(r)) {
338
395
  const stores = /* @__PURE__ */ new Map();
339
396
  const storeFor = (roots) => {
340
397
  const key = JSON.stringify(roots);
341
- let store = stores.get(key);
342
- if (!store) {
343
- store = makeStore(roots);
344
- stores.set(key, store);
398
+ const cached = stores.get(key);
399
+ if (cached) {
400
+ stores.delete(key);
401
+ stores.set(key, cached);
402
+ return cached;
403
+ }
404
+ const store = makeStore(roots);
405
+ stores.set(key, store);
406
+ if (stores.size > MAX_TASK_STORES) {
407
+ const oldest = stores.keys().next().value;
408
+ if (oldest !== void 0) stores.delete(oldest);
345
409
  }
346
410
  return store;
347
411
  };
@@ -359,7 +423,7 @@ function createServer(token2, makeStore = (r) => new TaskStore(r)) {
359
423
  return json(res, 400, { error: "session query must be an OpenChamber session id" });
360
424
  try {
361
425
  const store = storeFor(rootsFrom(url.searchParams));
362
- return json(res, 200, buildGraph(session, store.loadTasks(), store.loadRegistry()));
426
+ return json(res, 200, boundedGraph(buildGraph(session, store.loadTasks(), store.loadRegistry())));
363
427
  } catch (error) {
364
428
  return json(res, 500, { error: error instanceof Error ? error.message : String(error) });
365
429
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antechamber",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "description": "OpenCode-compatible HTTP/SSE server that lets OpenChamber drive the pi coding agent (and OmO) over RPC",
5
5
  "type": "module",
6
6
  "license": "MIT",