antechamber 0.2.5 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,19 @@ and this project uses [Semantic Versioning](https://semver.org/).
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.7] - 2026-10-15
11
+
12
+ ### Fixed
13
+
14
+ - OmO Graph: panning no longer selects the wave labels, so pressing near the
15
+ graph can no longer start a native text drag. That drag cancelled the pan
16
+ after a few pixels, and before 0.2.3 it left the graph following the mouse
17
+ with the button released.
18
+
19
+ ## [0.2.6] - 2026-10-15
20
+
21
+ - fix(omo-graph): stop ending the pan on blur and lost capture
22
+
10
23
  ## [0.2.5] - 2026-10-15
11
24
 
12
25
  ### Added
@@ -30,6 +43,13 @@ and this project uses [Semantic Versioning](https://semver.org/).
30
43
  `/mcp auth-complete` with a paste-the-code step. A completed sign-in emits
31
44
  `mcp.status.changed`.
32
45
 
46
+ ### Fixed
47
+
48
+ - OmO Graph: dragging the graph no longer stops after a fraction of a second.
49
+ The previous stuck-pan fix also ended the drag when the panel lost focus or
50
+ pointer capture, which can happen while the button is still held; the drag
51
+ now ends only on release, cancel, or a move without the button held.
52
+
33
53
  ## [0.2.4] - 2026-10-15
34
54
 
35
55
  ### Added
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antechamber-omo-graph",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "OpenChamber extension: live, interactive graph of the OmO sub-agents behind the current session",
5
5
  "private": true,
6
6
  "type": "module",
@@ -52,7 +52,7 @@
52
52
  #settings button { padding: 5px 12px; border-radius: 6px; border: 1px solid var(--border); background: var(--surface-2); cursor: pointer; }
53
53
  #settings #btn-save { background: var(--accent); color: var(--oc-primary-fg, #001); border-color: transparent; }
54
54
 
55
- #viewport { position: relative; flex: 1; overflow: hidden; cursor: grab; touch-action: none;
55
+ #viewport { position: relative; flex: 1; overflow: hidden; cursor: grab; touch-action: none; -webkit-user-select: none; user-select: none;
56
56
  background-image: radial-gradient(color-mix(in srgb, var(--muted) 22%, transparent) 1px, transparent 1px);
57
57
  background-size: 18px 18px; }
58
58
  .is-panning #viewport { cursor: grabbing; }
@@ -109,6 +109,7 @@
109
109
  @keyframes pulse { 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--run) 60%, transparent); } 50% { box-shadow: 0 0 0 4px transparent; } }
110
110
 
111
111
  #empty { position: absolute; inset: 0; display: grid; place-content: center; text-align: center; gap: 6px; padding: 24px; color: var(--muted); }
112
+ #empty { -webkit-user-select: text; user-select: text; cursor: auto; }
112
113
  #empty strong { color: var(--fg); font-size: 14px; }
113
114
  #empty p { margin: 0; max-width: 34ch; font-size: 12px; }
114
115
 
