dsh-thoughtdag 0.5.4 → 0.5.6

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 (37) hide show
  1. package/dist-app/assets/{canonical-lpYt01q8.js → canonical-CSoZNuPg.js} +2 -2
  2. package/dist-app/assets/{canvas-record-C954zMyU.js → canvas-record-wnrN3Xiq.js} +1 -1
  3. package/dist-app/assets/claude-code-session-Cjh9ZQd-.js +8 -0
  4. package/dist-app/assets/codex-session-Dgq2Nsm-.js +12 -0
  5. package/dist-app/assets/{dsh-session-ClUmglrW.js → dsh-session-B9EsawUx.js} +3 -3
  6. package/dist-app/assets/{experiment-loop-C9mVK7yX.js → experiment-loop-CW1DebVY.js} +1 -1
  7. package/dist-app/assets/{http-bridge-BL1SuJsm.js → http-bridge-DG_nZVjI.js} +1 -1
  8. package/dist-app/assets/index-B1IC85BS.js +914 -0
  9. package/dist-app/assets/index-CgnmeNGy.css +1 -0
  10. package/dist-app/assets/{index-CHV1get9.js → index-D7EuGCbC.js} +1 -1
  11. package/dist-app/assets/{index-DRuVr_fe.js → index-Fb-Q079K.js} +1 -1
  12. package/dist-app/assets/{index-C3YBa-cP.js → index-rGP3NmkV.js} +3 -3
  13. package/dist-app/assets/local-ladder.worker-Dj3KyWai.js +1 -0
  14. package/dist-app/assets/pi-session-1yVM3dMC.js +14 -0
  15. package/dist-app/assets/{sensitive-scan-ClJE_sMR.js → sensitive-scan-CROt_JlT.js} +1 -1
  16. package/dist-app/assets/{session-handoff-BPbFjcS2.js → session-handoff-r3h38IOI.js} +2 -2
  17. package/dist-app/assets/shared-ABEucpDy.js +10 -0
  18. package/dist-app/assets/{turndown-plugin-gfm.cjs-B51wGC07.js → turndown-plugin-gfm.cjs-C6ig148J.js} +1 -1
  19. package/dist-app/assets/update-check-Bo9R7uYE.js +1 -0
  20. package/dist-app/index.html +2 -2
  21. package/lib/client.js +33 -8
  22. package/lib/index.js +183 -11
  23. package/lib/runtime/agents/README.md +1 -1
  24. package/lib/runtime/agents/claude.cjs +13 -14
  25. package/lib/runtime/agents/codex.cjs +13 -14
  26. package/lib/runtime/agents/pi.cjs +14 -27
  27. package/lib/runtime/agents/where.cjs +99 -0
  28. package/lib/why.mjs +156 -6
  29. package/package.json +1 -1
  30. package/dist-app/assets/claude-code-session-Dvg2z_fp.js +0 -7
  31. package/dist-app/assets/codex-session-C8Wr73Y-.js +0 -12
  32. package/dist-app/assets/index-C8yf-QJz.js +0 -904
  33. package/dist-app/assets/index-Lvtth6pP.css +0 -1
  34. package/dist-app/assets/local-ladder.worker-BkmzXrqq.js +0 -1
  35. package/dist-app/assets/pi-session-BNZYRZki.js +0 -14
  36. package/dist-app/assets/shared-B7orUlMM.js +0 -10
  37. package/dist-app/assets/update-check-4z5bqXf5.js +0 -1
