@fitchmultz/pi-subagents 0.44.7 → 0.46.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 (955) hide show
  1. package/CHANGELOG.md +264 -7
  2. package/LICENSE +1 -0
  3. package/README.md +58 -1483
  4. package/agents/context-builder.md +19 -1
  5. package/agents/debugger.md +10 -3
  6. package/agents/delegate.md +1 -0
  7. package/agents/fixer.md +4 -1
  8. package/agents/oracle.md +13 -2
  9. package/agents/planner.md +14 -3
  10. package/agents/researcher.md +11 -2
  11. package/agents/reviewer-claude.md +11 -2
  12. package/agents/reviewer-gpt.md +12 -2
  13. package/agents/reviewer-ponytail.md +11 -1
  14. package/agents/reviewer-security.md +13 -2
  15. package/agents/reviewer.md +12 -3
  16. package/agents/scout.md +12 -1
  17. package/agents/ui-designer.md +10 -3
  18. package/agents/watcher.md +1 -0
  19. package/agents/worker.md +8 -2
  20. package/agents/writer.md +6 -3
  21. package/dist/agents/agent-defaults.js +9 -0
  22. package/dist/agents/agent-definition.js +196 -0
  23. package/dist/agents/agent-management.js +64 -905
  24. package/dist/agents/agent-scope.js +4 -2
  25. package/dist/agents/agent-selection.js +10 -5
  26. package/dist/agents/agent-serializer.js +55 -67
  27. package/dist/agents/agents.js +75 -716
  28. package/dist/agents/builtin-overrides.js +218 -0
  29. package/dist/agents/chain-serializer.js +3 -367
  30. package/dist/agents/config-values.js +52 -0
  31. package/dist/agents/discovery-paths.js +91 -0
  32. package/dist/agents/frontmatter.js +15 -5
  33. package/dist/agents/identity.js +25 -8
  34. package/dist/agents/json-chain.js +254 -0
  35. package/dist/agents/management-config.js +332 -0
  36. package/dist/agents/management-format.js +231 -0
  37. package/dist/agents/management-persistence.js +287 -0
  38. package/dist/agents/management-targets.js +136 -0
  39. package/dist/agents/management-warnings.js +81 -0
  40. package/dist/agents/markdown-chain.js +210 -0
  41. package/dist/agents/package-agents.js +154 -0
  42. package/dist/agents/skill-files.js +157 -0
  43. package/dist/agents/skill-search-paths.js +246 -0
  44. package/dist/agents/skill-types.js +1 -0
  45. package/dist/agents/skills.js +54 -499
  46. package/dist/extension/acceptance-schema.js +55 -0
  47. package/dist/extension/build-info.js +1 -1
  48. package/dist/extension/chain-schema.js +196 -0
  49. package/dist/extension/child-runtime.js +237 -0
  50. package/dist/extension/compact-tools.js +122 -51
  51. package/dist/extension/config-schema.js +29 -0
  52. package/dist/extension/config.js +27 -11
  53. package/dist/extension/control-notice-schema.js +37 -0
  54. package/dist/extension/control-notices.js +13 -6
  55. package/dist/extension/delegation-bridges.js +43 -0
  56. package/dist/extension/doctor.js +48 -25
  57. package/dist/extension/everyday-schemas.js +207 -0
  58. package/dist/extension/fanout-child.js +18 -319
  59. package/dist/extension/index.js +8 -563
  60. package/dist/extension/message-renderers.js +225 -0
  61. package/dist/extension/nested-control-inbox.js +154 -0
  62. package/dist/extension/parent-runtime.js +339 -0
  63. package/dist/extension/primary-tool.js +69 -0
  64. package/dist/extension/result-snapshot.js +22 -0
  65. package/dist/extension/runtime-reload.js +62 -0
  66. package/dist/extension/runtime-storage.js +43 -0
  67. package/dist/extension/schema-overrides.js +75 -0
  68. package/dist/extension/schemas.js +265 -336
  69. package/dist/extension/tool-input.js +27 -12
  70. package/dist/extension/tool-result.js +19 -4
  71. package/dist/history/answer-texts.js +57 -0
  72. package/dist/history/canonical-result.js +76 -43
  73. package/dist/history/canonical-selection.js +40 -0
  74. package/dist/history/database-generation.js +82 -0
  75. package/dist/history/database.js +57 -33
  76. package/dist/history/entry-ingestion.js +61 -0
  77. package/dist/history/index.js +242 -97
  78. package/dist/history/ingest.js +168 -331
  79. package/dist/history/output-digests.js +40 -0
  80. package/dist/history/preview.js +210 -0
  81. package/dist/history/prune.js +33 -0
  82. package/dist/history/queries.js +60 -349
  83. package/dist/history/query-scope.js +190 -0
  84. package/dist/history/rows.js +77 -0
  85. package/dist/history/run-projection.js +137 -0
  86. package/dist/history/run-queries.js +153 -0
  87. package/dist/history/schema.js +31 -0
  88. package/dist/history/search-queries.js +163 -0
  89. package/dist/history/selected-record.js +108 -0
  90. package/dist/history/source-file.js +45 -0
  91. package/dist/history/source-watches.js +141 -0
  92. package/dist/history/store.js +164 -153
  93. package/dist/history/text-chunks.js +169 -0
  94. package/dist/history/text.js +35 -0
  95. package/dist/history/transcript-queries.js +177 -0
  96. package/dist/history/types.js +5 -1
  97. package/dist/history/values.js +36 -0
  98. package/dist/history/wire-inputs.js +122 -0
  99. package/dist/history/wire-models.js +38 -0
  100. package/dist/history/worker-runtime.js +441 -0
  101. package/dist/history/worker.js +66 -462
  102. package/dist/intercom/intercom-bridge.js +48 -20
  103. package/dist/intercom/live-intercom.js +80 -23
  104. package/dist/intercom/nested-result-tree.js +163 -0
  105. package/dist/intercom/result-delivery.js +40 -0
  106. package/dist/intercom/result-intercom.js +178 -261
  107. package/dist/pi-intercom/agent-dir.js +7 -3
  108. package/dist/pi-intercom/async.js +27 -0
  109. package/dist/pi-intercom/bridge-ask.js +57 -0
  110. package/dist/pi-intercom/bridge-config.js +89 -0
  111. package/dist/pi-intercom/bridge-http.js +86 -0
  112. package/dist/pi-intercom/bridge-launch-policy.js +88 -0
  113. package/dist/pi-intercom/bridge-launch.js +217 -0
  114. package/dist/pi-intercom/bridge-protocol.js +106 -0
  115. package/dist/pi-intercom/bridge-routes.js +72 -0
  116. package/dist/pi-intercom/bridge-rpc-process.js +264 -0
  117. package/dist/pi-intercom/bridge-session.js +420 -0
  118. package/dist/pi-intercom/bridge.js +221 -606
  119. package/dist/pi-intercom/broker/broker.js +236 -244
  120. package/dist/pi-intercom/broker/client.js +189 -304
  121. package/dist/pi-intercom/broker/connection.js +165 -0
  122. package/dist/pi-intercom/broker/framing.js +5 -3
  123. package/dist/pi-intercom/broker/paths.js +4 -1
  124. package/dist/pi-intercom/broker/pid.js +53 -25
  125. package/dist/pi-intercom/broker/snapshot-reader.js +78 -0
  126. package/dist/pi-intercom/broker/snapshots.js +188 -0
  127. package/dist/pi-intercom/broker/spawn.js +36 -25
  128. package/dist/pi-intercom/config.js +85 -71
  129. package/dist/pi-intercom/connection.js +297 -0
  130. package/dist/pi-intercom/identity.js +58 -0
  131. package/dist/pi-intercom/inbound-delivery.js +356 -0
  132. package/dist/pi-intercom/inbound-journal.js +303 -0
  133. package/dist/pi-intercom/inbound-record.js +113 -0
  134. package/dist/pi-intercom/inbound.js +179 -0
  135. package/dist/pi-intercom/index.js +79 -2933
  136. package/dist/pi-intercom/inspection.js +62 -0
  137. package/dist/pi-intercom/interview.js +236 -0
  138. package/dist/pi-intercom/lifecycle.js +168 -0
  139. package/dist/pi-intercom/message-format.js +69 -0
  140. package/dist/pi-intercom/outbound.js +304 -0
  141. package/dist/pi-intercom/peer-awareness.js +66 -0
  142. package/dist/pi-intercom/reply-tracker.js +62 -43
  143. package/dist/pi-intercom/reply-wait.js +201 -0
  144. package/dist/pi-intercom/runtime-types.js +3 -0
  145. package/dist/pi-intercom/session-events.js +180 -0
  146. package/dist/pi-intercom/session-targets.js +42 -34
  147. package/dist/pi-intercom/subagent-events.js +238 -0
  148. package/dist/pi-intercom/subagent-live-events.js +129 -86
  149. package/dist/pi-intercom/supervisor.js +282 -0
  150. package/dist/pi-intercom/tool-arguments.js +74 -0
  151. package/dist/pi-intercom/tool-registration.js +95 -0
  152. package/dist/pi-intercom/tool-results.js +38 -0
  153. package/dist/pi-intercom/tool-schemas.js +82 -0
  154. package/dist/pi-intercom/tools.js +51 -0
  155. package/dist/pi-intercom/topic-actions.js +177 -0
  156. package/dist/pi-intercom/topics.js +177 -92
  157. package/dist/pi-intercom/transport.js +1 -0
  158. package/dist/pi-intercom/types.js +151 -114
  159. package/dist/pi-intercom/ui/compose-paste.js +93 -0
  160. package/dist/pi-intercom/ui/compose.js +121 -143
  161. package/dist/pi-intercom/ui/inline-message.js +59 -59
  162. package/dist/pi-intercom/ui/message-renderers.js +147 -0
  163. package/dist/pi-intercom/ui/overlay.js +181 -0
  164. package/dist/pi-intercom/ui/session-format.js +124 -0
  165. package/dist/pi-intercom/ui/session-list.js +76 -43
  166. package/dist/pi-intercom/ui/tool-renderers.js +110 -0
  167. package/dist/pi-intercom/ui/topic-view.js +88 -0
  168. package/dist/pi-intercom/validation.js +59 -0
  169. package/dist/runs/background/async-chain-plan.js +265 -0
  170. package/dist/runs/background/async-control.js +134 -58
  171. package/dist/runs/background/async-execution.js +136 -633
  172. package/dist/runs/background/async-job-admission.js +40 -0
  173. package/dist/runs/background/async-job-projection.js +169 -0
  174. package/dist/runs/background/async-job-tracker.js +297 -327
  175. package/dist/runs/background/async-launch.js +216 -0
  176. package/dist/runs/background/async-plan.js +116 -0
  177. package/dist/runs/background/async-result-file.js +47 -23
  178. package/dist/runs/background/async-resume.js +195 -253
  179. package/dist/runs/background/async-run-discovery.js +213 -0
  180. package/dist/runs/background/async-run-location.js +135 -0
  181. package/dist/runs/background/async-run-record.js +1 -0
  182. package/dist/runs/background/async-run-repair.js +223 -0
  183. package/dist/runs/background/async-run-summary.js +1 -0
  184. package/dist/runs/background/async-single-plan.js +105 -0
  185. package/dist/runs/background/async-status-projection.js +155 -0
  186. package/dist/runs/background/async-status-render.js +117 -0
  187. package/dist/runs/background/async-status-validation.js +181 -0
  188. package/dist/runs/background/async-status.js +3 -442
  189. package/dist/runs/background/async-value.js +21 -0
  190. package/dist/runs/background/completion-dedupe.js +36 -12
  191. package/dist/runs/background/completion-delivery.js +211 -205
  192. package/dist/runs/background/completion-receipts.js +237 -0
  193. package/dist/runs/background/legacy-status-acceptance.js +34 -0
  194. package/dist/runs/background/notify.js +96 -48
  195. package/dist/runs/background/parallel-groups.js +36 -19
  196. package/dist/runs/background/result-payload.js +178 -0
  197. package/dist/runs/background/result-watcher.js +348 -339
  198. package/dist/runs/background/run-id-resolver.js +53 -33
  199. package/dist/runs/background/run-schemas.js +189 -0
  200. package/dist/runs/background/run-status-contracts.js +14 -0
  201. package/dist/runs/background/run-status-render.js +270 -0
  202. package/dist/runs/background/run-status.js +231 -339
  203. package/dist/runs/background/runner-attempt-output.js +155 -0
  204. package/dist/runs/background/runner-attempt.js +263 -0
  205. package/dist/runs/background/runner-child-executor.js +166 -0
  206. package/dist/runs/background/runner-child-observer.js +192 -0
  207. package/dist/runs/background/runner-completion-summary.js +71 -0
  208. package/dist/runs/background/runner-completion.js +211 -0
  209. package/dist/runs/background/runner-config.js +1 -0
  210. package/dist/runs/background/runner-contract.js +1 -0
  211. package/dist/runs/background/runner-dynamic.js +121 -0
  212. package/dist/runs/background/runner-finalization.js +149 -0
  213. package/dist/runs/background/runner-graph.js +68 -0
  214. package/dist/runs/background/runner-initial-status.js +60 -0
  215. package/dist/runs/background/runner-lifecycle.js +142 -0
  216. package/dist/runs/background/runner-monitor.js +309 -0
  217. package/dist/runs/background/runner-parallel.js +204 -0
  218. package/dist/runs/background/runner-prepare-step.js +86 -0
  219. package/dist/runs/background/runner-reporting.js +153 -0
  220. package/dist/runs/background/runner-status.js +148 -0
  221. package/dist/runs/background/runner-step-output.js +92 -0
  222. package/dist/runs/background/runner-step-record.js +45 -0
  223. package/dist/runs/background/runner-step.js +112 -0
  224. package/dist/runs/background/runner-streaming.js +173 -0
  225. package/dist/runs/background/runner-workflow.js +213 -0
  226. package/dist/runs/background/stale-run-reconciler.js +155 -292
  227. package/dist/runs/background/subagent-runner-launcher.js +33 -13
  228. package/dist/runs/background/subagent-runner.js +51 -1842
  229. package/dist/runs/background/top-level-async.js +2 -1
  230. package/dist/runs/foreground/chain-clarify.js +293 -1017
  231. package/dist/runs/foreground/clarification-draft.js +87 -0
  232. package/dist/runs/foreground/clarify-contracts.js +1 -0
  233. package/dist/runs/foreground/clarify-invocation.js +129 -38
  234. package/dist/runs/foreground/clarify-text-editor.js +210 -0
  235. package/dist/runs/foreground/clarify-view.js +167 -0
  236. package/dist/runs/foreground/execution-input.js +226 -353
  237. package/dist/runs/foreground/execution-routing.js +33 -0
  238. package/dist/runs/foreground/execution-timeout.js +81 -0
  239. package/dist/runs/foreground/foreground-control.js +222 -763
  240. package/dist/runs/foreground/foreground-memory.js +99 -0
  241. package/dist/runs/foreground/invocation-context.js +55 -0
  242. package/dist/runs/foreground/invocation-execution.js +331 -0
  243. package/dist/runs/foreground/invocation-expansion.js +48 -0
  244. package/dist/runs/foreground/management-actions.js +295 -0
  245. package/dist/runs/foreground/nested-control.js +179 -0
  246. package/dist/runs/foreground/question-continuation.js +78 -0
  247. package/dist/runs/foreground/question-control.js +155 -50
  248. package/dist/runs/foreground/resume-target.js +221 -0
  249. package/dist/runs/foreground/revival-launch-policy.js +58 -0
  250. package/dist/runs/foreground/run-async-path.js +190 -178
  251. package/dist/runs/foreground/run-interrupt.js +164 -0
  252. package/dist/runs/foreground/run-nudge.js +278 -0
  253. package/dist/runs/foreground/saved-revival.js +251 -0
  254. package/dist/runs/foreground/subagent-executor.js +135 -424
  255. package/dist/runs/foreground/subagent-params.js +67 -30
  256. package/dist/runs/foreground/wait-observation.js +104 -0
  257. package/dist/runs/foreground/wait-registration.js +17 -0
  258. package/dist/runs/foreground/wait-run.js +283 -123
  259. package/dist/runs/shared/acceptance-contract.js +193 -99
  260. package/dist/runs/shared/acceptance-defaults.js +1 -0
  261. package/dist/runs/shared/acceptance-evaluation.js +201 -181
  262. package/dist/runs/shared/acceptance-finalization.js +256 -180
  263. package/dist/runs/shared/acceptance-outcome.js +53 -0
  264. package/dist/runs/shared/acceptance-reports.js +137 -72
  265. package/dist/runs/shared/acceptance-submission.js +167 -0
  266. package/dist/runs/shared/acceptance-verification.js +100 -0
  267. package/dist/runs/shared/chain-outputs.js +80 -52
  268. package/dist/runs/shared/child-attempt-types.js +1 -0
  269. package/dist/runs/shared/child-attempt.js +314 -667
  270. package/dist/runs/shared/child-boundaries.js +173 -0
  271. package/dist/runs/shared/child-context-filter.js +44 -0
  272. package/dist/runs/shared/child-event-observer.js +390 -0
  273. package/dist/runs/shared/child-execution-cwd.js +73 -43
  274. package/dist/runs/shared/child-execution-outcome.js +72 -0
  275. package/dist/runs/shared/child-invocation.js +54 -0
  276. package/dist/runs/shared/child-message-validation.js +215 -0
  277. package/dist/runs/shared/child-native-accounting.js +106 -0
  278. package/dist/runs/shared/child-native-observation.js +69 -0
  279. package/dist/runs/shared/child-observation-spool.js +164 -0
  280. package/dist/runs/shared/child-observations.js +157 -76
  281. package/dist/runs/shared/child-presence.js +3 -0
  282. package/dist/runs/shared/child-route-env.js +119 -0
  283. package/dist/runs/shared/child-stream-observer.js +221 -0
  284. package/dist/runs/shared/child-stream-projection.js +137 -0
  285. package/dist/runs/shared/child-structured-tool.js +27 -0
  286. package/dist/runs/shared/claude-code.js +121 -158
  287. package/dist/runs/shared/claude-model.js +42 -0
  288. package/dist/runs/shared/claude-session.js +83 -0
  289. package/dist/runs/shared/claude-types.js +1 -0
  290. package/dist/runs/shared/completion-guard.js +18 -18
  291. package/dist/runs/shared/control-event-policy.js +8 -0
  292. package/dist/runs/shared/control-notification-owner.js +13 -0
  293. package/dist/runs/shared/dynamic-fanout.js +188 -173
  294. package/dist/runs/shared/dynamic-item.js +102 -0
  295. package/dist/runs/shared/history-index.js +62 -36
  296. package/dist/runs/shared/legacy-async-recovery.js +114 -0
  297. package/dist/runs/shared/legacy-output-recovery.js +148 -0
  298. package/dist/runs/shared/mcp-config-schema.js +36 -0
  299. package/dist/runs/shared/mcp-direct-tool-allowlist.js +147 -116
  300. package/dist/runs/shared/model-fallback.js +97 -38
  301. package/dist/runs/shared/mutating-tool-guard.js +128 -88
  302. package/dist/runs/shared/native-finalization-types.js +1 -0
  303. package/dist/runs/shared/native-finalization.js +155 -76
  304. package/dist/runs/shared/native-usage.js +238 -98
  305. package/dist/runs/shared/nested-control-records.js +128 -0
  306. package/dist/runs/shared/nested-events.js +8 -700
  307. package/dist/runs/shared/nested-path.js +32 -28
  308. package/dist/runs/shared/nested-projection.js +155 -0
  309. package/dist/runs/shared/nested-protocol.js +18 -0
  310. package/dist/runs/shared/nested-registry.js +191 -0
  311. package/dist/runs/shared/nested-render.js +106 -58
  312. package/dist/runs/shared/nested-route.js +220 -0
  313. package/dist/runs/shared/nested-validation.js +216 -0
  314. package/dist/runs/shared/owned-child-evidence.js +125 -0
  315. package/dist/runs/shared/owned-run-list.js +146 -0
  316. package/dist/runs/shared/owned-run-observation.js +267 -0
  317. package/dist/runs/shared/owned-run-progress.js +109 -0
  318. package/dist/runs/shared/owned-run-read-state.js +1 -0
  319. package/dist/runs/shared/owned-run-results.js +202 -0
  320. package/dist/runs/shared/owned-run-status.js +180 -0
  321. package/dist/runs/shared/owned-run-view.js +51 -0
  322. package/dist/runs/shared/owned-workflow-details.js +17 -0
  323. package/dist/runs/shared/owner-output.js +43 -0
  324. package/dist/runs/shared/parallel-utils.js +36 -28
  325. package/dist/runs/shared/parent-receipts.js +90 -32
  326. package/dist/runs/shared/parent-usage.js +169 -57
  327. package/dist/runs/shared/pi-args.js +108 -201
  328. package/dist/runs/shared/pi-launch-input.js +1 -0
  329. package/dist/runs/shared/pi-session-launch.js +86 -0
  330. package/dist/runs/shared/pi-spawn.js +35 -21
  331. package/dist/runs/shared/run-history-queries.js +126 -35
  332. package/dist/runs/shared/run-history.js +101 -35
  333. package/dist/runs/shared/run-metadata-paths.js +14 -0
  334. package/dist/runs/shared/run-metadata.js +158 -0
  335. package/dist/runs/shared/run-persistence.js +131 -0
  336. package/dist/runs/shared/run-records.js +9 -679
  337. package/dist/runs/shared/run-restoration.js +338 -0
  338. package/dist/runs/shared/run-state-owner.js +26 -0
  339. package/dist/runs/shared/session-cwd-preload.js +27 -18
  340. package/dist/runs/shared/single-output.js +148 -70
  341. package/dist/runs/shared/stable-value.js +15 -0
  342. package/dist/runs/shared/streaming-text.js +23 -12
  343. package/dist/runs/shared/structured-output.js +25 -13
  344. package/dist/runs/shared/subagent-control.js +167 -100
  345. package/dist/runs/shared/subagent-prompt-runtime.js +27 -130
  346. package/dist/runs/shared/subagent-tool-loop-guard.js +81 -52
  347. package/dist/runs/shared/supervisor-question-state.js +145 -0
  348. package/dist/runs/shared/supervisor-questions.js +185 -254
  349. package/dist/runs/shared/workflow-graph.js +259 -167
  350. package/dist/runs/shared/workflow-policy.js +120 -48
  351. package/dist/runs/shared/worktree-contract.js +1 -0
  352. package/dist/runs/shared/worktree-hook.js +138 -0
  353. package/dist/runs/shared/worktree-location.js +47 -0
  354. package/dist/runs/shared/worktree-preservation.js +8 -0
  355. package/dist/runs/shared/worktree-process.js +107 -0
  356. package/dist/runs/shared/worktree.js +183 -322
  357. package/dist/shared/agent-context-policy.js +34 -44
  358. package/dist/shared/agent-dir.js +14 -0
  359. package/dist/shared/artifacts.js +30 -12
  360. package/dist/shared/atomic-json.js +4 -1
  361. package/dist/shared/chain-files.js +72 -0
  362. package/dist/shared/concurrency.js +18 -0
  363. package/dist/shared/content-preview.js +115 -0
  364. package/dist/shared/cooperative.js +5 -2
  365. package/dist/shared/execution-cwd.js +13 -5
  366. package/dist/shared/file-coalescer.js +2 -1
  367. package/dist/shared/fork-context.js +10 -12
  368. package/dist/shared/formatters.js +45 -19
  369. package/dist/shared/journal-frames.js +164 -0
  370. package/dist/shared/journal-projections.js +121 -0
  371. package/dist/shared/journal-reader.js +6 -407
  372. package/dist/shared/json-projection.js +191 -0
  373. package/dist/shared/lazy-tools.js +19 -8
  374. package/dist/shared/message-output.js +116 -0
  375. package/dist/shared/model-info.js +31 -14
  376. package/dist/shared/native-import.js +20 -0
  377. package/dist/shared/native-journal.js +140 -0
  378. package/dist/shared/native-session-loader.js +17 -0
  379. package/dist/shared/native-session.js +2 -13
  380. package/dist/shared/native-tui.js +7 -2
  381. package/dist/shared/native-typebox.js +15 -3
  382. package/dist/shared/output-page.js +63 -0
  383. package/dist/shared/post-exit-stdio-guard.js +128 -88
  384. package/dist/shared/prompt-sections.js +2 -0
  385. package/dist/shared/session-entries.js +70 -35
  386. package/dist/shared/session-identity.js +5 -3
  387. package/dist/shared/settings.js +62 -192
  388. package/dist/shared/status-format.js +97 -37
  389. package/dist/shared/task-file-policy.js +24 -0
  390. package/dist/shared/temp-root.js +44 -15
  391. package/dist/shared/types/acceptance.js +1 -0
  392. package/dist/shared/types/async.js +1 -0
  393. package/dist/shared/types/config.js +1 -0
  394. package/dist/shared/types/details.js +1 -0
  395. package/dist/shared/types/history.js +1 -0
  396. package/dist/shared/types/inputs.js +1 -0
  397. package/dist/shared/types/intercom.js +1 -0
  398. package/dist/shared/types/launch.js +1 -0
  399. package/dist/shared/types/messages.js +1 -0
  400. package/dist/shared/types/nested.js +1 -0
  401. package/dist/shared/types/owned-runs.js +1 -0
  402. package/dist/shared/types/progress.js +1 -0
  403. package/dist/shared/types/questions.js +1 -0
  404. package/dist/shared/types/results.js +1 -0
  405. package/dist/shared/types/state.js +1 -0
  406. package/dist/shared/types/usage.js +1 -0
  407. package/dist/shared/types/workflow.js +1 -0
  408. package/dist/shared/types.js +75 -30
  409. package/dist/shared/unknown.js +52 -0
  410. package/dist/shared/utils.js +54 -260
  411. package/dist/slash/command-discovery.js +82 -0
  412. package/dist/slash/command-input.js +190 -0
  413. package/dist/slash/prompt-template-bridge.js +94 -270
  414. package/dist/slash/prompt-template-contract.js +77 -0
  415. package/dist/slash/prompt-template-results.js +125 -0
  416. package/dist/slash/request-protocol.js +68 -0
  417. package/dist/slash/result-delivery.js +237 -0
  418. package/dist/slash/saved-chain.js +78 -0
  419. package/dist/slash/slash-bridge.js +123 -89
  420. package/dist/slash/slash-commands.js +101 -572
  421. package/dist/slash/slash-live-state.js +68 -47
  422. package/dist/tui/action-hints.js +50 -22
  423. package/dist/tui/activity-lines.js +32 -0
  424. package/dist/tui/agent-browser.js +290 -0
  425. package/dist/tui/agent-controls.js +289 -0
  426. package/dist/tui/agent-conversation.js +444 -0
  427. package/dist/tui/agent-dock.js +171 -0
  428. package/dist/tui/agent-history.js +50 -183
  429. package/dist/tui/agent-model.js +62 -0
  430. package/dist/tui/agent-picker.js +262 -0
  431. package/dist/tui/agent-view.js +232 -1564
  432. package/dist/tui/compact-results.js +193 -0
  433. package/dist/tui/conversation-details.js +190 -0
  434. package/dist/tui/conversation-frame.js +135 -0
  435. package/dist/tui/conversation-history.js +201 -0
  436. package/dist/tui/conversation-menu.js +78 -0
  437. package/dist/tui/conversation-notices.js +79 -0
  438. package/dist/tui/conversation-selection.js +58 -0
  439. package/dist/tui/conversation-viewport.js +129 -0
  440. package/dist/tui/direction-message.js +27 -0
  441. package/dist/tui/display.js +282 -0
  442. package/dist/tui/editor-viewport.js +18 -0
  443. package/dist/tui/expanded-content.js +87 -0
  444. package/dist/tui/expanded-multi.js +170 -0
  445. package/dist/tui/expanded-single.js +65 -0
  446. package/dist/tui/history-cards.js +216 -0
  447. package/dist/tui/history-display.js +238 -0
  448. package/dist/tui/history-json.js +16 -0
  449. package/dist/tui/history-metadata.js +152 -0
  450. package/dist/tui/history-record.js +251 -0
  451. package/dist/tui/history-text.js +34 -0
  452. package/dist/tui/indexed-history.js +116 -0
  453. package/dist/tui/nested-widget.js +120 -0
  454. package/dist/tui/picker-page.js +59 -0
  455. package/dist/tui/render.js +58 -1501
  456. package/dist/tui/result-facts.js +64 -0
  457. package/dist/tui/task-observation.js +59 -0
  458. package/dist/tui/task-store.js +366 -0
  459. package/dist/tui/text-values.js +16 -0
  460. package/dist/tui/view-connections.js +47 -0
  461. package/dist/tui/view-model.js +94 -0
  462. package/dist/tui/view-persistence.js +51 -0
  463. package/dist/tui/view-ports.js +1 -0
  464. package/dist/tui/view-session.js +37 -0
  465. package/dist/tui/widget-details.js +144 -0
  466. package/dist/tui/widget-status.js +245 -0
  467. package/dist/tui/widget.js +145 -0
  468. package/dist/tui/workflow-labels.js +223 -0
  469. package/dist/tui/workflow-outcomes.js +124 -0
  470. package/docs/code-quality.md +38 -0
  471. package/docs/development.md +99 -0
  472. package/docs/intercom-bridge.md +77 -22
  473. package/docs/intercom.md +132 -106
  474. package/docs/performance.md +19 -17
  475. package/docs/reference.md +1472 -0
  476. package/generated/RunValidators.d.ts +28 -0
  477. package/generated/RunValidators.js +2 -0
  478. package/package.json +27 -6
  479. package/prompts/parallel-cleanup.md +3 -0
  480. package/prompts/parallel-context-build.md +3 -0
  481. package/prompts/parallel-handoff-plan.md +6 -0
  482. package/prompts/parallel-research.md +4 -0
  483. package/prompts/parallel-review.md +2 -0
  484. package/prompts/review-loop.md +2 -0
  485. package/scripts/build.mjs +129 -85
  486. package/scripts/check-compat.mjs +48 -11
  487. package/scripts/compat-host.mjs +35 -7
  488. package/scripts/generate-run-schemas.mjs +210 -0
  489. package/scripts/intercom-bridge-credentials.mjs +158 -29
  490. package/scripts/intercom-remote.mjs +213 -52
  491. package/scripts/local-install-smoke.mjs +47 -37
  492. package/scripts/native-package-smoke.mjs +135 -25
  493. package/scripts/package-smoke.mjs +360 -140
  494. package/scripts/prepare.mjs +54 -34
  495. package/scripts/real-pi-processes.mjs +261 -0
  496. package/scripts/real-pi-smoke.mjs +432 -351
  497. package/scripts/run-tests.mjs +29 -15
  498. package/skills/pi-intercom/SKILL.md +11 -11
  499. package/skills/pi-intercom/references/peer-sessions.md +7 -2
  500. package/skills/pi-subagents/SKILL.md +1 -1
  501. package/skills/pi-subagents/references/full-orchestration-guide.md +254 -112
  502. package/src/agents/agent-defaults.ts +13 -0
  503. package/src/agents/agent-definition.ts +253 -0
  504. package/src/agents/agent-management.ts +111 -808
  505. package/src/agents/agent-scope.ts +7 -3
  506. package/src/agents/agent-selection.ts +26 -16
  507. package/src/agents/agent-serializer.ts +84 -93
  508. package/src/agents/agents.ts +199 -906
  509. package/src/agents/builtin-overrides.ts +297 -0
  510. package/src/agents/chain-serializer.ts +3 -329
  511. package/src/agents/config-values.ts +57 -0
  512. package/src/agents/discovery-paths.ts +134 -0
  513. package/src/agents/frontmatter.ts +35 -17
  514. package/src/agents/identity.ts +49 -18
  515. package/src/agents/json-chain.ts +305 -0
  516. package/src/agents/management-config.ts +342 -0
  517. package/src/agents/management-format.ts +243 -0
  518. package/src/agents/management-persistence.ts +408 -0
  519. package/src/agents/management-targets.ts +260 -0
  520. package/src/agents/management-warnings.ts +115 -0
  521. package/src/agents/markdown-chain.ts +237 -0
  522. package/src/agents/package-agents.ts +231 -0
  523. package/src/agents/skill-files.ts +182 -0
  524. package/src/agents/skill-search-paths.ts +289 -0
  525. package/src/agents/skill-types.ts +31 -0
  526. package/src/agents/skills.ts +152 -610
  527. package/src/extension/acceptance-schema.ts +88 -0
  528. package/src/extension/chain-schema.ts +276 -0
  529. package/src/extension/child-runtime.ts +302 -0
  530. package/src/extension/compact-tools.ts +259 -102
  531. package/src/extension/config-schema.ts +59 -0
  532. package/src/extension/config.ts +39 -17
  533. package/src/extension/control-notice-schema.ts +55 -0
  534. package/src/extension/control-notices.ts +57 -33
  535. package/src/extension/delegation-bridges.ts +59 -0
  536. package/src/extension/doctor.ts +171 -135
  537. package/src/extension/everyday-schemas.ts +252 -0
  538. package/src/extension/fanout-child.ts +29 -308
  539. package/src/extension/index.ts +17 -642
  540. package/src/extension/message-renderers.ts +334 -0
  541. package/src/extension/nested-control-inbox.ts +196 -0
  542. package/src/extension/parent-runtime.ts +405 -0
  543. package/src/extension/primary-tool.ts +130 -0
  544. package/src/extension/result-snapshot.ts +35 -0
  545. package/src/extension/runtime-reload.ts +72 -0
  546. package/src/extension/runtime-storage.ts +49 -0
  547. package/src/extension/schema-overrides.ts +114 -0
  548. package/src/extension/schemas.ts +451 -418
  549. package/src/extension/tool-input.ts +40 -13
  550. package/src/extension/tool-result.ts +45 -14
  551. package/src/history/answer-texts.ts +74 -0
  552. package/src/history/canonical-result.ts +127 -51
  553. package/src/history/canonical-selection.ts +54 -0
  554. package/src/history/database-generation.ts +86 -0
  555. package/src/history/database.ts +86 -48
  556. package/src/history/entry-ingestion.ts +129 -0
  557. package/src/history/index.ts +426 -148
  558. package/src/history/ingest.ts +372 -342
  559. package/src/history/output-digests.ts +41 -0
  560. package/src/history/preview.ts +235 -0
  561. package/src/history/prune.ts +48 -0
  562. package/src/history/queries.ts +122 -256
  563. package/src/history/query-scope.ts +278 -0
  564. package/src/history/rows.ts +118 -0
  565. package/src/history/run-projection.ts +164 -0
  566. package/src/history/run-queries.ts +199 -0
  567. package/src/history/schema.ts +34 -0
  568. package/src/history/search-queries.ts +216 -0
  569. package/src/history/selected-record.ts +140 -0
  570. package/src/history/source-file.ts +51 -0
  571. package/src/history/source-watches.ts +156 -0
  572. package/src/history/store.ts +310 -197
  573. package/src/history/text-chunks.ts +181 -0
  574. package/src/history/text.ts +43 -0
  575. package/src/history/transcript-queries.ts +251 -0
  576. package/src/history/types.ts +27 -164
  577. package/src/history/values.ts +36 -0
  578. package/src/history/wire-inputs.ts +141 -0
  579. package/src/history/wire-models.ts +51 -0
  580. package/src/history/worker-runtime.ts +502 -0
  581. package/src/history/worker.ts +94 -336
  582. package/src/intercom/intercom-bridge.ts +136 -69
  583. package/src/intercom/live-intercom.ts +197 -92
  584. package/src/intercom/nested-result-tree.ts +213 -0
  585. package/src/intercom/result-delivery.ts +56 -0
  586. package/src/intercom/result-intercom.ts +364 -382
  587. package/src/pi-intercom/agent-dir.ts +9 -3
  588. package/src/pi-intercom/async.ts +33 -0
  589. package/src/pi-intercom/bridge-ask.ts +64 -0
  590. package/src/pi-intercom/bridge-config.ts +120 -0
  591. package/src/pi-intercom/bridge-http.ts +97 -0
  592. package/src/pi-intercom/bridge-launch-policy.ts +109 -0
  593. package/src/pi-intercom/bridge-launch.ts +317 -0
  594. package/src/pi-intercom/bridge-protocol.ts +123 -0
  595. package/src/pi-intercom/bridge-routes.ts +105 -0
  596. package/src/pi-intercom/bridge-rpc-process.ts +293 -0
  597. package/src/pi-intercom/bridge-session.ts +510 -0
  598. package/src/pi-intercom/bridge.ts +305 -549
  599. package/src/pi-intercom/broker/broker.ts +326 -263
  600. package/src/pi-intercom/broker/client.ts +273 -354
  601. package/src/pi-intercom/broker/connection.ts +192 -0
  602. package/src/pi-intercom/broker/framing.ts +11 -6
  603. package/src/pi-intercom/broker/paths.ts +28 -25
  604. package/src/pi-intercom/broker/pid.ts +68 -24
  605. package/src/pi-intercom/broker/snapshot-reader.ts +91 -0
  606. package/src/pi-intercom/broker/snapshots.ts +241 -0
  607. package/src/pi-intercom/broker/spawn.ts +58 -34
  608. package/src/pi-intercom/config.ts +113 -108
  609. package/src/pi-intercom/connection.ts +346 -0
  610. package/src/pi-intercom/identity.ts +71 -0
  611. package/src/pi-intercom/inbound-delivery.ts +450 -0
  612. package/src/pi-intercom/inbound-journal.ts +350 -0
  613. package/src/pi-intercom/inbound-record.ts +141 -0
  614. package/src/pi-intercom/inbound.ts +237 -0
  615. package/src/pi-intercom/index.ts +86 -2923
  616. package/src/pi-intercom/inspection.ts +82 -0
  617. package/src/pi-intercom/interview.ts +295 -0
  618. package/src/pi-intercom/lifecycle.ts +183 -0
  619. package/src/pi-intercom/message-format.ts +77 -0
  620. package/src/pi-intercom/outbound.ts +418 -0
  621. package/src/pi-intercom/peer-awareness.ts +84 -0
  622. package/src/pi-intercom/reply-tracker.ts +121 -59
  623. package/src/pi-intercom/reply-wait.ts +247 -0
  624. package/src/pi-intercom/runtime-types.ts +97 -0
  625. package/src/pi-intercom/session-events.ts +247 -0
  626. package/src/pi-intercom/session-targets.ts +124 -72
  627. package/src/pi-intercom/subagent-events.ts +299 -0
  628. package/src/pi-intercom/subagent-live-events.ts +212 -109
  629. package/src/pi-intercom/supervisor.ts +362 -0
  630. package/src/pi-intercom/tool-arguments.ts +120 -0
  631. package/src/pi-intercom/tool-registration.ts +121 -0
  632. package/src/pi-intercom/tool-results.ts +54 -0
  633. package/src/pi-intercom/tool-schemas.ts +134 -0
  634. package/src/pi-intercom/tools.ts +80 -0
  635. package/src/pi-intercom/topic-actions.ts +243 -0
  636. package/src/pi-intercom/topics.ts +267 -121
  637. package/src/pi-intercom/transport.ts +14 -0
  638. package/src/pi-intercom/types.ts +288 -190
  639. package/src/pi-intercom/ui/compose-paste.ts +109 -0
  640. package/src/pi-intercom/ui/compose.ts +173 -157
  641. package/src/pi-intercom/ui/inline-message.ts +80 -62
  642. package/src/pi-intercom/ui/message-renderers.ts +182 -0
  643. package/src/pi-intercom/ui/overlay.ts +238 -0
  644. package/src/pi-intercom/ui/session-format.ts +146 -0
  645. package/src/pi-intercom/ui/session-list.ts +145 -62
  646. package/src/pi-intercom/ui/tool-renderers.ts +148 -0
  647. package/src/pi-intercom/ui/topic-view.ts +107 -0
  648. package/src/pi-intercom/validation.ts +69 -0
  649. package/src/runs/background/async-chain-plan.ts +451 -0
  650. package/src/runs/background/async-control.ts +201 -71
  651. package/src/runs/background/async-execution.ts +206 -829
  652. package/src/runs/background/async-job-admission.ts +54 -0
  653. package/src/runs/background/async-job-projection.ts +225 -0
  654. package/src/runs/background/async-job-tracker.ts +416 -360
  655. package/src/runs/background/async-launch.ts +319 -0
  656. package/src/runs/background/async-plan.ts +285 -0
  657. package/src/runs/background/async-result-file.ts +79 -37
  658. package/src/runs/background/async-resume.ts +338 -285
  659. package/src/runs/background/async-run-discovery.ts +270 -0
  660. package/src/runs/background/async-run-location.ts +194 -0
  661. package/src/runs/background/async-run-record.ts +14 -0
  662. package/src/runs/background/async-run-repair.ts +307 -0
  663. package/src/runs/background/async-run-summary.ts +71 -0
  664. package/src/runs/background/async-single-plan.ts +168 -0
  665. package/src/runs/background/async-status-projection.ts +188 -0
  666. package/src/runs/background/async-status-render.ts +164 -0
  667. package/src/runs/background/async-status-validation.ts +238 -0
  668. package/src/runs/background/async-status.ts +9 -481
  669. package/src/runs/background/async-value.ts +29 -0
  670. package/src/runs/background/completion-dedupe.ts +103 -54
  671. package/src/runs/background/completion-delivery.ts +313 -187
  672. package/src/runs/background/completion-receipts.ts +309 -0
  673. package/src/runs/background/legacy-status-acceptance.ts +38 -0
  674. package/src/runs/background/notify.ts +167 -106
  675. package/src/runs/background/parallel-groups.ts +95 -46
  676. package/src/runs/background/result-payload.ts +268 -0
  677. package/src/runs/background/result-watcher.ts +484 -387
  678. package/src/runs/background/run-id-resolver.ts +126 -57
  679. package/src/runs/background/run-schemas.ts +240 -0
  680. package/src/runs/background/run-status-contracts.ts +46 -0
  681. package/src/runs/background/run-status-render.ts +364 -0
  682. package/src/runs/background/run-status.ts +338 -356
  683. package/src/runs/background/runner-attempt-output.ts +281 -0
  684. package/src/runs/background/runner-attempt.ts +354 -0
  685. package/src/runs/background/runner-child-executor.ts +232 -0
  686. package/src/runs/background/runner-child-observer.ts +270 -0
  687. package/src/runs/background/runner-completion-summary.ts +106 -0
  688. package/src/runs/background/runner-completion.ts +274 -0
  689. package/src/runs/background/runner-config.ts +52 -0
  690. package/src/runs/background/runner-contract.ts +51 -0
  691. package/src/runs/background/runner-dynamic.ts +185 -0
  692. package/src/runs/background/runner-finalization.ts +203 -0
  693. package/src/runs/background/runner-graph.ts +91 -0
  694. package/src/runs/background/runner-initial-status.ts +72 -0
  695. package/src/runs/background/runner-lifecycle.ts +159 -0
  696. package/src/runs/background/runner-monitor.ts +399 -0
  697. package/src/runs/background/runner-parallel.ts +280 -0
  698. package/src/runs/background/runner-prepare-step.ts +128 -0
  699. package/src/runs/background/runner-reporting.ts +192 -0
  700. package/src/runs/background/runner-status.ts +220 -0
  701. package/src/runs/background/runner-step-output.ts +158 -0
  702. package/src/runs/background/runner-step-record.ts +76 -0
  703. package/src/runs/background/runner-step.ts +150 -0
  704. package/src/runs/background/runner-streaming.ts +220 -0
  705. package/src/runs/background/runner-workflow.ts +284 -0
  706. package/src/runs/background/stale-run-reconciler.ts +279 -336
  707. package/src/runs/background/subagent-runner-launcher.ts +67 -35
  708. package/src/runs/background/subagent-runner.ts +80 -2048
  709. package/src/runs/background/top-level-async.ts +9 -7
  710. package/src/runs/foreground/chain-clarify.ts +499 -1334
  711. package/src/runs/foreground/clarification-draft.ts +92 -0
  712. package/src/runs/foreground/clarify-contracts.ts +33 -0
  713. package/src/runs/foreground/clarify-invocation.ts +192 -65
  714. package/src/runs/foreground/clarify-text-editor.ts +229 -0
  715. package/src/runs/foreground/clarify-view.ts +222 -0
  716. package/src/runs/foreground/execution-input.ts +358 -424
  717. package/src/runs/foreground/execution-routing.ts +41 -0
  718. package/src/runs/foreground/execution-timeout.ts +92 -0
  719. package/src/runs/foreground/foreground-control.ts +333 -812
  720. package/src/runs/foreground/foreground-memory.ts +132 -0
  721. package/src/runs/foreground/invocation-context.ts +88 -0
  722. package/src/runs/foreground/invocation-execution.ts +465 -0
  723. package/src/runs/foreground/invocation-expansion.ts +58 -0
  724. package/src/runs/foreground/management-actions.ts +360 -0
  725. package/src/runs/foreground/nested-control.ts +248 -0
  726. package/src/runs/foreground/question-continuation.ts +112 -0
  727. package/src/runs/foreground/question-control.ts +297 -70
  728. package/src/runs/foreground/resume-target.ts +330 -0
  729. package/src/runs/foreground/revival-launch-policy.ts +112 -0
  730. package/src/runs/foreground/run-async-path.ts +307 -223
  731. package/src/runs/foreground/run-interrupt.ts +202 -0
  732. package/src/runs/foreground/run-nudge.ts +355 -0
  733. package/src/runs/foreground/saved-revival.ts +356 -0
  734. package/src/runs/foreground/subagent-executor.ts +195 -493
  735. package/src/runs/foreground/subagent-params.ts +314 -242
  736. package/src/runs/foreground/wait-observation.ts +160 -0
  737. package/src/runs/foreground/wait-registration.ts +18 -0
  738. package/src/runs/foreground/wait-run.ts +361 -119
  739. package/src/runs/shared/acceptance-contract.ts +410 -209
  740. package/src/runs/shared/acceptance-defaults.ts +1 -0
  741. package/src/runs/shared/acceptance-evaluation.ts +314 -240
  742. package/src/runs/shared/acceptance-finalization.ts +447 -305
  743. package/src/runs/shared/acceptance-outcome.ts +69 -0
  744. package/src/runs/shared/acceptance-reports.ts +220 -126
  745. package/src/runs/shared/acceptance-submission.ts +251 -0
  746. package/src/runs/shared/acceptance-verification.ts +118 -0
  747. package/src/runs/shared/acceptance.ts +25 -25
  748. package/src/runs/shared/chain-outputs.ts +190 -98
  749. package/src/runs/shared/child-attempt-types.ts +118 -0
  750. package/src/runs/shared/child-attempt.ts +372 -608
  751. package/src/runs/shared/child-boundaries.ts +217 -0
  752. package/src/runs/shared/child-context-filter.ts +53 -0
  753. package/src/runs/shared/child-event-observer.ts +496 -0
  754. package/src/runs/shared/child-execution-cwd.ts +139 -68
  755. package/src/runs/shared/child-execution-outcome.ts +103 -0
  756. package/src/runs/shared/child-invocation.ts +74 -0
  757. package/src/runs/shared/child-message-validation.ts +233 -0
  758. package/src/runs/shared/child-native-accounting.ts +154 -0
  759. package/src/runs/shared/child-native-observation.ts +79 -0
  760. package/src/runs/shared/child-observation-spool.ts +188 -0
  761. package/src/runs/shared/child-observations.ts +219 -89
  762. package/src/runs/shared/child-presence.ts +6 -0
  763. package/src/runs/shared/child-route-env.ts +142 -0
  764. package/src/runs/shared/child-stream-observer.ts +302 -0
  765. package/src/runs/shared/child-stream-projection.ts +160 -0
  766. package/src/runs/shared/child-structured-tool.ts +38 -0
  767. package/src/runs/shared/claude-code.ts +201 -228
  768. package/src/runs/shared/claude-model.ts +67 -0
  769. package/src/runs/shared/claude-session.ts +124 -0
  770. package/src/runs/shared/claude-types.ts +31 -0
  771. package/src/runs/shared/completion-guard.ts +35 -26
  772. package/src/runs/shared/control-event-policy.ts +15 -0
  773. package/src/runs/shared/control-notification-owner.ts +20 -0
  774. package/src/runs/shared/dynamic-fanout.ts +402 -238
  775. package/src/runs/shared/dynamic-item.ts +114 -0
  776. package/src/runs/shared/history-index.ts +112 -51
  777. package/src/runs/shared/legacy-async-recovery.ts +153 -0
  778. package/src/runs/shared/legacy-output-recovery.ts +214 -0
  779. package/src/runs/shared/mcp-config-schema.ts +46 -0
  780. package/src/runs/shared/mcp-direct-tool-allowlist.ts +396 -307
  781. package/src/runs/shared/model-fallback.ts +302 -180
  782. package/src/runs/shared/mutating-tool-guard.ts +259 -158
  783. package/src/runs/shared/native-finalization-types.ts +29 -0
  784. package/src/runs/shared/native-finalization.ts +233 -109
  785. package/src/runs/shared/native-usage.ts +379 -96
  786. package/src/runs/shared/nested-control-records.ts +178 -0
  787. package/src/runs/shared/nested-events.ts +45 -752
  788. package/src/runs/shared/nested-path.ts +47 -34
  789. package/src/runs/shared/nested-projection.ts +230 -0
  790. package/src/runs/shared/nested-protocol.ts +67 -0
  791. package/src/runs/shared/nested-registry.ts +273 -0
  792. package/src/runs/shared/nested-render.ts +198 -100
  793. package/src/runs/shared/nested-route.ts +292 -0
  794. package/src/runs/shared/nested-validation.ts +291 -0
  795. package/src/runs/shared/owned-child-evidence.ts +184 -0
  796. package/src/runs/shared/owned-run-list.ts +187 -0
  797. package/src/runs/shared/owned-run-observation.ts +368 -0
  798. package/src/runs/shared/owned-run-progress.ts +172 -0
  799. package/src/runs/shared/owned-run-read-state.ts +7 -0
  800. package/src/runs/shared/owned-run-results.ts +289 -0
  801. package/src/runs/shared/owned-run-status.ts +239 -0
  802. package/src/runs/shared/owned-run-view.ts +65 -0
  803. package/src/runs/shared/owned-workflow-details.ts +24 -0
  804. package/src/runs/shared/owner-output.ts +73 -0
  805. package/src/runs/shared/parallel-utils.ts +93 -129
  806. package/src/runs/shared/parent-receipts.ts +177 -50
  807. package/src/runs/shared/parent-usage.ts +314 -91
  808. package/src/runs/shared/pi-args.ts +241 -311
  809. package/src/runs/shared/pi-launch-input.ts +48 -0
  810. package/src/runs/shared/pi-session-launch.ts +94 -0
  811. package/src/runs/shared/pi-spawn.ts +57 -33
  812. package/src/runs/shared/run-history-queries.ts +189 -38
  813. package/src/runs/shared/run-history.ts +197 -76
  814. package/src/runs/shared/run-id-ambiguity.ts +7 -3
  815. package/src/runs/shared/run-metadata-paths.ts +17 -0
  816. package/src/runs/shared/run-metadata.ts +240 -0
  817. package/src/runs/shared/run-persistence.ts +181 -0
  818. package/src/runs/shared/run-records.ts +19 -607
  819. package/src/runs/shared/run-restoration.ts +455 -0
  820. package/src/runs/shared/run-state-owner.ts +31 -0
  821. package/src/runs/shared/session-cwd-preload.ts +39 -19
  822. package/src/runs/shared/single-output.ts +358 -205
  823. package/src/runs/shared/stable-value.ts +15 -0
  824. package/src/runs/shared/streaming-text.ts +39 -12
  825. package/src/runs/shared/structured-output.ts +76 -46
  826. package/src/runs/shared/subagent-control.ts +330 -197
  827. package/src/runs/shared/subagent-prompt-runtime.ts +92 -174
  828. package/src/runs/shared/subagent-tool-loop-guard.ts +118 -68
  829. package/src/runs/shared/supervisor-question-state.ts +221 -0
  830. package/src/runs/shared/supervisor-questions.ts +396 -401
  831. package/src/runs/shared/workflow-graph.ts +400 -198
  832. package/src/runs/shared/workflow-policy.ts +245 -110
  833. package/src/runs/shared/worktree-contract.ts +29 -0
  834. package/src/runs/shared/worktree-hook.ts +181 -0
  835. package/src/runs/shared/worktree-location.ts +61 -0
  836. package/src/runs/shared/worktree-preservation.ts +10 -0
  837. package/src/runs/shared/worktree-process.ts +132 -0
  838. package/src/runs/shared/worktree.ts +459 -587
  839. package/src/shared/agent-context-policy.ts +176 -145
  840. package/src/shared/agent-dir.ts +15 -0
  841. package/src/shared/artifacts.ts +99 -68
  842. package/src/shared/atomic-json.ts +14 -11
  843. package/src/shared/chain-files.ts +72 -0
  844. package/src/shared/concurrency.ts +27 -0
  845. package/src/shared/content-preview.ts +117 -0
  846. package/src/shared/cooperative.ts +17 -13
  847. package/src/shared/execution-cwd.ts +34 -9
  848. package/src/shared/file-coalescer.ts +24 -22
  849. package/src/shared/fork-context.ts +52 -48
  850. package/src/shared/formatters.ts +88 -47
  851. package/src/shared/journal-frames.ts +197 -0
  852. package/src/shared/journal-projections.ts +133 -0
  853. package/src/shared/journal-reader.ts +18 -333
  854. package/src/shared/json-projection.ts +224 -0
  855. package/src/shared/lazy-tools.ts +76 -27
  856. package/src/shared/message-output.ts +146 -0
  857. package/src/shared/model-info.ts +94 -58
  858. package/src/shared/native-import.ts +25 -0
  859. package/src/shared/native-journal.ts +172 -0
  860. package/src/shared/native-session-loader.ts +13 -0
  861. package/src/shared/native-session.ts +3 -5
  862. package/src/shared/native-tui.ts +13 -3
  863. package/src/shared/native-typebox.ts +18 -3
  864. package/src/shared/output-page.ts +76 -0
  865. package/src/shared/post-exit-stdio-guard.ts +232 -172
  866. package/src/shared/prompt-sections.ts +13 -7
  867. package/src/shared/session-entries.ts +103 -44
  868. package/src/shared/session-identity.ts +17 -10
  869. package/src/shared/settings.ts +182 -367
  870. package/src/shared/status-format.ts +207 -98
  871. package/src/shared/stream-json.d.ts +10 -0
  872. package/src/shared/task-file-policy.ts +35 -0
  873. package/src/shared/temp-root.ts +122 -71
  874. package/src/shared/types/acceptance.ts +149 -0
  875. package/src/shared/types/async.ts +247 -0
  876. package/src/shared/types/config.ts +139 -0
  877. package/src/shared/types/details.ts +104 -0
  878. package/src/shared/types/history.ts +217 -0
  879. package/src/shared/types/inputs.ts +4 -0
  880. package/src/shared/types/intercom.ts +57 -0
  881. package/src/shared/types/launch.ts +39 -0
  882. package/src/shared/types/messages.ts +104 -0
  883. package/src/shared/types/nested.ts +153 -0
  884. package/src/shared/types/owned-runs.ts +148 -0
  885. package/src/shared/types/progress.ts +106 -0
  886. package/src/shared/types/questions.ts +103 -0
  887. package/src/shared/types/results.ts +119 -0
  888. package/src/shared/types/state.ts +56 -0
  889. package/src/shared/types/usage.ts +36 -0
  890. package/src/shared/types/workflow.ts +187 -0
  891. package/src/shared/types.ts +222 -1161
  892. package/src/shared/ui-mode.ts +1 -1
  893. package/src/shared/unknown.ts +59 -0
  894. package/src/shared/utils.ts +111 -305
  895. package/src/slash/command-discovery.ts +109 -0
  896. package/src/slash/command-input.ts +232 -0
  897. package/src/slash/prompt-template-bridge.ts +153 -400
  898. package/src/slash/prompt-template-contract.ts +152 -0
  899. package/src/slash/prompt-template-results.ts +189 -0
  900. package/src/slash/request-protocol.ts +87 -0
  901. package/src/slash/result-delivery.ts +312 -0
  902. package/src/slash/saved-chain.ts +115 -0
  903. package/src/slash/slash-bridge.ts +202 -156
  904. package/src/slash/slash-commands.ts +176 -598
  905. package/src/slash/slash-live-state.ts +287 -229
  906. package/src/tui/action-hints.ts +147 -61
  907. package/src/tui/activity-lines.ts +40 -0
  908. package/src/tui/agent-browser.ts +354 -0
  909. package/src/tui/agent-controls.ts +355 -0
  910. package/src/tui/agent-conversation.ts +514 -0
  911. package/src/tui/agent-dock.ts +250 -0
  912. package/src/tui/agent-history.ts +78 -203
  913. package/src/tui/agent-model.ts +78 -0
  914. package/src/tui/agent-picker.ts +325 -0
  915. package/src/tui/agent-view.ts +391 -1333
  916. package/src/tui/compact-results.ts +342 -0
  917. package/src/tui/conversation-details.ts +206 -0
  918. package/src/tui/conversation-frame.ts +184 -0
  919. package/src/tui/conversation-history.ts +246 -0
  920. package/src/tui/conversation-menu.ts +119 -0
  921. package/src/tui/conversation-notices.ts +116 -0
  922. package/src/tui/conversation-selection.ts +66 -0
  923. package/src/tui/conversation-viewport.ts +169 -0
  924. package/src/tui/direction-message.ts +35 -0
  925. package/src/tui/display.ts +409 -0
  926. package/src/tui/editor-viewport.ts +19 -0
  927. package/src/tui/expanded-content.ts +134 -0
  928. package/src/tui/expanded-multi.ts +264 -0
  929. package/src/tui/expanded-single.ts +92 -0
  930. package/src/tui/history-cards.ts +316 -0
  931. package/src/tui/history-display.ts +334 -0
  932. package/src/tui/history-json.ts +17 -0
  933. package/src/tui/history-metadata.ts +177 -0
  934. package/src/tui/history-record.ts +321 -0
  935. package/src/tui/history-text.ts +34 -0
  936. package/src/tui/indexed-history.ts +149 -0
  937. package/src/tui/nested-widget.ts +192 -0
  938. package/src/tui/picker-page.ts +80 -0
  939. package/src/tui/render.ts +100 -1546
  940. package/src/tui/result-facts.ts +99 -0
  941. package/src/tui/task-observation.ts +96 -0
  942. package/src/tui/task-store.ts +432 -0
  943. package/src/tui/text-values.ts +20 -0
  944. package/src/tui/view-connections.ts +64 -0
  945. package/src/tui/view-model.ts +181 -0
  946. package/src/tui/view-persistence.ts +57 -0
  947. package/src/tui/view-ports.ts +55 -0
  948. package/src/tui/view-session.ts +42 -0
  949. package/src/tui/widget-details.ts +220 -0
  950. package/src/tui/widget-status.ts +331 -0
  951. package/src/tui/widget.ts +208 -0
  952. package/src/tui/workflow-labels.ts +340 -0
  953. package/src/tui/workflow-outcomes.ts +150 -0
  954. package/tsconfig.build.json +11 -10
  955. package/tsconfig.json +30 -17
