dsh-thoughtdag 0.4.12 → 0.4.16

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 (24) hide show
  1. package/README.md +11 -6
  2. package/dist-app/assets/{canonical-DccXDqkX.js → canonical-ChxvAi6N.js} +2 -2
  3. package/dist-app/assets/{canvas-record-Dw4tjwhH.js → canvas-record-Be2aKIf8.js} +1 -1
  4. package/dist-app/assets/{claude-code-session-ON4i33o-.js → claude-code-session-B51keZPd.js} +1 -1
  5. package/dist-app/assets/{codex-session-BWQTXLRK.js → codex-session-BR_x_Fzf.js} +1 -1
  6. package/dist-app/assets/{dsh-session-DoRNUaQq.js → dsh-session-D0yZa0_o.js} +1 -1
  7. package/dist-app/assets/{experiment-loop-BuZFR0si.js → experiment-loop-pAs6MwPV.js} +1 -1
  8. package/dist-app/assets/{index-DD461-fW.js → index-962V9CYS.js} +1 -1
  9. package/dist-app/assets/index-C3fERes9.css +1 -0
  10. package/dist-app/assets/{index-DaODh24h.js → index-DvBTIsHr.js} +1 -1
  11. package/dist-app/assets/{index-DwwxoOcO.js → index-JMt9ljo3.js} +149 -149
  12. package/dist-app/assets/{index-CTQSx_k0.js → index-_B6z8_Ff.js} +3 -3
  13. package/dist-app/assets/{live-mirror-D3u92mbO.js → live-mirror-C9sTXAvv.js} +2 -2
  14. package/dist-app/assets/{pi-session-IbIlOArr.js → pi-session-B7frsRRp.js} +1 -1
  15. package/dist-app/assets/{sensitive-scan-C6YN1rzZ.js → sensitive-scan-Cwg4RAEk.js} +1 -1
  16. package/dist-app/assets/{session-handoff-Fpl3jes7.js → session-handoff-BXosSY-e.js} +2 -2
  17. package/dist-app/assets/{shared-DCtLTsEN.js → shared-L3KzXorg.js} +1 -1
  18. package/dist-app/assets/{turndown-plugin-gfm.cjs-CqvfCrbV.js → turndown-plugin-gfm.cjs-pG4f1F8S.js} +1 -1
  19. package/dist-app/assets/{update-check-B1kgBEyl.js → update-check-lHz7ROW6.js} +1 -1
  20. package/dist-app/index.html +2 -2
  21. package/lib/client.js +64 -29
  22. package/lib/why.mjs +84 -0
  23. package/package.json +6 -4
  24. package/dist-app/assets/index-2pggDGtC.css +0 -1