package/lib/why.mjs CHANGED
@@ -61,8 +61,8 @@ function frameMembers(frame, nodes) {
61
61
  // ../src/lib/constants.ts
62
62
  var API_BASE = define_import_meta_env_default.VITE_API_BASE ?? (define_import_meta_env_default.DEV ? "http://localhost:3001" : "");
63
63
  var LAYOUT_COL_WIDTH = 540;
64
- var LAYOUT_H_GAP = 48;
65
- var LAYOUT_V_GAP = 72;
64
+ var LAYOUT_H_GAP = 64;
65
+ var LAYOUT_V_GAP = 96;
66
66
  var COLLAPSED_LAYOUT_HEIGHT = 240;
67
67
 
68
68
  // ../src/lib/layout.ts
@@ -548,6 +548,47 @@ ${tool.result}`,
548
548
  ...tool.op ? { op: tool.op } : {}
549
549
  }));
550
550
  }
551
+ function adoptSubagentSessions(turns, subs) {
552
+ const used = /* @__PURE__ */ new Set();
553
+ const settle = (run, sub) => {
554
+ used.add(sub);
555
+ const tools = sub.turns.flatMap((t) => t.tools);
556
+ if (tools.length) run.tools = tools;
557
+ if (!run.output.trim()) run.output = sub.turns.map((t) => t.response).filter((r) => r.trim()).at(-1) ?? "";
558
+ if (!run.itemIds.includes(sub.sessionId)) run.itemIds.push(sub.sessionId);
559
+ if (!run.at && sub.at) run.at = sub.at;
560
+ };
561
+ for (const turn of turns) for (const run of turn.subagents ?? []) {
562
+ const key = run.match?.trim();
563
+ if (!key) continue;
564
+ const sub = subs.find((x) => !used.has(x) && x.firstQuestion.trim() === key);
565
+ if (sub) settle(run, sub);
566
+ }
567
+ for (const sub of subs) {
568
+ if (used.has(sub) || !sub.at) continue;
569
+ const before = turns.filter((t) => t.at && t.at <= sub.at);
570
+ const turn = before.at(-1) ?? turns.at(-1);
571
+ if (!turn) continue;
572
+ const run = { agent: sub.runner, task: sub.firstQuestion, output: "", itemIds: [sub.sessionId], at: sub.at };
573
+ settle(run, sub);
574
+ (turn.subagents ??= []).push(run);
575
+ }
576
+ }
577
+ function attachSubagentBranches(parent, turn, nodes, edges, runner, sessionId, cwd) {
578
+ const kids = [];
579
+ for (const run of turn.subagents ?? []) {
580
+ const node = makeNode(`[${run.agent}] ${run.task}`.trim(), run.output, false);
581
+ node.data.isBranch = true;
582
+ node.data.importSource = { runner, sessionId, itemIds: run.itemIds, ...cwd ? { cwd } : {}, subagent: { agent: run.agent, of: turn.itemIds[0] ?? "" } };
583
+ node.data.source = { question: node.data.question, response: node.data.response };
584
+ if (run.tools?.length) node.data.attachments = toolAttachments({ question: run.task, response: run.output, itemIds: run.itemIds, tools: run.tools });
585
+ seedPlaque(node);
586
+ nodes.push(node);
587
+ kids.push(node);
588
+ edges.push({ id: generateId(), source: parent.id, target: node.id, type: "smoothstep", data: { isBranchFromSelection: true, branchYRatio: 0.5 } });
589
+ }
590
+ return kids;
591
+ }
551
592
  function toolScope(input) {
552
593
  const i = input ?? {};
553
594
  const out = {};
@@ -664,6 +705,10 @@ var ClaudeSessionCollector = class {
664
705
  ...reg.url ? { url: reg.url } : {},
665
706
  ...reg.locator ? { locator: reg.locator } : {}
666
707
  });
708
+ if (reg.spawn) {
709
+ const report = clip(resultText(p.content), ARTIFACT_CALL_LIMIT);
710
+ (this.current.subagents ??= []).push({ agent: reg.spawn.agent, task: reg.spawn.task, output: report.text, itemIds: [p.tool_use_id], match: reg.spawn.prompt, ...line.timestamp ? { at: line.timestamp } : {} });
711
+ }
667
712
  this.pendingTools.delete(p.tool_use_id);
668
713
  }
669
714
  }
@@ -708,7 +753,9 @@ ${text}` : text;
708
753
  if (p.type === "tool_use" && p.id && p.name) {
709
754
  const op = toolOpOf(p.name);
710
755
  const call = clip(renderCall(p.name, p.input), op === "write" || op === "edit" ? ARTIFACT_CALL_LIMIT : TOOL_CALL_LIMIT);
711
- this.pendingTools.set(p.id, { name: p.name, call: call.text, paths: toolPaths(p.input), op, ...toolScope(p.input) });
756
+ const inp = p.input && typeof p.input === "object" ? p.input : {};
757
+ const spawn = op === "agent" ? { agent: String(inp.subagent_type ?? "agent"), task: String(inp.description ?? inp.prompt?.split("\n")[0] ?? ""), prompt: String(inp.prompt ?? "") } : void 0;
758
+ this.pendingTools.set(p.id, { name: p.name, call: call.text, paths: toolPaths(p.input), op, ...toolScope(p.input), ...spawn ? { spawn } : {} });
712
759
  }
713
760
  }
