@koda-sl/baker-bridge 0.143.0-dev.d167daeeb → 0.144.0

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 (45) hide show
  1. package/README.md +13 -12
  2. package/dist/hono/agent.d.ts.map +1 -1
  3. package/dist/hono/agent.js +0 -3
  4. package/dist/hono/agent.js.map +1 -1
  5. package/dist/hono/bridge-job.d.ts +0 -16
  6. package/dist/hono/bridge-job.d.ts.map +1 -1
  7. package/dist/hono/bridge-job.js +23 -67
  8. package/dist/hono/bridge-job.js.map +1 -1
  9. package/dist/hono/bridge-job.test.js +66 -31
  10. package/dist/hono/bridge-job.test.js.map +1 -1
  11. package/dist/hono/publish-handoff.d.ts +5 -53
  12. package/dist/hono/publish-handoff.d.ts.map +1 -1
  13. package/dist/hono/publish-handoff.js +21 -194
  14. package/dist/hono/publish-handoff.js.map +1 -1
  15. package/dist/hono/publish-handoff.test.js +21 -54
  16. package/dist/hono/publish-handoff.test.js.map +1 -1
  17. package/dist/hono/runtime-files.d.ts +0 -1
  18. package/dist/hono/runtime-files.d.ts.map +1 -1
  19. package/dist/hono/runtime-files.js +0 -1
  20. package/dist/hono/runtime-files.js.map +1 -1
  21. package/dist/hono/turn-events.d.ts +1 -1
  22. package/dist/hono/turn-events.d.ts.map +1 -1
  23. package/dist/hono/turn-events.js.map +1 -1
  24. package/dist/hono/types.d.ts +2 -0
  25. package/dist/hono/types.d.ts.map +1 -1
  26. package/dist/review/evidence-block.d.ts.map +1 -1
  27. package/dist/review/evidence-block.js +3 -1
  28. package/dist/review/evidence-block.js.map +1 -1
  29. package/dist/review/evidence-block.test.js +33 -1
  30. package/dist/review/evidence-block.test.js.map +1 -1
  31. package/dist/review/evidence.d.ts +3 -0
  32. package/dist/review/evidence.d.ts.map +1 -1
  33. package/dist/review/evidence.js +27 -11
  34. package/dist/review/evidence.js.map +1 -1
  35. package/dist/review/evidence.test.d.ts +2 -0
  36. package/dist/review/evidence.test.d.ts.map +1 -0
  37. package/dist/review/evidence.test.js +94 -0
  38. package/dist/review/evidence.test.js.map +1 -0
  39. package/dist/review/transcripts.d.ts +29 -6
  40. package/dist/review/transcripts.d.ts.map +1 -1
  41. package/dist/review/transcripts.js +100 -18
  42. package/dist/review/transcripts.js.map +1 -1
  43. package/dist/review/transcripts.test.js +37 -0
  44. package/dist/review/transcripts.test.js.map +1 -1
  45. package/package.json +1 -1
