@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,10 +1,30 @@
1
1
  import { EventEmitter } from "events";
2
- import net from "net";
2
+ import type net from "net";
3
3
  import { randomUUID } from "crypto";
4
- import { writeMessage, createMessageReader } from "./framing.ts";
5
- import { getBrokerSocketPath, getLegacyBrokerSocketPath, isOwnedBrokerSocket } from "./paths.ts";
6
- import { compactTopicMessage, normalizeMessage, normalizeSessionInfo } from "../types.ts";
7
- import type { SessionInfo, Message, Attachment, MessageDelivery, QueueMode, HumanMessageOrigin, TopicUpdate, TopicChange, SessionSnapshot, SendResult } from "../types.ts";
4
+ import { writeMessage } from "./framing.ts";
5
+ import { BrokerConnection, connectBrokerSocket } from "./connection.ts";
6
+ import { SnapshotReader } from "./snapshot-reader.ts";
7
+ import {
8
+ errorMessage,
9
+ isRecord,
10
+ isUnknownArray,
11
+ type UnknownRecord,
12
+ } from "../../shared/unknown.ts";
13
+ import {
14
+ compactTopicMessage,
15
+ normalizeMessage,
16
+ normalizeSessionInfo,
17
+ type SessionInfo,
18
+ type Message,
19
+ type Attachment,
20
+ type MessageDelivery,
21
+ type QueueMode,
22
+ type HumanMessageOrigin,
23
+ type TopicUpdate,
24
+ type TopicChange,
25
+ type SessionSnapshot,
26
+ type SendResult,
27
+ } from "../types.ts";
8
28
  export type { SendResult } from "../types.ts";
9
29
 
10
30
  /** Default delivery-ack timeout for `send` (broker acknowledges quickly). */
@@ -14,77 +34,60 @@ const DEFAULT_LIST_TIMEOUT_MS = 5000;
14
34
 
15
35
  export interface IntercomClientOptions {
16
36
  /** Timeout (ms) for the broker to acknowledge message delivery. */
17
- sendTimeoutMs?: number;
37
+ readonly sendTimeoutMs?: number;
18
38
  /** Timeout (ms) for a session list response. */
19
- listTimeoutMs?: number;
39
+ readonly listTimeoutMs?: number;
20
40
  }
21
41
 
22
42
  interface SendOptions {
23
- text: string;
24
- attachments?: Attachment[];
25
- replyTo?: string;
26
- expectsReply?: boolean;
27
- delivery?: MessageDelivery;
28
- queueMode?: QueueMode;
29
- threadId?: string;
30
- passive?: boolean;
31
- messageId?: string;
32
- human?: HumanMessageOrigin;
33
- topic?: TopicUpdate;
43
+ readonly text: string;
44
+ readonly attachments?: readonly Attachment[];
45
+ readonly replyTo?: string;
46
+ readonly expectsReply?: boolean;
47
+ readonly delivery?: MessageDelivery;
48
+ readonly queueMode?: QueueMode;
49
+ readonly threadId?: string;
50
+ readonly passive?: boolean;
51
+ readonly messageId?: string;
52
+ readonly human?: HumanMessageOrigin;
53
+ readonly topic?: TopicUpdate;
34
54
  }
35
55
 
36
56
  function toError(error: unknown): Error {
37
- return error instanceof Error ? error : new Error(String(error));
57
+ return error instanceof Error ? error : new Error(errorMessage(error));
38
58
  }
39
59
 