714
761
  }
@@ -729,9 +776,17 @@ ${text}` : text;
729
776
  messageCount: s.turns.length,
730
777
  source: "claude-code",
731
778
  sessionId: s.sessionId,
732
- build: () => buildGraphFromTurns(s.turns, s.sessionId, s.cwd)
779
+ build: () => buildGraphFromTurns(s.turns, s.sessionId, s.cwd),
780
+ adopt: (subs) => adoptSubagentSessions(s.turns, subs)
733
781
  };
734
782
  }
783
+ /** This file as a subagent's transcript (a sidechain file), for its parent to adopt. */
784
+ toSubagentSession() {
785
+ const s = this.finish();
786
+ if (!s || s.turns.length === 0 || this.mode !== "sidechain") return null;
787
+ const first = s.turns[0];
788
+ return { runner: "claude-code", sessionId: s.sessionId, firstQuestion: this.firstQuestion ?? first.question, turns: s.turns, ...s.cwd ? { cwd: s.cwd } : {}, ...first.at ? { at: first.at } : {} };
789
+ }
735
790
  };
736
791
  function noteNode(text) {
737
792
  const n = makeNode(text, "", false);
@@ -762,6 +817,7 @@ function buildGraphFromTurns(turns, sessionId, cwd) {
762
817
  seedPlaque(node);
763
818
  node.data.attachments = toolAttachments(turn);
764
819
  nodes.push(node);
820
+ attachSubagentBranches(node, turn, nodes, edges, "claude-code", sessionId, cwd);
765
821
  const parent = turn.parentItemId ? byItem.get(turn.parentItemId) : void 0;
766
822
  if (parent) link(parent, node);
767
823
  else if (prev) link(prev, node);
@@ -799,6 +855,7 @@ var CodexSessionCollector = class {
799
855
  sawItems = false;
800
856
  firstQuestion = null;
801
857
  parentThreadId = null;
858
+ startedAt = null;
802
859
  feedLine(raw) {
803
860
  const t = raw.trim();
804
861
  if (!t) return;
@@ -832,6 +889,7 @@ var CodexSessionCollector = class {
832
889
  this.cwd = p.cwd ?? "";
833
890
  this.day = p.timestamp?.slice(0, 10) ?? "";
834
891
  this.parentThreadId = p.parent_thread_id ?? null;
892
+ this.startedAt = p.timestamp ?? line.timestamp ?? null;
835
893
  return;
836
894
  }
837
895
  if (line.type === "response_item" || line.type === "event_msg") this.sawItems = true;
@@ -931,9 +989,18 @@ ${turn.response}` : turn.response;
931
989
  messageCount: s.turns.length,
932
990
  source: "codex",
933
991
  sessionId: s.sessionId,
934
- build: () => buildGraphFromTurns2(s.turns, s.sessionId, s.cwd)
992
+ build: () => buildGraphFromTurns2(s.turns, s.sessionId, s.cwd),
993
+ adopt: (subs) => adoptSubagentSessions(s.turns, subs)
935
994
  };
936
995
  }