@@ -1,4 +1,4 @@
1
- "use strict";(()=>{var x="openchamber.sdk";var ze=`
1
+ "use strict";(()=>{var x="openchamber.sdk";var Fe=`
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,9 +28,9 @@
28
28
  * { scrollbar-color: auto; }
29
29
  ::-webkit-scrollbar-thumb, ::-webkit-scrollbar-thumb:hover { background: CanvasText; }
30
30
  }
31
- `;var yt=["file","directory","other","missing"],Ve=e=>!!(e&&"sessionId"in e),je=e=>!!(e&&"sent"in e&&!("sessionId"in e));var Te=500,_e=32e3,At=16e3,wt=128,vt=200,Mt=2e3,Ot=16e3,Lt=80,Ct=200,Rt=16e3;var Gt=2e3;var Ye=2e4,ye=1024,Ae=2e6;var we=64e3,ve=8e3,qe=4e3;var Je=9e4;var It=999,Me=500,$t=["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"],Nt=["stopped","starting","ready","failed"],io=new Set($t),Ut=e=>io.has(e),Dt=e=>e&&Ut(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,Ht=e=>ne(e)&&JSON.stringify(e).length<=Rt,_t=e=>e?.trim().slice(0,Ct)??"",re=e=>{let t=e.id.trim().slice(0,wt),r=e.title.trim().slice(0,vt),a=e.url.trim().slice(0,Mt),l=e.text?.trim().slice(0,Ot),p=e.author?.trim().slice(0,Lt),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=_t(e.branches?.head),A=_t(e.branches?.base);h&&A&&(c.branches={head:h,base:A})}return Ht(e.data)&&(c.data=e.data),c},We=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},Qe=e=>{let t={text:e.text.trim().slice(0,At)};return e.send&&(t.send=!0),t},Ze=e=>e===null||!Number.isFinite(e)?null:Math.min(It,Math.max(0,Math.round(e)));var se=e=>e.length>0&&e.length<=ye&&!e.includes("\0")&&!e.includes("\\");var Oe=e=>!e.startsWith("/")||e.includes("\0")||e.includes("\\")||e.includes("://")||e.length>Gt?!1:!e.split("/").some(r=>r==="."||r===".."),ao=new Set(Nt),et=e=>!!(e&&"status"in e&&ao.has(String(e.status))&&!("body"in e)),Le=e=>!!(e&&"status"in e&&"body"in e&&Number.isInteger(e.status)),tt=e=>!!(e&&"content"in e&&String(e.content)===e.content),ot=e=>!!(e&&"written"in e&&e.written===!0),nt=e=>!!(e&&"entries"in e&&Array.isArray(e.entries)),co=new Set(yt),rt=e=>!!(e&&"kind"in e&&"size"in e&&co.has(String(e.kind))&&Number.isFinite(e.size)),st=e=>!!(e&&"text"in e&&String(e.text)===e.text&&!("status"in e)),lo=new Set(["workspace","ready","directory","session","connection","settings","session-lifecycle","item","resolve","action"]),po=e=>Object(e)===e?e:null,Ke=e=>String(e)===e&&e.length>0,uo=e=>{if(!Ke(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&&Ke(e.error)?{channel:x,v:1,type:"result",id:e.id,ok:!1,error:e.error,code:Dt(Ke(e.code)?e.code:void 0)}:null},it=e=>{let t=po(e);return!t||t.channel!==x||t.v!==1?null:t.type==="result"?uo(t):!lo.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}},Pt=()=>Promise.reject(new u("BAD_PATH",'Request path must start with "/" and stay on the declared origin.')),Ce=()=>Promise.reject(new u("BAD_PATH",`File path must be 1 to ${ye} characters without NUL or backslash.`)),S=e=>(e.value+=1,`oc-${e.value}`),at=(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??Ye,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},T=null,j=null,St=o=>o?{sessionId:o.id,phase:o.busy?"started":"completed"}:null,W=o=>{t.parent.postMessage(o,"*")},N=(o,n)=>{for(let m of o)try{m(n)}catch(w){console.error(w)}},Tt=o=>{if(!(o instanceof MessageEvent)||!r(o.source))return;let n=it(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,j=St(n.payload.session),N(l,n.payload),N(p,n.payload.directory),N(s,n.payload.session),j&&N(c,j),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?j?.sessionId!==n.payload.session.id&&(j=St(n.payload.session)):j=null,N(s,n.payload.session);return}if(n.type==="session-lifecycle"){j=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=G=>{J||W({channel:x,v:1,type:"action-result",id:n.id,payload:G})},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}),G=>{let Fe=(G instanceof Error?G.message:String(G)).trim();w({ok:!1,error:(Fe||"Action failed.").slice(0,Me)})});return}if(n.type==="resolve"){let w=G=>{W({channel:x,v:1,type:"resolve-result",id:n.id,payload:G})},F=g;if(!F){w({error:"This extension does not resolve commands."});return}Promise.resolve().then(()=>F(n.payload)).then(G=>w({item:G?re(G):null}),G=>{let Fe=(G instanceof Error?G.message:String(G)).trim();w({error:(Fe||"Command failed.").slice(0,Me)})});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",Tt),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,w)=>{let F=setTimeout(()=>{k.delete(o.id),w(new u("HOST_TIMEOUT","Host did not answer in time."))},n);k.set(o.id,{resolve:m,reject:w,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.`)},Xe=async o=>{o.kind!=="projects"&&Z(o.projectId);let n=await H({...Q,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},Be=async(o,n)=>{o.kind!=="projects"&&Z(o.projectId);let m=S(E);I.set(m,n);try{await P({...Q,type:"workspace-subscribe",id:S(E),payload:{subscriptionId:m,query:o}})}catch(w){throw I.delete(m),J||W({...Q,type:"workspace-unsubscribe",id:S(E),payload:{subscriptionId:m}}),w}return()=>{!I.delete(m)||J||W({...Q,type:"workspace-unsubscribe",id:S(E),payload:{subscriptionId:m}})}},Se=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: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 Xe({kind:"projects"});if(o.kind!=="projects")throw new u("HOST_REJECTED","Expected projects.");return o},listWorktrees:async o=>{let n=await Xe({kind:"worktrees",projectId:o});if(n.kind!=="worktrees")throw new u("HOST_REJECTED","Expected worktrees.");return n},listSessions:async o=>{let n=await Xe({kind:"sessions",projectId:o});if(n.kind!=="sessions")throw new u("HOST_REJECTED","Expected sessions.");return n},onProjects:o=>Be({kind:"projects"},n=>{n.kind==="projects"&&o(n)}),onWorktrees:(o,n)=>Be({kind:"worktrees",projectId:o},m=>{m.kind==="worktrees"&&n(m)}),onSessions:(o,n)=>Be({kind:"sessions",projectId:o},m=>{m.kind==="sessions"&&n(m)}),openSession:async o=>{Z(o),await P({...Q,type:"open-session",id:S(E),payload:{sessionId:o}})},storage:{get:async o=>{let n=await Se({op:"get",key:o});return n.op==="get"&&n.found?n.value:void 0},set:async(o,n)=>{await Se({op:"set",key:o,value:n})},delete:async o=>{await Se({op:"delete",key:o})},keys:async()=>{let o=await Se({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),j&&o(j),()=>{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>Te?Promise.reject(new u("HOST_REJECTED",`Toast message must contain 1 to ${Te} characters.`)):o.copy&&o.copy!==!0&&(!o.copy.text.length||o.copy.text.length>_e)?Promise.reject(new u("HOST_REJECTED",`Toast copy text must contain 1 to ${_e} characters.`)):P({channel:x,v:1,type:"toast",id:S(E),payload:{...o,message:n}})},openUrl:o=>P({channel:x,v:1,type:"open-url",id:S(E),payload:{url:o}}),openSurface:o=>P({channel:x,v:1,type:"open-surface",id:S(E),payload:{surfaceId:o}}),writeClipboard:o=>P({channel:x,v:1,type:"clipboard-write",id:S(E),payload:{text:o}}),compose:o=>P({channel:x,v:1,type:"compose",id:S(E),payload:o}),attach:o=>P({channel:x,v:1,type:"attach",id:S(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:S(E),payload:We(o)},e.requestTimeoutMs??18e4);if(!Ve(m))throw new u("HOST_REJECTED","Host did not return a session.");return m},prompt:o=>H({channel:x,v:1,type:"prompt",id:S(E),payload:Qe(o)}).then(n=>{if(!je(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:S(E),payload:re(o)}),close:()=>P({channel:x,v:1,type:"close",id:S(E)}),oauthStart:()=>P({channel:x,v:1,type:"oauth-start",id:S(E)}),oauthDisconnect:()=>P({channel:x,v:1,type:"oauth-disconnect",id:S(E)}),request:o=>(Oe(o.path)?H({channel:x,v:1,type:"request",id:S(E),payload:o}):Pt()).then(n=>{if(!Le(n))throw new u("HOST_REJECTED","Host request result was empty.");return n}),serviceRequest:o=>(Oe(o.path)?H({channel:x,v:1,type:"service-request",id:S(E),payload:o}):Pt()).then(n=>{if(!Le(n))throw new u("HOST_REJECTED","Host service request result was empty.");return n}),serviceStatus:()=>H({channel:x,v:1,type:"service-status",id:S(E)}).then(o=>{if(!et(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:S(E),payload:{path:o}}):Ce()).then(n=>{if(!tt(n))throw new u("HOST_REJECTED","Host did not return file content.");return n}),writeFile:(o,n)=>se(o)?n.length>Ae?Promise.reject(new u("FILE_TOO_LARGE",`Content is over ${Ae} characters.`)):H({channel:x,v:1,type:"file-write",id:S(E),payload:{path:o,content:n}}).then(m=>{if(!ot(m))throw new u("HOST_REJECTED","Host did not confirm the write.");return m}):Ce(),listDir:o=>(se(o)?H({channel:x,v:1,type:"file-list",id:S(E),payload:{path:o}}):Ce()).then(n=>{if(!nt(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:S(E),payload:{path:o}}):Ce()).then(n=>{if(!rt(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>we)return Promise.reject(new u("HOST_REJECTED",`Prompt must be 1 to ${we} characters.`));if(m!==void 0&&(m.length===0||m.length>ve))return Promise.reject(new u("HOST_REJECTED",`System prompt must be 1 to ${ve} characters.`));let w=o.maxOutputTokens===void 0?void 0:Math.min(qe,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:x,v:1,type:"generate",id:S(E),payload:F},e.requestTimeoutMs??Je).then(G=>{if(!st(G))throw new u("HOST_REJECTED","Host did not return generated text.");return G})},setBadge:o=>P({channel:x,v:1,type:"badge",id:S(E),payload:{count:Ze(o)}}),dispose:()=>{for(let o of I.keys())W({...Q,type:"workspace-unsubscribe",id:S(E),payload:{subscriptionId:o}});I.clear(),J=!0,g=null,f=null,t.removeEventListener("message",Tt);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 fo=[["--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"]],Ft=(e,t)=>{t.style.colorScheme=e.mode;for(let[r,a]of fo)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)},ct=(e,t)=>{Ft(e.theme,t),t.dataset&&(t.dataset.ocSurface=e.surface,t.dataset.ocTheme=e.theme.mode)};var mo={"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-${mo[e]}, ${t}))`,ee=y("surface-background","transparent"),Re=y("surface-elevated","transparent"),le=y("surface-elevated-foreground","inherit"),pe=y("surface-foreground","inherit"),v=y("surface-muted-foreground","gray"),ho=y("surface-muted","transparent"),B=y("interactive-border","currentColor"),X=y("interactive-hover","transparent"),te=y("interactive-active","transparent"),dt=y("interactive-selection","transparent"),lt=y("interactive-selection-foreground","inherit"),Vt=y("interactive-focus-ring","currentColor"),z=y("primary","currentColor"),pt=y("primary-text","inherit"),ut=y("error-text","inherit"),go=y("font-sans","inherit"),ft=y("font-mono","monospace"),zt=y("radius","9px"),O=(e,t,r="transparent")=>`color-mix(in srgb, ${e} ${t}%, ${r})`,Kt=`box-shadow: 0 0 0 2px ${Vt};`,Ge=e=>{let t=y(`status-${e}`,"currentColor");return`
31
+ `;var yt=["file","directory","other","missing"],Ke=e=>!!(e&&"sessionId"in e),Ve=e=>!!(e&&"sent"in e&&!("sessionId"in e));var Se=500,Te=32e3,At=16e3,wt=128,vt=200,Mt=2e3,Ot=16e3,Lt=80,Ct=200,Rt=16e3;var Gt=2e3;var je=2e4,_e=1024,ye=2e6;var Ae=64e3,we=8e3,Ye=4e3;var qe=9e4;var It=999,ve=500,$t=["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"],Nt=["stopped","starting","ready","failed"],io=new Set($t),Ut=e=>io.has(e),Dt=e=>e&&Ut(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,Ht=e=>ne(e)&&JSON.stringify(e).length<=Rt,_t=e=>e?.trim().slice(0,Ct)??"",re=e=>{let t=e.id.trim().slice(0,wt),r=e.title.trim().slice(0,vt),a=e.url.trim().slice(0,Mt),l=e.text?.trim().slice(0,Ot),p=e.author?.trim().slice(0,Lt),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=_t(e.branches?.head),A=_t(e.branches?.base);h&&A&&(c.branches={head:h,base:A})}return Ht(e.data)&&(c.data=e.data),c},Je=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},We=e=>{let t={text:e.text.trim().slice(0,At)};return e.send&&(t.send=!0),t},Qe=e=>e===null||!Number.isFinite(e)?null:Math.min(It,Math.max(0,Math.round(e)));var se=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>Gt?!1:!e.split("/").some(r=>r==="."||r===".."),ao=new Set(Nt),Ze=e=>!!(e&&"status"in e&&ao.has(String(e.status))&&!("body"in e)),Oe=e=>!!(e&&"status"in e&&"body"in e&&Number.isInteger(e.status)),et=e=>!!(e&&"content"in e&&String(e.content)===e.content),tt=e=>!!(e&&"written"in e&&e.written===!0),ot=e=>!!(e&&"entries"in e&&Array.isArray(e.entries)),co=new Set(yt),nt=e=>!!(e&&"kind"in e&&"size"in e&&co.has(String(e.kind))&&Number.isFinite(e.size)),rt=e=>!!(e&&"text"in e&&String(e.text)===e.text&&!("status"in e)),lo=new Set(["workspace","ready","directory","session","connection","settings","session-lifecycle","item","resolve","action"]),po=e=>Object(e)===e?e:null,ze=e=>String(e)===e&&e.length>0,uo=e=>{if(!ze(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&&ze(e.error)?{channel:x,v:1,type:"result",id:e.id,ok:!1,error:e.error,code:Dt(ze(e.code)?e.code:void 0)}:null},st=e=>{let t=po(e);return!t||t.channel!==x||t.v!==1?null:t.type==="result"?uo(t):!lo.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}},Pt=()=>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}`),it=(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??je,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},T=null,j=null,St=o=>o?{sessionId:o.id,phase:o.busy?"started":"completed"}:null,W=o=>{t.parent.postMessage(o,"*")},N=(o,n)=>{for(let m of o)try{m(n)}catch(w){console.error(w)}},Tt=o=>{if(!(o instanceof MessageEvent)||!r(o.source))return;let n=st(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,j=St(n.payload.session),N(l,n.payload),N(p,n.payload.directory),N(s,n.payload.session),j&&N(c,j),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?j?.sessionId!==n.payload.session.id&&(j=St(n.payload.session)):j=null,N(s,n.payload.session);return}if(n.type==="session-lifecycle"){j=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=G=>{J||W({channel:x,v:1,type:"action-result",id:n.id,payload:G})},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}),G=>{let Be=(G instanceof Error?G.message:String(G)).trim();w({ok:!1,error:(Be||"Action failed.").slice(0,ve)})});return}if(n.type==="resolve"){let w=G=>{W({channel:x,v:1,type:"resolve-result",id:n.id,payload:G})},F=g;if(!F){w({error:"This extension does not resolve commands."});return}Promise.resolve().then(()=>F(n.payload)).then(G=>w({item:G?re(G):null}),G=>{let Be=(G instanceof Error?G.message:String(G)).trim();w({error:(Be||"Command failed.").slice(0,ve)})});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",Tt),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,w)=>{let F=setTimeout(()=>{k.delete(o.id),w(new u("HOST_TIMEOUT","Host did not answer in time."))},n);k.set(o.id,{resolve:m,reject:w,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.`)},Pe=async o=>{o.kind!=="projects"&&Z(o.projectId);let n=await H({...Q,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},Xe=async(o,n)=>{o.kind!=="projects"&&Z(o.projectId);let m=S(E);I.set(m,n);try{await P({...Q,type:"workspace-subscribe",id:S(E),payload:{subscriptionId:m,query:o}})}catch(w){throw I.delete(m),J||W({...Q,type:"workspace-unsubscribe",id:S(E),payload:{subscriptionId:m}}),w}return()=>{!I.delete(m)||J||W({...Q,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"&&!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: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 Pe({kind:"projects"});if(o.kind!=="projects")throw new u("HOST_REJECTED","Expected projects.");return o},listWorktrees:async o=>{let n=await Pe({kind:"worktrees",projectId:o});if(n.kind!=="worktrees")throw new u("HOST_REJECTED","Expected worktrees.");return n},listSessions:async o=>{let n=await Pe({kind:"sessions",projectId:o});if(n.kind!=="sessions")throw new u("HOST_REJECTED","Expected sessions.");return n},onProjects:o=>Xe({kind:"projects"},n=>{n.kind==="projects"&&o(n)}),onWorktrees:(o,n)=>Xe({kind:"worktrees",projectId:o},m=>{m.kind==="worktrees"&&n(m)}),onSessions:(o,n)=>Xe({kind:"sessions",projectId:o},m=>{m.kind==="sessions"&&n(m)}),openSession:async o=>{Z(o),await P({...Q,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),j&&o(j),()=>{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:x,v:1,type:"toast",id:S(E),payload:{...o,message:n}})},openUrl:o=>P({channel:x,v:1,type:"open-url",id:S(E),payload:{url:o}}),openSurface:o=>P({channel:x,v:1,type:"open-surface",id:S(E),payload:{surfaceId:o}}),writeClipboard:o=>P({channel:x,v:1,type:"clipboard-write",id:S(E),payload:{text:o}}),compose:o=>P({channel:x,v:1,type:"compose",id:S(E),payload:o}),attach:o=>P({channel:x,v:1,type:"attach",id:S(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:S(E),payload:Je(o)},e.requestTimeoutMs??18e4);if(!Ke(m))throw new u("HOST_REJECTED","Host did not return a session.");return m},prompt:o=>H({channel:x,v:1,type:"prompt",id:S(E),payload:We(o)}).then(n=>{if(!Ve(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:S(E),payload:re(o)}),close:()=>P({channel:x,v:1,type:"close",id:S(E)}),oauthStart:()=>P({channel:x,v:1,type:"oauth-start",id:S(E)}),oauthDisconnect:()=>P({channel:x,v:1,type:"oauth-disconnect",id:S(E)}),request:o=>(Me(o.path)?H({channel:x,v:1,type:"request",id:S(E),payload:o}):Pt()).then(n=>{if(!Oe(n))throw new u("HOST_REJECTED","Host request result was empty.");return n}),serviceRequest:o=>(Me(o.path)?H({channel:x,v:1,type:"service-request",id:S(E),payload:o}):Pt()).then(n=>{if(!Oe(n))throw new u("HOST_REJECTED","Host service request result was empty.");return n}),serviceStatus:()=>H({channel:x,v:1,type:"service-status",id:S(E)}).then(o=>{if(!Ze(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:S(E),payload:{path:o}}):Le()).then(n=>{if(!et(n))throw new u("HOST_REJECTED","Host did not return file content.");return n}),writeFile:(o,n)=>se(o)?n.length>ye?Promise.reject(new u("FILE_TOO_LARGE",`Content is over ${ye} characters.`)):H({channel:x,v:1,type:"file-write",id:S(E),payload:{path:o,content:n}}).then(m=>{if(!tt(m))throw new u("HOST_REJECTED","Host did not confirm the write.");return m}):Le(),listDir:o=>(se(o)?H({channel:x,v:1,type:"file-list",id:S(E),payload:{path:o}}):Le()).then(n=>{if(!ot(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:S(E),payload:{path:o}}):Le()).then(n=>{if(!nt(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(Ye,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:x,v:1,type:"generate",id:S(E),payload:F},e.requestTimeoutMs??qe).then(G=>{if(!rt(G))throw new u("HOST_REJECTED","Host did not return generated text.");return G})},setBadge:o=>P({channel:x,v:1,type:"badge",id:S(E),payload:{count:Qe(o)}}),dispose:()=>{for(let o of I.keys())W({...Q,type:"workspace-unsubscribe",id:S(E),payload:{subscriptionId:o}});I.clear(),J=!0,g=null,f=null,t.removeEventListener("message",Tt);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 fo=[["--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"]],Ft=(e,t)=>{t.style.colorScheme=e.mode;for(let[r,a]of fo)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)},at=(e,t)=>{Ft(e.theme,t),t.dataset&&(t.dataset.ocSurface=e.surface,t.dataset.ocTheme=e.theme.mode)};var mo={"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-${mo[e]}, ${t}))`,ee=y("surface-background","transparent"),Ce=y("surface-elevated","transparent"),le=y("surface-elevated-foreground","inherit"),pe=y("surface-foreground","inherit"),v=y("surface-muted-foreground","gray"),ho=y("surface-muted","transparent"),B=y("interactive-border","currentColor"),X=y("interactive-hover","transparent"),te=y("interactive-active","transparent"),ct=y("interactive-selection","transparent"),dt=y("interactive-selection-foreground","inherit"),Vt=y("interactive-focus-ring","currentColor"),z=y("primary","currentColor"),lt=y("primary-text","inherit"),pt=y("error-text","inherit"),go=y("font-sans","inherit"),ut=y("font-mono","monospace"),zt=y("radius","9px"),O=(e,t,r="transparent")=>`color-mix(in srgb, ${e} ${t}%, ${r})`,Kt=`box-shadow: 0 0 0 2px ${Vt};`,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
- ${ze}
33
+ ${Fe}
34
34
  .oc-sdk { box-sizing: border-box; color: ${pe}; font-family: ${go}; 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. */
@@ -38,27 +38,27 @@ ${ze}
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
40
  .oc-sdk :focus-visible { outline: none; ${Kt} }
41
- .oc-sdk-mono { font-family: ${ft}; }
41
+ .oc-sdk-mono { font-family: ${ut}; }
42
42
  .oc-sdk-muted { color: ${v}; }
43
- ${Ge("success")}${Ge("warning")}${Ge("error")}${Ge("info")}
44
- .oc-sdk[data-tone="primary"], .oc-sdk [data-tone="primary"] { --oc-sdk-tone: ${z}; --oc-sdk-tone-text: ${pt}; }
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: ${lt}; }
45
45
 
46
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: ${zt}; 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: ${pt}; background: ${O(z,10,ee)}; border-color: ${O(z,12)}; }
49
+ .oc-sdk-btn[data-variant="default"] { color: ${lt}; background: ${O(z,10,ee)}; border-color: ${O(z,12)}; }
50
50
  .oc-sdk-btn[data-variant="default"]:hover { background: ${O(z,16,ee)}; }
51
51
  .oc-sdk-btn[data-variant="default"]:active { background: ${O(z,22,ee)}; }
52
52
  .oc-sdk-btn[data-variant="secondary"] { background: ${ho}; color: var(--oc-fg); }
53
53
  .oc-sdk-btn[data-variant="secondary"]:hover { background-image: linear-gradient(${X}, ${X}); }
54
54
  .oc-sdk-btn[data-variant="secondary"]:active { background-image: linear-gradient(${te}, ${te}); }
55
- .oc-sdk-btn[data-variant="outline"] { background: ${Re}; color: ${le}; border-color: ${B}; }
55
+ .oc-sdk-btn[data-variant="outline"] { background: ${Ce}; color: ${le}; border-color: ${B}; }
56
56
  .oc-sdk-btn[data-variant="outline"]:hover { background-image: linear-gradient(${X}, ${X}); }
57
57
  .oc-sdk-btn[data-variant="outline"]:active { background-image: linear-gradient(${te}, ${te}); }
58
58
  .oc-sdk-btn[data-variant="ghost"] { background: transparent; }
59
59
  .oc-sdk-btn[data-variant="ghost"]:hover { background: ${X}; }
60
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: ${ut}; background: ${O("var(--oc-sdk-tone)",7,ee)}; border-color: ${O("var(--oc-sdk-tone)",12)}; }
61
+ .oc-sdk-btn[data-variant="destructive"] { --oc-sdk-tone: ${y("status-error","red")}; color: ${pt}; background: ${O("var(--oc-sdk-tone)",7,ee)}; border-color: ${O("var(--oc-sdk-tone)",12)}; }
62
62
  .oc-sdk-btn[data-variant="destructive"]:hover { background: ${O("var(--oc-sdk-tone)",9,ee)}; }
63
63
  .oc-sdk-btn[data-variant="destructive"]:active { background: ${O("var(--oc-sdk-tone)",11,ee)}; }
64
64
  .oc-sdk-btn[data-loading="true"] { opacity: .5; pointer-events: none; }
@@ -67,15 +67,15 @@ ${Ge("success")}${Ge("warning")}${Ge("error")}${Ge("info")}
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
69
  .oc-sdk-field-note { font-size: 0.75rem; color: ${v}; }
70
- .oc-sdk-field[data-invalid="true"] .oc-sdk-field-note { color: ${ut}; }
71
- .oc-sdk-input { display: block; width: 100%; min-width: 0; height: 36px; padding: 0 12px; border: 0; border-radius: ${zt}; background: ${Re}; color: ${le}; 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; }
70
+ .oc-sdk-field[data-invalid="true"] .oc-sdk-field-note { color: ${pt}; }
71
+ .oc-sdk-input { display: block; width: 100%; min-width: 0; height: 36px; padding: 0 12px; border: 0; border-radius: ${zt}; background: ${Ce}; color: ${le}; 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
73
  .oc-sdk-input::placeholder { color: ${v}; }
74
74
  .oc-sdk-input:hover:not(:focus) { background-image: linear-gradient(${X}, ${X}); }
75
75
  .oc-sdk-input:focus, .oc-sdk-input:focus-visible { box-shadow: inset 0 0 0 2px ${Vt}; }
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: ${ft}; }
78
+ .oc-sdk-input[data-mono="true"] { font-family: ${ut}; }
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; }
@@ -86,19 +86,19 @@ textarea.oc-sdk-input { height: auto; padding: 8px 12px; resize: vertical; }
86
86
  .oc-sdk-search-clear:hover { background: ${X}; color: ${pe}; }
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: ${Re}; color: ${le}; 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: ${le}; 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
91
  .oc-sdk-trigger[aria-expanded="true"] { background-image: linear-gradient(${te}, ${te}); }
92
92
  .oc-sdk-trigger-value { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
93
93
  .oc-sdk-trigger-value[data-empty="true"] { color: ${v}; }
94
94
  .oc-sdk-trigger-chevron { flex: 0 0 auto; color: ${v}; }
95
- .oc-sdk-popup { --surface-foreground: ${le}; 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: ${Re}; color: ${le}; box-shadow: 0 8px 24px ${O(pe,12)}; }
95
+ .oc-sdk-popup { --surface-foreground: ${le}; 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: ${le}; box-shadow: 0 8px 24px ${O(pe,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: ${dt}; color: ${lt}; }
101
- .oc-sdk-option[data-destructive="true"] { color: ${ut}; }
100
+ .oc-sdk-option[aria-selected="true"] { background: ${ct}; color: ${dt}; }
101
+ .oc-sdk-option[data-destructive="true"] { color: ${pt}; }
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
104
  .oc-sdk-option-hint { flex: 0 0 auto; font-size: 0.75rem; color: ${v}; }
@@ -124,7 +124,7 @@ textarea.oc-sdk-input { height: auto; padding: 8px 12px; resize: vertical; }
124
124
  .oc-sdk-tabs[data-track="true"] { background: ${O(pe,4)}; }
125
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
126
  .oc-sdk-tab:hover { color: ${pe}; }
127
- .oc-sdk-tab[aria-selected="true"] { color: ${lt}; background: ${dt}; border-color: ${B}; }
127
+ .oc-sdk-tab[aria-selected="true"] { color: ${dt}; background: ${ct}; border-color: ${B}; }
128
128
  .oc-sdk-tab-count { font-size: 0.75rem; font-variant-numeric: tabular-nums; color: ${v}; }
129
129
 
130
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}; }
@@ -133,8 +133,8 @@ textarea.oc-sdk-input { height: auto; padding: 8px 12px; resize: vertical; }
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: ${dt}; color: ${lt}; }
137
- .oc-sdk-row-lead { flex: 0 0 auto; width: 64px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: ${ft}; font-size: 0.75rem; color: ${v}; }
136
+ .oc-sdk-row[aria-selected="true"] { background: ${ct}; color: ${dt}; }
137
+ .oc-sdk-row-lead { flex: 0 0 auto; width: 64px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: ${ut}; 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
140
  .oc-sdk-row-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.75rem; color: ${v}; }
@@ -171,6 +171,6 @@ textarea.oc-sdk-input { height: auto; padding: 8px 12px; resize: vertical; }
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: ${pt}; text-decoration: underline; text-underline-offset: 2px; }
174
+ .oc-sdk-text a { color: ${lt}; 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 So=e=>24+e*308;function qt(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,So(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:To(e.edges,t),columnX:l,width:A,height:Math.max(s,162)}}function Yt(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 To(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+Yt(A.indexOf(s),A.length),k=h.x,I=h.y+Yt(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 ht(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 Jt(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 gt(e){if(e)return e.includes("/")?e.slice(e.indexOf("/")+1):e}function Wt(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(e>=1e4?0:1)}k`:String(e)}var _o={running:"running",queued:"queued",completed:"completed",failed:"failed",cancelled:"cancelled",idle:"idle"};function ue(e,t){if(e.kind==="root")return e.rawStatus;let r=e.rawStatus===e.state?_o[e.state]:e.rawStatus,a=e.startedAt;return a===void 0?r:e.state==="running"?`${r} \xB7 ${Jt(t-a)}`:e.endedAt!==void 0?`${r} \xB7 ${Jt(e.endedAt-a)}`:r}var De=class{drag;get active(){return this.drag!==void 0}down(t,r){t.button===0&&(this.drag={id:t.pointerId,x:t.clientX,y:t.clientY,vx:r.x,vy:r.y,moved:!1})}move(t){let r=this.drag;if(!r||t.pointerId!==r.id)return;if((t.buttons&1)===0)return"end";let a=t.clientX-r.x,l=t.clientY-r.y;if(!r.moved&&Math.hypot(a,l)<4)return;let p=!r.moved;return r.moved=!0,{x:r.vx+a,y:r.vy+l,started:p}}end(t){let r=this.drag;return!r||t!==void 0&&t!==r.id?!1:(this.drag=void 0,r.moved)}};var yo=new Set(["running","queued","completed","failed","cancelled","idle"]),me=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),q=e=>typeof e=="number"&&Number.isFinite(e),fe=e=>e===void 0||typeof e=="string",ae=e=>e===void 0||q(e),Ao=e=>typeof e=="string"&&yo.has(e);function wo(e){return me(e)?typeof e.id=="string"&&(e.kind==="root"||e.kind==="task")&&typeof e.sessionId=="string"&&typeof e.title=="string"&&Ao(e.state)&&typeof e.rawStatus=="string"&&fe(e.agent)&&fe(e.model)&&ae(e.createdAt)&&ae(e.startedAt)&&ae(e.endedAt)&&fe(e.summary)&&fe(e.error)&&ae(e.tokens)&&ae(e.costUsd)&&ae(e.toolCalls)&&fe(e.parentId)&&q(e.column)&&q(e.wave):!1}function vo(e){return me(e)&&typeof e.id=="string"&&typeof e.from=="string"&&typeof e.to=="string"&&(e.kind==="spawn"||e.kind==="uses")}function Mo(e){return me(e)&&q(e.column)&&q(e.total)&&q(e.done)&&q(e.running)}function Oo(e){return me(e)&&q(e.omittedNodes)&&Number.isInteger(e.omittedNodes)&&e.omittedNodes>=0}function Lo(e){return me(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(wo)&&Array.isArray(e.edges)&&e.edges.every(vo)&&Array.isArray(e.columns)&&e.columns.every(Mo)&&q(e.models)&&(e.truncated===void 0||Oo(e.truncated))}function Co(e){let t=JSON.parse(e);if(!Lo(t))throw new Error("service answered with an unexpected graph shape");return t}var He=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=Co(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 Qt="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 V=at(),C=e=>document.querySelector(e),d={app:C("#app"),title:C("#title"),titleDot:C("#title-dot"),meta:C("#meta"),viewport:C("#viewport"),world:C("#world"),edges:C("#edges"),bands:C("#bands"),nodes:C("#nodes"),empty:C("#empty"),inspector:C("#inspector"),settings:C("#settings")},ge=null,no=!1,M,R,Zt="",K,oe={},Et,_={x:0,y:0,k:1},ce=new Map;function L(e,t="",r=""){let a=document.createElement(e);return t&&(a.className=t),r&&(a.textContent=r),a}function xt(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 ro(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 de(){d.world.style.transform=`translate(${_.x}px, ${_.y}px) scale(${_.k})`,d.app.style.setProperty("--zoom",String(_.k))}function Pe(){if(!R)return;let e=d.viewport.clientWidth,t=d.viewport.clientHeight,r=Math.min(1,Math.max(.62,Math.min((e-16)/R.width,(t-16)/R.height)));_.k=r,_.x=Math.round(R.width*r<=e?(e-R.width*r)/2:8),_.y=Math.round(Math.max(8,(t-R.height*r)/2)),de()}function so(e){let t=e?R?.boxes.get(e):void 0;if(!t)return Pe();_.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),de()}function xe(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,de()}var Ee=new De,kt=!1;function ke(e,t=!1){if(!Ee.active)return;let r=Ee.end(e);Ee.active||(r&&t&&(kt=!0,setTimeout(()=>{kt=!1},0)),d.app.classList.remove("is-panning"))}d.viewport.addEventListener("pointerdown",e=>Ee.down(e,_));window.addEventListener("pointermove",e=>{let t=Ee.move(e);if(t==="end")return ke(e.pointerId);t&&(t.started&&(d.viewport.setPointerCapture?.(e.pointerId),d.app.classList.add("is-panning")),_.x=t.x,_.y=t.y,de())});window.addEventListener("pointerup",e=>ke(e.pointerId,!0));window.addEventListener("pointercancel",e=>ke(e.pointerId));d.viewport.addEventListener("lostpointercapture",e=>ke(e.pointerId));window.addEventListener("blur",()=>ke());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?xe(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,de())},{passive:!1});C("#btn-fit").addEventListener("click",Pe);C("#btn-locate").addEventListener("click",()=>{let e=M?.nodes.find(t=>t.kind==="task"&&t.state==="running");so(M?.focusId!==M?.rootId?M?.focusId:e?.id??M?.rootId)});C("#btn-in").addEventListener("click",()=>xe(1.2));C("#btn-out").addEventListener("click",()=>xe(1/1.2));window.addEventListener("keydown",e=>{e.target instanceof HTMLInputElement||(e.key==="0"?Pe():e.key==="+"||e.key==="="?xe(1.2):e.key==="-"&&xe(1/1.2))});function he(e){if(K=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?ht(t,e,"up"):new Set,p=e?ht(t,e,"down"):new Set;d.app.classList.toggle("has-hover",e!==void 0);for(let[s,c]of ce)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)))}Ro()}function Ro(){let e=M?.nodes.find(A=>A.id===(K??(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=[ue(e,Date.now())];e.agent&&a.push(e.agent);let l=gt(e.model);l&&a.push(l),e.toolCalls!==void 0&&a.push(`${e.toolCalls} tools`),e.tokens!==void 0&&a.push(`${Wt(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 Go(e){let t=ce.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",()=>he(e.id)),t.addEventListener("pointerleave",()=>{K===e.id&&he(void 0)}),t.addEventListener("focus",()=>he(e.id)),t.addEventListener("blur",()=>{K===e.id&&he(void 0)}),t.addEventListener("click",()=>{kt||Uo(e.id)}),ce.set(e.id,t),d.nodes.append(t)),t}function Io(e,t,r){e.className=`node k-${t.kind} s-${t.state}${M?.focusId===t.id&&t.kind==="task"?" is-current":""}`,K===t.id&&e.classList.add("is-hover"),e.setAttribute("aria-label",`${t.title}, ${ue(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",ue(t,r)),a(".n-meta",t.kind==="root"?`${M?.nodes.length?M.nodes.length-1:0} sub-agents`:[t.agent,gt(t.model)].filter(Boolean).join(" \xB7 ")),a(".n-sub",t.error??t.summary??""),e.querySelector(".dot")?.setAttribute("class",`dot s-${t.state}`)}function $o(e){M=e,R=qt(e),d.world.hidden=!1,d.empty.hidden=!0,d.world.style.width=`${R.width}px`,d.world.style.height=`${R.height}px`,d.edges.setAttribute("width",String(R.width)),d.edges.setAttribute("height",String(R.height)),d.edges.setAttribute("viewBox",`0 0 ${R.width} ${R.height}`);let t=new Map(e.nodes.map(i=>[i.id,i.state])),r=document.createDocumentFragment();for(let i of R.edges){let g=document.createElementNS(Qt,"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(Qt,"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(...[...R.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=Go(i),f=R.boxes.get(i.id);f&&(g.style.transform=`translate(${f.x}px, ${f.y}px)`),Io(g,i,a),l.add(i.id)}for(let[i,g]of ce)l.has(i)||(g.remove(),ce.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 "),V.setBadge(c>0?c:null).catch(()=>{}),Zt!==e.rootId&&(Zt=e.rootId,requestAnimationFrame(()=>e.focusId!==e.rootId?so(e.focusId):Pe())),K&&!e.nodes.some(i=>i.id===K)&&(K=void 0),he(K)}function No(){if(!M)return;let e=Date.now();for(let t of M.nodes){if(t.state!=="running")continue;let a=ce.get(t.id)?.querySelector(".n-status");a&&(a.textContent=ue(t,e))}}setInterval(No,1e3);async function Uo(e){let t=M?.nodes.find(r=>r.id===e);if(t)try{await V.openSession(t.sessionId)}catch(r){let[a,l]=ro(r);await V.toast({kind:"error",message:`${a}: ${l}`}).catch(()=>{})}}var be=new He({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"){$o(e.graph);return}M=void 0,V.setBadge(null).catch(()=>{}),e.kind==="no-session"?xt("No session open","Open a chat to see the OmO agents working behind it."):e.kind==="empty"?xt("No sub-agents yet","When this session launches OmO tasks or workflows, they appear here as a live graph."):xt(...ro(e.error))},schedule:(e,t)=>{Et&&clearTimeout(Et),Et=setTimeout(t,e)},isHidden:()=>document.hidden}),eo=C("#btn-settings");eo.addEventListener("click",()=>{d.settings.hidden=!d.settings.hidden,eo.setAttribute("aria-expanded",String(!d.settings.hidden)),d.settings.hidden||d.settings.querySelector("input")?.focus()});C("#btn-save").addEventListener("click",()=>{let e=new FormData(d.settings),t={},r=String(e.get("agentDir")??"").trim(),a=String(e.get("stateDir")??"").trim();r&&(t.agentDir=r),a&&(t.stateDir=a),oe=t,d.settings.hidden=!0,V.storage.set("paths",t).catch(()=>{}),be.invalidate()});function Do(){for(let e of["agentDir","stateDir"]){let t=d.settings.querySelector(`input[name="${e}"]`);t&&(t.value=oe[e]??"")}}var to=!1;V.onReady(e=>{ct(e,document.documentElement),d.app.dataset.surface=e.surface,!to&&(to=!0,ge=e.session?.id??ge,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}:{}}}Do()}).catch(()=>{}).finally(()=>{no=!0,be.setSession(ge)}))});V.onSession(e=>{let t=e?.id??null;t!==ge&&(K=void 0),ge=t,no&&be.setSession(t)});V.onSessionLifecycle(()=>{be.refresh()});document.addEventListener("visibilitychange",()=>{document.hidden||be.refresh()});window.addEventListener("resize",()=>{R&&_.k<=1&&de()});})();
176
+ `;var So=e=>24+e*308;function qt(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,So(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:To(e.edges,t),columnX:l,width:A,height:Math.max(s,162)}}function Yt(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 To(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+Yt(A.indexOf(s),A.length),k=h.x,I=h.y+Yt(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 mt(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 Jt(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 ht(e){if(e)return e.includes("/")?e.slice(e.indexOf("/")+1):e}function Wt(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(e>=1e4?0:1)}k`:String(e)}var _o={running:"running",queued:"queued",completed:"completed",failed:"failed",cancelled:"cancelled",idle:"idle"};function ue(e,t){if(e.kind==="root")return e.rawStatus;let r=e.rawStatus===e.state?_o[e.state]:e.rawStatus,a=e.startedAt;return a===void 0?r:e.state==="running"?`${r} \xB7 ${Jt(t-a)}`:e.endedAt!==void 0?`${r} \xB7 ${Jt(e.endedAt-a)}`:r}var Ue=class{drag;get active(){return this.drag!==void 0}down(t,r){t.button===0&&(this.drag={id:t.pointerId,x:t.clientX,y:t.clientY,vx:r.x,vy:r.y,moved:!1})}move(t){let r=this.drag;if(!r||t.pointerId!==r.id)return;if((t.buttons&1)===0)return"end";let a=t.clientX-r.x,l=t.clientY-r.y;if(!r.moved&&Math.hypot(a,l)<4)return;let p=!r.moved;return r.moved=!0,{x:r.vx+a,y:r.vy+l,started:p}}end(t){let r=this.drag;return!r||t!==void 0&&t!==r.id?!1:(this.drag=void 0,r.moved)}};var yo=new Set(["running","queued","completed","failed","cancelled","idle"]),me=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),q=e=>typeof e=="number"&&Number.isFinite(e),fe=e=>e===void 0||typeof e=="string",ae=e=>e===void 0||q(e),Ao=e=>typeof e=="string"&&yo.has(e);function wo(e){return me(e)?typeof e.id=="string"&&(e.kind==="root"||e.kind==="task")&&typeof e.sessionId=="string"&&typeof e.title=="string"&&Ao(e.state)&&typeof e.rawStatus=="string"&&fe(e.agent)&&fe(e.model)&&ae(e.createdAt)&&ae(e.startedAt)&&ae(e.endedAt)&&fe(e.summary)&&fe(e.error)&&ae(e.tokens)&&ae(e.costUsd)&&ae(e.toolCalls)&&fe(e.parentId)&&q(e.column)&&q(e.wave):!1}function vo(e){return me(e)&&typeof e.id=="string"&&typeof e.from=="string"&&typeof e.to=="string"&&(e.kind==="spawn"||e.kind==="uses")}function Mo(e){return me(e)&&q(e.column)&&q(e.total)&&q(e.done)&&q(e.running)}function Oo(e){return me(e)&&q(e.omittedNodes)&&Number.isInteger(e.omittedNodes)&&e.omittedNodes>=0}function Lo(e){return me(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(wo)&&Array.isArray(e.edges)&&e.edges.every(vo)&&Array.isArray(e.columns)&&e.columns.every(Mo)&&q(e.models)&&(e.truncated===void 0||Oo(e.truncated))}function Co(e){let t=JSON.parse(e);if(!Lo(t))throw new Error("service answered with an unexpected graph shape");return t}var De=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=Co(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 Qt="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 V=it(),C=e=>document.querySelector(e),d={app:C("#app"),title:C("#title"),titleDot:C("#title-dot"),meta:C("#meta"),viewport:C("#viewport"),world:C("#world"),edges:C("#edges"),bands:C("#bands"),nodes:C("#nodes"),empty:C("#empty"),inspector:C("#inspector"),settings:C("#settings")},ge=null,no=!1,M,R,Zt="",K,oe={},gt,_={x:0,y:0,k:1},ce=new Map;function L(e,t="",r=""){let a=document.createElement(e);return t&&(a.className=t),r&&(a.textContent=r),a}function Et(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 ro(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 de(){d.world.style.transform=`translate(${_.x}px, ${_.y}px) scale(${_.k})`,d.app.style.setProperty("--zoom",String(_.k))}function He(){if(!R)return;let e=d.viewport.clientWidth,t=d.viewport.clientHeight,r=Math.min(1,Math.max(.62,Math.min((e-16)/R.width,(t-16)/R.height)));_.k=r,_.x=Math.round(R.width*r<=e?(e-R.width*r)/2:8),_.y=Math.round(Math.max(8,(t-R.height*r)/2)),de()}function so(e){let t=e?R?.boxes.get(e):void 0;if(!t)return He();_.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),de()}function xe(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,de()}var Ee=new Ue,xt=!1;function bt(e,t=!1){if(!Ee.active)return;let r=Ee.end(e);Ee.active||(r&&t&&(xt=!0,setTimeout(()=>{xt=!1},0)),d.app.classList.remove("is-panning"))}d.viewport.addEventListener("pointerdown",e=>Ee.down(e,_));window.addEventListener("pointermove",e=>{let t=Ee.move(e);if(t==="end")return bt(e.pointerId);t&&(t.started&&(d.viewport.setPointerCapture?.(e.pointerId),d.app.classList.add("is-panning")),_.x=t.x,_.y=t.y,de())});window.addEventListener("pointerup",e=>bt(e.pointerId,!0));window.addEventListener("pointercancel",e=>bt(e.pointerId));d.viewport.addEventListener("dragstart",e=>e.preventDefault());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?xe(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,de())},{passive:!1});C("#btn-fit").addEventListener("click",He);C("#btn-locate").addEventListener("click",()=>{let e=M?.nodes.find(t=>t.kind==="task"&&t.state==="running");so(M?.focusId!==M?.rootId?M?.focusId:e?.id??M?.rootId)});C("#btn-in").addEventListener("click",()=>xe(1.2));C("#btn-out").addEventListener("click",()=>xe(1/1.2));window.addEventListener("keydown",e=>{e.target instanceof HTMLInputElement||(e.key==="0"?He():e.key==="+"||e.key==="="?xe(1.2):e.key==="-"&&xe(1/1.2))});function he(e){if(K=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?mt(t,e,"up"):new Set,p=e?mt(t,e,"down"):new Set;d.app.classList.toggle("has-hover",e!==void 0);for(let[s,c]of ce)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)))}Ro()}function Ro(){let e=M?.nodes.find(A=>A.id===(K??(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=[ue(e,Date.now())];e.agent&&a.push(e.agent);let l=ht(e.model);l&&a.push(l),e.toolCalls!==void 0&&a.push(`${e.toolCalls} tools`),e.tokens!==void 0&&a.push(`${Wt(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 Go(e){let t=ce.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",()=>he(e.id)),t.addEventListener("pointerleave",()=>{K===e.id&&he(void 0)}),t.addEventListener("focus",()=>he(e.id)),t.addEventListener("blur",()=>{K===e.id&&he(void 0)}),t.addEventListener("click",()=>{xt||Uo(e.id)}),ce.set(e.id,t),d.nodes.append(t)),t}function Io(e,t,r){e.className=`node k-${t.kind} s-${t.state}${M?.focusId===t.id&&t.kind==="task"?" is-current":""}`,K===t.id&&e.classList.add("is-hover"),e.setAttribute("aria-label",`${t.title}, ${ue(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",ue(t,r)),a(".n-meta",t.kind==="root"?`${M?.nodes.length?M.nodes.length-1:0} sub-agents`:[t.agent,ht(t.model)].filter(Boolean).join(" \xB7 ")),a(".n-sub",t.error??t.summary??""),e.querySelector(".dot")?.setAttribute("class",`dot s-${t.state}`)}function $o(e){M=e,R=qt(e),d.world.hidden=!1,d.empty.hidden=!0,d.world.style.width=`${R.width}px`,d.world.style.height=`${R.height}px`,d.edges.setAttribute("width",String(R.width)),d.edges.setAttribute("height",String(R.height)),d.edges.setAttribute("viewBox",`0 0 ${R.width} ${R.height}`);let t=new Map(e.nodes.map(i=>[i.id,i.state])),r=document.createDocumentFragment();for(let i of R.edges){let g=document.createElementNS(Qt,"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(Qt,"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(...[...R.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=Go(i),f=R.boxes.get(i.id);f&&(g.style.transform=`translate(${f.x}px, ${f.y}px)`),Io(g,i,a),l.add(i.id)}for(let[i,g]of ce)l.has(i)||(g.remove(),ce.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 "),V.setBadge(c>0?c:null).catch(()=>{}),Zt!==e.rootId&&(Zt=e.rootId,requestAnimationFrame(()=>e.focusId!==e.rootId?so(e.focusId):He())),K&&!e.nodes.some(i=>i.id===K)&&(K=void 0),he(K)}function No(){if(!M)return;let e=Date.now();for(let t of M.nodes){if(t.state!=="running")continue;let a=ce.get(t.id)?.querySelector(".n-status");a&&(a.textContent=ue(t,e))}}setInterval(No,1e3);async function Uo(e){let t=M?.nodes.find(r=>r.id===e);if(t)try{await V.openSession(t.sessionId)}catch(r){let[a,l]=ro(r);await V.toast({kind:"error",message:`${a}: ${l}`}).catch(()=>{})}}var ke=new De({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"){$o(e.graph);return}M=void 0,V.setBadge(null).catch(()=>{}),e.kind==="no-session"?Et("No session open","Open a chat to see the OmO agents working behind it."):e.kind==="empty"?Et("No sub-agents yet","When this session launches OmO tasks or workflows, they appear here as a live graph."):Et(...ro(e.error))},schedule:(e,t)=>{gt&&clearTimeout(gt),gt=setTimeout(t,e)},isHidden:()=>document.hidden}),eo=C("#btn-settings");eo.addEventListener("click",()=>{d.settings.hidden=!d.settings.hidden,eo.setAttribute("aria-expanded",String(!d.settings.hidden)),d.settings.hidden||d.settings.querySelector("input")?.focus()});C("#btn-save").addEventListener("click",()=>{let e=new FormData(d.settings),t={},r=String(e.get("agentDir")??"").trim(),a=String(e.get("stateDir")??"").trim();r&&(t.agentDir=r),a&&(t.stateDir=a),oe=t,d.settings.hidden=!0,V.storage.set("paths",t).catch(()=>{}),ke.invalidate()});function Do(){for(let e of["agentDir","stateDir"]){let t=d.settings.querySelector(`input[name="${e}"]`);t&&(t.value=oe[e]??"")}}var to=!1;V.onReady(e=>{at(e,document.documentElement),d.app.dataset.surface=e.surface,!to&&(to=!0,ge=e.session?.id??ge,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}:{}}}Do()}).catch(()=>{}).finally(()=>{no=!0,ke.setSession(ge)}))});V.onSession(e=>{let t=e?.id??null;t!==ge&&(K=void 0),ge=t,no&&ke.setSession(t)});V.onSessionLifecycle(()=>{ke.refresh()});document.addEventListener("visibilitychange",()=>{document.hidden||ke.refresh()});window.addEventListener("resize",()=>{R&&_.k<=1&&de()});})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antechamber",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
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",