@@ -1,3 +1,3 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/claude-code-session-ON4i33o-.js","assets/index-DwwxoOcO.js","assets/index-2pggDGtC.css","assets/shared-DCtLTsEN.js","assets/codex-session-BWQTXLRK.js","assets/dsh-session-DoRNUaQq.js","assets/pi-session-IbIlOArr.js"])))=>i.map(i=>d[i]);
2
- import{_ as e}from"./index-DwwxoOcO.js";async function S(s){const{claudeCodeSessionConversation:i}=await e(async()=>{const{claudeCodeSessionConversation:o}=await import("./claude-code-session-ON4i33o-.js");return{claudeCodeSessionConversation:o}},__vite__mapDeps([0,1,2,3])),_=i(s);if(_)return _;const{codexSessionConversation:u}=await e(async()=>{const{codexSessionConversation:o}=await import("./codex-session-BWQTXLRK.js");return{codexSessionConversation:o}},__vite__mapDeps([4,1,2,3])),d=u(s);if(d)return d;const{dshSessionConversation:r}=await e(async()=>{const{dshSessionConversation:o}=await import("./dsh-session-DoRNUaQq.js");return{dshSessionConversation:o}},__vite__mapDeps([5,1,2,3])),a=r(s);if(a)return a;const{piSessionConversation:c}=await e(async()=>{const{piSessionConversation:o}=await import("./pi-session-IbIlOArr.js");return{piSessionConversation:o}},__vite__mapDeps([6,1,2,3]));return c(s)}async function E(s){const{ClaudeSessionCollector:i}=await e(async()=>{const{ClaudeSessionCollector:t}=await import("./claude-code-session-ON4i33o-.js");return{ClaudeSessionCollector:t}},__vite__mapDeps([0,1,2,3])),{CodexSessionCollector:_}=await e(async()=>{const{CodexSessionCollector:t}=await import("./codex-session-BWQTXLRK.js");return{CodexSessionCollector:t}},__vite__mapDeps([4,1,2,3])),{DshSessionCollector:u}=await e(async()=>{const{DshSessionCollector:t}=await import("./dsh-session-DoRNUaQq.js");return{DshSessionCollector:t}},__vite__mapDeps([5,1,2,3])),{PiSessionCollector:d}=await e(async()=>{const{PiSessionCollector:t}=await import("./pi-session-IbIlOArr.js");return{PiSessionCollector:t}},__vite__mapDeps([6,1,2,3])),r=new i,a=new _,c=new u,o=new d;let n="";for(let t=await s();t!==null;t=await s()){if(!t)continue;const w=(n+t).split(`
3
- `);n=w.pop()??"";for(const l of w)r.feedLine(l),a.feedLine(l),c.feedLine(l),o.feedLine(l)}return n&&(r.feedLine(n),a.feedLine(n),c.feedLine(n),o.feedLine(n)),r.toConversation()??a.toConversation()??c.toConversation()??o.toConversation()}async function f(s,i){const{claudeCodeSessionAsBranch:_}=await e(async()=>{const{claudeCodeSessionAsBranch:n}=await import("./claude-code-session-ON4i33o-.js");return{claudeCodeSessionAsBranch:n}},__vite__mapDeps([0,1,2,3])),u=_(s,i);if(u)return u;const{codexSessionAsBranch:d}=await e(async()=>{const{codexSessionAsBranch:n}=await import("./codex-session-BWQTXLRK.js");return{codexSessionAsBranch:n}},__vite__mapDeps([4,1,2,3])),r=d(s,i);if(r)return r;const{dshSessionAsBranch:a}=await e(async()=>{const{dshSessionAsBranch:n}=await import("./dsh-session-DoRNUaQq.js");return{dshSessionAsBranch:n}},__vite__mapDeps([5,1,2,3])),c=a(s,i);if(c)return c;const{piSessionAsBranch:o}=await e(async()=>{const{piSessionAsBranch:n}=await import("./pi-session-IbIlOArr.js");return{piSessionAsBranch:n}},__vite__mapDeps([6,1,2,3]));return o(s,i)}export{f as anyRunnerSessionAsBranch,S as anyRunnerSessionConversation,E as streamRunnerConversation};
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/claude-code-session-B51keZPd.js","assets/index-JMt9ljo3.js","assets/index-C3fERes9.css","assets/shared-L3KzXorg.js","assets/codex-session-BR_x_Fzf.js","assets/dsh-session-D0yZa0_o.js","assets/pi-session-B7frsRRp.js"])))=>i.map(i=>d[i]);
2
+ import{_ as e}from"./index-JMt9ljo3.js";async function S(s){const{claudeCodeSessionConversation:i}=await e(async()=>{const{claudeCodeSessionConversation:o}=await import("./claude-code-session-B51keZPd.js");return{claudeCodeSessionConversation:o}},__vite__mapDeps([0,1,2,3])),_=i(s);if(_)return _;const{codexSessionConversation:u}=await e(async()=>{const{codexSessionConversation:o}=await import("./codex-session-BR_x_Fzf.js");return{codexSessionConversation:o}},__vite__mapDeps([4,1,2,3])),d=u(s);if(d)return d;const{dshSessionConversation:r}=await e(async()=>{const{dshSessionConversation:o}=await import("./dsh-session-D0yZa0_o.js");return{dshSessionConversation:o}},__vite__mapDeps([5,1,2,3])),a=r(s);if(a)return a;const{piSessionConversation:c}=await e(async()=>{const{piSessionConversation:o}=await import("./pi-session-B7frsRRp.js");return{piSessionConversation:o}},__vite__mapDeps([6,1,2,3]));return c(s)}async function E(s){const{ClaudeSessionCollector:i}=await e(async()=>{const{ClaudeSessionCollector:t}=await import("./claude-code-session-B51keZPd.js");return{ClaudeSessionCollector:t}},__vite__mapDeps([0,1,2,3])),{CodexSessionCollector:_}=await e(async()=>{const{CodexSessionCollector:t}=await import("./codex-session-BR_x_Fzf.js");return{CodexSessionCollector:t}},__vite__mapDeps([4,1,2,3])),{DshSessionCollector:u}=await e(async()=>{const{DshSessionCollector:t}=await import("./dsh-session-D0yZa0_o.js");return{DshSessionCollector:t}},__vite__mapDeps([5,1,2,3])),{PiSessionCollector:d}=await e(async()=>{const{PiSessionCollector:t}=await import("./pi-session-B7frsRRp.js");return{PiSessionCollector:t}},__vite__mapDeps([6,1,2,3])),r=new i,a=new _,c=new u,o=new d;let n="";for(let t=await s();t!==null;t=await s()){if(!t)continue;const w=(n+t).split(`
3
+ `);n=w.pop()??"";for(const l of w)r.feedLine(l),a.feedLine(l),c.feedLine(l),o.feedLine(l)}return n&&(r.feedLine(n),a.feedLine(n),c.feedLine(n),o.feedLine(n)),r.toConversation()??a.toConversation()??c.toConversation()??o.toConversation()}async function f(s,i){const{claudeCodeSessionAsBranch:_}=await e(async()=>{const{claudeCodeSessionAsBranch:n}=await import("./claude-code-session-B51keZPd.js");return{claudeCodeSessionAsBranch:n}},__vite__mapDeps([0,1,2,3])),u=_(s,i);if(u)return u;const{codexSessionAsBranch:d}=await e(async()=>{const{codexSessionAsBranch:n}=await import("./codex-session-BR_x_Fzf.js");return{codexSessionAsBranch:n}},__vite__mapDeps([4,1,2,3])),r=d(s,i);if(r)return r;const{dshSessionAsBranch:a}=await e(async()=>{const{dshSessionAsBranch:n}=await import("./dsh-session-D0yZa0_o.js");return{dshSessionAsBranch:n}},__vite__mapDeps([5,1,2,3])),c=a(s,i);if(c)return c;const{piSessionAsBranch:o}=await e(async()=>{const{piSessionAsBranch:n}=await import("./pi-session-B7frsRRp.js");return{piSessionAsBranch:n}},__vite__mapDeps([6,1,2,3]));return o(s,i)}export{f as anyRunnerSessionAsBranch,S as anyRunnerSessionConversation,E as streamRunnerConversation};
@@ -1,2 +1,2 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-DwwxoOcO.js","assets/index-2pggDGtC.css","assets/experiment-loop-BuZFR0si.js","assets/index-CTQSx_k0.js","assets/canonical-DccXDqkX.js"])))=>i.map(i=>d[i]);
2
- import{_ as l,i as b,t as p,a as h,f as R}from"./index-DwwxoOcO.js";function K(d,S){return d.find(y=>(y.rel.split("/").pop()??y.rel).includes(S))}let j=!1,I=null;function H(){I?.()}function z(){const d=window.desktopSessions;if(!d||j)return;j=!0,d.watchStart();let S=!1,y=null;const g=async s=>{if(S){y=s;return}S=!0;try{window.dispatchEvent(new CustomEvent("td:sessions-changed"));const{useProjects:a,subscribedSessionIds:i}=await l(async()=>{const{useProjects:w,subscribedSessionIds:E}=await import("./index-DwwxoOcO.js").then(D=>D.H);return{useProjects:w,subscribedSessionIds:E}},__vite__mapDeps([0,1])),{activeId:c,projects:o}=a.getState(),m=o.find(w=>w.id===c),t=await d.head(s.rootKey,s.rel,262144).catch(()=>"");if(!t)return;const e=b(t);if(!e)return;const f=!!m&&i(m).includes(e);let r=null;if(!f){if(o.some(v=>i(v).includes(e)))return;const{useStore:E}=await l(async()=>{const{useStore:v}=await import("./index-DwwxoOcO.js").then(A=>A.G);return{useStore:v}},__vite__mapDeps([0,1]));if(!E.getState().nodes.some(v=>v.data.importSource?.sessionId===e)){const{parseAnchor:v}=await l(async()=>{const{parseAnchor:k}=await import("./experiment-loop-BuZFR0si.js");return{parseAnchor:k}},__vite__mapDeps([2,0,1])),A=v(t);if(!A||!o.some(k=>k.id===A.project))return;if(r=A.project,r!==c){p("info",h("atlas.mountPending"),9e3);return}}}const{streamRunnerConversation:n}=await l(async()=>{const{streamRunnerConversation:w}=await import("./index-CTQSx_k0.js");return{streamRunnerConversation:w}},__vite__mapDeps([3,0,1])),{importOrAppendConversation:u,shellSessionReader:_}=await l(async()=>{const{importOrAppendConversation:w,shellSessionReader:E}=await import("./canonical-DccXDqkX.js");return{importOrAppendConversation:w,shellSessionReader:E}},__vite__mapDeps([4,0,1])),V=await n(_(s.rootKey,s.rel)).catch(()=>null),P=await u(V);P?.kind==="appended"?p("success",R(h("atlas.liveAppended"),{n:P.turns}),8e3):P?.kind==="mounted"&&p("success",R(h(P.mode==="continue"?"atlas.mountedChapter":"atlas.mountedBranch"),{n:P.turns}),9e3)}finally{if(S=!1,y){const a=y;y=null,g(a)}}};d.onSessionsChanged(s=>{g(s)});const C=async s=>{if(!s)return;const{useStore:a}=await l(async()=>{const{useStore:o}=await import("./index-DwwxoOcO.js").then(m=>m.G);return{useStore:o}},__vite__mapDeps([0,1])),{useUiStore:i}=await l(async()=>{const{useUiStore:o}=await import("./index-DwwxoOcO.js").then(m=>m.D);return{useUiStore:o}},__vite__mapDeps([0,1])),c=a.getState().nodes.find(o=>o.data.importSource?.itemIds?.includes(s));c&&i.getState().setArrivalFocusNodeId(c.id)},T=async(s,a)=>{const{useProjects:i,switchProject:c}=await l(async()=>{const{useProjects:e,switchProject:f}=await import("./index-DwwxoOcO.js").then(r=>r.H);return{useProjects:e,switchProject:f}},__vite__mapDeps([0,1])),o=i.getState().projects,m=o.filter(e=>e.name===s),t=o.find(e=>e.id===s)??(m.length===1?m[0]:void 0);if(!t){p("error",h("handoff.deeplinkMiss"));return}if(await c(t.id),a){const{useStore:e}=await l(async()=>{const{useStore:r}=await import("./index-DwwxoOcO.js").then(n=>n.G);return{useStore:r}},__vite__mapDeps([0,1])),{useUiStore:f}=await l(async()=>{const{useUiStore:r}=await import("./index-DwwxoOcO.js").then(n=>n.D);return{useUiStore:r}},__vite__mapDeps([0,1]));e.getState().nodes.some(r=>r.id===a)&&f.getState().setArrivalFocusNodeId(a)}},O=async s=>{let a="",i="";try{const n=new URL(s),u=n.searchParams.get("canvas");if(u){await T(u,n.searchParams.get("node")??"");return}a=n.searchParams.get("session")??"",i=n.searchParams.get("turn")??""}catch{return}if(!/^[A-Za-z0-9_-]{8,}$/.test(a))return;/^[A-Za-z0-9_-]*$/.test(i)||(i="");const c=await d.roots().catch(()=>[]);let o=null;for(const n of c){const u=await d.list(n.key).catch(()=>[]),_=K(u,a);if(_){o={rootKey:n.key,rel:_.rel};break}}if(!o){const n=[];for(const u of c)for(const _ of await d.list(u.key).catch(()=>[]))n.push({rootKey:u.key,rel:_.rel,mtime:_.mtime});n.sort((u,_)=>_.mtime-u.mtime);for(const u of n.slice(0,40)){const _=await d.head(u.rootKey,u.rel,262144).catch(()=>"");if(_&&b(_)===a){o=u;break}}}if(!o){p("error",h("handoff.deeplinkMiss"));return}const{streamRunnerConversation:m}=await l(async()=>{const{streamRunnerConversation:n}=await import("./index-CTQSx_k0.js");return{streamRunnerConversation:n}},__vite__mapDeps([3,0,1])),{importOrAppendConversation:t,shellSessionReader:e}=await l(async()=>{const{importOrAppendConversation:n,shellSessionReader:u}=await import("./canonical-DccXDqkX.js");return{importOrAppendConversation:n,shellSessionReader:u}},__vite__mapDeps([4,0,1])),f=await m(e(o.rootKey,o.rel)).catch(()=>null),r=await t(f);r?r.kind==="appended"?p("success",R(h("atlas.liveAppended"),{n:r.turns}),8e3):r.kind==="mounted"?p("success",R(h(r.mode==="continue"?"atlas.mountedChapter":"atlas.mountedBranch"),{n:r.turns}),9e3):r.kind==="imported"&&p("success",R(h("toast.importedChats"),{n:1,m:r.nodeCount}),8e3):p("error",h("handoff.notASession")),r&&i&&await C(i)};d.onDeepLink?.(s=>{O(s)}),(async()=>{const{bootProjects:s}=await l(async()=>{const{bootProjects:i}=await import("./index-DwwxoOcO.js").then(c=>c.H);return{bootProjects:i}},__vite__mapDeps([0,1]));await s();const a=await d.pendingDeepLink?.().catch(()=>null);a&&O(a)})();const L="thoughtdag.atlas.sweepmark";I=async()=>{const{bootProjects:s}=await l(async()=>{const{bootProjects:t}=await import("./index-DwwxoOcO.js").then(e=>e.H);return{bootProjects:t}},__vite__mapDeps([0,1]));await s();const a=await d.roots().catch(()=>[]),i=[];for(const t of a){const e=await d.list(t.key).catch(()=>[]);for(const f of e)i.push({rootKey:t.key,rel:f.rel,mtime:f.mtime,size:f.size})}let c={};try{c=JSON.parse(localStorage.getItem(L)??"{}")}catch{}const o=Object.keys(c).length===0;i.sort((t,e)=>e.mtime-t.mtime);const m=i.filter((t,e)=>{const f=`${t.mtime}|${t.size}`;return c[`${t.rootKey}|${t.rel}`]===f?!1:o?e<30:!0});for(const t of m)await g({rootKey:t.rootKey,rel:t.rel});for(const t of i)c[`${t.rootKey}|${t.rel}`]=`${t.mtime}|${t.size}`;localStorage.setItem(L,JSON.stringify(c))},I()}export{K as pickSessionFile,z as startLiveMirror,H as sweepRecentSessions};
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-JMt9ljo3.js","assets/index-C3fERes9.css","assets/experiment-loop-pAs6MwPV.js","assets/index-_B6z8_Ff.js","assets/canonical-ChxvAi6N.js"])))=>i.map(i=>d[i]);
2
+ import{_ as l,i as b,t as p,a as h,f as R}from"./index-JMt9ljo3.js";function K(d,S){return d.find(y=>(y.rel.split("/").pop()??y.rel).includes(S))}let j=!1,I=null;function H(){I?.()}function z(){const d=window.desktopSessions;if(!d||j)return;j=!0,d.watchStart();let S=!1,y=null;const g=async s=>{if(S){y=s;return}S=!0;try{window.dispatchEvent(new CustomEvent("td:sessions-changed"));const{useProjects:a,subscribedSessionIds:i}=await l(async()=>{const{useProjects:w,subscribedSessionIds:E}=await import("./index-JMt9ljo3.js").then(D=>D.H);return{useProjects:w,subscribedSessionIds:E}},__vite__mapDeps([0,1])),{activeId:c,projects:o}=a.getState(),m=o.find(w=>w.id===c),t=await d.head(s.rootKey,s.rel,262144).catch(()=>"");if(!t)return;const e=b(t);if(!e)return;const f=!!m&&i(m).includes(e);let r=null;if(!f){if(o.some(v=>i(v).includes(e)))return;const{useStore:E}=await l(async()=>{const{useStore:v}=await import("./index-JMt9ljo3.js").then(A=>A.G);return{useStore:v}},__vite__mapDeps([0,1]));if(!E.getState().nodes.some(v=>v.data.importSource?.sessionId===e)){const{parseAnchor:v}=await l(async()=>{const{parseAnchor:k}=await import("./experiment-loop-pAs6MwPV.js");return{parseAnchor:k}},__vite__mapDeps([2,0,1])),A=v(t);if(!A||!o.some(k=>k.id===A.project))return;if(r=A.project,r!==c){p("info",h("atlas.mountPending"),9e3);return}}}const{streamRunnerConversation:n}=await l(async()=>{const{streamRunnerConversation:w}=await import("./index-_B6z8_Ff.js");return{streamRunnerConversation:w}},__vite__mapDeps([3,0,1])),{importOrAppendConversation:u,shellSessionReader:_}=await l(async()=>{const{importOrAppendConversation:w,shellSessionReader:E}=await import("./canonical-ChxvAi6N.js");return{importOrAppendConversation:w,shellSessionReader:E}},__vite__mapDeps([4,0,1])),V=await n(_(s.rootKey,s.rel)).catch(()=>null),P=await u(V);P?.kind==="appended"?p("success",R(h("atlas.liveAppended"),{n:P.turns}),8e3):P?.kind==="mounted"&&p("success",R(h(P.mode==="continue"?"atlas.mountedChapter":"atlas.mountedBranch"),{n:P.turns}),9e3)}finally{if(S=!1,y){const a=y;y=null,g(a)}}};d.onSessionsChanged(s=>{g(s)});const C=async s=>{if(!s)return;const{useStore:a}=await l(async()=>{const{useStore:o}=await import("./index-JMt9ljo3.js").then(m=>m.G);return{useStore:o}},__vite__mapDeps([0,1])),{useUiStore:i}=await l(async()=>{const{useUiStore:o}=await import("./index-JMt9ljo3.js").then(m=>m.D);return{useUiStore:o}},__vite__mapDeps([0,1])),c=a.getState().nodes.find(o=>o.data.importSource?.itemIds?.includes(s));c&&i.getState().setArrivalFocusNodeId(c.id)},T=async(s,a)=>{const{useProjects:i,switchProject:c}=await l(async()=>{const{useProjects:e,switchProject:f}=await import("./index-JMt9ljo3.js").then(r=>r.H);return{useProjects:e,switchProject:f}},__vite__mapDeps([0,1])),o=i.getState().projects,m=o.filter(e=>e.name===s),t=o.find(e=>e.id===s)??(m.length===1?m[0]:void 0);if(!t){p("error",h("handoff.deeplinkMiss"));return}if(await c(t.id),a){const{useStore:e}=await l(async()=>{const{useStore:r}=await import("./index-JMt9ljo3.js").then(n=>n.G);return{useStore:r}},__vite__mapDeps([0,1])),{useUiStore:f}=await l(async()=>{const{useUiStore:r}=await import("./index-JMt9ljo3.js").then(n=>n.D);return{useUiStore:r}},__vite__mapDeps([0,1]));e.getState().nodes.some(r=>r.id===a)&&f.getState().setArrivalFocusNodeId(a)}},O=async s=>{let a="",i="";try{const n=new URL(s),u=n.searchParams.get("canvas");if(u){await T(u,n.searchParams.get("node")??"");return}a=n.searchParams.get("session")??"",i=n.searchParams.get("turn")??""}catch{return}if(!/^[A-Za-z0-9_-]{8,}$/.test(a))return;/^[A-Za-z0-9_-]*$/.test(i)||(i="");const c=await d.roots().catch(()=>[]);let o=null;for(const n of c){const u=await d.list(n.key).catch(()=>[]),_=K(u,a);if(_){o={rootKey:n.key,rel:_.rel};break}}if(!o){const n=[];for(const u of c)for(const _ of await d.list(u.key).catch(()=>[]))n.push({rootKey:u.key,rel:_.rel,mtime:_.mtime});n.sort((u,_)=>_.mtime-u.mtime);for(const u of n.slice(0,40)){const _=await d.head(u.rootKey,u.rel,262144).catch(()=>"");if(_&&b(_)===a){o=u;break}}}if(!o){p("error",h("handoff.deeplinkMiss"));return}const{streamRunnerConversation:m}=await l(async()=>{const{streamRunnerConversation:n}=await import("./index-_B6z8_Ff.js");return{streamRunnerConversation:n}},__vite__mapDeps([3,0,1])),{importOrAppendConversation:t,shellSessionReader:e}=await l(async()=>{const{importOrAppendConversation:n,shellSessionReader:u}=await import("./canonical-ChxvAi6N.js");return{importOrAppendConversation:n,shellSessionReader:u}},__vite__mapDeps([4,0,1])),f=await m(e(o.rootKey,o.rel)).catch(()=>null),r=await t(f);r?r.kind==="appended"?p("success",R(h("atlas.liveAppended"),{n:r.turns}),8e3):r.kind==="mounted"?p("success",R(h(r.mode==="continue"?"atlas.mountedChapter":"atlas.mountedBranch"),{n:r.turns}),9e3):r.kind==="imported"&&p("success",R(h("toast.importedChats"),{n:1,m:r.nodeCount}),8e3):p("error",h("handoff.notASession")),r&&i&&await C(i)};d.onDeepLink?.(s=>{O(s)}),(async()=>{const{bootProjects:s}=await l(async()=>{const{bootProjects:i}=await import("./index-JMt9ljo3.js").then(c=>c.H);return{bootProjects:i}},__vite__mapDeps([0,1]));await s();const a=await d.pendingDeepLink?.().catch(()=>null);a&&O(a)})();const L="thoughtdag.atlas.sweepmark";I=async()=>{const{bootProjects:s}=await l(async()=>{const{bootProjects:t}=await import("./index-JMt9ljo3.js").then(e=>e.H);return{bootProjects:t}},__vite__mapDeps([0,1]));await s();const a=await d.roots().catch(()=>[]),i=[];for(const t of a){const e=await d.list(t.key).catch(()=>[]);for(const f of e)i.push({rootKey:t.key,rel:f.rel,mtime:f.mtime,size:f.size})}let c={};try{c=JSON.parse(localStorage.getItem(L)??"{}")}catch{}const o=Object.keys(c).length===0;i.sort((t,e)=>e.mtime-t.mtime);const m=i.filter((t,e)=>{const f=`${t.mtime}|${t.size}`;return c[`${t.rootKey}|${t.rel}`]===f?!1:o?e<30:!0});for(const t of m)await g({rootKey:t.rootKey,rel:t.rel});for(const t of i)c[`${t.rootKey}|${t.rel}`]=`${t.mtime}|${t.size}`;localStorage.setItem(L,JSON.stringify(c))},I()}export{K as pickSessionFile,z as startLiveMirror,H as sweepRecentSessions};
@@ -1,4 +1,4 @@
1
- import{v as w,B as x,o as T}from"./index-DwwxoOcO.js";import{t as A,a as I,e as l,d as C,T as L,A as h,g as m,f as O,s as S}from"./shared-DCtLTsEN.js";const f=r=>typeof r=="string"?r:Array.isArray(r)?r.filter(t=>t&&t.type==="text"&&typeof t.text=="string").map(t=>t.text).join(`
1
+ import{v as w,B as x,o as T}from"./index-JMt9ljo3.js";import{t as A,a as I,e as l,d as C,T as L,A as h,g as m,f as O,s as S}from"./shared-L3KzXorg.js";const f=r=>typeof r=="string"?r:Array.isArray(r)?r.filter(t=>t&&t.type==="text"&&typeof t.text=="string").map(t=>t.text).join(`
2
2
  `):"";function b(r,t){const s=t&&typeof t=="object"?t:{},e=I(r),n=typeof s.path=="string"&&s.path&&(e==="read"||e==="edit"||e==="write")?[s.path]:[];let o;if(e==="read"&&(typeof s.offset=="number"||typeof s.limit=="number")){const c=Math.max(1,typeof s.offset=="number"?s.offset:1),d=typeof s.limit=="number"?c+Math.max(0,s.limit)-1:c;o={lines:[c,Math.max(c,d)]}}if(e==="write"&&typeof s.content=="string")return{...l(`${s.path??""}
3
3
 
4
4
  ${s.content}`,h),paths:n};if(e==="edit"){const c=Array.isArray(s.edits)?s.edits:typeof s.newText=="string"?[{oldText:s.oldText,newText:s.newText}]:[];if(c.length){const d=c.map(i=>`${s.path??""}
@@ -1,4 +1,4 @@
1
- import{f as c,a,w as g}from"./index-DwwxoOcO.js";const k=[{kind:"sk-… key",re:/\bsk-[A-Za-z0-9_-]{16,}\b/g},{kind:"GitHub token",re:/\bgh[pousr]_[A-Za-z0-9]{20,}\b/g},{kind:"AWS access key",re:/\bAKIA[0-9A-Z]{16}\b/g},{kind:"Slack token",re:/\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g},{kind:"Google API key",re:/\bAIza[0-9A-Za-z_-]{35}\b/g},{kind:"JWT",re:/\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{6,}\b/g},{kind:"private key block",re:/-----BEGIN [A-Z ]*PRIVATE KEY-----/g},{kind:"token assignment",re:/\b(?:API_KEY|APIKEY|SECRET|TOKEN|PASSWORD|ACCESS_KEY|AUTH_TOKEN)[A-Z_]*\s*[=:]\s*['"]?[A-Za-z0-9_/+-]{16,}/g},{kind:"HuggingFace token",re:/\bhf_[A-Za-z0-9]{30,}\b/g},{kind:"npm token",re:/\bnpm_[A-Za-z0-9]{30,}\b/g}],f=t=>t.length<=10?`${t.slice(0,4)}…`:`${t.slice(0,6)}…${t.slice(-2)}`;function o(t,e,s){if(t)for(const{kind:i,re:n}of k){n.lastIndex=0;const r=n.exec(t);if(r&&s.push({where:e,kind:i,sample:f(r[0])}),s.length>=20)return}}function l(t){const e=[];for(const s of t){const i=(s.data.question||s.data.summaries?.[0]||s.id).replace(/\s+/g," ").slice(0,28);o(s.data.question,i,e);for(const n of s.data.responses??[])o(n,i,e);for(const n of s.data.attachments??[])n.type.startsWith("image/")||o(n.content,`${i} · ${n.name}`,e);if(e.length>=20)break}return e}async function b(t){const e=l(t);if(e.length===0)return!0;const s=e.slice(0,5).map(n=>`· ${n.where} — ${n.kind}(${n.sample})`).join(`
1
+ import{f as c,a,w as g}from"./index-JMt9ljo3.js";const k=[{kind:"sk-… key",re:/\bsk-[A-Za-z0-9_-]{16,}\b/g},{kind:"GitHub token",re:/\bgh[pousr]_[A-Za-z0-9]{20,}\b/g},{kind:"AWS access key",re:/\bAKIA[0-9A-Z]{16}\b/g},{kind:"Slack token",re:/\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g},{kind:"Google API key",re:/\bAIza[0-9A-Za-z_-]{35}\b/g},{kind:"JWT",re:/\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{6,}\b/g},{kind:"private key block",re:/-----BEGIN [A-Z ]*PRIVATE KEY-----/g},{kind:"token assignment",re:/\b(?:API_KEY|APIKEY|SECRET|TOKEN|PASSWORD|ACCESS_KEY|AUTH_TOKEN)[A-Z_]*\s*[=:]\s*['"]?[A-Za-z0-9_/+-]{16,}/g},{kind:"HuggingFace token",re:/\bhf_[A-Za-z0-9]{30,}\b/g},{kind:"npm token",re:/\bnpm_[A-Za-z0-9]{30,}\b/g}],f=t=>t.length<=10?`${t.slice(0,4)}…`:`${t.slice(0,6)}…${t.slice(-2)}`;function o(t,e,s){if(t)for(const{kind:i,re:n}of k){n.lastIndex=0;const r=n.exec(t);if(r&&s.push({where:e,kind:i,sample:f(r[0])}),s.length>=20)return}}function l(t){const e=[];for(const s of t){const i=(s.data.question||s.data.summaries?.[0]||s.id).replace(/\s+/g," ").slice(0,28);o(s.data.question,i,e);for(const n of s.data.responses??[])o(n,i,e);for(const n of s.data.attachments??[])n.type.startsWith("image/")||o(n.content,`${i} · ${n.name}`,e);if(e.length>=20)break}return e}async function b(t){const e=l(t);if(e.length===0)return!0;const s=e.slice(0,5).map(n=>`· ${n.where} — ${n.kind}(${n.sample})`).join(`
2
2
  `),i=e.length>5?`
3
3
  ${c(a("sensitive.more"),{n:e.length-5})}`:"";return g({title:a("sensitive.title"),message:`${c(a("sensitive.body"),{n:e.length})}
4
4
 
@@ -1,2 +1,2 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/canonical-DccXDqkX.js","assets/index-DwwxoOcO.js","assets/index-2pggDGtC.css"])))=>i.map(i=>d[i]);
2
- import{t as n,a as e,_ as p,f as a,u as h}from"./index-DwwxoOcO.js";const l=/^http:\/\/(127\.0\.0\.1|localhost|\[::1\])(:\d+)?\//i;async function w(){const s=window.location.hash,r=s.match(/[#&]import-url=([^&]+)/);if(!r)return;const c=/[#&]mode=harvest\b/.test(s);history.replaceState(null,"",window.location.pathname+window.location.search);const i=decodeURIComponent(r[1]);if(!l.test(i)){n("error",e("handoff.notLoopback"),9e3);return}try{const o=await fetch(i);if(!o.ok)throw new Error(`HTTP ${o.status}`);const d=await o.text(),{importOrAppendSession:f}=await p(async()=>{const{importOrAppendSession:u}=await import("./canonical-DccXDqkX.js");return{importOrAppendSession:u}},__vite__mapDeps([0,1,2])),t=await f(d);if(!t)throw new Error(e("handoff.notASession"));t.kind==="appended"?n("success",a(e("atlas.appended"),{n:t.turns}),9e3):t.kind==="mounted"?n("success",a(e(t.mode==="continue"?"atlas.mountedChapter":"atlas.mountedBranch"),{n:t.turns}),12e3):t.kind==="opened"?n("info",e("atlas.upToDate"),6e3):n("info",a(e("handoff.saved"),{n:t.nodeCount}),12e3,{label:e("handoff.backupAction"),run:()=>h.getState().setBackupDialogOpen(!0)})}catch(o){n("error",a(e("handoff.failed"),{msg:o instanceof Error?o.message:String(o)}),12e3)}}export{w as consumeSessionHandoff};
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/canonical-ChxvAi6N.js","assets/index-JMt9ljo3.js","assets/index-C3fERes9.css"])))=>i.map(i=>d[i]);
2
+ import{t as n,a as e,_ as p,f as a,u as h}from"./index-JMt9ljo3.js";const l=/^http:\/\/(127\.0\.0\.1|localhost|\[::1\])(:\d+)?\//i;async function w(){const s=window.location.hash,r=s.match(/[#&]import-url=([^&]+)/);if(!r)return;const c=/[#&]mode=harvest\b/.test(s);history.replaceState(null,"",window.location.pathname+window.location.search);const i=decodeURIComponent(r[1]);if(!l.test(i)){n("error",e("handoff.notLoopback"),9e3);return}try{const o=await fetch(i);if(!o.ok)throw new Error(`HTTP ${o.status}`);const d=await o.text(),{importOrAppendSession:f}=await p(async()=>{const{importOrAppendSession:u}=await import("./canonical-ChxvAi6N.js");return{importOrAppendSession:u}},__vite__mapDeps([0,1,2])),t=await f(d);if(!t)throw new Error(e("handoff.notASession"));t.kind==="appended"?n("success",a(e("atlas.appended"),{n:t.turns}),9e3):t.kind==="mounted"?n("success",a(e(t.mode==="continue"?"atlas.mountedChapter":"atlas.mountedBranch"),{n:t.turns}),12e3):t.kind==="opened"?n("info",e("atlas.upToDate"),6e3):n("info",a(e("handoff.saved"),{n:t.nodeCount}),12e3,{label:e("handoff.backupAction"),run:()=>h.getState().setBackupDialogOpen(!0)})}catch(o){n("error",a(e("handoff.failed"),{msg:o instanceof Error?o.message:String(o)}),12e3)}}export{w as consumeSessionHandoff};
@@ -1,4 +1,4 @@
1
- import{v as m,o as p,B as h,C as g}from"./index-DwwxoOcO.js";const _=[[/^(Read|NotebookRead|read_file|view_image)$/i,"read"],[/^(Write|write_file)$/i,"write"],[/^(Edit|MultiEdit|NotebookEdit|apply_patch)$/i,"edit"],[/^(Bash|BashOutput|Shell|exec_command|local_shell|write_stdin)$/i,"run"],[/^(Grep|Glob|LS|Search|WebSearch|web_search)$/i,"search"],[/^(WebFetch|Fetch)$/i,"fetch"],[/^(Task|Agent)$/i,"agent"]];function y(e){return _.find(([t])=>t.test(e))?.[1]??"other"}const x=800,O=32e3,S=4e3,I=(e,t)=>e.length>t?{text:`${e.slice(0,t)}
1
+ import{v as m,o as p,B as h,C as g}from"./index-JMt9ljo3.js";const _=[[/^(Read|NotebookRead|read_file|view_image)$/i,"read"],[/^(Write|write_file)$/i,"write"],[/^(Edit|MultiEdit|NotebookEdit|apply_patch)$/i,"edit"],[/^(Bash|BashOutput|Shell|exec_command|local_shell|write_stdin)$/i,"run"],[/^(Grep|Glob|LS|Search|WebSearch|web_search)$/i,"search"],[/^(WebFetch|Fetch)$/i,"fetch"],[/^(Task|Agent)$/i,"agent"]];function y(e){return _.find(([t])=>t.test(e))?.[1]??"other"}const x=800,O=32e3,S=4e3,I=(e,t)=>e.length>t?{text:`${e.slice(0,t)}
2
2
  …[truncated, ${e.length} chars total]`,truncated:!0}:{text:e,truncated:!1},$=["<command-name>/thoughtdag</command-name>","[[thoughtdag:command]]"];function M(e){return e.filter(t=>!$.some(n=>t.question.includes(n)))}function w(e){e.width=460}function b(e){const t=g(e.data.response,90);t&&(e.data.summaries=[t])}function L(e){return e.tools.map(t=>({id:p(),name:`tool: ${t.name}${t.truncated?" (truncated)":""}`,type:"text/plain",size:t.call.length+t.result.length,content:`[call] ${t.call}
3
3
  [result]
4
4
  ${t.result}`,...t.paths?.length?{paths:t.paths}:{},...t.op?{op:t.op}:{}}))}function k(e,t,n,s,i){if(e.length===0)return null;const r=[],l=[];let u={id:s.id};for(const o of e){const a=m(o.question||"(tool-only turn)",o.response,!1);a.data.importSource={runner:n,sessionId:t,itemIds:o.itemIds,...i?{cwd:i}:{}},a.data.source={question:a.data.question,response:a.data.response},a.data.attachments=L(o),b(a),r.length===0&&(a.data.isBranch=!0),r.push(a),l.push({id:p(),source:u.id,target:a.id,type:"smoothstep"}),u=a}const c=h(r,l.filter(o=>o.source!==s.id)),f=Math.min(...c.map(o=>o.position.x)),d=Math.min(...c.map(o=>o.position.y));for(const o of c)o.position={x:o.position.x-f+s.x+560,y:o.position.y-d+s.y};return{nodes:c,edges:l,turnCount:e.length}}function A(e){const t=e??{},n={};typeof t.url=="string"&&/^https?:\/\//.test(t.url)&&(n.url=t.url);const s={};if(typeof t.pages=="string"&&t.pages.trim()&&(s.pages=t.pages.trim()),typeof t.offset=="number"||typeof t.limit=="number"){const i=Math.max(1,typeof t.offset=="number"?t.offset:1),r=typeof t.limit=="number"?i+Math.max(0,t.limit)-1:i;s.lines=[i,Math.max(i,r)]}return Object.keys(s).length&&(n.locator=s),n}function C(e){const t=e??{},n=t.file_path??t.notebook_path;return typeof n=="string"&&n?[n]:[]}function q(e,t){const n=t??{},s=y(e);return s==="write"&&typeof n.content=="string"?`${n.file_path??""}
@@ -1,4 +1,4 @@
1
- import{A as W}from"./index-DwwxoOcO.js";function Y(d,p){for(var g=0;g<p.length;g++){const s=p[g];if(typeof s!="string"&&!Array.isArray(s)){for(const c in s)if(c!=="default"&&!(c in d)){const o=Object.getOwnPropertyDescriptor(s,c);o&&Object.defineProperty(d,c,o.get?o:{enumerable:!0,get:()=>s[c]})}}}return Object.freeze(Object.defineProperty(d,Symbol.toStringTag,{value:"Module"}))}var u={},E;function J(){if(E)return u;E=1,Object.defineProperty(u,"__esModule",{value:!0});var d=/highlight-(?:text|source)-([a-z0-9]+)/;function p(t){t.addRule("highlightedCodeBlock",{filter:function(e){var r=e.firstChild;return e.nodeName==="DIV"&&d.test(e.className)&&r&&r.nodeName==="PRE"},replacement:function(e,r,n){var l=r.className||"",i=(l.match(d)||[null,""])[1];return`
1
+ import{A as W}from"./index-JMt9ljo3.js";function Y(d,p){for(var g=0;g<p.length;g++){const s=p[g];if(typeof s!="string"&&!Array.isArray(s)){for(const c in s)if(c!=="default"&&!(c in d)){const o=Object.getOwnPropertyDescriptor(s,c);o&&Object.defineProperty(d,c,o.get?o:{enumerable:!0,get:()=>s[c]})}}}return Object.freeze(Object.defineProperty(d,Symbol.toStringTag,{value:"Module"}))}var u={},E;function J(){if(E)return u;E=1,Object.defineProperty(u,"__esModule",{value:!0});var d=/highlight-(?:text|source)-([a-z0-9]+)/;function p(t){t.addRule("highlightedCodeBlock",{filter:function(e){var r=e.firstChild;return e.nodeName==="DIV"&&d.test(e.className)&&r&&r.nodeName==="PRE"},replacement:function(e,r,n){var l=r.className||"",i=(l.match(d)||[null,""])[1];return`
2
2
 
3
3
  `+n.fence+i+`
4
4
  `+r.firstChild.textContent+`
@@ -1 +1 @@
1
- import{t as u,a as n,f}from"./index-DwwxoOcO.js";const h=15*6e4;let i=!1;const d=new URLSearchParams(window.location.search),s=d.get("dv"),p=d.get("su")==="1",w=30*6e4;let c=!1,r=0;async function a(){if(!(!s||p||c)&&!(Date.now()-r<w)){r=Date.now();try{const t=await fetch("https://api.github.com/repos/chenxiachan/thoughtdag/releases?per_page=1");if(!t.ok)return;const o=(await t.json())?.[0]?.tag_name?.replace(/^v/,"");if(!o||o===s)return;c=!0,u("info",f(n("update.desktopAvailable"),{v:o}),0,{label:n("update.desktopDownload"),run:()=>window.open("https://chenxiachan.github.io/thoughtdag/#download","_blank")})}catch{}}}function v(){for(const t of document.querySelectorAll("script[src]")){const e=t.src.match(/assets\/index-[^/?#]+\.js/);if(e)return e[0]}return null}async function m(){try{const t=await fetch(`${window.location.pathname}?u=${Date.now()}`,{cache:"no-store"});if(!t.ok)return null;const e=(await t.text()).match(/assets\/index-[^"'?#]+\.js/);return e?e[0]:null}catch{return null}}async function l(){if(i)return;const t=v();if(!t)return;const e=await m();e&&e!==t&&(i=!0,u("info",n("update.available"),0,{label:n("update.refresh"),run:()=>window.location.reload()}))}function b(){document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&(l(),a())}),setInterval(()=>{l(),a()},h),s&&setTimeout(()=>{a()},5e3)}export{b as bootUpdateCheck};
1
+ import{t as u,a as n,f}from"./index-JMt9ljo3.js";const h=15*6e4;let i=!1;const d=new URLSearchParams(window.location.search),s=d.get("dv"),p=d.get("su")==="1",w=30*6e4;let c=!1,r=0;async function a(){if(!(!s||p||c)&&!(Date.now()-r<w)){r=Date.now();try{const t=await fetch("https://api.github.com/repos/chenxiachan/thoughtdag/releases?per_page=1");if(!t.ok)return;const o=(await t.json())?.[0]?.tag_name?.replace(/^v/,"");if(!o||o===s)return;c=!0,u("info",f(n("update.desktopAvailable"),{v:o}),0,{label:n("update.desktopDownload"),run:()=>window.open("https://chenxiachan.github.io/thoughtdag/#download","_blank")})}catch{}}}function v(){for(const t of document.querySelectorAll("script[src]")){const e=t.src.match(/assets\/index-[^/?#]+\.js/);if(e)return e[0]}return null}async function m(){try{const t=await fetch(`${window.location.pathname}?u=${Date.now()}`,{cache:"no-store"});if(!t.ok)return null;const e=(await t.text()).match(/assets\/index-[^"'?#]+\.js/);return e?e[0]:null}catch{return null}}async function l(){if(i)return;const t=v();if(!t)return;const e=await m();e&&e!==t&&(i=!0,u("info",n("update.available"),0,{label:n("update.refresh"),run:()=>window.location.reload()}))}function b(){document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&(l(),a())}),setInterval(()=>{l(),a()},h),s&&setTimeout(()=>{a()},5e3)}export{b as bootUpdateCheck};
@@ -22,8 +22,8 @@
22
22
  <meta name="twitter:title" content="ThoughtDAG — Your thinking deserves a map" />
23
23
  <meta name="twitter:description" content="Wires are the context: an infinite canvas where LLM conversations grow into an editable thought graph. No signup; the example canvas needs no key." />
24
24
  <meta name="twitter:image" content="https://app.thoughtdag.workers.dev/og-twitter.jpg" />
25
- <script type="module" crossorigin src="/thoughtdag/assets/index-DwwxoOcO.js"></script>
26
- <link rel="stylesheet" crossorigin href="/thoughtdag/assets/index-2pggDGtC.css">
25
+ <script type="module" crossorigin src="/thoughtdag/assets/index-JMt9ljo3.js"></script>
26
+ <link rel="stylesheet" crossorigin href="/thoughtdag/assets/index-C3fERes9.css">
27
27
  </head>
28
28
  <body>
29
29
  <div id="root"></div>
package/lib/client.js CHANGED
@@ -1,21 +1,26 @@
1
1
  // dsh-thoughtdag client half — the lightest possible browser shim.
2
- // It renders a floating "对话 | 思维图" switch over the harness UI and, on
2
+ // It renders a "对话 | 思维图" switch in the harness session header (slot
3
+ // `conversation.session.header.actions`, so it flows with the native layout
4
+ // on desktop and mobile web instead of floating over the title bar) and, on
3
5
  // "思维图", shows a full-screen SAME-ORIGIN iframe at /thoughtdag/ (the SPA
4
6
  // is served by the host half on the same web server — no CORS, no second
5
- // origin). All conversation smarts live inside the ThoughtDAG app; this file
7
+ // origin) with its own floating back pill, since the overlay covers the
8
+ // header. All conversation smarts live inside the ThoughtDAG app; this file
6
9
  // only opens the door and forwards the current session id so the canvas can
7
10
  // offer to mirror it.
8
11
  //
9
12
  // Same pattern as dsh-synapse: window.__ModuleLoader__.load with a module
10
- // whose inject lists the client services it reads (sessions) and whose apply
11
- // touches the DOM.
13
+ // whose inject lists the client services it reads (sessions, slots) and whose
14
+ // apply registers the switch. react is a platform seed module — the loader's
15
+ // require answers it from the module table, so the bundle stays tiny.
12
16
 
13
17
  window.__ModuleLoader__.load({
14
18
  id: 'dsh-thoughtdag',
15
- factory: () => {
19
+ factory: require => {
16
20
  const module = { exports: {} }
21
+ const React = require('react')
17
22
 
18
- module.exports.inject = ['sessions']
23
+ module.exports.inject = ['sessions', 'slots']
19
24
  module.exports.apply = ctx => {
20
25
  const currentSession = () => {
21
26
  const snapshot = ctx.sessions.list.getSnapshot()
@@ -26,29 +31,26 @@ window.__ModuleLoader__.load({
26
31
  }
27
32
 
28
33
  const style = document.createElement('style')
29
- style.textContent = '.dsh-td-switch{position:fixed;z-index:120;top:12px;left:50%;display:flex;gap:2px;transform:translateX(-50%);border:1px solid #d1d5db;border-radius:999px;background:rgba(255,255,255,.96);padding:3px;backdrop-filter:blur(10px)}.dsh-td-switch button{height:28px;border:0;border-radius:999px;background:transparent;padding:0 11px;color:#6b7280;font:600 12px Inter,system-ui,sans-serif;cursor:pointer;white-space:nowrap}.dsh-td-switch button:hover{background:#f3f4f6;color:#111827}.dsh-td-switch button.active{background:#111827;color:#fff}.dsh-td-overlay{position:fixed;z-index:100;inset:0;background:#faf9f7}.dsh-td-overlay[hidden]{display:none}.dsh-td-overlay iframe{display:block;width:100%;height:100%;border:0}'
34
+ style.textContent = '.dsh-td-switch{display:inline-flex;gap:2px;border:1px solid #d1d5db;border-radius:999px;background:rgba(255,255,255,.96);padding:3px;backdrop-filter:blur(10px)}.dsh-td-switch button{height:26px;border:0;border-radius:999px;background:transparent;padding:0 11px;color:#6b7280;font:600 12px Inter,system-ui,sans-serif;cursor:pointer;white-space:nowrap}.dsh-td-switch button:hover{background:#f3f4f6;color:#111827}.dsh-td-switch button.active{background:#111827;color:#fff}.dsh-td-back{position:fixed;z-index:130;top:12px;left:50%;transform:translateX(-50%);border:1px solid #d1d5db;border-radius:999px;background:rgba(255,255,255,.96);padding:5px 14px;color:#374151;font:600 12px Inter,system-ui,sans-serif;cursor:pointer;backdrop-filter:blur(10px)}.dsh-td-back:hover{background:#f3f4f6;color:#111827}.dsh-td-overlay{position:fixed;z-index:100;inset:0;background:#faf9f7}.dsh-td-overlay[hidden]{display:none}.dsh-td-overlay iframe{display:block;width:100%;height:100%;border:0}'
30
35
  document.head.append(style)
31
36
 
32
- const host = document.createElement('div')
33
- host.innerHTML = '<div class="dsh-td-switch" role="group" aria-label="view switch"><button type="button" data-view="dialog" class="active" aria-pressed="true">对话</button><button type="button" data-view="map" aria-pressed="false">思维图</button></div><section class="dsh-td-overlay" hidden><iframe title="ThoughtDAG" data-src="/thoughtdag/"></iframe></section>'
34
- document.body.append(host)
37
+ const overlayHost = document.createElement('div')
38
+ overlayHost.innerHTML = '<section class="dsh-td-overlay" hidden><button type="button" class="dsh-td-back">对话</button><iframe title="ThoughtDAG" data-src="/thoughtdag/"></iframe></section>'
39
+ document.body.append(overlayHost)
40
+ const overlay = overlayHost.querySelector('.dsh-td-overlay')
41
+ const frame = overlayHost.querySelector('iframe')
42
+ const backBtn = overlayHost.querySelector('.dsh-td-back')
35
43
 
36
44
  // the plugin's version, for the canvas's update dialog and release history
37
45
  let pluginVersion = null
38
46
  fetch('/thoughtdag/api/version').then(r => (r.ok ? r.json() : null)).then(j => { if (j && typeof j.version === 'string') pluginVersion = j.version }).catch(() => {})
39
47
 
40
- const dialogBtn = host.querySelector('[data-view="dialog"]')
41
- const mapBtn = host.querySelector('[data-view="map"]')
42
- const overlay = host.querySelector('.dsh-td-overlay')
43
- const frame = host.querySelector('iframe')
48
+ // store 由本文件自行维护:setMap 是唯一写入口,既切 overlay(命令式
49
+ // DOM),也通知 Switch 组件重渲染 active 态。不走 slots 的 store/inject
50
+ // 契约——session 作用域槽位的 inject 首参是 sessionKey,签名因槽位而异。
51
+ let mapState = false
52
+ const mapSubscribers = new Set()
44
53
 
45
- const setView = map => {
46
- dialogBtn.classList.toggle('active', !map)
47
- dialogBtn.setAttribute('aria-pressed', String(!map))
48
- mapBtn.classList.toggle('active', map)
49
- mapBtn.setAttribute('aria-pressed', String(map))
50
- }
51
- const close = () => { overlay.hidden = true; setView(false); send('td:view', { shown: false }) }
52
54
  const send = (type, payload) => frame.contentWindow?.postMessage({ source: 'dsh-thoughtdag', type, ...payload }, location.origin)
53
55
 
54
56
  const syncCurrent = () => {
@@ -56,9 +58,11 @@ window.__ModuleLoader__.load({
56
58
  send('td:current-session', { session })
57
59
  }
58
60
 
59
- mapBtn.addEventListener('click', () => {
60
- overlay.hidden = false
61
- setView(true)
61
+ const setMap = map => {
62
+ mapState = map
63
+ overlay.hidden = !map
64
+ for (const notify of mapSubscribers) notify(map)
65
+ if (!map) { send('td:view', { shown: false }); return }
62
66
  // the SPA boots on first open, never while hidden: a canvas that
63
67
  // measures itself inside a display:none frame fits its view to a 0×0
64
68
  // box and shows nothing when revealed
@@ -67,18 +71,49 @@ window.__ModuleLoader__.load({
67
71
  send('td:view', { shown: true })
68
72
  // let the SPA boot, then re-sync so its listener is ready
69
73
  window.setTimeout(() => { syncCurrent(); send('td:view', { shown: true }) }, 400)
70
- })
71
- dialogBtn.addEventListener('click', close)
74
+ }
75
+
76
+ const Switch = () => {
77
+ const [map, setMapState] = React.useState(mapState)
78
+ React.useEffect(() => {
79
+ const notify = m => setMapState(m)
80
+ mapSubscribers.add(notify)
81
+ return () => { mapSubscribers.delete(notify) }
82
+ }, [])
83
+ return React.createElement('div', { className: 'dsh-td-switch', role: 'group', 'aria-label': 'view switch' },
84
+ React.createElement('button', {
85
+ type: 'button', 'data-view': 'dialog', className: map ? '' : 'active', 'aria-pressed': String(!map),
86
+ onClick: () => setMap(false),
87
+ }, '对话'),
88
+ React.createElement('button', {
89
+ type: 'button', 'data-view': 'map', className: map ? 'active' : '', 'aria-pressed': String(map),
90
+ onClick: () => setMap(true),
91
+ }, '思维图'),
92
+ )
93
+ }
94
+
95
+ ctx.slots.inject('conversation.session.header.actions', () =>
96
+ ctx.slots.register({
97
+ name: 'conversation.session.header.actions',
98
+ id: 'thoughtdag-view-switch',
99
+ order: 90,
100
+ }, Switch),
101
+ )
102
+
103
+ backBtn.addEventListener('click', () => setMap(false))
72
104
 
73
105
  window.addEventListener('message', event => {
74
106
  if (event.origin !== location.origin || event.data?.source !== 'dsh-thoughtdag') return
75
- if (event.data.type === 'td:close') return close()
107
+ if (event.data.type === 'td:close') return setMap(false)
76
108
  if (event.data.type === 'td:request-current') return syncCurrent()
77
109
  // the canvas forked or continued a session: stage it and go back to the
78
110
  // chat, which now shows exactly the context the canvas produced
79
111
  if (event.data.type === 'td:select-session' && typeof event.data.session === 'string') {
80
- ctx.sessions.select(event.data.session)
81
- if (event.data.close !== false) close()
112
+ // 0.1.2 renamed the selector: the ISessions contract exposes open(id);
113
+ // older runtimes (0.1.1) still call it select
114
+ const select = ctx.sessions.open ?? ctx.sessions.select
115
+ select.call(ctx.sessions, event.data.session)
116
+ if (event.data.close !== false) setMap(false)
82
117
  syncCurrent()
83
118
  }
84
119
  })
package/lib/why.mjs CHANGED
@@ -27,6 +27,36 @@ function getDescendantIds(nodeId, edges) {
27
27
  return descendants;
28
28
  }
29
29
 
30
+ // ../src/lib/frames.ts
31
+ function frameRect(frame) {
32
+ return {
33
+ x: frame.position.x,
34
+ y: frame.position.y,
35
+ width: frame.measured?.width ?? frame.width ?? 0,
36
+ height: frame.measured?.height ?? frame.height ?? 0
37
+ };
38
+ }
39
+ function nodeCenter(node) {
40
+ return {
41
+ x: node.position.x + (node.measured?.width ?? 520) / 2,
42
+ y: node.position.y + (node.measured?.height ?? 120) / 2
43
+ };
44
+ }
45
+ var isFrameNode = (n) => n.data.stepKind === "frame";
46
+ function frameContains(outer, inner) {
47
+ const strictlyLarger = outer.width * outer.height > inner.width * inner.height;
48
+ return strictlyLarger && inner.x >= outer.x && inner.y >= outer.y && inner.x + inner.width <= outer.x + outer.width && inner.y + inner.height <= outer.y + outer.height;
49
+ }
50
+ function frameMembers(frame, nodes) {
51
+ const r = frameRect(frame);
52
+ return nodes.filter((n) => {
53
+ if (n.id === frame.id) return false;
54
+ if (isFrameNode(n)) return frameContains(r, frameRect(n));
55
+ const c = nodeCenter(n);
56
+ return c.x >= r.x && c.x <= r.x + r.width && c.y >= r.y && c.y <= r.y + r.height;
57
+ });
58
+ }
59
+
30
60
  // ../src/lib/constants.ts
31
61
  var API_BASE = define_import_meta_env_default.VITE_API_BASE ?? (define_import_meta_env_default.DEV ? "http://localhost:3001" : "");
32
62
  var LAYOUT_COL_WIDTH = 540;
@@ -47,8 +77,33 @@ function estimateNodeHeight(node) {
47
77
  function nodeHeight(node) {
48
78
  return Math.max(node.measured?.height ?? 0, estimateNodeHeight(node));
49
79
  }
80
+ var FRAME_SIDE_PADDING = 36;
81
+ var FRAME_TITLE_GAP = 44;
82
+ var FRAME_NESTING_GAP = 24;
83
+ var FRAME_MIN_WIDTH = 280;
84
+ var FRAME_MIN_HEIGHT = 180;
85
+ function snapshotLayoutFrames(allNodes) {
86
+ const frames = allNodes.filter((n) => n.data.stepKind === "frame" && n.data.frameCarry !== false);
87
+ const snapshots = frames.map((frame) => {
88
+ const memberIds = frameMembers(frame, allNodes).filter((n) => !isFrameNode(n)).map((n) => n.id);
89
+ return { id: frame.id, memberIds, rect: frameRect(frame), nestingLevel: 0 };
90
+ });
91
+ const contains = (outer, inner) => outer.id !== inner.id && frameContains(outer.rect, inner.rect);
92
+ const memo = /* @__PURE__ */ new Map();
93
+ const levelOf = (frame) => {
94
+ const cached = memo.get(frame.id);
95
+ if (cached !== void 0) return cached;
96
+ const innerFrames = snapshots.filter((candidate) => contains(frame, candidate));
97
+ const level = innerFrames.length === 0 ? 0 : 1 + Math.max(...innerFrames.map(levelOf));
98
+ memo.set(frame.id, level);
99
+ return level;
100
+ };
101
+ for (const snapshot of snapshots) snapshot.nestingLevel = levelOf(snapshot);
102
+ return snapshots;
103
+ }
50
104
  function autoLayout(allNodes, allEdges) {
51
105
  if (allNodes.length === 0) return allNodes;
106
+ const frameSnapshots = snapshotLayoutFrames(allNodes);
52
107
  const contentIds = new Set(
53
108
  allNodes.filter((n) => ["note", "file", "link", "frame"].includes(n.data.stepKind ?? "")).map((n) => n.id)
54
109
  );
@@ -378,7 +433,36 @@ function autoLayout(allNodes, allEdges) {
378
433
  }
379
434
  positioned.set(note.id, { x, y });
380
435
  }
436
+ const frameLayouts = /* @__PURE__ */ new Map();
437
+ const nodeById = new Map(allNodes.map((n) => [n.id, n]));
438
+ const contentKinds = /* @__PURE__ */ new Set(["note", "file", "link"]);
439
+ const snapshotsInnerToOuter = [...frameSnapshots].sort((a, b) => a.nestingLevel - b.nestingLevel);
440
+ for (const frame of snapshotsInnerToOuter) {
441
+ if (frame.memberIds.length === 0) continue;
442
+ const rects = frame.memberIds.map((id) => {
443
+ const node = nodeById.get(id);
444
+ if (!node) return null;
445
+ const position = positioned.get(id) ?? node.position;
446
+ const width2 = node.measured?.width ?? node.width ?? LAYOUT_COL_WIDTH;
447
+ const height2 = contentKinds.has(node.data.stepKind ?? "") ? node.measured?.height ?? node.height ?? 120 : Math.max(node.measured?.height ?? 0, node.height ?? 0, nodeHeight(node));
448
+ return { x: position.x, y: position.y, width: width2, height: height2 };
449
+ }).filter((r) => r !== null);
450
+ if (rects.length === 0) continue;
451
+ const minX = Math.min(...rects.map((r) => r.x));
452
+ const minY = Math.min(...rects.map((r) => r.y));
453
+ const maxX = Math.max(...rects.map((r) => r.x + r.width));
454
+ const maxY = Math.max(...rects.map((r) => r.y + r.height));
455
+ const sidePadding = FRAME_SIDE_PADDING + frame.nestingLevel * FRAME_NESTING_GAP;
456
+ const topPadding = sidePadding + FRAME_TITLE_GAP;
457
+ const x = minX - sidePadding;
458
+ const y = minY - topPadding;
459
+ const width = Math.max(FRAME_MIN_WIDTH, maxX - minX + sidePadding * 2);
460
+ const height = Math.max(FRAME_MIN_HEIGHT, maxY - minY + topPadding + sidePadding);
461
+ frameLayouts.set(frame.id, { position: { x, y }, width, height });
462
+ }
381
463
  return allNodes.map((node) => {
464
+ const frameLayout = frameLayouts.get(node.id);
465
+ if (frameLayout) return { ...node, ...frameLayout };
382
466
  const pos = positioned.get(node.id);
383
467
  return pos ? { ...node, position: pos } : node;
384
468
  });
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "dsh-thoughtdag",
3
- "version": "0.4.12",
3
+ "version": "0.4.16",
4
4
  "description": "ThoughtDAG for DeepSeek Harness: turn the current DSH session into an editable thought graph on an infinite canvas.",
5
5
  "author": "Xia Chen",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "https://github.com/chenxiachan/thoughtdag.git",
8
+ "url": "git+https://github.com/chenxiachan/thoughtdag.git",
9
9
  "directory": "dsh"
10
10
  },
11
11
  "homepage": "https://github.com/chenxiachan/thoughtdag/tree/main/dsh#readme",
@@ -42,13 +42,15 @@
42
42
  "inject": [
43
43
  "@deepseek-ai/dsh-client-modules",
44
44
  "@deepseek-ai/dsh-api-session-controller",
45
- "@deepseek-ai/dsh-client-connection"
45
+ "@deepseek-ai/dsh-client-connection",
46
+ "@deepseek-ai/dsh-client-ui-conversation"
46
47
  ],
47
48
  "immediately": false
48
49
  },
49
50
  "compatibility": {
50
51
  "dshReleases": {
51
- "0.1.2-rc.1": "compatible"
52
+ "0.1.2-rc.1": "compatible",
53
+ "0.1.5-rc.1": "compatible"
52
54
  }
53
55
  }
54
56
  },