996
+ /** This rollout as a child thread's transcript, for the parent named in its header to adopt. */
997
+ toSubagentSession() {
998
+ const s = this.finish();
999
+ if (!s || s.turns.length === 0 || !s.subagent) return null;
1000
+ const first = s.turns[0];
1001
+ const at = first.at ?? this.startedAt ?? void 0;
1002
+ return { runner: "codex", sessionId: s.sessionId, firstQuestion: this.firstQuestion ?? first.question, turns: s.turns, ...s.cwd ? { cwd: s.cwd } : {}, ...at ? { at } : {} };
1003
+ }
937
1004
  };
938
1005
  function buildGraphFromTurns2(turns, sessionId, cwd) {
939
1006
  const origin = cwd ? { cwd } : {};
@@ -958,6 +1025,7 @@ function buildGraphFromTurns2(turns, sessionId, cwd) {
958
1025
  nodes.push(node);
959
1026
  if (prev) edges.push({ id: generateId(), source: prev.id, target: node.id, type: "smoothstep" });
960
1027
  if (noteToWire) edges.push({ id: generateId(), source: noteToWire.id, target: node.id, type: "smoothstep" });
1028
+ attachSubagentBranches(node, turn, nodes, edges, "codex", sessionId, cwd);
961
1029
  prev = node;
962
1030
  }
963
1031
  return { nodes: autoLayout(nodes, edges), edges };
@@ -1199,6 +1267,27 @@ ${e.newText ?? ""}`).join("\n\n");
1199
1267
  const c = clipText(JSON.stringify(args ?? {}), TOOL_CALL_LIMIT);
1200
1268
  return { ...c, paths, ...locator ? { locator } : {} };
1201
1269
  }
1270
+ var finalOutput = (messages) => {
1271
+ if (!Array.isArray(messages)) return "";
1272
+ for (let i = messages.length - 1; i >= 0; i--) {
1273
+ const m = messages[i];
1274
+ if (m?.role === "assistant") {
1275
+ const text = textOf(m.content).trim();
1276
+ if (text) return text;
1277
+ }
1278
+ }
1279
+ return "";
1280
+ };
1281
+ function subagentRuns(args, content, details, callId) {
1282
+ const d = details;
1283
+ if (Array.isArray(d?.results) && d.results.length) {
1284
+ return d.results.map((r, i) => ({ agent: String(r.agent ?? "agent"), task: String(r.task ?? ""), output: finalOutput(r.messages) || String(r.stderr ?? "").trim(), itemIds: [`${callId}#${i}`] }));
1285
+ }
1286
+ const a = args && typeof args === "object" ? args : {};
1287
+ const asked = Array.isArray(a.tasks) && a.tasks.length ? a.tasks : Array.isArray(a.chain) && a.chain.length ? a.chain : a.agent || a.task ? [{ agent: a.agent, task: a.task }] : [];
1288
+ const text = textOf(content).trim();
1289
+ return asked.map((x, i) => ({ agent: String(x.agent ?? "agent"), task: String(x.task ?? ""), output: asked.length === 1 ? text : "", itemIds: [`${callId}#${i}`] }));
1290
+ }
1202
1291
  var PiSessionCollector = class {
1203
1292
  turns = [];
1204
1293
  pending = /* @__PURE__ */ new Map();
@@ -1261,7 +1350,7 @@ ${text}` : text;
1261
1350
  for (const b of m.content) {
1262
1351
  if (b?.type !== "toolCall" || typeof b.id !== "string" || typeof b.name !== "string") continue;
1263
1352
  const r = renderCall2(b.name, b.arguments);
1264
- this.pending.set(b.id, { name: b.name, call: r.text, truncated: r.truncated, op: toolOpOf(b.name), paths: r.paths, ...r.locator ? { locator: r.locator } : {} });
1353
+ this.pending.set(b.id, { name: b.name, call: r.text, truncated: r.truncated, op: toolOpOf(b.name), paths: r.paths, ...r.locator ? { locator: r.locator } : {}, ...b.name === "subagent" ? { args: b.arguments } : {} });
1265
1354
  }
1266
1355
  }
1267
1356
  return;
@@ -1284,6 +1373,10 @@ ${text}` : text;
1284
1373
  ...reg.paths.length ? { paths: reg.paths } : {},
1285
1374
  ...reg.locator ? { locator: reg.locator } : {}
1286
1375
  });
