dsh-thoughtdag 0.4.4 → 0.4.5

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 (22) hide show
  1. package/README.md +22 -6
  2. package/cordis.patch.yml +5 -0
  3. package/dist-app/assets/{canonical-DbPqsMYz.js → canonical-DDfsxGbh.js} +2 -2
  4. package/dist-app/assets/{canvas-record-C1A8ExlM.js → canvas-record-vunI4XSG.js} +1 -1
  5. package/dist-app/assets/{claude-code-session-DQRgWy00.js → claude-code-session-w7XeYCbv.js} +1 -1
  6. package/dist-app/assets/{codex-session--KVj3_vb.js → codex-session-BteJdhnJ.js} +1 -1
  7. package/dist-app/assets/{dsh-session-6OCSm4h5.js → dsh-session-DtVkAUjy.js} +1 -1
  8. package/dist-app/assets/{experiment-loop-BfxITu2e.js → experiment-loop-cKs-OaUA.js} +1 -1
  9. package/dist-app/assets/{index-6m02Pb4Q.js → index-BgFLKHxw.js} +10 -10
  10. package/dist-app/assets/{index-BH-U0zVI.js → index-CZgf0TxH.js} +1 -1
  11. package/dist-app/assets/{index-D-BTv0n0.js → index-DbmziCje.js} +3 -3
  12. package/dist-app/assets/{index-BL39OXsY.js → index-ZY9zV6mj.js} +1 -1
  13. package/dist-app/assets/{live-mirror-BElcCk_a.js → live-mirror-Cil__utB.js} +2 -2
  14. package/dist-app/assets/{sensitive-scan-L0rFzufE.js → sensitive-scan-NBqP2Srd.js} +1 -1
  15. package/dist-app/assets/{session-handoff-CGrowwZp.js → session-handoff-C_88Qy1y.js} +2 -2
  16. package/dist-app/assets/{shared-CURSZnXt.js → shared-0Cyt1YSM.js} +1 -1
  17. package/dist-app/assets/{turndown-plugin-gfm.cjs-p3SpZgsj.js → turndown-plugin-gfm.cjs-BkQZDlXD.js} +1 -1
  18. package/dist-app/assets/{update-check-D5daO3Cz.js → update-check-Ca6SiYKC.js} +1 -1
  19. package/dist-app/index.html +1 -1
  20. package/lib/index.js +95 -2
  21. package/lib/why.mjs +2588 -0
  22. package/package.json +1 -1
package/README.md CHANGED
@@ -62,17 +62,33 @@ full-screen iframe.
62
62
 
63
63
  ### Canvas-side import
64
64
 
65
- ThoughtDAG's own session importer (`dsh-session` adapter + the canonical
66
- import path) accepts the bridge's JSONL verbatim. Wiring a "DSH sessions"
67
- source into the in-iframe canvas UI (Session Atlas) is planned; the bridge is
68
- the data plane it will read.
65
+ Inside the iframe the canvas runs with this bridge as its session source
66
+ (the SPA is built with `VITE_DSH_BRIDGE=/thoughtdag/api`): Session Atlas
67
+ lists the harness's sessions beside Claude Code's and Codex's (served by
68
+ this host from their directories), opens one as a graph, and follows it
69
+ live by polling the session's seq. The client half tells the canvas which
70
+ session the chat shows (`td:current-session`) and switches the chat when the
71
+ canvas names one (`td:select-session`).
72
+
73
+ ## The why layer inside the harness
74
+
75
+ The plugin bundles the `thoughtdag` CLI's library (`lib/why.mjs`, built at pack time) and answers the same four questions over the same `~/.thoughtdag` index — no CLI or MCP install needed:
76
+
77
+ | Surface | What |
78
+ |---|---|
79
+ | Native tools | `why_check(path)`, `why_file(path, include_read?, limit?)`, `why_find(phrase, in?, limit?)`, `why_recall(session, turn)` — the agent calls them like any harness tool; relative paths resolve against the session's working directory |
80
+ | `/why <path \| url \| arxiv:id>` | a person asks from the chat; the answer is the CLI's `why` output, no model message |
81
+ | System-prompt section | four lines telling the model to `why_check` before editing a file with history and how to read the other three |
82
+
83
+ Both are on by default; `whyTools: false` / `whyPrompt: false` in the plugin config turn them off.
69
84
 
70
85
  ## Not yet (roadmap)
71
86
 
