@jinn-network/client 0.1.7 → 0.1.8

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 (319) hide show
  1. package/README.md +67 -1
  2. package/dist/adapters/mech/adapter.d.ts +19 -1
  3. package/dist/adapters/mech/adapter.js +130 -14
  4. package/dist/adapters/mech/adapter.js.map +1 -1
  5. package/dist/adapters/mech/contracts.d.ts +22 -1
  6. package/dist/adapters/mech/contracts.js +34 -24
  7. package/dist/adapters/mech/contracts.js.map +1 -1
  8. package/dist/adapters/mech/safe.d.ts +1 -1
  9. package/dist/adapters/mech/safe.js +5 -3
  10. package/dist/adapters/mech/safe.js.map +1 -1
  11. package/dist/adapters/mech/types.d.ts +6 -1
  12. package/dist/adapters/mech/types.js.map +1 -1
  13. package/dist/agent/operator-claude.js +8 -0
  14. package/dist/agent/operator-claude.js.map +1 -1
  15. package/dist/api/activity-events-endpoint.d.ts +14 -0
  16. package/dist/api/activity-events-endpoint.js +59 -0
  17. package/dist/api/activity-events-endpoint.js.map +1 -0
  18. package/dist/api/bootstrap-endpoint.d.ts +1 -2
  19. package/dist/api/bootstrap-endpoint.js +42 -24
  20. package/dist/api/bootstrap-endpoint.js.map +1 -1
  21. package/dist/api/codex-doctor-endpoint.d.ts +22 -5
  22. package/dist/api/codex-doctor-endpoint.js +136 -17
  23. package/dist/api/codex-doctor-endpoint.js.map +1 -1
  24. package/dist/api/debug-report-endpoint.d.ts +27 -0
  25. package/dist/api/debug-report-endpoint.js +157 -0
  26. package/dist/api/debug-report-endpoint.js.map +1 -0
  27. package/dist/api/gather-status.d.ts +33 -0
  28. package/dist/api/gather-status.js +211 -26
  29. package/dist/api/gather-status.js.map +1 -1
  30. package/dist/api/hermes-doctor-endpoint.d.ts +15 -7
  31. package/dist/api/hermes-doctor-endpoint.js +56 -19
  32. package/dist/api/hermes-doctor-endpoint.js.map +1 -1
  33. package/dist/api/launcher-status.d.ts +4 -2
  34. package/dist/api/launcher-status.js +11 -10
  35. package/dist/api/launcher-status.js.map +1 -1
  36. package/dist/api/launcher-tasks.d.ts +1 -1
  37. package/dist/api/launcher-tasks.js +12 -8
  38. package/dist/api/launcher-tasks.js.map +1 -1
  39. package/dist/api/operator-artifacts-endpoint.js +73 -6
  40. package/dist/api/operator-artifacts-endpoint.js.map +1 -1
  41. package/dist/api/portfolio-v0-build.d.ts +7 -1
  42. package/dist/api/portfolio-v0-build.js +6 -2
  43. package/dist/api/portfolio-v0-build.js.map +1 -1
  44. package/dist/api/prediction-v1-build.d.ts +6 -0
  45. package/dist/api/prediction-v1-build.js +3 -1
  46. package/dist/api/prediction-v1-build.js.map +1 -1
  47. package/dist/api/server.d.ts +17 -0
  48. package/dist/api/server.js +40 -1
  49. package/dist/api/server.js.map +1 -1
  50. package/dist/api/setup-endpoints.d.ts +0 -9
  51. package/dist/api/setup-endpoints.js +11 -153
  52. package/dist/api/setup-endpoints.js.map +1 -1
  53. package/dist/api/solvernets-endpoints.js +30 -63
  54. package/dist/api/solvernets-endpoints.js.map +1 -1
  55. package/dist/api/status-build.d.ts +115 -2
  56. package/dist/api/status-build.js +47 -11
  57. package/dist/api/status-build.js.map +1 -1
  58. package/dist/api/status-harness-rollup.d.ts +35 -0
  59. package/dist/api/status-harness-rollup.js +45 -0
  60. package/dist/api/status-harness-rollup.js.map +1 -0
  61. package/dist/api/task-runs-build.d.ts +8 -0
  62. package/dist/api/task-runs-build.js +5 -1
  63. package/dist/api/task-runs-build.js.map +1 -1
  64. package/dist/build-info.json +4 -4
  65. package/dist/build-meta.json +1 -1
  66. package/dist/captures/live-publisher.js +24 -4
  67. package/dist/captures/live-publisher.js.map +1 -1
  68. package/dist/captures/publish.d.ts +1 -1
  69. package/dist/chain-read-errors.d.ts +12 -0
  70. package/dist/chain-read-errors.js +26 -1
  71. package/dist/chain-read-errors.js.map +1 -1
  72. package/dist/cli/commands/codedigest-revert-check.d.ts +33 -0
  73. package/dist/cli/commands/codedigest-revert-check.js +249 -0
  74. package/dist/cli/commands/codedigest-revert-check.js.map +1 -0
  75. package/dist/cli/commands/solver-nets.d.ts +1 -0
  76. package/dist/cli/commands/solver-nets.js +177 -22
  77. package/dist/cli/commands/solver-nets.js.map +1 -1
  78. package/dist/cli/commands/solver-plugins-block.d.ts +33 -0
  79. package/dist/cli/commands/solver-plugins-block.js +118 -0
  80. package/dist/cli/commands/solver-plugins-block.js.map +1 -0
  81. package/dist/cli/commands/solver-plugins-feedback.d.ts +72 -0
  82. package/dist/cli/commands/solver-plugins-feedback.js +262 -0
  83. package/dist/cli/commands/solver-plugins-feedback.js.map +1 -0
  84. package/dist/cli/commands/solver-plugins-read.d.ts +54 -0
  85. package/dist/cli/commands/solver-plugins-read.js +259 -0
  86. package/dist/cli/commands/solver-plugins-read.js.map +1 -0
  87. package/dist/cli/commands/solver-plugins.d.ts +35 -0
  88. package/dist/cli/commands/solver-plugins.js +399 -2
  89. package/dist/cli/commands/solver-plugins.js.map +1 -1
  90. package/dist/cli/commands/tasks.js +15 -2
  91. package/dist/cli/commands/tasks.js.map +1 -1
  92. package/dist/cli/index.js +2 -0
  93. package/dist/cli/index.js.map +1 -1
  94. package/dist/cli/task-native-readiness.d.ts +7 -0
  95. package/dist/cli/task-native-readiness.js +7 -5
  96. package/dist/cli/task-native-readiness.js.map +1 -1
  97. package/dist/config.d.ts +183 -232
  98. package/dist/config.js +232 -107
  99. package/dist/config.js.map +1 -1
  100. package/dist/daemon/ai-units-gate.d.ts +54 -0
  101. package/dist/daemon/ai-units-gate.js +82 -0
  102. package/dist/daemon/ai-units-gate.js.map +1 -0
  103. package/dist/daemon/creator.js +13 -0
  104. package/dist/daemon/creator.js.map +1 -1
  105. package/dist/daemon/daemon.d.ts +10 -0
  106. package/dist/daemon/daemon.js +203 -30
  107. package/dist/daemon/daemon.js.map +1 -1
  108. package/dist/daemon/gate-logger.d.ts +9 -0
  109. package/dist/daemon/gate-logger.js +2 -0
  110. package/dist/daemon/gate-logger.js.map +1 -0
  111. package/dist/daemon/jinn-claim-loop.js +22 -4
  112. package/dist/daemon/jinn-claim-loop.js.map +1 -1
  113. package/dist/daemon/readiness-gate.d.ts +1 -4
  114. package/dist/daemon/readiness-gate.js.map +1 -1
  115. package/dist/daemon/spend-cap-gate.d.ts +40 -0
  116. package/dist/daemon/spend-cap-gate.js +46 -0
  117. package/dist/daemon/spend-cap-gate.js.map +1 -0
  118. package/dist/dashboard/assets/index-CzKxvMcU.css +32 -0
  119. package/dist/dashboard/assets/index-yVemxHot.js +351 -0
  120. package/dist/dashboard/index.html +2 -2
  121. package/dist/discovery/http.js +328 -1
  122. package/dist/discovery/http.js.map +1 -1
  123. package/dist/discovery/onchain.js +42 -4
  124. package/dist/discovery/onchain.js.map +1 -1
  125. package/dist/discovery/types.d.ts +129 -0
  126. package/dist/discovery/types.js.map +1 -1
  127. package/dist/discovery/with-fallback.js +27 -0
  128. package/dist/discovery/with-fallback.js.map +1 -1
  129. package/dist/earning/bootstrap.d.ts +8 -3
  130. package/dist/earning/bootstrap.js +36 -13
  131. package/dist/earning/bootstrap.js.map +1 -1
  132. package/dist/earning/safe-adapter.js +23 -11
  133. package/dist/earning/safe-adapter.js.map +1 -1
  134. package/dist/earning/types.d.ts +6 -6
  135. package/dist/earning/viem-clients.d.ts +11 -4
  136. package/dist/earning/viem-clients.js +14 -5
  137. package/dist/earning/viem-clients.js.map +1 -1
  138. package/dist/erc8004/identity.d.ts +19 -3
  139. package/dist/erc8004/identity.js +38 -11
  140. package/dist/erc8004/identity.js.map +1 -1
  141. package/dist/erc8004/index.d.ts +1 -1
  142. package/dist/erc8004/index.js.map +1 -1
  143. package/dist/events/types.d.ts +2 -2
  144. package/dist/harnesses/cost-estimates.d.ts +10 -31
  145. package/dist/harnesses/cost-estimates.js +11 -43
  146. package/dist/harnesses/cost-estimates.js.map +1 -1
  147. package/dist/harnesses/engine/engine.d.ts +28 -4
  148. package/dist/harnesses/engine/engine.js +103 -17
  149. package/dist/harnesses/engine/engine.js.map +1 -1
  150. package/dist/harnesses/engine/persistence.d.ts +21 -4
  151. package/dist/harnesses/engine/persistence.js +43 -6
  152. package/dist/harnesses/engine/persistence.js.map +1 -1
  153. package/dist/harnesses/engine/state.d.ts +9 -0
  154. package/dist/harnesses/engine/state.js +23 -10
  155. package/dist/harnesses/engine/state.js.map +1 -1
  156. package/dist/harnesses/impls/hermes-agent/bootstrap.js +4 -2
  157. package/dist/harnesses/impls/hermes-agent/bootstrap.js.map +1 -1
  158. package/dist/harnesses/impls/hermes-agent/config-builder.d.ts +1 -1
  159. package/dist/harnesses/impls/hermes-agent/config-builder.js +4 -2
  160. package/dist/harnesses/impls/hermes-agent/config-builder.js.map +1 -1
  161. package/dist/harnesses/impls/hermes-agent/harness.d.ts +14 -0
  162. package/dist/harnesses/impls/hermes-agent/harness.js +16 -2
  163. package/dist/harnesses/impls/hermes-agent/harness.js.map +1 -1
  164. package/dist/harnesses/impls/hermes-agent/prompt.d.ts +6 -6
  165. package/dist/harnesses/impls/hermes-agent/prompt.js +6 -6
  166. package/dist/harnesses/impls/learner/adapters/claude-code.d.ts +17 -0
  167. package/dist/harnesses/impls/learner/adapters/claude-code.js +113 -14
  168. package/dist/harnesses/impls/learner/adapters/claude-code.js.map +1 -1
  169. package/dist/harnesses/impls/learner/adapters/codex-code.d.ts +9 -0
  170. package/dist/harnesses/impls/learner/adapters/codex-code.js +30 -8
  171. package/dist/harnesses/impls/learner/adapters/codex-code.js.map +1 -1
  172. package/dist/harnesses/impls/learner/harness.d.ts +24 -0
  173. package/dist/harnesses/impls/learner/harness.js +27 -3
  174. package/dist/harnesses/impls/learner/harness.js.map +1 -1
  175. package/dist/harnesses/impls/learner/harvest.d.ts +1 -1
  176. package/dist/harnesses/impls/learner/harvest.js +23 -5
  177. package/dist/harnesses/impls/learner/harvest.js.map +1 -1
  178. package/dist/harnesses/impls/learner/restoration-patch.d.ts +2 -2
  179. package/dist/harnesses/impls/learner/restoration-patch.js +25 -6
  180. package/dist/harnesses/impls/learner/restoration-patch.js.map +1 -1
  181. package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js +21 -1
  182. package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js.map +1 -1
  183. package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.d.ts +74 -5
  184. package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js +103 -32
  185. package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js.map +1 -1
  186. package/dist/harnesses/readiness-registry.d.ts +7 -0
  187. package/dist/harnesses/readiness-registry.js +9 -0
  188. package/dist/harnesses/readiness-registry.js.map +1 -1
  189. package/dist/learner/revert-decision.d.ts +59 -0
  190. package/dist/learner/revert-decision.js +53 -0
  191. package/dist/learner/revert-decision.js.map +1 -0
  192. package/dist/learner/revert-stats.d.ts +24 -0
  193. package/dist/learner/revert-stats.js +44 -0
  194. package/dist/learner/revert-stats.js.map +1 -0
  195. package/dist/main.js +177 -104
  196. package/dist/main.js.map +1 -1
  197. package/dist/mcp/get-codedigest-reward.d.ts +13 -0
  198. package/dist/mcp/get-codedigest-reward.js +23 -0
  199. package/dist/mcp/get-codedigest-reward.js.map +1 -0
  200. package/dist/mcp/server.js +23 -0
  201. package/dist/mcp/server.js.map +1 -1
  202. package/dist/observability/debug-report-assemble.d.ts +43 -0
  203. package/dist/observability/debug-report-assemble.js +80 -0
  204. package/dist/observability/debug-report-assemble.js.map +1 -0
  205. package/dist/observability/emit-event.d.ts +9 -2
  206. package/dist/observability/emit-event.js +36 -2
  207. package/dist/observability/emit-event.js.map +1 -1
  208. package/dist/observability/file-logger.d.ts +69 -0
  209. package/dist/observability/file-logger.js +177 -0
  210. package/dist/observability/file-logger.js.map +1 -0
  211. package/dist/observability/redact-secrets.d.ts +65 -0
  212. package/dist/observability/redact-secrets.js +300 -0
  213. package/dist/observability/redact-secrets.js.map +1 -0
  214. package/dist/observability/tar.d.ts +30 -0
  215. package/dist/observability/tar.js +102 -0
  216. package/dist/observability/tar.js.map +1 -0
  217. package/dist/plugins/learner/skills/learn/consolidator-prompt.md +18 -1
  218. package/dist/plugins/learner/skills/learn/promoter-prompt.md +72 -1
  219. package/dist/preflight/pidfile-liveness.d.ts +44 -0
  220. package/dist/preflight/pidfile-liveness.js +103 -0
  221. package/dist/preflight/pidfile-liveness.js.map +1 -0
  222. package/dist/preflight/rpc-network.d.ts +40 -0
  223. package/dist/preflight/rpc-network.js +67 -1
  224. package/dist/preflight/rpc-network.js.map +1 -1
  225. package/dist/rpc/transport.d.ts +109 -0
  226. package/dist/rpc/transport.js +220 -0
  227. package/dist/rpc/transport.js.map +1 -0
  228. package/dist/scripts/donation-consumption-acceptance.js +7 -28
  229. package/dist/scripts/donation-consumption-acceptance.js.map +1 -1
  230. package/dist/scripts/swe-rebench-v2-pytest-missing.json +16 -0
  231. package/dist/solver-nets/prediction-operator-ux.d.ts +1 -2
  232. package/dist/solver-nets/prediction-operator-ux.js +56 -53
  233. package/dist/solver-nets/prediction-operator-ux.js.map +1 -1
  234. package/dist/solver-nets/registry.d.ts +19 -1
  235. package/dist/solver-nets/registry.js +37 -24
  236. package/dist/solver-nets/registry.js.map +1 -1
  237. package/dist/solver-types/_swe-rebench-v2-pool.d.ts +9 -2
  238. package/dist/solver-types/_swe-rebench-v2-pool.js +15 -20
  239. package/dist/solver-types/_swe-rebench-v2-pool.js.map +1 -1
  240. package/dist/solver-types/_swe-rebench-v2-state.d.ts +15 -0
  241. package/dist/solver-types/_swe-rebench-v2-state.js +19 -0
  242. package/dist/solver-types/_swe-rebench-v2-state.js.map +1 -1
  243. package/dist/solver-types/_swe-rebench-v2-validated-pool.d.ts +116 -2
  244. package/dist/solver-types/_swe-rebench-v2-validated-pool.js +296 -21
  245. package/dist/solver-types/_swe-rebench-v2-validated-pool.js.map +1 -1
  246. package/dist/solver-types/swe-rebench-v2-auto.d.ts +20 -11
  247. package/dist/solver-types/swe-rebench-v2-auto.js +64 -19
  248. package/dist/solver-types/swe-rebench-v2-auto.js.map +1 -1
  249. package/dist/solver-types/swe-rebench-v2.d.ts +8 -2
  250. package/dist/solver-types/swe-rebench-v2.js +127 -11
  251. package/dist/solver-types/swe-rebench-v2.js.map +1 -1
  252. package/dist/solvernets/daemon-init.d.ts +1 -1
  253. package/dist/solvernets/daemon-init.js +19 -4
  254. package/dist/solvernets/daemon-init.js.map +1 -1
  255. package/dist/solvernets/launched-record-dispatcher.d.ts +4 -0
  256. package/dist/solvernets/launched-record-dispatcher.js +10 -4
  257. package/dist/solvernets/launched-record-dispatcher.js.map +1 -1
  258. package/dist/solvernets/registry-client-erc8004.js +11 -0
  259. package/dist/solvernets/registry-client-erc8004.js.map +1 -1
  260. package/dist/solvernets/store.d.ts +2 -2
  261. package/dist/spend/ai-units-config.d.ts +39 -0
  262. package/dist/spend/ai-units-config.js +28 -0
  263. package/dist/spend/ai-units-config.js.map +1 -0
  264. package/dist/spend/ai-units.d.ts +89 -0
  265. package/dist/spend/ai-units.js +156 -0
  266. package/dist/spend/ai-units.js.map +1 -0
  267. package/dist/spend/cost-surface-status.d.ts +12 -0
  268. package/dist/spend/cost-surface-status.js +24 -0
  269. package/dist/spend/cost-surface-status.js.map +1 -0
  270. package/dist/spend/credential.d.ts +39 -0
  271. package/dist/spend/credential.js +71 -0
  272. package/dist/spend/credential.js.map +1 -0
  273. package/dist/spend/daemon-config.d.ts +13 -0
  274. package/dist/spend/daemon-config.js +24 -0
  275. package/dist/spend/daemon-config.js.map +1 -0
  276. package/dist/spend/pricing.d.ts +16 -0
  277. package/dist/spend/pricing.js +26 -0
  278. package/dist/spend/pricing.js.map +1 -0
  279. package/dist/spend/record.d.ts +13 -0
  280. package/dist/spend/record.js +36 -0
  281. package/dist/spend/record.js.map +1 -0
  282. package/dist/spend/usage.d.ts +27 -0
  283. package/dist/spend/usage.js +113 -0
  284. package/dist/spend/usage.js.map +1 -0
  285. package/dist/store/store.d.ts +101 -0
  286. package/dist/store/store.js +304 -4
  287. package/dist/store/store.js.map +1 -1
  288. package/dist/trajectory/transcript-parsers/codex-session.d.ts +12 -6
  289. package/dist/trajectory/transcript-parsers/codex-session.js +114 -13
  290. package/dist/trajectory/transcript-parsers/codex-session.js.map +1 -1
  291. package/dist/trajectory/transcript-parsers/types.d.ts +8 -8
  292. package/dist/trajectory/transcript-session-dirs.d.ts +18 -0
  293. package/dist/trajectory/transcript-session-dirs.js +85 -0
  294. package/dist/trajectory/transcript-session-dirs.js.map +1 -0
  295. package/dist/trajectory/transcript-watcher.d.ts +20 -1
  296. package/dist/trajectory/transcript-watcher.js +108 -32
  297. package/dist/trajectory/transcript-watcher.js.map +1 -1
  298. package/dist/tx-retry.d.ts +25 -0
  299. package/dist/tx-retry.js +95 -7
  300. package/dist/tx-retry.js.map +1 -1
  301. package/dist/types/payloads/portfolio-v0.d.ts +3 -3
  302. package/dist/types/payloads/prediction-apy-v0.d.ts +3 -3
  303. package/dist/types/payloads/prediction-v0.d.ts +12 -12
  304. package/package.json +11 -3
  305. package/plugins/learner/skills/learn/consolidator-prompt.md +18 -1
  306. package/plugins/learner/skills/learn/promoter-prompt.md +72 -1
  307. package/plugins/swe-rebench-v2-diffmin/README.md +10 -9
  308. package/plugins/swe-rebench-v2-diffmin/jinn.plugin.json +1 -1
  309. package/plugins/swe-rebench-v2-diffmin/skills/diffmin/SKILL.md +15 -10
  310. package/plugins/swe-rebench-v2-diffmin/skills/test-map/SKILL.md +10 -12
  311. package/plugins/swe-rebench-v2-runtime/.claude-plugin/plugin.json +1 -1
  312. package/plugins/swe-rebench-v2-runtime/.codex-plugin/plugin.json +3 -3
  313. package/plugins/swe-rebench-v2-runtime/README.md +6 -6
  314. package/plugins/swe-rebench-v2-runtime/jinn.plugin.json +2 -3
  315. package/plugins/swe-rebench-v2-runtime/skills/task/SKILL.md +81 -0
  316. package/dist/dashboard/assets/index-BUlE8F3Y.js +0 -330
  317. package/dist/dashboard/assets/index-blqc7eqq.css +0 -32
  318. package/plugins/swe-rebench-v2-runtime/skills/orient/SKILL.md +0 -29
  319. package/plugins/swe-rebench-v2-runtime/skills/plan/SKILL.md +0 -53