1376
+ if (reg.name === "subagent") {
1377
+ const runs = subagentRuns(reg.args, m.content, m.details, id);
1378
+ if (runs.length) cur.subagents = [...cur.subagents ?? [], ...runs];
1379
+ }
1287
1380
  this.pending.delete(id);
1288
1381
  }
1289
1382
  }
@@ -1322,6 +1415,7 @@ function buildGraphFromTurns4(turns, sessionId, cwd) {
1322
1415
  const parent = turn.parentItemId ? byItem.get(turn.parentItemId) : void 0;
1323
1416
  if (parent) link(parent, node);
1324
1417
  else if (prev) link(prev, node);
1418
+ attachSubagentBranches(node, turn, nodes, edges, "pi", sessionId, cwd);
1325
1419
  for (const id of turn.itemIds) byItem.set(id, node);
1326
1420
  prev = node;
1327
1421
  }
@@ -2999,6 +3093,61 @@ async function findJson(phrase, opts = {}) {
2999
3093
  hits: shown.map((h) => ({ kind: h.kind, session: h.session.id, runner: h.session.runner, title: h.session.title, cwd: h.turn.cwd ?? h.session.cwd, file: h.session.file, turn: turnNumber(facts, h), at: h.turn.at ?? null, where: h.where, snippet: h.snippet, open: openLink(h) }))
3000
3094
  };
3001
3095
  }
3096
+ async function turnsJson(opts = {}) {
3097
+ if (opts.limit === 0) {
3098
+ const text = await loadText();
3099
+ return { total: Object.values(text.sessions).reduce((a, b) => a + b, 0), turns: [] };
3100
+ }
3101
+ const facts = await ensureFresh();
3102
+ const head = Math.max(40, Math.min(1e3, opts.head ?? 300));
3103
+ const turnsOf = /* @__PURE__ */ new Map();
3104
+ const lookup = (k, i) => {
3105
+ let m = turnsOf.get(k);
3106
+ if (!m) {
3107
+ m = new Map(facts.sessions[k]?.turns.map((t) => [t.i, t]) ?? []);
3108
+ turnsOf.set(k, m);
3109
+ }
3110
+ return m.get(i);
3111
+ };
3112
+ const clipHead = (text) => (text ?? "").replace(/\s+/g, " ").trim().slice(0, head);
3113
+ const raw = [];
3114
+ let lines = null;
3115
+ try {
3116
+ await fsp.access(TEXT_LINES);
3117
+ lines = createInterface({ input: createReadStream(TEXT_LINES, { encoding: "utf8", highWaterMark: 1 << 20 }) });
3118
+ } catch {
3119
+ return { total: 0, turns: [] };
3120
+ }
3121
+ for await (const line of lines) {
3122
+ let t;
3123
+ try {
3124
+ t = JSON.parse(line);
3125
+ } catch {
3126
+ continue;
3127
+ }
3128
+ const session = facts.sessions[t.k];
3129
+ const turn = lookup(t.k, t.i);
3130
+ if (!session || !turn) continue;
3131
+ const memory = session.kind === "memory";
3132
+ raw.push({ session, sourceKey: t.k, turn, q: memory ? "" : clipHead(t.q), a: clipHead(memory ? t.m : t.a), kind: memory ? "memory" : "turn" });
3133
+ }
3134
+ const seen = /* @__PURE__ */ new Set();
3135
+ const all = [];
3136
+ for (const h of raw.sort((a, b) => a.session.mtime - b.session.mtime)) {
3137
+ if (h.turn.item) {
3138
+ if (seen.has(h.turn.item)) continue;
3139
+ seen.add(h.turn.item);
3140
+ }
3141
+ all.push(h);
3142
+ }
3143
+ all.sort((a, b) => (b.turn.at ?? "").localeCompare(a.turn.at ?? ""));
3144
+ const offset = Math.max(0, opts.offset ?? 0);
3145
+ const limit = Math.max(0, opts.limit ?? all.length);
3146
+ return {
3147
+ total: all.length,
3148
+ turns: all.slice(offset, offset + limit).map((h) => ({ kind: h.kind, session: h.session.id, runner: h.session.runner, title: h.session.title, cwd: h.turn.cwd ?? h.session.cwd, file: h.session.file, turn: turnNumber(facts, h), at: h.turn.at ?? null, q: h.q, a: h.a, open: openLink(h) }))
3149
+ };
3150
+ }
3002
3151
  async function recallJson(session, n) {
3003
3152
  return recallTurn(await ensureFresh(), session, n);
3004
3153
  }