87
+ - Canvas why panel (a node's file → its history through `/thoughtdag/api`)
72
88
  - 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`)
73
89
  - `replace`: shadow a surface range from the canvas (DSH's compaction primitive); needs a live check of how the chat renders a replaced range
74
- - Theme sync and live session following in the iframe
75
- - A real "import current session" affordance inside the canvas UI
90
+ - Theme and language sync with the harness UI
91
+ - Open the chat's current session on the canvas automatically when the view switches
76
92
 
77
93
  ## Development
78
94
 
package/cordis.patch.yml CHANGED
@@ -9,3 +9,8 @@
9
9
  # Extra authorities the /thoughtdag/api Host check accepts; localhost
10
10
  # and 127.0.0.1 are always allowed.
11
11
  trustedHosts: []
12
+ # The why layer as native harness tools (why_check, why_file, why_find,
13
+ # why_recall) and a /why command. Set false to leave them out.
14
+ whyTools: true
15
+ # A short system-prompt section telling the model when to ask why.
16
+ whyPrompt: true
@@ -1,2 +1,2 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-D-BTv0n0.js","assets/index-6m02Pb4Q.js","assets/index-DEHbIrRr.css","assets/experiment-loop-BfxITu2e.js"])))=>i.map(i=>d[i]);
2
- import{c as N,b as y,_ as E,p as q,r as M,h as O,a as D,u as j,j as X,s as B,k as Q,l as z,f as U,m as $,n as W,t as Y,o as F,q as Z,v as tt}from"./index-6m02Pb4Q.js";const et=190;async function dt(o){const{anyRunnerSessionConversation:n}=await E(async()=>{const{anyRunnerSessionConversation:a}=await import("./index-D-BTv0n0.js");return{anyRunnerSessionConversation:a}},__vite__mapDeps([0,1,2])),e=await n(o);return V(e)}function at(o,n){let a=0,s=!1;return async()=>{if(s)return null;const c=await window.desktopSessions.readRange(o,n,a,8388608);return a=c.nextStart,c.eof&&(s=!0),c.text}}function L(o){if(!o)return null;for(const n of N.getState().projects){const e=n.sourceSession;if(!e)continue;if(e.sessionId===o)return{project:n,entry:e};const a=e.chapters?.find(c=>c.sessionId===o);if(a)return{project:n,entry:a};const s=e.branches?.find(c=>c.sessionId===o);if(s)return{project:n,entry:s}}return null}function H(o,n,e,a,s){const c=a.position.x+(s?560:0),m=c-40,d=c+580,t=o.nodes.reduce((w,S)=>{const x=S.width??S.measured?.width??540;if(S.position.x+x<m||S.position.x>d)return w;const l=S.height??S.measured?.height??300;return Math.max(w,S.position.y+l)},s?a.position.y-300:a.position.y+(a.height??140)),u=c-n[0].position.x,f=Math.max(t+et,s?a.position.y:-1/0)-n[0].position.y,i=n.map(w=>({...w,position:{x:w.position.x+u,y:w.position.y+f}})),h=[{id:F(),source:a.id,target:i[0].id,type:"smoothstep"},...e];return{moved:i,edges:h}}async function V(o){if(!o)return null;const n=o.build(),e=n.nodes.filter(m=>m.data.importSource),a=e.at(-1)?.id??n.nodes.at(-1)?.id??"";if(n.nodes.length===0)return null;const s=L(o.sessionId);if(s)return G(o,n,e,a,s);if(o.sessionId){const m=await st(o.sessionId);if(m){let d=-1,t="";if(e.forEach((u,f)=>{const i=u.data.importSource?.itemIds?.[0],h=i?m.byFirstId.get(i):void 0;h&&(d=f,t=h)}),d>=0){await M(m.projectId,"chapter",{sessionId:o.sessionId,runner:o.source,importedCount:d+1,tailNodeId:t});const u=L(o.sessionId);if(u)return G(o,n,e,a,u)}}}if(o.sessionId&&e.length>0){const{parseAnchor:m}=await E(async()=>{const{parseAnchor:t}=await import("./experiment-loop-BfxITu2e.js");return{parseAnchor:t}},__vite__mapDeps([3,1,2])),d=m(e[0].data.question??"");if(d&&N.getState().projects.some(t=>t.id===d.project)){await O(d.project);const t=y.getState(),u=N.getState().projects.find(i=>i.id===d.project);let f=t.nodes.find(i=>i.id===d.node)??null;if(!f&&d.mode==="continue"&&u.sourceSession?.sessionId){const i=u.sourceSession;f=t.nodes.find(h=>h.id===i.tailNodeId)??t.nodes.filter(h=>h.data.importSource?.sessionId===i.sessionId).at(-1)??null}if(f){const i=n.nodes.find(l=>l.data.importSource&&l.data.stepKind!=="note");if(i&&m(i.data.question??"")){const l=D("exp.openerMark");i.data={...i.data,question:l,source:i.data.source?{...i.data.source,question:l}:i.data.source}}const h=new Set(n.nodes.map(l=>l.id)),w=n.edges.filter(l=>h.has(l.source)&&h.has(l.target)),S=d.mode!=="continue",x=H(t,n.nodes,w,f,S);if(S){const l=x.moved.find(_=>_.data.importSource&&_.data.stepKind!=="note");l&&(l.data={...l.data,isBranch:!0})}return t.pushHistory(),y.setState(l=>({nodes:[...l.nodes,...x.moved],edges:[...l.edges,...x.edges]})),await M(d.project,S?"branch":"chapter",{sessionId:o.sessionId,runner:o.source,importedCount:e.length,tailNodeId:a,anchorNodeId:f.id}),j.getState().setArrivalFocusNodeId(x.moved[x.moved.length-1].id),{kind:"mounted",mode:S?"branch":"continue",turns:e.length}}}}const c=crypto.randomUUID();return await X(q(c),JSON.stringify({state:{nodes:B(n.nodes),edges:n.edges},version:1})),j.getState().setArrivalFocusNodeId(n.nodes[n.nodes.length-1].id),await Q(c,o.title.slice(0,60),"chat",o.sessionId?{sourceSession:{sessionId:o.sessionId,runner:o.source,importedCount:e.length,tailNodeId:a}}:void 0),{kind:"imported",nodeCount:n.nodes.length}}async function ct(o,n){if(!o||!o.sessionId)return null;if(L(o.sessionId))return V(o);const e=o.build(),a=e.nodes.filter(i=>i.data.importSource);if(e.nodes.length===0)return null;await O(n);const s=y.getState(),c=N.getState().projects.find(i=>i.id===n);if(!c)return null;const m=c.sourceSession,d=(m?.sessionId?s.nodes.find(i=>i.id===m.tailNodeId)??s.nodes.filter(i=>i.data.importSource?.sessionId===m.sessionId).at(-1):null)??s.nodes.at(-1)??null;if(!d)return null;const t=new Set(e.nodes.map(i=>i.id)),u=e.edges.filter(i=>t.has(i.source)&&t.has(i.target)),f=H(s,e.nodes,u,d,!1);return s.pushHistory(),y.setState(i=>({nodes:[...i.nodes,...f.moved],edges:[...i.edges,...f.edges]})),await M(n,"chapter",{sessionId:o.sessionId,runner:o.source,importedCount:a.length,tailNodeId:a.at(-1)?.id??e.nodes.at(-1).id,anchorNodeId:d.id}),j.getState().setArrivalFocusNodeId(f.moved[f.moved.length-1].id),{kind:"mounted",mode:"continue",turns:a.length}}async function st(o){const{projects:n,activeId:e}=N.getState(),a=[...n].sort((s,c)=>s.id===e?-1:c.id===e?1:c.updatedAt-s.updatedAt);for(const s of a){if(s.id!==e&&s.provenanceSessions&&!s.provenanceSessions.includes(o))continue;let c;if(s.id===e)c=y.getState().nodes;else try{const{get:d}=await E(async()=>{const{get:f}=await import("./index-6m02Pb4Q.js").then(i=>i.D);return{get:f}},__vite__mapDeps([1,2])),t=await d(q(s.id));c=(typeof t=="string"?JSON.parse(t):t)?.state?.nodes??[]}catch{continue}if(s.id!==e&&!s.provenanceSessions){const d=[...new Set(c.map(t=>t.data.importSource?.sessionId).filter(t=>!!t))];N.setState(t=>({projects:t.projects.map(u=>u.id===s.id?{...u,provenanceSessions:d}:u)}))}const m=new Map;for(const d of c)if(d.data.importSource?.sessionId===o&&d.data.stepKind!=="note"){const t=d.data.importSource.itemIds?.[0];t&&m.set(t,d.id)}if(m.size>0)return{projectId:s.id,byFirstId:m}}return null}async function G(o,n,e,a,s){await O(s.project.id);const c=y.getState(),m=c.nodes.filter(p=>p.data.importSource?.sessionId===o.sessionId),d=c.nodes.find(p=>p.id===s.entry.tailNodeId)??m.at(-1)??null,t=s.entry.importedCount>0&&e.length>=s.entry.importedCount?e[s.entry.importedCount-1]:null;if(t){const p=t.data.importSource?.itemIds?.[0],r=p?m.find(C=>C.data.importSource?.itemIds?.[0]===p):void 0,g=r?.data.source,k=!!g&&r.data.question===g.question&&(r.data.response??"")===(g.response??""),I=t.data,K=!!r&&(I.question!==r.data.question||(I.response??"")!==(r.data.response??"")),A=r?.data.attachments??[],T=I.attachments??[],J=!!r&&T.length>A.length&&A.every((C,R)=>T[R]?.name===C.name);if(r&&k&&(K||J)){const C=K?I.attachments:[...A,...T.slice(A.length)];y.setState(R=>({nodes:R.nodes.map(P=>P.id===r.id?{...P,data:{...P.data,question:I.question,response:I.response,responses:I.responses,responseIndex:I.responseIndex,tokenCount:I.tokenCount,attachments:C,importSource:I.importSource,source:I.source}}:P)})),y.getState().recomputeStaleness()}}if(e.length<=s.entry.importedCount)return j.getState().setArrivalFocusNodeId(d?.id??null),{kind:"opened"};const u=e[s.entry.importedCount],f=n.nodes.findIndex(p=>p.id===u.id),i=n.nodes.slice(f),h=new Set(i.map(p=>p.id)),w=n.edges.filter(p=>h.has(p.source)&&h.has(p.target)),S=new Map;for(const p of m){const r=p.data.importSource?.itemIds?.[0];r&&S.set(r,p.id)}const x=new Map;for(const p of n.nodes){const r=p.data.importSource?.itemIds?.[0];r&&!h.has(p.id)&&x.set(p.id,r)}const l=[];for(const p of n.edges){if(!h.has(p.target)||h.has(p.source))continue;const r=x.get(p.source),g=r?S.get(r):void 0;g&&l.push({...p,id:F(),source:g})}const _=new Set(l.map(p=>p.target));let v,b;if(d){const p=H(c,i,w,d,!1);v=p.moved;const r=new Set(w.map(g=>g.target));b=p.edges.filter(g=>!(g.source===d.id&&_.has(g.target)));for(const g of v)g.id!==v[0].id&&!r.has(g.id)&&!_.has(g.id)&&g.data.stepKind!=="note"&&b.push({id:F(),source:d.id,target:g.id,type:"smoothstep"});b=[...b,...l]}else{const r=(c.nodes.length?Math.max(...c.nodes.map(I=>I.position.x)):0)+560-i[0].position.x,g=-i[0].position.y;v=i.map(I=>({...I,position:{x:I.position.x+r,y:I.position.y+g}}));const k=nt(ot(e.length-s.entry.importedCount),v[0]);v=[k,...v],b=[{id:F(),source:k.id,target:v[1].id,type:"smoothstep"},...w]}return c.pushHistory(),y.setState(p=>({nodes:[...p.nodes,...v],edges:[...p.edges,...b]})),await Z(s.project.id,o.sessionId,{importedCount:e.length,tailNodeId:a}),j.getState().setArrivalFocusNodeId(v[d?0:1].id),{kind:"appended",turns:e.length-s.entry.importedCount}}function ot(o){return`[Mirror] The source session grew by ${o} turn(s); the earlier mirrored turns were removed from this canvas by hand, so the new turns land here on their own.`}function nt(o,n){const e=tt(o,"",!1);return e.data.stepKind="note",e.data.importSource=n.data.importSource?{...n.data.importSource,itemIds:[]}:void 0,e.width=460,e.position={x:n.position.x-520,y:n.position.y},e}async function ut(o){const{projects:n,activeId:e}=N.getState(),a=n.find(t=>t.id===o);if(!a?.sourceSession)return"native";if((a.sourceSession.chapters?.length??0)>0||(a.sourceSession.branches?.length??0)>0)return"diverged-mirror";let s;if(o===e)s=y.getState().nodes;else{const{get:t}=await E(async()=>{const{get:f}=await import("./index-6m02Pb4Q.js").then(i=>i.D);return{get:f}},__vite__mapDeps([1,2])),u=await t(q(o));try{s=(typeof u=="string"?JSON.parse(u):u)?.state?.nodes??[]}catch{return"diverged-mirror"}}const c=a.sourceSession.sessionId,m=s.filter(t=>t.data.importSource?.sessionId===c);return s.some(t=>!t.data.importSource)||s.some(t=>t.data.importSource&&t.data.importSource.sessionId!==c)||m.filter(t=>t.data.source).length<a.sourceSession.importedCount||m.some(t=>t.data.source&&(t.data.question!==t.data.source.question||t.data.response!==t.data.source.response))?"diverged-mirror":"pristine-mirror"}async function pt(){const{bootProjects:o}=await E(async()=>{const{bootProjects:u}=await import("./index-6m02Pb4Q.js").then(f=>f.H);return{bootProjects:u}},__vite__mapDeps([1,2]));await o();const{projects:n,activeId:e}=N.getState(),a=n.find(u=>u.id===e);if(!a?.sourceSession)return;const s=$(a);if(s.length===0)return;const c=new Set;for(const u of y.getState().nodes){const f=u.data.importSource?.sessionId;f&&c.add(f)}const m=s.filter(u=>!c.has(u));if(m.length===0)return;for(const u of m)await W(a.id,u);const t=N.getState().projects.find(u=>u.id===a.id)?.sourceSession?"toast.unsubscribed":"toast.unsubscribedNative";Y("info",U(D(t),{n:m.length}),8e3)}async function mt(o,n){const e=o.filter(d=>!!d&&!!d.sessionId);if(e.length===0)return null;const a=n??await z(U(D("atlas.mergedName"),{title:e[0].title.slice(0,24),n:e.length}));await O(a),y.getState().pushHistory();let s=0,c=0;for(const d of e){const t=d.sessionId;if(L(t)){c++;continue}const u=d.build();if(u.nodes.length===0){c++;continue}const f=u.nodes.filter(r=>r.data.importSource),i=y.getState().nodes,h=i.reduce((r,g)=>Math.max(r,g.position.x+(g.width??g.measured?.width??540)),-1/0),w=i.reduce((r,g)=>Math.min(r,g.position.y),1/0),S=Math.min(...u.nodes.map(r=>r.position.x)),x=Math.min(...u.nodes.map(r=>r.position.y)),l=(Number.isFinite(h)?h+180:0)-S,_=(Number.isFinite(w)?w:0)-x,v=u.nodes.map(r=>({...r,position:{x:r.position.x+l,y:r.position.y+_}})),b=new Set(v.map(r=>r.id)),p=u.edges.filter(r=>b.has(r.source)&&b.has(r.target));y.setState(r=>({nodes:[...r.nodes,...v],edges:[...r.edges,...p]})),await M(a,"chapter",{sessionId:t,runner:d.source,importedCount:f.length,tailNodeId:f.at(-1)?.id??v[v.length-1].id}),s++}y.getState().pushHistory();const m=y.getState().nodes.at(-1);return s>0&&m&&j.getState().setArrivalFocusNodeId(m.id),{mounted:s,skipped:c,projectId:a}}export{ut as canvasUniqueness,V as importOrAppendConversation,dt as importOrAppendSession,mt as mergeSessionsIntoProject,ct as mountConversationToProject,at as shellSessionReader,$ as subscribedSessionIds,pt as unsubscribeOrphanedSessions};
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-DbmziCje.js","assets/index-BgFLKHxw.js","assets/index-DEHbIrRr.css","assets/experiment-loop-cKs-OaUA.js"])))=>i.map(i=>d[i]);
2
+ import{c as N,b as y,_ as E,p as q,r as M,h as O,a as D,u as j,j as X,s as B,k as Q,l as z,f as U,m as $,n as W,t as Y,o as F,q as Z,v as tt}from"./index-BgFLKHxw.js";const et=190;async function dt(o){const{anyRunnerSessionConversation:n}=await E(async()=>{const{anyRunnerSessionConversation:a}=await import("./index-DbmziCje.js");return{anyRunnerSessionConversation:a}},__vite__mapDeps([0,1,2])),e=await n(o);return V(e)}function at(o,n){let a=0,s=!1;return async()=>{if(s)return null;const c=await window.desktopSessions.readRange(o,n,a,8388608);return a=c.nextStart,c.eof&&(s=!0),c.text}}function L(o){if(!o)return null;for(const n of N.getState().projects){const e=n.sourceSession;if(!e)continue;if(e.sessionId===o)return{project:n,entry:e};const a=e.chapters?.find(c=>c.sessionId===o);if(a)return{project:n,entry:a};const s=e.branches?.find(c=>c.sessionId===o);if(s)return{project:n,entry:s}}return null}function H(o,n,e,a,s){const c=a.position.x+(s?560:0),m=c-40,d=c+580,t=o.nodes.reduce((w,S)=>{const x=S.width??S.measured?.width??540;if(S.position.x+x<m||S.position.x>d)return w;const l=S.height??S.measured?.height??300;return Math.max(w,S.position.y+l)},s?a.position.y-300:a.position.y+(a.height??140)),u=c-n[0].position.x,f=Math.max(t+et,s?a.position.y:-1/0)-n[0].position.y,i=n.map(w=>({...w,position:{x:w.position.x+u,y:w.position.y+f}})),h=[{id:F(),source:a.id,target:i[0].id,type:"smoothstep"},...e];return{moved:i,edges:h}}async function V(o){if(!o)return null;const n=o.build(),e=n.nodes.filter(m=>m.data.importSource),a=e.at(-1)?.id??n.nodes.at(-1)?.id??"";if(n.nodes.length===0)return null;const s=L(o.sessionId);if(s)return G(o,n,e,a,s);if(o.sessionId){const m=await st(o.sessionId);if(m){let d=-1,t="";if(e.forEach((u,f)=>{const i=u.data.importSource?.itemIds?.[0],h=i?m.byFirstId.get(i):void 0;h&&(d=f,t=h)}),d>=0){await M(m.projectId,"chapter",{sessionId:o.sessionId,runner:o.source,importedCount:d+1,tailNodeId:t});const u=L(o.sessionId);if(u)return G(o,n,e,a,u)}}}if(o.sessionId&&e.length>0){const{parseAnchor:m}=await E(async()=>{const{parseAnchor:t}=await import("./experiment-loop-cKs-OaUA.js");return{parseAnchor:t}},__vite__mapDeps([3,1,2])),d=m(e[0].data.question??"");if(d&&N.getState().projects.some(t=>t.id===d.project)){await O(d.project);const t=y.getState(),u=N.getState().projects.find(i=>i.id===d.project);let f=t.nodes.find(i=>i.id===d.node)??null;if(!f&&d.mode==="continue"&&u.sourceSession?.sessionId){const i=u.sourceSession;f=t.nodes.find(h=>h.id===i.tailNodeId)??t.nodes.filter(h=>h.data.importSource?.sessionId===i.sessionId).at(-1)??null}if(f){const i=n.nodes.find(l=>l.data.importSource&&l.data.stepKind!=="note");if(i&&m(i.data.question??"")){const l=D("exp.openerMark");i.data={...i.data,question:l,source:i.data.source?{...i.data.source,question:l}:i.data.source}}const h=new Set(n.nodes.map(l=>l.id)),w=n.edges.filter(l=>h.has(l.source)&&h.has(l.target)),S=d.mode!=="continue",x=H(t,n.nodes,w,f,S);if(S){const l=x.moved.find(_=>_.data.importSource&&_.data.stepKind!=="note");l&&(l.data={...l.data,isBranch:!0})}return t.pushHistory(),y.setState(l=>({nodes:[...l.nodes,...x.moved],edges:[...l.edges,...x.edges]})),await M(d.project,S?"branch":"chapter",{sessionId:o.sessionId,runner:o.source,importedCount:e.length,tailNodeId:a,anchorNodeId:f.id}),j.getState().setArrivalFocusNodeId(x.moved[x.moved.length-1].id),{kind:"mounted",mode:S?"branch":"continue",turns:e.length}}}}const c=crypto.randomUUID();return await X(q(c),JSON.stringify({state:{nodes:B(n.nodes),edges:n.edges},version:1})),j.getState().setArrivalFocusNodeId(n.nodes[n.nodes.length-1].id),await Q(c,o.title.slice(0,60),"chat",o.sessionId?{sourceSession:{sessionId:o.sessionId,runner:o.source,importedCount:e.length,tailNodeId:a}}:void 0),{kind:"imported",nodeCount:n.nodes.length}}async function ct(o,n){if(!o||!o.sessionId)return null;if(L(o.sessionId))return V(o);const e=o.build(),a=e.nodes.filter(i=>i.data.importSource);if(e.nodes.length===0)return null;await O(n);const s=y.getState(),c=N.getState().projects.find(i=>i.id===n);if(!c)return null;const m=c.sourceSession,d=(m?.sessionId?s.nodes.find(i=>i.id===m.tailNodeId)??s.nodes.filter(i=>i.data.importSource?.sessionId===m.sessionId).at(-1):null)??s.nodes.at(-1)??null;if(!d)return null;const t=new Set(e.nodes.map(i=>i.id)),u=e.edges.filter(i=>t.has(i.source)&&t.has(i.target)),f=H(s,e.nodes,u,d,!1);return s.pushHistory(),y.setState(i=>({nodes:[...i.nodes,...f.moved],edges:[...i.edges,...f.edges]})),await M(n,"chapter",{sessionId:o.sessionId,runner:o.source,importedCount:a.length,tailNodeId:a.at(-1)?.id??e.nodes.at(-1).id,anchorNodeId:d.id}),j.getState().setArrivalFocusNodeId(f.moved[f.moved.length-1].id),{kind:"mounted",mode:"continue",turns:a.length}}async function st(o){const{projects:n,activeId:e}=N.getState(),a=[...n].sort((s,c)=>s.id===e?-1:c.id===e?1:c.updatedAt-s.updatedAt);for(const s of a){if(s.id!==e&&s.provenanceSessions&&!s.provenanceSessions.includes(o))continue;let c;if(s.id===e)c=y.getState().nodes;else try{const{get:d}=await E(async()=>{const{get:f}=await import("./index-BgFLKHxw.js").then(i=>i.D);return{get:f}},__vite__mapDeps([1,2])),t=await d(q(s.id));c=(typeof t=="string"?JSON.parse(t):t)?.state?.nodes??[]}catch{continue}if(s.id!==e&&!s.provenanceSessions){const d=[...new Set(c.map(t=>t.data.importSource?.sessionId).filter(t=>!!t))];N.setState(t=>({projects:t.projects.map(u=>u.id===s.id?{...u,provenanceSessions:d}:u)}))}const m=new Map;for(const d of c)if(d.data.importSource?.sessionId===o&&d.data.stepKind!=="note"){const t=d.data.importSource.itemIds?.[0];t&&m.set(t,d.id)}if(m.size>0)return{projectId:s.id,byFirstId:m}}return null}async function G(o,n,e,a,s){await O(s.project.id);const c=y.getState(),m=c.nodes.filter(p=>p.data.importSource?.sessionId===o.sessionId),d=c.nodes.find(p=>p.id===s.entry.tailNodeId)??m.at(-1)??null,t=s.entry.importedCount>0&&e.length>=s.entry.importedCount?e[s.entry.importedCount-1]:null;if(t){const p=t.data.importSource?.itemIds?.[0],r=p?m.find(C=>C.data.importSource?.itemIds?.[0]===p):void 0,g=r?.data.source,k=!!g&&r.data.question===g.question&&(r.data.response??"")===(g.response??""),I=t.data,K=!!r&&(I.question!==r.data.question||(I.response??"")!==(r.data.response??"")),A=r?.data.attachments??[],T=I.attachments??[],J=!!r&&T.length>A.length&&A.every((C,R)=>T[R]?.name===C.name);if(r&&k&&(K||J)){const C=K?I.attachments:[...A,...T.slice(A.length)];y.setState(R=>({nodes:R.nodes.map(P=>P.id===r.id?{...P,data:{...P.data,question:I.question,response:I.response,responses:I.responses,responseIndex:I.responseIndex,tokenCount:I.tokenCount,attachments:C,importSource:I.importSource,source:I.source}}:P)})),y.getState().recomputeStaleness()}}if(e.length<=s.entry.importedCount)return j.getState().setArrivalFocusNodeId(d?.id??null),{kind:"opened"};const u=e[s.entry.importedCount],f=n.nodes.findIndex(p=>p.id===u.id),i=n.nodes.slice(f),h=new Set(i.map(p=>p.id)),w=n.edges.filter(p=>h.has(p.source)&&h.has(p.target)),S=new Map;for(const p of m){const r=p.data.importSource?.itemIds?.[0];r&&S.set(r,p.id)}const x=new Map;for(const p of n.nodes){const r=p.data.importSource?.itemIds?.[0];r&&!h.has(p.id)&&x.set(p.id,r)}const l=[];for(const p of n.edges){if(!h.has(p.target)||h.has(p.source))continue;const r=x.get(p.source),g=r?S.get(r):void 0;g&&l.push({...p,id:F(),source:g})}const _=new Set(l.map(p=>p.target));let v,b;if(d){const p=H(c,i,w,d,!1);v=p.moved;const r=new Set(w.map(g=>g.target));b=p.edges.filter(g=>!(g.source===d.id&&_.has(g.target)));for(const g of v)g.id!==v[0].id&&!r.has(g.id)&&!_.has(g.id)&&g.data.stepKind!=="note"&&b.push({id:F(),source:d.id,target:g.id,type:"smoothstep"});b=[...b,...l]}else{const r=(c.nodes.length?Math.max(...c.nodes.map(I=>I.position.x)):0)+560-i[0].position.x,g=-i[0].position.y;v=i.map(I=>({...I,position:{x:I.position.x+r,y:I.position.y+g}}));const k=nt(ot(e.length-s.entry.importedCount),v[0]);v=[k,...v],b=[{id:F(),source:k.id,target:v[1].id,type:"smoothstep"},...w]}return c.pushHistory(),y.setState(p=>({nodes:[...p.nodes,...v],edges:[...p.edges,...b]})),await Z(s.project.id,o.sessionId,{importedCount:e.length,tailNodeId:a}),j.getState().setArrivalFocusNodeId(v[d?0:1].id),{kind:"appended",turns:e.length-s.entry.importedCount}}function ot(o){return`[Mirror] The source session grew by ${o} turn(s); the earlier mirrored turns were removed from this canvas by hand, so the new turns land here on their own.`}function nt(o,n){const e=tt(o,"",!1);return e.data.stepKind="note",e.data.importSource=n.data.importSource?{...n.data.importSource,itemIds:[]}:void 0,e.width=460,e.position={x:n.position.x-520,y:n.position.y},e}async function ut(o){const{projects:n,activeId:e}=N.getState(),a=n.find(t=>t.id===o);if(!a?.sourceSession)return"native";if((a.sourceSession.chapters?.length??0)>0||(a.sourceSession.branches?.length??0)>0)return"diverged-mirror";let s;if(o===e)s=y.getState().nodes;else{const{get:t}=await E(async()=>{const{get:f}=await import("./index-BgFLKHxw.js").then(i=>i.D);return{get:f}},__vite__mapDeps([1,2])),u=await t(q(o));try{s=(typeof u=="string"?JSON.parse(u):u)?.state?.nodes??[]}catch{return"diverged-mirror"}}const c=a.sourceSession.sessionId,m=s.filter(t=>t.data.importSource?.sessionId===c);return s.some(t=>!t.data.importSource)||s.some(t=>t.data.importSource&&t.data.importSource.sessionId!==c)||m.filter(t=>t.data.source).length<a.sourceSession.importedCount||m.some(t=>t.data.source&&(t.data.question!==t.data.source.question||t.data.response!==t.data.source.response))?"diverged-mirror":"pristine-mirror"}async function pt(){const{bootProjects:o}=await E(async()=>{const{bootProjects:u}=await import("./index-BgFLKHxw.js").then(f=>f.H);return{bootProjects:u}},__vite__mapDeps([1,2]));await o();const{projects:n,activeId:e}=N.getState(),a=n.find(u=>u.id===e);if(!a?.sourceSession)return;const s=$(a);if(s.length===0)return;const c=new Set;for(const u of y.getState().nodes){const f=u.data.importSource?.sessionId;f&&c.add(f)}const m=s.filter(u=>!c.has(u));if(m.length===0)return;for(const u of m)await W(a.id,u);const t=N.getState().projects.find(u=>u.id===a.id)?.sourceSession?"toast.unsubscribed":"toast.unsubscribedNative";Y("info",U(D(t),{n:m.length}),8e3)}async function mt(o,n){const e=o.filter(d=>!!d&&!!d.sessionId);if(e.length===0)return null;const a=n??await z(U(D("atlas.mergedName"),{title:e[0].title.slice(0,24),n:e.length}));await O(a),y.getState().pushHistory();let s=0,c=0;for(const d of e){const t=d.sessionId;if(L(t)){c++;continue}const u=d.build();if(u.nodes.length===0){c++;continue}const f=u.nodes.filter(r=>r.data.importSource),i=y.getState().nodes,h=i.reduce((r,g)=>Math.max(r,g.position.x+(g.width??g.measured?.width??540)),-1/0),w=i.reduce((r,g)=>Math.min(r,g.position.y),1/0),S=Math.min(...u.nodes.map(r=>r.position.x)),x=Math.min(...u.nodes.map(r=>r.position.y)),l=(Number.isFinite(h)?h+180:0)-S,_=(Number.isFinite(w)?w:0)-x,v=u.nodes.map(r=>({...r,position:{x:r.position.x+l,y:r.position.y+_}})),b=new Set(v.map(r=>r.id)),p=u.edges.filter(r=>b.has(r.source)&&b.has(r.target));y.setState(r=>({nodes:[...r.nodes,...v],edges:[...r.edges,...p]})),await M(a,"chapter",{sessionId:t,runner:d.source,importedCount:f.length,tailNodeId:f.at(-1)?.id??v[v.length-1].id}),s++}y.getState().pushHistory();const m=y.getState().nodes.at(-1);return s>0&&m&&j.getState().setArrivalFocusNodeId(m.id),{mounted:s,skipped:c,projectId:a}}export{ut as canvasUniqueness,V as importOrAppendConversation,dt as importOrAppendSession,mt as mergeSessionsIntoProject,ct as mountConversationToProject,at as shellSessionReader,$ as subscribedSessionIds,pt as unsubscribeOrphanedSessions};
@@ -1 +1 @@
1
- import{b as c,c as p,E as m,s as v,d as w,e as h,g}from"./index-6m02Pb4Q.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 r=u.find(l=>l.id===a),f=JSON.stringify({version:m,name:w(),projectId:a,exportedAt:new Date().toISOString(),record:"thoughtdag-canvas-record",instantiatedFrom:r?.instantiatedFrom,sourceSession:r?.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 i=!1;function E(){i||h||typeof window>"u"||!window.desktopCanvas||(i=!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,e as h,g}from"./index-BgFLKHxw.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 r=u.find(l=>l.id===a),f=JSON.stringify({version:m,name:w(),projectId:a,exportedAt:new Date().toISOString(),record:"thoughtdag-canvas-record",instantiatedFrom:r?.instantiatedFrom,sourceSession:r?.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 i=!1;function E(){i||h||typeof window>"u"||!window.desktopCanvas||(i=!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{v as I,B as g,o as T}from"./index-6m02Pb4Q.js";import{t as C,a as _,r as A,b as x,c as w,d as L,e as v,s as S,f as k,m as O,T as b,A as B,g as M}from"./shared-CURSZnXt.js";const q=16e3;function f(o){return typeof o=="string"?o:Array.isArray(o)?o.filter(t=>t.type==="text"&&t.text).map(t=>t.text).join(`
1
+ import{v as I,B as g,o as T}from"./index-BgFLKHxw.js";import{t as C,a as _,r as A,b as x,c as w,d as L,e as v,s as S,f as k,m as O,T as b,A as B,g as M}from"./shared-0Cyt1YSM.js";const q=16e3;function f(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 N(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 p=v;class ${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 n;try{n=JSON.parse(s)}catch{return}this.feed(n)}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 i=this.pendingTools.get(e.tool_use_id);if(i&&this.current){const a=p(N(e.content),b);this.current.tools.push({name:i.name,call:i.call,result:a.text,truncated:a.truncated,...i.paths.length?{paths:i.paths}:{},op:i.op,nativeCallId:e.tool_use_id,...i.url?{url:i.url}:{},...i.locator?{locator:i.locator}:{}}),this.pendingTools.delete(e.tool_use_id)}}}const n=f(s);if(!n.trim())return;if(/^\s*<task-notification>/.test(n)){if(this.current){const e=p(n,q);this.current.tools.push({name:"Agent",call:"(task notification)",result:e.text,truncated:e.truncated,op:"agent"})}return}this.flush(),this.firstQuestion||(this.firstQuestion=n.trim()),this.current={question:n,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,n=f(s);if(n.trim()&&(this.current.response=this.current.response?`${this.current.response}
4
4
 
@@ -1,4 +1,4 @@
1
- import{v as p,o as d,B as m}from"./index-6m02Pb4Q.js";import{t as y,a as _,d as g,e as I,m as x,f as T,s as C,A as w,g as v,T as A}from"./shared-CURSZnXt.js";function B(n){const t=[];for(const e of n.matchAll(/^\*\*\* (?:Add|Update|Delete) File: (.+)$/gm))t.push(e[1].trim());return t}const h=I,L=n=>(n??[]).filter(t=>t.text&&(t.type==="input_text"||t.type==="output_text"||t.type==="text")).map(t=>t.text).join(`
1
+ import{v as p,o as d,B as m}from"./index-BgFLKHxw.js";import{t as y,a as _,d as g,e as I,m as x,f as T,s as C,A as w,g as v,T as A}from"./shared-0Cyt1YSM.js";function B(n){const t=[];for(const e of n.matchAll(/^\*\*\* (?:Add|Update|Delete) File: (.+)$/gm))t.push(e[1].trim());return t}const h=I,L=n=>(n??[]).filter(t=>t.text&&(t.type==="input_text"||t.type==="output_text"||t.type==="text")).map(t=>t.text).join(`
2
2
  `),S=/^\s*<\/?[a-zA-Z_][\w-]*[^>]*>/,q=n=>S.test(n)||n.trimStart().startsWith("# AGENTS.md instructions for "),O=n=>(n??[]).filter(t=>t.text&&(t.type==="input_text"||t.type==="text")&&!q(t.text)).map(t=>t.text).join(`
3
3
  `),N=n=>typeof n=="string"?n:Array.isArray(n)?n.map(t=>t?.text??"").filter(Boolean).join(`
4
4
  `):n==null?"":JSON.stringify(n);class ${turns=[];pendingCalls=new Map;current=null;pendingCompaction;sessionId=null;cwd="";day="";sawItems=!1;firstQuestion=null;parentThreadId=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;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=O(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{v as T,B as w,o as C}from"./index-6m02Pb4Q.js";import{t as x,a as l,b as f,c as p,e as d,r as g,d as L,T as m,A as h,g as I,f as S,s as A}from"./shared-CURSZnXt.js";function c(o,s=0){return typeof o=="string"?o:!Array.isArray(o)||s>2?"":o.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"?"":c(e.text??e.content,s+1)}).filter(Boolean).join(`
1
+ import{v as T,B as w,o as C}from"./index-BgFLKHxw.js";import{t as x,a as l,b as f,c as p,e as d,r as g,d as L,T as m,A as h,g as I,f as S,s as A}from"./shared-0Cyt1YSM.js";function c(o,s=0){return typeof o=="string"?o:!Array.isArray(o)||s>2?"":o.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"?"":c(e.text??e.content,s+1)}).filter(Boolean).join(`
2
2
  `)}function O(o,s,t){const e=l(o);if(e==="run"||/^run_code$/i.test(o)){const r=t??{};return d(typeof r.code=="string"?r.code:s,h)}const n=t&&typeof t=="object"?g(o,t):s;return d(n,e==="write"||e==="edit"?h:I)}const b=o=>{try{return JSON.parse(o??"")}catch{return}};class q{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){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=c(t.data?.content).trim();if(!n)return;this.firstQuestion||(this.firstQuestion=n.split(`
3
3
  `)[0].slice(0,80)),this.flush();const r=this.ensure();r.question=n,r.itemIds=[t.data?.id??`u${t.seq}`],t.time&&(r.at=new Date(t.time).toISOString());return}if(s.type==="assistant/message"&&this.current){const t=s,e=t.data?.message?.content,n=c(e).trim(),r=t.data?.message?.id;r&&this.current.itemIds.push(r),n&&(this.current.response=this.current.response?`${this.current.response}
4
4
 
@@ -1,2 +1,2 @@
1
- import{a as c,b as l,c as p,x as h,t as u,f as m}from"./index-6m02Pb4Q.js";const b=/\[ThoughtDAG anchor: project=([\w-]+) node=([\w-]+) bundle=([\w-]+)(?: mode=(branch|continue))?\]/;function f(o){const n=o.match(b);return n?{project:n[1],node:n[2],bundle:n[3],mode:n[4]==="continue"?"continue":"branch"}:null}function g(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 l,c as p,x as h,t as u,f as m}from"./index-BgFLKHxw.js";const b=/\[ThoughtDAG anchor: project=([\w-]+) node=([\w-]+) bundle=([\w-]+)(?: mode=(branch|continue))?\]/;function f(o){const n=o.match(b);return n?{project:n[1],node:n[2],bundle:n[3],mode:n[4]==="continue"?"continue":"branch"}:null}function g(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 w(o,n="branch"){const e=l.getState(),s=p.getState().activeId??"default",t=await h(o,e.nodes,e.edges,{now:new Date().toISOString(),projectId:s,staleIds:e.staleIds}),d={project:s,node:o,bundle:t.id,mode:n},i=g(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",m(c("exp.copied"),{n:t.context.messages.length,tok:t.budget.estimated_tokens}),12e3),!0}export{f as parseAnchor,g as renderHandoffMarkdown,w as takeToExperiment};