@@ -9,21 +9,24 @@
9
9
  * a top-level function_call field)
10
10
  * - role: 'tool' with content → tool-result
11
11
  *
12
+ * Codex CLI 0.129.0+ wraps each line as `{ timestamp, type, payload }` where
13
+ * `type` is `session_meta`, `turn_context`, `response_item`, or `event_msg`.
14
+ * Tool calls and messages live inside `payload` (e.g. `function_call`,
15
+ * `function_call_output`, `message` with `input_text` / `output_text` blocks).
16
+ * Older sessions use a flat per-line shape with `role` at the top level; both
17
+ * are detected by record shape.
18
+ *
12
19
  * `parseChunk` preserves any incomplete trailing line across calls so the
13
20
  * watcher (Task 3.9) can stream tail bytes without losing partial records.
14
21
  *
15
- * Codex CLI versions vary in their on-disk shape; this parser follows a
16
- * defensible best-effort: timestamps are read from `ts` (or `timestamp`),
17
- * function-call arguments are JSON-decoded best-effort, and tool-results
18
- * carry the call's `name` (or `tool_call_id` as a fallback) so downstream
19
- * consumers always see a stable identifier even if it is opaque.
20
- *
21
22
  * Spec: spec/2026-05-07-telemetry-collector-and-task-generator.md §4.2 path B.