@@ -1,349 +1,379 @@
1
1
  import * as fs from "node:fs";
2
2
  import { createHash, type Hash } from "node:crypto";
3
- import { JournalFrames, type Projection } from "../shared/journal-reader.ts";
3
+ import { JournalFrames } from "../shared/journal-reader.ts";
4
4
  import { HistoryIndexError } from "./types.ts";
5
- import { exactTextDigest, HistoryStore, safeText, type SourceRow } from "./store.ts";
6
- import { stripTerminalSequences } from "../shared/native-tui.ts";
7
- import { stripAcceptanceReport } from "../runs/shared/acceptance-reports.ts";
8
-
9
- export function identity(stat: fs.BigIntStats): string { return `${stat.dev}:${stat.ino}`; }
10
- export function stamp(stat: fs.BigIntStats): string { return `${identity(stat)}:${stat.size}:${stat.mtimeNs}:${stat.ctimeNs}`; }
11
- const metadata = new Set(["type", "id", "parentId", "timestamp", "version", "cwd", "provider", "model", "modelId", "thinkingLevel", "customType", "display", "summary", "content"]);
12
- const messageFields = new Set(["role", "content", "output", "summary", "toolCallId", "toolName", "isError", "timestamp", "model", "provider", "stopReason", "errorMessage", "customType", "display", "command", "exitCode", "cancelled"]);
13
- export const previewLimits = { depth: 64, nodes: 16_384, arrayLength: 4096, keyLength: 512 };
14
- export const previewProjection: Projection = (keys, root) => {
15
- if (!keys.length) return true;
16
- if (keys[0] === "message") {
17
- if (keys.length === 1) return true;
18
- if (!messageFields.has(String(keys[1]))) return false;
19
- if (keys[1] === "content") {
20
- if (keys.length <= 3) return 512;
21
- if (keys[3] === "arguments") {
22
- if (keys.length === 4) return true;
23
- if (keys.length === 5) return Object.keys(root?.message?.content?.[Number(keys[2])]?.arguments ?? {}).length < 32 ? 512 : false;
24
- return keys.length === 6 && keys[5] === 0 ? 512 : false;
25
- }
26
- return keys.length === 4 && ["type", "text", "thinking", "id", "name", "mimeType"].includes(String(keys[3])) ? 512 : false;
27
- }
28
- return keys.length === 2 ? 512 : false;
29
- }
30
- if (keys[0] === "details") return keys.length === 1 || keys.length === 2 && ["bodyText", "message"].includes(String(keys[1])) || keys.length === 3 && keys[1] === "message" && keys[2] === "id" ? 512 : false;
31
- if (keys[0] === "content" && keys.length > 1) return keys.length <= 2 || keys.length === 3 && ["type", "text", "mimeType"].includes(String(keys[2])) ? 512 : false;
32
- return keys.length === 1 && metadata.has(String(keys[0])) ? 512 : false;
33
- };
34
- function candidate(keys: readonly (string | number)[]): boolean {
35
- return ["summary", "content"].includes(String(keys[0])) && keys.length === 1
36
- || keys.length === 2 && keys[0] === "details" && keys[1] === "bodyText"
37
- || keys[0] === "message" && keys.length === 2 && ["content", "output", "summary"].includes(String(keys[1]))
38
- || keys[0] === "message" && keys[1] === "content" && keys.length === 4 && keys[3] === "text"
39
- || keys[0] === "content" && keys.length === 3 && keys[2] === "text";
40
- }
41
- function allowed(value: any, field: string): boolean {
42
- const keys = JSON.parse(field) as (string | number)[];
43
- if (value.type === "custom_message") {
44
- if (value.display === false) return false;
45
- if (keys[0] === "details") return value.customType === "subagent-human-message";
46
- if (value.customType === "subagent-human-message" && typeof value.details?.bodyText === "string") return false;
47
- return keys[0] === "content" && (keys.length === 1 || value.content?.[Number(keys[1])]?.type === "text");
48
- }
49
- if (["compaction", "branch_summary"].includes(value.type)) return keys.length === 1 && keys[0] === "summary";
50
- if (value.type !== "message" || keys[0] !== "message") return false;
51
- const message = value.message;
52
- if (!message) return false;
53
- if (["compactionSummary", "branchSummary"].includes(message.role)) return keys[1] === "summary";
54
- if (message.role === "bashExecution") return keys[1] === "output";
55
- if (!["user", "assistant", "toolResult", "custom"].includes(message.role) || message.role === "custom" && message.display === false) return false;
56
- return keys[1] === "content" && (keys.length === 2 || message.content?.[Number(keys[2])]?.type === "text");
57
- }
58
- export function compactEntry(value: any): Record<string, any> {
59
- let remaining = 4096;
60
- const clean = (input: any, key?: string): any => {
61
- if (typeof input === "string") { const text = safeText(input, ["id", "parentId", "type", "role", "toolCallId", "name", "toolName", "timestamp"].includes(key ?? "") ? 512 : Math.min(512, remaining)); remaining -= Math.min(remaining, text.length); return text; }
62
- if (Array.isArray(input)) return input.slice(0, 32).map((item) => clean(item));
63
- if (input && typeof input === "object") return Object.fromEntries(Object.entries(input).map(([name, item]) => [name, clean(item, name)]));
64
- return input;
65
- };
66
- return clean(value);
67
- }
68
- /** Exact matches never use previews. Oversized selected text has no fingerprint. */
69
- class AnswerTexts {
70
- private fields = new Map<number, string>();
71
- private length = 0;
72
- private unavailable = false;
73
- write(keys: readonly (string | number)[], text: string): void {
74
- if (this.unavailable || keys.length !== 4 || keys[0] !== "message" || keys[1] !== "content" || !["text", "thinking"].includes(String(keys[3]))) return;
75
- this.length += text.length;
76
- if (this.length > 16 * 1024 * 1024 || Number(keys[2]) >= 4096) { this.unavailable = true; this.fields.clear(); return; }
77
- const index = Number(keys[2]);
78
- this.fields.set(index, (this.fields.get(index) ?? "") + text);
79
- }
80
- fingerprints(value: any, id: string): Array<[string, string]> {
81
- if (this.unavailable || value.type !== "message" || value.message?.role !== "assistant") return [];
82
- const content = Array.isArray(value.message.content) ? value.message.content : [];
83
- const first = content.findIndex((part: any, index: number) => ["text", "thinking"].includes(part.type) && Boolean(this.fields.get(index)));
84
- if (first < 0 || !content.some((part: any, index: number) => part.type === "text" && Boolean(this.fields.get(index)))) return [];
85
- const item = `${id}:${first}`, parts = content.map((part: any, index: number) => ["text", "thinking"].includes(part.type) ? stripTerminalSequences(this.fields.get(index) ?? "") : part.type === "image" ? `[Image: ${part.mimeType ?? "image"}]` : "").filter(Boolean);
86
- const texts = [parts.join("\n"), ...content.flatMap((part: any, index: number) => part.type === "text" ? [stripTerminalSequences(this.fields.get(index) ?? "")] : [])];
87
- return [...new Set(texts.map((text) => stripAcceptanceReport(text).trim()).filter(Boolean))].map((text) => [exactTextDigest(text), item]);
88
- }
89
- }
90
- function visibleId(value: any, id: string): string | null {
91
- if (["custom_message", "compaction", "branch_summary"].includes(value.type)) return id;
92
- if (value.type !== "message") return null;
93
- if (["user", "toolResult", "bashExecution"].includes(value.message?.role)) return id;
94
- if (value.message?.role !== "assistant") return null;
95
- const content = Array.isArray(value.message.content) ? value.message.content : [];
96
- const last = content.findLastIndex((part: any) => part.type === "toolCall" || part.type === "text" && part.text || part.type === "thinking" && part.thinking);
97
- return value.message.errorMessage ? `${id}:error` : last < 0 ? null : `${id}:${last}`;
98
- }
99
- interface TextToken { text: string; start: number; end: number }
100
- interface TextBuffer { word: string; wordStart: number; received: number; tokens: TextToken[]; length: number; terminal: TerminalText }
101
- /** Streaming ECMA-48 removal, retaining original UTF-16 positions without buffering control payloads. */
102
- class TerminalText {
103
- private state: "text" | "escape" | "intermediate" | "csi" | "string" | "stringEscape" = "text";
104
- write(text: string, visible: (text: string, start: number) => void): void {
105
- let position = 0;
106
- while (position < text.length) {
107
- if (this.state === "text") {
108
- const next = text.slice(position).search(/[\x1b\x90\x98\x9b\x9d-\x9f]/);
109
- if (next < 0) { visible(text.slice(position), position); return; }
110
- visible(text.slice(position, position + next), position); position += next;
111
- const control = text[position++];
112
- this.state = control === "\x1b" ? "escape" : control === "\x9b" ? "csi" : "string";
113
- continue;
114
- }
115
- const char = text[position++];
116
- if (this.state === "escape") this.state = char === "[" ? "csi" : "]PX^_".includes(char) ? "string" : char >= " " && char <= "/" ? "intermediate" : "text";
117
- else if (this.state === "intermediate") { if (char >= "0" && char <= "~") this.state = "text"; }
118
- else if (this.state === "csi") { if (char >= "@" && char <= "~") this.state = "text"; }
119
- else if (char === "\x07" || char === "\x9c" || this.state === "stringEscape" && char === "\\") this.state = "text";
120
- else this.state = char === "\x1b" ? "stringEscape" : "string";
121
- }
122
- }
123
- }
124
- /** Token windows overlap 12 tokens, including phrases across arbitrarily long whitespace. */
125
- class TextChunks {
126
- private fields = new Map<string, TextBuffer>();
127
- private staged: Array<{ field: string; start: number; end: number; text: string }> = [];
128
- private emit(field: string, buffer: TextBuffer, final = false): void {
129
- if (!buffer.tokens.length) return;
130
- this.staged.push({ field, start: buffer.tokens[0].start, end: buffer.tokens.at(-1)!.end, text: buffer.tokens.map((token) => token.text).join(" ") });
131
- buffer.tokens = final ? [] : buffer.tokens.slice(-12);
132
- buffer.length = buffer.tokens.reduce((length, token) => length + token.text.length + 1, 0);
133
- }
134
- private token(field: string, buffer: TextBuffer, end: number): void {
135
- if (!buffer.word) return;
136
- buffer.tokens.push({ text: buffer.word, start: buffer.wordStart, end });
137
- buffer.length += buffer.word.length + 1; buffer.word = "";
138
- if (buffer.tokens.length >= 256 || buffer.length >= 8192 && buffer.tokens.length > 12) this.emit(field, buffer);
139
- }
140
- write(keys: readonly (string | number)[], text: string): void {
141
- if (!candidate(keys)) return;
142
- const field = JSON.stringify(keys);
143
- let buffer = this.fields.get(field);
144
- if (!buffer) {
145
- if (this.fields.size >= 4096) throw new HistoryIndexError("RECORD_COMPLEXITY", "Record exceeds the 4096 visible text-field indexing budget.");
146
- this.fields.set(field, buffer = { word: "", wordStart: 0, received: 0, tokens: [], length: 0, terminal: new TerminalText() });
147
- }
148
- buffer.terminal.write(text, (visible, offset) => {
149
- for (const part of visible.matchAll(/[\p{L}\p{N}\p{M}]+|[^\p{L}\p{N}\p{M}]+/gu)) {
150
- const start = buffer.received + offset + part.index!;
151
- if (/^[\p{L}\p{N}\p{M}]/u.test(part[0])) {
152
- if (!buffer.word) buffer.wordStart = start;
153
- buffer.word += part[0];
154
- if (buffer.word.length > 65_536) throw new HistoryIndexError("RECORD_COMPLEXITY", "Record contains a lexical token exceeding the 64 KiB indexing budget.");
155
- } else this.token(field, buffer, start);
156
- }
157
- });
158
- buffer.received += text.length;
159
- }
160
- flush(store: HistoryStore, finish = false): void {
161
- if (finish) {
162
- for (const [field, buffer] of this.fields) { this.token(field, buffer, buffer.received); this.emit(field, buffer, true); }
163
- this.fields.clear();
164
- }
165
- if (this.staged.length) {
166
- const insert = store.db.prepare("INSERT INTO pending_text VALUES (?,?,?,?)");
167
- for (const item of this.staged) insert.run(item.field, item.start, item.end, item.text);
168
- this.staged = [];
169
- }
170
- }
171
- }
5
+ import { type HistoryStore, safeText, type SourceRow } from "./store.ts";
6
+ import { previewProjection, previewLimits, allowed } from "./preview.ts";
7
+ import { TextChunks } from "./text-chunks.ts";
8
+ import { AnswerTexts } from "./answer-texts.ts";
9
+ import { object } from "./values.ts";
10
+ import { identity, stamp, openSource, requireSource } from "./source-file.ts";
11
+ export { identity, stamp } from "./source-file.ts";
12
+ import { number, text } from "./rows.ts";
13
+ import { stageEntry, publishTools, type IngestRecord } from "./entry-ingestion.ts";
14
+ export { previewProjection, previewLimits, compactEntry } from "./preview.ts";
172
15
 
