@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,370 +1,81 @@
1
- import * as fs from "node:fs";
2
- import { createHash } from "node:crypto";
3
- import { JsonProjection } from "../shared/journal-reader.js";
4
- import { compactEntry, identity, previewLimits, previewProjection } from "./ingest.js";
5
- import { HistoryIndexError } from "./types.js";
6
- import { hash, HistoryStore, integer, pageLimit } from "./store.js";
1
+ import { HistoryIndexError, } from "./types.js";
2
+ import { entryRow } from "./rows.js";
3
+ import { QueryScope } from "./query-scope.js";
4
+ import { RunQueries } from "./run-queries.js";
5
+ import { TranscriptQueries } from "./transcript-queries.js";
6
+ import { SearchQueries } from "./search-queries.js";
7
+ import { validateRecord } from "./selected-record.js";
8
+ import { compactEntry } from "./preview.js";
9
+ import { hasText } from "./text.js";
10
+ /** One query facade with separate run, transcript, search and selected-detail responsibilities. */
7
11
  export class HistoryQueries {
8
- store;
9
- info;
10
- configurations = new Map();
11
- constructor(store, info) { this.store = store; this.info = info; }
12
- sourcesRemoved() { this.configurations.clear(); }
13
- cursor(query, keys, offset) {
14
- return Buffer.from(JSON.stringify({ generation: this.store.generation, owner: this.store.owner, version: this.info().version, query, keys, offset })).toString("base64url");
12
+ scope;
13
+ runs;
14
+ transcript;
15
+ searchQueries;
16
+ constructor(store, info) {
17
+ this.scope = new QueryScope(store, info);
18
+ this.runs = new RunQueries(this.scope);
19
+ this.transcript = new TranscriptQueries(this.scope);
20
+ this.searchQueries = new SearchQueries(this.scope);
15
21
  }
16
- parseCursor(value, query) {
17
- if (value === undefined)
18
- return;
19
- let cursor;
20
- try {
21
- if (value.length > 4096)
22
- throw new Error();
23
- cursor = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
24
- if (!Array.isArray(cursor.keys) || cursor.keys.length > 8 || cursor.keys.some((key) => typeof key !== "number" && typeof key !== "string") || !Number.isSafeInteger(cursor.offset) || cursor.offset < 0)
25
- throw new Error();
26
- }
27
- catch {
28
- throw new HistoryIndexError("INVALID_CURSOR", "Invalid history cursor.");
29
- }
30
- if (cursor.generation !== this.store.generation || cursor.owner !== this.store.owner || cursor.query !== query || cursor.version !== this.info().version)
31
- throw new HistoryIndexError("STALE_CURSOR", "History changed or this cursor belongs to a different query/source; restart paging.");
32
- return cursor;
33
- }
34
- child(runId, index) {
35
- integer(index, 0);
36
- const child = this.store.get("SELECT * FROM children WHERE run_id=? AND child_index=?", runId, index);
37
- if (!child)
38
- throw new HistoryIndexError("OWNERSHIP", "Run/child is not in the current owner's admitted handles.");
39
- return { source: child.source_id ? this.store.source(child.source_id) : undefined, agent: child.agent };
22
+ sourcesRemoved() {
23
+ this.scope.sourcesRemoved();
40
24
  }
41
25
  listRuns(options) {
42
- const limit = pageLimit(options.limit, 20), offset = integer(options.offset, 0), sort = options.sort ?? "attention";
43
- if (!["attention", "newest", "oldest"].includes(sort))
44
- throw new HistoryIndexError("INVALID", "Unsupported run sort.");
45
- if (options.state && !["live", "completed", "paused", "blocked", "failed", "unknown"].includes(options.state))
46
- throw new HistoryIndexError("INVALID", "Unsupported run state.");
47
- if ((options.text?.length ?? 0) > 256 || (options.agent?.length ?? 0) > 256 || options.latestTasksOnly !== undefined && typeof options.latestTasksOnly !== "boolean")
48
- throw new HistoryIndexError("INVALID", "Invalid run filter.");
49
- const query = hash(JSON.stringify(["runs", sort, options.agent ?? null, options.state ?? null, options.text?.toLowerCase() ?? null, options.latestTasksOnly ?? false]));
50
- const cursor = this.parseCursor(options.cursor, query);
51
- if (cursor && options.offset !== undefined)
52
- throw new HistoryIndexError("INVALID", "Use cursor or offset, not both.");
53
- const clauses = [], params = [], childClauses = [], childParams = [];
54
- if (options.agent) {
55
- childClauses.push("c.agent=?");
56
- childParams.push(options.agent);
57
- }
58
- if (options.text) {
59
- childClauses.push("instr(c.filter_text,?)>0");
60
- childParams.push(options.text.toLowerCase());
61
- }
62
- if (options.latestTasksOnly)
63
- childClauses.push("NOT EXISTS(SELECT 1 FROM runs successor WHERE successor.predecessor_id=c.run_id AND successor.predecessor_index=c.child_index)");
64
- const childWhere = childClauses.length ? ` AND ${childClauses.join(" AND ")}` : "";
65
- if (childWhere) {
66
- clauses.push(`EXISTS(SELECT 1 FROM children c WHERE c.run_id=r.id${childWhere})`);
67
- params.push(...childParams);
68
- }
69
- if (options.state) {
70
- clauses.push("r.state=?");
71
- params.push(options.state);
72
- }
73
- const total = Number(this.store.get(`SELECT COUNT(*) AS total FROM runs r ${clauses.length ? `WHERE ${clauses.join(" AND ")}` : ""}`, ...params).total);
74
- const columns = sort === "attention" ? ["attention", "negative_updated", "id"] : [sort === "newest" ? "negative_updated" : "updated", "id"];
75
- if (cursor) {
76
- if (cursor.keys.length !== columns.length)
77
- throw new HistoryIndexError("INVALID_CURSOR", "Invalid run seek tuple.");
78
- clauses.push(`(${columns.map((column) => `r.${column}`).join(",")}) > (${columns.map(() => "?").join(",")})`);
79
- params.push(...cursor.keys);
80
- }
81
- const rows = this.store.all(`SELECT * FROM runs r ${clauses.length ? `WHERE ${clauses.join(" AND ")}` : ""} ORDER BY ${columns.map((column) => `r.${column}`).join(",")} LIMIT ? OFFSET ?`, ...params, limit + 1, cursor ? 0 : offset);
82
- const more = rows.length > limit, page = rows.slice(0, limit), position = cursor?.offset ?? offset;
83
- const views = page.map((row) => {
84
- const view = JSON.parse(row.view);
85
- if (childWhere)
86
- view.matchedChildIndexes = this.store.all(`SELECT child_index FROM children c WHERE c.run_id=?${childWhere} ORDER BY child_index`, view.runId, ...childParams).map((child) => child.child_index);
87
- for (const child of view.children) {
88
- const { source } = this.child(view.runId, child.index);
89
- if (source)
90
- child.nativeConfiguration = this.configuration(source, child.state === "live" ? {} : { terminalEntryId: child.result?.terminalEntryId, endedAt: child.result?.terminalEntryId ? undefined : view.updatedAt, leaf: child.result?.terminalLeafId }, false);
91
- }
92
- return view;
93
- });
94
- return { rows: views, total, offset: position, ...this.info(), ...(more ? { nextOffset: position + page.length, nextCursor: this.cursor(query, columns.map((column) => page.at(-1)[column]), position + page.length) } : {}) };
95
- }
96
- boundary(source, input, alias = "") {
97
- const column = alias ? `${alias}.` : "", clauses = [`${column}source_id=?`, `${column}generation=?`, `${column}published=1`], params = [source.id, source.generation];
98
- let terminalSequence;
99
- if (input.terminalEntryId) {
100
- const terminal = this.store.get("SELECT start FROM entries WHERE source_id=? AND generation=? AND id=? AND published=1", source.id, source.generation, input.terminalEntryId);
101
- if (!terminal)
102
- throw new HistoryIndexError("BOUNDARY_UNAVAILABLE", "Saved terminal entry is not available in the current indexed generation.");
103
- terminalSequence = terminal.start;
104
- clauses.push(`${column}start<=?`);
105
- params.push(terminal.start);
106
- }
107
- else if (input.endedAt !== undefined) {
108
- clauses.push(`${column}timestamp<=?`);
109
- params.push(integer(input.endedAt, 0));
110
- }
111
- return { clauses, params, terminalSequence };
112
- }
113
- configuration(source, input, strict = true) {
114
- if (input.leaf === null)
115
- return {};
116
- let boundary;
117
- try {
118
- boundary = this.boundary(source, input);
119
- }
120
- catch (error) {
121
- if (!strict && error instanceof HistoryIndexError && error.code === "BOUNDARY_UNAVAILABLE")
122
- return {};
123
- throw error;
124
- }
125
- // Only committed source changes invalidate ancestry, not unrelated run projections.
126
- // Validate boundaries before reuse; explicit null leaves returned above remain empty.
127
- const leafKey = input.leaf === undefined ? null : [typeof input.leaf, String(input.leaf)];
128
- const key = JSON.stringify([source.id, source.generation, source.cursor, source.stamp, input.terminalEntryId || null, input.terminalEntryId ? null : input.endedAt ?? null, leafKey, strict]);
129
- const cached = this.configurations.get(key);
130
- if (cached)
131
- return { ...cached };
132
- const leaf = input.leaf ?? this.store.get(`SELECT id FROM entries WHERE ${boundary.clauses.join(" AND ")} ORDER BY start DESC LIMIT 1`, ...boundary.params)?.id;
133
- if (!leaf)
134
- return {};
135
- // Fix recursive loop order: look up each child's parent by ID instead of
136
- // rescanning the eligible transcript at every ancestry step.
137
- const ancestry = `WITH RECURSIVE eligible AS (SELECT rowid,id,parent_id,start,timestamp,configuration_model,configuration_thinking FROM entries WHERE ${boundary.clauses.join(" AND ")}), branch AS (SELECT * FROM eligible WHERE id=? UNION SELECT parent.* FROM branch child CROSS JOIN eligible parent WHERE parent.id=child.parent_id)`;
138
- const facts = this.store.get(`${ancestry} SELECT
139
- (SELECT COUNT(*) FROM branch) AS count,
140
- EXISTS(SELECT 1 FROM branch child WHERE parent_id IS NULL OR NOT EXISTS(SELECT 1 FROM eligible parent WHERE parent.id=child.parent_id)) AS rooted,
141
- (SELECT configuration_model FROM branch WHERE configuration_model IS NOT NULL ORDER BY start DESC LIMIT 1) AS model,
142
- (SELECT timestamp FROM branch WHERE configuration_model IS NOT NULL ORDER BY start DESC LIMIT 1) AS recorded_at,
143
- (SELECT configuration_thinking FROM branch WHERE configuration_thinking IS NOT NULL ORDER BY start DESC LIMIT 1) AS thinking`, ...boundary.params, leaf);
144
- if (!facts.count && input.leaf && strict)
145
- throw new HistoryIndexError("BOUNDARY_UNAVAILABLE", "Selected configuration leaf is not available in the indexed generation.");
146
- if (facts.count && !facts.rooted) {
147
- if (!strict)
148
- return {};
149
- throw new HistoryIndexError("MALFORMED_ANCESTRY", "Selected native configuration has cyclic ancestry.");
150
- }
151
- const configuration = { ...(facts.model ? { model: facts.model, modelRecordedAt: facts.recorded_at ?? undefined } : {}), ...(facts.thinking ? { thinking: facts.thinking } : {}) };
152
- // Bound memory across arbitrary sources, boundaries and pages. Eviction only recomputes.
153
- if (this.configurations.size >= 128)
154
- this.configurations.delete(this.configurations.keys().next().value);
155
- this.configurations.set(key, configuration);
156
- return { ...configuration };
26
+ return this.runs.list(options);
157
27
  }
158
28
  historyPage(input) {
159
- const { source } = this.child(input.runId, input.index);
160
- const info = this.info(), limit = pageLimit(input.limit);
161
- if (input.before !== undefined && input.after !== undefined)
162
- throw new HistoryIndexError("INVALID", "Use before or after, not both.");
163
- if (input.messageIds && (!Array.isArray(input.messageIds) || input.messageIds.length > 1000 || input.messageIds.some((id) => typeof id !== "string" || id.length > 512)) || input.readThrough !== undefined && input.readThrough !== null && (typeof input.readThrough !== "string" || input.readThrough.length > 1024))
164
- throw new HistoryIndexError("INVALID", "Invalid scoped message/read metadata request.");
165
- const empty = { ...info, entries: [], count: 0, hasMore: false, sourceId: source?.id ?? null, generation: source?.generation ?? null, sessionId: source?.session_id ?? null, sourceState: source?.state ?? "unlinked", configuration: {}, deliveredMessages: [], latestEntryId: null };
166
- if (!source)
167
- return { ...empty, unavailable: "This legacy or unstarted child has no linked native conversation." };
168
- const query = hash(JSON.stringify(["history", input.runId, input.index, source.id, source.generation, input.terminalEntryId ?? null, input.endedAt ?? null, input.leaf ?? null]));
169
- const cursor = this.parseCursor(input.cursor, query);
170
- if (cursor && (input.before !== undefined || input.after !== undefined))
171
- throw new HistoryIndexError("INVALID", "Use cursor or sequence, not both.");
172
- const { clauses, params, terminalSequence } = this.boundary(source, input);
173
- const metadataWhere = clauses.join(" AND "), metadataParams = params.slice();
174
- const latest = this.store.get(`SELECT start,visible_id FROM entries WHERE ${metadataWhere} AND visible_id IS NOT NULL ORDER BY start DESC LIMIT 1`, ...metadataParams);
175
- const marker = typeof input.readThrough === "string" ? this.store.get(`SELECT start,visible_id FROM entries WHERE ${metadataWhere} AND id=?`, ...metadataParams, input.readThrough.replace(/:(?:\d+|error)$/, "")) : undefined;
176
- const deliveredMessages = [];
177
- for (const id of new Set(input.messageIds ?? [])) {
178
- const human = this.store.get(`SELECT start FROM entries WHERE ${metadataWhere} AND human_id=? ORDER BY start DESC LIMIT 1`, ...metadataParams, id);
179
- if (human)
180
- deliveredMessages.push([id, Boolean(this.store.get(`SELECT rowid FROM entries WHERE ${metadataWhere} AND start>? AND assistant_text=1 LIMIT 1`, ...metadataParams, human.start))]);
181
- }
182
- const outputDigest = this.store.get("SELECT output_digest FROM children WHERE run_id=? AND child_index=?", input.runId, input.index)?.output_digest;
183
- const configuration = this.configuration(source, input);
184
- const count = Number(this.store.get(`SELECT COUNT(*) AS count FROM entries WHERE ${metadataWhere}`, ...metadataParams).count);
185
- const before = cursor ? integer(cursor.keys[0], 0) : input.before;
186
- if (before !== undefined) {
187
- clauses.push("start<?");
188
- params.push(integer(before, 0));
189
- }
190
- if (input.after !== undefined) {
191
- clauses.push("start>?");
192
- params.push(integer(input.after, 0));
193
- }
194
- const forward = input.after !== undefined;
195
- const fetched = this.store.all(`SELECT * FROM entries WHERE ${clauses.join(" AND ")} ORDER BY start ${forward ? "ASC" : "DESC"} LIMIT ?`, ...params, limit + 1);
196
- const more = fetched.length > limit, rows = fetched.slice(0, limit);
197
- if (!forward)
198
- rows.reverse();
199
- const first = rows[0], last = rows.at(-1);
200
- const finalResultId = outputDigest ? this.finalResultId(input, outputDigest, first && last ? [first.start, last.start] : undefined) : undefined;
201
- const previous = first && this.store.get(`SELECT start FROM entries WHERE ${metadataWhere} AND start<? LIMIT 1`, ...metadataParams, first.start);
202
- return { ...empty, configuration, deliveredMessages, latestEntryId: latest?.visible_id ?? null, terminalSequence,
203
- ...(input.readThrough !== undefined ? { unreadAfter: Boolean(latest && (!marker || latest.start > marker.start || latest.start === marker.start && latest.visible_id !== input.readThrough)) } : {}),
204
- ...(finalResultId ? { finalResultId } : {}), entries: rows.map((row) => this.store.entry(row)), count, hasMore: forward ? more : Boolean(previous),
205
- ...(previous && first ? { previousBefore: first.start, previousCursor: this.cursor(query, [first.start], 0) } : {}),
206
- ...(last ? { nextAfter: last.start } : {}), ...(source.error ? { unavailable: source.error } : source.state === "missing" ? { unavailable: "Linked conversation is missing." } : {}) };
29
+ return this.transcript.page(input);
207
30
  }
208
31
  search(input) {
209
- const expression = searchGrammar(input.query), limit = pageLimit(input.limit, 20), sort = input.sort ?? "relevance";
210
- if (!["relevance", "newest"].includes(sort))
211
- throw new HistoryIndexError("INVALID", "Unsupported search sort.");
212
- if (input.index !== undefined && !input.runId)
213
- throw new HistoryIndexError("INVALID", "A child search requires runId.");
214
- if (input.runId && !this.store.get("SELECT id FROM runs WHERE id=?", input.runId))
215
- throw new HistoryIndexError("OWNERSHIP", "Run is not admitted by the current owner.");
216
- if (input.index !== undefined)
217
- this.child(input.runId, input.index);
218
- if (input.runId)
219
- for (const child of this.store.all(`SELECT source_id,terminal_entry_id,ended_at FROM children WHERE run_id=?${input.index !== undefined ? " AND child_index=?" : ""}`, input.runId, ...(input.index !== undefined ? [input.index] : []))) {
220
- const source = child.source_id && this.store.source(child.source_id);
221
- if (source)
222
- this.boundary(source, { terminalEntryId: child.terminal_entry_id ?? undefined, endedAt: child.ended_at ?? undefined });
223
- }
224
- const query = hash(JSON.stringify(["search", expression, sort, input.runId ?? null, input.index ?? null, input.agent ?? null]));
225
- const cursor = this.parseCursor(input.cursor, query);
226
- const clauses = ["e.published=1", "e.generation=s.generation", "(c.terminal_entry_id IS NULL OR e.start<=terminal.start)", "(c.ended_at IS NULL OR e.timestamp<=c.ended_at)"], params = [...expression];
227
- if (input.runId) {
228
- clauses.push("c.run_id=?");
229
- params.push(input.runId);
230
- }
231
- if (input.index !== undefined) {
232
- clauses.push("c.child_index=?");
233
- params.push(input.index);
234
- }
235
- if (input.agent) {
236
- if (input.agent.length > 256)
237
- throw new HistoryIndexError("INVALID", "Agent filter is too long.");
238
- clauses.push("c.agent=?");
239
- params.push(input.agent);
240
- }
241
- const joins = "JOIN sources s ON s.id=e.source_id JOIN children c ON c.source_id=s.id LEFT JOIN entries terminal ON terminal.source_id=s.id AND terminal.generation=s.generation AND terminal.id=c.terminal_entry_id AND terminal.published=1";
242
- // Scope records before materializing/grouping hits, while bm25 still sees the
243
- // complete corpus. Scan each linked source once, not once per continuation.
244
- // Attempt boundaries, attribution and seek filtering remain in the final join.
245
- const eligible = input.runId || input.agent ? `eligible AS MATERIALIZED (SELECT e.rowid FROM entries e JOIN sources s ON s.id=e.source_id WHERE e.published=1 AND e.generation=s.generation AND e.source_id IN (SELECT c.source_id FROM children c WHERE ${clauses.slice(4).join(" AND ")})),` : "";
246
- const eligibleParams = eligible ? params.slice(expression.length) : [];
247
- // Ordering/filters apply globally before limit. Common terms may still require an FTS
248
- // scan/sort; the parent enforces a hard deadline by killing this separate process.
249
- const score = sort === "relevance" ? "matched.score" : "-COALESCE(e.timestamp,0)";
250
- if (cursor) {
251
- if (cursor.keys.length !== 4)
252
- throw new HistoryIndexError("INVALID_CURSOR", "Invalid search seek tuple.");
253
- clauses.push(`(${score},d.id,c.run_id,c.child_index)>(?,?,?,?)`);
254
- params.push(...cursor.keys);
255
- }
256
- // Match words across all visible fields/windows of one native record. A quoted
257
- // phrase remains a single FTS expression, so it cannot span unrelated fields.
258
- const rows = this.store.all(`WITH ${eligible} hits AS MATERIALIZED (
259
- ${expression.map((_term, index) => `SELECT d.id,d.entry_rowid,bm25(corpus) AS score,${index} AS term FROM corpus JOIN documents d ON d.id=corpus.rowid WHERE corpus MATCH ?${eligible ? " AND d.entry_rowid IN (SELECT rowid FROM eligible)" : ""}`).join(" UNION ALL ")}
260
- ), terms AS (
261
- SELECT entry_rowid,term,MIN(score) AS score FROM hits GROUP BY entry_rowid,term
262
- ), matched AS (
263
- SELECT entry_rowid,SUM(score) AS score FROM terms GROUP BY entry_rowid HAVING COUNT(*)=${expression.length}
264
- ), excerpts AS (
265
- SELECT id,entry_rowid,ROW_NUMBER() OVER (PARTITION BY entry_rowid ORDER BY score,id) AS choice FROM hits
266
- )
267
- SELECT d.*,${score} AS score,e.*,d.id AS document_id,s.path,s.session_id,c.run_id,c.child_index,c.agent,d.preview AS document_preview FROM matched JOIN excerpts ON excerpts.entry_rowid=matched.entry_rowid AND excerpts.choice=1 JOIN documents d ON d.id=excerpts.id JOIN entries e ON e.rowid=matched.entry_rowid ${joins} WHERE ${clauses.join(" AND ")} ORDER BY score,d.id,c.run_id,c.child_index LIMIT ?`, ...eligibleParams, ...params, limit + 1);
268
- const more = rows.length > limit, page = rows.slice(0, limit);
269
- return { ...this.info(), matches: page.map((row) => ({ id: row.document_id, runId: row.run_id, index: row.child_index, agent: row.agent, entryId: row.id, nativeId: row.native_id, sessionId: row.session_id, sessionFile: row.path, timestamp: row.timestamp,
270
- ref: { sourceId: row.source_id, generation: row.generation, start: row.start, end: row.end, digest: row.digest }, preview: row.document_preview, field: row.field, textStart: row.text_start, textEnd: row.text_end, score: row.score })),
271
- ...(more ? { nextCursor: this.cursor(query, [page.at(-1).score, page.at(-1).document_id, page.at(-1).run_id, page.at(-1).child_index], (cursor?.offset ?? 0) + page.length) } : {}) };
32
+ return this.searchQueries.search(input);
272
33
  }
273
34
  finalResultId(input, digest, preferredRange) {
274
- const { source } = this.child(input.runId, input.index);
275
- if (!source)
276
- return;
277
- const boundary = this.boundary(source, input, "e");
278
- return this.store.get(`SELECT a.item_id FROM answers a JOIN entries e ON e.rowid=a.entry_rowid WHERE a.digest=? AND ${boundary.clauses.join(" AND ")} ORDER BY ${preferredRange ? "(e.start BETWEEN ? AND ?) DESC," : ""}e.start DESC LIMIT 1`, digest, ...boundary.params, ...(preferredRange ?? []))?.item_id;
35
+ return this.scope.finalResultId(input, digest, preferredRange);
279
36
  }
280
- selected(input, full) {
281
- const { source } = this.child(input.runId, input.index);
282
- if (!source)
283
- return null;
284
- const boundary = this.boundary(source, input), where = boundary.clauses.join(" AND ");
37
+ selectedRow(input) {
38
+ const { source } = this.scope.child(input.runId, input.index);
39
+ if (!source) {
40
+ return;
41
+ }
42
+ const boundary = this.scope.boundary(source, input);
43
+ const where = boundary.clauses.join(" AND ");
285
44
  let row;
286
45
  if (input.ref) {
287
- if (input.ref.sourceId !== source.id || input.ref.generation !== source.generation)
288
- throw new HistoryIndexError("SOURCE_CHANGED", "Selected source generation changed; refresh history.");
289
- row = this.store.get(`SELECT * FROM entries WHERE ${where} AND start=? AND end=? AND digest=?`, ...boundary.params, input.ref.start, input.ref.end, input.ref.digest);
290
- if (!row)
291
- throw new HistoryIndexError("SOURCE_CHANGED", "Selected byte reference is no longer indexed.");
46
+ return this.referenceRow(input.ref, source, boundary);
47
+ }
48
+ else if (hasText(input.entryId)) {
49
+ row = this.scope.store.get(`SELECT * FROM entries WHERE ${where} AND id=?`, ...boundary.params, input.entryId);
50
+ }
51
+ else if (hasText(input.toolCallId) && ["call", "result"].includes(input.kind ?? "call")) {
52
+ const toolBoundary = this.scope.boundary(source, input, "e");
53
+ row = this.scope.store.get(`SELECT e.* FROM tools t JOIN entries e ON e.rowid=t.entry_rowid WHERE ${toolBoundary.clauses.join(" AND ")} AND t.call_id=? AND t.kind=? ORDER BY e.start DESC LIMIT 1`, ...toolBoundary.params, input.toolCallId, input.kind ?? "call");
292
54
  }
293
- else if (input.entryId)
294
- row = this.store.get(`SELECT * FROM entries WHERE ${where} AND id=?`, ...boundary.params, input.entryId);
295
- else if (input.toolCallId && ["call", "result"].includes(input.kind ?? "call"))
296
- row = this.store.get(`SELECT e.* FROM tools t JOIN entries e ON e.rowid=t.entry_rowid WHERE ${this.boundary(source, input, "e").clauses.join(" AND ")} AND t.call_id=? AND t.kind=? ORDER BY e.start DESC LIMIT 1`, ...boundary.params, input.toolCallId, input.kind ?? "call");
297
- else
55
+ else {
298
56
  throw new HistoryIndexError("INVALID", "Select an entry ID, byte reference, or tool call/result ID.");
299
- if (!row)
300
- return null;
301
- const body = validateRecord(source, row, full);
302
- return full ? body : { ...this.store.entry(row), entry: { ...compactEntry(body), id: row.id } };
57
+ }
58
+ return row ? entryRow(row) : undefined;
303
59
  }
304
- }
305
- function searchGrammar(query) {
306
- if (typeof query !== "string" || !query.trim() || query.length > 1024)
307
- throw new HistoryIndexError("INVALID_QUERY", "Search requires 1–12 tokens or one quoted phrase.");
308
- const text = query.trim(), phrase = text.startsWith('"') && text.endsWith('"');
309
- const words = (phrase ? text.slice(1, -1) : text).trim().split(/\s+/u);
310
- if (!words.length || words.length > 12 || words.some((word) => !/^[\p{L}\p{N}\p{M}]{1,64}$/u.test(word) || !phrase && ["AND", "OR", "NOT", "NEAR"].includes(word)))
311
- throw new HistoryIndexError("INVALID_QUERY", "Only lexical tokens or one quoted phrase are supported; operators, punctuation, and prefixes are not allowed.");
312
- return phrase ? [`"${words.join(" ")}"`] : [...new Set(words.map((word) => `"${word}"`))];
313
- }
314
- function validateRecord(source, row, full) {
315
- let fd;
316
- try {
317
- fd = fs.openSync(source.path, "r");
318
- const stat = fs.fstatSync(fd, { bigint: true });
319
- if (identity(stat) !== source.identity || Number(stat.size) < row.end)
320
- throw new HistoryIndexError("SOURCE_CHANGED", "Selected conversation was replaced or truncated.");
321
- const headerHash = createHash("sha256"), headerBytes = Buffer.allocUnsafe(64 * 1024);
322
- let headerPosition = 0, headerComplete = false;
323
- while (!headerComplete && headerPosition < 1024 * 1024) {
324
- const count = fs.readSync(fd, headerBytes, 0, headerBytes.length, headerPosition);
325
- if (!count)
326
- break;
327
- const newline = headerBytes.subarray(0, count).indexOf(10);
328
- const length = newline < 0 ? count : newline + 1;
329
- headerHash.update(headerBytes.subarray(0, length));
330
- headerPosition += length;
331
- headerComplete = newline >= 0;
60
+ referenceRow(ref, source, boundary) {
61
+ if (ref.sourceId !== source.id || ref.generation !== source.generation) {
62
+ throw new HistoryIndexError("SOURCE_CHANGED", "Selected source generation changed; refresh history.");
332
63
  }
333
- if (!headerComplete || headerHash.digest("hex") !== source.header_digest)
334
- throw new HistoryIndexError("SOURCE_CHANGED", "Selected native header changed or exceeds its validation budget.");
335
- if (full && row.end - row.start > 16 * 1024 * 1024)
336
- throw new HistoryIndexError("RECORD_TOO_LARGE", "Selected full record exceeds the 16 MiB detail budget; use its validated preview.");
337
- const digest = createHash("sha256"), parser = new JsonProjection(previewProjection, undefined, undefined, previewLimits), bytes = Buffer.allocUnsafe(64 * 1024), body = [];
338
- const decoder = new TextDecoder("utf8", { fatal: true });
339
- for (let position = row.start; position < row.end;) {
340
- const count = fs.readSync(fd, bytes, 0, Math.min(bytes.length, row.end - position), position);
341
- if (!count)
342
- throw new HistoryIndexError("SOURCE_CHANGED", "Selected record was truncated during validation.");
343
- const chunk = bytes.subarray(0, count);
344
- digest.update(chunk);
345
- if (full)
346
- body.push(Buffer.from(chunk));
347
- else
348
- parser.write(decoder.decode(chunk, { stream: true }));
349
- position += count;
64
+ const row = this.scope.store.get(`SELECT * FROM entries WHERE ${boundary.clauses.join(" AND ")} AND start=? AND end=? AND digest=?`, ...boundary.params, ref.start, ref.end, ref.digest);
65
+ if (!row) {
66
+ throw new HistoryIndexError("SOURCE_CHANGED", "Selected byte reference is no longer indexed.");
350
67
  }
351
- const current = fs.statSync(source.path, { bigint: true }), after = fs.fstatSync(fd, { bigint: true });
352
- if (identity(current) !== identity(stat) || current.size < BigInt(row.end) || after.ctimeNs !== stat.ctimeNs && after.size <= stat.size || digest.digest("hex") !== row.digest)
353
- throw new HistoryIndexError("SOURCE_CHANGED", "Selected record changed; refresh history before reading details.");
354
- if (full)
355
- return JSON.parse(new TextDecoder("utf8", { fatal: true }).decode(Buffer.concat(body)));
356
- parser.write(decoder.decode());
357
- return parser.finish();
68
+ return entryRow(row);
358
69
  }
359
- catch (error) {
360
- if (error.code === "ENOENT")
361
- throw new HistoryIndexError("SOURCE_CHANGED", "Selected conversation is missing.");
362
- if (error instanceof RangeError)
363
- throw new HistoryIndexError("RECORD_COMPLEXITY", "Selected preview exceeds bounded history structure budgets.");
364
- throw error;
365
- }
366
- finally {
367
- if (fd !== undefined)
368
- fs.closeSync(fd);
70
+ selected(input, full) {
71
+ const { source } = this.scope.child(input.runId, input.index);
72
+ const row = this.selectedRow(input);
73
+ if (!source || !row) {
74
+ return null;
75
+ }
76
+ const body = validateRecord(source, row, full);
77
+ return full
78
+ ? body
79
+ : { ...this.scope.store.entry(row), entry: { ...compactEntry(body), id: row.id } };
369
80
  }
370
81
  }
@@ -0,0 +1,190 @@
1
+ import { Type, Check } from "../shared/native-typebox.js";
2
+ import { HistoryIndexError, } from "./types.js";
3
+ import { hash, integer, hasText } from "./text.js";
4
+ import { number, nullableText, nullableNumber, text, } from "./rows.js";
5
+ import { parseObject } from "./values.js";
6
+ const cursorSchema = Type.Object({
7
+ generation: Type.String(),
8
+ owner: Type.String(),
9
+ version: Type.Number(),
10
+ query: Type.String(),
11
+ keys: Type.Array(Type.Union([Type.Number(), Type.String()]), { maxItems: 8 }),
12
+ offset: Type.Integer({ minimum: 0, maximum: Number.MAX_SAFE_INTEGER }),
13
+ });
14
+ function configurationValues(facts, leaf, strict) {
15
+ const count = number(facts, "count");
16
+ if (count === 0 && hasText(leaf) && strict) {
17
+ throw new HistoryIndexError("BOUNDARY_UNAVAILABLE", "Selected configuration leaf is not available in the indexed generation.");
18
+ }
19
+ if (count > 0 && number(facts, "rooted") === 0) {
20
+ if (!strict) {
21
+ return {};
22
+ }
23
+ throw new HistoryIndexError("MALFORMED_ANCESTRY", "Selected native configuration has cyclic ancestry.");
24
+ }
25
+ const model = nullableText(facts, "model");
26
+ const thinking = nullableText(facts, "thinking");
27
+ return {
28
+ ...(model === null
29
+ ? {}
30
+ : { model, modelRecordedAt: nullableNumber(facts, "recorded_at") ?? undefined }),
31
+ ...(thinking === null ? {} : { thinking }),
32
+ };
33
+ }
34
+ function configurationKey(source, input, strict) {
35
+ const terminal = hasText(input.terminalEntryId);
36
+ return JSON.stringify([
37
+ source.id,
38
+ source.generation,
39
+ source.cursor,
40
+ source.stamp,
41
+ terminal ? input.terminalEntryId : null,
42
+ terminal ? null : (input.endedAt ?? null),
43
+ input.leaf === undefined ? null : [typeof input.leaf, input.leaf],
44
+ strict,
45
+ ]);
46
+ }
47
+ export class QueryScope {
48
+ store;
49
+ info;
50
+ configurations = new Map();
51
+ constructor(store, info) {
52
+ this.store = store;
53
+ this.info = info;
54
+ }
55
+ sourcesRemoved() {
56
+ this.configurations.clear();
57
+ }
58
+ key(parts) {
59
+ return hash(JSON.stringify(parts));
60
+ }
61
+ cursor(query, keys, offset) {
62
+ return Buffer.from(JSON.stringify({
63
+ generation: this.store.generation,
64
+ owner: this.store.owner,
65
+ version: this.info().version,
66
+ query,
67
+ keys,
68
+ offset,
69
+ })).toString("base64url");
70
+ }
71
+ parseCursor(value, query) {
72
+ if (value === undefined) {
73
+ return;
74
+ }
75
+ let cursor;
76
+ try {
77
+ if (value.length > 4096) {
78
+ throw new Error("Cursor exceeds budget.");
79
+ }
80
+ const parsed = parseObject(Buffer.from(value, "base64url").toString("utf8"));
81
+ if (!Check(cursorSchema, parsed)) {
82
+ throw new Error("Invalid cursor fields.");
83
+ }
84
+ cursor = parsed;
85
+ }
86
+ catch {
87
+ throw new HistoryIndexError("INVALID_CURSOR", "Invalid history cursor.");
88
+ }
89
+ if (cursor.generation !== this.store.generation ||
90
+ cursor.owner !== this.store.owner ||
91
+ cursor.query !== query ||
92
+ cursor.version !== this.info().version) {
93
+ throw new HistoryIndexError("STALE_CURSOR", "History changed or this cursor belongs to a different query/source; restart paging.");
94
+ }
95
+ return cursor;
96
+ }
97
+ child(runId, index) {
98
+ integer(index, 0);
99
+ const child = this.store.get("SELECT * FROM children WHERE run_id=? AND child_index=?", runId, index);
100
+ if (!child) {
101
+ throw new HistoryIndexError("OWNERSHIP", "Run/child is not in the current owner's admitted handles.");
102
+ }
103
+ const sourceId = nullableText(child, "source_id");
104
+ return {
105
+ source: sourceId === null ? undefined : this.store.source(sourceId),
106
+ agent: text(child, "agent"),
107
+ };
108
+ }
109
+ boundary(source, input, alias = "") {
110
+ const column = alias.length > 0 ? `${alias}.` : "";
111
+ const clauses = [`${column}source_id=?`, `${column}generation=?`, `${column}published=1`];
112
+ const params = [source.id, source.generation];
113
+ let terminalSequence;
114
+ if (input.terminalEntryId !== undefined && input.terminalEntryId.length > 0) {
115
+ const terminal = this.store.get("SELECT start FROM entries WHERE source_id=? AND generation=? AND id=? AND published=1", source.id, source.generation, input.terminalEntryId);
116
+ if (!terminal) {
117
+ throw new HistoryIndexError("BOUNDARY_UNAVAILABLE", "Saved terminal entry is not available in the current indexed generation.");
118
+ }
119
+ terminalSequence = number(terminal, "start");
120
+ clauses.push(`${column}start<=?`);
121
+ params.push(terminalSequence);
122
+ }
123
+ else if (input.endedAt !== undefined) {
124
+ clauses.push(`${column}timestamp<=?`);
125
+ params.push(integer(input.endedAt, 0));
126
+ }
127
+ return { clauses, params, terminalSequence };
128
+ }
129
+ configurationFacts(source, input) {
130
+ const boundary = this.boundary(source, input);
131
+ const latest = this.store.get(`SELECT id FROM entries WHERE ${boundary.clauses.join(" AND ")} ORDER BY start DESC LIMIT 1`, ...boundary.params);
132
+ const leaf = input.leaf ?? (latest ? text(latest, "id") : undefined);
133
+ if (leaf === undefined || leaf.length === 0) {
134
+ return;
135
+ }
136
+ // Resolve each child's parent by its indexed ID, not a transcript rescan at every step.
137
+ const ancestry = `WITH RECURSIVE eligible AS (SELECT rowid,id,parent_id,start,timestamp,configuration_model,configuration_thinking FROM entries WHERE ${boundary.clauses.join(" AND ")}), branch AS (SELECT * FROM eligible WHERE id=? UNION SELECT parent.* FROM branch child CROSS JOIN eligible parent WHERE parent.id=child.parent_id)`;
138
+ return this.store.require(`${ancestry} SELECT
139
+ (SELECT COUNT(*) FROM branch) AS count,
140
+ EXISTS(SELECT 1 FROM branch child WHERE parent_id IS NULL OR NOT EXISTS(SELECT 1 FROM eligible parent WHERE parent.id=child.parent_id)) AS rooted,
141
+ (SELECT configuration_model FROM branch WHERE configuration_model IS NOT NULL ORDER BY start DESC LIMIT 1) AS model,
142
+ (SELECT timestamp FROM branch WHERE configuration_model IS NOT NULL ORDER BY start DESC LIMIT 1) AS recorded_at,
143
+ (SELECT configuration_thinking FROM branch WHERE configuration_thinking IS NOT NULL ORDER BY start DESC LIMIT 1) AS thinking`, ...boundary.params, leaf);
144
+ }
145
+ configuration(source, input, strict = true) {
146
+ if (input.leaf === null) {
147
+ return {};
148
+ }
149
+ try {
150
+ // Validate boundaries before reuse. Only committed source changes invalidate ancestry.
151
+ this.boundary(source, input);
152
+ const key = configurationKey(source, input, strict);
153
+ const cached = this.configurations.get(key);
154
+ if (cached) {
155
+ return { ...cached };
156
+ }
157
+ const facts = this.configurationFacts(source, input);
158
+ if (!facts) {
159
+ return {};
160
+ }
161
+ const configuration = configurationValues(facts, input.leaf, strict);
162
+ this.cacheConfiguration(key, configuration);
163
+ return { ...configuration };
164
+ }
165
+ catch (error) {
166
+ if (!strict && error instanceof HistoryIndexError && error.code === "BOUNDARY_UNAVAILABLE") {
167
+ return {};
168
+ }
169
+ throw error;
170
+ }
171
+ }
172
+ cacheConfiguration(key, configuration) {
173
+ if (this.configurations.size >= 128) {
174
+ const oldest = this.configurations.keys().next().value;
175
+ if (oldest !== undefined) {
176
+ this.configurations.delete(oldest);
177
+ }
178
+ }
179
+ this.configurations.set(key, configuration);
180
+ }
181
+ finalResultId(input, digest, preferredRange) {
182
+ const { source } = this.child(input.runId, input.index);
183
+ if (!source) {
184
+ return;
185
+ }
186
+ const boundary = this.boundary(source, input, "e");
187
+ const row = this.store.get(`SELECT a.item_id FROM answers a JOIN entries e ON e.rowid=a.entry_rowid WHERE a.digest=? AND ${boundary.clauses.join(" AND ")} ORDER BY ${preferredRange ? "(e.start BETWEEN ? AND ?) DESC," : ""}e.start DESC LIMIT 1`, digest, ...boundary.params, ...(preferredRange ?? []));
188
+ return row ? text(row, "item_id") : undefined;
189
+ }
190
+ }