22
23
  */
23
24
  import { readFile } from 'node:fs/promises';
24
25
  export class CodexSessionParser {
25
26
  tool = 'codex';
26
27
  buffer = '';
28
+ /** Maps function_call `call_id` → tool name for function_call_output rows. */
29
+ callNames = new Map();
27
30
  parseChunk(input) {
28
31
  const text = typeof input.chunk === 'string' ? input.chunk : input.chunk.toString('utf-8');
29
32
  this.buffer += text;
@@ -33,14 +36,14 @@ export class CodexSessionParser {
33
36
  for (const line of lines) {
34
37
  if (!line.trim())
35
38
  continue;
36
- let record;
39
+ let raw;
37
40
  try {
38
- record = JSON.parse(line);
41
+ raw = JSON.parse(line);
39
42
  }
40
43
  catch {
41
44
  continue;
42
45
  }
43
- events.push(...this.recordToEvents(record));
46
+ events.push(...this.lineToEvents(raw));
44
47
  }
45
48
  return events;
46
49
  }
@@ -48,13 +51,83 @@ export class CodexSessionParser {
48
51
  const text = await readFile(input.path, 'utf-8');
49
52
  const normalised = text.endsWith('\n') ? text : text + '\n';
50
53
  const previousBuffer = this.buffer;
54
+ const previousCallNames = new Map(this.callNames);
51
55
  this.buffer = '';
56
+ this.callNames.clear();
52
57
  try {
53
58
  return this.parseChunk({ sessionId: input.sessionId, chunk: normalised });
54
59
  }
55
60
  finally {
56
61
  this.buffer = previousBuffer;
62
+ this.callNames = previousCallNames;
63
+ }
64
+ }
65
+ lineToEvents(raw) {
66
+ if (!raw || typeof raw !== 'object')
67
+ return [];
68
+ if (isWrappedEnvelope(raw)) {
69
+ return this.wrappedEnvelopeToEvents(raw);
57
70
  }
71
+ return this.recordToEvents(raw);
72
+ }
73
+ wrappedEnvelopeToEvents(envelope) {
74
+ const ts = envelope.timestamp;
75
+ if (typeof ts !== 'string')
76
+ return [];
77
+ const payload = envelope.payload;
78
+ if (!payload || typeof payload !== 'object')
79
+ return [];
80
+ if (envelope.type === 'response_item') {
81
+ return this.responseItemToEvents(ts, payload);
82
+ }
83
+ // `event_msg` rows (user_message, agent_message, mcp_tool_call_end) duplicate
84
+ // `response_item` message/tool rows — skip them to avoid double-counting.
85
+ return [];
86
+ }
87
+ responseItemToEvents(ts, payload) {
88
+ const itemType = payload.type;
89
+ if (itemType === 'function_call') {
90
+ const name = payload.name;
91
+ if (typeof name !== 'string')
92
+ return [];
93
+ const callId = payload.call_id;
94
+ if (typeof callId === 'string') {
95
+ this.callNames.set(callId, name);
96
+ }
97
+ return [
98
+ {
99
+ kind: 'tool-call',
100
+ timestamp: ts,
101
+ name,
102
+ args: parseArgs(payload.arguments),
103
+ },
104
+ ];
105
+ }
106
+ if (itemType === 'function_call_output') {
107
+ const output = payload.output;
108
+ const content = typeof output === 'string' ? output : stringifyContent(output);
109
+ if (!content)
110
+ return [];
111
+ const callId = payload.call_id;
112
+ const name = (typeof callId === 'string' ? this.callNames.get(callId) : undefined) ??
113
+ (typeof callId === 'string' ? callId : undefined);
114
+ if (typeof name !== 'string')
115
+ return [];
116
+ return [{ kind: 'tool-result', timestamp: ts, name, content, isError: false }];
117
+ }
118
+ if (itemType === 'message') {
119
+ const role = payload.role;
120
+ const text = extractMessageText(payload.content);
121
+ if (!text)
122
+ return [];
123
+ if (role === 'user') {
124
+ return [{ kind: 'user-message', timestamp: ts, content: text }];
125
+ }
126
+ if (role === 'assistant') {
127
+ return [{ kind: 'assistant-message', timestamp: ts, content: text }];
128
+ }
129
+ }
130
+ return [];
58
131
  }
59
132
  recordToEvents(record) {
60
133
  if (!record || typeof record !== 'object')
@@ -79,14 +152,16 @@ export class CodexSessionParser {
79
152
  }
80
153
  }
81
154
  if (role === 'user') {
82
- if (typeof record.content === 'string') {
83
- return [{ kind: 'user-message', timestamp: ts, content: record.content }];
155
+ const text = extractMessageText(record.content);
156
+ if (text) {
157
+ return [{ kind: 'user-message', timestamp: ts, content: text }];
84
158
  }
85
159
  return [];
86
160
  }
87
161
  if (role === 'assistant') {
88
- if (typeof record.content === 'string') {
89
- return [{ kind: 'assistant-message', timestamp: ts, content: record.content }];
162
+ const text = extractMessageText(record.content);
163
+ if (text) {
164
+ return [{ kind: 'assistant-message', timestamp: ts, content: text }];
90
165
  }
91
166
  return [];
92
167
  }
@@ -105,6 +180,32 @@ export class CodexSessionParser {
105
180
  return [];
106
181
  }
107
182
  }
183
+ function isWrappedEnvelope(raw) {
184
+ const rec = raw;
185
+ return (typeof rec.type === 'string' &&
186
+ rec.payload !== undefined &&
187
+ rec.payload !== null &&
188
+ typeof rec.payload === 'object' &&
189
+ !('role' in rec));
190
+ }
191
+ function extractMessageText(content) {
192
+ if (typeof content === 'string')
193
+ return content;
194
+ if (!Array.isArray(content))
195
+ return null;
196
+ const parts = [];
197
+ for (const block of content) {
198
+ if (!block || typeof block !== 'object')
199
+ continue;
200
+ const b = block;
201
+ const blockType = b.type;
202
+ if ((blockType === 'input_text' || blockType === 'output_text') &&
203
+ typeof b.text === 'string') {
204
+ parts.push(b.text);
205
+ }
206
+ }
207
+ return parts.length > 0 ? parts.join('\n') : null;
208
+ }
108
209
  function parseArgs(raw) {
109
210
  if (!raw)
110
211
  return {};
@@ -1 +1 @@
1
- {"version":3,"file":"codex-session.js","sourceRoot":"","sources":["../../../src/trajectory/transcript-parsers/codex-session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"codex-session.js","sourceRoot":"","sources":["../../../src/trajectory/transcript-parsers/codex-session.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAwB5C,MAAM,OAAO,kBAAkB;IACpB,IAAI,GAAG,OAAgB,CAAC;IACzB,MAAM,GAAG,EAAE,CAAC;IACpB,8EAA8E;IACtE,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE9C,UAAU,CAAC,KAAoD;QAC7D,MAAM,IAAI,GACR,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAChF,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;QAEhC,MAAM,MAAM,GAAsB,EAAE,CAAC;QACrC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBAAE,SAAS;YAC3B,IAAI,GAAY,CAAC;YACjB,IAAI,CAAC;gBACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,KAA0C;QACxD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC;QAC5D,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC;QACnC,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,UAAU,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;QAC5E,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC;YAC7B,IAAI,CAAC,SAAS,GAAG,iBAAiB,CAAC;QACrC,CAAC;IACH,CAAC;IAEO,YAAY,CAAC,GAAY;QAC/B,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QAC/C,IAAI,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,IAAI,CAAC,cAAc,CAAC,GAAkB,CAAC,CAAC;IACjD,CAAC;IAEO,uBAAuB,CAAC,QAAyB;QACvD,MAAM,EAAE,GAAG,QAAQ,CAAC,SAAS,CAAC;QAC9B,IAAI,OAAO,EAAE,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QAEtC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;QACjC,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QAEvD,IAAI,QAAQ,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC,oBAAoB,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAChD,CAAC;QAED,8EAA8E;QAC9E,0EAA0E;QAC1E,OAAO,EAAE,CAAC;IACZ,CAAC;IAEO,oBAAoB,CAAC,EAAU,EAAE,OAAgC;QACvE,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;QAC9B,IAAI,QAAQ,KAAK,eAAe,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;YAC1B,IAAI,OAAO,IAAI,KAAK,QAAQ;gBAAE,OAAO,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YAC/B,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;gBAC/B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YACnC,CAAC;YACD,OAAO;gBACL;oBACE,IAAI,EAAE,WAAW;oBACjB,SAAS,EAAE,EAAE;oBACb,IAAI;oBACJ,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,SAAyD,CAAC;iBACnF;aACF,CAAC;QACJ,CAAC;QAED,IAAI,QAAQ,KAAK,sBAAsB,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAC9B,MAAM,OAAO,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;YAC/E,IAAI,CAAC,OAAO;gBAAE,OAAO,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YAC/B,MAAM,IAAI,GACR,CAAC,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBACrE,CAAC,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YACpD,IAAI,OAAO,IAAI,KAAK,QAAQ;gBAAE,OAAO,EAAE,CAAC;YACxC,OAAO,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QACjF,CAAC;QAED,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;YAC1B,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACjD,IAAI,CAAC,IAAI;gBAAE,OAAO,EAAE,CAAC;YACrB,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;gBACpB,OAAO,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YAClE,CAAC;YACD,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;gBACzB,OAAO,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACvE,CAAC;QACH,CAAC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;IAEO,cAAc,CAAC,MAAmB;QACxC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QACrD,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,SAAS,CAAC;QACzC,IAAI,OAAO,EAAE,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QAEtC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QAEzB,2EAA2E;QAC3E,oEAAoE;QACpE,IAAI,MAAM,CAAC,aAAa,IAAI,OAAO,MAAM,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;YACrE,MAAM,EAAE,GAAG,MAAM,CAAC,aAAa,CAAC;YAChC,IAAI,OAAO,EAAE,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAChC,OAAO;oBACL;wBACE,IAAI,EAAE,WAAW;wBACjB,SAAS,EAAE,EAAE;wBACb,IAAI,EAAE,EAAE,CAAC,IAAI;wBACb,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC;qBAC9B;iBACF,CAAC;YACJ,CAAC;QACH,CAAC;QAED,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACpB,MAAM,IAAI,GAAG,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAChD,IAAI,IAAI,EAAE,CAAC;gBACT,OAAO,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YAClE,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAChD,IAAI,IAAI,EAAE,CAAC;gBACT,OAAO,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACvE,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,iBAAiB,EAAE,CAAC;YAClD,MAAM,OAAO,GAAG,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACjD,IAAI,CAAC,OAAO;gBAAE,OAAO,EAAE,CAAC;YACxB,uEAAuE;YACvE,oEAAoE;YACpE,wEAAwE;YACxE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,YAAY,CAAC;YAChD,IAAI,OAAO,IAAI,KAAK,QAAQ;gBAAE,OAAO,EAAE,CAAC;YACxC,OAAO,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QACjF,CAAC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;CACF;AAED,SAAS,iBAAiB,CAAC,GAAW;IACpC,MAAM,GAAG,GAAG,GAAsB,CAAC;IACnC,OAAO,CACL,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;QAC5B,GAAG,CAAC,OAAO,KAAK,SAAS;QACzB,GAAG,CAAC,OAAO,KAAK,IAAI;QACpB,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ;QAC/B,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CACjB,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,OAAgB;IAC1C,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC;IAChD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,SAAS;QAClD,MAAM,CAAC,GAAG,KAAgC,CAAC;QAC3C,MAAM,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC;QACzB,IACE,CAAC,SAAS,KAAK,YAAY,IAAI,SAAS,KAAK,aAAa,CAAC;YAC3D,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,EAC1B,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC;AAED,SAAS,SAAS,CAAC,GAAiD;IAClE,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IACxC,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/B,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBACnE,OAAO,MAAiC,CAAC;YAC3C,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,uEAAuE;YACvE,qEAAqE;YACrE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAgB;IACxC,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC;IAChD,IAAI,OAAO,IAAI,IAAI;QAAE,OAAO,EAAE,CAAC;IAC/B,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC"}
@@ -5,24 +5,24 @@ export declare const TranscriptEventSchema: z.ZodDiscriminatedUnion<"kind", [z.Z
5
5
  content: z.ZodString;
6
6
  }, "strip", z.ZodTypeAny, {
7
7
  kind: "user-message";
8
- content: string;
9
8
  timestamp: string;
9
+ content: string;
10
10
  }, {
11
11
  kind: "user-message";
12
- content: string;
13
12
  timestamp: string;
13
+ content: string;
14
14
  }>, z.ZodObject<{
15
15
  kind: z.ZodLiteral<"assistant-message">;
16
16
  timestamp: z.ZodString;
17
17
  content: z.ZodString;
18
18
  }, "strip", z.ZodTypeAny, {
19
19
  kind: "assistant-message";
20
- content: string;
21
20
  timestamp: string;
21
+ content: string;
22
22
  }, {
23
23
  kind: "assistant-message";
24
- content: string;
25
24
  timestamp: string;
25
+ content: string;
26
26
  }>, z.ZodObject<{
27
27
  kind: z.ZodLiteral<"tool-call">;
28
28
  timestamp: z.ZodString;
@@ -31,13 +31,13 @@ export declare const TranscriptEventSchema: z.ZodDiscriminatedUnion<"kind", [z.Z
31
31
  }, "strip", z.ZodTypeAny, {
32
32
  name: string;
33
33
  kind: "tool-call";
34
- args: Record<string, unknown>;
35
34
  timestamp: string;
35
+ args: Record<string, unknown>;
36
36
  }, {
37
37
  name: string;
38
38
  kind: "tool-call";
39
- args: Record<string, unknown>;
40
39
  timestamp: string;
40
+ args: Record<string, unknown>;
41
41
  }>, z.ZodObject<{
42
42
  kind: z.ZodLiteral<"tool-result">;
43
43
  timestamp: z.ZodString;
@@ -47,14 +47,14 @@ export declare const TranscriptEventSchema: z.ZodDiscriminatedUnion<"kind", [z.Z
47
47
  }, "strip", z.ZodTypeAny, {
48
48
  name: string;
49
49
  kind: "tool-result";
50
- content: string;
51
50
  timestamp: string;
51
+ content: string;
52
52
  isError?: boolean | undefined;
53
53
  }, {
54
54
  name: string;
55
55
  kind: "tool-result";
56
- content: string;
57
56
  timestamp: string;
57
+ content: string;
58
58
  isError?: boolean | undefined;
59
59
  }>, z.ZodObject<{
60
60
  kind: z.ZodLiteral<"edit">;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Standard per-tool session transcript directories for Path B tail watching.
3
+ *
4
+ * Spec: spec/2026-05-07-telemetry-collector-and-task-generator.md §4.2 path B.
5
+ */
6
+ import type { WatchedDirectory } from './transcript-watcher.js';
7
+ export declare function resolveCodexHomeDir(): string;
8
+ export declare function resolveCodexSessionsDir(): string;
9
+ export declare function resolveClaudeProjectsDir(): string;
10
+ export declare function sessionIdFromJsonlPath(filePath: string): string;
11
+ /** Lists `*.jsonl` session files under `directory` (flat or recursive). */
12
+ export declare function listSessionJsonlFiles(directory: string, recursive: boolean): Promise<string[]>;
13
+ /**
14
+ * Default Path-B directories for tools that write session JSONL to well-known
15
+ * locations. Missing directories are omitted so a fresh operator machine does
16
+ * not fail daemon startup.
17
+ */
18
+ export declare function defaultTranscriptWatchDirectories(): WatchedDirectory[];
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Standard per-tool session transcript directories for Path B tail watching.
3
+ *
4
+ * Spec: spec/2026-05-07-telemetry-collector-and-task-generator.md §4.2 path B.
5
+ */
6
+ import { existsSync } from 'node:fs';
7
+ import { readdir } from 'node:fs/promises';
8
+ import { homedir } from 'node:os';
9
+ import { basename, join } from 'node:path';
10
+ export function resolveCodexHomeDir() {
11
+ return process.env['CODEX_HOME']?.trim() || join(homedir(), '.codex');
12
+ }
13
+ export function resolveCodexSessionsDir() {
14
+ return join(resolveCodexHomeDir(), 'sessions');
15
+ }
16
+ export function resolveClaudeProjectsDir() {
17
+ return join(homedir(), '.claude', 'projects');
18
+ }
19
+ export function sessionIdFromJsonlPath(filePath) {
20
+ const name = basename(filePath);
21
+ return name.endsWith('.jsonl') ? name.slice(0, -'.jsonl'.length) : name;
22
+ }
23
+ async function listJsonlFilesRecursive(dir) {
24
+ let entries;
25
+ try {
26
+ entries = await readdir(dir, { withFileTypes: true });
27
+ }
28
+ catch {
29
+ return [];
30
+ }
31
+ const out = [];
32
+ for (const entry of entries) {
33
+ const full = join(dir, entry.name);
34
+ if (entry.isDirectory()) {
35
+ out.push(...(await listJsonlFilesRecursive(full)));
36
+ }
37
+ else if (entry.isFile() && entry.name.endsWith('.jsonl')) {
38
+ out.push(full);
39
+ }
40
+ }
41
+ return out;
42
+ }
43
+ /** Lists `*.jsonl` session files under `directory` (flat or recursive). */
44
+ export async function listSessionJsonlFiles(directory, recursive) {
45
+ if (recursive) {
46
+ return listJsonlFilesRecursive(directory);
47
+ }
48
+ let entries;
49
+ try {
50
+ entries = await readdir(directory, { withFileTypes: true });
51
+ }
52
+ catch {
53
+ return [];
54
+ }
55
+ return entries
56
+ .filter((e) => e.isFile() && e.name.endsWith('.jsonl'))
57
+ .map((e) => join(directory, e.name));
58
+ }
59
+ /**
60
+ * Default Path-B directories for tools that write session JSONL to well-known
61
+ * locations. Missing directories are omitted so a fresh operator machine does
62
+ * not fail daemon startup.
63
+ */
64
+ export function defaultTranscriptWatchDirectories() {
65
+ const dirs = [];
66
+ const codexSessions = resolveCodexSessionsDir();
67
+ if (existsSync(codexSessions)) {
68
+ dirs.push({
69
+ tool: 'codex',
70
+ directory: codexSessions,
71
+ sessionIdFromPath: sessionIdFromJsonlPath,
72
+ });
73
+ }
74
+ const claudeProjects = resolveClaudeProjectsDir();
75
+ if (existsSync(claudeProjects)) {
76
+ dirs.push({
77
+ tool: 'claude-code',
78
+ directory: claudeProjects,
79
+ recursive: true,
80
+ sessionIdFromPath: sessionIdFromJsonlPath,
81
+ });
82
+ }
83
+ return dirs;
84
+ }
85
+ //# sourceMappingURL=transcript-session-dirs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript-session-dirs.js","sourceRoot":"","sources":["../../src/trajectory/transcript-session-dirs.ts"],"names":[],"mappings":"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"}
@@ -23,6 +23,13 @@
23
23
  * every previously-seen transcript record. (The `jinn capture import` CLI
24
24
  * uses `parser.parseFull` for one-shot history ingest.)
25
25
  *
26
+ * ## Directory watching
27
+ *
28
+ * `directories` watches a session folder for new or growing `*.jsonl` files
29
+ * (e.g. `~/.codex/sessions`, `~/.claude/projects/**`). Existing files are
30
+ * registered at startup with the same tail-from-end baseline; `add` events
31
+ * register files created after startup.
32
+ *
26
33
  * ## Cursor SQLite quirk — fail loudly
27
34
  *
28
35
  * The Cursor parser's `parseChunk` is a no-op: SQLite isn't streaming, and
@@ -47,13 +54,25 @@ export interface WatchedSource {
47
54
  */
48
55
  sessionId: string;
49
56
  }
57
+ export interface WatchedDirectory {
58
+ tool: WatchedTool;
59
+ /** Absolute path to the directory containing session JSONL files. */
60
+ directory: string;
61
+ /** When true, watch nested .jsonl files recursively (Claude Code projects layout). */
62
+ recursive?: boolean;
63
+ /** Derive the capture session id from an absolute JSONL path. */
64
+ sessionIdFromPath: (absolutePath: string) => string;
65
+ }
50
66
  export interface DispatchEnvelope {
51
67
  tool: WatchedTool;
52
68
  sessionId: string;
53
69
  event: TranscriptEvent;
54
70
  }
55
71
  export interface TranscriptWatcherConfig {
56
- sources: WatchedSource[];
72
+ /** Explicit per-file sources (tests, stop-hook safety-net paths). */
73
+ sources?: WatchedSource[];
74
+ /** Standard session directories (Codex, Claude Code, …). */
75
+ directories?: WatchedDirectory[];
57
76
  onEvent: (envelope: DispatchEnvelope) => void;
58
77
  }
59
78
  export interface TranscriptWatcher {
@@ -23,6 +23,13 @@
23
23
  * every previously-seen transcript record. (The `jinn capture import` CLI
24
24
  * uses `parser.parseFull` for one-shot history ingest.)
25
25
  *
26
+ * ## Directory watching
27
+ *
28
+ * `directories` watches a session folder for new or growing `*.jsonl` files
29
+ * (e.g. `~/.codex/sessions`, `~/.claude/projects/**`). Existing files are
30
+ * registered at startup with the same tail-from-end baseline; `add` events
31
+ * register files created after startup.
32
+ *
26
33
  * ## Cursor SQLite quirk — fail loudly
27
34
  *
28
35
  * The Cursor parser's `parseChunk` is a no-op: SQLite isn't streaming, and
@@ -35,12 +42,15 @@
35
42
  * Spec: spec/2026-05-07-telemetry-collector-and-task-generator.md §4.2 path B.
36
43
  */
37
44
  import * as fs from 'node:fs/promises';
45
+ import { resolve as resolvePath } from 'node:path';
46
+ import { once } from 'node:events';
38
47
  import chokidar from 'chokidar';
39
48
  import { ClaudeCodeJsonlParser } from './transcript-parsers/claude-code-jsonl.js';
40
49
  import { CodexSessionParser } from './transcript-parsers/codex-session.js';
41
50
  import { GeminiSessionParser } from './transcript-parsers/gemini-session.js';
42
51
  import { AiderHistoryParser } from './transcript-parsers/aider-history.js';
43
52
  import { ContinueDevDataParser } from './transcript-parsers/continue-devdata.js';
53
+ import { listSessionJsonlFiles } from './transcript-session-dirs.js';
44
54
  function makeParser(tool) {
45
55
  switch (tool) {
46
56
  case 'claude-code':
@@ -54,10 +64,6 @@ function makeParser(tool) {
54
64
  case 'continue':
55
65
  return new ContinueDevDataParser();
56
66
  case 'cursor':
57
- // See file header. Cursor streaming via chokidar would silently miss
58
- // WAL deltas; the parser's parseChunk is a deliberate no-op. Polling-
59
- // based Cursor support is a Phase 3.5+ follow-up; until then operators
60
- // should use `jinn capture import` for Cursor sessions.
61
67
  throw new Error("Cursor SQLite watching not yet supported in v0 — use 'jinn capture import' " +
62
68
  'for Cursor sessions or wait for polling support (Phase 3.5+).');
63
69
  default: {
@@ -66,44 +72,119 @@ function makeParser(tool) {
66
72
  }
67
73
  }
68
74
  }
75
+ async function tailOffsetForPath(filePath) {
76
+ try {
77
+ const stats = await fs.stat(filePath);
78
+ return stats.size;
79
+ }
80
+ catch {
81
+ return 0;
82
+ }
83
+ }
84
+ function isJsonlSessionFile(filePath) {
85
+ return filePath.endsWith('.jsonl');
86
+ }
69
87
  export async function startTranscriptWatcher(cfg) {
88
+ const sources = cfg.sources ?? [];
89
+ const directories = cfg.directories ?? [];
90
+ if (sources.length === 0 && directories.length === 0) {
91
+ throw new Error('startTranscriptWatcher requires at least one source or directory');
92
+ }
70
93
  const states = new Map();
71
- for (const source of cfg.sources) {
72
- // Construct the parser first so a Cursor source fails loudly *before* we
73
- // open any chokidar handles.
74
- const parser = makeParser(source.tool);
75
- let nextOffset = 0;
76
- try {
77
- const stats = await fs.stat(source.path);
78
- nextOffset = stats.size;
79
- }
80
- catch {
81
- // File doesn't exist yet — start at offset 0; chokidar will fire `add`
82
- // when it appears.
83
- nextOffset = 0;
94
+ const directoryParsers = new Map();
95
+ const registerSource = async (source, opts) => {
96
+ const normalizedPath = resolvePath(source.path);
97
+ const nextOffset = opts.tailFromEnd ? await tailOffsetForPath(normalizedPath) : 0;
98
+ const parser = opts.parser ?? makeParser(source.tool);
99
+ states.set(normalizedPath, {
100
+ source: { ...source, path: normalizedPath },
101
+ parser,
102
+ nextOffset,
103
+ inFlight: Promise.resolve(),
104
+ });
105
+ };
106
+ for (const source of sources) {
107
+ await registerSource(source, { tailFromEnd: true });
108
+ }
109
+ for (const dir of directories) {
110
+ const parser = makeParser(dir.tool);
111
+ directoryParsers.set(dir.tool, parser);
112
+ const files = await listSessionJsonlFiles(dir.directory, dir.recursive === true);
113
+ for (const filePath of files) {
114
+ await registerSource({
115
+ tool: dir.tool,
116
+ path: filePath,
117
+ sessionId: dir.sessionIdFromPath(filePath),
118
+ }, { tailFromEnd: true, parser });
84
119
  }
85
- states.set(source.path, { source, parser, nextOffset, inFlight: Promise.resolve() });
86
120
  }
87
121
  let shuttingDown = false;
88
- const watcher = chokidar.watch(cfg.sources.map((s) => s.path), {
122
+ const watchPaths = [
123
+ ...sources.map((s) => s.path),
124
+ ...directories.map((d) => d.directory),
125
+ ];
126
+ const watcher = chokidar.watch(watchPaths, {
89
127
  persistent: true,
90
- // Wait for writers to settle before reading; cheap insurance against
91
- // half-written JSONL lines.
92
128
  awaitWriteFinish: { stabilityThreshold: 50, pollInterval: 25 },
93
- // Tail-from-end: on startup, current contents are the baseline. Only
94
- // mutations *after* startup should dispatch.
95
129
  ignoreInitial: true,
96
130
  });
131
+ const resolveDirectoryForPath = (filepath) => {
132
+ const normalized = resolvePath(filepath);
133
+ for (const dir of directories) {
134
+ const root = resolvePath(dir.directory);
135
+ const prefix = root.endsWith('/') ? root : `${root}/`;
136
+ if (normalized === root || normalized.startsWith(prefix)) {
137
+ return dir;
138
+ }
139
+ }
140
+ return undefined;
141
+ };
142
+ const ensureStateForPath = async (filepath) => {
143
+ const normalized = resolvePath(filepath);
144
+ const existing = states.get(normalized);
145
+ if (existing)
146
+ return existing;
147
+ const dir = resolveDirectoryForPath(normalized);
148
+ if (!dir || !isJsonlSessionFile(normalized))
149
+ return undefined;
150
+ const parser = directoryParsers.get(dir.tool) ?? makeParser(dir.tool);
151
+ directoryParsers.set(dir.tool, parser);
152
+ const source = {
153
+ tool: dir.tool,
154
+ path: normalized,
155
+ sessionId: dir.sessionIdFromPath(normalized),
156
+ };
157
+ const state = {
158
+ source,
159
+ parser,
160
+ nextOffset: 0,
161
+ inFlight: Promise.resolve(),
162
+ };
163
+ states.set(normalized, state);
164
+ return state;
165
+ };
97
166
  const enqueue = (filepath) => {
98
167
  if (shuttingDown)
99
168
  return;
100
- const state = states.get(filepath);
101
- if (!state)
102
- return;
103
- state.inFlight = state.inFlight.then(() => handleChange(state));
169
+ const normalized = resolvePath(filepath);
170
+ void (async () => {
171
+ const state = states.get(normalized) ?? await ensureStateForPath(normalized);
172
+ if (!state)
173
+ return;
174
+ state.inFlight = state.inFlight.then(() => handleChange(state));
175
+ })();
104
176
  };
105
177
  watcher.on('add', enqueue);
106
178
  watcher.on('change', enqueue);
179
+ // Resolve only once chokidar has finished its initial scan and bound the
180
+ // underlying OS watches. With `awaitWriteFinish` enabled, chokidar does not
181
+ // process `add`/`change` events until `ready` has fired (see chokidar's
182
+ // `_emit` guard on `_readyEmitted`), so returning the watcher before `ready`
183
+ // means appends made immediately after `startTranscriptWatcher` can be
184
+ // silently dropped. Awaiting `ready` makes detection deterministic — the
185
+ // caller is guaranteed a live watcher — instead of racing fs-watch setup
186
+ // latency against a fixed polling budget (the root of #304's CI flake).
187
+ await once(watcher, 'ready');
107
188
  async function handleChange(state) {
108
189
  if (shuttingDown)
109
190
  return;
@@ -115,9 +196,6 @@ export async function startTranscriptWatcher(cfg) {
115
196
  catch {
116
197
  return;
117
198
  }
118
- // Truncation or stale event — skip. (We deliberately do not reset
119
- // nextOffset on truncation; if the file is rotated we'd need explicit
120
- // operator intervention. Phase 3.5+ may add inode-change detection.)
121
199
  if (size <= state.nextOffset)
122
200
  return;
123
201
  const handle = await fs.open(state.source.path, 'r');
@@ -148,8 +226,6 @@ export async function startTranscriptWatcher(cfg) {
148
226
  async shutdown() {
149
227
  shuttingDown = true;
150
228
  await watcher.close();
151
- // Drain any in-flight per-source handlers so post-shutdown the map is
152
- // settled. Errors here are intentionally swallowed — we're tearing down.
153
229
  await Promise.allSettled(Array.from(states.values(), (state) => state.inFlight));
154
230
  },
155
231
  };
@@ -1 +1 @@
1
- {"version":3,"file":"transcript-watcher.js","sourceRoot":"","sources":["../../src/trajectory/transcript-watcher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transcript-watcher.js","sourceRoot":"","sources":["../../src/trajectory/transcript-watcher.ts"],"names":[],"mappings":"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"}