@@ -9,6 +9,7 @@ function report(overrides = {}) {
9
9
  {
10
10
  threadId: "thread-1",
11
11
  sessionIds: ["sess-1"],
12
+ sessionIdsWithoutTranscript: [],
12
13
  files: ["/home/u/.claude/projects/p/sess-1.jsonl"],
13
14
  subagentFiles: ["/home/u/.claude/projects/p/sess-1/subagents/a.jsonl"],
14
15
  },
@@ -56,7 +57,16 @@ describe("renderEvidenceBlock", () => {
56
57
  digestDir: "/tmp/d",
57
58
  paths,
58
59
  evidence: report({
59
- threads: [{ threadId: "t2", sessionIds: [], files: [], subagentFiles: [], missing: "no_session_file" }],
60
+ threads: [
61
+ {
62
+ threadId: "t2",
63
+ sessionIds: [],
64
+ sessionIdsWithoutTranscript: [],
65
+ files: [],
66
+ subagentFiles: [],
67
+ missing: "no_session_file",
68
+ },
69
+ ],
60
70
  transcriptsFound: 0,
61
71
  transcriptsMissing: 1,
62
72
  }),
@@ -66,6 +76,28 @@ describe("renderEvidenceBlock", () => {
66
76
  expect(block).toContain("t2: **missing**");
67
77
  expect(block).toContain("no session file");
68
78
  });
79
+ it("names a session the thread ran under whose transcript is gone, beside the ones it read", () => {
80
+ const block = renderEvidenceBlock({
81
+ digestDir: "/tmp/d",
82
+ paths,
83
+ evidence: report({
84
+ threads: [
85
+ {
86
+ threadId: "thread-1",
87
+ sessionIds: ["sess-0", "sess-1"],
88
+ sessionIdsWithoutTranscript: ["sess-0"],
89
+ files: ["/home/u/.claude/projects/p/sess-1.jsonl"],
90
+ subagentFiles: [],
91
+ },
92
+ ],
93
+ transcriptsMissing: 1,
94
+ }),
95
+ chatId: "chat_1",
96
+ threadIds: ["thread-1"],
97
+ });
98
+ expect(block).toContain("/home/u/.claude/projects/p/sess-1.jsonl");
99
+ expect(block).toContain("no transcript for session sess-0");
100
+ });
69
101
  it("puts the digest before the raw transcript in the reading order", () => {
70
102
  // Starting on the JSONL spends the whole context arriving at numbers the
71
103
  // digest already has — and getting them wrong on the way.
@@ -1 +1 @@
1
- {"version":3,"file":"evidence-block.test.js","sourceRoot":"","sources":["../../src/review/evidence-block.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,MAAM,KAAK,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC;AAExC,SAAS,MAAM,CAAC,SAAS,GAA4B,EAAE;IACrD,OAAO;QACL,WAAW,EAAE,0BAA0B;QACvC,OAAO,EAAE;YACP;gBACE,QAAQ,EAAE,UAAU;gBACpB,UAAU,EAAE,CAAC,QAAQ,CAAC;gBACtB,KAAK,EAAE,CAAC,yCAAyC,CAAC;gBAClD,aAAa,EAAE,CAAC,qDAAqD,CAAC;aACvE;SACF;QACD,gBAAgB,EAAE,CAAC;QACnB,kBAAkB,EAAE,CAAC;QACrB,eAAe,EAAE,IAAI;QACrB,iBAAiB,EAAE,IAAI;QACvB,kBAAkB,EAAE,IAAI;QACxB,mBAAmB,EAAE,IAAI;QACzB,oBAAoB,EAAE,IAAI;QAC1B,aAAa,EAAE,IAAI;QACnB,cAAc,EAAE,EAAE;QAClB,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,KAAK,GAAG,mBAAmB,CAAC;YAChC,SAAS,EAAE,0BAA0B;YACrC,KAAK;YACL,QAAQ,EAAE,MAAM,EAAE;YAClB,MAAM,EAAE,QAAQ;YAChB,SAAS,EAAE,CAAC,UAAU,CAAC;SACxB,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,yCAAyC,CAAC,CAAC;QACnE,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4EAA4E,EAAE,GAAG,EAAE;QACpF,2EAA2E;QAC3E,+DAA+D;QAC/D,MAAM,KAAK,GAAG,mBAAmB,CAAC;YAChC,SAAS,EAAE,QAAQ;YACnB,KAAK;YACL,QAAQ,EAAE,MAAM,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAAC;YACzE,MAAM,EAAE,QAAQ;YAChB,SAAS,EAAE,CAAC,UAAU,CAAC;SACxB,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC;QACvD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gFAAgF,EAAE,GAAG,EAAE;QACxF,MAAM,KAAK,GAAG,mBAAmB,CAAC;YAChC,SAAS,EAAE,QAAQ;YACnB,KAAK;YACL,QAAQ,EAAE,MAAM,CAAC;gBACf,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC;gBACvG,gBAAgB,EAAE,CAAC;gBACnB,kBAAkB,EAAE,CAAC;aACtB,CAAC;YACF,MAAM,EAAE,QAAQ;YAChB,SAAS,EAAE,CAAC,IAAI,CAAC;SAClB,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,yEAAyE;QACzE,0DAA0D;QAC1D,MAAM,KAAK,GAAG,mBAAmB,CAAC;YAChC,SAAS,EAAE,QAAQ;YACnB,KAAK;YACL,QAAQ,EAAE,MAAM,EAAE;YAClB,MAAM,EAAE,QAAQ;YAChB,SAAS,EAAE,CAAC,UAAU,CAAC;SACxB,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC;IACxF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,4EAA4E;QAC5E,4EAA4E;QAC5E,MAAM,KAAK,GAAG,mBAAmB,CAAC;YAChC,SAAS,EAAE,QAAQ;YACnB,KAAK;YACL,QAAQ,EAAE,MAAM,EAAE;YAClB,MAAM,EAAE,QAAQ;YAChB,SAAS,EAAE,CAAC,UAAU,CAAC;SACxB,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC;QAClD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,GAAG,EAAE;QAClF,iEAAiE;QACjE,0EAA0E;QAC1E,uDAAuD;QACvD,MAAM,KAAK,GAAG,mBAAmB,CAAC;YAChC,SAAS,EAAE,QAAQ;YACnB,KAAK;YACL,QAAQ,EAAE,MAAM,EAAE;YAClB,MAAM,EAAE,QAAQ;YAChB,SAAS,EAAE,CAAC,UAAU,CAAC;SACxB,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"evidence-block.test.js","sourceRoot":"","sources":["../../src/review/evidence-block.test.ts"],"names":[],"mappings":"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"}
@@ -16,12 +16,15 @@ export type EvidenceReport = {
16
16
  threads: {
17
17
  threadId: string;
18
18
  sessionIds: string[];
19
+ /** Session ids the thread ran under whose transcript is not on disk. */
20
+ sessionIdsWithoutTranscript: string[];
19
21
  files: string[];
20
22
  subagentFiles: string[];
21
23
  /** Present when this thread's transcript could not be read, and why. */
22
24
  missing?: string;
23
25
  }[];
24
26
  transcriptsFound: number;
27
+ /** Threads with no transcript at all, plus every session a thread ran under whose transcript is gone. */
25
28
  transcriptsMissing: number;
26
29
  debugLogPresent: boolean;
27
30
  turnEventsPresent: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"evidence.d.ts","sourceRoot":"","sources":["../../src/review/evidence.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,aAAa,EAalB,KAAK,gBAAgB,EAErB,KAAK,aAAa,EAEnB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGxD;;;;;;;;;GASG;AAEH,eAAO,MAAM,UAAU,6BAA6B,CAAC;AAKrD,MAAM,MAAM,cAAc,GAAG;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE;QACP,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,wEAAwE;QACxE,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,EAAE,CAAC;IACJ,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,OAAO,CAAC;IACzB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,aAAa,EAAE,OAAO,CAAC;IACvB,qDAAqD;IACrD,cAAc,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACnD,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,gBAAgB,CAAC;IACzB,GAAG,EAAE,aAAa,EAAE,CAAC;IACrB,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,cAAc,CAAC;IACzB,kEAAkE;IAClE,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE;IACpC,MAAM,EAAE,gBAAgB,CAAC;IACzB,GAAG,EAAE,aAAa,EAAE,CAAC;IACrB,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,cAAc,CAAC;CAC1B,GAAG,aAAa,EAAE,CAiBlB;AAkBD,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAU5D;AA+DD;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GACnD,OAAO,CAAC,YAAY,CAAC,CAyCvB"}
1
+ {"version":3,"file":"evidence.d.ts","sourceRoot":"","sources":["../../src/review/evidence.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,aAAa,EAalB,KAAK,gBAAgB,EAErB,KAAK,aAAa,EAEnB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGxD;;;;;;;;;GASG;AAEH,eAAO,MAAM,UAAU,6BAA6B,CAAC;AAKrD,MAAM,MAAM,cAAc,GAAG;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE;QACP,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,wEAAwE;QACxE,2BAA2B,EAAE,MAAM,EAAE,CAAC;QACtC,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,wEAAwE;QACxE,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,EAAE,CAAC;IACJ,gBAAgB,EAAE,MAAM,CAAC;IACzB,yGAAyG;IACzG,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,OAAO,CAAC;IACzB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,aAAa,EAAE,OAAO,CAAC;IACvB,qDAAqD;IACrD,cAAc,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACnD,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,gBAAgB,CAAC;IACzB,GAAG,EAAE,aAAa,EAAE,CAAC;IACrB,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,cAAc,CAAC;IACzB,kEAAkE;IAClE,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE;IACpC,MAAM,EAAE,gBAAgB,CAAC;IACzB,GAAG,EAAE,aAAa,EAAE,CAAC;IACrB,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,cAAc,CAAC;CAC1B,GAAG,aAAa,EAAE,CAiBlB;AAkBD,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAU5D;AA+ED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GACnD,OAAO,CAAC,YAAY,CAAC,CA8CvB"}
@@ -85,25 +85,32 @@ async function readTranscriptLines(transcripts) {
85
85
  const skippedForSize = [];
86
86
  const lines = [];
87
87
  for (const thread of transcripts) {
88
+ const seenUuids = new Set();
88
89
  // Grouped by thread rather than interleaved by clock: two threads are two
89
90
  // conversations, and a turn stream that alternates between them reads as
90
91
  // one conversation nobody had. Each line is stamped instead, so a finding
91
92
  // can name the thread it happened in.
92
- for (const file of thread.files) {
93
- await absorbFile(file, { threadId: thread.threadId }, lines, skippedForSize);
94
- }
95
- // A subagent's own file records its prompt as an ordinary `user` line — the
96
- // `isSidechain` flag lives only in the parent's copy. Taken at face value
97
- // every fan-out opens a turn the marketer never took, and every per-turn
98
- // number is then divided by a turn count that is wrong.
99
- for (const file of thread.subagentFiles) {
100
- await absorbFile(file, { threadId: thread.threadId, isSubagent: true }, lines, skippedForSize);
93
+ //
94
+ // Within a thread, session by session, each followed by the subagents spawned in it: the
95
+ // digest charges a line to the turn open when it is read, so a subagent read
96
+ // after every session would be charged to the thread's last turn.
97
+ for (const session of thread.sessions) {
98
+ if (session.file !== null) {
99
+ await absorbFile(session.file, { threadId: thread.threadId }, lines, skippedForSize, seenUuids);
100
+ }
101
+ // A subagent's own file records its prompt as an ordinary `user` line — the
102
+ // `isSidechain` flag lives only in the parent's copy. Taken at face value
103
+ // every fan-out opens a turn the marketer never took, and every per-turn
104
+ // number is then divided by a turn count that is wrong.
105
+ for (const file of session.subagentFiles) {
106
+ await absorbFile(file, { threadId: thread.threadId, isSubagent: true }, lines, skippedForSize, seenUuids);
107
+ }
101
108
  }
102
109
  }
103
110
  return { lines, skippedForSize };
104
111
  }
105
112
  /** Read one transcript, stamp every line with where it came from, or record why not. */
106
- async function absorbFile(file, stamp, into, skippedForSize) {
113
+ async function absorbFile(file, stamp, into, skippedForSize, seenUuids) {
107
114
  const bytes = await byteSize(file);
108
115
  if (bytes !== null && bytes > MAX_TRANSCRIPT_BYTES) {
109
116
  skippedForSize.push({ path: file, bytes });
@@ -114,6 +121,14 @@ async function absorbFile(file, stamp, into, skippedForSize) {
114
121
  return;
115
122
  }
116
123
  for (const line of parseTranscript(body)) {
124
+ // A fork starts with a copy of the conversation it forked from, under the
125
+ // same uuids: the first file to carry a line is the one that counts it.
126
+ if (line.uuid !== undefined) {
127
+ if (seenUuids.has(line.uuid)) {
128
+ continue;
129
+ }
130
+ seenUuids.add(line.uuid);
131
+ }
117
132
  into.push({ ...line, ...stamp });
118
133
  }
119
134
  }
@@ -149,12 +164,13 @@ export async function buildReviewDigest(threadIds, options = {}) {
149
164
  threads: transcripts.map((thread) => ({
150
165
  threadId: thread.threadId,
151
166
  sessionIds: thread.sessionIds,
167
+ sessionIdsWithoutTranscript: thread.sessionIdsWithoutTranscript,
152
168
  files: thread.files,
153
169
  subagentFiles: thread.subagentFiles,
154
170
  ...(thread.missing === undefined ? {} : { missing: thread.missing }),
155
171
  })),
156
172
  transcriptsFound: transcripts.filter((thread) => thread.files.length > 0).length,
157
- transcriptsMissing: transcripts.filter((thread) => thread.missing !== undefined).length,
173
+ transcriptsMissing: transcripts.reduce((missing, thread) => missing + (thread.missing === "no_session_file" ? 1 : thread.sessionIdsWithoutTranscript.length), 0),
158
174
  debugLogPresent: debugBody !== null,
159
175
  turnEventsPresent: (await readIfPresent(paths.turnEvents)) !== null,
160
176
  relayErrorsPresent: (await readIfPresent(paths.relayErrors)) !== null,
@@ -1 +1 @@
1
- {"version":3,"file":"evidence.js","sourceRoot":"","sources":["../../src/review/evidence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EACL,cAAc,EACd,qBAAqB,EAGrB,UAAU,EACV,eAAe,EACf,SAAS,EACT,cAAc,EACd,YAAY,EACZ,WAAW,EACX,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,eAAe,GAKhB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,wBAAwB,EAA0B,MAAM,kBAAkB,CAAC;AAEpF;;;;;;;;;GASG;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG,0BAA0B,CAAC;AAErD,uEAAuE;AACvE,MAAM,oBAAoB,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AAkC/C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc,CAAC,KAK9B;IACC,OAAO;QACL,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;QAC9D,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;QACxD,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;QACxD,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;QAC1D,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;QACxD,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;QACnE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;QACjD,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;QAC1D,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;QAC3E;YACE,IAAI,EAAE,YAAY;YAClB,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;SACnG;QACD,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;KACjF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,IAAY;IACvC,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,IAAY;IAClC,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAWD,MAAM,UAAU,WAAW,CAAC,WAAmB;IAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC5C,OAAO;QACL,QAAQ,EAAE,4BAA4B;QACtC,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC;QAChD,WAAW,EAAE,IAAI,CAAC,SAAS,EAAE,oBAAoB,CAAC;QAClD,YAAY,EAAE,IAAI,CAAC,WAAW,EAAE,mCAAmC,CAAC;QACpE,aAAa,EAAE,IAAI,CAAC,WAAW,EAAE,qCAAqC,CAAC;QACvE,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,0BAA0B,CAAC;KACtD,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,mBAAmB,CAChC,WAAyC;IAEzC,MAAM,cAAc,GAAqC,EAAE,CAAC;IAC5D,MAAM,KAAK,GAAqB,EAAE,CAAC;IACnC,KAAK,MAAM,MAAM,IAAI,WAAW,EAAE,CAAC;QACjC,0EAA0E;QAC1E,yEAAyE;QACzE,0EAA0E;QAC1E,sCAAsC;QACtC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAChC,MAAM,UAAU,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;QAC/E,CAAC;QACD,4EAA4E;QAC5E,0EAA0E;QAC1E,yEAAyE;QACzE,wDAAwD;QACxD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YACxC,MAAM,UAAU,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;QACjG,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;AACnC,CAAC;AAED,wFAAwF;AACxF,KAAK,UAAU,UAAU,CACvB,IAAY,EACZ,KAAiD,EACjD,IAAsB,EACtB,cAAgD;IAEhD,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,GAAG,oBAAoB,EAAE,CAAC;QACnD,cAAc,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3C,OAAO;IACT,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO;IACT,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;IACnC,CAAC;AACH,CAAC;AAED,2FAA2F;AAC3F,SAAS,iBAAiB,CAAC,IAAY;IACrC,IAAI,CAAC;QACH,OAAO,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAkB,CAAC,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,SAA4B,EAC5B,OAAO,GAA2C,EAAE;IAEpD,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,kBAAkB,CAAC,WAAW,EAAE,CAAC;IAC5E,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,UAAU,CAAC;IACtC,MAAM,KAAK,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;IAEvC,MAAM,WAAW,GAAG,MAAM,wBAAwB,CAAC,SAAS,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;IAC/E,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,MAAM,mBAAmB,CAAC,WAAW,CAAC,CAAC;IACzE,MAAM,MAAM,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;IAE5C,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,UAAU,CAAe,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAEjF,MAAM,WAAW,GAAG,MAAM,aAAa,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAE5E,MAAM,QAAQ,GAAmB;QAC/B,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,OAAO,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,MAAyB,EAAE,EAAE,CAAC,CAAC;YACvD,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;SACrE,CAAC,CAAC;QACH,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM;QAChF,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,MAAM;QACvF,eAAe,EAAE,SAAS,KAAK,IAAI;QACnC,iBAAiB,EAAE,CAAC,MAAM,aAAa,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,KAAK,IAAI;QACnE,kBAAkB,EAAE,CAAC,MAAM,aAAa,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,KAAK,IAAI;QACrE,mBAAmB,EAAE,CAAC,MAAM,aAAa,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,KAAK,IAAI;QACvE,oBAAoB,EAAE,WAAW,KAAK,IAAI;QAC1C,aAAa,EAAE,CAAC,MAAM,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI;QAC3D,cAAc;KACf,CAAC;IAEF,MAAM,QAAQ,GAAG,cAAc,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IAEnE,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAE3G,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AAC1D,CAAC"}
1
+ {"version":3,"file":"evidence.js","sourceRoot":"","sources":["../../src/review/evidence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=evidence.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence.test.d.ts","sourceRoot":"","sources":["../../src/review/evidence.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,94 @@
1
+ import { mkdirSync, rmSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { afterAll, describe, expect, it, vi } from "vitest";
4
+ import { buildReviewDigest } from "./evidence.js";
5
+ import { projectSlug } from "./transcripts.js";
6
+ // The Session's home is the Runtime's: both the bridge's `~/.baker` and the
7
+ // CLI's `~/.claude/projects` resolve under it.
8
+ const root = vi.hoisted(() => {
9
+ const { mkdtempSync } = require("node:fs");
10
+ const { tmpdir } = require("node:os");
11
+ const { join } = require("node:path");
12
+ return mkdtempSync(join(tmpdir(), "review-evidence-"));
13
+ });
14
+ const bakerHome = join(root, ".baker");
15
+ const projectsRoot = join(root, ".claude", "projects");
16
+ vi.mock("node:os", async () => {
17
+ const actual = await vi.importActual("node:os");
18
+ return { ...actual, homedir: () => root };
19
+ });
20
+ afterAll(() => {
21
+ rmSync(root, { recursive: true, force: true });
22
+ });
23
+ function jsonl(lines) {
24
+ return lines.map((line) => `${JSON.stringify(line)}\n`).join("");
25
+ }
26
+ function userLine(uuid, text) {
27
+ return { type: "user", uuid, message: { role: "user", content: text } };
28
+ }
29
+ function callLine(uuid, id, command) {
30
+ return {
31
+ type: "assistant",
32
+ uuid,
33
+ message: { role: "assistant", content: [{ type: "tool_use", id, name: "Bash", input: { command } }] },
34
+ };
35
+ }
36
+ function resultLine(uuid, id, content, isError = false) {
37
+ return {
38
+ type: "user",
39
+ uuid,
40
+ message: { role: "user", content: [{ type: "tool_result", tool_use_id: id, content, is_error: isError }] },
41
+ };
42
+ }
43
+ describe("buildReviewDigest", () => {
44
+ // The shape every chat has: each message forks the session (the fork copies the
45
+ // conversation so far under the same line uuids), `/publish` runs in a session
46
+ // the thread never adopts, and a subagent lives under the id it was spawned in.
47
+ it("reads every session a thread ran under once, publish and earlier subagents included", async () => {
48
+ const projectRoot = join(root, "repo");
49
+ const dir = join(projectsRoot, projectSlug(projectRoot));
50
+ mkdirSync(join(dir, "s-turn1", "subagents"), { recursive: true });
51
+ const turn1 = [
52
+ userLine("u1", "Build the landing"),
53
+ callLine("a1", "b1", "pnpm build"),
54
+ resultLine("r1", "b1", "built"),
55
+ ];
56
+ writeFileSync(join(dir, "s-turn1.jsonl"), jsonl(turn1));
57
+ writeFileSync(join(dir, "s-turn1", "subagents", "agent-visual.jsonl"), jsonl([
58
+ userLine("v0", "Check the hero at 390px"),
59
+ callLine("v1", "vb1", "agent-browser help"),
60
+ resultLine("v2", "vb1", "Blocked by guard-agent-browser: use the wrapper", true),
61
+ ]));
62
+ writeFileSync(join(dir, "s-publish.jsonl"), jsonl([
63
+ userLine("p0", "/publish"),
64
+ callLine("p1", "pb1", "pnpm verify"),
65
+ resultLine("p2", "pb1", "verify failed", true),
66
+ ]));
67
+ writeFileSync(join(dir, "s-turn3.jsonl"), jsonl([...turn1, userLine("u3", "Make the hero blue"), callLine("a3", "b3", "pnpm build")]));
68
+ mkdirSync(join(bakerHome, "sessions"), { recursive: true });
69
+ writeFileSync(join(bakerHome, "sessions", "thread-1.json"), JSON.stringify({ version: 2, sessionId: "s-turn3", updatedAtMs: 3 }));
70
+ writeFileSync(join(bakerHome, "turn-events.jsonl"), jsonl(["s-turn1", "s-publish", "s-turn3", "s-reaped"].map((sessionId, index) => ({
71
+ threadId: "thread-1",
72
+ turnId: `turn-${index}`,
73
+ event: "session",
74
+ detail: { sessionId },
75
+ }))));
76
+ const result = await buildReviewDigest(["thread-1"], { projectRoot, dir: join(root, "digest") });
77
+ expect(result.digest.totals.turns).toBe(3);
78
+ expect(result.digest.toolCalls.map((call) => call.toolUseId).sort()).toEqual(["b1", "b3", "pb1", "vb1"]);
79
+ expect(result.digest.guards.map((guard) => guard.message)).toEqual([
80
+ expect.stringContaining("guard-agent-browser"),
81
+ "verify failed",
82
+ ]);
83
+ // A subagent counts toward the turn that spawned it, not the thread's last turn.
84
+ const turnOf = (id) => result.digest.toolCalls.find((call) => call.toolUseId === id)?.turn;
85
+ expect(turnOf("vb1")).toBe(turnOf("b1"));
86
+ expect(result.evidence.threads[0]?.subagentFiles).toEqual([
87
+ join(dir, "s-turn1", "subagents", "agent-visual.jsonl"),
88
+ ]);
89
+ // A session the thread ran under whose transcript is gone is missing evidence, said out loud.
90
+ expect(result.evidence.threads[0]?.sessionIdsWithoutTranscript).toEqual(["s-reaped"]);
91
+ expect(result.evidence.transcriptsMissing).toBe(1);
92
+ });
93
+ });
94
+ //# sourceMappingURL=evidence.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence.test.js","sourceRoot":"","sources":["../../src/review/evidence.test.ts"],"names":[],"mappings":"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"}
@@ -6,18 +6,41 @@
6
6
  * this sandbox. That file is append-only, so it survives compaction: a
7
7
  * compaction adds a summary line, it never removes one.
8
8
  *
9
- * The mapping runs thread id → `~/.baker/sessions/<threadId>.json` → session id
10
- * → `~/.claude/projects/<cwd-slug>/<sessionId>.jsonl`, plus the subagent
11
- * directory beside it. A thread whose session file is missing is reported rather
12
- * than skipped: "we could not read this thread" and "this thread had no tool
13
- * calls" must never look the same to the reviewer.
9
+ * A thread is not one SDK session. Every message resumes the last one as a
10
+ * fork, a stall or a restart forks again, and `/publish` runs in a session of
11
+ * its own the thread never adopts. The bridge records each id a turn runs under
12
+ * as a `session` line in `~/.baker/turn-events.jsonl`; the thread's session file
13
+ * (`~/.baker/sessions/<threadId>.json`) names only the latest. Both are read,
14
+ * and each id maps to `~/.claude/projects/<cwd-slug>/<sessionId>.jsonl` plus the
15
+ * subagent directory beside it — a subagent lives under the id it was spawned
16
+ * in, so reading the latest alone drops every earlier turn's fan-out.
17
+ *
18
+ * A fork copies the conversation so far into its new file under the same line
19
+ * uuids, so the files overlap; the reader dedupes by uuid.
20
+ *
21
+ * Whatever cannot be read is reported rather than skipped: "we could not read
22
+ * this" and "this had no tool calls" must never look the same to the reviewer.
14
23
  */
15
24
  /** Claude Code names a project directory after its cwd, with every separator folded to `-`. */
16
25
  export declare function projectSlug(cwd: string): string;
26
+ /** One session a thread ran under: its own transcript and the subagents spawned in it. */
27
+ export type SessionTranscripts = {
28
+ sessionId: string;
29
+ /** The session's transcript, or null when it is not on disk. */
30
+ file: string | null;
31
+ subagentFiles: string[];
32
+ };
17
33
  export type ThreadTranscripts = {
18
34
  threadId: string;
19
- /** Every session id this thread ran under. A stall fork resumes into a new one. */
35
+ /**
36
+ * Per session, in run order. Read in this order so a subagent follows the turn
37
+ * that spawned it, not the thread's last turn.
38
+ */
39
+ sessions: SessionTranscripts[];
40
+ /** Every session id this thread ran under, in the order it first ran under each. */
20
41
  sessionIds: string[];
42
+ /** Session ids the thread ran under whose transcript file is not on disk. */
43
+ sessionIdsWithoutTranscript: string[];
21
44
  /** Transcript files that exist on disk. */
22
45
  files: string[];
23
46
  /** Subagent transcript files, one per fan-out task. */
@@ -1 +1 @@
1
- {"version":3,"file":"transcripts.d.ts","sourceRoot":"","sources":["../../src/review/transcripts.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;GAaG;AAEH,+FAA+F;AAC/F,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,mFAAmF;IACnF,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,uDAAuD;IACvD,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gFAAgF;IAChF,OAAO,CAAC,EAAE,iBAAiB,GAAG,eAAe,CAAC;CAC/C,CAAC;AA6BF,MAAM,MAAM,uBAAuB,GAAG;IACpC,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CA0B9B"}
1
+ {"version":3,"file":"transcripts.d.ts","sourceRoot":"","sources":["../../src/review/transcripts.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,+FAA+F;AAC/F,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,0FAA0F;AAC1F,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,oFAAoF;IACpF,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,6EAA6E;IAC7E,2BAA2B,EAAE,MAAM,EAAE,CAAC;IACtC,2CAA2C;IAC3C,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,uDAAuD;IACvD,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gFAAgF;IAChF,OAAO,CAAC,EAAE,iBAAiB,GAAG,eAAe,CAAC;CAC/C,CAAC;AA6EF,MAAM,MAAM,uBAAuB,GAAG;IACpC,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAkB9B"}
@@ -10,11 +10,20 @@ import { bridgeRuntimeFiles, runtimeFileStore } from "../hono/runtime-files.js";
10
10
  * this sandbox. That file is append-only, so it survives compaction: a
11
11
  * compaction adds a summary line, it never removes one.
12
12
  *
13
- * The mapping runs thread id → `~/.baker/sessions/<threadId>.json` → session id
14
- * → `~/.claude/projects/<cwd-slug>/<sessionId>.jsonl`, plus the subagent
15
- * directory beside it. A thread whose session file is missing is reported rather
16
- * than skipped: "we could not read this thread" and "this thread had no tool
17
- * calls" must never look the same to the reviewer.
13
+ * A thread is not one SDK session. Every message resumes the last one as a
14
+ * fork, a stall or a restart forks again, and `/publish` runs in a session of
15
+ * its own the thread never adopts. The bridge records each id a turn runs under
16
+ * as a `session` line in `~/.baker/turn-events.jsonl`; the thread's session file
17
+ * (`~/.baker/sessions/<threadId>.json`) names only the latest. Both are read,
18
+ * and each id maps to `~/.claude/projects/<cwd-slug>/<sessionId>.jsonl` plus the
19
+ * subagent directory beside it — a subagent lives under the id it was spawned
20
+ * in, so reading the latest alone drops every earlier turn's fan-out.
21
+ *
22
+ * A fork copies the conversation so far into its new file under the same line
23
+ * uuids, so the files overlap; the reader dedupes by uuid.
24
+ *
25
+ * Whatever cannot be read is reported rather than skipped: "we could not read
26
+ * this" and "this had no tool calls" must never look the same to the reviewer.
18
27
  */
19
28
  /** Claude Code names a project directory after its cwd, with every separator folded to `-`. */
20
29
  export function projectSlug(cwd) {
@@ -36,6 +45,53 @@ async function readSessionId(threadId) {
36
45
  return undefined;
37
46
  }
38
47
  }
48
+ /**
49
+ * Session ids per thread, in the order the bridge first saw each one.
50
+ *
51
+ * Absent or unreadable is an empty map: a Runtime whose bridge predates the
52
+ * `session` event still has the session file, which is what it had before.
53
+ */
54
+ async function readTurnSessionIds() {
55
+ const byThread = new Map();
56
+ const result = await runtimeFileStore.readText(bridgeRuntimeFiles.turnEventsFile());
57
+ if (!result.ok) {
58
+ return byThread;
59
+ }
60
+ for (const line of result.value.split("\n")) {
61
+ const sessionId = sessionEventId(line);
62
+ if (!sessionId) {
63
+ continue;
64
+ }
65
+ const ids = byThread.get(sessionId.threadId) ?? [];
66
+ if (!ids.includes(sessionId.sessionId)) {
67
+ ids.push(sessionId.sessionId);
68
+ }
69
+ byThread.set(sessionId.threadId, ids);
70
+ }
71
+ return byThread;
72
+ }
73
+ function sessionEventId(line) {
74
+ if (line.trim().length === 0) {
75
+ return undefined;
76
+ }
77
+ let parsed;
78
+ try {
79
+ parsed = JSON.parse(line);
80
+ }
81
+ catch {
82
+ // A truncated final line is normal on a file still being appended to.
83
+ return undefined;
84
+ }
85
+ if (typeof parsed !== "object" || parsed === null) {
86
+ return undefined;
87
+ }
88
+ const event = parsed;
89
+ if (event.event !== "session" || typeof event.threadId !== "string") {
90
+ return undefined;
91
+ }
92
+ const sessionId = event.detail?.sessionId;
93
+ return typeof sessionId === "string" && sessionId.length > 0 ? { threadId: event.threadId, sessionId } : undefined;
94
+ }
39
95
  async function listJsonl(dir) {
40
96
  try {
41
97
  const entries = await readdir(dir);
@@ -57,24 +113,50 @@ export async function resolveThreadTranscripts(threadIds, options = {}) {
57
113
  const projectsRoot = options.projectsRoot ?? join(homedir(), ".claude", "projects");
58
114
  const projectDir = join(projectsRoot, projectSlug(projectRoot));
59
115
  const onDisk = new Set(await listJsonl(projectDir));
116
+ const turnSessionIds = await readTurnSessionIds();
60
117
  const out = [];
61
118
  for (const threadId of threadIds) {
62
- const sessionId = await readSessionId(threadId);
63
- if (!sessionId) {
64
- out.push({ threadId, sessionIds: [], files: [], subagentFiles: [], missing: "no_session_file" });
65
- continue;
119
+ const sessionIds = [...(turnSessionIds.get(threadId) ?? [])];
120
+ const latest = await readSessionId(threadId);
121
+ if (latest && !sessionIds.includes(latest)) {
122
+ sessionIds.push(latest);
66
123
  }
67
- const file = join(projectDir, `${sessionId}.jsonl`);
68
- const files = onDisk.has(file) ? [file] : [];
69
- const subagentFiles = await listJsonl(join(projectDir, sessionId, "subagents"));
70
- out.push({
124
+ out.push(await threadTranscripts(threadId, sessionIds, projectDir, onDisk));
125
+ }
126
+ return out;
127
+ }
128
+ async function threadTranscripts(threadId, sessionIds, projectDir, onDisk) {
129
+ if (sessionIds.length === 0) {
130
+ return {
71
131
  threadId,
72
- sessionIds: [sessionId],
73
- files,
74
- subagentFiles,
75
- ...(files.length === 0 ? { missing: "no_transcript" } : {}),
132
+ sessions: [],
133
+ sessionIds: [],
134
+ sessionIdsWithoutTranscript: [],
135
+ files: [],
136
+ subagentFiles: [],
137
+ missing: "no_session_file",
138
+ };
139
+ }
140
+ const sessions = [];
141
+ for (const sessionId of sessionIds) {
142
+ const file = join(projectDir, `${sessionId}.jsonl`);
143
+ sessions.push({
144
+ sessionId,
145
+ file: onDisk.has(file) ? file : null,
146
+ subagentFiles: await listJsonl(join(projectDir, sessionId, "subagents")),
76
147
  });
77
148
  }
78
- return out;
149
+ const files = sessions.flatMap((session) => (session.file === null ? [] : [session.file]));
150
+ return {
151
+ threadId,
152
+ sessions,
153
+ sessionIds,
154
+ sessionIdsWithoutTranscript: sessions
155
+ .filter((session) => session.file === null)
156
+ .map((session) => session.sessionId),
157
+ subagentFiles: sessions.flatMap((session) => session.subagentFiles),
158
+ files,
159
+ ...(files.length === 0 ? { missing: "no_transcript" } : {}),
160
+ };
79
161
  }
80
162
  //# sourceMappingURL=transcripts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transcripts.js","sourceRoot":"","sources":["../../src/review/transcripts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transcripts.js","sourceRoot":"","sources":["../../src/review/transcripts.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,7 @@ vi.mock("../hono/runtime-files.ts", async () => {
10
10
  bridgeRuntimeFiles: {
11
11
  ...actual.bridgeRuntimeFiles,
12
12
  sessionFile: (threadId) => join(bakerHome, "sessions", `${threadId}.json`),
13
+ turnEventsFile: () => join(bakerHome, "turn-events.jsonl"),
13
14
  },
14
15
  };
15
16
  });
@@ -25,6 +26,9 @@ function writeSession(threadId, body) {
25
26
  mkdirSync(join(bakerHome, "sessions"), { recursive: true });
26
27
  writeFileSync(join(bakerHome, "sessions", `${threadId}.json`), body);
27
28
  }
29
+ function writeTurnEvents(events) {
30
+ writeFileSync(join(bakerHome, "turn-events.jsonl"), events.map((event) => `${JSON.stringify(event)}\n`).join(""));
31
+ }
28
32
  describe("projectSlug", () => {
29
33
  it("folds every path separator and dot, the way Claude Code names its project directory", () => {
30
34
  expect(projectSlug("/home/user/my.repo")).toBe("-home-user-my-repo");
@@ -78,5 +82,38 @@ describe("resolveThreadTranscripts", () => {
78
82
  const result = await resolveThreadTranscripts(["thread-reaped"], { projectRoot, projectsRoot });
79
83
  expect(result[0]?.missing).toBe("no_transcript");
80
84
  });
85
+ it("joins every session a resumed thread ran under, with each one's subagents", async () => {
86
+ // Every message forks the SDK session: the thread's session file names only
87
+ // the last id, while the visual checks of turn 2 sit under the id turn 2 ran in.
88
+ const projectsRoot = mkdtempSync(join(tmpdir(), "projects-"));
89
+ created.push(projectsRoot);
90
+ const projectRoot = "/work/resumed";
91
+ const dir = join(projectsRoot, projectSlug(projectRoot));
92
+ mkdirSync(dir, { recursive: true });
93
+ for (const sessionId of ["s-turn1", "s-turn2", "s-turn3"]) {
94
+ writeFileSync(join(dir, `${sessionId}.jsonl`), "{}\n");
95
+ }
96
+ mkdirSync(join(dir, "s-turn2", "subagents"), { recursive: true });
97
+ writeFileSync(join(dir, "s-turn2", "subagents", "agent-v4.jsonl"), "{}\n");
98
+ writeFileSync(join(dir, "s-turn2", "subagents", "agent-v1.jsonl"), "{}\n");
99
+ mkdirSync(join(dir, "s-turn3", "subagents"), { recursive: true });
100
+ writeFileSync(join(dir, "s-turn3", "subagents", "agent-last.jsonl"), "{}\n");
101
+ writeSession("thread-resumed", JSON.stringify({ version: 2, sessionId: "s-turn3", updatedAtMs: 3 }));
102
+ writeTurnEvents([
103
+ { threadId: "thread-resumed", turnId: "t1", event: "session", detail: { sessionId: "s-turn1" } },
104
+ { threadId: "thread-other", turnId: "o1", event: "session", detail: { sessionId: "s-other" } },
105
+ { threadId: "thread-resumed", turnId: "t2", event: "session", detail: { sessionId: "s-turn2" } },
106
+ { threadId: "thread-resumed", turnId: "t2", event: "turn_end" },
107
+ { threadId: "thread-resumed", turnId: "t3", event: "session", detail: { sessionId: "s-turn3" } },
108
+ ]);
109
+ const [thread] = await resolveThreadTranscripts(["thread-resumed"], { projectRoot, projectsRoot });
110
+ expect(thread?.sessionIds).toEqual(["s-turn1", "s-turn2", "s-turn3"]);
111
+ expect(thread?.files).toEqual(["s-turn1", "s-turn2", "s-turn3"].map((id) => join(dir, `${id}.jsonl`)));
112
+ expect([...(thread?.subagentFiles ?? [])].sort()).toEqual([
113
+ join(dir, "s-turn2", "subagents", "agent-v1.jsonl"),
114
+ join(dir, "s-turn2", "subagents", "agent-v4.jsonl"),
115
+ join(dir, "s-turn3", "subagents", "agent-last.jsonl"),
116
+ ].sort());
117
+ });
81
118
  });
82
119
  //# sourceMappingURL=transcripts.test.js.map