dsh-thoughtdag 0.5.18 → 0.5.19

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 (21) hide show
  1. package/README.md +13 -12
  2. package/dist-app/assets/{canonical-agWec4XS.js → canonical-bSxBmsm7.js} +2 -2
  3. package/dist-app/assets/{canvas-record-C2yZbu5N.js → canvas-record-qO1KINUh.js} +1 -1
  4. package/dist-app/assets/{claude-code-session-CbBcaUqO.js → claude-code-session-DkNDRQp8.js} +1 -1
  5. package/dist-app/assets/{codex-session-wxU_-LWp.js → codex-session-B2hAZ_ax.js} +1 -1
  6. package/dist-app/assets/{dsh-session-DmOP3XKa.js → dsh-session-AQk-ryCb.js} +1 -1
  7. package/dist-app/assets/{experiment-loop-XP_t_khd.js → experiment-loop-BzzzDlbH.js} +1 -1
  8. package/dist-app/assets/{http-bridge-Cyr8eePQ.js → http-bridge-BnYAV4lB.js} +1 -1
  9. package/dist-app/assets/{index-DWanOFbr.js → index-BH9ozg79.js} +14 -14
  10. package/dist-app/assets/{index-ShRKYhWs.js → index-BmwffA_p.js} +1 -1
  11. package/dist-app/assets/{index-DFZu6h8O.js → index-YWyx765g.js} +3 -3
  12. package/dist-app/assets/{index-1Y_JzMpx.js → index-aOSCk5D-.js} +1 -1
  13. package/dist-app/assets/{pi-session-DXj3K4Qb.js → pi-session-CNcLBGJ1.js} +1 -1
  14. package/dist-app/assets/{sensitive-scan-B3jSpKVr.js → sensitive-scan-Cs2TuwIB.js} +1 -1
  15. package/dist-app/assets/{session-handoff-y5-kuOb1.js → session-handoff-CLQ0ZIYD.js} +2 -2
  16. package/dist-app/assets/{shared-DxaHN0fp.js → shared-LHIg0YHa.js} +1 -1
  17. package/dist-app/assets/{turndown-plugin-gfm.cjs-wNy9Tytn.js → turndown-plugin-gfm.cjs-j992pbuV.js} +1 -1
  18. package/dist-app/assets/{update-check-DyyT5hjM.js → update-check-3zMP9HL5.js} +1 -1
  19. package/dist-app/index.html +1 -1
  20. package/lib/client.js +161 -67
  21. package/package.json +1 -1