@@ -3440,6 +3589,7 @@ export {
3440
3589
  suggestJson,
3441
3590
  summarize,
3442
3591
  topicsJson,
3592
+ turnsJson,
3443
3593
  when,
3444
3594
  zstdSkipped
3445
3595
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-thoughtdag",
3
- "version": "0.5.4",
3
+ "version": "0.5.6",
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": {
@@ -1,7 +0,0 @@
1
- import{q as I,B as g,n as T}from"./index-C8yf-QJz.js";import{t as C,a as _,r as A,b as x,c as w,d as L,e as S,s as k,f as v,m as O,T as b,A as q,g as B}from"./shared-B7orUlMM.js";const M=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
- `):""}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
- `):""}const p=S;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,M);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
-
5
- ${n}`:n),Array.isArray(s)){for(const e of s)if(e.type==="tool_use"&&e.id&&e.name){const i=_(e.name),a=p(A(e.name,e.input),i==="write"||i==="edit"?q:B);this.pendingTools.set(e.id,{name:e.name,call:a.text,paths:w(e.input),op:i,...x(e.input)})}}}}}finish(){if(this.flush(),!this.sessionId)return null;const t=this.firstQuestion?.split(`
6
- `).map(n=>n.trim()).find(n=>n&&!n.startsWith("<"))?.slice(0,80)??null,s=this.customTitle??this.summary??t??this.slug??`session ${this.sessionId.slice(0,8)}`;return{sessionId:this.sessionId,title:s,turns:L(this.turns),...this.cwd?{cwd:this.cwd}:{}}}toConversation(){const t=this.finish();return!t||t.turns.length===0?null:{title:t.title,messageCount:t.turns.length,source:"claude-code",sessionId:t.sessionId,build:()=>Q(t.turns,t.sessionId,t.cwd)}}}function y(o){const t=new $;for(const s of o.split(`
7
- `))t.feedLine(s);return t}function F(o){const t=I(o,"",!1);return t.data.stepKind="note",O(t),t}function Q(o,t,s){const n=s?{cwd:s}:{},e=[],i=[];let a=null;const m=new Map,l=(u,c)=>{i.push({id:T(),source:u.id,target:c.id,type:"smoothstep"})};for(const u of o){let c=null;if(u.compactionBefore){const d=F(u.compactionBefore);d.data.importSource={runner:"claude-code",sessionId:t,itemIds:[],...n},e.push(d),c=d}const r=I(u.question,u.response,a===null);r.data.importSource={runner:"claude-code",sessionId:t,itemIds:u.itemIds,...n},r.data.source={question:r.data.question,response:r.data.response},k(r),r.data.attachments=v(u),e.push(r);const h=u.parentItemId?m.get(u.parentItemId):void 0;h?l(h,r):a&&l(a,r),c&&l(c,r);for(const d of u.itemIds)m.set(d,r);a=r}return{nodes:g(e,i),edges:i}}function E(o,t){const s=y(o).finish();return s?C(s.turns,s.sessionId,"claude-code",t,s.cwd):null}function R(o){return y(o).toConversation()}export{$ as ClaudeSessionCollector,E as claudeCodeSessionAsBranch,R as claudeCodeSessionConversation};
@@ -1,12 +0,0 @@
1
- import{q as p,n as d,B as m}from"./index-C8yf-QJz.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-B7orUlMM.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
- `),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
- `),N=n=>typeof n=="string"?n:Array.isArray(n)?n.map(t=>t?.text??"").filter(Boolean).join(`
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}
5
-
6
- ${s}`:s}}else if(e.role==="assistant"){const s=L(e.content);if(s.trim()){const o=this.ensure();o.response=o.response?`${o.response}
7
-
8
- ${s}`:s}}}else if((e.type==="function_call"||e.type==="custom_tool_call")&&e.call_id&&e.name){const s=String(e.arguments??e.input??""),o=_(e.name),i=h(s,o==="edit"||o==="write"?w:v),r=o==="read"?(()=>{try{const a=JSON.parse(s);return typeof a.path=="string"&&a.path?[a.path]:[]}catch{return[]}})():[];this.pendingCalls.set(e.call_id,{name:e.name,call:i.text,paths:o==="edit"?B(s):r,op:o})}else if((e.type==="function_call_output"||e.type==="custom_tool_call_output")&&e.call_id){const s=this.pendingCalls.get(e.call_id);if(s){const o=this.ensure(),i=h(N(e.output),A);o.tools.push({name:s.name,call:s.call,result:i.text,truncated:i.truncated,...s.paths.length?{paths:s.paths}:{},op:s.op,nativeCallId:e.call_id}),this.pendingCalls.delete(e.call_id)}}}}finish(){if(this.flush(),!this.sessionId||!this.sawItems)return null;const t=[];let e;for(const i of this.turns){const r=t[t.length-1];!i.question.trim()&&r?(i.compactionBefore&&(e=e??i.compactionBefore),i.response&&(r.response=r.response?`${r.response}
9
-
10
- ${i.response}`:i.response),r.tools.push(...i.tools),r.itemIds.push(...i.itemIds)):(e&&!i.compactionBefore&&(i.compactionBefore=e),e=void 0,t.push(i))}this.turns=t;const s=this.cwd.split("/").filter(Boolean).pop(),o=this.firstQuestion?.split(`
11
- `)[0].slice(0,60)||["codex",s,this.day].filter(Boolean).join(" · ");return{sessionId:this.sessionId,title:o,turns:g(this.turns),subagent:!!this.parentThreadId,...this.cwd?{cwd:this.cwd}:{}}}toConversation(){const t=this.finish();return!t||t.turns.length===0?null:{title:t.title,messageCount:t.turns.length,source:"codex",sessionId:t.sessionId,build:()=>j(t.turns,t.sessionId,t.cwd)}}}function f(n){const t=new $;for(const e of n.split(`
12
- `))t.feedLine(e);return t}function j(n,t,e){const s=e?{cwd:e}:{},o=[],i=[];let r=null;for(const a of n){let l=null;if(a.compactionBefore){const u=p(a.compactionBefore,"",!1);u.data.stepKind="note",u.data.importSource={runner:"codex",sessionId:t,itemIds:[],...s},x(u),o.push(u),l=u}const c=p(a.question||"(tool-only turn)",a.response,r===null);c.data.importSource={runner:"codex",sessionId:t,itemIds:a.itemIds,...s},c.data.source={question:c.data.question,response:c.data.response},c.data.attachments=T(a),C(c),o.push(c),r&&i.push({id:d(),source:r.id,target:c.id,type:"smoothstep"}),l&&i.push({id:d(),source:l.id,target:c.id,type:"smoothstep"}),r=c}return{nodes:m(o,i),edges:i}}function F(n,t){const e=f(n).finish();return e?y(e.turns,e.sessionId,"codex",t,e.cwd):null}function J(n){return f(n).toConversation()}export{$ as CodexSessionCollector,j as buildGraphFromTurns,F as codexSessionAsBranch,J as codexSessionConversation};