40
- function connectSocket(socketPath: string, timeoutMs = 500): Promise<net.Socket> {
41
- return new Promise((resolve, reject) => {
42
- const socket = net.connect(socketPath);
43
- const finish = (error?: Error) => {
44
- clearTimeout(timeout);
45
- socket.off("connect", onConnect);
46
- socket.off("error", onError);
47
- if (error) {
48
- socket.destroy();
49
- reject(error);
50
- } else {
51
- resolve(socket);
52
- }
53
- };
54
- const onConnect = () => finish();
55
- const onError = (error: Error) => finish(error);
56
- socket.once("connect", onConnect);
57
- socket.once("error", onError);
58
- const timeout = setTimeout(() => finish(new Error(`Connection timeout: ${socketPath}`)), timeoutMs);
59
- timeout.unref?.();
60
- });
61
- }
62
-
63
- async function connectBrokerSocket(): Promise<net.Socket> {
64
- const preferred = getBrokerSocketPath();
65
- const legacy = getLegacyBrokerSocketPath();
66
- const candidates = [preferred, ...(legacy !== preferred ? [legacy] : [])];
67
- let lastError: Error | undefined;
68
- for (const candidate of candidates) {
69
- if (!isOwnedBrokerSocket(candidate)) continue;
70
- try {
71
- return await connectSocket(candidate);
72
- } catch (error) {
73
- lastError = toError(error);
74
- }
60
+ function messageDelivery(options: SendOptions): MessageDelivery | undefined {
61
+ if (options.delivery !== undefined) {
62
+ return options.delivery;
63
+ }
64
+ if (options.passive === true) {
65
+ return "passive";
75
66
  }
76
- throw lastError ?? new Error(`Intercom broker socket is unavailable: ${preferred}`);
67
+ if (options.expectsReply === true) {
68
+ return;
69
+ }
70
+ return "steer";
77
71
  }
78
72
 
79
73
  export class IntercomClient extends EventEmitter {
80
- private socket: net.Socket | null = null;
74
+ private connection: BrokerConnection | null = null;
81
75
  private _sessionId: string | null = null;
82
76
  private _topicsSupported = false;
83
- private pendingSends = new Map<string, { resolve: (r: SendResult) => void; reject: (e: Error) => void }>();
84
- private pendingLists = new Map<string, { resolve: (snapshot: SessionSnapshot) => void; reject: (e: Error) => void; sessions: Map<string, SessionInfo>; receipts: SessionSnapshot["receipts"] }>();
77
+ private readonly pendingSends = new Map<
78
+ string,
79
+ { readonly resolve: (r: SendResult) => void; readonly reject: (e: Readonly<Error>) => void }
80
+ >();
81
+ private readonly pendingLists = new Map<
82
+ string,
83
+ {
84
+ readonly resolve: (snapshot: SessionSnapshot) => void;
85
+ readonly reject: (e: Readonly<Error>) => void;
86
+ readonly reader: SnapshotReader;
87
+ }
88
+ >();
85
89
  private connecting = false;
86
90
  private disconnecting = false;
87
- private disconnectError: Error | null = null;
88
91
  private readonly sendTimeoutMs: number;
89
92
  private readonly listTimeoutMs: number;
90
93
 
@@ -94,7 +97,7 @@ export class IntercomClient extends EventEmitter {
94
97
  this.listTimeoutMs = options.listTimeoutMs ?? DEFAULT_LIST_TIMEOUT_MS;
95
98
  }
96
99
 
97
- private failPending(error: Error): void {
100
+ private failPending(error: Readonly<Error>): void {
98
101
  for (const pending of this.pendingSends.values()) {
99
102
  pending.reject(error);
100
103
  }
@@ -109,347 +112,233 @@ export class IntercomClient extends EventEmitter {
109
112
  return this._sessionId;
110
113
  }
111
114
 
112
- get supportsTopics(): boolean { return this.isConnected() && this._topicsSupported; }
115
+ get supportsTopics(): boolean {
116
+ return this.isConnected() && this._topicsSupported;
117
+ }
113
118
  isConnected(): boolean {
114
- const socket = this.socket;
115
- return Boolean(socket && this._sessionId && !this.disconnecting && !socket.destroyed && !socket.writableEnded && socket.writable);
119
+ return (
120
+ (this._sessionId ?? "").length > 0 &&
121
+ !this.disconnecting &&
122
+ this.connection?.isActive() === true
123
+ );
116
124
  }
117
125
 
118
126
  private requireActiveSocket(): net.Socket {
119
127
  if (this.disconnecting) {
120
128
  throw new Error("Client disconnecting");
121
129
  }
122
-
123
- const socket = this.socket;
124
- if (!socket || !this._sessionId) {
130
+ const connection = this.connection;
131
+ if (!connection || (this._sessionId ?? "").length === 0) {
125
132
  throw new Error("Not connected");
126
133
  }
127
-
128
- if (socket.destroyed || socket.writableEnded || !socket.writable) {
134
+ if (!connection.isActive()) {
129
135
  throw new Error("Client disconnected");
130
136
  }
131
-
132
- return socket;
137
+ return connection.socket;
133
138
  }
134
139
 
135
140
  async connect(session: Omit<SessionInfo, "id">, requestedId?: string): Promise<void> {
136
- if (this.socket || this.connecting) {
141
+ if (this.connection || this.connecting) {
137
142
  throw new Error("Already connected");
138
143
  }
139
-
140
144
  this.connecting = true;
141
- let socket: net.Socket;
142
145
  try {
143
- socket = await connectBrokerSocket();
144
- } finally {
145
- this.connecting = false;
146
- }
147
- const { topics, subscriptions, ...identity } = session;
148
- await new Promise<void>((resolve, reject) => {
149
- this.socket = socket;
150
- this.disconnectError = null;
151
- let settled = false;
152
- const timeout = setTimeout(() => {
153
- if (!this._sessionId) {
154
- cleanupConnectionAttempt();
155
- cleanupSocketListeners();
156
- if (this.socket === socket) {
157
- this.socket = null;
146
+ const socket = await connectBrokerSocket();
147
+ const connection = new BrokerConnection(socket, {
148
+ message: (message) => this.handleBrokerMessage(message),
149
+ error: (error) => {
150
+ this.emit("error", error);
151
+ },
152
+ closed: (error, expected) => {
153
+ if (this.connection !== connection) {
154
+ return;
158
155
  }
159
- socket.destroy();
160
- reject(new Error("Connection timeout"));
161
- }
162
- }, 10000);
163
- timeout.unref?.();
164
-
165
- let connectionEstablished = false;
166
-
167
- const onRegistered = () => {
168
- settled = true;
169
- connectionEstablished = true;
170
- cleanupConnectionAttempt();
171
- resolve();
172
- };
173
-
174
- const onError = (err: Error) => {
175
- settled = true;
176
- cleanupConnectionAttempt();
177
- cleanupSocketListeners();
178
- if (this.socket === socket) {
179
- this.socket = null;
180
- }
181
- socket.destroy();
182
- reject(err);
183
- };
184
-
185
- const onClose = () => {
186
- const wasConnecting = !settled && !this._sessionId;
187
- const wasDisconnecting = this.disconnecting;
188
- const disconnectError = this.disconnectError ?? new Error("Client disconnected");
189
- this.disconnecting = false;
190
- cleanupConnectionAttempt();
191
- cleanupSocketListeners();
192
- this.failPending(disconnectError);
193
- if (this.socket === socket) {
194
- this.socket = null;
195
- }
196
- this._sessionId = null;
197
- this.disconnectError = null;
198
- if (connectionEstablished && !wasDisconnecting) {
199
- this.emit("disconnected", disconnectError);
200
- }
201
- if (wasConnecting) {
202
- reject(new Error("Connection closed before registration"));
203
- }
204
- };
205
-
206
- const onSocketError = (err: Error) => {
207
- if (connectionEstablished) {
208
- this.disconnectError = err;
209
- this.emit("error", err);
210
- }
211
- };
212
-
213
- const onReaderError = (error: Error) => {
214
- const protocolError = new Error(`Intercom protocol error: ${error.message}`, { cause: error });
215
- if (!connectionEstablished) {
216
- onError(protocolError);
217
- return;
218
- }
219
- this.disconnectError = protocolError;
220
- this.emit("error", protocolError);
221
- socket.destroy();
222
- };
223
-
224
- const reader = createMessageReader((msg) => {
225
- this.handleBrokerMessage(msg);
226
- }, onReaderError);
227
-
228
- const cleanupConnectionAttempt = () => {
229
- this.off("_registered", onRegistered);
230
- socket.off("error", onError);
231
- clearTimeout(timeout);
232
- };
233
-
234
- const cleanupSocketListeners = () => {
235
- socket.off("data", reader);
236
- socket.off("error", onSocketError);
237
- socket.off("close", onClose);
238
- };
239
-
240
- socket.on("data", reader);
241
- socket.on("error", onError);
242
- socket.on("close", onClose);
243
-
244
- socket.on("error", onSocketError);
245
- this.once("_registered", onRegistered);
246
-
156
+ const established = this._sessionId !== null;
157
+ this.connection = null;
158
+ this._sessionId = null;
159
+ this._topicsSupported = false;
160
+ this.disconnecting = false;
161
+ this.failPending(error);
162
+ if (established && !expected) {
163
+ this.emit("disconnected", error);
164
+ }
165
+ },
166
+ });
167
+ this.connection = connection;
168
+ const { topics, subscriptions, ...identity } = session;
247
169
  try {
248
- writeMessage(socket, { type: "register", session: identity, requestedId, topicFrames: true });
170
+ await connection.start({
171
+ type: "register",
172
+ session: identity,
173
+ requestedId,
174
+ topicFrames: true,
175
+ });
249
176
  } catch (error) {
250
- cleanupConnectionAttempt();
251
- cleanupSocketListeners();
252
- if (this.socket === socket) {
253
- this.socket = null;
177
+ if (this.connection === connection) {
178
+ this.connection = null;
254
179
  }
255
- socket.destroy();
256
- reject(toError(error));
180
+ throw error;
257
181
  }
258
- });
259
- if (this.supportsTopics) {
260
- for (const topic of topics ?? []) await this.updateTopics({ action: "restore", topic });
261
- for (const subscription of subscriptions ?? []) await this.updateTopics({ action: "restore", subscription });
182
+ if (this.supportsTopics) {
183
+ await this.restoreTopics(topics, subscriptions);
184
+ }
185
+ } finally {
186
+ this.connecting = false;
187
+ }
188
+ }
189
+
190
+ private async restoreTopics(
191
+ topics: SessionInfo["topics"],
192
+ subscriptions: SessionInfo["subscriptions"],
193
+ ): Promise<void> {
194
+ for (const topic of topics ?? []) {
195
+ // Restore frames are individually acknowledged to preserve order and bound socket payloads.
196
+ // oxlint-disable-next-line no-await-in-loop
197
+ await this.updateTopics({ action: "restore", topic });
198
+ }
199
+ for (const subscription of subscriptions ?? []) {
200
+ // Subscriptions are committed before connect resolves and subsequent messages can arrive.
201
+ // oxlint-disable-next-line no-await-in-loop
202
+ await this.updateTopics({ action: "restore", subscription });
262
203
  }
263
204
  }
264
205
 
265
206
  private handleBrokerMessage(msg: unknown): void {
266
- if (typeof msg !== "object" || msg === null || !("type" in msg) || typeof msg.type !== "string") {
207
+ if (!isRecord(msg) || typeof msg.type !== "string") {
267
208
  throw new Error("Invalid broker message");
268
209
  }
269
210
 
270
- const brokerMessage = msg as { type: string } & Record<string, unknown>;
211
+ const brokerMessage = msg;
212
+ const type = msg.type;
271
213
 
272
- if (this._sessionId === null && brokerMessage.type !== "registered") {
273
- throw new Error(`Received ${brokerMessage.type} before registered`);
214
+ if (this._sessionId === null && type !== "registered") {
215
+ throw new Error(`Received ${type} before registered`);
274
216
  }
275
217
 
276
- switch (brokerMessage.type) {
277
- case "registered": {
278
- if (typeof brokerMessage.sessionId !== "string") {
279
- throw new Error("Invalid registered message");
280
- }
281
-
282
- if (this._sessionId !== null) {
283
- throw new Error("Received duplicate registered message");
284
- }
285
-
286
- this._sessionId = brokerMessage.sessionId;
287
- this._topicsSupported = brokerMessage.topicsSupported === true && brokerMessage.topicFrames === true;
288
- this.emit("_registered", { type: "registered", sessionId: brokerMessage.sessionId });
289
- break;
290
- }
291
-
292
- case "sessions": {
293
- const { requestId, sessions, receipts, more, error } = brokerMessage;
294
- if (typeof requestId !== "string" || !Array.isArray(sessions) || (more !== undefined && typeof more !== "boolean")) throw new Error("Invalid sessions message");
295
- const pending = this.pendingLists.get(requestId);
296
- if (!pending) return;
297
- if (typeof error === "string") {
298
- this.pendingLists.delete(requestId);
299
- pending.reject(new Error(error));
300
- break;
301
- }
302
- for (const row of sessions) {
303
- if (!row || typeof row.id !== "string" || (row.topics !== undefined && !Array.isArray(row.topics)) || (row.subscriptions !== undefined && !Array.isArray(row.subscriptions))) throw new Error("Invalid session snapshot row");
304
- const previous = pending.sessions.get(row.id);
305
- const info = normalizeSessionInfo({ ...previous, ...row,
306
- ...(row.topics ? { topics: [...(previous?.topics ?? []), ...row.topics] } : {}),
307
- ...(row.subscriptions ? { subscriptions: [...(previous?.subscriptions ?? []), ...row.subscriptions] } : {}),
308
- });
309
- if (!info) throw new Error("Invalid session snapshot");
310
- pending.sessions.set(info.id, info);
311
- }
312
- if (receipts !== undefined) {
313
- if (!Array.isArray(receipts) || receipts.some((receipt) => !receipt || typeof receipt.to !== "string" || typeof receipt.id !== "string" || typeof receipt.accepted !== "boolean" || typeof receipt.delivered !== "boolean")) throw new Error("Invalid topic delivery receipts");
314
- pending.receipts.push(...receipts);
315
- }
316
- if (more !== true) {
317
- this.pendingLists.delete(requestId);
318
- pending.resolve({ sessions: [...pending.sessions.values()], receipts: pending.receipts });
319
- }
320
- break;
321
- }
322
-
323
- case "message": {
324
- const { from } = brokerMessage;
325
- const message = normalizeMessage(brokerMessage.message);
326
- const normalizedFrom = normalizeSessionInfo(from);
327
- if (!normalizedFrom || !message) {
328
- throw new Error("Invalid message event");
329
- }
330
-
331
- this.emit("message", normalizedFrom, message);
218
+ switch (type) {
219
+ case "registered":
220
+ this.receiveRegistration(brokerMessage);
332
221
  break;
333
- }
334
-
335
- case "delivered": {
336
- const { messageId } = brokerMessage;
337
- if (typeof messageId !== "string") {
338
- throw new Error("Invalid delivered message");
339
- }
340
-
341
- const pending = this.pendingSends.get(messageId);
342
- if (!pending) {
343
- // Late send responses are harmless once the caller has already timed out.
344
- return;
345
- }
346
-
347
- this.pendingSends.delete(messageId);
348
- pending.resolve({ id: messageId, accepted: true, delivered: true });
222
+ case "sessions":
223
+ this.receiveSessions(brokerMessage);
349
224
  break;
350
- }
351
-
352
- case "delivery_queued": {
353
- const { messageId, reason } = brokerMessage;
354
- if (typeof messageId !== "string" || typeof reason !== "string") {
355
- throw new Error("Invalid delivery_queued message");
356
- }
357
-
358
- const pending = this.pendingSends.get(messageId);
359
- if (!pending) {
360
- // Late send responses are harmless once the caller has already timed out.
361
- return;
362
- }
363
-
364
- this.pendingSends.delete(messageId);
365
- pending.resolve({ id: messageId, accepted: true, delivered: false, queued: true, reason });
225
+ case "message":
226
+ this.receiveMessage(brokerMessage);
366
227
  break;
367
- }
368
-
369
- case "delivery_failed": {
370
- const { messageId, reason } = brokerMessage;
371
- if (typeof messageId !== "string" || typeof reason !== "string") {
372
- throw new Error("Invalid delivery_failed message");
373
- }
374
-
375
- const pending = this.pendingSends.get(messageId);
376
- if (!pending) {
377
- // Late send responses are harmless once the caller has already timed out.
378
- return;
379
- }
380
-
381
- this.pendingSends.delete(messageId);
382
- pending.resolve({ id: messageId, accepted: false, delivered: false, reason });
228
+ case "delivered":
229
+ case "delivery_queued":
230
+ case "delivery_failed":
231
+ this.receiveDelivery(brokerMessage);
383
232
  break;
384
- }
385
-
386
- case "session_left": {
233
+ case "session_left":
387
234
  if (typeof brokerMessage.sessionId !== "string") {
388
235
  throw new Error("Invalid session_left message");
389
236
  }
390
-
391
237
  this.emit("session_left", brokerMessage.sessionId);
392
238
  break;
393
- }
394
-
395
239
  default:
396
- throw new Error(`Unknown broker message type: ${brokerMessage.type}`);
240
+ throw new Error(`Unknown broker message type: ${type}`);
397
241
  }
398
242
  }
399
243
 
400
- async disconnect(): Promise<void> {
401
- const socket = this.socket;
402
- if (!socket) {
403
- return;
244
+ private receiveRegistration(msg: UnknownRecord): void {
245
+ if (typeof msg.sessionId !== "string") {
246
+ throw new Error("Invalid registered message");
404
247
  }
248
+ if (this._sessionId !== null) {
249
+ throw new Error("Received duplicate registered message");
250
+ }
251
+ this._sessionId = msg.sessionId;
252
+ this._topicsSupported = msg.topicsSupported === true && msg.topicFrames === true;
253
+ this.connection?.confirmRegistration();
254
+ this.emit("_registered", { type: "registered", sessionId: msg.sessionId });
255
+ }
405
256
 
406
- this.disconnecting = true;
407
- this.disconnectError = null;
408
- this.failPending(new Error("Client disconnected"));
257
+ private receiveMessage(msg: UnknownRecord): void {
258
+ const message = normalizeMessage(msg.message);
259
+ const from = normalizeSessionInfo(msg.from);
260
+ if (!from || !message) {
261
+ throw new Error("Invalid message event");
262
+ }
263
+ this.emit("message", from, message);
264
+ }
409
265
 
410
- await new Promise<void>((resolve) => {
411
- let settled = false;
412
- const finish = () => {
413
- if (settled) {
414
- return;
415
- }
416
- settled = true;
417
- clearTimeout(timeout);
418
- socket.off("close", onClose);
419
- socket.off("error", onError);
420
- resolve();
421
- };
422
- const onClose = () => finish();
423
- const onError = () => {
424
- socket.destroy();
425
- };
426
- const timeout = setTimeout(() => {
427
- socket.destroy();
428
- }, 2000);
266
+ private receiveDelivery(msg: UnknownRecord): void {
267
+ const { messageId, reason, type } = msg;
268
+ if (typeof messageId !== "string") {
269
+ throw new Error(`Invalid ${errorMessage(type)} message`);
270
+ }
271
+ if (type !== "delivered" && typeof reason !== "string") {
272
+ throw new Error(`Invalid ${errorMessage(type)} message`);
273
+ }
274
+ const pending = this.pendingSends.get(messageId);
275
+ // Late responses are harmless after the caller has timed out.
276
+ if (!pending) {
277
+ return;
278
+ }
279
+ this.pendingSends.delete(messageId);
280
+ pending.resolve({
281
+ id: messageId,
282
+ accepted: type !== "delivery_failed",
283
+ delivered: type === "delivered",
284
+ ...(type === "delivery_queued" ? { queued: true } : {}),
285
+ ...(typeof reason === "string" && type !== "delivered" ? { reason } : {}),
286
+ });
287
+ }
429
288
 
430
- socket.once("close", onClose);
431
- socket.once("error", onError);
289
+ private receiveSessions(brokerMessage: UnknownRecord): void {
290
+ const { requestId, sessions, receipts, more, error } = brokerMessage;
291
+ if (
292
+ typeof requestId !== "string" ||
293
+ !isUnknownArray(sessions) ||
294
+ (more !== undefined && typeof more !== "boolean")
295
+ ) {
296
+ throw new Error("Invalid sessions message");
297
+ }
298
+ const pending = this.pendingLists.get(requestId);
299
+ if (!pending) {
300
+ return;
301
+ }
302
+ if (typeof error === "string") {
303
+ this.pendingLists.delete(requestId);
304
+ pending.reject(new Error(error));
305
+ return;
306
+ }
307
+ pending.reader.append(sessions, receipts);
308
+ if (more !== true) {
309
+ this.pendingLists.delete(requestId);
310
+ pending.resolve(pending.reader.finish());
311
+ }
312
+ }
432
313
 
433
- try {
434
- writeMessage(socket, { type: "unregister" });
435
- socket.end();
436
- } catch {
437
- // Disconnect should still finish even if the unregister write fails.
438
- socket.destroy();
439
- }
440
- });
314
+ async disconnect(): Promise<void> {
315
+ const connection = this.connection;
316
+ if (!connection) {
317
+ return;
318
+ }
319
+ this.disconnecting = true;
320
+ this.failPending(new Error("Client disconnected"));
321
+ await connection.disconnect();
441
322
  }
442
323
 
443
324
  listSessions(): Promise<SessionInfo[]> {
444
- return this.requestSessions().then((snapshot) => snapshot.sessions);
325
+ return this.requestSessions().then((snapshot) => [...snapshot.sessions]);
445
326
  }
446
327
 
447
- updateTopics(change: TopicChange, onAccepted?: (snapshot: SessionSnapshot) => void): Promise<SessionSnapshot> {
448
- if (!this.supportsTopics) return Promise.reject(new Error("This broker does not support topic snapshots."));
328
+ updateTopics(
329
+ change: TopicChange,
330
+ onAccepted?: (snapshot: SessionSnapshot) => void,
331
+ ): Promise<SessionSnapshot> {
332
+ if (!this.supportsTopics) {
333
+ return Promise.reject(new Error("This broker does not support topic snapshots."));
334
+ }
449
335
  return this.requestSessions(change, onAccepted);
450
336
  }
451
337
 
452
- private requestSessions(change?: TopicChange, onAccepted?: (snapshot: SessionSnapshot) => void): Promise<SessionSnapshot> {
338
+ private requestSessions(
339
+ change?: TopicChange,
340
+ onAccepted?: (snapshot: SessionSnapshot) => void,
341
+ ): Promise<SessionSnapshot> {
453
342
  let socket: net.Socket;
454
343
  try {
455
344
  socket = this.requireActiveSocket();
@@ -465,9 +354,11 @@ export class IntercomClient extends EventEmitter {
465
354
  // Commit confirmed subscriptions before handling a following message in the same read.
466
355
  onAccepted?.(snapshot);
467
356
  resolve(snapshot);
468
- } catch (error) { reject(toError(error)); }
357
+ } catch (error) {
358
+ reject(toError(error));
359
+ }
469
360
  };
470
- const wrappedReject = (error: Error) => {
361
+ const wrappedReject = (error: Readonly<Error>) => {
471
362
  clearTimeout(timeout);
472
363
  reject(error);
473
364
  };
@@ -477,10 +368,19 @@ export class IntercomClient extends EventEmitter {
477
368
  wrappedReject(new Error("List sessions timeout"));
478
369
  }
479
370
  }, this.listTimeoutMs);
480
- timeout.unref?.();
481
- this.pendingLists.set(requestId, { resolve: wrappedResolve, reject: wrappedReject, sessions: new Map(), receipts: [] });
371
+ timeout.unref();
372
+ this.pendingLists.set(requestId, {
373
+ resolve: wrappedResolve,
374
+ reject: wrappedReject,
375
+ reader: new SnapshotReader(),
376
+ });
482
377
  try {
483
- writeMessage(socket, { type: "list", requestId, stream: true, ...(change ? { change } : {}) });
378
+ writeMessage(socket, {
379
+ type: "list",
380
+ requestId,
381
+ stream: true,
382
+ ...(change ? { change } : {}),
383
+ });
484
384
  } catch (error) {
485
385
  clearTimeout(timeout);
486
386
  this.pendingLists.delete(requestId);
@@ -505,7 +405,7 @@ export class IntercomClient extends EventEmitter {
505
405
  expectsReply: options.expectsReply,
506
406
  ...(options.human ? { human: options.human } : {}),
507
407
  ...(options.topic ? { topic: options.topic } : {}),
508
- delivery: options.delivery ?? (options.passive === true ? "passive" : options.expectsReply === true ? undefined : "steer"),
408
+ delivery: messageDelivery(options),
509
409
  queueMode: options.queueMode,
510
410
  threadId: options.threadId,
511
411
  passive: options.passive,
@@ -520,7 +420,7 @@ export class IntercomClient extends EventEmitter {
520
420
  clearTimeout(timeout);
521
421
  resolve(result);
522
422
  };
523
- const wrappedReject = (error: Error) => {
423
+ const wrappedReject = (error: Readonly<Error>) => {
524
424
  clearTimeout(timeout);
525
425
  reject(error);
526
426
  };
@@ -530,11 +430,15 @@ export class IntercomClient extends EventEmitter {
530
430
  wrappedReject(new Error("Send timeout"));
531
431
  }
532
432
  }, this.sendTimeoutMs);
533
- timeout.unref?.();
433
+ timeout.unref();
534
434
  this.pendingSends.set(messageId, { resolve: wrappedResolve, reject: wrappedReject });
535
435
 
536
436
  try {
537
- writeMessage(socket, { type: "send", to, message: this._topicsSupported ? compactTopicMessage(message) : message });
437
+ writeMessage(socket, {
438
+ type: "send",
439
+ to,
440
+ message: this._topicsSupported ? compactTopicMessage(message) : message,
441
+ });
538
442
  } catch (error) {
539
443
  clearTimeout(timeout);
540
444
  this.pendingSends.delete(messageId);
@@ -543,13 +447,28 @@ export class IntercomClient extends EventEmitter {
543
447
  });
544
448
  }
545
449
 
546
- updatePresence(updates: { name?: string; status?: string; model?: string; pendingAsks?: number; acceptsAsks?: boolean; lastIntercomActivity?: number; subscriptions?: SessionInfo["subscriptions"]; topics?: TopicUpdate[] }): void {
450
+ updatePresence(updates: {
451
+ readonly name?: string;
452
+ readonly status?: string;
453
+ readonly model?: string;
454
+ readonly pendingAsks?: number;
455
+ readonly acceptsAsks?: boolean;
456
+ readonly lastIntercomActivity?: number;
457
+ readonly subscriptions?: SessionInfo["subscriptions"];
458
+ readonly topics?: readonly TopicUpdate[];
459
+ }): void {
547
460
  if (this.disconnecting) {
548
461
  return;
549
462
  }
550
463
 
551
- const socket = this.socket;
552
- if (!socket || !this._sessionId || socket.destroyed || socket.writableEnded || !socket.writable) {
464
+ const socket = this.connection?.socket;
465
+ if (
466
+ !socket ||
467
+ (this._sessionId ?? "").length === 0 ||
468
+ socket.destroyed ||
469
+ socket.writableEnded ||
470
+ !socket.writable
471
+ ) {
553
472
  return;
554
473
  }
555
474