173
16
  /** One physical source, incremental byte framing and short row/cursor publication transactions. */
174
17
  export class SourceIngest {
175
- private fd: number;
176
- private initial: fs.BigIntStats;
177
- private source: SourceRow;
178
- private recordDigest: Hash = createHash("sha256");
179
- /** prefix_digest is "start:sha256" of the last indexed line; earlier releases hashed the whole prefix. */
180
- private legacy = false;
181
- private expected: string | null = null;
182
- private verified: Hash = createHash("sha256");
183
- private line: Hash = createHash("sha256");
184
- private lineStart = 0;
185
- private verifyAt = 0;
186
- private position: number;
187
- private frames: JournalFrames;
188
- private text = new TextChunks();
189
- private answerTexts = new AnswerTexts();
190
- private buffer = Buffer.alloc(0);
191
- private record?: { value: any; start: number; end: number; digest: string };
192
- private stagedEntry?: number;
193
- private textCursor = 0;
194
- private malformed = false;
195
- private complexity = false;
196
- private phase: "verify" | "read" | "text" | "done";
197
- private closed = false;
198
- private headerSeen: boolean;
199
- private store: HistoryStore;
200
- readonly id: string;
201
- constructor(store: HistoryStore, source: SourceRow, force = false) {
202
- this.store = store; this.source = source; this.id = source.id;
203
- store.beginIngest();
204
- let opened: number | undefined;
205
- try {
206
- this.source = source = store.source(source.id)!;
207
- if (!source) throw new HistoryIndexError("SOURCE_CHANGED", "Source was removed before ingestion.");
208
- store.operations.sourceChecks++; store.operations.sourceOpens++;
209
- this.fd = opened = fs.openSync(source.path, "r"); this.initial = fs.fstatSync(this.fd, { bigint: true });
210
- if (!this.initial.isFile() || this.initial.size > BigInt(Number.MAX_SAFE_INTEGER)) throw new Error("Journal is not a supported regular file.");
211
- if (source.identity && (source.identity !== identity(this.initial) || Number(this.initial.size) < source.cursor)) { store.resetSource(source.id); this.source = source = store.source(source.id)!; }
212
- this.position = source.cursor;
213
- this.headerSeen = source.cursor > 0;
214
- store.clearUnpublished(source.id);
215
- store.run("DELETE FROM pending_text");
216
- // Appends re-hash only the last indexed line, so live sources cost their new bytes, not their size.
217
- const anchor = /^(\d+):([0-9a-f]{64})$/.exec(source.prefix_digest ?? "");
218
- this.legacy = !anchor; this.expected = anchor ? anchor[2] : source.prefix_digest;
219
- this.verifyAt = this.lineStart = anchor ? Number(anchor[1]) : 0;
220
- this.phase = !force && source.stamp === stamp(this.initial) ? "done" : source.cursor ? "verify" : "read";
221
- if (this.phase !== "done") store.run("UPDATE sources SET state='indexing',error=NULL WHERE id=?", source.id);
222
- this.frames = new JournalFrames(previewProjection, (record) => {
223
- this.record = { ...record, digest: this.recordDigest.copy().digest("hex") };
224
- }, "inspect", source.cursor, (_start, _end, error) => { this.malformed = true; this.complexity = error instanceof RangeError || error instanceof HistoryIndexError && error.code === "RECORD_COMPLEXITY"; }, (keys, chunk) => { this.text.write(keys, chunk); this.answerTexts.write(keys, chunk); }, undefined, true, previewLimits);
225
- } catch (error) {
226
- if (opened !== undefined) fs.closeSync(opened);
227
- store.endIngest();
228
- throw error;
229
- }
230
- }
231
- private published(end: number, work?: () => void): void {
232
- this.store.transaction(() => {
233
- const current = this.store.source(this.id)!;
234
- if (!current || current.generation !== this.source.generation || current.cursor !== this.source.cursor) throw new HistoryIndexError("SOURCE_CHANGED", "Another writer advanced this source; reconcile before replaying.");
235
- work?.();
236
- this.store.run("UPDATE sources SET cursor=?,prefix_digest=?,identity=? WHERE id=?", end, `${this.source.cursor}:${this.recordDigest.copy().digest("hex")}`, identity(this.initial), this.id);
237
- this.store.bump();
238
- });
239
- this.source.cursor = end;
240
- this.recordDigest = createHash("sha256"); this.text = new TextChunks(); this.answerTexts = new AnswerTexts();
241
- this.store.run("DELETE FROM pending_text"); this.record = undefined; this.malformed = this.complexity = false;
242
- }
243
- private finishRecord(end: number): void {
244
- this.text.flush(this.store, true);
245
- if (this.malformed) {
246
- if (!this.headerSeen) throw new Error("Malformed native session header.");
247
- this.published(end, () => this.store.run("UPDATE sources SET malformed=malformed+1,complexity=complexity+? WHERE id=?", this.complexity ? 1 : 0, this.id)); return;
248
- }
249
- const record = this.record;
250
- if (!record) { this.published(end); return; }
251
- const value = record.value;
252
- if (!this.headerSeen) {
253
- if (value.type !== "session") throw new Error("Linked source does not have a native session header.");
254
- this.published(end, () => this.store.run("UPDATE sources SET session_id=?,header_digest=?,format_version=? WHERE id=?", typeof value.id === "string" ? value.id : null, record.digest, typeof value.version === "number" ? value.version : null, this.id));
255
- this.source.format_version = typeof value.version === "number" ? value.version : null;
256
- this.headerSeen = true; return;
257
- }
258
- if (value.type === "session") throw new Error("Unexpected session header inside a native source.");
259
- const nativeId = typeof value.id === "string" ? value.id : null;
260
- const id = nativeId ?? `legacy-${record.start}`;
261
- if (this.store.get("SELECT rowid FROM entries WHERE source_id=? AND generation=? AND id=?", this.id, this.source.generation, id)) {
262
- this.published(end, () => this.store.run("UPDATE sources SET malformed=malformed+1 WHERE id=?", this.id)); return;
263
- }
264
- const timestamp = typeof value.timestamp === "number" ? value.timestamp : Date.parse(value.timestamp);
265
- const parent = this.source.format_version === 1 ? this.store.get("SELECT id FROM entries WHERE source_id=? AND generation=? AND published=1 ORDER BY start DESC LIMIT 1", this.id, this.source.generation)?.id ?? null : typeof value.parentId === "string" ? value.parentId : null;
266
- const preview = compactEntry(value); preview.id = id; preview.parentId = parent;
267
- const model = value.type === "model_change" && typeof value.modelId === "string" ? `${value.provider}/${value.modelId}` : value.type === "message" && value.message?.role === "assistant" && typeof value.message.model === "string" ? `${value.message.provider}/${value.message.model}` : null;
268
- this.stagedEntry = Number(this.store.run("INSERT INTO entries(source_id,generation,id,native_id,parent_id,start,end,digest,timestamp,type,preview,role,assistant_text,visible_id,human_id,configuration_model,configuration_thinking) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", this.id, this.source.generation, id, nativeId, parent, record.start, end, record.digest, Number.isFinite(timestamp) ? timestamp : null, typeof value.type === "string" ? value.type : "unknown", JSON.stringify(preview), typeof value.message?.role === "string" ? value.message.role : null,
269
- value.message?.role === "assistant" && Array.isArray(value.message.content) && value.message.content.some((part: any) => part.type === "text" && part.text) ? 1 : 0,
270
- visibleId(value, id), value.type === "custom_message" && value.customType === "subagent-human-message" && typeof value.details?.message?.id === "string" ? value.details.message.id : null, model, value.type === "thinking_level_change" && typeof value.thinkingLevel === "string" ? value.thinkingLevel : null).lastInsertRowid);
271
- this.textCursor = 0; this.phase = "text";
272
- }
273
- private indexText(): void {
274
- const chunks = this.store.all("SELECT rowid,* FROM pending_text WHERE rowid>? ORDER BY rowid LIMIT 32", this.textCursor);
275
- if (chunks.length) {
276
- this.store.transaction(() => {
277
- for (const chunk of chunks) {
278
- if (!allowed(this.record!.value, chunk.field)) continue;
279
- const text = safeText(chunk.text, 1_048_576);
280
- const id = this.store.run("INSERT INTO documents(entry_rowid,field,text_start,text_end,preview) VALUES (?,?,?,?,?)", this.stagedEntry!, chunk.field, chunk.position, chunk.end_position, safeText(text, 512)).lastInsertRowid;
281
- this.store.run("INSERT INTO corpus(rowid,text) VALUES (?,?)", id, text);
282
- }
283
- });
284
- this.textCursor = chunks.at(-1).rowid; return;
285
- }
286
- const value = this.record!.value, rowid = this.stagedEntry!;
287
- const answers = this.answerTexts.fingerprints(value, typeof value.id === "string" ? value.id : `legacy-${this.record!.start}`);
288
- this.published(this.record!.end, () => {
289
- if (this.store.run("UPDATE entries SET published=1 WHERE rowid=? AND source_id=? AND generation=? AND published=0", rowid, this.id, this.source.generation).changes !== 1) throw new HistoryIndexError("SOURCE_CHANGED", "Staged entry disappeared before publication; reconcile before advancing the source.");
290
- for (const [digest, item] of answers) this.store.run("INSERT OR IGNORE INTO answers VALUES (?,?,?)", rowid, digest, item);
291
- for (const part of Array.isArray(value.message?.content) ? value.message.content : []) if (part.type === "toolCall" && typeof part.id === "string") this.store.run("INSERT INTO tools VALUES (?,?,?,?,?)", rowid, this.id, this.source.generation, part.id, "call");
292
- if (value.message?.role === "toolResult" && typeof value.message.toolCallId === "string") this.store.run("INSERT INTO tools VALUES (?,?,?,?,?)", rowid, this.id, this.source.generation, value.message.toolCallId, "result");
293
- });
294
- this.stagedEntry = undefined; this.phase = "read";
295
- }
296
- /** Each pump reads <=64 KiB or indexes <=32 chunks, then returns to the IPC event loop. */
297
- step(): boolean {
298
- if (this.phase === "done") { this.close(); return true; }
299
- if (this.phase === "text") { this.indexText(); return false; }
300
- if (this.phase === "verify") {
301
- const bytes = Buffer.allocUnsafe(Math.min(64 * 1024, this.source.cursor - this.verifyAt));
302
- const count = fs.readSync(this.fd, bytes, 0, bytes.length, this.verifyAt);
303
- if (count !== bytes.length) throw new Error("Journal truncated during prefix verification.");
304
- this.store.operations.sourceBytesRead += count;
305
- this.verified.update(bytes);
306
- if (this.legacy) {
307
- // A whole-prefix check also finds the last indexed line, which anchors every later check.
308
- const before = this.source.cursor - 2 - this.verifyAt, lf = before < 0 ? -1 : bytes.lastIndexOf(10, before);
309
- if (lf < 0) this.line.update(bytes);
310
- else { this.lineStart = this.verifyAt + lf + 1; this.line = createHash("sha256").update(bytes.subarray(lf + 1)); }
311
- }
312
- this.verifyAt += count;
313
- if (this.verifyAt === this.source.cursor) {
314
- if (this.verified.digest("hex") !== this.expected) {
315
- this.store.resetSource(this.id); throw new HistoryIndexError("SOURCE_CHANGED", "Journal prefix changed; a new physical generation was scheduled.");
316
- }
317
- if (this.legacy) this.store.run("UPDATE sources SET prefix_digest=? WHERE id=?", `${this.lineStart}:${this.line.digest("hex")}`, this.id);
318
- this.phase = "read";
319
- }
320
- return false;
321
- }
322
- if (!this.buffer.length) {
323
- const remaining = Number(this.initial.size) - this.position;
324
- if (remaining <= 0) return this.finish();
325
- const bytes = Buffer.allocUnsafe(Math.min(64 * 1024, remaining));
326
- const count = fs.readSync(this.fd, bytes, 0, bytes.length, this.position);
327
- if (count !== bytes.length) throw new Error("Journal truncated during ingestion.");
328
- this.store.operations.sourceBytesRead += count;
329
- this.position += count; this.buffer = bytes;
330
- }
331
- const newline = this.buffer.indexOf(10);
332
- const bytes = newline < 0 ? this.buffer : this.buffer.subarray(0, newline + 1);
333
- this.recordDigest.update(bytes); this.frames.write(bytes); this.text.flush(this.store);
334
- this.buffer = this.buffer.subarray(bytes.length);
335
- if (newline >= 0) this.finishRecord(this.frames.offset);
336
- return false;
337
- }
338
- private finish(): boolean {
339
- this.frames.finish();
340
- const now = fs.statSync(this.source.path, { bigint: true });
341
- if (identity(now) !== identity(this.initial) || now.size < this.initial.size || now.size === this.initial.size && stamp(now) !== stamp(this.initial)) {
342
- this.store.resetSource(this.id); throw new HistoryIndexError("SOURCE_CHANGED", "Journal changed during ingestion; retrying its new generation.");
343
- }
344
- const { malformed, complexity } = this.store.source(this.id)!;
345
- this.store.run("UPDATE sources SET identity=?,stamp=?,checked_at=?,state=?,error=? WHERE id=?", identity(this.initial), stamp(this.initial), Date.now(), malformed ? "degraded" : this.source.cursor < Number(this.initial.size) ? "partial" : "current", malformed ? `${malformed} malformed, duplicate or over-budget LF-published records were skipped.${complexity ? ` ${complexity} exceeded bounded history structure/text budgets.` : ""}` : null, this.id);
346
- this.phase = "done"; this.close(); return true;
347
- }
348
- close(): void { if (!this.closed) { fs.closeSync(this.fd); this.store.endIngest(); this.closed = true; } }
18
+ private readonly fd: number;
19
+ private readonly initial: fs.BigIntStats;
20
+ private source: SourceRow;
21
+ private recordDigest: Hash = createHash("sha256");
22
+ /** prefix_digest anchors the last indexed line; older releases hashed the whole prefix. */
23
+ private legacy: boolean = false;
24
+ private expected: string | null = null;
25
+ private readonly verified: Hash = createHash("sha256");
26
+ private line: Hash = createHash("sha256");
27
+ private lineStart = 0;
28
+ private verifyAt = 0;
29
+ private position: number;
30
+ private readonly frames: JournalFrames;
31
+ private text = new TextChunks();
32
+ private answerTexts = new AnswerTexts();
33
+ private buffer = Buffer.alloc(0);
34
+ private record?: IngestRecord;
35
+ private stagedEntry?: number;
36
+ private textCursor = 0;
37
+ private malformed = false;
38
+ private complexity = false;
39
+ private phase: "verify" | "read" | "text" | "done";
40
+ private closed = false;
41
+ private headerSeen: boolean;
42
+ private readonly store: Readonly<HistoryStore>;
43
+ readonly id: string;
44
+ constructor(store: Readonly<HistoryStore>, source: SourceRow, force = false) {
45
+ this.store = store;
46
+ this.id = source.id;
47
+ const opened = openSource(store, source.id);
48
+ this.source = opened.source;
49
+ this.fd = opened.fd;
50
+ this.initial = opened.initial;
51
+ this.position = this.source.cursor;
52
+ this.headerSeen = this.source.cursor > 0;
53
+ this.prepareVerification();
54
+ this.phase = this.source.cursor > 0 ? "verify" : "read";
55
+ if (!force && this.source.stamp === stamp(this.initial)) {
56
+ this.phase = "done";
57
+ }
58
+ try {
59
+ if (this.phase !== "done") {
60
+ store.run("UPDATE sources SET state='indexing',error=NULL WHERE id=?", this.id);
61
+ }
62
+ this.frames = new JournalFrames(
63
+ previewProjection,
64
+ (record) => {
65
+ this.record = {
66
+ ...record,
67
+ value: object(record.value),
68
+ digest: this.recordDigest.copy().digest("hex"),
69
+ };
70
+ },
71
+ {
72
+ policy: "inspect",
73
+ start: this.source.cursor,
74
+ malformed: (_start, _end, error) => {
75
+ this.malformed = true;
76
+ this.complexity =
77
+ error instanceof RangeError ||
78
+ (error instanceof HistoryIndexError && error.code === "RECORD_COMPLEXITY");
79
+ },
80
+ stringChunk: (keys, chunk) => {
81
+ this.text.write(keys, chunk);
82
+ this.answerTexts.write(keys, chunk);
83
+ },
84
+ requireNewline: true,
85
+ limits: previewLimits,
86
+ },
87
+ );
88
+ } catch (error) {
89
+ fs.closeSync(this.fd);
90
+ store.endIngest();
91
+ throw error;
92
+ }
93
+ }
94
+ private prepareVerification(): void {
95
+ const anchor = /^(\d+):([0-9a-f]{64})$/.exec(this.source.prefix_digest ?? "");
96
+ this.legacy = !anchor;
97
+ this.expected = anchor ? anchor[2] : this.source.prefix_digest;
98
+ this.lineStart = anchor ? Number(anchor[1]) : 0;
99
+ this.verifyAt = this.lineStart;
100
+ }
101
+ private published(end: number, work?: () => void): void {
102
+ this.store.transaction(() => {
103
+ const current = this.store.source(this.id);
104
+ if (
105
+ !current ||
106
+ current.generation !== this.source.generation ||
107
+ current.cursor !== this.source.cursor
108
+ ) {
109
+ throw new HistoryIndexError(
110
+ "SOURCE_CHANGED",
111
+ "Another writer advanced this source; reconcile before replaying.",
112
+ );
113
+ }
114
+ work?.();
115
+ this.store.run(
116
+ "UPDATE sources SET cursor=?,prefix_digest=?,identity=? WHERE id=?",
117
+ end,
118
+ `${this.source.cursor}:${this.recordDigest.copy().digest("hex")}`,
119
+ identity(this.initial),
120
+ this.id,
121
+ );
122
+ this.store.bump();
123
+ });
124
+ this.source = { ...this.source, cursor: end };
125
+ this.recordDigest = createHash("sha256");
126
+ this.text = new TextChunks();
127
+ this.answerTexts = new AnswerTexts();
128
+ this.store.run("DELETE FROM pending_text");
129
+ this.record = undefined;
130
+ this.malformed = false;
131
+ this.complexity = false;
132
+ }
133
+ private finishRecord(end: number): void {
134
+ this.text.flush(this.store, true);
135
+ if (this.malformed) {
136
+ if (!this.headerSeen) {
137
+ throw new Error("Malformed native session header.");
138
+ }
139
+ this.published(end, () => {
140
+ this.store.run(
141
+ "UPDATE sources SET malformed=malformed+1,complexity=complexity+? WHERE id=?",
142
+ this.complexity ? 1 : 0,
143
+ this.id,
144
+ );
145
+ });
146
+ return;
147
+ }
148
+ const record = this.record;
149
+ if (!record) {
150
+ this.published(end);
151
+ return;
152
+ }
153
+ const value = record.value;
154
+ if (!this.headerSeen) {
155
+ this.publishHeader(record);
156
+ return;
157
+ }
158
+ if (value.type === "session") {
159
+ throw new Error("Unexpected session header inside a native source.");
160
+ }
161
+ const nativeId = typeof value.id === "string" ? value.id : null;
162
+ const id = nativeId ?? `legacy-${record.start}`;
163
+ if (
164
+ this.store.get(
165
+ "SELECT rowid FROM entries WHERE source_id=? AND generation=? AND id=?",
166
+ this.id,
167
+ this.source.generation,
168
+ id,
169
+ )
170
+ ) {
171
+ this.published(end, () => {
172
+ this.store.run("UPDATE sources SET malformed=malformed+1 WHERE id=?", this.id);
173
+ });
174
+ return;
175
+ }
176
+ this.stagedEntry = stageEntry(this.store, this.source, record);
177
+ this.textCursor = 0;
178
+ this.phase = "text";
179
+ }
180
+ private publishHeader(record: IngestRecord): void {
181
+ const value = record.value;
182
+ if (value.type !== "session") {
183
+ throw new Error("Linked source does not have a native session header.");
184
+ }
185
+ const version = typeof value.version === "number" ? value.version : null;
186
+ this.published(record.end, () => {
187
+ this.store.run(
188
+ "UPDATE sources SET session_id=?,header_digest=?,format_version=? WHERE id=?",
189
+ typeof value.id === "string" ? value.id : null,
190
+ record.digest,
191
+ version,
192
+ this.id,
193
+ );
194
+ });
195
+ this.source = { ...this.source, format_version: version };
196
+ this.headerSeen = true;
197
+ }
198
+ private verifyPrefix(): void {
199
+ const bytes = Buffer.allocUnsafe(Math.min(64 * 1024, this.source.cursor - this.verifyAt));
200
+ const count = fs.readSync(this.fd, bytes, 0, bytes.length, this.verifyAt);
201
+ if (count !== bytes.length) {
202
+ throw new Error("Journal truncated during prefix verification.");
203
+ }
204
+ this.store.count("sourceBytesRead", count);
205
+ this.verified.update(bytes);
206
+ if (this.legacy) {
207
+ // A whole-prefix check also finds the last indexed line for later bounded checks.
208
+ const before = this.source.cursor - 2 - this.verifyAt;
209
+ const lf = before < 0 ? -1 : bytes.lastIndexOf(10, before);
210
+ if (lf < 0) {
211
+ this.line.update(bytes);
212
+ } else {
213
+ this.lineStart = this.verifyAt + lf + 1;
214
+ this.line = createHash("sha256").update(bytes.subarray(lf + 1));
215
+ }
216
+ }
217
+ this.verifyAt += count;
218
+ if (this.verifyAt === this.source.cursor) {
219
+ if (this.verified.digest("hex") !== this.expected) {
220
+ this.store.resetSource(this.id);
221
+ throw new HistoryIndexError(
222
+ "SOURCE_CHANGED",
223
+ "Journal prefix changed; a new physical generation was scheduled.",
224
+ );
225
+ }
226
+ if (this.legacy) {
227
+ this.store.run(
228
+ "UPDATE sources SET prefix_digest=? WHERE id=?",
229
+ `${this.lineStart}:${this.line.digest("hex")}`,
230
+ this.id,
231
+ );
232
+ }
233
+ this.phase = "read";
234
+ }
235
+ }
236
+ private indexText(): void {
237
+ const record = this.record;
238
+ const rowid = this.stagedEntry;
239
+ if (!record || rowid === undefined) {
240
+ throw new HistoryIndexError("CORRUPT", "Missing staged entry.");
241
+ }
242
+ const chunks = this.store.all(
243
+ "SELECT rowid,* FROM pending_text WHERE rowid>? ORDER BY rowid LIMIT 32",
244
+ this.textCursor,
245
+ );
246
+ if (chunks.length > 0) {
247
+ this.store.transaction(() => {
248
+ for (const chunk of chunks) {
249
+ if (!allowed(record.value, text(chunk, "field"))) {
250
+ continue;
251
+ }
252
+ const body = safeText(text(chunk, "text"), 1_048_576);
253
+ const id = this.store.run(
254
+ "INSERT INTO documents(entry_rowid,field,text_start,text_end,preview) VALUES (?,?,?,?,?)",
255
+ rowid,
256
+ text(chunk, "field"),
257
+ number(chunk, "position"),
258
+ number(chunk, "end_position"),
259
+ safeText(body, 512),
260
+ ).lastInsertRowid;
261
+ this.store.run("INSERT INTO corpus(rowid,text) VALUES (?,?)", id, body);
262
+ }
263
+ });
264
+ const last = chunks.at(-1);
265
+ if (last) {
266
+ this.textCursor = number(last, "rowid");
267
+ }
268
+ return;
269
+ }
270
+ const value = record.value;
271
+ const answers = this.answerTexts.fingerprints(
272
+ value,
273
+ typeof value.id === "string" ? value.id : `legacy-${record.start}`,
274
+ );
275
+ this.published(record.end, () => {
276
+ if (
277
+ this.store.run(
278
+ "UPDATE entries SET published=1 WHERE rowid=? AND source_id=? AND generation=? AND published=0",
279
+ rowid,
280
+ this.id,
281
+ this.source.generation,
282
+ ).changes !== 1
283
+ ) {
284
+ throw new HistoryIndexError(
285
+ "SOURCE_CHANGED",
286
+ "Staged entry disappeared before publication; reconcile before advancing the source.",
287
+ );
288
+ }
289
+ for (const [digest, item] of answers) {
290
+ this.store.run("INSERT OR IGNORE INTO answers VALUES (?,?,?)", rowid, digest, item);
291
+ }
292
+ publishTools(this.store, this.source, rowid, value);
293
+ });
294
+ this.stagedEntry = undefined;
295
+ this.phase = "read";
296
+ }
297
+ /** Each pump reads <=64 KiB or indexes <=32 chunks, then returns to the IPC event loop. */
298
+ step(): boolean {
299
+ if (this.phase === "done") {
300
+ this.close();
301
+ return true;
302
+ }
303
+ if (this.phase === "text") {
304
+ this.indexText();
305
+ return false;
306
+ }
307
+ if (this.phase === "verify") {
308
+ this.verifyPrefix();
309
+ return false;
310
+ }
311
+ if (this.buffer.length === 0) {
312
+ const remaining = Number(this.initial.size) - this.position;
313
+ if (remaining <= 0) {
314
+ return this.finish();
315
+ }
316
+ const bytes = Buffer.allocUnsafe(Math.min(64 * 1024, remaining));
317
+ const count = fs.readSync(this.fd, bytes, 0, bytes.length, this.position);
318
+ if (count !== bytes.length) {
319
+ throw new Error("Journal truncated during ingestion.");
320
+ }
321
+ this.store.count("sourceBytesRead", count);
322
+ this.position += count;
323
+ this.buffer = bytes;
324
+ }
325
+ const newline = this.buffer.indexOf(10);
326
+ const bytes = newline < 0 ? this.buffer : this.buffer.subarray(0, newline + 1);
327
+ this.recordDigest.update(bytes);
328
+ this.frames.write(bytes);
329
+ this.text.flush(this.store);
330
+ this.buffer = this.buffer.subarray(bytes.length);
331
+ if (newline >= 0) {
332
+ this.finishRecord(this.frames.offset);
333
+ }
334
+ return false;
335
+ }
336
+ private finish(): boolean {
337
+ this.frames.finish();
338
+ const now = fs.statSync(this.source.path, { bigint: true });
339
+ if (
340
+ identity(now) !== identity(this.initial) ||
341
+ now.size < this.initial.size ||
342
+ (now.size === this.initial.size && stamp(now) !== stamp(this.initial))
343
+ ) {
344
+ this.store.resetSource(this.id);
345
+ throw new HistoryIndexError(
346
+ "SOURCE_CHANGED",
347
+ "Journal changed during ingestion; retrying its new generation.",
348
+ );
349
+ }
350
+ const { malformed, complexity } = requireSource(this.store, this.id);
351
+ this.store.run(
352
+ "UPDATE sources SET identity=?,stamp=?,checked_at=?,state=?,error=? WHERE id=?",
353
+ identity(this.initial),
354
+ stamp(this.initial),
355
+ Date.now(),
356
+ this.sourceState(malformed),
357
+ malformed > 0
358
+ ? `${malformed} malformed, duplicate or over-budget LF-published records were skipped.${complexity > 0 ? ` ${complexity} exceeded bounded history structure/text budgets.` : ""}`
359
+ : null,
360
+ this.id,
361
+ );
362
+ this.phase = "done";
363
+ this.close();
364
+ return true;
365
+ }
366
+ private sourceState(malformed: number): string {
367
+ if (malformed > 0) {
368
+ return "degraded";
369
+ }
370
+ return this.source.cursor < Number(this.initial.size) ? "partial" : "current";
371
+ }
372
+ close(): void {
373
+ if (!this.closed) {
374
+ fs.closeSync(this.fd);
375
+ this.store.endIngest();
376
+ this.closed = true;
377
+ }
378
+ }
349
379
  }