@hawkeyexl/manni 4.4.1 → 4.6.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 (226) hide show
  1. package/README.md +1 -1
  2. package/dist/batch-OZOACN4G.js +41 -0
  3. package/dist/build-Z5VOVADH.js +32 -0
  4. package/dist/calibrate-TZYT42DR.js +36 -0
  5. package/dist/capture-SL4MNDDP.js +34 -0
  6. package/dist/check-5OMA42Y6.js +26 -0
  7. package/dist/{check-HYNGXYJV.js → check-OAJWC3WD.js} +7 -5
  8. package/dist/{check-ASPIHA6B.js → check-PKY7KTQE.js} +13 -14
  9. package/dist/check-WB2QDHJQ.js +880 -0
  10. package/dist/check-WB2QDHJQ.js.map +1 -0
  11. package/dist/{chunk-MWJLZMBL.js → chunk-2JFPBZJK.js} +11 -11
  12. package/dist/{chunk-QQUKGCAJ.js → chunk-2KRB3EG7.js} +2 -2
  13. package/dist/{chunk-DXNZS72W.js → chunk-2M6DVNI5.js} +10 -6
  14. package/dist/{chunk-DXNZS72W.js.map → chunk-2M6DVNI5.js.map} +1 -1
  15. package/dist/{chunk-QZ6LRSNV.js → chunk-3NWX34ZI.js} +19 -19
  16. package/dist/{chunk-IDV6HJCB.js → chunk-5G53XATW.js} +4 -4
  17. package/dist/{chunk-M2JCK5F6.js → chunk-6KKZXB2O.js} +19 -6
  18. package/dist/chunk-6KKZXB2O.js.map +1 -0
  19. package/dist/{chunk-PNPQTHBT.js → chunk-733Y2STG.js} +2 -2
  20. package/dist/{chunk-WB3QM6PP.js → chunk-73TC4DYH.js} +332 -2522
  21. package/dist/chunk-73TC4DYH.js.map +1 -0
  22. package/dist/{chunk-EPH54CAY.js → chunk-7WRP5FFP.js} +4 -4
  23. package/dist/{chunk-NXV7WE2D.js → chunk-APKH2T6E.js} +29 -591
  24. package/dist/chunk-APKH2T6E.js.map +1 -0
  25. package/dist/{chunk-I2AH3CJJ.js → chunk-B3TS4WRM.js} +17 -15
  26. package/dist/{chunk-I2AH3CJJ.js.map → chunk-B3TS4WRM.js.map} +1 -1
  27. package/dist/chunk-BWCWTHYS.js +146 -0
  28. package/dist/chunk-BWCWTHYS.js.map +1 -0
  29. package/dist/{chunk-MMTSSTG7.js → chunk-C3B2VJNC.js} +2 -2
  30. package/dist/{chunk-PU6DFJMY.js → chunk-C73RSUIC.js} +4 -4
  31. package/dist/chunk-CU57HT2E.js +116 -0
  32. package/dist/chunk-CU57HT2E.js.map +1 -0
  33. package/dist/chunk-CWXZ2MRT.js +222 -0
  34. package/dist/chunk-CWXZ2MRT.js.map +1 -0
  35. package/dist/{chunk-GCQRPUSB.js → chunk-DC5DDJVE.js} +6 -6
  36. package/dist/{chunk-6OYEI2VV.js → chunk-ECVQNGTH.js} +3 -3
  37. package/dist/chunk-FLAO4ZS3.js +502 -0
  38. package/dist/chunk-FLAO4ZS3.js.map +1 -0
  39. package/dist/chunk-FQGLRJGX.js +174 -0
  40. package/dist/chunk-FQGLRJGX.js.map +1 -0
  41. package/dist/{chunk-7UKO3ASZ.js → chunk-GAJIJKET.js} +3 -3
  42. package/dist/{chunk-6JSSEWBG.js → chunk-GREQKO6M.js} +202 -54
  43. package/dist/chunk-GREQKO6M.js.map +1 -0
  44. package/dist/chunk-HX44GB4Z.js +30 -0
  45. package/dist/chunk-HX44GB4Z.js.map +1 -0
  46. package/dist/{chunk-4IUC2MNL.js → chunk-IY7NYNPZ.js} +9 -11
  47. package/dist/{chunk-4IUC2MNL.js.map → chunk-IY7NYNPZ.js.map} +1 -1
  48. package/dist/{chunk-57NEQRVO.js → chunk-KCOFEWV5.js} +8 -6
  49. package/dist/{chunk-57NEQRVO.js.map → chunk-KCOFEWV5.js.map} +1 -1
  50. package/dist/chunk-M2RLHZ4J.js +849 -0
  51. package/dist/chunk-M2RLHZ4J.js.map +1 -0
  52. package/dist/{chunk-NLXTXE5Y.js → chunk-M6GSS72T.js} +185 -33
  53. package/dist/chunk-M6GSS72T.js.map +1 -0
  54. package/dist/{chunk-YTURO7SI.js → chunk-MHM4QEBV.js} +4 -4
  55. package/dist/{chunk-RL5XWQOL.js → chunk-MOWMCEOJ.js} +143 -54
  56. package/dist/chunk-MOWMCEOJ.js.map +1 -0
  57. package/dist/{chunk-C4SQM22E.js → chunk-MWBJ3KTF.js} +13 -11
  58. package/dist/chunk-MWBJ3KTF.js.map +1 -0
  59. package/dist/chunk-N7JSEDSC.js +233 -0
  60. package/dist/chunk-N7JSEDSC.js.map +1 -0
  61. package/dist/{chunk-JCDXE76J.js → chunk-NBMPHD4I.js} +2 -2
  62. package/dist/{chunk-37LP5HMZ.js → chunk-NHHOPZRA.js} +12 -10
  63. package/dist/{chunk-37LP5HMZ.js.map → chunk-NHHOPZRA.js.map} +1 -1
  64. package/dist/{chunk-YB4IBW3M.js → chunk-NTWW7J76.js} +2 -2
  65. package/dist/{chunk-UJCVAWP7.js → chunk-PCFG7E6B.js} +3 -3
  66. package/dist/{chunk-UJCVAWP7.js.map → chunk-PCFG7E6B.js.map} +1 -1
  67. package/dist/{chunk-FBEQCK47.js → chunk-PL4UAF4S.js} +73 -1304
  68. package/dist/chunk-PL4UAF4S.js.map +1 -0
  69. package/dist/chunk-QCHVR4ZM.js +286 -0
  70. package/dist/chunk-QCHVR4ZM.js.map +1 -0
  71. package/dist/{chunk-PIKOVN6W.js → chunk-QW77LCOU.js} +10 -10
  72. package/dist/{chunk-2B7ZNTPV.js → chunk-SM6NOMJS.js} +2 -2
  73. package/dist/chunk-SWSTHZBI.js +2464 -0
  74. package/dist/chunk-SWSTHZBI.js.map +1 -0
  75. package/dist/{chunk-JXLTXMJ7.js → chunk-T6SYGLWR.js} +3 -3
  76. package/dist/{chunk-CK7SKVHR.js → chunk-TBAMBLF3.js} +3 -12
  77. package/dist/chunk-TBAMBLF3.js.map +1 -0
  78. package/dist/chunk-TH4JVQPF.js +133 -0
  79. package/dist/chunk-TH4JVQPF.js.map +1 -0
  80. package/dist/{chunk-QRWGPQKO.js → chunk-TLXE7LYK.js} +4 -4
  81. package/dist/{chunk-M3W7J6MU.js → chunk-TUAAR3MM.js} +3280 -283
  82. package/dist/chunk-TUAAR3MM.js.map +1 -0
  83. package/dist/{chunk-SKSDRUUK.js → chunk-UAKNZVCD.js} +4 -4
  84. package/dist/{chunk-YJOGUXGP.js → chunk-UJSGS2Y5.js} +8 -6
  85. package/dist/{chunk-YJOGUXGP.js.map → chunk-UJSGS2Y5.js.map} +1 -1
  86. package/dist/{chunk-UQISLDAV.js → chunk-UWQ2UVHE.js} +8 -6
  87. package/dist/{chunk-UQISLDAV.js.map → chunk-UWQ2UVHE.js.map} +1 -1
  88. package/dist/chunk-WQWKYAAK.js +86 -0
  89. package/dist/chunk-WQWKYAAK.js.map +1 -0
  90. package/dist/{chunk-LJ2RDH3F.js → chunk-XG6PVB5S.js} +1 -23
  91. package/dist/chunk-XG6PVB5S.js.map +1 -0
  92. package/dist/{chunk-Q35YIDBV.js → chunk-XKBEHKWO.js} +29 -264
  93. package/dist/chunk-XKBEHKWO.js.map +1 -0
  94. package/dist/chunk-XPEWUK7J.js +532 -0
  95. package/dist/chunk-XPEWUK7J.js.map +1 -0
  96. package/dist/{chunk-MYMBCTDE.js → chunk-XXDXIIQ4.js} +2 -2
  97. package/dist/chunk-YGFIQ6Y5.js +17 -0
  98. package/dist/chunk-YGFIQ6Y5.js.map +1 -0
  99. package/dist/chunk-YLK2J5YK.js +610 -0
  100. package/dist/chunk-YLK2J5YK.js.map +1 -0
  101. package/dist/{chunk-3VK37OR2.js → chunk-Z4IZGEM3.js} +16 -12
  102. package/dist/{chunk-3VK37OR2.js.map → chunk-Z4IZGEM3.js.map} +1 -1
  103. package/dist/{cli-6HIDIFVT.js → cli-6EWVMEN6.js} +5 -3
  104. package/dist/{cli-6HIDIFVT.js.map → cli-6EWVMEN6.js.map} +1 -1
  105. package/dist/{cli-VI7VHWNZ.js → cli-6H7HVDMQ.js} +113 -20
  106. package/dist/{cli-VI7VHWNZ.js.map → cli-6H7HVDMQ.js.map} +1 -1
  107. package/dist/{cli-RPM5PELX.js → cli-EPVZHAZS.js} +24 -20
  108. package/dist/cli-EPVZHAZS.js.map +1 -0
  109. package/dist/{cli-MN7PYMBI.js → cli-LUCSGTVI.js} +17 -19
  110. package/dist/{cli-MN7PYMBI.js.map → cli-LUCSGTVI.js.map} +1 -1
  111. package/dist/{cli-LFP5ZGYS.js → cli-NIG4N3XM.js} +16 -15
  112. package/dist/{cli-LFP5ZGYS.js.map → cli-NIG4N3XM.js.map} +1 -1
  113. package/dist/{cli-PYPX6O6E.js → cli-PSKNB66T.js} +225 -58
  114. package/dist/cli-PSKNB66T.js.map +1 -0
  115. package/dist/{cli-3BIBYHFK.js → cli-UO4NHIB3.js} +17 -17
  116. package/dist/{cli-6UB5N6CU.js → cli-UQ7A3YA2.js} +17 -18
  117. package/dist/{cli-6UB5N6CU.js.map → cli-UQ7A3YA2.js.map} +1 -1
  118. package/dist/{cli-673OTRGE.js → cli-YHYDLQAF.js} +10 -10
  119. package/dist/cli.js +11 -11
  120. package/dist/config-P4HDNTYD.js +26 -0
  121. package/dist/conformance-ZFCMKM6M.js +18 -0
  122. package/dist/docmeta.js +9 -9
  123. package/dist/github-7ZCH5PSO.js +26 -0
  124. package/dist/github-POT6724K.js +31 -0
  125. package/dist/host-6GURH5HE.js +23 -0
  126. package/dist/index.d.ts +102 -12
  127. package/dist/index.js +185 -171
  128. package/dist/index.js.map +1 -1
  129. package/dist/{json-SY7KLNC7.js → json-KT2K62L5.js} +12 -13
  130. package/dist/lint-5AQ5C2BV.js +29 -0
  131. package/dist/list-5JZKX2NK.js +28 -0
  132. package/dist/list-SWPFXQMU.js +30 -0
  133. package/dist/{page-KSGV5RD4.js → page-UPSXRP75.js} +11 -12
  134. package/dist/prepare-6GNEWCNH.js +155 -0
  135. package/dist/prepare-6GNEWCNH.js.map +1 -0
  136. package/dist/{pretty-CXSDXNAS.js → pretty-Q6FQAOK4.js} +13 -14
  137. package/dist/{pretty-A5EGTN35.js → pretty-SQRPFPSQ.js} +12 -13
  138. package/dist/provider-AMGRDY6V.js +34 -0
  139. package/dist/release-IECYCLTD.js +36 -0
  140. package/dist/release-IECYCLTD.js.map +1 -0
  141. package/dist/{reporters-HUY7UXFS.js → reporters-45MMC2ID.js} +13 -13
  142. package/dist/{reporters-K2VUKSAK.js → reporters-XUV4MM64.js} +7 -5
  143. package/dist/reporters-XUV4MM64.js.map +1 -0
  144. package/dist/run-KMWY2IAN.js +32 -0
  145. package/dist/run-KMWY2IAN.js.map +1 -0
  146. package/dist/{term-BIQUPMOR.js → term-PCJUCWNF.js} +16 -17
  147. package/dist/{term-BIQUPMOR.js.map → term-PCJUCWNF.js.map} +1 -1
  148. package/dist/validate-IMNCZNWG.js +17 -0
  149. package/dist/validate-IMNCZNWG.js.map +1 -0
  150. package/package.json +2 -2
  151. package/plugin/manni/.claude-plugin/plugin.json +1 -1
  152. package/plugin/manni/hooks/hooks.json +47 -0
  153. package/dist/batch-GFNLTGOH.js +0 -36
  154. package/dist/build-COYIQ25L.js +0 -31
  155. package/dist/calibrate-MDBLJKEE.js +0 -31
  156. package/dist/capture-LRML2PKV.js +0 -32
  157. package/dist/check-EDLBYL5N.js +0 -27
  158. package/dist/chunk-6JSSEWBG.js.map +0 -1
  159. package/dist/chunk-A5ULMVHQ.js +0 -164
  160. package/dist/chunk-A5ULMVHQ.js.map +0 -1
  161. package/dist/chunk-C4SQM22E.js.map +0 -1
  162. package/dist/chunk-CK7SKVHR.js.map +0 -1
  163. package/dist/chunk-FBEQCK47.js.map +0 -1
  164. package/dist/chunk-LJ2RDH3F.js.map +0 -1
  165. package/dist/chunk-M2JCK5F6.js.map +0 -1
  166. package/dist/chunk-M3W7J6MU.js.map +0 -1
  167. package/dist/chunk-NLXTXE5Y.js.map +0 -1
  168. package/dist/chunk-NXV7WE2D.js.map +0 -1
  169. package/dist/chunk-Q35YIDBV.js.map +0 -1
  170. package/dist/chunk-RL5XWQOL.js.map +0 -1
  171. package/dist/chunk-TK3FC4RF.js +0 -3090
  172. package/dist/chunk-TK3FC4RF.js.map +0 -1
  173. package/dist/chunk-TU2WUBVZ.js +0 -2
  174. package/dist/chunk-WB3QM6PP.js.map +0 -1
  175. package/dist/cli-PYPX6O6E.js.map +0 -1
  176. package/dist/cli-RPM5PELX.js.map +0 -1
  177. package/dist/github-6QMYOHC3.js +0 -27
  178. package/dist/github-SXPGP5DB.js +0 -32
  179. package/dist/lint-ASMJLLPA.js +0 -28
  180. package/dist/list-KZNVTNVC.js +0 -31
  181. package/dist/list-Q57YTFUQ.js +0 -29
  182. package/dist/run-3DYJNRIG.js +0 -33
  183. package/dist/validate-53RKM2XG.js +0 -16
  184. /package/dist/{batch-GFNLTGOH.js.map → batch-OZOACN4G.js.map} +0 -0
  185. /package/dist/{build-COYIQ25L.js.map → build-Z5VOVADH.js.map} +0 -0
  186. /package/dist/{calibrate-MDBLJKEE.js.map → calibrate-TZYT42DR.js.map} +0 -0
  187. /package/dist/{capture-LRML2PKV.js.map → capture-SL4MNDDP.js.map} +0 -0
  188. /package/dist/{check-ASPIHA6B.js.map → check-5OMA42Y6.js.map} +0 -0
  189. /package/dist/{check-EDLBYL5N.js.map → check-OAJWC3WD.js.map} +0 -0
  190. /package/dist/{check-HYNGXYJV.js.map → check-PKY7KTQE.js.map} +0 -0
  191. /package/dist/{chunk-MWJLZMBL.js.map → chunk-2JFPBZJK.js.map} +0 -0
  192. /package/dist/{chunk-QQUKGCAJ.js.map → chunk-2KRB3EG7.js.map} +0 -0
  193. /package/dist/{chunk-QZ6LRSNV.js.map → chunk-3NWX34ZI.js.map} +0 -0
  194. /package/dist/{chunk-IDV6HJCB.js.map → chunk-5G53XATW.js.map} +0 -0
  195. /package/dist/{chunk-PNPQTHBT.js.map → chunk-733Y2STG.js.map} +0 -0
  196. /package/dist/{chunk-EPH54CAY.js.map → chunk-7WRP5FFP.js.map} +0 -0
  197. /package/dist/{chunk-MMTSSTG7.js.map → chunk-C3B2VJNC.js.map} +0 -0
  198. /package/dist/{chunk-PU6DFJMY.js.map → chunk-C73RSUIC.js.map} +0 -0
  199. /package/dist/{chunk-GCQRPUSB.js.map → chunk-DC5DDJVE.js.map} +0 -0
  200. /package/dist/{chunk-6OYEI2VV.js.map → chunk-ECVQNGTH.js.map} +0 -0
  201. /package/dist/{chunk-7UKO3ASZ.js.map → chunk-GAJIJKET.js.map} +0 -0
  202. /package/dist/{chunk-YTURO7SI.js.map → chunk-MHM4QEBV.js.map} +0 -0
  203. /package/dist/{chunk-JCDXE76J.js.map → chunk-NBMPHD4I.js.map} +0 -0
  204. /package/dist/{chunk-YB4IBW3M.js.map → chunk-NTWW7J76.js.map} +0 -0
  205. /package/dist/{chunk-PIKOVN6W.js.map → chunk-QW77LCOU.js.map} +0 -0
  206. /package/dist/{chunk-2B7ZNTPV.js.map → chunk-SM6NOMJS.js.map} +0 -0
  207. /package/dist/{chunk-JXLTXMJ7.js.map → chunk-T6SYGLWR.js.map} +0 -0
  208. /package/dist/{chunk-QRWGPQKO.js.map → chunk-TLXE7LYK.js.map} +0 -0
  209. /package/dist/{chunk-SKSDRUUK.js.map → chunk-UAKNZVCD.js.map} +0 -0
  210. /package/dist/{chunk-MYMBCTDE.js.map → chunk-XXDXIIQ4.js.map} +0 -0
  211. /package/dist/{cli-3BIBYHFK.js.map → cli-UO4NHIB3.js.map} +0 -0
  212. /package/dist/{chunk-TU2WUBVZ.js.map → cli-YHYDLQAF.js.map} +0 -0
  213. /package/dist/{cli-673OTRGE.js.map → config-P4HDNTYD.js.map} +0 -0
  214. /package/dist/{github-6QMYOHC3.js.map → conformance-ZFCMKM6M.js.map} +0 -0
  215. /package/dist/{github-SXPGP5DB.js.map → github-7ZCH5PSO.js.map} +0 -0
  216. /package/dist/{json-SY7KLNC7.js.map → github-POT6724K.js.map} +0 -0
  217. /package/dist/{lint-ASMJLLPA.js.map → host-6GURH5HE.js.map} +0 -0
  218. /package/dist/{list-KZNVTNVC.js.map → json-KT2K62L5.js.map} +0 -0
  219. /package/dist/{list-Q57YTFUQ.js.map → lint-5AQ5C2BV.js.map} +0 -0
  220. /package/dist/{page-KSGV5RD4.js.map → list-5JZKX2NK.js.map} +0 -0
  221. /package/dist/{pretty-A5EGTN35.js.map → list-SWPFXQMU.js.map} +0 -0
  222. /package/dist/{pretty-CXSDXNAS.js.map → page-UPSXRP75.js.map} +0 -0
  223. /package/dist/{reporters-HUY7UXFS.js.map → pretty-Q6FQAOK4.js.map} +0 -0
  224. /package/dist/{reporters-K2VUKSAK.js.map → pretty-SQRPFPSQ.js.map} +0 -0
  225. /package/dist/{run-3DYJNRIG.js.map → provider-AMGRDY6V.js.map} +0 -0
  226. /package/dist/{validate-53RKM2XG.js.map → reporters-45MMC2ID.js.map} +0 -0
