@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
@@ -7,18 +7,21 @@ import net from "net";
7
7
  import { getPiAgentDir } from "../agent-dir.js";
8
8
  import { getBrokerSocketPath, getLegacyBrokerSocketPath, isOwnedBrokerSocket } from "./paths.js";
9
9
  import { isBrokerPidReused } from "./pid.js";
10
+ import { errorMessage, hasErrorCode } from "../../shared/unknown.js";
10
11
  const INTERCOM_DIR = join(getPiAgentDir(), "intercom");
11
12
  const EXTENSION_DIR = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
12
13
  const BROKER_PID = join(INTERCOM_DIR, "broker.pid");
13
14
  const BROKER_SPAWN_LOCK = join(INTERCOM_DIR, "broker.spawn.lock");
14
15
  function sleep(ms) {
15
- return new Promise(resolve => setTimeout(resolve, ms));
16
+ return new Promise((resolve) => {
17
+ setTimeout(resolve, ms);
18
+ });
16
19
  }
17
20
  function usesLegacyTsxDefault(brokerCommand, brokerArgs) {
18
- return brokerCommand === "npx"
19
- && brokerArgs.length === 2
20
- && brokerArgs[0] === "--no-install"
21
- && brokerArgs[1] === "tsx";
21
+ return (brokerCommand === "npx" &&
22
+ brokerArgs.length === 2 &&
23
+ brokerArgs[0] === "--no-install" &&
24
+ brokerArgs[1] === "tsx");
22
25
  }
