tumwater 0.3.0 → 0.4.1

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 (315) hide show
  1. package/README.md +1 -1
  2. package/dist/build-info.json +2 -2
  3. package/dist/src/agent/agent-backend.js +5 -2
  4. package/dist/src/agent/backend-traits.js +20 -0
  5. package/dist/src/agent/claude/claude-backend.js +3 -3
  6. package/dist/src/agent/claude/claude-stream.js +170 -166
  7. package/dist/src/agent/claude/{write-guard-hook.js → claude-write-guard-hook.js} +1 -1
  8. package/dist/src/agent/claude/claude-write-guard.js +5 -4
  9. package/dist/src/agent/codex/codex-backend.js +4 -4
  10. package/dist/src/agent/codex/codex-rollout.js +10 -21
  11. package/dist/src/agent/codex/codex-stream.js +202 -179
  12. package/dist/src/agent/codex/{write-guard-hook.js → codex-write-guard-hook.js} +2 -1
  13. package/dist/src/agent/codex/codex-write-guard.js +3 -3
  14. package/dist/src/agent/notes-shim.js +2 -2
  15. package/dist/src/agent/opencode/opencode-backend.js +4 -4
  16. package/dist/src/agent/opencode/opencode-config.js +2 -2
  17. package/dist/src/agent/opencode/opencode-stream.js +97 -88
  18. package/dist/src/agent/run-agent.js +66 -381
  19. package/dist/src/agent/run-settle.js +3 -2
  20. package/dist/src/agent/run-spawn.js +235 -0
  21. package/dist/src/agent/run-stream.js +193 -0
  22. package/dist/src/agent/write-guard.js +5 -3
  23. package/dist/src/backlog/backlog-archive.js +88 -36
  24. package/dist/src/backlog/backlog-cli-view.js +92 -98
  25. package/dist/src/backlog/backlog-cli.js +9 -64
  26. package/dist/src/backlog/backlog-commit.js +17 -9
  27. package/dist/src/backlog/backlog-eligibility.js +45 -27
  28. package/dist/src/backlog/backlog-index-data.js +159 -0
  29. package/dist/src/backlog/backlog-index.js +7 -5
  30. package/dist/src/backlog/backlog-md.js +1 -1
  31. package/dist/src/backlog/backlog-parts.js +23 -13
  32. package/dist/src/backlog/backlog-release.js +43 -33
  33. package/dist/src/backlog/backlog-render.js +1 -1
  34. package/dist/src/backlog/backlog-structure.js +0 -144
  35. package/dist/src/backlog/backlog-write.js +30 -17
  36. package/dist/src/backlog/backlog.js +9 -0
  37. package/dist/src/backlog/question-answer.js +3 -1
  38. package/dist/src/baseline/main-baseline.js +50 -15
  39. package/dist/src/baseline/main-guardrails.js +29 -78
  40. package/dist/src/baseline/main-red.js +64 -103
  41. package/dist/src/baseline/main-watch.js +89 -35
  42. package/dist/src/brief/brief-edit.js +3 -1
  43. package/dist/src/brief/brief.js +40 -0
  44. package/dist/src/budget/budget-fallback-view.js +330 -0
  45. package/dist/src/budget/budget-wiring.js +167 -0
  46. package/dist/src/budget/budget.js +3 -2
  47. package/dist/src/build/build-check-events.js +4 -2
  48. package/dist/src/build/build-check-report.js +2 -1
  49. package/dist/src/build/dep-install.js +64 -1
  50. package/dist/src/cli/cli-args.js +72 -0
  51. package/dist/src/cli/cli-flag-specs.js +38 -0
  52. package/dist/src/cli/cli-marker-commands.js +2 -2
  53. package/dist/src/cli/cli-query-commands.js +51 -41
  54. package/dist/src/cli/cli-review-commands.js +113 -0
  55. package/dist/src/cli/cli-role-command.js +140 -58
  56. package/dist/src/cli/cli-start-summary.js +10 -3
  57. package/dist/src/cli/cli-start.js +92 -38
  58. package/dist/src/cli/completion.js +21 -1
  59. package/dist/src/cli/config-commands.js +17 -8
  60. package/dist/src/cli/help.js +84 -16
  61. package/dist/src/cli/log-commands.js +137 -105
  62. package/dist/src/cli/question-commands.js +89 -64
  63. package/dist/src/cli.js +408 -286
  64. package/dist/src/collections.js +56 -6
  65. package/dist/src/config/config-editable-keys.js +3 -0
  66. package/dist/src/config/config-fallbacks.js +3 -2
  67. package/dist/src/config/config-request.js +176 -51
  68. package/dist/src/config/config-validation-roles.js +271 -0
  69. package/dist/src/config/config-validation.js +51 -241
  70. package/dist/src/config/config-views.js +10 -2
  71. package/dist/src/config/config-write.js +209 -140
  72. package/dist/src/config/config.js +9 -3
  73. package/dist/src/doctor/doctor-backlog-bugs.js +96 -53
  74. package/dist/src/doctor/doctor-backlog-plans.js +222 -88
  75. package/dist/src/doctor/doctor-backlog.js +171 -32
  76. package/dist/src/doctor/doctor-check-names.js +7 -1
  77. package/dist/src/doctor/doctor-checks.js +26 -19
  78. package/dist/src/doctor/doctor-claude-checks.js +6 -9
  79. package/dist/src/doctor/doctor-codex-checks.js +15 -29
  80. package/dist/src/doctor/doctor-contention-checks.js +293 -134
  81. package/dist/src/doctor/doctor-fallback-checks.js +130 -0
  82. package/dist/src/doctor/doctor-holds.js +13 -15
  83. package/dist/src/doctor/doctor-model-checks.js +45 -200
  84. package/dist/src/doctor/doctor-notify.js +7 -2
  85. package/dist/src/doctor/doctor-opencode-checks.js +23 -9
  86. package/dist/src/doctor/doctor-pi-checks.js +62 -0
  87. package/dist/src/doctor/doctor-principles.js +26 -0
  88. package/dist/src/doctor/doctor-project-checks.js +108 -13
  89. package/dist/src/doctor/doctor-role-notes.js +51 -0
  90. package/dist/src/doctor/doctor.js +17 -5
  91. package/dist/src/doctor/probe.js +14 -1
  92. package/dist/src/events/event-format.js +313 -157
  93. package/dist/src/events/event-labels.js +0 -1
  94. package/dist/src/events/event-read.js +13 -0
  95. package/dist/src/events/event-window.js +20 -2
  96. package/dist/src/events/notify.js +1 -1
  97. package/dist/src/failure/failure-cluster.js +4 -3
  98. package/dist/src/failure/failure-data.js +127 -90
  99. package/dist/src/failure/failure-render.js +62 -21
  100. package/dist/src/failure/failure-state-change.js +174 -8
  101. package/dist/src/failure/time-spend.js +136 -167
  102. package/dist/src/files/file-queue.js +17 -0
  103. package/dist/src/files/files.js +7 -0
  104. package/dist/src/gates/budget-gates.js +116 -324
  105. package/dist/src/gates/gate-polls.js +123 -184
  106. package/dist/src/gates/maintenance-quota.js +27 -17
  107. package/dist/src/gates/role-cap-gates.js +1 -1
  108. package/dist/src/gates/streak-gate.js +1 -1
  109. package/dist/src/git/commit-message.js +12 -0
  110. package/dist/src/git/git.js +18 -0
  111. package/dist/src/git/slot-salvage.js +4 -5
  112. package/dist/src/git/slots-state.js +12 -3
  113. package/dist/src/git/worktree-pool-startup.js +127 -0
  114. package/dist/src/git/worktree-pool.js +1 -120
  115. package/dist/src/gui/gui-admin-endpoints.js +1 -1
  116. package/dist/src/gui/gui-args.js +1 -1
  117. package/dist/src/gui/gui-backlog-commands.js +21 -12
  118. package/dist/src/gui/gui-backlog-endpoints.js +6 -5
  119. package/dist/src/gui/gui-command.js +19 -1
  120. package/dist/src/gui/gui-config-commands.js +126 -85
  121. package/dist/src/gui/gui-endpoint-commands.js +5 -3
  122. package/dist/src/gui/gui-endpoint-common.js +4 -3
  123. package/dist/src/gui/gui-history-endpoints.js +36 -27
  124. package/dist/src/gui/gui-operator-commands.js +175 -10
  125. package/dist/src/gui/gui-prompt-commands.js +16 -7
  126. package/dist/src/gui/gui-quarantine-commands.js +30 -0
  127. package/dist/src/gui/gui-report-endpoints.js +14 -4
  128. package/dist/src/gui/gui-server.js +20 -3
  129. package/dist/src/gui/gui-team-commands.js +1 -1
  130. package/dist/src/history/history-data.js +7 -1
  131. package/dist/src/history/history-queued.js +8 -0
  132. package/dist/src/history/history-render.js +15 -10
  133. package/dist/src/history/history.js +3 -6
  134. package/dist/src/inbox/inbox-top.js +4 -9
  135. package/dist/src/inbox/pending-prompt.js +3 -2
  136. package/dist/src/inbox/prompt-commands.js +189 -161
  137. package/dist/src/init/init.js +43 -17
  138. package/dist/src/merge/merge-core.js +2 -25
  139. package/dist/src/merge/merge-drain.js +23 -136
  140. package/dist/src/merge/merge-git.js +5 -5
  141. package/dist/src/merge/merge-pipeline.js +1 -1
  142. package/dist/src/merge/merge-post-review-drain.js +214 -0
  143. package/dist/src/merge/merge-queue-render.js +11 -12
  144. package/dist/src/merge/merge-queue.js +24 -2
  145. package/dist/src/merge/merge-requeue.js +1 -0
  146. package/dist/src/merge/merge-stack.js +1 -7
  147. package/dist/src/merge/merge-to-main.js +2 -10
  148. package/dist/src/merge/merge-top.js +33 -19
  149. package/dist/src/merge/merge-verify.js +65 -9
  150. package/dist/src/notes-cli.js +8 -3
  151. package/dist/src/operator/operator-commands.js +16 -5
  152. package/dist/src/operator/operator-intent.js +26 -3
  153. package/dist/src/operator/revert.js +18 -12
  154. package/dist/src/orchestrator/orchestrator-poll.js +49 -17
  155. package/dist/src/orchestrator/orchestrator-scheduling.js +4 -2
  156. package/dist/src/orchestrator/orchestrator.js +6 -5
  157. package/dist/src/orchestrator/scheduling-scope.js +51 -7
  158. package/dist/src/orchestrator/scheduling-skip.js +15 -5
  159. package/dist/src/paths.js +26 -10
  160. package/dist/src/pi/pi-backend.js +2 -2
  161. package/dist/src/pi/pi-bin.js +2 -2
  162. package/dist/src/pi/pi-models.js +9 -0
  163. package/dist/src/pi/pi-stream.js +63 -41
  164. package/dist/src/pi/pi-watchdogs.js +65 -49
  165. package/dist/src/pi-extension/full-output.js +2 -3
  166. package/dist/src/process/process.js +1 -1
  167. package/dist/src/process/run-marker.js +10 -2
  168. package/dist/src/process/supervisor.js +7 -4
  169. package/dist/src/prompt/gate-notes.js +35 -10
  170. package/dist/src/prompt/gate-prompts.js +30 -7
  171. package/dist/src/prompt/notes-backlog.js +24 -15
  172. package/dist/src/prompt/principles.js +11 -0
  173. package/dist/src/prompt/prompt.js +13 -7
  174. package/dist/src/redeploy/redeploy-probes.js +11 -1
  175. package/dist/src/redeploy/redeployer.js +54 -7
  176. package/dist/src/redeploy/self-reload.js +7 -2
  177. package/dist/src/report/report-data.js +322 -223
  178. package/dist/src/report/report-fold.js +257 -191
  179. package/dist/src/report/report-main-red.js +64 -0
  180. package/dist/src/report/report-render.js +133 -25
  181. package/dist/src/report/report.js +2 -5
  182. package/dist/src/review/diff-rules.js +53 -0
  183. package/dist/src/review/known-flakes.js +32 -1
  184. package/dist/src/review/post-merge-review-accept.js +51 -0
  185. package/dist/src/review/post-merge-review-render.js +112 -0
  186. package/dist/src/review/post-merge-review.js +159 -24
  187. package/dist/src/review/protected-edits.js +22 -7
  188. package/dist/src/review/quarantine-render.js +82 -0
  189. package/dist/src/review/review-precheck.js +2 -1
  190. package/dist/src/review/review.js +33 -49
  191. package/dist/src/roles/role-catalog.js +73 -2
  192. package/dist/src/roles/role-guidance.js +18 -0
  193. package/dist/src/roles/role-labels.js +6 -3
  194. package/dist/src/roles/role-render.js +62 -8
  195. package/dist/src/roles/role-view.js +54 -12
  196. package/dist/src/roles/roles.js +3 -23
  197. package/dist/src/run/ci-parity.js +121 -0
  198. package/dist/src/run/feedback-filings.js +10 -1
  199. package/dist/src/run/qa-coverage.js +50 -15
  200. package/dist/src/run/run-apply.js +14 -2
  201. package/dist/src/run/run-detail-data.js +36 -16
  202. package/dist/src/run/run-detail-render.js +27 -9
  203. package/dist/src/run/run-finalize.js +76 -46
  204. package/dist/src/run/run-prompt.js +231 -177
  205. package/dist/src/run/run-stage.js +168 -70
  206. package/dist/src/run/run-verdict.js +127 -13
  207. package/dist/src/run/stage-backlog-checks.js +2 -2
  208. package/dist/src/run/stage-check.js +17 -11
  209. package/dist/src/run/stage-checks-shared.js +80 -0
  210. package/dist/src/run/stage-name-checks.js +194 -0
  211. package/dist/src/run/stage-path-checks.js +35 -537
  212. package/dist/src/run/stage-prose-checks.js +261 -0
  213. package/dist/src/runner/leftover.js +61 -21
  214. package/dist/src/runner/revision.js +14 -25
  215. package/dist/src/runner/runner-fallback.js +1 -1
  216. package/dist/src/runner/runner-outcome.js +4 -2
  217. package/dist/src/runner/runner-pi.js +72 -49
  218. package/dist/src/runner/runner-recovery.js +18 -3
  219. package/dist/src/runner/runner-run.js +36 -29
  220. package/dist/src/runner/runner-state.js +4 -3
  221. package/dist/src/scheduling/claim-entries.js +49 -0
  222. package/dist/src/scheduling/claims.js +1 -1
  223. package/dist/src/status/status-data.js +144 -86
  224. package/dist/src/status/status-polls.js +56 -5
  225. package/dist/src/status/status-role-notes.js +49 -0
  226. package/dist/src/status/status-roles.js +19 -2
  227. package/dist/src/team/reclaim.js +2 -2
  228. package/dist/src/text/datetime.js +3 -2
  229. package/dist/src/text/format.js +13 -1
  230. package/dist/src/text/phrases.js +22 -5
  231. package/dist/src/text/text.js +11 -0
  232. package/dist/src/ui/alert-feeds.js +320 -0
  233. package/dist/src/ui/badges.js +35 -2
  234. package/dist/src/ui/gui/gui-client-backlog.js +25 -3
  235. package/dist/src/ui/gui/gui-client-boot.js +102 -74
  236. package/dist/src/ui/gui/gui-client-drawer-config.js +64 -17
  237. package/dist/src/ui/gui/gui-client-drawer.js +46 -5
  238. package/dist/src/ui/gui/gui-client-feed.js +4 -9
  239. package/dist/src/ui/gui/gui-client-history.js +90 -88
  240. package/dist/src/ui/gui/gui-client-labels.js +5 -1
  241. package/dist/src/ui/gui/gui-client-model.js +9 -9
  242. package/dist/src/ui/gui/gui-client-operator.js +11 -11
  243. package/dist/src/ui/gui/gui-client-pending.js +189 -12
  244. package/dist/src/ui/gui/gui-client-report-chart.js +137 -10
  245. package/dist/src/ui/gui/gui-client-report.js +81 -6
  246. package/dist/src/ui/gui/gui-client-roles.js +52 -12
  247. package/dist/src/ui/gui/gui-client-settings.js +138 -4
  248. package/dist/src/ui/gui/gui-client-team.js +13 -2
  249. package/dist/src/ui/gui/gui-client.js +44 -5
  250. package/dist/src/ui/gui/gui-page.js +1 -0
  251. package/dist/src/ui/gui/gui-styles.js +4 -0
  252. package/dist/src/ui/progress-data.js +2 -2
  253. package/dist/src/ui/run-progress-model.js +4 -3
  254. package/dist/src/ui/status-model.js +24 -14
  255. package/dist/src/ui/status-payload.js +168 -117
  256. package/dist/src/ui/status-render.js +140 -81
  257. package/dist/src/ui/team-alert-backlog-feed.js +181 -0
  258. package/dist/src/ui/team-alert-backlog.js +267 -0
  259. package/dist/src/ui/team-alert-merge.js +183 -0
  260. package/dist/src/ui/team-alert-shared.js +79 -0
  261. package/dist/src/ui/team-alert-status.js +321 -0
  262. package/dist/src/ui/team-alert-tail.js +251 -0
  263. package/dist/src/ui/team-alerts.js +31 -513
  264. package/dist/src/ui/tone.js +7 -0
  265. package/dist/src/ui/tui/tui-backlog.js +8 -6
  266. package/dist/src/ui/tui/tui-editor-attach.js +1 -7
  267. package/dist/src/ui/tui/tui-editor-backends.js +1 -6
  268. package/dist/src/ui/tui/tui-editor-brief.js +4 -24
  269. package/dist/src/ui/tui/tui-editor-budget.js +10 -12
  270. package/dist/src/ui/tui/tui-editor-check.js +29 -0
  271. package/dist/src/ui/tui/tui-editor-checks.js +28 -0
  272. package/dist/src/ui/tui/tui-editor-concurrency.js +1 -0
  273. package/dist/src/ui/tui/tui-editor-config.js +19 -6
  274. package/dist/src/ui/tui/tui-editor-ctx.js +12 -1
  275. package/dist/src/ui/tui/tui-editor-entry.js +3 -17
  276. package/dist/src/ui/tui/tui-editor-instances.js +9 -0
  277. package/dist/src/ui/tui/tui-editor-instructions.js +51 -127
  278. package/dist/src/ui/tui/tui-editor-interval.js +51 -113
  279. package/dist/src/ui/tui/tui-editor-notes.js +29 -103
  280. package/dist/src/ui/tui/tui-editor-pause.js +2 -1
  281. package/dist/src/ui/tui/tui-editor-prompt.js +2 -1
  282. package/dist/src/ui/tui/tui-editor-quiet.js +4 -13
  283. package/dist/src/ui/tui/tui-editor-release.js +77 -0
  284. package/dist/src/ui/tui/tui-editor-retire.js +1 -7
  285. package/dist/src/ui/tui/tui-editor-role-enabled.js +126 -0
  286. package/dist/src/ui/tui/tui-editor-role-file.js +75 -0
  287. package/dist/src/ui/tui/tui-editor-role-key.js +3 -7
  288. package/dist/src/ui/tui/tui-editor-session.js +44 -0
  289. package/dist/src/ui/tui/tui-editor-slots.js +1 -0
  290. package/dist/src/ui/tui/tui-editors.js +13 -1
  291. package/dist/src/ui/tui/tui-frame.js +23 -7
  292. package/dist/src/ui/tui/tui-history.js +12 -10
  293. package/dist/src/ui/tui/tui-keys.js +14 -0
  294. package/dist/src/ui/tui/tui-pane-activity.js +21 -8
  295. package/dist/src/ui/tui/tui-pane-backlog.js +36 -9
  296. package/dist/src/ui/tui/tui-pane-ctx.js +1 -1
  297. package/dist/src/ui/tui/tui-pane-health.js +153 -3
  298. package/dist/src/ui/tui/tui-pane-history.js +308 -228
  299. package/dist/src/ui/tui/tui-pane-pending.js +285 -56
  300. package/dist/src/ui/tui/tui-pane-queued.js +7 -2
  301. package/dist/src/ui/tui/tui-pane-report.js +9 -3
  302. package/dist/src/ui/tui/tui-pane-session.js +12 -0
  303. package/dist/src/ui/tui/tui-pane-transcript.js +12 -8
  304. package/dist/src/ui/tui/tui-pane.js +16 -10
  305. package/dist/src/ui/tui/tui-panes.js +247 -134
  306. package/dist/src/ui/tui/tui.js +8 -5
  307. package/dist/src/verdict/fix-claim.js +47 -1
  308. package/dist/src/verdict/refusal.js +2 -1
  309. package/dist/src/verdict/reply-contract.js +35 -0
  310. package/package.json +1 -1
  311. package/dist/src/baseline/main-culprit.js +0 -94
  312. package/dist/src/baseline/main-revert.js +0 -133
  313. package/dist/src/merge/merge-post-review.js +0 -90
  314. /package/dist/src/gui/{http-body.js → gui-http-body.js} +0 -0
  315. /package/dist/src/merge/{backlog-conflicts.js → merge-backlog-conflicts.js} +0 -0
