@fitchmultz/pi-subagents 0.44.7 → 0.45.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 (947) hide show
  1. package/CHANGELOG.md +258 -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 +79 -0
  111. package/dist/pi-intercom/bridge-http.js +86 -0
  112. package/dist/pi-intercom/bridge-protocol.js +106 -0
  113. package/dist/pi-intercom/bridge-routes.js +64 -0
  114. package/dist/pi-intercom/bridge-session.js +416 -0
  115. package/dist/pi-intercom/bridge.js +182 -603
  116. package/dist/pi-intercom/broker/broker.js +236 -244
  117. package/dist/pi-intercom/broker/client.js +189 -304
  118. package/dist/pi-intercom/broker/connection.js +165 -0
  119. package/dist/pi-intercom/broker/framing.js +5 -3
  120. package/dist/pi-intercom/broker/paths.js +4 -1
  121. package/dist/pi-intercom/broker/pid.js +53 -25
  122. package/dist/pi-intercom/broker/snapshot-reader.js +78 -0
  123. package/dist/pi-intercom/broker/snapshots.js +188 -0
  124. package/dist/pi-intercom/broker/spawn.js +36 -25
  125. package/dist/pi-intercom/config.js +85 -71
  126. package/dist/pi-intercom/connection.js +297 -0
  127. package/dist/pi-intercom/identity.js +58 -0
  128. package/dist/pi-intercom/inbound-delivery.js +356 -0
  129. package/dist/pi-intercom/inbound-journal.js +303 -0
  130. package/dist/pi-intercom/inbound-record.js +113 -0
  131. package/dist/pi-intercom/inbound.js +179 -0
  132. package/dist/pi-intercom/index.js +79 -2933
  133. package/dist/pi-intercom/inspection.js +62 -0
  134. package/dist/pi-intercom/interview.js +236 -0
  135. package/dist/pi-intercom/lifecycle.js +168 -0
  136. package/dist/pi-intercom/message-format.js +69 -0
  137. package/dist/pi-intercom/outbound.js +304 -0
  138. package/dist/pi-intercom/peer-awareness.js +66 -0
  139. package/dist/pi-intercom/reply-tracker.js +62 -43
  140. package/dist/pi-intercom/reply-wait.js +201 -0
  141. package/dist/pi-intercom/runtime-types.js +3 -0
  142. package/dist/pi-intercom/session-events.js +180 -0
  143. package/dist/pi-intercom/session-targets.js +42 -34
  144. package/dist/pi-intercom/subagent-events.js +238 -0
  145. package/dist/pi-intercom/subagent-live-events.js +129 -86
  146. package/dist/pi-intercom/supervisor.js +282 -0
  147. package/dist/pi-intercom/tool-arguments.js +74 -0
  148. package/dist/pi-intercom/tool-registration.js +95 -0
  149. package/dist/pi-intercom/tool-results.js +38 -0
  150. package/dist/pi-intercom/tool-schemas.js +82 -0
  151. package/dist/pi-intercom/tools.js +51 -0
  152. package/dist/pi-intercom/topic-actions.js +177 -0
  153. package/dist/pi-intercom/topics.js +177 -92
  154. package/dist/pi-intercom/transport.js +1 -0
  155. package/dist/pi-intercom/types.js +151 -114
  156. package/dist/pi-intercom/ui/compose-paste.js +93 -0
  157. package/dist/pi-intercom/ui/compose.js +121 -143
  158. package/dist/pi-intercom/ui/inline-message.js +59 -59
  159. package/dist/pi-intercom/ui/message-renderers.js +147 -0
  160. package/dist/pi-intercom/ui/overlay.js +181 -0
  161. package/dist/pi-intercom/ui/session-format.js +124 -0
  162. package/dist/pi-intercom/ui/session-list.js +76 -43
  163. package/dist/pi-intercom/ui/tool-renderers.js +110 -0
  164. package/dist/pi-intercom/ui/topic-view.js +88 -0
  165. package/dist/pi-intercom/validation.js +59 -0
  166. package/dist/runs/background/async-chain-plan.js +265 -0
  167. package/dist/runs/background/async-control.js +134 -58
  168. package/dist/runs/background/async-execution.js +136 -633
  169. package/dist/runs/background/async-job-admission.js +40 -0
  170. package/dist/runs/background/async-job-projection.js +169 -0
  171. package/dist/runs/background/async-job-tracker.js +297 -327
  172. package/dist/runs/background/async-launch.js +216 -0
  173. package/dist/runs/background/async-plan.js +116 -0
  174. package/dist/runs/background/async-result-file.js +47 -23
  175. package/dist/runs/background/async-resume.js +195 -253
  176. package/dist/runs/background/async-run-discovery.js +213 -0
  177. package/dist/runs/background/async-run-location.js +135 -0
  178. package/dist/runs/background/async-run-record.js +1 -0
  179. package/dist/runs/background/async-run-repair.js +223 -0
  180. package/dist/runs/background/async-run-summary.js +1 -0
  181. package/dist/runs/background/async-single-plan.js +105 -0
  182. package/dist/runs/background/async-status-projection.js +155 -0
  183. package/dist/runs/background/async-status-render.js +117 -0
  184. package/dist/runs/background/async-status-validation.js +181 -0
  185. package/dist/runs/background/async-status.js +3 -442
  186. package/dist/runs/background/async-value.js +21 -0
  187. package/dist/runs/background/completion-dedupe.js +36 -12
  188. package/dist/runs/background/completion-delivery.js +211 -205
  189. package/dist/runs/background/completion-receipts.js +237 -0
  190. package/dist/runs/background/legacy-status-acceptance.js +34 -0
  191. package/dist/runs/background/notify.js +96 -48
  192. package/dist/runs/background/parallel-groups.js +36 -19
  193. package/dist/runs/background/result-payload.js +178 -0
  194. package/dist/runs/background/result-watcher.js +348 -339
  195. package/dist/runs/background/run-id-resolver.js +53 -33
  196. package/dist/runs/background/run-schemas.js +189 -0
  197. package/dist/runs/background/run-status-contracts.js +14 -0
  198. package/dist/runs/background/run-status-render.js +270 -0
  199. package/dist/runs/background/run-status.js +231 -339
  200. package/dist/runs/background/runner-attempt-output.js +155 -0
  201. package/dist/runs/background/runner-attempt.js +263 -0
  202. package/dist/runs/background/runner-child-executor.js +166 -0
  203. package/dist/runs/background/runner-child-observer.js +192 -0
  204. package/dist/runs/background/runner-completion-summary.js +71 -0
  205. package/dist/runs/background/runner-completion.js +211 -0
  206. package/dist/runs/background/runner-config.js +1 -0
  207. package/dist/runs/background/runner-contract.js +1 -0
  208. package/dist/runs/background/runner-dynamic.js +121 -0
  209. package/dist/runs/background/runner-finalization.js +149 -0
  210. package/dist/runs/background/runner-graph.js +68 -0
  211. package/dist/runs/background/runner-initial-status.js +60 -0
  212. package/dist/runs/background/runner-lifecycle.js +142 -0
  213. package/dist/runs/background/runner-monitor.js +309 -0
  214. package/dist/runs/background/runner-parallel.js +204 -0
  215. package/dist/runs/background/runner-prepare-step.js +86 -0
  216. package/dist/runs/background/runner-reporting.js +153 -0
  217. package/dist/runs/background/runner-status.js +148 -0
  218. package/dist/runs/background/runner-step-output.js +92 -0
  219. package/dist/runs/background/runner-step-record.js +45 -0
  220. package/dist/runs/background/runner-step.js +112 -0
  221. package/dist/runs/background/runner-streaming.js +173 -0
  222. package/dist/runs/background/runner-workflow.js +213 -0
  223. package/dist/runs/background/stale-run-reconciler.js +155 -292
  224. package/dist/runs/background/subagent-runner-launcher.js +33 -13
  225. package/dist/runs/background/subagent-runner.js +51 -1842
  226. package/dist/runs/background/top-level-async.js +2 -1
  227. package/dist/runs/foreground/chain-clarify.js +293 -1017
  228. package/dist/runs/foreground/clarification-draft.js +87 -0
  229. package/dist/runs/foreground/clarify-contracts.js +1 -0
  230. package/dist/runs/foreground/clarify-invocation.js +129 -38
  231. package/dist/runs/foreground/clarify-text-editor.js +210 -0
  232. package/dist/runs/foreground/clarify-view.js +167 -0
  233. package/dist/runs/foreground/execution-input.js +226 -353
  234. package/dist/runs/foreground/execution-routing.js +33 -0
  235. package/dist/runs/foreground/execution-timeout.js +81 -0
  236. package/dist/runs/foreground/foreground-control.js +222 -763
  237. package/dist/runs/foreground/foreground-memory.js +99 -0
  238. package/dist/runs/foreground/invocation-context.js +55 -0
  239. package/dist/runs/foreground/invocation-execution.js +331 -0
  240. package/dist/runs/foreground/invocation-expansion.js +48 -0
  241. package/dist/runs/foreground/management-actions.js +295 -0
  242. package/dist/runs/foreground/nested-control.js +179 -0
  243. package/dist/runs/foreground/question-continuation.js +78 -0
  244. package/dist/runs/foreground/question-control.js +155 -50
  245. package/dist/runs/foreground/resume-target.js +221 -0
  246. package/dist/runs/foreground/revival-launch-policy.js +58 -0
  247. package/dist/runs/foreground/run-async-path.js +190 -178
  248. package/dist/runs/foreground/run-interrupt.js +164 -0
  249. package/dist/runs/foreground/run-nudge.js +278 -0
  250. package/dist/runs/foreground/saved-revival.js +251 -0
  251. package/dist/runs/foreground/subagent-executor.js +135 -424
  252. package/dist/runs/foreground/subagent-params.js +67 -30
  253. package/dist/runs/foreground/wait-observation.js +104 -0
  254. package/dist/runs/foreground/wait-registration.js +17 -0
  255. package/dist/runs/foreground/wait-run.js +283 -123
  256. package/dist/runs/shared/acceptance-contract.js +193 -99
  257. package/dist/runs/shared/acceptance-defaults.js +1 -0
  258. package/dist/runs/shared/acceptance-evaluation.js +201 -181
  259. package/dist/runs/shared/acceptance-finalization.js +256 -180
  260. package/dist/runs/shared/acceptance-outcome.js +53 -0
  261. package/dist/runs/shared/acceptance-reports.js +137 -72
  262. package/dist/runs/shared/acceptance-submission.js +167 -0
  263. package/dist/runs/shared/acceptance-verification.js +100 -0
  264. package/dist/runs/shared/chain-outputs.js +80 -52
  265. package/dist/runs/shared/child-attempt-types.js +1 -0
  266. package/dist/runs/shared/child-attempt.js +314 -667
  267. package/dist/runs/shared/child-boundaries.js +173 -0
  268. package/dist/runs/shared/child-context-filter.js +44 -0
  269. package/dist/runs/shared/child-event-observer.js +390 -0
  270. package/dist/runs/shared/child-execution-cwd.js +73 -43
  271. package/dist/runs/shared/child-execution-outcome.js +72 -0
  272. package/dist/runs/shared/child-invocation.js +54 -0
  273. package/dist/runs/shared/child-message-validation.js +215 -0
  274. package/dist/runs/shared/child-native-accounting.js +106 -0
  275. package/dist/runs/shared/child-native-observation.js +69 -0
  276. package/dist/runs/shared/child-observation-spool.js +164 -0
  277. package/dist/runs/shared/child-observations.js +157 -76
  278. package/dist/runs/shared/child-presence.js +3 -0
  279. package/dist/runs/shared/child-route-env.js +119 -0
  280. package/dist/runs/shared/child-stream-observer.js +221 -0
  281. package/dist/runs/shared/child-stream-projection.js +137 -0
  282. package/dist/runs/shared/child-structured-tool.js +27 -0
  283. package/dist/runs/shared/claude-code.js +121 -158
  284. package/dist/runs/shared/claude-model.js +42 -0
  285. package/dist/runs/shared/claude-session.js +83 -0
  286. package/dist/runs/shared/claude-types.js +1 -0
  287. package/dist/runs/shared/completion-guard.js +18 -18
  288. package/dist/runs/shared/control-event-policy.js +8 -0
  289. package/dist/runs/shared/control-notification-owner.js +13 -0
  290. package/dist/runs/shared/dynamic-fanout.js +188 -173
  291. package/dist/runs/shared/dynamic-item.js +102 -0
  292. package/dist/runs/shared/history-index.js +62 -36
  293. package/dist/runs/shared/legacy-async-recovery.js +114 -0
  294. package/dist/runs/shared/legacy-output-recovery.js +148 -0
  295. package/dist/runs/shared/mcp-config-schema.js +36 -0
  296. package/dist/runs/shared/mcp-direct-tool-allowlist.js +147 -116
  297. package/dist/runs/shared/model-fallback.js +97 -38
  298. package/dist/runs/shared/mutating-tool-guard.js +128 -88
  299. package/dist/runs/shared/native-finalization-types.js +1 -0
  300. package/dist/runs/shared/native-finalization.js +155 -76
  301. package/dist/runs/shared/native-usage.js +238 -98
  302. package/dist/runs/shared/nested-control-records.js +128 -0
  303. package/dist/runs/shared/nested-events.js +8 -700
  304. package/dist/runs/shared/nested-path.js +32 -28
  305. package/dist/runs/shared/nested-projection.js +155 -0
  306. package/dist/runs/shared/nested-protocol.js +18 -0
  307. package/dist/runs/shared/nested-registry.js +191 -0
  308. package/dist/runs/shared/nested-render.js +106 -58
  309. package/dist/runs/shared/nested-route.js +220 -0
  310. package/dist/runs/shared/nested-validation.js +216 -0
  311. package/dist/runs/shared/owned-child-evidence.js +125 -0
  312. package/dist/runs/shared/owned-run-list.js +146 -0
  313. package/dist/runs/shared/owned-run-observation.js +267 -0
  314. package/dist/runs/shared/owned-run-progress.js +109 -0
  315. package/dist/runs/shared/owned-run-read-state.js +1 -0
  316. package/dist/runs/shared/owned-run-results.js +202 -0
  317. package/dist/runs/shared/owned-run-status.js +180 -0
  318. package/dist/runs/shared/owned-run-view.js +51 -0
  319. package/dist/runs/shared/owned-workflow-details.js +17 -0
  320. package/dist/runs/shared/owner-output.js +43 -0
  321. package/dist/runs/shared/parallel-utils.js +36 -28
  322. package/dist/runs/shared/parent-receipts.js +90 -32
  323. package/dist/runs/shared/parent-usage.js +169 -57
  324. package/dist/runs/shared/pi-args.js +108 -201
  325. package/dist/runs/shared/pi-launch-input.js +1 -0
  326. package/dist/runs/shared/pi-session-launch.js +86 -0
  327. package/dist/runs/shared/pi-spawn.js +35 -21
  328. package/dist/runs/shared/run-history-queries.js +126 -35
  329. package/dist/runs/shared/run-history.js +101 -35
  330. package/dist/runs/shared/run-metadata-paths.js +14 -0
  331. package/dist/runs/shared/run-metadata.js +158 -0
  332. package/dist/runs/shared/run-persistence.js +131 -0
  333. package/dist/runs/shared/run-records.js +9 -679
  334. package/dist/runs/shared/run-restoration.js +338 -0
  335. package/dist/runs/shared/run-state-owner.js +26 -0
  336. package/dist/runs/shared/session-cwd-preload.js +27 -18
  337. package/dist/runs/shared/single-output.js +148 -70
  338. package/dist/runs/shared/stable-value.js +15 -0
  339. package/dist/runs/shared/streaming-text.js +23 -12
  340. package/dist/runs/shared/structured-output.js +25 -13
  341. package/dist/runs/shared/subagent-control.js +167 -100
  342. package/dist/runs/shared/subagent-prompt-runtime.js +27 -130
  343. package/dist/runs/shared/subagent-tool-loop-guard.js +81 -52
  344. package/dist/runs/shared/supervisor-question-state.js +145 -0
  345. package/dist/runs/shared/supervisor-questions.js +185 -254
  346. package/dist/runs/shared/workflow-graph.js +259 -167
  347. package/dist/runs/shared/workflow-policy.js +120 -48
  348. package/dist/runs/shared/worktree-contract.js +1 -0
  349. package/dist/runs/shared/worktree-hook.js +138 -0
  350. package/dist/runs/shared/worktree-location.js +47 -0
  351. package/dist/runs/shared/worktree-preservation.js +8 -0
  352. package/dist/runs/shared/worktree-process.js +107 -0
  353. package/dist/runs/shared/worktree.js +183 -322
  354. package/dist/shared/agent-context-policy.js +34 -44
  355. package/dist/shared/agent-dir.js +14 -0
  356. package/dist/shared/artifacts.js +30 -12
  357. package/dist/shared/atomic-json.js +4 -1
  358. package/dist/shared/chain-files.js +72 -0
  359. package/dist/shared/concurrency.js +18 -0
  360. package/dist/shared/content-preview.js +115 -0
  361. package/dist/shared/cooperative.js +5 -2
  362. package/dist/shared/execution-cwd.js +13 -5
  363. package/dist/shared/file-coalescer.js +2 -1
  364. package/dist/shared/fork-context.js +10 -12
  365. package/dist/shared/formatters.js +45 -19
  366. package/dist/shared/journal-frames.js +164 -0
  367. package/dist/shared/journal-projections.js +121 -0
  368. package/dist/shared/journal-reader.js +6 -407
  369. package/dist/shared/json-projection.js +191 -0
  370. package/dist/shared/lazy-tools.js +19 -8
  371. package/dist/shared/message-output.js +116 -0
  372. package/dist/shared/model-info.js +31 -14
  373. package/dist/shared/native-import.js +20 -0
  374. package/dist/shared/native-journal.js +140 -0
  375. package/dist/shared/native-session.js +5 -2
  376. package/dist/shared/native-tui.js +7 -2
  377. package/dist/shared/native-typebox.js +15 -3
  378. package/dist/shared/output-page.js +63 -0
  379. package/dist/shared/post-exit-stdio-guard.js +128 -88
  380. package/dist/shared/prompt-sections.js +2 -0
  381. package/dist/shared/session-entries.js +70 -35
  382. package/dist/shared/session-identity.js +5 -3
  383. package/dist/shared/settings.js +62 -192
  384. package/dist/shared/status-format.js +97 -37
  385. package/dist/shared/task-file-policy.js +24 -0
  386. package/dist/shared/temp-root.js +44 -15
  387. package/dist/shared/types/acceptance.js +1 -0
  388. package/dist/shared/types/async.js +1 -0
  389. package/dist/shared/types/config.js +1 -0
  390. package/dist/shared/types/details.js +1 -0
  391. package/dist/shared/types/history.js +1 -0
  392. package/dist/shared/types/inputs.js +1 -0
  393. package/dist/shared/types/intercom.js +1 -0
  394. package/dist/shared/types/launch.js +1 -0
  395. package/dist/shared/types/messages.js +1 -0
  396. package/dist/shared/types/nested.js +1 -0
  397. package/dist/shared/types/owned-runs.js +1 -0
  398. package/dist/shared/types/progress.js +1 -0
  399. package/dist/shared/types/questions.js +1 -0
  400. package/dist/shared/types/results.js +1 -0
  401. package/dist/shared/types/state.js +1 -0
  402. package/dist/shared/types/usage.js +1 -0
  403. package/dist/shared/types/workflow.js +1 -0
  404. package/dist/shared/types.js +75 -30
  405. package/dist/shared/unknown.js +52 -0
  406. package/dist/shared/utils.js +54 -260
  407. package/dist/slash/command-discovery.js +82 -0
  408. package/dist/slash/command-input.js +190 -0
  409. package/dist/slash/prompt-template-bridge.js +94 -270
  410. package/dist/slash/prompt-template-contract.js +77 -0
  411. package/dist/slash/prompt-template-results.js +125 -0
  412. package/dist/slash/request-protocol.js +68 -0
  413. package/dist/slash/result-delivery.js +237 -0
  414. package/dist/slash/saved-chain.js +78 -0
  415. package/dist/slash/slash-bridge.js +123 -89
  416. package/dist/slash/slash-commands.js +101 -572
  417. package/dist/slash/slash-live-state.js +68 -47
  418. package/dist/tui/action-hints.js +50 -22
  419. package/dist/tui/activity-lines.js +32 -0
  420. package/dist/tui/agent-browser.js +290 -0
  421. package/dist/tui/agent-controls.js +289 -0
  422. package/dist/tui/agent-conversation.js +444 -0
  423. package/dist/tui/agent-dock.js +171 -0
  424. package/dist/tui/agent-history.js +50 -183
  425. package/dist/tui/agent-model.js +62 -0
  426. package/dist/tui/agent-picker.js +262 -0
  427. package/dist/tui/agent-view.js +232 -1564
  428. package/dist/tui/compact-results.js +193 -0
  429. package/dist/tui/conversation-details.js +190 -0
  430. package/dist/tui/conversation-frame.js +135 -0
  431. package/dist/tui/conversation-history.js +201 -0
  432. package/dist/tui/conversation-menu.js +78 -0
  433. package/dist/tui/conversation-notices.js +79 -0
  434. package/dist/tui/conversation-selection.js +58 -0
  435. package/dist/tui/conversation-viewport.js +129 -0
  436. package/dist/tui/direction-message.js +27 -0
  437. package/dist/tui/display.js +282 -0
  438. package/dist/tui/editor-viewport.js +18 -0
  439. package/dist/tui/expanded-content.js +87 -0
  440. package/dist/tui/expanded-multi.js +170 -0
  441. package/dist/tui/expanded-single.js +65 -0
  442. package/dist/tui/history-cards.js +216 -0
  443. package/dist/tui/history-display.js +238 -0
  444. package/dist/tui/history-json.js +16 -0
  445. package/dist/tui/history-metadata.js +152 -0
  446. package/dist/tui/history-record.js +251 -0
  447. package/dist/tui/history-text.js +34 -0
  448. package/dist/tui/indexed-history.js +116 -0
  449. package/dist/tui/nested-widget.js +120 -0
  450. package/dist/tui/picker-page.js +59 -0
  451. package/dist/tui/render.js +58 -1501
  452. package/dist/tui/result-facts.js +64 -0
  453. package/dist/tui/task-observation.js +59 -0
  454. package/dist/tui/task-store.js +366 -0
  455. package/dist/tui/text-values.js +16 -0
  456. package/dist/tui/view-connections.js +47 -0
  457. package/dist/tui/view-model.js +94 -0
  458. package/dist/tui/view-persistence.js +51 -0
  459. package/dist/tui/view-ports.js +1 -0
  460. package/dist/tui/view-session.js +37 -0
  461. package/dist/tui/widget-details.js +144 -0
  462. package/dist/tui/widget-status.js +245 -0
  463. package/dist/tui/widget.js +145 -0
  464. package/dist/tui/workflow-labels.js +223 -0
  465. package/dist/tui/workflow-outcomes.js +124 -0
  466. package/docs/code-quality.md +38 -0
  467. package/docs/development.md +99 -0
  468. package/docs/intercom-bridge.md +22 -17
  469. package/docs/intercom.md +132 -106
  470. package/docs/performance.md +19 -17
  471. package/docs/reference.md +1472 -0
  472. package/generated/RunValidators.d.ts +28 -0
  473. package/generated/RunValidators.js +2 -0
  474. package/package.json +27 -6
  475. package/prompts/parallel-cleanup.md +3 -0
  476. package/prompts/parallel-context-build.md +3 -0
  477. package/prompts/parallel-handoff-plan.md +6 -0
  478. package/prompts/parallel-research.md +4 -0
  479. package/prompts/parallel-review.md +2 -0
  480. package/prompts/review-loop.md +2 -0
  481. package/scripts/build.mjs +129 -85
  482. package/scripts/check-compat.mjs +48 -11
  483. package/scripts/compat-host.mjs +35 -7
  484. package/scripts/generate-run-schemas.mjs +210 -0
  485. package/scripts/intercom-bridge-credentials.mjs +155 -28
  486. package/scripts/intercom-remote.mjs +175 -50
  487. package/scripts/local-install-smoke.mjs +47 -37
  488. package/scripts/native-package-smoke.mjs +135 -25
  489. package/scripts/package-smoke.mjs +360 -140
  490. package/scripts/prepare.mjs +54 -34
  491. package/scripts/real-pi-processes.mjs +261 -0
  492. package/scripts/real-pi-smoke.mjs +432 -351
  493. package/scripts/run-tests.mjs +29 -15
  494. package/skills/pi-intercom/SKILL.md +11 -11
  495. package/skills/pi-intercom/references/peer-sessions.md +7 -2
  496. package/skills/pi-subagents/SKILL.md +1 -1
  497. package/skills/pi-subagents/references/full-orchestration-guide.md +254 -112
  498. package/src/agents/agent-defaults.ts +13 -0
  499. package/src/agents/agent-definition.ts +253 -0
  500. package/src/agents/agent-management.ts +111 -808
  501. package/src/agents/agent-scope.ts +7 -3
  502. package/src/agents/agent-selection.ts +26 -16
  503. package/src/agents/agent-serializer.ts +84 -93
  504. package/src/agents/agents.ts +199 -906
  505. package/src/agents/builtin-overrides.ts +297 -0
  506. package/src/agents/chain-serializer.ts +3 -329
  507. package/src/agents/config-values.ts +57 -0
  508. package/src/agents/discovery-paths.ts +134 -0
  509. package/src/agents/frontmatter.ts +35 -17
  510. package/src/agents/identity.ts +49 -18
  511. package/src/agents/json-chain.ts +305 -0
  512. package/src/agents/management-config.ts +342 -0
  513. package/src/agents/management-format.ts +243 -0
  514. package/src/agents/management-persistence.ts +408 -0
  515. package/src/agents/management-targets.ts +260 -0
  516. package/src/agents/management-warnings.ts +115 -0
  517. package/src/agents/markdown-chain.ts +237 -0
  518. package/src/agents/package-agents.ts +231 -0
  519. package/src/agents/skill-files.ts +182 -0
  520. package/src/agents/skill-search-paths.ts +289 -0
  521. package/src/agents/skill-types.ts +31 -0
  522. package/src/agents/skills.ts +152 -610
  523. package/src/extension/acceptance-schema.ts +88 -0
  524. package/src/extension/chain-schema.ts +276 -0
  525. package/src/extension/child-runtime.ts +302 -0
  526. package/src/extension/compact-tools.ts +259 -102
  527. package/src/extension/config-schema.ts +59 -0
  528. package/src/extension/config.ts +39 -17
  529. package/src/extension/control-notice-schema.ts +55 -0
  530. package/src/extension/control-notices.ts +57 -33
  531. package/src/extension/delegation-bridges.ts +59 -0
  532. package/src/extension/doctor.ts +171 -135
  533. package/src/extension/everyday-schemas.ts +252 -0
  534. package/src/extension/fanout-child.ts +29 -308
  535. package/src/extension/index.ts +17 -642
  536. package/src/extension/message-renderers.ts +334 -0
  537. package/src/extension/nested-control-inbox.ts +196 -0
  538. package/src/extension/parent-runtime.ts +405 -0
  539. package/src/extension/primary-tool.ts +130 -0
  540. package/src/extension/result-snapshot.ts +35 -0
  541. package/src/extension/runtime-reload.ts +72 -0
  542. package/src/extension/runtime-storage.ts +49 -0
  543. package/src/extension/schema-overrides.ts +114 -0
  544. package/src/extension/schemas.ts +451 -418
  545. package/src/extension/tool-input.ts +40 -13
  546. package/src/extension/tool-result.ts +45 -14
  547. package/src/history/answer-texts.ts +74 -0
  548. package/src/history/canonical-result.ts +127 -51
  549. package/src/history/canonical-selection.ts +54 -0
  550. package/src/history/database-generation.ts +86 -0
  551. package/src/history/database.ts +86 -48
  552. package/src/history/entry-ingestion.ts +129 -0
  553. package/src/history/index.ts +426 -148
  554. package/src/history/ingest.ts +372 -342
  555. package/src/history/output-digests.ts +41 -0
  556. package/src/history/preview.ts +235 -0
  557. package/src/history/prune.ts +48 -0
  558. package/src/history/queries.ts +122 -256
  559. package/src/history/query-scope.ts +278 -0
  560. package/src/history/rows.ts +118 -0
  561. package/src/history/run-projection.ts +164 -0
  562. package/src/history/run-queries.ts +199 -0
  563. package/src/history/schema.ts +34 -0
  564. package/src/history/search-queries.ts +216 -0
  565. package/src/history/selected-record.ts +140 -0
  566. package/src/history/source-file.ts +51 -0
  567. package/src/history/source-watches.ts +156 -0
  568. package/src/history/store.ts +310 -197
  569. package/src/history/text-chunks.ts +181 -0
  570. package/src/history/text.ts +43 -0
  571. package/src/history/transcript-queries.ts +251 -0
  572. package/src/history/types.ts +27 -164
  573. package/src/history/values.ts +36 -0
  574. package/src/history/wire-inputs.ts +141 -0
  575. package/src/history/wire-models.ts +51 -0
  576. package/src/history/worker-runtime.ts +502 -0
  577. package/src/history/worker.ts +94 -336
  578. package/src/intercom/intercom-bridge.ts +136 -69
  579. package/src/intercom/live-intercom.ts +197 -92
  580. package/src/intercom/nested-result-tree.ts +213 -0
  581. package/src/intercom/result-delivery.ts +56 -0
  582. package/src/intercom/result-intercom.ts +364 -382
  583. package/src/pi-intercom/agent-dir.ts +9 -3
  584. package/src/pi-intercom/async.ts +33 -0
  585. package/src/pi-intercom/bridge-ask.ts +64 -0
  586. package/src/pi-intercom/bridge-config.ts +101 -0
  587. package/src/pi-intercom/bridge-http.ts +97 -0
  588. package/src/pi-intercom/bridge-protocol.ts +123 -0
  589. package/src/pi-intercom/bridge-routes.ts +90 -0
  590. package/src/pi-intercom/bridge-session.ts +506 -0
  591. package/src/pi-intercom/bridge.ts +258 -547
  592. package/src/pi-intercom/broker/broker.ts +326 -263
  593. package/src/pi-intercom/broker/client.ts +273 -354
  594. package/src/pi-intercom/broker/connection.ts +192 -0
  595. package/src/pi-intercom/broker/framing.ts +11 -6
  596. package/src/pi-intercom/broker/paths.ts +28 -25
  597. package/src/pi-intercom/broker/pid.ts +68 -24
  598. package/src/pi-intercom/broker/snapshot-reader.ts +91 -0
  599. package/src/pi-intercom/broker/snapshots.ts +241 -0
  600. package/src/pi-intercom/broker/spawn.ts +58 -34
  601. package/src/pi-intercom/config.ts +113 -108
  602. package/src/pi-intercom/connection.ts +346 -0
  603. package/src/pi-intercom/identity.ts +71 -0
  604. package/src/pi-intercom/inbound-delivery.ts +450 -0
  605. package/src/pi-intercom/inbound-journal.ts +350 -0
  606. package/src/pi-intercom/inbound-record.ts +141 -0
  607. package/src/pi-intercom/inbound.ts +237 -0
  608. package/src/pi-intercom/index.ts +86 -2923
  609. package/src/pi-intercom/inspection.ts +82 -0
  610. package/src/pi-intercom/interview.ts +295 -0
  611. package/src/pi-intercom/lifecycle.ts +183 -0
  612. package/src/pi-intercom/message-format.ts +77 -0
  613. package/src/pi-intercom/outbound.ts +418 -0
  614. package/src/pi-intercom/peer-awareness.ts +84 -0
  615. package/src/pi-intercom/reply-tracker.ts +121 -59
  616. package/src/pi-intercom/reply-wait.ts +247 -0
  617. package/src/pi-intercom/runtime-types.ts +97 -0
  618. package/src/pi-intercom/session-events.ts +247 -0
  619. package/src/pi-intercom/session-targets.ts +124 -72
  620. package/src/pi-intercom/subagent-events.ts +299 -0
  621. package/src/pi-intercom/subagent-live-events.ts +212 -109
  622. package/src/pi-intercom/supervisor.ts +362 -0
  623. package/src/pi-intercom/tool-arguments.ts +120 -0
  624. package/src/pi-intercom/tool-registration.ts +121 -0
  625. package/src/pi-intercom/tool-results.ts +54 -0
  626. package/src/pi-intercom/tool-schemas.ts +134 -0
  627. package/src/pi-intercom/tools.ts +80 -0
  628. package/src/pi-intercom/topic-actions.ts +243 -0
  629. package/src/pi-intercom/topics.ts +267 -121
  630. package/src/pi-intercom/transport.ts +14 -0
  631. package/src/pi-intercom/types.ts +288 -190
  632. package/src/pi-intercom/ui/compose-paste.ts +109 -0
  633. package/src/pi-intercom/ui/compose.ts +173 -157
  634. package/src/pi-intercom/ui/inline-message.ts +80 -62
  635. package/src/pi-intercom/ui/message-renderers.ts +182 -0
  636. package/src/pi-intercom/ui/overlay.ts +238 -0
  637. package/src/pi-intercom/ui/session-format.ts +146 -0
  638. package/src/pi-intercom/ui/session-list.ts +145 -62
  639. package/src/pi-intercom/ui/tool-renderers.ts +148 -0
  640. package/src/pi-intercom/ui/topic-view.ts +107 -0
  641. package/src/pi-intercom/validation.ts +69 -0
  642. package/src/runs/background/async-chain-plan.ts +451 -0
  643. package/src/runs/background/async-control.ts +201 -71
  644. package/src/runs/background/async-execution.ts +206 -829
  645. package/src/runs/background/async-job-admission.ts +54 -0
  646. package/src/runs/background/async-job-projection.ts +225 -0
  647. package/src/runs/background/async-job-tracker.ts +416 -360
  648. package/src/runs/background/async-launch.ts +319 -0
  649. package/src/runs/background/async-plan.ts +285 -0
  650. package/src/runs/background/async-result-file.ts +79 -37
  651. package/src/runs/background/async-resume.ts +338 -285
  652. package/src/runs/background/async-run-discovery.ts +270 -0
  653. package/src/runs/background/async-run-location.ts +194 -0
  654. package/src/runs/background/async-run-record.ts +14 -0
  655. package/src/runs/background/async-run-repair.ts +307 -0
  656. package/src/runs/background/async-run-summary.ts +71 -0
  657. package/src/runs/background/async-single-plan.ts +168 -0
  658. package/src/runs/background/async-status-projection.ts +188 -0
  659. package/src/runs/background/async-status-render.ts +164 -0
  660. package/src/runs/background/async-status-validation.ts +238 -0
  661. package/src/runs/background/async-status.ts +9 -481
  662. package/src/runs/background/async-value.ts +29 -0
  663. package/src/runs/background/completion-dedupe.ts +103 -54
  664. package/src/runs/background/completion-delivery.ts +313 -187
  665. package/src/runs/background/completion-receipts.ts +309 -0
  666. package/src/runs/background/legacy-status-acceptance.ts +38 -0
  667. package/src/runs/background/notify.ts +167 -106
  668. package/src/runs/background/parallel-groups.ts +95 -46
  669. package/src/runs/background/result-payload.ts +268 -0
  670. package/src/runs/background/result-watcher.ts +484 -387
  671. package/src/runs/background/run-id-resolver.ts +126 -57
  672. package/src/runs/background/run-schemas.ts +240 -0
  673. package/src/runs/background/run-status-contracts.ts +46 -0
  674. package/src/runs/background/run-status-render.ts +364 -0
  675. package/src/runs/background/run-status.ts +338 -356
  676. package/src/runs/background/runner-attempt-output.ts +281 -0
  677. package/src/runs/background/runner-attempt.ts +354 -0
  678. package/src/runs/background/runner-child-executor.ts +232 -0
  679. package/src/runs/background/runner-child-observer.ts +270 -0
  680. package/src/runs/background/runner-completion-summary.ts +106 -0
  681. package/src/runs/background/runner-completion.ts +274 -0
  682. package/src/runs/background/runner-config.ts +52 -0
  683. package/src/runs/background/runner-contract.ts +51 -0
  684. package/src/runs/background/runner-dynamic.ts +185 -0
  685. package/src/runs/background/runner-finalization.ts +203 -0
  686. package/src/runs/background/runner-graph.ts +91 -0
  687. package/src/runs/background/runner-initial-status.ts +72 -0
  688. package/src/runs/background/runner-lifecycle.ts +159 -0
  689. package/src/runs/background/runner-monitor.ts +399 -0
  690. package/src/runs/background/runner-parallel.ts +280 -0
  691. package/src/runs/background/runner-prepare-step.ts +128 -0
  692. package/src/runs/background/runner-reporting.ts +192 -0
  693. package/src/runs/background/runner-status.ts +220 -0
  694. package/src/runs/background/runner-step-output.ts +158 -0
  695. package/src/runs/background/runner-step-record.ts +76 -0
  696. package/src/runs/background/runner-step.ts +150 -0
  697. package/src/runs/background/runner-streaming.ts +220 -0
  698. package/src/runs/background/runner-workflow.ts +284 -0
  699. package/src/runs/background/stale-run-reconciler.ts +279 -336
  700. package/src/runs/background/subagent-runner-launcher.ts +67 -35
  701. package/src/runs/background/subagent-runner.ts +80 -2048
  702. package/src/runs/background/top-level-async.ts +9 -7
  703. package/src/runs/foreground/chain-clarify.ts +499 -1334
  704. package/src/runs/foreground/clarification-draft.ts +92 -0
  705. package/src/runs/foreground/clarify-contracts.ts +33 -0
  706. package/src/runs/foreground/clarify-invocation.ts +192 -65
  707. package/src/runs/foreground/clarify-text-editor.ts +229 -0
  708. package/src/runs/foreground/clarify-view.ts +222 -0
  709. package/src/runs/foreground/execution-input.ts +358 -424
  710. package/src/runs/foreground/execution-routing.ts +41 -0
  711. package/src/runs/foreground/execution-timeout.ts +92 -0
  712. package/src/runs/foreground/foreground-control.ts +333 -812
  713. package/src/runs/foreground/foreground-memory.ts +132 -0
  714. package/src/runs/foreground/invocation-context.ts +88 -0
  715. package/src/runs/foreground/invocation-execution.ts +465 -0
  716. package/src/runs/foreground/invocation-expansion.ts +58 -0
  717. package/src/runs/foreground/management-actions.ts +360 -0
  718. package/src/runs/foreground/nested-control.ts +248 -0
  719. package/src/runs/foreground/question-continuation.ts +112 -0
  720. package/src/runs/foreground/question-control.ts +297 -70
  721. package/src/runs/foreground/resume-target.ts +330 -0
  722. package/src/runs/foreground/revival-launch-policy.ts +112 -0
  723. package/src/runs/foreground/run-async-path.ts +307 -223
  724. package/src/runs/foreground/run-interrupt.ts +202 -0
  725. package/src/runs/foreground/run-nudge.ts +355 -0
  726. package/src/runs/foreground/saved-revival.ts +356 -0
  727. package/src/runs/foreground/subagent-executor.ts +195 -493
  728. package/src/runs/foreground/subagent-params.ts +314 -242
  729. package/src/runs/foreground/wait-observation.ts +160 -0
  730. package/src/runs/foreground/wait-registration.ts +18 -0
  731. package/src/runs/foreground/wait-run.ts +361 -119
  732. package/src/runs/shared/acceptance-contract.ts +410 -209
  733. package/src/runs/shared/acceptance-defaults.ts +1 -0
  734. package/src/runs/shared/acceptance-evaluation.ts +314 -240
  735. package/src/runs/shared/acceptance-finalization.ts +447 -305
  736. package/src/runs/shared/acceptance-outcome.ts +69 -0
  737. package/src/runs/shared/acceptance-reports.ts +220 -126
  738. package/src/runs/shared/acceptance-submission.ts +251 -0
  739. package/src/runs/shared/acceptance-verification.ts +118 -0
  740. package/src/runs/shared/acceptance.ts +25 -25
  741. package/src/runs/shared/chain-outputs.ts +190 -98
  742. package/src/runs/shared/child-attempt-types.ts +118 -0
  743. package/src/runs/shared/child-attempt.ts +372 -608
  744. package/src/runs/shared/child-boundaries.ts +217 -0
  745. package/src/runs/shared/child-context-filter.ts +53 -0
  746. package/src/runs/shared/child-event-observer.ts +496 -0
  747. package/src/runs/shared/child-execution-cwd.ts +139 -68
  748. package/src/runs/shared/child-execution-outcome.ts +103 -0
  749. package/src/runs/shared/child-invocation.ts +74 -0
  750. package/src/runs/shared/child-message-validation.ts +233 -0
  751. package/src/runs/shared/child-native-accounting.ts +154 -0
  752. package/src/runs/shared/child-native-observation.ts +79 -0
  753. package/src/runs/shared/child-observation-spool.ts +188 -0
  754. package/src/runs/shared/child-observations.ts +219 -89
  755. package/src/runs/shared/child-presence.ts +6 -0
  756. package/src/runs/shared/child-route-env.ts +142 -0
  757. package/src/runs/shared/child-stream-observer.ts +302 -0
  758. package/src/runs/shared/child-stream-projection.ts +160 -0
  759. package/src/runs/shared/child-structured-tool.ts +38 -0
  760. package/src/runs/shared/claude-code.ts +201 -228
  761. package/src/runs/shared/claude-model.ts +67 -0
  762. package/src/runs/shared/claude-session.ts +124 -0
  763. package/src/runs/shared/claude-types.ts +31 -0
  764. package/src/runs/shared/completion-guard.ts +35 -26
  765. package/src/runs/shared/control-event-policy.ts +15 -0
  766. package/src/runs/shared/control-notification-owner.ts +20 -0
  767. package/src/runs/shared/dynamic-fanout.ts +402 -238
  768. package/src/runs/shared/dynamic-item.ts +114 -0
  769. package/src/runs/shared/history-index.ts +112 -51
  770. package/src/runs/shared/legacy-async-recovery.ts +153 -0
  771. package/src/runs/shared/legacy-output-recovery.ts +214 -0
  772. package/src/runs/shared/mcp-config-schema.ts +46 -0
  773. package/src/runs/shared/mcp-direct-tool-allowlist.ts +396 -307
  774. package/src/runs/shared/model-fallback.ts +302 -180
  775. package/src/runs/shared/mutating-tool-guard.ts +259 -158
  776. package/src/runs/shared/native-finalization-types.ts +29 -0
  777. package/src/runs/shared/native-finalization.ts +233 -109
  778. package/src/runs/shared/native-usage.ts +379 -96
  779. package/src/runs/shared/nested-control-records.ts +178 -0
  780. package/src/runs/shared/nested-events.ts +45 -752
  781. package/src/runs/shared/nested-path.ts +47 -34
  782. package/src/runs/shared/nested-projection.ts +230 -0
  783. package/src/runs/shared/nested-protocol.ts +67 -0
  784. package/src/runs/shared/nested-registry.ts +273 -0
  785. package/src/runs/shared/nested-render.ts +198 -100
  786. package/src/runs/shared/nested-route.ts +292 -0
  787. package/src/runs/shared/nested-validation.ts +291 -0
  788. package/src/runs/shared/owned-child-evidence.ts +184 -0
  789. package/src/runs/shared/owned-run-list.ts +187 -0
  790. package/src/runs/shared/owned-run-observation.ts +368 -0
  791. package/src/runs/shared/owned-run-progress.ts +172 -0
  792. package/src/runs/shared/owned-run-read-state.ts +7 -0
  793. package/src/runs/shared/owned-run-results.ts +289 -0
  794. package/src/runs/shared/owned-run-status.ts +239 -0
  795. package/src/runs/shared/owned-run-view.ts +65 -0
  796. package/src/runs/shared/owned-workflow-details.ts +24 -0
  797. package/src/runs/shared/owner-output.ts +73 -0
  798. package/src/runs/shared/parallel-utils.ts +93 -129
  799. package/src/runs/shared/parent-receipts.ts +177 -50
  800. package/src/runs/shared/parent-usage.ts +314 -91
  801. package/src/runs/shared/pi-args.ts +241 -311
  802. package/src/runs/shared/pi-launch-input.ts +48 -0
  803. package/src/runs/shared/pi-session-launch.ts +94 -0
  804. package/src/runs/shared/pi-spawn.ts +57 -33
  805. package/src/runs/shared/run-history-queries.ts +189 -38
  806. package/src/runs/shared/run-history.ts +197 -76
  807. package/src/runs/shared/run-id-ambiguity.ts +7 -3
  808. package/src/runs/shared/run-metadata-paths.ts +17 -0
  809. package/src/runs/shared/run-metadata.ts +240 -0
  810. package/src/runs/shared/run-persistence.ts +181 -0
  811. package/src/runs/shared/run-records.ts +19 -607
  812. package/src/runs/shared/run-restoration.ts +455 -0
  813. package/src/runs/shared/run-state-owner.ts +31 -0
  814. package/src/runs/shared/session-cwd-preload.ts +39 -19
  815. package/src/runs/shared/single-output.ts +358 -205
  816. package/src/runs/shared/stable-value.ts +15 -0
  817. package/src/runs/shared/streaming-text.ts +39 -12
  818. package/src/runs/shared/structured-output.ts +76 -46
  819. package/src/runs/shared/subagent-control.ts +330 -197
  820. package/src/runs/shared/subagent-prompt-runtime.ts +92 -174
  821. package/src/runs/shared/subagent-tool-loop-guard.ts +118 -68
  822. package/src/runs/shared/supervisor-question-state.ts +221 -0
  823. package/src/runs/shared/supervisor-questions.ts +396 -401
  824. package/src/runs/shared/workflow-graph.ts +400 -198
  825. package/src/runs/shared/workflow-policy.ts +245 -110
  826. package/src/runs/shared/worktree-contract.ts +29 -0
  827. package/src/runs/shared/worktree-hook.ts +181 -0
  828. package/src/runs/shared/worktree-location.ts +61 -0
  829. package/src/runs/shared/worktree-preservation.ts +10 -0
  830. package/src/runs/shared/worktree-process.ts +132 -0
  831. package/src/runs/shared/worktree.ts +459 -587
  832. package/src/shared/agent-context-policy.ts +176 -145
  833. package/src/shared/agent-dir.ts +15 -0
  834. package/src/shared/artifacts.ts +99 -68
  835. package/src/shared/atomic-json.ts +14 -11
  836. package/src/shared/chain-files.ts +72 -0
  837. package/src/shared/concurrency.ts +27 -0
  838. package/src/shared/content-preview.ts +117 -0
  839. package/src/shared/cooperative.ts +17 -13
  840. package/src/shared/execution-cwd.ts +34 -9
  841. package/src/shared/file-coalescer.ts +24 -22
  842. package/src/shared/fork-context.ts +52 -48
  843. package/src/shared/formatters.ts +88 -47
  844. package/src/shared/journal-frames.ts +197 -0
  845. package/src/shared/journal-projections.ts +133 -0
  846. package/src/shared/journal-reader.ts +18 -333
  847. package/src/shared/json-projection.ts +224 -0
  848. package/src/shared/lazy-tools.ts +76 -27
  849. package/src/shared/message-output.ts +146 -0
  850. package/src/shared/model-info.ts +94 -58
  851. package/src/shared/native-import.ts +25 -0
  852. package/src/shared/native-journal.ts +172 -0
  853. package/src/shared/native-session.ts +8 -3
  854. package/src/shared/native-tui.ts +13 -3
  855. package/src/shared/native-typebox.ts +18 -3
  856. package/src/shared/output-page.ts +76 -0
  857. package/src/shared/post-exit-stdio-guard.ts +232 -172
  858. package/src/shared/prompt-sections.ts +13 -7
  859. package/src/shared/session-entries.ts +103 -44
  860. package/src/shared/session-identity.ts +17 -10
  861. package/src/shared/settings.ts +182 -367
  862. package/src/shared/status-format.ts +207 -98
  863. package/src/shared/stream-json.d.ts +10 -0
  864. package/src/shared/task-file-policy.ts +35 -0
  865. package/src/shared/temp-root.ts +122 -71
  866. package/src/shared/types/acceptance.ts +149 -0
  867. package/src/shared/types/async.ts +247 -0
  868. package/src/shared/types/config.ts +139 -0
  869. package/src/shared/types/details.ts +104 -0
  870. package/src/shared/types/history.ts +217 -0
  871. package/src/shared/types/inputs.ts +4 -0
  872. package/src/shared/types/intercom.ts +57 -0
  873. package/src/shared/types/launch.ts +39 -0
  874. package/src/shared/types/messages.ts +104 -0
  875. package/src/shared/types/nested.ts +153 -0
  876. package/src/shared/types/owned-runs.ts +148 -0
  877. package/src/shared/types/progress.ts +106 -0
  878. package/src/shared/types/questions.ts +103 -0
  879. package/src/shared/types/results.ts +119 -0
  880. package/src/shared/types/state.ts +56 -0
  881. package/src/shared/types/usage.ts +36 -0
  882. package/src/shared/types/workflow.ts +187 -0
  883. package/src/shared/types.ts +222 -1161
  884. package/src/shared/ui-mode.ts +1 -1
  885. package/src/shared/unknown.ts +59 -0
  886. package/src/shared/utils.ts +111 -305
  887. package/src/slash/command-discovery.ts +109 -0
  888. package/src/slash/command-input.ts +232 -0
  889. package/src/slash/prompt-template-bridge.ts +153 -400
  890. package/src/slash/prompt-template-contract.ts +152 -0
  891. package/src/slash/prompt-template-results.ts +189 -0
  892. package/src/slash/request-protocol.ts +87 -0
  893. package/src/slash/result-delivery.ts +312 -0
  894. package/src/slash/saved-chain.ts +115 -0
  895. package/src/slash/slash-bridge.ts +202 -156
  896. package/src/slash/slash-commands.ts +176 -598
  897. package/src/slash/slash-live-state.ts +287 -229
  898. package/src/tui/action-hints.ts +147 -61
  899. package/src/tui/activity-lines.ts +40 -0
  900. package/src/tui/agent-browser.ts +354 -0
  901. package/src/tui/agent-controls.ts +355 -0
  902. package/src/tui/agent-conversation.ts +514 -0
  903. package/src/tui/agent-dock.ts +250 -0
  904. package/src/tui/agent-history.ts +78 -203
  905. package/src/tui/agent-model.ts +78 -0
  906. package/src/tui/agent-picker.ts +325 -0
  907. package/src/tui/agent-view.ts +391 -1333
  908. package/src/tui/compact-results.ts +342 -0
  909. package/src/tui/conversation-details.ts +206 -0
  910. package/src/tui/conversation-frame.ts +184 -0
  911. package/src/tui/conversation-history.ts +246 -0
  912. package/src/tui/conversation-menu.ts +119 -0
  913. package/src/tui/conversation-notices.ts +116 -0
  914. package/src/tui/conversation-selection.ts +66 -0
  915. package/src/tui/conversation-viewport.ts +169 -0
  916. package/src/tui/direction-message.ts +35 -0
  917. package/src/tui/display.ts +409 -0
  918. package/src/tui/editor-viewport.ts +19 -0
  919. package/src/tui/expanded-content.ts +134 -0
  920. package/src/tui/expanded-multi.ts +264 -0
  921. package/src/tui/expanded-single.ts +92 -0
  922. package/src/tui/history-cards.ts +316 -0
  923. package/src/tui/history-display.ts +334 -0
  924. package/src/tui/history-json.ts +17 -0
  925. package/src/tui/history-metadata.ts +177 -0
  926. package/src/tui/history-record.ts +321 -0
  927. package/src/tui/history-text.ts +34 -0
  928. package/src/tui/indexed-history.ts +149 -0
  929. package/src/tui/nested-widget.ts +192 -0
  930. package/src/tui/picker-page.ts +80 -0
  931. package/src/tui/render.ts +100 -1546
  932. package/src/tui/result-facts.ts +99 -0
  933. package/src/tui/task-observation.ts +96 -0
  934. package/src/tui/task-store.ts +432 -0
  935. package/src/tui/text-values.ts +20 -0
  936. package/src/tui/view-connections.ts +64 -0
  937. package/src/tui/view-model.ts +181 -0
  938. package/src/tui/view-persistence.ts +57 -0
  939. package/src/tui/view-ports.ts +55 -0
  940. package/src/tui/view-session.ts +42 -0
  941. package/src/tui/widget-details.ts +220 -0
  942. package/src/tui/widget-status.ts +331 -0
  943. package/src/tui/widget.ts +208 -0
  944. package/src/tui/workflow-labels.ts +340 -0
  945. package/src/tui/workflow-outcomes.ts +150 -0
  946. package/tsconfig.build.json +11 -10
  947. 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