package/README.md CHANGED
@@ -13,20 +13,21 @@ plugin (a Cordis plugin distributed as an npm package), built on the same shell
13
13
  pattern as [dsh-synapse](https://github.com/liangmianya/dsh-synapse): the host
14
14
  half mounts the ThoughtDAG SPA under `/thoughtdag/` on the EXISTING harness
15
15
  web server (no second process, no second port), and the client half adds a
16
- floating "对话 | 思维图" switch at the top of the harness page that shows the
17
- canvas in a same-origin full-screen iframe.
16
+ **ThoughtDAG** entry to the harness sidebar (beside Plugins) that shows the
17
+ canvas in the main column, in a same-origin iframe.
18
18
 
19
- > The switch floats over the chat, so it is there before any session is
20
- > open; while the canvas is up, the same switch sits in the canvas's own top
21
- > bar next to the canvas chip, so it never covers the canvas toolbar. (开关浮
22
- > 在对话页顶部,空态也能切换;思维图打开时,同一个开关在画布顶栏「画布名」右侧,
23
- > 不再压住画布工具栏。0.4.18 曾把它放进会话标题栏,0.4.19 撤回。)
19
+ > The entry is the host's own panel mechanism (`sidebar.panellist` plus the
20
+ > root `main` panel slot), so it is there before any session is open and
21
+ > follows the host's language and theme. The iframe stays in the plugin's own
22
+ > layer, laid over the panel while it is selected, so switching never reloads
23
+ > the canvas. (0.4.19 to 0.5.18 floated a 对话 | 思维图 switch over the top
24
+ > strip instead; every placement collided with host chrome somewhere, see
25
+ > #55, #61, #63, #73. Hosts without the panel slot still get that switch.)
24
26
 
25
27
  ## What works
26
28
 
27
29
  - `dsh plugin --profile web add dsh-thoughtdag` installs the plugin from npm; every GitHub release also carries `dsh-thoughtdag-<version>.tgz`, and the same command takes that file's URL (`dsh plugin` forwards to pnpm)
28
- - The harness GUI gains a floating "对话 | 思维图" switch at the top of the page;
29
- "思维图" opens ThoughtDAG at
30
+ - The harness sidebar gains a **ThoughtDAG** entry; selecting it opens ThoughtDAG at
30
31
  `/thoughtdag/` (same origin — no CORS, no second server)
31
32
  - The host serves the SPA plus a read-only session bridge:
32
33
 
@@ -57,8 +58,8 @@ canvas in a same-origin full-screen iframe.
57
58
  - installed into the local `web` profile via `dsh plugin --profile web add <dir>`
58
59
  - a fresh web-profile boot serves `/thoughtdag/` (SPA) and the bridge API; the
59
60
  index injection table lists `dsh-thoughtdag/client.js`
60
- - headless-browser walk: the "对话 | 思维图" switch floats at the top of the page, the full-screen
61
- same-origin iframe opens, and ThoughtDAG boots inside it
61
+ - headless-browser walk: the ThoughtDAG entry appears in the sidebar, selecting it lays the
62
+ same-origin iframe over the main column, and ThoughtDAG boots inside it
62
63
  - fetching the bridge from INSIDE the thoughtdag origin works with no extra
63
64
  auth: `GET /thoughtdag/api/disksessions` lists every on-disk session (new
64
65
  sessions created by the running instance appear automatically) and
@@ -106,7 +107,7 @@ Both are on by default; `whyTools: false` / `whyPrompt: false` in the plugin con
106
107
  - Canvas why panel (a node's file → its history through `/thoughtdag/api`)
107
108
  - Canvas UI for the write bridge: name a fork point on a node, hand a compiled context to `inject`, continue with `followup`; the client already switches the chat to a session the canvas names (`td:select-session`)
108
109
  - `replace`: shadow a surface range from the canvas (DSH's compaction primitive); needs a live check of how the chat renders a replaced range
109
- - Theme and language sync with the harness UI
110
+ - Theme sync of the canvas itself with the harness UI (the sidebar entry already follows the host's language and theme)
110
111
  - Open the chat's current session on the canvas automatically when the view switches
111
112
 
112
113
  ## Development
@@ -1,2 +1,2 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-DFZu6h8O.js","assets/index-DWanOFbr.js","assets/index-YkjjqQPO.css","assets/experiment-loop-XP_t_khd.js"])))=>i.map(i=>d[i]);
2
- import{c as _,b as y,_ as k,p as D,r as O,g as R,a as K,u as C,h as Q,s as z,j as $,k as W,f as V,l as Y,m as Z,t as tt,n as M,o as et,q as st}from"./index-DWanOFbr.js";const ot=190;async function ct(n){const{anyRunnerSessionConversation:d}=await k(async()=>{const{anyRunnerSessionConversation:r}=await import("./index-DFZu6h8O.js");return{anyRunnerSessionConversation:r}},__vite__mapDeps([0,1,2])),t=await d(n);return J(t)}function ut(n,d){let r=0,s=!1;return async()=>{if(s)return null;const a=await window.desktopSessions.readRange(n,d,r,8388608);return r=a.nextStart,a.eof&&(s=!0),a.text}}function L(n){if(!n)return null;for(const d of _.getState().projects){const t=d.sourceSession;if(!t)continue;if(t.sessionId===n)return{project:d,entry:t};const r=t.chapters?.find(a=>a.sessionId===n);if(r)return{project:d,entry:r};const s=t.branches?.find(a=>a.sessionId===n);if(s)return{project:d,entry:s}}return null}function H(n,d,t,r,s){const a=r.position.x+(s?560:0),f=a-40,c=a+580,e=n.nodes.reduce((g,w)=>{const b=w.width??w.measured?.width??540;if(w.position.x+b<f||w.position.x>c)return g;const x=w.height??w.measured?.height??300;return Math.max(g,w.position.y+x)},s?r.position.y-300:r.position.y+(r.height??140)),i=a-d[0].position.x,m=Math.max(e+ot,s?r.position.y:-1/0)-d[0].position.y,u=d.map(g=>({...g,position:{x:g.position.x+i,y:g.position.y+m}})),l=[{id:M(),source:r.id,target:u[0].id,type:"smoothstep"},...t];return{moved:u,edges:l}}async function J(n,d={}){if(!n)return null;const t=n.build(),r=t.nodes.filter(c=>c.data.importSource),s=r.at(-1)?.id??t.nodes.at(-1)?.id??"";if(t.nodes.length===0)return null;const a=L(n.sessionId);if(a)return U(n,t,r,s,a,d);if(n.sessionId){const c=await nt(n.sessionId);if(c){let e=-1,i="";if(r.forEach((m,u)=>{const l=m.data.importSource?.itemIds?.[0],g=l?c.byFirstId.get(l):void 0;g&&(e=u,i=g)}),e>=0){await O(c.projectId,"chapter",{sessionId:n.sessionId,runner:n.source,importedCount:e+1,tailNodeId:i});const m=L(n.sessionId);if(m)return U(n,t,r,s,m,d)}}}if(n.sessionId&&r.length>0){const{parseAnchor:c}=await k(async()=>{const{parseAnchor:i}=await import("./experiment-loop-XP_t_khd.js");return{parseAnchor:i}},__vite__mapDeps([3,1,2])),e=c(r[0].data.question??"");if(e&&_.getState().projects.some(i=>i.id===e.project)){await R(e.project);const i=y.getState(),m=_.getState().projects.find(l=>l.id===e.project);let u=i.nodes.find(l=>l.id===e.node)??null;if(!u&&e.mode==="continue"&&m.sourceSession?.sessionId){const l=m.sourceSession;u=i.nodes.find(g=>g.id===l.tailNodeId)??i.nodes.filter(g=>g.data.importSource?.sessionId===l.sessionId).at(-1)??null}if(u){const l=t.nodes.find(h=>h.data.importSource&&h.data.stepKind!=="note");if(l&&c(l.data.question??"")){const h=K("exp.openerMark");l.data={...l.data,question:h,source:l.data.source?{...l.data.source,question:h}:l.data.source}}const g=new Set(t.nodes.map(h=>h.id)),w=t.edges.filter(h=>g.has(h.source)&&g.has(h.target)),b=e.mode!=="continue",x=H(i,t.nodes,w,u,b);if(b){const h=x.moved.find(N=>N.data.importSource&&N.data.stepKind!=="note");h&&(h.data={...h.data,isBranch:!0})}return i.pushHistory(),y.setState(h=>({nodes:[...h.nodes,...x.moved],edges:[...h.edges,...x.edges]})),await O(e.project,b?"branch":"chapter",{sessionId:n.sessionId,runner:n.source,importedCount:r.length,tailNodeId:s,anchorNodeId:u.id}),C.getState().setArrivalFocusNodeId(x.moved[x.moved.length-1].id),{kind:"mounted",mode:b?"branch":"continue",turns:r.length}}}}const f=crypto.randomUUID();return await Q(D(f),JSON.stringify({state:{nodes:z(t.nodes),edges:t.edges},version:1})),C.getState().setArrivalFocusNodeId(t.nodes[t.nodes.length-1].id),await $(f,n.title.slice(0,60),"chat",n.sessionId?{sourceSession:{sessionId:n.sessionId,runner:n.source,importedCount:r.length,tailNodeId:s}}:void 0),{kind:"imported",nodeCount:t.nodes.length}}async function pt(n,d){if(!n||!n.sessionId)return null;if(L(n.sessionId))return J(n);const t=n.build(),r=t.nodes.filter(u=>u.data.importSource);if(t.nodes.length===0)return null;await R(d);const s=y.getState(),a=_.getState().projects.find(u=>u.id===d);if(!a)return null;const f=a.sourceSession,c=(f?.sessionId?s.nodes.find(u=>u.id===f.tailNodeId)??s.nodes.filter(u=>u.data.importSource?.sessionId===f.sessionId).at(-1):null)??s.nodes.at(-1)??null;if(!c)return null;const e=new Set(t.nodes.map(u=>u.id)),i=t.edges.filter(u=>e.has(u.source)&&e.has(u.target)),m=H(s,t.nodes,i,c,!1);return s.pushHistory(),y.setState(u=>({nodes:[...u.nodes,...m.moved],edges:[...u.edges,...m.edges]})),await O(d,"chapter",{sessionId:n.sessionId,runner:n.source,importedCount:r.length,tailNodeId:r.at(-1)?.id??t.nodes.at(-1).id,anchorNodeId:c.id}),C.getState().setArrivalFocusNodeId(m.moved[m.moved.length-1].id),{kind:"mounted",mode:"continue",turns:r.length}}async function nt(n){const{projects:d,activeId:t}=_.getState(),r=[...d].sort((s,a)=>s.id===t?-1:a.id===t?1:a.updatedAt-s.updatedAt);for(const s of r){if(s.id!==t&&s.provenanceSessions&&!s.provenanceSessions.includes(n))continue;let a;if(s.id===t)a=y.getState().nodes;else try{const{get:c}=await k(async()=>{const{get:m}=await import("./index-DWanOFbr.js").then(u=>u.D);return{get:m}},__vite__mapDeps([1,2])),e=await c(D(s.id));a=(typeof e=="string"?JSON.parse(e):e)?.state?.nodes??[]}catch{continue}if(s.id!==t&&!s.provenanceSessions){const c=[...new Set(a.map(e=>e.data.importSource?.sessionId).filter(e=>!!e))];_.setState(e=>({projects:e.projects.map(i=>i.id===s.id?{...i,provenanceSessions:c}:i)}))}const f=new Map;for(const c of a)if(c.data.importSource?.sessionId===n&&c.data.stepKind!=="note"){const e=c.data.importSource.itemIds?.[0];e&&f.set(e,c.id)}if(f.size>0)return{projectId:s.id,byFirstId:f}}return null}async function U(n,d,t,r,s,a={}){await R(s.project.id);const f=y.getState(),c=f.nodes.filter(o=>o.data.importSource?.sessionId===n.sessionId),e=f.nodes.find(o=>o.id===s.entry.tailNodeId)??c.at(-1)??null,i=s.entry.importedCount>0&&t.length>=s.entry.importedCount?t[s.entry.importedCount-1]:null;if(i){const o=i.data.importSource?.itemIds?.[0],p=o?c.find(E=>E.data.importSource?.itemIds?.[0]===o):void 0,S=p?.data.source,A=!!S&&p.data.question===S.question&&(p.data.response??"")===(S.response??""),I=i.data,X=!!p&&(I.response??"").trim()===""&&(p.data.response??"").trim()!=="",G=!!p&&!X&&(I.question!==p.data.question||(I.response??"")!==(p.data.response??"")),P=p?.data.attachments??[],T=I.attachments??[],B=!!p&&T.length>P.length&&P.every((E,q)=>T[q]?.name===E.name);if(p&&A&&(G||B)){const E=G?I.attachments:[...P,...T.slice(P.length)];y.setState(q=>({nodes:q.nodes.map(F=>F.id===p.id?{...F,data:{...F.data,question:I.question,response:I.response,responses:I.responses,responseIndex:I.responseIndex,tokenCount:I.tokenCount,attachments:E,importSource:I.importSource,source:I.source}}:F)})),y.getState().recomputeStaleness()}}if(t.length<=s.entry.importedCount)return a.focusOnRefresh!==!1&&C.getState().setArrivalFocusNodeId(e?.id??null),{kind:"opened"};const m=t[s.entry.importedCount],u=d.nodes.findIndex(o=>o.id===m.id),l=d.nodes.slice(u),g=new Set(l.map(o=>o.id)),w=d.edges.filter(o=>g.has(o.source)&&g.has(o.target)),b=new Map;for(const o of c){const p=o.data.importSource?.itemIds?.[0];p&&b.set(p,o.id)}const x=new Map;for(const o of d.nodes){const p=o.data.importSource?.itemIds?.[0];p&&!g.has(o.id)&&x.set(o.id,p)}const h=[];for(const o of d.edges){if(!g.has(o.target)||g.has(o.source))continue;const p=x.get(o.source),S=p?b.get(p):void 0;S&&h.push({...o,id:M(),source:S})}const N=new Set(h.map(o=>o.target));let v,j;if(e){const o=H(f,l,w,e,!1);v=o.moved;const p=new Set(w.map(S=>S.target));j=o.edges.filter(S=>!(S.source===e.id&&N.has(S.target)));for(const S of v)S.id!==v[0].id&&!p.has(S.id)&&!N.has(S.id)&&S.data.stepKind!=="note"&&j.push({id:M(),source:e.id,target:S.id,type:"smoothstep"});j=[...j,...h]}else{const p=(f.nodes.length?Math.max(...f.nodes.map(I=>I.position.x)):0)+560-l[0].position.x,S=-l[0].position.y;v=l.map(I=>({...I,position:{x:I.position.x+p,y:I.position.y+S}}));const A=rt(it(t.length-s.entry.importedCount),v[0]);v=[A,...v],j=[{id:M(),source:A.id,target:v[1].id,type:"smoothstep"},...w]}return f.pushHistory(),y.setState(o=>({nodes:[...o.nodes,...v],edges:[...o.edges,...j]})),await et(s.project.id,n.sessionId,{importedCount:t.length,tailNodeId:r}),C.getState().setArrivalFocusNodeId(v[e?0:1].id),{kind:"appended",turns:t.length-s.entry.importedCount}}function it(n){return`[Mirror] The source session grew by ${n} turn(s); the earlier mirrored turns were removed from this canvas by hand, so the new turns land here on their own.`}function rt(n,d){const t=st(n,"",!1);return t.data.stepKind="note",t.data.importSource=d.data.importSource?{...d.data.importSource,itemIds:[]}:void 0,t.width=460,t.position={x:d.position.x-520,y:d.position.y},t}async function ft(n){const{projects:d,activeId:t}=_.getState(),r=d.find(e=>e.id===n);if(!r?.sourceSession)return"native";if((r.sourceSession.chapters?.length??0)>0||(r.sourceSession.branches?.length??0)>0)return"diverged-mirror";let s;if(n===t)s=y.getState().nodes;else{const{get:e}=await k(async()=>{const{get:m}=await import("./index-DWanOFbr.js").then(u=>u.D);return{get:m}},__vite__mapDeps([1,2])),i=await e(D(n));try{s=(typeof i=="string"?JSON.parse(i):i)?.state?.nodes??[]}catch{return"diverged-mirror"}}const a=r.sourceSession.sessionId,f=s.filter(e=>e.data.importSource?.sessionId===a);return s.some(e=>!e.data.importSource)||s.some(e=>e.data.importSource&&e.data.importSource.sessionId!==a)||f.filter(e=>e.data.source).length<r.sourceSession.importedCount||f.some(e=>e.data.source&&(e.data.question!==e.data.source.question||e.data.response!==e.data.source.response))?"diverged-mirror":"pristine-mirror"}async function mt(){const{bootProjects:n}=await k(async()=>{const{bootProjects:i}=await import("./index-DWanOFbr.js").then(m=>m.F);return{bootProjects:i}},__vite__mapDeps([1,2]));await n();const{projects:d,activeId:t}=_.getState(),r=d.find(i=>i.id===t);if(!r?.sourceSession)return;const s=Y(r);if(s.length===0)return;const a=new Set;for(const i of y.getState().nodes){const m=i.data.importSource?.sessionId;m&&a.add(m)}const f=s.filter(i=>!a.has(i));if(f.length===0)return;for(const i of f)await Z(r.id,i);const e=_.getState().projects.find(i=>i.id===r.id)?.sourceSession?"toast.unsubscribed":"toast.unsubscribedNative";tt("info",V(K(e),{n:f.length}),8e3)}async function lt(n,d){const t=n.filter(c=>!!c&&!!c.sessionId);if(t.length===0)return null;const r=d??await W(V(K("atlas.mergedName"),{title:t[0].title.slice(0,24),n:t.length}));await R(r),y.getState().pushHistory();let s=0,a=0;for(const c of t){const e=c.sessionId;if(L(e)){a++;continue}const i=c.build();if(i.nodes.length===0){a++;continue}const m=i.nodes.filter(o=>o.data.importSource),u=y.getState().nodes,l=u.reduce((o,p)=>Math.max(o,p.position.x+(p.width??p.measured?.width??540)),-1/0),g=u.reduce((o,p)=>Math.min(o,p.position.y),1/0),w=Math.min(...i.nodes.map(o=>o.position.x)),b=Math.min(...i.nodes.map(o=>o.position.y)),x=(Number.isFinite(l)?l+180:0)-w,h=(Number.isFinite(g)?g:0)-b,N=i.nodes.map(o=>({...o,position:{x:o.position.x+x,y:o.position.y+h}})),v=new Set(N.map(o=>o.id)),j=i.edges.filter(o=>v.has(o.source)&&v.has(o.target));y.setState(o=>({nodes:[...o.nodes,...N],edges:[...o.edges,...j]})),await O(r,"chapter",{sessionId:e,runner:c.source,importedCount:m.length,tailNodeId:m.at(-1)?.id??N[N.length-1].id}),s++}y.getState().pushHistory();const f=y.getState().nodes.at(-1);return s>0&&f&&C.getState().setArrivalFocusNodeId(f.id),{mounted:s,skipped:a,projectId:r}}export{ft as canvasUniqueness,J as importOrAppendConversation,ct as importOrAppendSession,lt as mergeSessionsIntoProject,pt as mountConversationToProject,ut as shellSessionReader,Y as subscribedSessionIds,mt as unsubscribeOrphanedSessions};
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-YWyx765g.js","assets/index-BH9ozg79.js","assets/index-YkjjqQPO.css","assets/experiment-loop-BzzzDlbH.js"])))=>i.map(i=>d[i]);
2
+ import{c as _,b as y,_ as k,p as D,r as O,g as R,a as K,u as C,h as Q,s as z,j as $,k as W,f as V,l as Y,m as Z,t as tt,n as M,o as et,q as st}from"./index-BH9ozg79.js";const ot=190;async function ct(n){const{anyRunnerSessionConversation:d}=await k(async()=>{const{anyRunnerSessionConversation:r}=await import("./index-YWyx765g.js");return{anyRunnerSessionConversation:r}},__vite__mapDeps([0,1,2])),t=await d(n);return J(t)}function ut(n,d){let r=0,s=!1;return async()=>{if(s)return null;const a=await window.desktopSessions.readRange(n,d,r,8388608);return r=a.nextStart,a.eof&&(s=!0),a.text}}function L(n){if(!n)return null;for(const d of _.getState().projects){const t=d.sourceSession;if(!t)continue;if(t.sessionId===n)return{project:d,entry:t};const r=t.chapters?.find(a=>a.sessionId===n);if(r)return{project:d,entry:r};const s=t.branches?.find(a=>a.sessionId===n);if(s)return{project:d,entry:s}}return null}function H(n,d,t,r,s){const a=r.position.x+(s?560:0),f=a-40,c=a+580,e=n.nodes.reduce((g,w)=>{const b=w.width??w.measured?.width??540;if(w.position.x+b<f||w.position.x>c)return g;const x=w.height??w.measured?.height??300;return Math.max(g,w.position.y+x)},s?r.position.y-300:r.position.y+(r.height??140)),i=a-d[0].position.x,m=Math.max(e+ot,s?r.position.y:-1/0)-d[0].position.y,u=d.map(g=>({...g,position:{x:g.position.x+i,y:g.position.y+m}})),l=[{id:M(),source:r.id,target:u[0].id,type:"smoothstep"},...t];return{moved:u,edges:l}}async function J(n,d={}){if(!n)return null;const t=n.build(),r=t.nodes.filter(c=>c.data.importSource),s=r.at(-1)?.id??t.nodes.at(-1)?.id??"";if(t.nodes.length===0)return null;const a=L(n.sessionId);if(a)return U(n,t,r,s,a,d);if(n.sessionId){const c=await nt(n.sessionId);if(c){let e=-1,i="";if(r.forEach((m,u)=>{const l=m.data.importSource?.itemIds?.[0],g=l?c.byFirstId.get(l):void 0;g&&(e=u,i=g)}),e>=0){await O(c.projectId,"chapter",{sessionId:n.sessionId,runner:n.source,importedCount:e+1,tailNodeId:i});const m=L(n.sessionId);if(m)return U(n,t,r,s,m,d)}}}if(n.sessionId&&r.length>0){const{parseAnchor:c}=await k(async()=>{const{parseAnchor:i}=await import("./experiment-loop-BzzzDlbH.js");return{parseAnchor:i}},__vite__mapDeps([3,1,2])),e=c(r[0].data.question??"");if(e&&_.getState().projects.some(i=>i.id===e.project)){await R(e.project);const i=y.getState(),m=_.getState().projects.find(l=>l.id===e.project);let u=i.nodes.find(l=>l.id===e.node)??null;if(!u&&e.mode==="continue"&&m.sourceSession?.sessionId){const l=m.sourceSession;u=i.nodes.find(g=>g.id===l.tailNodeId)??i.nodes.filter(g=>g.data.importSource?.sessionId===l.sessionId).at(-1)??null}if(u){const l=t.nodes.find(h=>h.data.importSource&&h.data.stepKind!=="note");if(l&&c(l.data.question??"")){const h=K("exp.openerMark");l.data={...l.data,question:h,source:l.data.source?{...l.data.source,question:h}:l.data.source}}const g=new Set(t.nodes.map(h=>h.id)),w=t.edges.filter(h=>g.has(h.source)&&g.has(h.target)),b=e.mode!=="continue",x=H(i,t.nodes,w,u,b);if(b){const h=x.moved.find(N=>N.data.importSource&&N.data.stepKind!=="note");h&&(h.data={...h.data,isBranch:!0})}return i.pushHistory(),y.setState(h=>({nodes:[...h.nodes,...x.moved],edges:[...h.edges,...x.edges]})),await O(e.project,b?"branch":"chapter",{sessionId:n.sessionId,runner:n.source,importedCount:r.length,tailNodeId:s,anchorNodeId:u.id}),C.getState().setArrivalFocusNodeId(x.moved[x.moved.length-1].id),{kind:"mounted",mode:b?"branch":"continue",turns:r.length}}}}const f=crypto.randomUUID();return await Q(D(f),JSON.stringify({state:{nodes:z(t.nodes),edges:t.edges},version:1})),C.getState().setArrivalFocusNodeId(t.nodes[t.nodes.length-1].id),await $(f,n.title.slice(0,60),"chat",n.sessionId?{sourceSession:{sessionId:n.sessionId,runner:n.source,importedCount:r.length,tailNodeId:s}}:void 0),{kind:"imported",nodeCount:t.nodes.length}}async function pt(n,d){if(!n||!n.sessionId)return null;if(L(n.sessionId))return J(n);const t=n.build(),r=t.nodes.filter(u=>u.data.importSource);if(t.nodes.length===0)return null;await R(d);const s=y.getState(),a=_.getState().projects.find(u=>u.id===d);if(!a)return null;const f=a.sourceSession,c=(f?.sessionId?s.nodes.find(u=>u.id===f.tailNodeId)??s.nodes.filter(u=>u.data.importSource?.sessionId===f.sessionId).at(-1):null)??s.nodes.at(-1)??null;if(!c)return null;const e=new Set(t.nodes.map(u=>u.id)),i=t.edges.filter(u=>e.has(u.source)&&e.has(u.target)),m=H(s,t.nodes,i,c,!1);return s.pushHistory(),y.setState(u=>({nodes:[...u.nodes,...m.moved],edges:[...u.edges,...m.edges]})),await O(d,"chapter",{sessionId:n.sessionId,runner:n.source,importedCount:r.length,tailNodeId:r.at(-1)?.id??t.nodes.at(-1).id,anchorNodeId:c.id}),C.getState().setArrivalFocusNodeId(m.moved[m.moved.length-1].id),{kind:"mounted",mode:"continue",turns:r.length}}async function nt(n){const{projects:d,activeId:t}=_.getState(),r=[...d].sort((s,a)=>s.id===t?-1:a.id===t?1:a.updatedAt-s.updatedAt);for(const s of r){if(s.id!==t&&s.provenanceSessions&&!s.provenanceSessions.includes(n))continue;let a;if(s.id===t)a=y.getState().nodes;else try{const{get:c}=await k(async()=>{const{get:m}=await import("./index-BH9ozg79.js").then(u=>u.D);return{get:m}},__vite__mapDeps([1,2])),e=await c(D(s.id));a=(typeof e=="string"?JSON.parse(e):e)?.state?.nodes??[]}catch{continue}if(s.id!==t&&!s.provenanceSessions){const c=[...new Set(a.map(e=>e.data.importSource?.sessionId).filter(e=>!!e))];_.setState(e=>({projects:e.projects.map(i=>i.id===s.id?{...i,provenanceSessions:c}:i)}))}const f=new Map;for(const c of a)if(c.data.importSource?.sessionId===n&&c.data.stepKind!=="note"){const e=c.data.importSource.itemIds?.[0];e&&f.set(e,c.id)}if(f.size>0)return{projectId:s.id,byFirstId:f}}return null}async function U(n,d,t,r,s,a={}){await R(s.project.id);const f=y.getState(),c=f.nodes.filter(o=>o.data.importSource?.sessionId===n.sessionId),e=f.nodes.find(o=>o.id===s.entry.tailNodeId)??c.at(-1)??null,i=s.entry.importedCount>0&&t.length>=s.entry.importedCount?t[s.entry.importedCount-1]:null;if(i){const o=i.data.importSource?.itemIds?.[0],p=o?c.find(E=>E.data.importSource?.itemIds?.[0]===o):void 0,S=p?.data.source,A=!!S&&p.data.question===S.question&&(p.data.response??"")===(S.response??""),I=i.data,X=!!p&&(I.response??"").trim()===""&&(p.data.response??"").trim()!=="",G=!!p&&!X&&(I.question!==p.data.question||(I.response??"")!==(p.data.response??"")),P=p?.data.attachments??[],T=I.attachments??[],B=!!p&&T.length>P.length&&P.every((E,q)=>T[q]?.name===E.name);if(p&&A&&(G||B)){const E=G?I.attachments:[...P,...T.slice(P.length)];y.setState(q=>({nodes:q.nodes.map(F=>F.id===p.id?{...F,data:{...F.data,question:I.question,response:I.response,responses:I.responses,responseIndex:I.responseIndex,tokenCount:I.tokenCount,attachments:E,importSource:I.importSource,source:I.source}}:F)})),y.getState().recomputeStaleness()}}if(t.length<=s.entry.importedCount)return a.focusOnRefresh!==!1&&C.getState().setArrivalFocusNodeId(e?.id??null),{kind:"opened"};const m=t[s.entry.importedCount],u=d.nodes.findIndex(o=>o.id===m.id),l=d.nodes.slice(u),g=new Set(l.map(o=>o.id)),w=d.edges.filter(o=>g.has(o.source)&&g.has(o.target)),b=new Map;for(const o of c){const p=o.data.importSource?.itemIds?.[0];p&&b.set(p,o.id)}const x=new Map;for(const o of d.nodes){const p=o.data.importSource?.itemIds?.[0];p&&!g.has(o.id)&&x.set(o.id,p)}const h=[];for(const o of d.edges){if(!g.has(o.target)||g.has(o.source))continue;const p=x.get(o.source),S=p?b.get(p):void 0;S&&h.push({...o,id:M(),source:S})}const N=new Set(h.map(o=>o.target));let v,j;if(e){const o=H(f,l,w,e,!1);v=o.moved;const p=new Set(w.map(S=>S.target));j=o.edges.filter(S=>!(S.source===e.id&&N.has(S.target)));for(const S of v)S.id!==v[0].id&&!p.has(S.id)&&!N.has(S.id)&&S.data.stepKind!=="note"&&j.push({id:M(),source:e.id,target:S.id,type:"smoothstep"});j=[...j,...h]}else{const p=(f.nodes.length?Math.max(...f.nodes.map(I=>I.position.x)):0)+560-l[0].position.x,S=-l[0].position.y;v=l.map(I=>({...I,position:{x:I.position.x+p,y:I.position.y+S}}));const A=rt(it(t.length-s.entry.importedCount),v[0]);v=[A,...v],j=[{id:M(),source:A.id,target:v[1].id,type:"smoothstep"},...w]}return f.pushHistory(),y.setState(o=>({nodes:[...o.nodes,...v],edges:[...o.edges,...j]})),await et(s.project.id,n.sessionId,{importedCount:t.length,tailNodeId:r}),C.getState().setArrivalFocusNodeId(v[e?0:1].id),{kind:"appended",turns:t.length-s.entry.importedCount}}function it(n){return`[Mirror] The source session grew by ${n} turn(s); the earlier mirrored turns were removed from this canvas by hand, so the new turns land here on their own.`}function rt(n,d){const t=st(n,"",!1);return t.data.stepKind="note",t.data.importSource=d.data.importSource?{...d.data.importSource,itemIds:[]}:void 0,t.width=460,t.position={x:d.position.x-520,y:d.position.y},t}async function ft(n){const{projects:d,activeId:t}=_.getState(),r=d.find(e=>e.id===n);if(!r?.sourceSession)return"native";if((r.sourceSession.chapters?.length??0)>0||(r.sourceSession.branches?.length??0)>0)return"diverged-mirror";let s;if(n===t)s=y.getState().nodes;else{const{get:e}=await k(async()=>{const{get:m}=await import("./index-BH9ozg79.js").then(u=>u.D);return{get:m}},__vite__mapDeps([1,2])),i=await e(D(n));try{s=(typeof i=="string"?JSON.parse(i):i)?.state?.nodes??[]}catch{return"diverged-mirror"}}const a=r.sourceSession.sessionId,f=s.filter(e=>e.data.importSource?.sessionId===a);return s.some(e=>!e.data.importSource)||s.some(e=>e.data.importSource&&e.data.importSource.sessionId!==a)||f.filter(e=>e.data.source).length<r.sourceSession.importedCount||f.some(e=>e.data.source&&(e.data.question!==e.data.source.question||e.data.response!==e.data.source.response))?"diverged-mirror":"pristine-mirror"}async function mt(){const{bootProjects:n}=await k(async()=>{const{bootProjects:i}=await import("./index-BH9ozg79.js").then(m=>m.F);return{bootProjects:i}},__vite__mapDeps([1,2]));await n();const{projects:d,activeId:t}=_.getState(),r=d.find(i=>i.id===t);if(!r?.sourceSession)return;const s=Y(r);if(s.length===0)return;const a=new Set;for(const i of y.getState().nodes){const m=i.data.importSource?.sessionId;m&&a.add(m)}const f=s.filter(i=>!a.has(i));if(f.length===0)return;for(const i of f)await Z(r.id,i);const e=_.getState().projects.find(i=>i.id===r.id)?.sourceSession?"toast.unsubscribed":"toast.unsubscribedNative";tt("info",V(K(e),{n:f.length}),8e3)}async function lt(n,d){const t=n.filter(c=>!!c&&!!c.sessionId);if(t.length===0)return null;const r=d??await W(V(K("atlas.mergedName"),{title:t[0].title.slice(0,24),n:t.length}));await R(r),y.getState().pushHistory();let s=0,a=0;for(const c of t){const e=c.sessionId;if(L(e)){a++;continue}const i=c.build();if(i.nodes.length===0){a++;continue}const m=i.nodes.filter(o=>o.data.importSource),u=y.getState().nodes,l=u.reduce((o,p)=>Math.max(o,p.position.x+(p.width??p.measured?.width??540)),-1/0),g=u.reduce((o,p)=>Math.min(o,p.position.y),1/0),w=Math.min(...i.nodes.map(o=>o.position.x)),b=Math.min(...i.nodes.map(o=>o.position.y)),x=(Number.isFinite(l)?l+180:0)-w,h=(Number.isFinite(g)?g:0)-b,N=i.nodes.map(o=>({...o,position:{x:o.position.x+x,y:o.position.y+h}})),v=new Set(N.map(o=>o.id)),j=i.edges.filter(o=>v.has(o.source)&&v.has(o.target));y.setState(o=>({nodes:[...o.nodes,...N],edges:[...o.edges,...j]})),await O(r,"chapter",{sessionId:e,runner:c.source,importedCount:m.length,tailNodeId:m.at(-1)?.id??N[N.length-1].id}),s++}y.getState().pushHistory();const f=y.getState().nodes.at(-1);return s>0&&f&&C.getState().setArrivalFocusNodeId(f.id),{mounted:s,skipped:a,projectId:r}}export{ft as canvasUniqueness,J as importOrAppendConversation,ct as importOrAppendSession,lt as mergeSessionsIntoProject,pt as mountConversationToProject,ut as shellSessionReader,Y as subscribedSessionIds,mt as unsubscribeOrphanedSessions};
@@ -1 +1 @@
1
- import{b as c,c as p,E as m,s as v,d as w,i as h,e as g}from"./index-DWanOFbr.js";const S=6e4,T=4e3;function y(e){const s=(e.data.attachments??[]).map(t=>({id:t.id,name:t.name,type:t.type,size:t.size,content:"",...t.addedAt?{addedAt:t.addedAt}:{},...t.extractedText?{extractedText:t.extractedText.slice(0,T)}:{},...t.paths?{paths:t.paths}:{},...t.op?{op:t.op}:{}}));return{...e,data:{...e.data,attachments:s}}}function j(){const{nodes:e,edges:s,events:t}=c.getState(),{projects:u,activeId:a}=p.getState();if(!a||e.length===0)return null;const i=u.find(l=>l.id===a),f=JSON.stringify({version:m,name:w(),projectId:a,exportedAt:new Date().toISOString(),record:"thoughtdag-canvas-record",instantiatedFrom:i?.instantiatedFrom,sourceSession:i?.sourceSession,nodes:v(e).map(y),edges:s,events:t});return{projectId:a,json:f}}let n=null,o=!1;async function d(){n&&(clearTimeout(n),n=null),o=!1;const e=window.desktopCanvas;if(!e)return!1;const s=j();return s?!!(await e.write(s.projectId,s.json).catch(()=>({ok:!1}))).ok:!1}function x(){o=!0,n&&clearTimeout(n),n=setTimeout(()=>{n=null,o&&d().catch(e=>console.warn("[thoughtdag] canvas record write failed:",e))},S)}let r=!1;function E(){r||h||typeof window>"u"||!window.desktopCanvas||(r=!0,c.subscribe((e,s)=>{(e.nodes!==s.nodes||e.edges!==s.edges||e.events!==s.events)&&x()}),g.push(async()=>{o&&await d()}),window.addEventListener("pagehide",()=>{o&&d()}))}async function R(e){await window.desktopCanvas?.remove(e).catch(()=>{})}export{j as canvasRecordPayload,d as flushCanvasRecord,R as removeCanvasRecord,E as startCanvasRecord};
1
+ import{b as c,c as p,E as m,s as v,d as w,i as h,e as g}from"./index-BH9ozg79.js";const S=6e4,T=4e3;function y(e){const s=(e.data.attachments??[]).map(t=>({id:t.id,name:t.name,type:t.type,size:t.size,content:"",...t.addedAt?{addedAt:t.addedAt}:{},...t.extractedText?{extractedText:t.extractedText.slice(0,T)}:{},...t.paths?{paths:t.paths}:{},...t.op?{op:t.op}:{}}));return{...e,data:{...e.data,attachments:s}}}function j(){const{nodes:e,edges:s,events:t}=c.getState(),{projects:u,activeId:a}=p.getState();if(!a||e.length===0)return null;const i=u.find(l=>l.id===a),f=JSON.stringify({version:m,name:w(),projectId:a,exportedAt:new Date().toISOString(),record:"thoughtdag-canvas-record",instantiatedFrom:i?.instantiatedFrom,sourceSession:i?.sourceSession,nodes:v(e).map(y),edges:s,events:t});return{projectId:a,json:f}}let n=null,o=!1;async function d(){n&&(clearTimeout(n),n=null),o=!1;const e=window.desktopCanvas;if(!e)return!1;const s=j();return s?!!(await e.write(s.projectId,s.json).catch(()=>({ok:!1}))).ok:!1}function x(){o=!0,n&&clearTimeout(n),n=setTimeout(()=>{n=null,o&&d().catch(e=>console.warn("[thoughtdag] canvas record write failed:",e))},S)}let r=!1;function E(){r||h||typeof window>"u"||!window.desktopCanvas||(r=!0,c.subscribe((e,s)=>{(e.nodes!==s.nodes||e.edges!==s.edges||e.events!==s.events)&&x()}),g.push(async()=>{o&&await d()}),window.addEventListener("pagehide",()=>{o&&d()}))}async function R(e){await window.desktopCanvas?.remove(e).catch(()=>{})}export{j as canvasRecordPayload,d as flushCanvasRecord,R as removeCanvasRecord,E as startCanvasRecord};
@@ -1,4 +1,4 @@
1
- import{q as y,B as w,n as C}from"./index-DWanOFbr.js";import{t as _,a as S,r as x,b as A,c as L,d as b,e as k,f as v,s as O,g as q,h as B,m as M,T as N,A as f,i as Q}from"./shared-DxaHN0fp.js";const $=16e3;function g(o){return typeof o=="string"?o:Array.isArray(o)?o.filter(t=>t.type==="text"&&t.text).map(t=>t.text).join(`
1
+ import{q as y,B as w,n as C}from"./index-BH9ozg79.js";import{t as _,a as S,r as x,b as A,c as L,d as b,e as k,f as v,s as O,g as q,h as B,m as M,T as N,A as f,i as Q}from"./shared-LHIg0YHa.js";const $=16e3;function g(o){return typeof o=="string"?o:Array.isArray(o)?o.filter(t=>t.type==="text"&&t.text).map(t=>t.text).join(`
2
2
  `):""}function I(o){return typeof o=="string"?o:Array.isArray(o)?o.map(t=>t.type==="text"&&t.text?t.text:t.type==="image"?"[image result omitted]":"").filter(Boolean).join(`
3
3
  `):""}const m=v;class F{turns=[];pendingTools=new Map;current=null;pendingCompaction;sessionId=null;customTitle=null;summary=null;slug=null;firstQuestion=null;cwd=null;mode=null;feedLine(t){const s=t.trim();if(!s)return;let i;try{i=JSON.parse(s)}catch{return}this.feed(i)}flush(){const t=this.current;t&&(t.question||t.response||t.tools.length)&&this.turns.push(t),this.current=null}feed(t){if(t.type==="custom-title"&&t.customTitle&&(this.customTitle=t.customTitle),t.type==="summary"&&t.summary&&!this.summary&&(this.summary=t.summary),t.slug&&!this.slug&&(this.slug=t.slug),t.cwd&&!this.cwd&&(this.cwd=t.cwd),this.mode===null&&(t.type==="user"||t.type==="assistant")&&t.uuid&&(this.mode=t.isSidechain&&t.agentId?"sidechain":"main",this.mode==="sidechain"&&(this.sessionId=t.agentId)),!!t.isSidechain==(this.mode==="sidechain")){if(t.type==="system"&&t.subtype==="compact_boundary"){this.flush();const s=t.compactMetadata;this.pendingCompaction=`[Compaction] The source runner compacted its history here${s?.preTokens?` (${s.preTokens} → ${s.postTokens??"?"} tokens)`:""}. Everything above this point reached later turns only as a summary.`;return}if((t.type==="user"||t.type==="assistant")&&t.uuid&&t.sessionId&&!this.sessionId&&(this.sessionId=t.sessionId),t.type==="user"){const s=t.message?.content;if(Array.isArray(s)){for(const e of s)if(e.type==="tool_result"&&e.tool_use_id){const n=this.pendingTools.get(e.tool_use_id);if(n&&this.current){const u=m(I(e.content),N);if(this.current.tools.push({name:n.name,call:n.call,result:u.text,truncated:u.truncated,...n.paths.length?{paths:n.paths}:{},op:n.op,nativeCallId:e.tool_use_id,...n.url?{url:n.url}:{},...n.locator?{locator:n.locator}:{}}),n.spawn){const c=m(I(e.content),f);(this.current.subagents??=[]).push({agent:n.spawn.agent,task:n.spawn.task,output:c.text,itemIds:[e.tool_use_id],match:n.spawn.prompt,...t.timestamp?{at:t.timestamp}:{}})}this.pendingTools.delete(e.tool_use_id)}}}const i=g(s);if(!i.trim())return;if(/^\s*<task-notification>/.test(i)){if(this.current){const e=m(i,$);this.current.tools.push({name:"Agent",call:"(task notification)",result:e.text,truncated:e.truncated,op:"agent"})}return}this.flush(),this.firstQuestion||(this.firstQuestion=i.trim()),this.current={question:i,response:"",itemIds:t.uuid?[t.uuid]:[],tools:[],parentItemId:t.parentUuid??void 0,...t.timestamp?{at:t.timestamp}:{}},this.pendingCompaction&&(this.current.compactionBefore=this.pendingCompaction,this.pendingCompaction=void 0);return}if(t.type==="assistant"&&this.current){t.uuid&&this.current.itemIds.push(t.uuid);const s=t.message?.content,i=g(s);if(i.trim()&&(this.current.response=this.current.response?`${this.current.response}
4
4
 
@@ -1,4 +1,4 @@
1
- import{q as d,n as p,B as m}from"./index-DWanOFbr.js";import{t as g,a as y,d as I,e as _,m as x,g as T,s as C,h as w,f as S,A,i as v,T as B}from"./shared-DxaHN0fp.js";function L(n){const t=[];for(const e of n.matchAll(/^\*\*\* (?:Add|Update|Delete) File: (.+)$/gm))t.push(e[1].trim());return t}const h=S,q=n=>(n??[]).filter(t=>t.text&&(t.type==="input_text"||t.type==="output_text"||t.type==="text")).map(t=>t.text).join(`
1
+ import{q as d,n as p,B as m}from"./index-BH9ozg79.js";import{t as g,a as y,d as I,e as _,m as x,g as T,s as C,h as w,f as S,A,i as v,T as B}from"./shared-LHIg0YHa.js";function L(n){const t=[];for(const e of n.matchAll(/^\*\*\* (?:Add|Update|Delete) File: (.+)$/gm))t.push(e[1].trim());return t}const h=S,q=n=>(n??[]).filter(t=>t.text&&(t.type==="input_text"||t.type==="output_text"||t.type==="text")).map(t=>t.text).join(`
2
2
  `),O=/^\s*<\/?[a-zA-Z_][\w-]*[^>]*>/,b=n=>O.test(n)||n.trimStart().startsWith("# AGENTS.md instructions for "),N=n=>(n??[]).filter(t=>t.text&&(t.type==="input_text"||t.type==="text")&&!b(t.text)).map(t=>t.text).join(`
3
3
  `),$=n=>typeof n=="string"?n:Array.isArray(n)?n.map(t=>t?.text??"").filter(Boolean).join(`
4
4
  `):n==null?"":JSON.stringify(n);class Q{turns=[];pendingCalls=new Map;current=null;pendingCompaction;sessionId=null;cwd="";day="";sawItems=!1;firstQuestion=null;parentThreadId=null;startedAt=null;feedLine(t){const e=t.trim();if(!e)return;let s;try{s=JSON.parse(e)}catch{return}this.feed(s)}flush(){const t=this.current;t&&(t.question||t.response||t.tools.length)&&this.turns.push(t),this.current=null}ensure(){return this.current||(this.current={question:"",response:"",itemIds:[],tools:[]},this.pendingCompaction&&(this.current.compactionBefore=this.pendingCompaction,this.pendingCompaction=void 0)),this.current}feed(t){const e=t.payload??{};if(t.type==="session_meta"&&e.id&&!this.sessionId){this.sessionId=e.id,this.cwd=e.cwd??"",this.day=e.timestamp?.slice(0,10)??"",this.parentThreadId=e.parent_thread_id??null,this.startedAt=e.timestamp??t.timestamp??null;return}if((t.type==="response_item"||t.type==="event_msg")&&(this.sawItems=!0),t.type==="compacted"){this.flush(),this.pendingCompaction="[Compaction] The source runner compacted its history here. Everything above this point reached later turns only as a summary.";return}if(t.type==="turn_context"||t.type==="event_msg"&&e.type==="task_started"){this.flush();const s=this.ensure();e.turn_id&&s.itemIds.push(e.turn_id);return}if(t.type==="response_item"){if(e.type==="message"){if(e.role==="user"){const s=N(e.content);if(s.trim()){this.firstQuestion||(this.firstQuestion=s.trim());const o=this.ensure();!o.at&&t.timestamp&&(o.at=t.timestamp),o.question=o.question?`${o.question}
@@ -1,4 +1,4 @@
1
- import{q as C,B as x,n as w}from"./index-DWanOFbr.js";import{t as L,a as h,b as I,c as y,f as c,r as f,d as A,T as d,i as p,A as m,g as S,s as b}from"./shared-DxaHN0fp.js";function q(r){if(!r)return!1;if(r.error)return!0;const s=r.message?.content;return Array.isArray(s)&&s.some(t=>!!t&&typeof t=="object"&&t.isError===!0)}function l(r,s=0){return typeof r=="string"?r:!Array.isArray(r)||s>2?"":r.map(t=>{if(!t||typeof t!="object")return"";const e=t;return e.type==="text"&&typeof e.text=="string"?e.text:e.type==="image"?"[image omitted]":e.type==="reasoning"?"":l(e.text??e.content,s+1)}).filter(Boolean).join(`
1
+ import{q as C,B as x,n as w}from"./index-BH9ozg79.js";import{t as L,a as h,b as I,c as y,f as c,r as f,d as A,T as d,i as p,A as m,g as S,s as b}from"./shared-LHIg0YHa.js";function q(r){if(!r)return!1;if(r.error)return!0;const s=r.message?.content;return Array.isArray(s)&&s.some(t=>!!t&&typeof t=="object"&&t.isError===!0)}function l(r,s=0){return typeof r=="string"?r:!Array.isArray(r)||s>2?"":r.map(t=>{if(!t||typeof t!="object")return"";const e=t;return e.type==="text"&&typeof e.text=="string"?e.text:e.type==="image"?"[image omitted]":e.type==="reasoning"?"":l(e.text??e.content,s+1)}).filter(Boolean).join(`
2
2
  `)}function O(r,s,t){const e=h(r);if(e==="run"||/^run_code$/i.test(r)){const o=t??{};return c(typeof o.code=="string"?o.code:s,m)}const n=t&&typeof t=="object"?f(r,t):s;return c(n,e==="write"||e==="edit"?m:p)}const v=r=>{try{return JSON.parse(r??"")}catch{return}};class _{turns=[];pendingTools=new Map;current=null;sessionId=null;cwd=null;title=null;firstQuestion=null;feedLine(s){const t=s.trim();if(!t)return;let e;try{e=JSON.parse(t)}catch{return}this.feed(e)}flush(){const s=this.current;s&&(s.question||s.response||s.tools.length)&&this.turns.push(s),this.current=null}ensure(){return this.current||(this.current={question:"",response:"",itemIds:[],tools:[]}),this.current}feed(s){if(s.type==="session"&&s.id&&!("timestamp"in s)){this.sessionId||(this.sessionId=s.id),s.cwd&&!this.cwd&&(this.cwd=s.cwd);return}if(s.type==="session/title"&&s.data?.title&&!this.title){this.title=s.data.title;return}if(s.type==="user/message"){const t=s,e=t.data?.source?.kind;if(e&&e!=="user")return;const n=l(t.data?.content).trim();if(!n)return;this.firstQuestion||(this.firstQuestion=n.split(`
3
3
  `)[0].slice(0,80)),this.flush();const o=this.ensure();o.question=n,o.itemIds=[t.data?.id??`u${t.seq}`],t.time&&(o.at=new Date(t.time).toISOString());return}if(s.type==="assistant/message"&&this.current){const t=s,e=t.data?.message?.content,n=l(e).trim(),o=t.data?.message?.id;o&&this.current.itemIds.push(o),n&&(this.current.response=this.current.response?`${this.current.response}
4
4
 
@@ -1,2 +1,2 @@
1
- import{a as c,b as h,c as l,w as p,x as m,t as u,f as b}from"./index-DWanOFbr.js";const g=/\[ThoughtDAG anchor: project=([\w-]+) node=([\w-]+) bundle=([\w-]+)(?: mode=(branch|continue))?\]/;function w(o){const n=o.match(g);return n?{project:n[1],node:n[2],bundle:n[3],mode:n[4]==="continue"?"continue":"branch"}:null}function x(o,n){const e=[];e.push(c("exp.mdIntro")),e.push("");for(const s of o.context.messages){const t=s.content[0].text;switch(s.source.layer){case"system":e.push(`**${c("exp.mdRole")}** ${t}`);break;case"chain":e.push(s.role==="assistant"?`**A:** ${t}`:`**Q:** ${t}`);break;default:e.push(t)}e.push("")}return e.push("---"),e.push(c("exp.mdOutro")),e.push(""),e.push(`[ThoughtDAG anchor: project=${n.project} node=${n.node} bundle=${n.bundle}${n.mode==="continue"?" mode=continue":""}]`),e.join(`
1
+ import{a as c,b as h,c as l,w as p,x as m,t as u,f as b}from"./index-BH9ozg79.js";const g=/\[ThoughtDAG anchor: project=([\w-]+) node=([\w-]+) bundle=([\w-]+)(?: mode=(branch|continue))?\]/;function w(o){const n=o.match(g);return n?{project:n[1],node:n[2],bundle:n[3],mode:n[4]==="continue"?"continue":"branch"}:null}function x(o,n){const e=[];e.push(c("exp.mdIntro")),e.push("");for(const s of o.context.messages){const t=s.content[0].text;switch(s.source.layer){case"system":e.push(`**${c("exp.mdRole")}** ${t}`);break;case"chain":e.push(s.role==="assistant"?`**A:** ${t}`:`**Q:** ${t}`);break;default:e.push(t)}e.push("")}return e.push("---"),e.push(c("exp.mdOutro")),e.push(""),e.push(`[ThoughtDAG anchor: project=${n.project} node=${n.node} bundle=${n.bundle}${n.mode==="continue"?" mode=continue":""}]`),e.join(`
2
2
  `)}async function j(o,n="branch"){const e=h.getState(),s=l.getState().activeId??"default",t=await p(o,e.nodes,e.edges,{now:new Date().toISOString(),projectId:s,staleIds:m(e)}),d={project:s,node:o,bundle:t.id,mode:n},i=x(t,d);try{await navigator.clipboard.writeText(i)}catch{return u("error",c("exp.clipboardFailed")),!1}{const a=[...new Set(t.context.messages.map(r=>r.source?.node_id).filter(r=>!!r))];e.logEvent("commit",o,{kind:"bundle",sha:t.integrity.content_hash,bundle:t.id,n:t.context.messages.length,...a.length?{m:a.slice(0,200).join(",")}:{},...a.length>200?{more:!0}:{}})}return u("success",b(c("exp.copied"),{n:t.context.messages.length,tok:t.budget.estimated_tokens}),12e3),!0}export{w as parseAnchor,x as renderHandoffMarkdown,j as takeToExperiment};
@@ -1 +1 @@
1
- import{I as f}from"./index-DWanOFbr.js";async function y(p){if(window.desktopAgents)return!0;const r=p.replace(/\/+$/,"");let i;try{const e=await fetch(r+"/agents/available",{credentials:"same-origin"});if(!e.ok)return!1;i=await e.json()}catch{return!1}const a=async(e,t)=>{const n=await fetch(r+e,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"same-origin",body:JSON.stringify(t??{})});if(!n.ok)throw new Error(`${e}: ${n.status}`);return n.json()},c=[];let o=null;const d=()=>{o||(o=new EventSource(r+"/agents/events"),o.onmessage=e=>{try{const t=JSON.parse(e.data);for(const n of c)n(t)}catch{}})},w=f,u={nativePicker:w},l=()=>new Promise(e=>{if(!w)return e(null);const t=`cwd-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`,n=g=>{const s=g.data;g.origin!==window.location.origin||s?.source!=="dsh-thoughtdag"||s.type!=="td:picked-cwd"||s.requestId!==t||(window.removeEventListener("message",n),s.unsupported&&(u.nativePicker=!1),e(typeof s.path=="string"&&s.path?s.path:null))};window.addEventListener("message",n),window.parent.postMessage({source:"dsh-thoughtdag",type:"td:pick-cwd",requestId:t},window.location.origin)});return window.desktopAgents={capabilities:u,available:async()=>i,models:async e=>(await fetch(r+"/agents/models"+(e?`?runtime=${encodeURIComponent(e)}`:""),{credentials:"same-origin"})).json(),run:async e=>(d(),(await a("/agents/run",e)).runId),abort:async e=>(await a("/agents/abort",{runId:e})).ok,answer:async(e,t,n)=>(await a("/agents/answer",{runId:e,requestId:t,response:n})).ok,workspace:async e=>(await a("/agents/workspace",{canvasId:e})).dir,pickCwd:()=>l(),guardWrite:async(e,t)=>(await a("/agents/guard",{cwd:e,config:t})).ok,writeMaterials:async(e,t)=>a("/agents/materials",{cwd:e,files:t}),backupJson:async(e,t,n)=>a("/backup",{dir:e,name:t,json:n}),onEvent:e=>{c.push(e),d()}},!0}export{y as installAgentsHttpBridge};
1
+ import{I as f}from"./index-BH9ozg79.js";async function y(p){if(window.desktopAgents)return!0;const r=p.replace(/\/+$/,"");let i;try{const e=await fetch(r+"/agents/available",{credentials:"same-origin"});if(!e.ok)return!1;i=await e.json()}catch{return!1}const a=async(e,t)=>{const n=await fetch(r+e,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"same-origin",body:JSON.stringify(t??{})});if(!n.ok)throw new Error(`${e}: ${n.status}`);return n.json()},c=[];let o=null;const d=()=>{o||(o=new EventSource(r+"/agents/events"),o.onmessage=e=>{try{const t=JSON.parse(e.data);for(const n of c)n(t)}catch{}})},w=f,u={nativePicker:w},l=()=>new Promise(e=>{if(!w)return e(null);const t=`cwd-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`,n=g=>{const s=g.data;g.origin!==window.location.origin||s?.source!=="dsh-thoughtdag"||s.type!=="td:picked-cwd"||s.requestId!==t||(window.removeEventListener("message",n),s.unsupported&&(u.nativePicker=!1),e(typeof s.path=="string"&&s.path?s.path:null))};window.addEventListener("message",n),window.parent.postMessage({source:"dsh-thoughtdag",type:"td:pick-cwd",requestId:t},window.location.origin)});return window.desktopAgents={capabilities:u,available:async()=>i,models:async e=>(await fetch(r+"/agents/models"+(e?`?runtime=${encodeURIComponent(e)}`:""),{credentials:"same-origin"})).json(),run:async e=>(d(),(await a("/agents/run",e)).runId),abort:async e=>(await a("/agents/abort",{runId:e})).ok,answer:async(e,t,n)=>(await a("/agents/answer",{runId:e,requestId:t,response:n})).ok,workspace:async e=>(await a("/agents/workspace",{canvasId:e})).dir,pickCwd:()=>l(),guardWrite:async(e,t)=>(await a("/agents/guard",{cwd:e,config:t})).ok,writeMaterials:async(e,t)=>a("/agents/materials",{cwd:e,files:t}),backupJson:async(e,t,n)=>a("/backup",{dir:e,name:t,json:n}),onEvent:e=>{c.push(e),d()}},!0}export{y as installAgentsHttpBridge};