@@ -0,0 +1,849 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ windowFor
4
+ } from "./chunk-CWXZ2MRT.js";
5
+ import {
6
+ applyAvailabilityRecord,
7
+ foldBranchAvailability,
8
+ newAvailability,
9
+ newReplay,
10
+ remapAvailability
11
+ } from "./chunk-APKH2T6E.js";
12
+ import {
13
+ makeRedactor
14
+ } from "./chunk-CU57HT2E.js";
15
+ import {
16
+ TracevalsError
17
+ } from "./chunk-UKZNLVJW.js";
18
+
19
+ // src/tracevals/trace/claude.ts
20
+ import { readdir, readFile } from "node:fs/promises";
21
+ import { basename, dirname, join, resolve } from "node:path";
22
+
23
+ // src/tracevals/trace/detect.ts
24
+ var SUPPORTED = "supported formats: Claude Code session files (~/.claude/projects/**.jsonl) and claude -p stream-json";
25
+ function detectFormat(line) {
26
+ let rec;
27
+ try {
28
+ rec = JSON.parse(line);
29
+ } catch {
30
+ throw new TracevalsError(`trace is not JSONL (${SUPPORTED})`);
31
+ }
32
+ if (typeof rec !== "object" || rec === null) {
33
+ throw new TracevalsError(`unrecognized trace format (${SUPPORTED})`);
34
+ }
35
+ if ("parentUuid" in rec || "sessionId" in rec) return "claude-session";
36
+ if ("session_id" in rec) return "claude-stream";
37
+ throw new TracevalsError(`unrecognized trace format (${SUPPORTED})`);
38
+ }
39
+ function detectContentFormat(content) {
40
+ let sawParseable = false;
41
+ for (const line of content.split("\n")) {
42
+ const trimmed = line.trim();
43
+ if (!trimmed) continue;
44
+ let rec;
45
+ try {
46
+ rec = JSON.parse(trimmed);
47
+ } catch {
48
+ continue;
49
+ }
50
+ if (typeof rec !== "object" || rec === null) continue;
51
+ sawParseable = true;
52
+ const r = rec;
53
+ if ("parentUuid" in r || "sessionId" in r) return "claude-session";
54
+ if ("session_id" in r) return "claude-stream";
55
+ }
56
+ throw new TracevalsError(
57
+ sawParseable ? `unrecognized trace format (${SUPPORTED})` : `empty or unparseable trace file (${SUPPORTED})`
58
+ );
59
+ }
60
+
61
+ // src/tracevals/trace/claude.ts
62
+ async function parseTraceFile(filePath) {
63
+ const absolute = resolve(filePath);
64
+ const content = await readFile(absolute, "utf-8");
65
+ const trace = parseTraceContent(content, absolute);
66
+ await mergeSidecarBranches(trace, absolute);
67
+ return trace;
68
+ }
69
+ function parseTraceContent(content, filePath) {
70
+ const format = detectContentFormat(content);
71
+ const { records, unparseable } = parseLines(content);
72
+ const trace = format === "claude-session" ? parseSession(records, filePath) : parseStream(records, filePath);
73
+ if (unparseable > 0) {
74
+ trace.warnings.push(
75
+ `${unparseable} unparseable JSONL line(s) were skipped`
76
+ );
77
+ }
78
+ return trace;
79
+ }
80
+ function parseLines(content) {
81
+ const records = [];
82
+ let unparseable = 0;
83
+ for (const line of content.split("\n")) {
84
+ const trimmed = line.trim();
85
+ if (!trimmed) continue;
86
+ try {
87
+ const rec = JSON.parse(trimmed);
88
+ if (typeof rec === "object" && rec !== null) records.push(rec);
89
+ else unparseable += 1;
90
+ } catch {
91
+ unparseable += 1;
92
+ }
93
+ }
94
+ return { records, unparseable };
95
+ }
96
+ var SESSION_META_TYPES = /* @__PURE__ */ new Set([
97
+ "queue-operation",
98
+ "attachment",
99
+ "last-prompt",
100
+ "custom-title",
101
+ "summary",
102
+ "mode",
103
+ "pr-link"
104
+ ]);
105
+ var COMMAND_NAME_RE = /<command-name>([^<]+)<\/command-name>/;
106
+ var COMMAND_ARGS_RE = /<command-args>([^<]*)<\/command-args>/;
107
+ function newTrace(filePath) {
108
+ return {
109
+ source: "claude-code",
110
+ file: filePath,
111
+ cwd: "",
112
+ events: [],
113
+ toolCalls: [],
114
+ skillInvocations: [],
115
+ agentSpawns: [],
116
+ subagentBranches: [],
117
+ availability: newAvailability(),
118
+ fileAccesses: [],
119
+ userMessages: [],
120
+ assistantTexts: [],
121
+ turnCount: 0,
122
+ warnings: []
123
+ };
124
+ }
125
+ function pushEvent(trace, event) {
126
+ const index = trace.events.length;
127
+ trace.events.push({ ...event, index });
128
+ return index;
129
+ }
130
+ function plainMessageText(rec) {
131
+ const content = rec.message?.content;
132
+ return typeof content === "string" ? content : void 0;
133
+ }
134
+ function resolveBranch(branches, parentUuid, rootText) {
135
+ if (typeof parentUuid !== "string") return void 0;
136
+ const inherited = branches.resolved.get(parentUuid);
137
+ if (inherited !== void 0) return inherited;
138
+ const pending = branches.spawns.get(parentUuid);
139
+ if (pending === void 0 || pending.length === 0) return void 0;
140
+ const byPrompt = rootText !== void 0 ? pending.find((b) => !b.claimed && b.prompt === rootText) : void 0;
141
+ const branch = byPrompt ?? pending.find((b) => !b.claimed) ?? pending[0];
142
+ if (branch === void 0) return void 0;
143
+ branch.claimed = true;
144
+ return branch.toolUseId;
145
+ }
146
+ function parseSession(records, filePath) {
147
+ const trace = newTrace(filePath);
148
+ const branches = { spawns: /* @__PURE__ */ new Map(), resolved: /* @__PURE__ */ new Map() };
149
+ const availability = newReplay();
150
+ const uuids = /* @__PURE__ */ new Set();
151
+ for (const rec of records) {
152
+ if (typeof rec.uuid === "string") uuids.add(rec.uuid);
153
+ }
154
+ const continuations = [];
155
+ let sawMessage = false;
156
+ let compactions = 0;
157
+ let inputTokens = 0;
158
+ let outputTokens = 0;
159
+ let sawUsage = false;
160
+ for (const rec of records) {
161
+ const type = rec.type;
162
+ const timestamp = rec.timestamp;
163
+ if (timestamp) {
164
+ trace.startedAt ??= timestamp;
165
+ trace.endedAt = timestamp;
166
+ }
167
+ if (rec.sessionId) trace.sessionId ??= rec.sessionId;
168
+ if (rec.subtype === "compact_boundary") compactions += 1;
169
+ if (type !== void 0 && SESSION_META_TYPES.has(type)) {
170
+ if (type === "summary" && !sawMessage && typeof rec.leafUuid === "string" && !uuids.has(rec.leafUuid)) {
171
+ continuations.push(rec.leafUuid);
172
+ }
173
+ const index = pushEvent(trace, { kind: "meta", timestamp, raw: rec });
174
+ if (type === "attachment" && applyAvailabilityRecord(availability, rec.attachment, index)) {
175
+ availability.roster.recorded = true;
176
+ }
177
+ continue;
178
+ }
179
+ const sidechain = rec.isSidechain === true;
180
+ if (!sidechain && typeof rec.cwd === "string") trace.cwd = rec.cwd;
181
+ if (!sidechain && typeof rec.gitBranch === "string") {
182
+ trace.gitBranch = rec.gitBranch;
183
+ }
184
+ const context = { sidechain, timestamp, branches };
185
+ if (typeof rec.uuid === "string") context.uuid = rec.uuid;
186
+ if (sidechain) {
187
+ const branchId = resolveBranch(
188
+ branches,
189
+ rec.parentUuid,
190
+ plainMessageText(rec)
191
+ );
192
+ if (branchId !== void 0) {
193
+ context.branchId = branchId;
194
+ if (context.uuid) branches.resolved.set(context.uuid, branchId);
195
+ }
196
+ }
197
+ const message = rec.message;
198
+ if (type === "user" && message) {
199
+ sawMessage = true;
200
+ handleUserMessage(trace, message, context, rec);
201
+ } else if (type === "assistant" && message) {
202
+ sawMessage = true;
203
+ const usage = handleAssistantMessage(trace, message, context, rec);
204
+ if (usage && !sidechain) {
205
+ inputTokens += usage.input;
206
+ outputTokens += usage.output;
207
+ sawUsage = true;
208
+ }
209
+ } else {
210
+ pushEvent(trace, { kind: "system", timestamp, raw: rec });
211
+ }
212
+ }
213
+ if (sawUsage) trace.usage = { inputTokens, outputTokens };
214
+ for (const leaf of continuations) {
215
+ trace.warnings.push(
216
+ `this trace is a fragment of a longer session: it resumes an earlier one recorded elsewhere (summary leafUuid ${leaf} is not in this file), so evals see only the turns recorded here`
217
+ );
218
+ }
219
+ if (compactions > 0) {
220
+ trace.warnings.push(
221
+ `the conversation was compacted ${compactions} time(s): the agent stopped seeing the turns before each boundary, so early transcript content is not what it was working from`
222
+ );
223
+ }
224
+ trace.availability = availability.roster;
225
+ trace.subagentBranches = buildBranches(trace);
226
+ return trace;
227
+ }
228
+ function buildBranches(trace, sidecars = /* @__PURE__ */ new Map()) {
229
+ const ranges = /* @__PURE__ */ new Map();
230
+ for (const event of trace.events) {
231
+ const id = event.branchId;
232
+ if (id === void 0) continue;
233
+ const range = ranges.get(id);
234
+ if (range === void 0) ranges.set(id, { min: event.index, max: event.index });
235
+ else range.max = Math.max(range.max, event.index);
236
+ }
237
+ if (ranges.size === 0) return [];
238
+ const spawnFor = /* @__PURE__ */ new Map();
239
+ for (const spawn of trace.agentSpawns) {
240
+ if (spawn.toolUseId) spawnFor.set(spawn.toolUseId, spawn);
241
+ }
242
+ const parentOf = /* @__PURE__ */ new Map();
243
+ for (const id of ranges.keys()) {
244
+ const spawn = spawnFor.get(id);
245
+ parentOf.set(
246
+ id,
247
+ spawn ? trace.events[spawn.index]?.branchId : void 0
248
+ );
249
+ }
250
+ const depthOf = (id) => {
251
+ let depth = 1;
252
+ let cursor = parentOf.get(id);
253
+ const seen = /* @__PURE__ */ new Set([id]);
254
+ while (cursor !== void 0 && !seen.has(cursor)) {
255
+ seen.add(cursor);
256
+ depth += 1;
257
+ cursor = parentOf.get(cursor);
258
+ }
259
+ return depth;
260
+ };
261
+ const branches = [];
262
+ for (const [id, range] of ranges) {
263
+ const spawn = spawnFor.get(id);
264
+ const sidecar = sidecars.get(id);
265
+ const branch = {
266
+ branchId: id,
267
+ agentType: sidecar?.agentType ?? spawn?.subagentType ?? id,
268
+ origin: sidecar ? "sidecar" : "inline",
269
+ spawnDepth: sidecar?.spawnDepth ?? depthOf(id),
270
+ spawnIndex: spawn?.index ?? range.min,
271
+ startIndex: range.min,
272
+ endIndex: range.max + 1
273
+ };
274
+ const description = sidecar?.description ?? spawn?.description;
275
+ if (description !== void 0) branch.description = description;
276
+ if (sidecar?.agentId) branch.agentId = sidecar.agentId;
277
+ if (sidecar?.parentAgentId) branch.parentAgentId = sidecar.parentAgentId;
278
+ if (sidecar?.file) branch.file = sidecar.file;
279
+ branches.push(branch);
280
+ }
281
+ branches.sort((a, b) => b.spawnDepth - a.spawnDepth);
282
+ const byId = new Map(branches.map((b) => [b.branchId, b]));
283
+ for (const branch of branches) {
284
+ const parentId = parentOf.get(branch.branchId);
285
+ const parent = parentId === void 0 ? void 0 : byId.get(parentId);
286
+ if (parent === void 0) continue;
287
+ parent.startIndex = Math.min(parent.startIndex, branch.startIndex);
288
+ parent.endIndex = Math.max(parent.endIndex, branch.endIndex);
289
+ }
290
+ branches.sort((a, b) => a.startIndex - b.startIndex);
291
+ return branches;
292
+ }
293
+ function handleUserMessage(trace, message, context, raw) {
294
+ const { sidechain, timestamp, branchId } = context;
295
+ const content = message.content;
296
+ if (typeof content === "string") {
297
+ const index = pushEvent(trace, {
298
+ kind: "user",
299
+ timestamp,
300
+ text: content,
301
+ sidechain,
302
+ branchId,
303
+ raw
304
+ });
305
+ if (sidechain) return;
306
+ const command = COMMAND_NAME_RE.exec(content);
307
+ if (command?.[1]) {
308
+ const invocation = {
309
+ name: command[1].replace(/^\//, ""),
310
+ via: "command-injection",
311
+ index
312
+ };
313
+ const args = COMMAND_ARGS_RE.exec(content)?.[1]?.trim();
314
+ if (args) invocation.args = args;
315
+ trace.skillInvocations.push(invocation);
316
+ }
317
+ trace.userMessages.push(content);
318
+ trace.turnCount += 1;
319
+ return;
320
+ }
321
+ if (Array.isArray(content)) {
322
+ let hasToolResult = false;
323
+ const texts = [];
324
+ for (const block of content) {
325
+ if (block?.type === "tool_result") hasToolResult = true;
326
+ if (block?.type === "text" && typeof block.text === "string") {
327
+ texts.push(block.text);
328
+ }
329
+ }
330
+ if (hasToolResult) {
331
+ pushEvent(trace, {
332
+ kind: "tool_result",
333
+ timestamp,
334
+ sidechain,
335
+ branchId,
336
+ raw
337
+ });
338
+ return;
339
+ }
340
+ const text = texts.join("\n");
341
+ pushEvent(trace, {
342
+ kind: "user",
343
+ timestamp,
344
+ text,
345
+ sidechain,
346
+ branchId,
347
+ raw
348
+ });
349
+ if (!sidechain && text) {
350
+ trace.userMessages.push(text);
351
+ trace.turnCount += 1;
352
+ }
353
+ }
354
+ }
355
+ function handleAssistantMessage(trace, message, context, raw) {
356
+ const { sidechain, timestamp, branchId } = context;
357
+ if (!sidechain && typeof message.model === "string") {
358
+ trace.model ??= message.model;
359
+ }
360
+ const content = message.content;
361
+ if (Array.isArray(content)) {
362
+ for (const block of content) {
363
+ if (block?.type === "text" && typeof block.text === "string") {
364
+ pushEvent(trace, {
365
+ kind: "assistant",
366
+ timestamp,
367
+ text: block.text,
368
+ sidechain,
369
+ branchId,
370
+ raw
371
+ });
372
+ if (!sidechain) trace.assistantTexts.push(block.text);
373
+ } else if (block?.type === "tool_use") {
374
+ extractToolUse(trace, block, context);
375
+ }
376
+ }
377
+ }
378
+ const usage = message.usage;
379
+ if (usage) {
380
+ return {
381
+ input: typeof usage.input_tokens === "number" ? usage.input_tokens : 0,
382
+ output: typeof usage.output_tokens === "number" ? usage.output_tokens : 0
383
+ };
384
+ }
385
+ return void 0;
386
+ }
387
+ function extractToolUse(trace, block, context) {
388
+ const { sidechain, timestamp, branchId } = context;
389
+ const name = block.name;
390
+ const input = block.input ?? {};
391
+ const toolUseId = typeof block.id === "string" ? block.id : void 0;
392
+ const index = pushEvent(trace, {
393
+ kind: "tool_call",
394
+ timestamp,
395
+ toolName: name,
396
+ sidechain,
397
+ branchId,
398
+ raw: block
399
+ });
400
+ const call = { name, input, index, sidechain };
401
+ if (timestamp) call.timestamp = timestamp;
402
+ if (branchId) call.branchId = branchId;
403
+ trace.toolCalls.push(call);
404
+ switch (name) {
405
+ case "Skill": {
406
+ if (typeof input.skill === "string") {
407
+ const invocation = {
408
+ name: input.skill,
409
+ via: "skill-tool",
410
+ index
411
+ };
412
+ if (toolUseId) invocation.toolUseId = toolUseId;
413
+ if (typeof input.args === "string" && input.args) {
414
+ invocation.args = input.args;
415
+ }
416
+ trace.skillInvocations.push(invocation);
417
+ }
418
+ break;
419
+ }
420
+ case "Agent": {
421
+ if (typeof input.subagent_type === "string") {
422
+ const spawn = {
423
+ subagentType: input.subagent_type,
424
+ index
425
+ };
426
+ if (typeof input.description === "string") {
427
+ spawn.description = input.description;
428
+ }
429
+ if (toolUseId) spawn.toolUseId = toolUseId;
430
+ trace.agentSpawns.push(spawn);
431
+ }
432
+ if (context.branches && context.uuid && toolUseId) {
433
+ const pending = context.branches.spawns.get(context.uuid) ?? [];
434
+ pending.push({
435
+ toolUseId,
436
+ prompt: typeof input.prompt === "string" ? input.prompt : void 0,
437
+ claimed: false
438
+ });
439
+ context.branches.spawns.set(context.uuid, pending);
440
+ }
441
+ break;
442
+ }
443
+ case "Read":
444
+ case "Write":
445
+ case "Edit": {
446
+ if (typeof input.file_path === "string") {
447
+ const op = name === "Read" ? "read" : name === "Write" ? "write" : "edit";
448
+ trace.fileAccesses.push({ path: input.file_path, op, index });
449
+ }
450
+ break;
451
+ }
452
+ }
453
+ }
454
+ function parseStream(records, filePath) {
455
+ const trace = newTrace(filePath);
456
+ const context = { sidechain: false };
457
+ let inputTokens = 0;
458
+ let outputTokens = 0;
459
+ let sawMessageUsage = false;
460
+ for (const rec of records) {
461
+ const type = rec.type;
462
+ if (type === "system" && (rec.subtype === "init" || !rec.subtype)) {
463
+ if (typeof rec.cwd === "string") trace.cwd = rec.cwd;
464
+ if (typeof rec.model === "string") trace.model = rec.model;
465
+ if (typeof rec.session_id === "string") trace.sessionId = rec.session_id;
466
+ pushEvent(trace, { kind: "system", raw: rec });
467
+ continue;
468
+ }
469
+ if (type === "assistant" || type === "user") {
470
+ const message = rec.message ?? rec;
471
+ if (type === "assistant") {
472
+ const usage = handleAssistantMessage(trace, message, context, rec);
473
+ if (usage) {
474
+ inputTokens += usage.input;
475
+ outputTokens += usage.output;
476
+ sawMessageUsage = true;
477
+ }
478
+ } else {
479
+ handleUserMessage(trace, message, context, rec);
480
+ }
481
+ continue;
482
+ }
483
+ if (type === "result") {
484
+ trace.isError = rec.is_error === true;
485
+ if (typeof rec.num_turns === "number") trace.turnCount = rec.num_turns;
486
+ const usage = rec.usage;
487
+ const totalCost = typeof rec.total_cost_usd === "number" ? rec.total_cost_usd : void 0;
488
+ if (usage) {
489
+ trace.usage = {
490
+ inputTokens: typeof usage.input_tokens === "number" ? usage.input_tokens : 0,
491
+ outputTokens: typeof usage.output_tokens === "number" ? usage.output_tokens : 0
492
+ };
493
+ if (totalCost !== void 0) trace.usage.totalCostUsd = totalCost;
494
+ } else if (sawMessageUsage) {
495
+ trace.usage = { inputTokens, outputTokens };
496
+ if (totalCost !== void 0) trace.usage.totalCostUsd = totalCost;
497
+ }
498
+ pushEvent(trace, { kind: "meta", raw: rec });
499
+ continue;
500
+ }
501
+ pushEvent(trace, { kind: "meta", raw: rec });
502
+ }
503
+ if (!trace.usage && sawMessageUsage) {
504
+ trace.usage = { inputTokens, outputTokens };
505
+ }
506
+ return trace;
507
+ }
508
+ var AGENT_META_RE = /^agent-(.+)\.meta\.json$/;
509
+ var AGENT_JSONL_RE = /^agent-(.+)\.jsonl$/;
510
+ function sidecarDirFor(traceFile) {
511
+ const stem = basename(traceFile).replace(/\.jsonl$/i, "");
512
+ return join(dirname(traceFile), stem, "subagents");
513
+ }
514
+ function asSource(id, trace) {
515
+ return {
516
+ id,
517
+ events: trace.events,
518
+ toolCalls: trace.toolCalls,
519
+ fileAccesses: trace.fileAccesses,
520
+ skillInvocations: trace.skillInvocations,
521
+ agentSpawns: trace.agentSpawns
522
+ };
523
+ }
524
+ function stampBranch(sub, branchId) {
525
+ for (const event of sub.events) {
526
+ event.sidechain = true;
527
+ event.branchId = branchId;
528
+ }
529
+ for (const call of sub.toolCalls) {
530
+ call.sidechain = true;
531
+ call.branchId = branchId;
532
+ }
533
+ }
534
+ async function loadSidecars(dir, trace) {
535
+ let names;
536
+ try {
537
+ names = await readdir(dir);
538
+ } catch (error) {
539
+ const code = error.code;
540
+ if (code !== "ENOENT" && code !== "ENOTDIR") {
541
+ trace.warnings.push(
542
+ `could not read the subagent transcript directory ${dir} (${code ?? "unknown error"}), so subagent turns are missing here`
543
+ );
544
+ }
545
+ return [];
546
+ }
547
+ const metas = /* @__PURE__ */ new Set();
548
+ const transcripts = /* @__PURE__ */ new Set();
549
+ for (const name of names) {
550
+ const meta = AGENT_META_RE.exec(name);
551
+ if (meta?.[1] !== void 0) {
552
+ metas.add(meta[1]);
553
+ continue;
554
+ }
555
+ const jsonl = AGENT_JSONL_RE.exec(name);
556
+ if (jsonl?.[1] !== void 0) transcripts.add(jsonl[1]);
557
+ }
558
+ for (const orphan of [...transcripts].sort()) {
559
+ if (!metas.has(orphan)) {
560
+ trace.warnings.push(
561
+ `subagent transcript agent-${orphan}.jsonl has no agent-${orphan}.meta.json, so it names no Agent spawn and was not merged`
562
+ );
563
+ }
564
+ }
565
+ const loaded = [];
566
+ for (const agentId of [...metas].sort()) {
567
+ let meta;
568
+ try {
569
+ const raw = await readFile(
570
+ join(dir, `agent-${agentId}.meta.json`),
571
+ "utf-8"
572
+ );
573
+ const parsed = JSON.parse(raw);
574
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
575
+ throw new Error("shape");
576
+ }
577
+ meta = parsed;
578
+ } catch {
579
+ trace.warnings.push(
580
+ `subagent metadata agent-${agentId}.meta.json is unreadable or not an object, so that branch was not merged`
581
+ );
582
+ continue;
583
+ }
584
+ const file = join(dir, `agent-${agentId}.jsonl`);
585
+ let sub;
586
+ try {
587
+ sub = parseTraceContent(await readFile(file, "utf-8"), file);
588
+ } catch {
589
+ trace.warnings.push(
590
+ `subagent transcript agent-${agentId}.jsonl is missing or unreadable, so that branch was not merged`
591
+ );
592
+ continue;
593
+ }
594
+ for (const warning of sub.warnings) {
595
+ trace.warnings.push(`subagent ${meta.agentType ?? agentId}: ${warning}`);
596
+ }
597
+ loaded.push({ agentId, file, meta, sub, source: asSource(agentId, sub) });
598
+ }
599
+ return loaded;
600
+ }
601
+ async function mergeSidecarBranches(trace, traceFile) {
602
+ const loaded = await loadSidecars(sidecarDirFor(traceFile), trace);
603
+ if (loaded.length === 0) return;
604
+ const base = asSource("", trace);
605
+ const sources = /* @__PURE__ */ new Map([["", base]]);
606
+ const spawnOwner = /* @__PURE__ */ new Map();
607
+ const registerSpawns = (source) => {
608
+ for (const spawn of source.agentSpawns) {
609
+ if (spawn.toolUseId !== void 0) {
610
+ spawnOwner.set(spawn.toolUseId, {
611
+ sourceId: source.id,
612
+ local: spawn.index
613
+ });
614
+ }
615
+ }
616
+ };
617
+ registerSpawns(base);
618
+ const children = /* @__PURE__ */ new Map();
619
+ const attached = [];
620
+ const pending = [...loaded].sort(
621
+ (a, b) => (a.meta.spawnDepth ?? 1) - (b.meta.spawnDepth ?? 1) || (a.agentId < b.agentId ? -1 : a.agentId > b.agentId ? 1 : 0)
622
+ );
623
+ let progress = true;
624
+ while (progress) {
625
+ progress = false;
626
+ for (let i = 0; i < pending.length; i += 1) {
627
+ const sidecar = pending[i];
628
+ const branchId = sidecar.meta.toolUseId;
629
+ const owner = branchId === void 0 ? void 0 : spawnOwner.get(branchId);
630
+ if (branchId === void 0 || owner === void 0) continue;
631
+ pending.splice(i, 1);
632
+ i -= 1;
633
+ progress = true;
634
+ stampBranch(sidecar.sub, branchId);
635
+ sources.set(sidecar.agentId, sidecar.source);
636
+ const key = `${owner.sourceId}\0${owner.local}`;
637
+ children.set(key, [...children.get(key) ?? [], sidecar]);
638
+ registerSpawns(sidecar.source);
639
+ attached.push({ sidecar, branchId });
640
+ }
641
+ }
642
+ for (const sidecar of pending) {
643
+ trace.warnings.push(
644
+ `subagent transcript agent-${sidecar.agentId}.jsonl names Agent call ${sidecar.meta.toolUseId ?? "(none recorded)"}, which is not in this trace, so that branch was not merged`
645
+ );
646
+ }
647
+ if (attached.length === 0) return;
648
+ const slots = [];
649
+ const emit = (sourceId) => {
650
+ const source = sources.get(sourceId);
651
+ if (source === void 0) return;
652
+ for (let local = 0; local < source.events.length; local += 1) {
653
+ slots.push({ sourceId, local });
654
+ for (const kid of children.get(`${sourceId}\0${local}`) ?? []) {
655
+ emit(kid.agentId);
656
+ }
657
+ }
658
+ };
659
+ emit("");
660
+ const remap = /* @__PURE__ */ new Map();
661
+ slots.forEach((slot, final) => {
662
+ const row = remap.get(slot.sourceId) ?? [];
663
+ row[slot.local] = final;
664
+ remap.set(slot.sourceId, row);
665
+ });
666
+ const finalIndex = (sourceId, local) => remap.get(sourceId)?.[local] ?? local;
667
+ trace.events = slots.map((slot, final) => {
668
+ const event = sources.get(slot.sourceId)?.events[slot.local];
669
+ return { ...event, index: final };
670
+ });
671
+ const gather = (pick) => [...sources.values()].flatMap(
672
+ (source) => pick(source).map((item) => ({
673
+ ...item,
674
+ index: finalIndex(source.id, item.index)
675
+ }))
676
+ ).sort((a, b) => a.index - b.index);
677
+ trace.toolCalls = gather((s) => s.toolCalls);
678
+ trace.fileAccesses = gather((s) => s.fileAccesses);
679
+ trace.skillInvocations = gather((s) => s.skillInvocations);
680
+ trace.agentSpawns = gather((s) => s.agentSpawns);
681
+ trace.availability = remapAvailability(
682
+ trace.availability,
683
+ (index) => finalIndex("", index)
684
+ );
685
+ for (const { sidecar, branchId } of attached) {
686
+ const owner = spawnOwner.get(branchId);
687
+ foldBranchAvailability(
688
+ trace.availability,
689
+ sidecar.sub.availability,
690
+ branchId,
691
+ owner === void 0 ? 0 : finalIndex(owner.sourceId, owner.local)
692
+ );
693
+ }
694
+ const described = /* @__PURE__ */ new Map();
695
+ for (const { sidecar, branchId } of attached) {
696
+ const info = {
697
+ agentId: sidecar.agentId,
698
+ file: sidecar.file
699
+ };
700
+ if (sidecar.meta.agentType) info.agentType = sidecar.meta.agentType;
701
+ if (sidecar.meta.description) info.description = sidecar.meta.description;
702
+ if (sidecar.meta.parentAgentId) {
703
+ info.parentAgentId = sidecar.meta.parentAgentId;
704
+ }
705
+ if (typeof sidecar.meta.spawnDepth === "number") {
706
+ info.spawnDepth = sidecar.meta.spawnDepth;
707
+ }
708
+ described.set(branchId, info);
709
+ }
710
+ trace.subagentBranches = buildBranches(trace, described);
711
+ }
712
+
713
+ // src/tracevals/judge/render.ts
714
+ var DEFAULTS = {
715
+ maxBlockChars: 2e3,
716
+ maxTotalChars: 15e4,
717
+ redact: []
718
+ };
719
+ var MIN_TIMELINE_CHARS = 200;
720
+ var HEADER_TRUNCATED = "\n[... header truncated ...]";
721
+ var TIMELINE_SHELL = "\n\n## Timeline\n";
722
+ function renderTrace(trace, options = {}, plan) {
723
+ const { maxBlockChars, maxTotalChars, redact } = { ...DEFAULTS, ...options };
724
+ const scrub = makeRedactor(redact);
725
+ const clip = (text, max) => {
726
+ const safe = scrub(text);
727
+ if (safe.length <= max) return safe;
728
+ return `${safe.slice(0, max)} [... truncated ${safe.length - max} chars ...]`;
729
+ };
730
+ const window = options.window ?? (plan === void 0 ? void 0 : windowFor(trace, plan));
731
+ const scoped = window !== void 0 && window.scope !== "session" ? window : void 0;
732
+ const events = scoped?.events ?? trace.events;
733
+ const fullHeader = scrub(
734
+ [
735
+ "# Session",
736
+ `source: ${trace.source}`,
737
+ trace.model ? `model: ${trace.model}` : void 0,
738
+ `cwd: ${trace.cwd}`,
739
+ trace.gitBranch ? `branch: ${trace.gitBranch}` : void 0,
740
+ scoped ? `scope: ${scoped.label} \u2014 ${events.length} of ${trace.events.length} session events` : void 0,
741
+ // Everything below describes what the judge can actually see. On a
742
+ // scoped render the timeline is the window, so a session-wide count here
743
+ // reads as evidence that the rest was truncated away — the judge would
744
+ // discount a digest that is complete for what it was asked about. The
745
+ // session totals stay, in parentheses, because "3 of 87" is context the
746
+ // window count alone does not carry.
747
+ scoped ? `turns: ${scoped.turnCount} (of ${trace.turnCount} in the session)` : `turns: ${trace.turnCount}`,
748
+ (() => {
749
+ const used = (scoped ?? trace).skillInvocations.map((s) => s.name);
750
+ return used.length > 0 ? `skills used: ${used.join(", ")}` : "skills used: none";
751
+ })(),
752
+ (() => {
753
+ const inWindow = new Set(events.map((e) => e.index));
754
+ const spawns = trace.agentSpawns.filter(
755
+ (a) => !scoped || inWindow.has(a.index)
756
+ );
757
+ return spawns.length > 0 ? `agents spawned: ${spawns.map((a) => a.subagentType).join(", ")}` : void 0;
758
+ })(),
759
+ (() => {
760
+ const inWindow = new Set(events.map((e) => e.index));
761
+ const branches = trace.subagentBranches.filter(
762
+ (b) => !scoped || inWindow.has(b.spawnIndex)
763
+ );
764
+ return branches.length > 0 ? `subagent transcripts: ${branches.map((b) => `${b.agentType} (depth ${b.spawnDepth})`).join(", ")}` : void 0;
765
+ })()
766
+ ].filter((line) => line !== void 0).join("\n")
767
+ );
768
+ const headerRoom = Math.max(
769
+ maxTotalChars - TIMELINE_SHELL.length - MIN_TIMELINE_CHARS,
770
+ 0
771
+ );
772
+ if (fullHeader.length > headerRoom) options.onTruncated?.();
773
+ const header = fullHeader.length <= headerRoom ? fullHeader : fullHeader.slice(
774
+ 0,
775
+ Math.max(headerRoom - HEADER_TRUNCATED.length, 0)
776
+ ) + HEADER_TRUNCATED;
777
+ const branchTypes = /* @__PURE__ */ new Map();
778
+ for (const spawn of trace.agentSpawns) {
779
+ if (spawn.toolUseId) branchTypes.set(spawn.toolUseId, spawn.subagentType);
780
+ }
781
+ for (const branch2 of trace.subagentBranches) {
782
+ branchTypes.set(branch2.branchId, branch2.agentType);
783
+ }
784
+ const label = (branchId) => branchTypes.get(branchId) ?? branchId;
785
+ const callAt = new Map(trace.toolCalls.map((call) => [call.index, call]));
786
+ if (scoped?.empty === true) {
787
+ return `${header}${TIMELINE_SHELL}[no turns: ${scrub(scoped.reason ?? "")}]`;
788
+ }
789
+ const lines = [];
790
+ let branch;
791
+ for (const event of events) {
792
+ const tag = event.branchId ? `:${label(event.branchId)}` : event.sidechain ? ":sidechain" : "";
793
+ let line;
794
+ switch (event.kind) {
795
+ case "user":
796
+ if (event.text) line = `[user${tag}] ${clip(event.text, maxBlockChars)}`;
797
+ break;
798
+ case "assistant":
799
+ if (event.text) {
800
+ line = `[assistant${tag}] ${clip(event.text, maxBlockChars)}`;
801
+ }
802
+ break;
803
+ case "tool_call": {
804
+ const call = callAt.get(event.index);
805
+ const input = call ? JSON.stringify(call.input) : "";
806
+ line = `[tool${tag}] ${event.toolName ?? call?.name ?? "?"} ${clip(input, Math.min(maxBlockChars, 500))}`;
807
+ break;
808
+ }
809
+ default:
810
+ break;
811
+ }
812
+ if (line === void 0) continue;
813
+ if (event.branchId !== branch) {
814
+ if (branch !== void 0) lines.push(`[/subagent ${label(branch)}]`);
815
+ branch = event.branchId;
816
+ if (branch !== void 0) {
817
+ lines.push(`[subagent ${label(branch)} (${branch})]`);
818
+ }
819
+ }
820
+ lines.push(line);
821
+ }
822
+ if (branch !== void 0) lines.push(`[/subagent ${label(branch)}]`);
823
+ let timeline = scrub(lines.join("\n"));
824
+ const budget = Math.max(
825
+ maxTotalChars - header.length - TIMELINE_SHELL.length,
826
+ MIN_TIMELINE_CHARS
827
+ );
828
+ if (timeline.length > budget) {
829
+ options.onTruncated?.();
830
+ const marker = (omitted2) => `
831
+ [... truncated ${omitted2} chars of transcript ...]
832
+ `;
833
+ const room = Math.max(budget - marker(timeline.length).length, 0);
834
+ const headLen = Math.floor(room * 0.6);
835
+ const tailLen = room - headLen;
836
+ const omitted = timeline.length - headLen - tailLen;
837
+ timeline = `${timeline.slice(0, headLen)}${marker(omitted)}${tailLen > 0 ? timeline.slice(-tailLen) : ""}`;
838
+ }
839
+ return `${header}${TIMELINE_SHELL}${timeline}`;
840
+ }
841
+
842
+ export {
843
+ detectFormat,
844
+ detectContentFormat,
845
+ parseTraceFile,
846
+ parseTraceContent,
847
+ renderTrace
848
+ };
849
+ //# sourceMappingURL=chunk-M2RLHZ4J.js.map