23
26
  export function getBrokerLaunchSpec(brokerPath, brokerCommand, brokerArgs) {
24
27
  if (usesLegacyTsxDefault(brokerCommand, brokerArgs)) {
@@ -41,7 +44,7 @@ export function getBrokerSpawnOptions() {
41
44
  };
42
45
  }
43
46
  function toError(error) {
44
- return error instanceof Error ? error : new Error(String(error));
47
+ return error instanceof Error ? error : new Error(errorMessage(error));
45
48
  }
46
49
  export async function spawnBrokerIfNeeded(brokerCommand, brokerArgs) {
47
50
  await mkdir(INTERCOM_DIR, { recursive: true });
@@ -73,7 +76,7 @@ export async function spawnBrokerIfNeeded(brokerCommand, brokerArgs) {
73
76
  };
74
77
  const onExit = (code, signal) => {
75
78
  cleanup();
76
- if (signal) {
79
+ if (signal !== null) {
77
80
  reject(new Error(`Intercom broker exited before startup with signal ${signal}`));
78
81
  return;
79
82
  }
@@ -81,10 +84,12 @@ export async function spawnBrokerIfNeeded(brokerCommand, brokerArgs) {
81
84
  };
82
85
  child.once("error", onError);
83
86
  child.once("exit", onExit);
84
- waitForBroker().then(() => {
87
+ waitForBroker()
88
+ .then(() => {
85
89
  cleanup();
86
90
  resolve();
87
- }, (error) => {
91
+ })
92
+ .catch((error) => {
88
93
  cleanup();
89
94
  reject(toError(error));
90
95
  });
@@ -98,8 +103,9 @@ export async function isBrokerRunning() {
98
103
  return checkSocketConnectable();
99
104
  }
100
105
  function readLivePid() {
101
- if (!existsSync(BROKER_PID))
106
+ if (!existsSync(BROKER_PID)) {
102
107
  return null;
108
+ }
103
109
  let raw;
104
110
  try {
105
111
  raw = readFileSync(BROKER_PID, "utf-8");
@@ -108,30 +114,34 @@ function readLivePid() {
108
114
  return null;
109
115
  }
110
116
  const pid = parseInt(raw.trim(), 10);
111
- if (!Number.isFinite(pid) || pid <= 0)
117
+ if (!Number.isFinite(pid) || pid <= 0) {
112
118
  return null;
119
+ }
113
120
  try {
114
121
  process.kill(pid, 0);
115
122
  }
116
123
  catch (error) {
117
- return error.code === "EPERM" ? pid : null;
124
+ return hasErrorCode(error, "EPERM") ? pid : null;
118
125
  }
119
126
  return isBrokerPidReused(pid, raw) ? null : pid;
120
127
  }
121
128
  export async function stopUnhealthyBrokerBeforeSpawn() {
122
- if (await checkSocketConnectable())
129
+ if (await checkSocketConnectable()) {
123
130
  return;
131
+ }
124
132
  const pid = readLivePid();
125
- if (pid === null)
133
+ if (pid === null) {
126
134
  return;
135
+ }
127
136
  throw new Error(`Intercom broker PID ${pid} may still own accepted work but its socket is unhealthy; refusing to spawn a second broker. Let the broker exit normally, then retry.`);
128
137
  }
129
138
  async function checkSocketConnectable() {
130
139
  const preferred = getBrokerSocketPath();
131
- if (isOwnedBrokerSocket(preferred) && await checkOneSocket(preferred))
140
+ if (isOwnedBrokerSocket(preferred) && (await checkOneSocket(preferred))) {
132
141
  return true;
142
+ }
133
143
  const legacy = getLegacyBrokerSocketPath();
134
- return legacy !== preferred && isOwnedBrokerSocket(legacy) && await checkOneSocket(legacy);
144
+ return legacy !== preferred && isOwnedBrokerSocket(legacy) && (await checkOneSocket(legacy));
135
145
  }
136
146
  function checkOneSocket(brokerSocket) {
137
147
  return new Promise((resolve) => {
@@ -148,7 +158,7 @@ function checkOneSocket(brokerSocket) {
148
158
  socket.on("connect", onConnect);
149
159
  socket.on("error", onError);
150
160
  const timeout = setTimeout(() => finish(false), 1000);
151
- timeout.unref?.();
161
+ timeout.unref();
152
162
  });
153
163
  }
154
164
  function acquireSpawnLock() {
@@ -159,16 +169,11 @@ function acquireSpawnLock() {
159
169
  return true;
160
170
  }
161
171
  catch (error) {
162
- if (!(error instanceof Error) || error.code !== "EEXIST") {
172
+ if (!hasErrorCode(error, "EEXIST")) {
163
173
  throw error;
164
174
  }
165
175
  if (isSpawnLockStale()) {
166
- try {
167
- unlinkSync(BROKER_SPAWN_LOCK);
168
- }
169
- catch {
170
- // If we can't delete the stale lock, retry a few times before giving up
171
- }
176
+ releaseSpawnLock();
172
177
  continue;
173
178
  }
174
179
  return false;
@@ -181,7 +186,9 @@ function isSpawnLockStale() {
181
186
  return false;
182
187
  }
183
188
  try {
184
- const [pidLine = "", createdAtLine = "0"] = readFileSync(BROKER_SPAWN_LOCK, "utf-8").trim().split("\n");
189
+ const [pidLine = "", createdAtLine = "0"] = readFileSync(BROKER_SPAWN_LOCK, "utf-8")
190
+ .trim()
191
+ .split("\n");
185
192
  const pid = Number.parseInt(pidLine, 10);
186
193
  const createdAt = Number.parseInt(createdAtLine, 10);
187
194
  const ageMs = Date.now() - createdAt;
@@ -212,9 +219,13 @@ function releaseSpawnLock() {
212
219
  async function waitForBroker(timeoutMs = 5000) {
213
220
  const start = Date.now();
214
221
  while (Date.now() - start < timeoutMs) {
222
+ // Each probe must finish before the next to avoid parallel socket attempts.
223
+ // oxlint-disable-next-line no-await-in-loop
215
224
  if (await checkSocketConnectable()) {
216
225
  return;
217
226
  }
227
+ // Polling waits between probes rather than starting an unbounded batch.
228
+ // oxlint-disable-next-line no-await-in-loop
218
229
  await sleep(100);
219
230
  }
220
231
  throw new Error("Broker failed to start within timeout");
@@ -1,10 +1,8 @@
1
- import { existsSync, readFileSync } from "fs";
2
- import { join } from "path";
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
3
  import { Key } from "@earendil-works/pi-tui";
4
4
  import { getPiAgentDir } from "./agent-dir.js";
5
- function getConfigPath() {
6
- return join(getPiAgentDir(), "intercom", "config.json");
7
- }
5
+ import { isRecord, isUnknownArray } from "./validation.js";
8
6
  const defaults = {
9
7
  shortcut: Key.altShift("m"),
10
8
  brokerCommand: process.execPath,
@@ -20,80 +18,96 @@ function isShortcut(value) {
20
18
  const prefix = value.match(/^(?:(?:ctrl|shift|alt|super)\+)+/)?.[0] ?? "";
21
19
  const modifiers = prefix.split("+").filter(Boolean);
22
20
  const key = value.slice(prefix.length);
23
- return new Set(modifiers).size === modifiers.length && (namedKeys.has(key) || /^[a-z0-9]$/.test(key));
21
+ return (new Set(modifiers).size === modifiers.length && (namedKeys.has(key) || /^[a-z0-9]$/.test(key)));
22
+ }
23
+ function configuredString(parsed, key) {
24
+ if (!Object.hasOwn(parsed, key)) {
25
+ return defaults[key];
26
+ }
27
+ const value = parsed[key];
28
+ if (typeof value !== "string") {
29
+ throw new Error(`"${key}" must be a string`);
30
+ }
31
+ if (key === "status") {
32
+ return value;
33
+ }
34
+ if (value.trim() === "") {
35
+ throw new Error('"brokerCommand" must not be empty');
36
+ }
37
+ return value.trim();
38
+ }
39
+ function brokerCommand(parsed) {
40
+ return configuredString(parsed, "brokerCommand") ?? defaults.brokerCommand;
41
+ }
42
+ function configuredShortcut(parsed) {
43
+ if (!Object.hasOwn(parsed, "shortcut")) {
44
+ return defaults.shortcut;
45
+ }
46
+ if (typeof parsed.shortcut !== "string") {
47
+ throw new Error('"shortcut" must be a native key identifier');
48
+ }
49
+ const shortcut = parsed.shortcut.trim();
50
+ if (!isShortcut(shortcut)) {
51
+ throw new Error('"shortcut" must be a native key identifier, for example alt+shift+m');
52
+ }
53
+ return shortcut;
54
+ }
55
+ function configuredArgs(parsed) {
56
+ if (!Object.hasOwn(parsed, "brokerArgs")) {
57
+ return defaults.brokerArgs;
58
+ }
59
+ if (!isUnknownArray(parsed.brokerArgs)) {
60
+ throw new Error('"brokerArgs" must be an array');
61
+ }
62
+ return parsed.brokerArgs.map((arg) => {
63
+ if (typeof arg !== "string") {
64
+ throw new Error('"brokerArgs" items must be strings');
65
+ }
66
+ return arg;
67
+ });
68
+ }
69
+ function configuredBoolean(parsed, key) {
70
+ if (!Object.hasOwn(parsed, key)) {
71
+ return defaults[key];
72
+ }
73
+ const value = parsed[key];
74
+ if (typeof value !== "boolean") {
75
+ throw new Error(`"${key}" must be a boolean`);
76
+ }
77
+ return value;
78
+ }
79
+ function configuredTimeout(parsed, key) {
80
+ if (!Object.hasOwn(parsed, key)) {
81
+ return defaults[key];
82
+ }
83
+ const value = parsed[key];
84
+ const min = key === "askTimeoutMs" ? 1000 : 500;
85
+ if (typeof value !== "number" || !Number.isFinite(value) || value < min) {
86
+ throw new Error(`"${key}" must be a finite number >= ${min}`);
87
+ }
88
+ return value;
24
89
  }
25
90
  export function loadConfig() {
26
- const configPath = getConfigPath();
91
+ const configPath = join(getPiAgentDir(), "intercom", "config.json");
27
92
  if (!existsSync(configPath)) {
28
93
  return { ...defaults };
29
94
  }
30
95
  try {
31
- const raw = readFileSync(configPath, "utf-8");
32
- const parsed = JSON.parse(raw);
33
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
96
+ const parsed = JSON.parse(readFileSync(configPath, "utf-8"));
97
+ if (!isRecord(parsed)) {
34
98
  throw new Error("Config must be a JSON object");
35
99
  }
36
- const parsedConfig = parsed;
37
- const config = { ...defaults };
38
- if (Object.hasOwn(parsedConfig, "shortcut")) {
39
- if (typeof parsedConfig.shortcut !== "string")
40
- throw new Error('"shortcut" must be a native key identifier');
41
- const shortcut = parsedConfig.shortcut.trim();
42
- if (!isShortcut(shortcut))
43
- throw new Error('"shortcut" must be a native key identifier, for example alt+shift+m');
44
- config.shortcut = shortcut;
45
- }
46
- if (Object.hasOwn(parsedConfig, "brokerCommand")) {
47
- if (typeof parsedConfig.brokerCommand !== "string") {
48
- throw new Error(`"brokerCommand" must be a string`);
49
- }
50
- const brokerCommand = parsedConfig.brokerCommand.trim();
51
- if (!brokerCommand) {
52
- throw new Error(`"brokerCommand" must not be empty`);
53
- }
54
- config.brokerCommand = brokerCommand;
55
- }
56
- if (Object.hasOwn(parsedConfig, "brokerArgs")) {
57
- if (!Array.isArray(parsedConfig.brokerArgs)) {
58
- throw new Error(`"brokerArgs" must be an array`);
59
- }
60
- const brokerArgs = [];
61
- for (const arg of parsedConfig.brokerArgs) {
62
- if (typeof arg !== "string") {
63
- throw new Error(`"brokerArgs" items must be strings`);
64
- }
65
- brokerArgs.push(arg);
66
- }
67
- config.brokerArgs = brokerArgs;
68
- }
69
- if (Object.hasOwn(parsedConfig, "confirmSend")) {
70
- if (typeof parsedConfig.confirmSend !== "boolean") {
71
- throw new Error(`"confirmSend" must be a boolean`);
72
- }
73
- config.confirmSend = parsedConfig.confirmSend;
74
- }
75
- if (Object.hasOwn(parsedConfig, "replyHint")) {
76
- if (typeof parsedConfig.replyHint !== "boolean") {
77
- throw new Error(`"replyHint" must be a boolean`);
78
- }
79
- config.replyHint = parsedConfig.replyHint;
80
- }
81
- if (Object.hasOwn(parsedConfig, "status")) {
82
- if (typeof parsedConfig.status !== "string") {
83
- throw new Error(`"status" must be a string`);
84
- }
85
- config.status = parsedConfig.status;
86
- }
87
- for (const [key, min] of [["askTimeoutMs", 1000], ["sendTimeoutMs", 500], ["listTimeoutMs", 500]]) {
88
- if (Object.hasOwn(parsedConfig, key)) {
89
- const value = parsedConfig[key];
90
- if (typeof value !== "number" || !Number.isFinite(value) || value < min) {
91
- throw new Error(`"${key}" must be a finite number >= ${min}`);
92
- }
93
- config[key] = value;
94
- }
95
- }
96
- return config;
100
+ return {
101
+ shortcut: configuredShortcut(parsed),
102
+ brokerCommand: brokerCommand(parsed),
103
+ brokerArgs: configuredArgs(parsed),
104
+ confirmSend: configuredBoolean(parsed, "confirmSend"),
105
+ replyHint: configuredBoolean(parsed, "replyHint"),
106
+ status: configuredString(parsed, "status"),
107
+ askTimeoutMs: configuredTimeout(parsed, "askTimeoutMs"),
108
+ sendTimeoutMs: configuredTimeout(parsed, "sendTimeoutMs"),
109
+ listTimeoutMs: configuredTimeout(parsed, "listTimeoutMs"),
110
+ };
97
111
  }
98
112
  catch (error) {
99
113
  console.error(`Failed to load intercom config at ${configPath}:`, error);
@@ -0,0 +1,297 @@
1
+ import { createHash } from "node:crypto";
2
+ import { IntercomClient } from "./broker/client.js";
3
+ import { spawnBrokerIfNeeded } from "./broker/spawn.js";
4
+ import { asError, errorMessage } from "./validation.js";
5
+ import { formatTargetOptions, resolveSessionTarget } from "./session-targets.js";
6
+ /** Owns socket registration, coalesced connects and the reconnect/startup timers. */
7
+ export class IntercomConnection {
8
+ client = null;
9
+ reconnectTimer = null;
10
+ startupTimer = null;
11
+ connecting = null;
12
+ connectingGeneration = null;
13
+ attempt = 0;
14
+ syncError;
15
+ lifecycle;
16
+ config;
17
+ topics;
18
+ hooks;
19
+ constructor(lifecycle, config, topics, hooks) {
20
+ this.lifecycle = lifecycle;
21
+ this.config = config;
22
+ this.topics = topics;
23
+ this.hooks = hooks;
24
+ }
25
+ get active() {
26
+ return this.client;
27
+ }
28
+ get topicSyncError() {
29
+ return this.syncError;
30
+ }
31
+ get isConnecting() {
32
+ return this.startupTimer !== null || this.connecting !== null;
33
+ }
34
+ clearTopicSyncError() {
35
+ this.syncError = undefined;
36
+ }
37
+ start(ctx, generation) {
38
+ this.attempt = 0;
39
+ this.syncError = undefined;
40
+ this.clearTimers();
41
+ this.scheduleStartup(ctx, generation);
42
+ }
43
+ clearStartup() {
44
+ if (this.startupTimer) {
45
+ clearTimeout(this.startupTimer);
46
+ this.startupTimer = null;
47
+ }
48
+ }
49
+ clearReconnect() {
50
+ if (this.reconnectTimer) {
51
+ clearTimeout(this.reconnectTimer);
52
+ this.reconnectTimer = null;
53
+ }
54
+ }
55
+ clearTimers() {
56
+ this.clearStartup();
57
+ this.clearReconnect();
58
+ }
59
+ scheduleStartup(ctx, generation) {
60
+ this.clearStartup();
61
+ this.startupTimer = setTimeout(() => {
62
+ this.startupTimer = null;
63
+ if (!this.lifecycle.live(ctx, generation)) {
64
+ return;
65
+ }
66
+ this.ensure("startup").catch(() => {
67
+ if (!this.lifecycle.live(ctx, generation)) {
68
+ return;
69
+ }
70
+ this.client = null;
71
+ this.scheduleReconnect();
72
+ });
73
+ }, 0);
74
+ this.startupTimer.unref();
75
+ }
76
+ scheduleReconnect() {
77
+ if (this.reconnectTimer || this.connecting || !this.lifecycle.live()) {
78
+ return;
79
+ }
80
+ const generation = this.lifecycle.generation;
81
+ const delays = [1000, 2000, 5000, 10000, 30000];
82
+ const delay = delays[Math.min(this.attempt, delays.length - 1)] ?? 30000;
83
+ this.reconnectTimer = setTimeout(() => {
84
+ this.reconnectTimer = null;
85
+ if (this.lifecycle.generation !== generation || !this.lifecycle.live()) {
86
+ return;
87
+ }
88
+ this.attempt += 1;
89
+ this.ensure("background").catch(() => {
90
+ /* ensure owns the next retry after settlement. */
91
+ });
92
+ }, delay);
93
+ this.reconnectTimer.unref();
94
+ }
95
+ syncIdentity(sessionId) {
96
+ if (this.client && this.lifecycle.live()) {
97
+ this.client.updatePresence({
98
+ ...this.lifecycle.identity(sessionId),
99
+ status: this.lifecycle.status(),
100
+ ...this.lifecycle.health(this.hooks.pendingAsks()),
101
+ });
102
+ }
103
+ }
104
+ syncStatus() {
105
+ if (this.client && this.lifecycle.currentSessionId !== null && this.lifecycle.live()) {
106
+ this.client.updatePresence({
107
+ status: this.lifecycle.status(),
108
+ ...this.lifecycle.health(this.hooks.pendingAsks()),
109
+ });
110
+ }
111
+ }
112
+ createClient() {
113
+ const next = new IntercomClient({
114
+ sendTimeoutMs: this.config.sendTimeoutMs,
115
+ listTimeoutMs: this.config.listTimeoutMs,
116
+ });
117
+ this.client = next;
118
+ next.on("message", (from, message) => {
119
+ const ctx = this.lifecycle.live();
120
+ if (this.client !== next || !ctx) {
121
+ return;
122
+ }
123
+ this.hooks.incoming(ctx, from, message).catch((error) => {
124
+ console.error("Intercom inbound delivery failed:", error);
125
+ });
126
+ });
127
+ next.on("session_left", (id) => {
128
+ if (this.client !== next) {
129
+ return;
130
+ }
131
+ this.topics.disconnected(id);
132
+ this.hooks.peerLeft(id);
133
+ });
134
+ next.on("disconnected", (error) => {
135
+ if (this.client !== next) {
136
+ return;
137
+ }
138
+ this.hooks.disconnected(error);
139
+ this.client = null;
140
+ this.topics.disconnected();
141
+ this.clearReconnect();
142
+ this.scheduleReconnect();
143
+ });
144
+ next.on("error", () => {
145
+ /* Disconnect owns recovery; suppress socket noise in the TUI. */
146
+ });
147
+ return next;
148
+ }
149
+ async restoreTopics(active) {
150
+ const changes = [
151
+ ...[...this.topics.presence().topics].map((topic) => ({
152
+ action: "restore",
153
+ topic,
154
+ })),
155
+ ...[...this.topics.presence().subscriptions].map((subscription) => ({
156
+ action: "restore",
157
+ subscription,
158
+ })),
159
+ ];
160
+ let failure;
161
+ for (const change of changes) {
162
+ try {
163
+ // Restore order preserves publication/subscription admission and bounded transport pressure.
164
+ // oxlint-disable-next-line no-await-in-loop
165
+ await active.updateTopics(change);
166
+ }
167
+ catch (error) {
168
+ if (!active.isConnected()) {
169
+ throw error;
170
+ }
171
+ failure ??= errorMessage(error);
172
+ }
173
+ }
174
+ return failure;
175
+ }
176
+ async synchronizeTopics(next, ctx, generation) {
177
+ if (!next.supportsTopics) {
178
+ this.topics.disconnected();
179
+ return;
180
+ }
181
+ const failure = await this.restoreTopics(next);
182
+ const sessions = await next.listSessions();
183
+ if (!this.lifecycle.live(ctx, generation)) {
184
+ return;
185
+ }
186
+ this.syncError = failure;
187
+ this.topics.refresh(sessions);
188
+ if (failure !== undefined && failure !== "" && next.sessionId !== null) {
189
+ this.topics.disconnected(next.sessionId);
190
+ }
191
+ }
192
+ async connect(reason, ctx, generation, sessionId) {
193
+ const next = this.createClient();
194
+ try {
195
+ if (reason !== "peer-awareness") {
196
+ await spawnBrokerIfNeeded(this.config.brokerCommand, this.config.brokerArgs);
197
+ }
198
+ await next.connect(await this.lifecycle.registration(this.hooks.pendingAsks()), `pi-${createHash("sha256").update(sessionId).digest("hex").slice(0, 32)}`);
199
+ if (!this.lifecycle.live(ctx, generation)) {
200
+ await next.disconnect();
201
+ throw new Error("Intercom runtime no longer active");
202
+ }
203
+ this.client = next;
204
+ this.syncIdentity(ctx.sessionManager.getSessionId());
205
+ this.attempt = 0;
206
+ await this.synchronizeTopics(next, ctx, generation);
207
+ return next;
208
+ }
209
+ catch (error) {
210
+ if (this.client === next) {
211
+ this.client = null;
212
+ }
213
+ // A failed topic snapshot can leave a registered socket alive; the attempt still owns it.
214
+ await next.disconnect().catch((cleanupError) => {
215
+ console.error("Intercom failed connection cleanup:", cleanupError);
216
+ });
217
+ throw asError(error);
218
+ }
219
+ }
220
+ async ensure(reason) {
221
+ const generation = this.lifecycle.generation;
222
+ const restoring = this.hooks.restoring();
223
+ if (restoring) {
224
+ await restoring;
225
+ }
226
+ const ctx = this.lifecycle.live();
227
+ if (!ctx || generation !== this.lifecycle.generation) {
228
+ throw new Error("Intercom shutting down");
229
+ }
230
+ if (this.connecting && this.connectingGeneration === generation) {
231
+ return this.connecting;
232
+ }
233
+ if (this.client?.isConnected() === true) {
234
+ return this.client;
235
+ }
236
+ const sessionId = this.lifecycle.currentSessionId;
237
+ if (sessionId === null) {
238
+ throw new Error("Intercom runtime not initialized");
239
+ }
240
+ this.clearReconnect();
241
+ // Publish ownership before registration, which can synchronously invoke subscribers.
242
+ const attempt = Promise.resolve().then(() => this.connect(reason, ctx, generation, sessionId));
243
+ this.connecting = attempt;
244
+ this.connectingGeneration = generation;
245
+ return await this.finishAttempt(attempt, ctx, generation);
246
+ }
247
+ async finishAttempt(attempt, ctx, generation) {
248
+ let retry = false;
249
+ try {
250
+ return await attempt;
251
+ }
252
+ catch (error) {
253
+ retry = this.lifecycle.live(ctx, generation) !== null;
254
+ throw error;
255
+ }
256
+ finally {
257
+ if (this.connecting === attempt) {
258
+ this.connecting = null;
259
+ this.connectingGeneration = null;
260
+ }
261
+ if (retry) {
262
+ this.scheduleReconnect();
263
+ }
264
+ }
265
+ }
266
+ async shutdown() {
267
+ this.clearTimers();
268
+ // The bounded launcher attempt is joined before socket shutdown.
269
+ await Promise.allSettled([this.connecting]);
270
+ if (this.client) {
271
+ await this.client.disconnect();
272
+ this.client = null;
273
+ }
274
+ }
275
+ }
276
+ export async function resolveConnectedTarget(active, name) {
277
+ const sessions = await active.listSessions();
278
+ const resolution = resolveSessionTarget(sessions, name);
279
+ if (resolution.status === "found" && resolution.target) {
280
+ return resolution.target.id;
281
+ }
282
+ if (resolution.status === "ambiguous") {
283
+ throw new Error(`Target "${name}" matches multiple sessions. Use one of these targets: ${formatTargetOptions(resolution.matches, sessions)}.`);
284
+ }
285
+ if (resolution.status === "prefix_too_short") {
286
+ throw new Error(`Target "${name}" is too short. Use the displayed target from intercom list, such as ${formatTargetOptions(resolution.matches, sessions)}.`);
287
+ }
288
+ return null;
289
+ }
290
+ export async function resolvePeerHealth(active, id) {
291
+ try {
292
+ return (await active.listSessions()).find((session) => session.id === id) ?? null;
293
+ }
294
+ catch {
295
+ return null; /* Unknown health must not skip an ordinary blocking reply. */
296
+ }
297
+ }
@@ -0,0 +1,58 @@
1
+ function environmentText(name) {
2
+ return process.env[name]?.trim() ?? "";
3
+ }
4
+ export function readChildOrchestratorMetadata() {
5
+ const orchestratorTarget = environmentText("PI_SUBAGENT_ORCHESTRATOR_TARGET");
6
+ const runId = environmentText("PI_SUBAGENT_RUN_ID");
7
+ const agent = environmentText("PI_SUBAGENT_CHILD_AGENT");
8
+ const index = environmentText("PI_SUBAGENT_CHILD_INDEX");
9
+ if ([orchestratorTarget, runId, agent, index].includes("")) {
10
+ return null;
11
+ }
12
+ const sessionName = environmentText("PI_SUBAGENT_INTERCOM_SESSION_NAME");
13
+ return {
14
+ orchestratorTarget,
15
+ runId,
16
+ agent,
17
+ index,
18
+ ...(sessionName !== "" ? { sessionName } : {}),
19
+ };
20
+ }
21
+ export function formatChildOrchestratorMessage(kind, metadata, message) {
22
+ const headings = {
23
+ ask: "Subagent needs a supervisor decision.",
24
+ interview: "Subagent requests a structured supervisor interview.",
25
+ update: "Subagent progress update.",
26
+ };
27
+ return [
28
+ headings[kind],
29
+ `Run: ${metadata.runId}`,
30
+ `Agent: ${metadata.agent}`,
31
+ `Child index: ${metadata.index}`,
32
+ metadata.sessionName !== undefined && metadata.sessionName !== ""
33
+ ? `Child intercom target: ${metadata.sessionName}`
34
+ : undefined,
35
+ "",
36
+ message,
37
+ ]
38
+ .filter((line) => line !== undefined)
39
+ .join("\n");
40
+ }
41
+ export function resolveIntercomPresenceName(sessionName, sessionId) {
42
+ const name = sessionName?.trim();
43
+ if (name !== undefined && name !== "") {
44
+ return name;
45
+ }
46
+ const normalized = sessionId.startsWith("session-")
47
+ ? sessionId.slice("session-".length)
48
+ : sessionId;
49
+ return `subagent-chat-${normalized.slice(0, 8)}`;
50
+ }
51
+ export function buildPresenceIdentity(pi, sessionId) {
52
+ const name = process.env.PI_SUBAGENT_INTERCOM_SESSION_NAME?.trim();
53
+ return {
54
+ name: name !== undefined && name !== ""
55
+ ? name
56
+ : resolveIntercomPresenceName(pi.getSessionName(), sessionId),
57
+ };
58
+ }