@@ -117,14 +117,7 @@ export function opencodeTranslator(opts = {}) {
117
117
  }
118
118
  return out;
119
119
  };
120
- const translate = (line) => {
121
- const parsed = parseJsonObject(line);
122
- if (!parsed) {
123
- // A malformed / non-JSON line on stdout is skipped with one warning for the run.
124
- record("malformed");
125
- return [];
126
- }
127
- const event = parsed;
120
+ const announceSession = (event) => {
128
121
  // The first event with a non-empty `sessionID` announces the session and the agent start.
129
122
  // An error raised before a session exists has `sessionID: ""` (or none) and emits neither.
130
123
  let out = [];
@@ -140,92 +133,108 @@ export function opencodeTranslator(opts = {}) {
140
133
  out.push(JSON.stringify({ type: "agent_start" }));
141
134
  }
142
135
  }
136
+ return out;
137
+ };
138
+ const handleStepStart = () => {
139
+ step = { content: [], calls: [] };
140
+ return [];
141
+ };
142
+ const handleText = (event) => {
143
+ // A content block with no open buffer opens one: `step_start` is sometimes missing, and
144
+ // edit-run.jsonl's final `text` lands after its last `step_finish`, so a block dropped
145
+ // for want of a buffer would lose the run's last turn.
146
+ step ??= { content: [], calls: [] };
147
+ step.content.push({ type: "text", text: objectOrEmpty(event.part).text ?? "" });
148
+ return [];
149
+ };
150
+ const handleReasoning = (event) => {
151
+ step ??= { content: [], calls: [] };
152
+ const thinking = objectOrEmpty(event.part).text ?? "";
153
+ step.content.push({ type: "thinking", thinking: typeof thinking === "string" ? thinking : "" });
154
+ return [];
155
+ };
156
+ const handleToolUse = (event) => {
157
+ // As above, a tool reported with no open buffer opens one.
158
+ step ??= { content: [], calls: [] };
159
+ const partValue = objectOrEmpty(event.part);
160
+ const state = objectOrEmpty(partValue.state);
161
+ const input = objectOrEmpty(state.input);
162
+ // `arguments` is the tool's `input` plus a `path` alias of `filePath` —
163
+ // describeToolCall reads either.
164
+ const args = { ...input };
165
+ if (typeof input.filePath === "string")
166
+ args.path = input.filePath;
167
+ // V2 2.0.32 emits the native tool name in `part.tool` (not `part.name`); the live
168
+ // captures agree.
169
+ const name = typeof partValue.tool === "string" ? partValue.tool : "";
170
+ // Own-property test, not a bare index: a tool name like `constructor` or
171
+ // `__proto__` would otherwise inherit a function from the table's prototype chain and
172
+ // bypass the lower-cased fallback (the same guard claude-stream.ts applies).
173
+ const canonicalName = Object.hasOwn(TOOL_NAMES, name) ? (TOOL_NAMES[name] ?? name.toLowerCase()) : name.toLowerCase();
174
+ const id = typeof partValue.id === "string" ? partValue.id : "";
175
+ step.content.push({ type: "toolCall", id, name: canonicalName, arguments: args });
176
+ step.calls.push({ id, name: canonicalName, args, isError: state.status === "error" });
177
+ return [];
178
+ };
179
+ const handleStepFinish = (event) => {
180
+ if (!step)
181
+ return [];
182
+ const part = objectOrEmpty(event.part);
183
+ const tokens = objectOrEmpty(part.tokens);
184
+ const cache = objectOrEmpty(tokens.cache);
185
+ step.usage = canonicalUsage({
186
+ input: tokens.input,
187
+ output: tokens.output,
188
+ cache: { read: cache.read, write: cache.write },
189
+ }, nonNegativeNumber(part.cost, 0));
190
+ return flush(true);
191
+ };
192
+ const handleError = (event) => {
193
+ // Errors carry their payload in `event.error` (`{type, message, status?, response?}`,
194
+ // plan finding 8); classification reads type first, message second.
195
+ const err = objectOrEmpty(event.error);
196
+ const cls = classifyError(err);
197
+ if (cls.freeTier)
198
+ sawFreeTier = true;
199
+ const message = typeof err.message === "string" ? err.message : "";
200
+ // The open step (if any) is cut off by the error and flushed without usage first.
201
+ const out = flush(false);
202
+ const m = { role: "assistant", content: [], stopReason: "error" };
203
+ if (message !== "")
204
+ m.errorMessage = message;
205
+ // tumwaterKind/backendKind ride the canonical EVENT (not its message): the parser
206
+ // reads event.tumwaterKind and trusts it before its text regexes.
207
+ out.push(JSON.stringify({
208
+ type: "message_end",
209
+ message: m,
210
+ ...(cls.kind !== undefined ? { tumwaterKind: cls.kind } : {}),
211
+ ...(cls.backendKind !== undefined ? { backendKind: cls.backendKind } : {}),
212
+ ...(cls.retryAfterSeconds !== undefined ? { retryAfterSeconds: cls.retryAfterSeconds } : {}),
213
+ }));
214
+ return out;
215
+ };
216
+ const translate = (line) => {
217
+ const parsed = parseJsonObject(line);
218
+ if (!parsed) {
219
+ // A malformed / non-JSON line on stdout is skipped with one warning for the run.
220
+ record("malformed");
221
+ return [];
222
+ }
223
+ const event = parsed;
224
+ const out = announceSession(event);
143
225
  const type = event.type;
144
226
  switch (type) {
145
- case "step_start":
146
- step = { content: [], calls: [] };
147
- break;
148
- case "text": {
149
- // A content block with no open buffer opens one: `step_start` is sometimes missing, and
150
- // edit-run.jsonl's final `text` lands after its last `step_finish`, so a block dropped
151
- // for want of a buffer would lose the run's last turn.
152
- step ??= { content: [], calls: [] };
153
- step.content.push({ type: "text", text: objectOrEmpty(event.part).text ?? "" });
154
- break;
155
- }
156
- case "reasoning": {
157
- step ??= { content: [], calls: [] };
158
- const thinking = objectOrEmpty(event.part).text ?? "";
159
- step.content.push({ type: "thinking", thinking: typeof thinking === "string" ? thinking : "" });
160
- break;
161
- }
162
- case "tool_use": {
163
- // As above, a tool reported with no open buffer opens one.
164
- step ??= { content: [], calls: [] };
165
- const partValue = objectOrEmpty(event.part);
166
- const state = objectOrEmpty(partValue.state);
167
- const input = objectOrEmpty(state.input);
168
- // `arguments` is the tool's `input` plus a `path` alias of `filePath` —
169
- // describeToolCall reads either.
170
- const args = { ...input };
171
- if (typeof input.filePath === "string")
172
- args.path = input.filePath;
173
- // V2 2.0.32 emits the native tool name in `part.tool` (not `part.name`); the live
174
- // captures agree.
175
- const name = typeof partValue.tool === "string" ? partValue.tool : "";
176
- // Own-property test, not a bare index: a tool name like `constructor` or
177
- // `__proto__` would otherwise inherit a function from the table's prototype chain and
178
- // bypass the lower-cased fallback (the same guard claude-stream.ts applies).
179
- const canonicalName = Object.hasOwn(TOOL_NAMES, name) ? (TOOL_NAMES[name] ?? name.toLowerCase()) : name.toLowerCase();
180
- const id = typeof partValue.id === "string" ? partValue.id : "";
181
- step.content.push({ type: "toolCall", id, name: canonicalName, arguments: args });
182
- step.calls.push({ id, name: canonicalName, args, isError: state.status === "error" });
183
- break;
184
- }
185
- case "step_finish": {
186
- if (!step)
187
- break;
188
- const part = objectOrEmpty(event.part);
189
- const tokens = objectOrEmpty(part.tokens);
190
- const cache = objectOrEmpty(tokens.cache);
191
- step.usage = canonicalUsage({
192
- input: tokens.input,
193
- output: tokens.output,
194
- cache: { read: cache.read, write: cache.write },
195
- }, nonNegativeNumber(part.cost, 0));
196
- out.push(...flush(true));
197
- break;
198
- }
199
- case "error": {
200
- // Errors carry their payload in `event.error` (`{type, message, status?, response?}`,
201
- // plan finding 8); classification reads type first, message second.
202
- const err = objectOrEmpty(event.error);
203
- const cls = classifyError(err);
204
- if (cls.freeTier)
205
- sawFreeTier = true;
206
- const message = typeof err.message === "string" ? err.message : "";
207
- // The open step (if any) is cut off by the error and flushed without usage first.
208
- out.push(...flush(false));
209
- const m = { role: "assistant", content: [], stopReason: "error" };
210
- if (message !== "")
211
- m.errorMessage = message;
212
- // tumwaterKind/backendKind ride the canonical EVENT (not its message): the parser
213
- // reads event.tumwaterKind and trusts it before its text regexes.
214
- out.push(JSON.stringify({
215
- type: "message_end",
216
- message: m,
217
- ...(cls.kind !== undefined ? { tumwaterKind: cls.kind } : {}),
218
- ...(cls.backendKind !== undefined ? { backendKind: cls.backendKind } : {}),
219
- ...(cls.retryAfterSeconds !== undefined ? { retryAfterSeconds: cls.retryAfterSeconds } : {}),
220
- }));
221
- break;
222
- }
227
+ case "step_start": return [...out, ...handleStepStart()];
228
+ case "text": return [...out, ...handleText(event)];
229
+ case "reasoning": return [...out, ...handleReasoning(event)];
230
+ case "tool_use": return [...out, ...handleToolUse(event)];
231
+ case "step_finish": return [...out, ...handleStepFinish(event)];
232
+ case "error": return [...out, ...handleError(event)];
223
233
  default:
224
234
  // Record the unknown type ("" for a type-less line), once, in first-seen order.
225
235
  record(typeof type === "string" ? type : "unknown");
226
- break;
236
+ return out;
227
237
  }
228
- return out;
229
238
  };
230
239
  return {
231
240
  translate,