@fitchmultz/pi-subagents 0.44.6 → 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 +265 -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 -1537
  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 +23 -18
  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 -1310
  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
@@ -0,0 +1,362 @@
1
+ import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
2
+ import type { ReadonlyInput } from "../shared/types/inputs.ts";
3
+ import type { Message, SendResult } from "./types.ts";
4
+ import type { IntercomLifecycle } from "./lifecycle.ts";
5
+ import { resolveConnectedTarget, type IntercomConnection } from "./connection.ts";
6
+ import type { ReplyWait } from "./reply-wait.ts";
7
+ import type {
8
+ ChildOrchestratorMetadata,
9
+ ContactSupervisorToolParams,
10
+ ToolResultLike,
11
+ } from "./runtime-types.ts";
12
+ import { formatChildOrchestratorMessage } from "./identity.ts";
13
+ import {
14
+ formatSupervisorInterviewRequest,
15
+ parseStructuredSupervisorReply,
16
+ validateSupervisorInterviewRequest,
17
+ type SupervisorInterviewRequest,
18
+ } from "./interview.ts";
19
+ import { errorMessage } from "./validation.ts";
20
+ import { formatAttachments } from "./message-format.ts";
21
+ import { toolError, toolText } from "./tool-arguments.ts";
22
+ import {
23
+ createSupervisorQuestion,
24
+ readQuestionState,
25
+ recordQuestionDelivery,
26
+ type SupervisorQuestion,
27
+ } from "../runs/shared/supervisor-questions.ts";
28
+ import { formatRunAction } from "../shared/status-format.ts";
29
+
30
+ type Lifecycle = Readonly<Pick<IntercomLifecycle, "identity" | "markActivity">>;
31
+ type Connection = Readonly<Pick<IntercomConnection, "ensure" | "syncIdentity" | "syncStatus">>;
32
+ type ReplyWaitHandle = Readonly<
33
+ Pick<ReplyWait, "clearRetry" | "isWaitingFor" | "retarget" | "retry" | "wait" | "waiting">
34
+ >;
35
+
36
+ interface SupervisorOwners {
37
+ readonly pi: ExtensionAPI;
38
+ readonly lifecycle: Lifecycle;
39
+ readonly connection: Connection;
40
+ readonly wait: ReplyWaitHandle;
41
+ }
42
+ interface DecisionRequest {
43
+ readonly reason: "need_decision" | "interview_request";
44
+ readonly message?: string;
45
+ readonly interview?: SupervisorInterviewRequest;
46
+ readonly signal?: AbortSignal;
47
+ readonly ctx: ExtensionContext;
48
+ }
49
+ interface Notification {
50
+ readonly question: ReadonlyInput<SupervisorQuestion>;
51
+ readonly text: string;
52
+ readonly reason: DecisionRequest["reason"];
53
+ }
54
+ function validateContact(params: ContactSupervisorToolParams): ToolResultLike | undefined {
55
+ const { reason, message } = params;
56
+ if (!["need_decision", "progress_update", "interview_request"].includes(reason)) {
57
+ return toolError(
58
+ "Invalid reason. Use 'need_decision', 'interview_request', or 'progress_update'.",
59
+ );
60
+ }
61
+ if ((reason === "need_decision" || reason === "progress_update") && typeof message !== "string") {
62
+ return toolError(`Missing 'message' parameter for reason '${reason}'.`);
63
+ }
64
+ return;
65
+ }
66
+ function replyDetails(
67
+ questionId: string,
68
+ text: string,
69
+ interview: SupervisorInterviewRequest | undefined,
70
+ ): Readonly<Record<string, unknown>> {
71
+ const structured = interview ? parseStructuredSupervisorReply(text, interview) : undefined;
72
+ if (structured?.value) {
73
+ return { questionId, structuredReply: structured.value };
74
+ }
75
+ if (structured?.error !== undefined && structured.error !== "") {
76
+ return { questionId, structuredReplyParseError: structured.error };
77
+ }
78
+ return { questionId };
79
+ }
80
+ /** Owns durable supervisor questions and every wake-notification attempt. */
81
+ export class IntercomSupervisor {
82
+ private readonly owners: SupervisorOwners;
83
+ private readonly metadata: ChildOrchestratorMetadata;
84
+ private readonly notifications = new Set<Promise<void>>();
85
+ constructor(owners: SupervisorOwners, metadata: ChildOrchestratorMetadata) {
86
+ this.owners = owners;
87
+ this.metadata = metadata;
88
+ }
89
+ async drain(): Promise<void> {
90
+ await Promise.allSettled(this.notifications);
91
+ }
92
+ private createQuestion(request: DecisionRequest): {
93
+ readonly question: ReadonlyInput<SupervisorQuestion>;
94
+ readonly text: string;
95
+ } {
96
+ const { reason, interview, ctx } = request;
97
+ const body = interview
98
+ ? formatSupervisorInterviewRequest(interview, request.message)
99
+ : (request.message ?? "");
100
+ const metadata = this.metadata;
101
+ const question = createSupervisorQuestion({
102
+ runId: metadata.runId,
103
+ ownerTarget: metadata.orchestratorTarget,
104
+ agent: metadata.agent,
105
+ index: Number(metadata.index),
106
+ childSessionId: ctx.sessionManager.getSessionId(),
107
+ childTarget:
108
+ metadata.sessionName ??
109
+ this.owners.lifecycle.identity(ctx.sessionManager.getSessionId()).name,
110
+ sessionFile: ctx.sessionManager.getSessionFile() ?? "",
111
+ cwd: ctx.cwd,
112
+ pid: process.pid,
113
+ reason,
114
+ message: body,
115
+ ...(interview ? { interview } : {}),
116
+ });
117
+ const text = formatChildOrchestratorMessage(
118
+ interview ? "interview" : "ask",
119
+ metadata,
120
+ [
121
+ `Question ID: ${question.questionId}`,
122
+ `Answer after reconnect/reload: ${formatRunAction("answer", question.runId, { questionId: question.questionId, message: "..." }, Number(process.env.PI_SUBAGENT_DEPTH) > 1)}`,
123
+ body,
124
+ ].join("\n"),
125
+ );
126
+ return { question, text };
127
+ }
128
+ private ownNotification(operation: () => Promise<void>): void {
129
+ const task = Promise.resolve().then(operation);
130
+ this.notifications.add(task);
131
+ task
132
+ .then(
133
+ () => {
134
+ this.notifications.delete(task);
135
+ },
136
+ (error: unknown) => {
137
+ this.notifications.delete(task);
138
+ console.error("Intercom supervisor notification failed:", error);
139
+ },
140
+ )
141
+ .catch((error: unknown) => {
142
+ console.error("Intercom supervisor notification cleanup failed:", error);
143
+ });
144
+ }
145
+ private scheduleNotification(notification: Notification): void {
146
+ let retryAfter = 0;
147
+ let failureLogged = false;
148
+ const { question, text, reason } = notification;
149
+ const active = () => this.owners.wait.isWaitingFor(question.questionId);
150
+ const logFailure = (error: unknown) => {
151
+ if (active() && !failureLogged) {
152
+ this.owners.pi.appendEntry("intercom_question_notification_error", {
153
+ questionId: question.questionId,
154
+ error: errorMessage(error),
155
+ });
156
+ failureLogged = true;
157
+ }
158
+ };
159
+ const recordNotification = (to: string, sent: SendResult) => {
160
+ if (sent.accepted || !failureLogged) {
161
+ this.owners.pi.appendEntry("intercom_sent", {
162
+ to,
163
+ messageId: question.questionId,
164
+ message: { text, reason },
165
+ accepted: sent.accepted,
166
+ timestamp: Date.now(),
167
+ });
168
+ }
169
+ failureLogged ||= !sent.accepted;
170
+ };
171
+ const notify = async () => {
172
+ if (!active() || Date.now() < retryAfter) {
173
+ return;
174
+ }
175
+ this.owners.wait.clearRetry(question.questionId);
176
+ let retry = true;
177
+ try {
178
+ const client = await this.owners.connection.ensure("tool");
179
+ if (!active()) {
180
+ return;
181
+ }
182
+ const to =
183
+ (await resolveConnectedTarget(client, this.metadata.orchestratorTarget)) ??
184
+ this.metadata.orchestratorTarget;
185
+ if (!active()) {
186
+ return;
187
+ }
188
+ this.owners.wait.retarget(question.questionId, to);
189
+ // A thrown send may have lost only its acknowledgement; replay only explicit rejection.
190
+ retry = false;
191
+ const sent = await client.send(to, {
192
+ text,
193
+ messageId: question.questionId,
194
+ expectsReply: true,
195
+ delivery: "steer",
196
+ });
197
+ if (!active()) {
198
+ return;
199
+ }
200
+ retry = !sent.accepted;
201
+ recordNotification(to, sent);
202
+ } catch (error) {
203
+ logFailure(error);
204
+ } finally {
205
+ if (retry && active()) {
206
+ retryAfter = Date.now() + 1000;
207
+ this.owners.wait.retry(question.questionId, () => {
208
+ this.ownNotification(notify);
209
+ });
210
+ }
211
+ }
212
+ };
213
+ this.ownNotification(notify);
214
+ }
215
+ private async decision(request: DecisionRequest): Promise<ToolResultLike> {
216
+ if (this.owners.wait.waiting) {
217
+ throw new Error("Already waiting for a reply");
218
+ }
219
+ if (request.signal?.aborted === true) {
220
+ throw new Error("Cancelled");
221
+ }
222
+ const { question, text } = this.createQuestion(request);
223
+ const reply = this.owners.wait.wait({
224
+ from: this.metadata.orchestratorTarget,
225
+ replyTo: question.questionId,
226
+ signal: request.signal,
227
+ question,
228
+ });
229
+ this.scheduleNotification({ question, text, reason: request.reason });
230
+ const message = await reply;
231
+ return this.answer(question, message, request.interview);
232
+ }
233
+ private answer(
234
+ question: ReadonlyInput<SupervisorQuestion>,
235
+ message: Message,
236
+ interview: SupervisorInterviewRequest | undefined,
237
+ ): ToolResultLike {
238
+ this.owners.pi.appendEntry("intercom_received", {
239
+ from: this.metadata.orchestratorTarget,
240
+ questionId: question.questionId,
241
+ message: message.content,
242
+ messageId: message.id,
243
+ timestamp: message.timestamp,
244
+ });
245
+ recordQuestionDelivery(question, {
246
+ kind: "live",
247
+ runId: question.runId,
248
+ deliveredAt: Date.now(),
249
+ });
250
+ const details = replyDetails(question.questionId, message.content.text, interview);
251
+ const origin = readQuestionState(question).answer?.origin;
252
+ return toolText(
253
+ `**${origin === "human" ? "Direct user answer (human origin)" : "Reply from supervisor"}:**\n${message.content.text}${formatAttachments(message.content.attachments ?? [])}`,
254
+ details,
255
+ );
256
+ }
257
+ private async progress(
258
+ message: string,
259
+ signal: AbortSignal | undefined,
260
+ ctx: ExtensionContext,
261
+ ): Promise<ToolResultLike> {
262
+ let client;
263
+ try {
264
+ client = await this.owners.connection.ensure("tool");
265
+ } catch (error) {
266
+ return toolError(`Intercom not connected: ${errorMessage(error)}`);
267
+ }
268
+ this.owners.connection.syncIdentity(ctx.sessionManager.getSessionId());
269
+ if (signal?.aborted === true) {
270
+ return toolError("Cancelled");
271
+ }
272
+ let to: string;
273
+ try {
274
+ to =
275
+ (await resolveConnectedTarget(client, this.metadata.orchestratorTarget)) ??
276
+ this.metadata.orchestratorTarget;
277
+ } catch (error) {
278
+ return toolError(`Failed to resolve supervisor target: ${errorMessage(error)}`);
279
+ }
280
+ if (this.cancelled(signal)) {
281
+ return toolError("Cancelled");
282
+ }
283
+ if (to === client.sessionId) {
284
+ return toolError("Cannot message the current session");
285
+ }
286
+ try {
287
+ const result = await client.send(to, {
288
+ text: formatChildOrchestratorMessage("update", this.metadata, message),
289
+ delivery: "steer",
290
+ });
291
+ return this.progressReceipt(message, result);
292
+ } catch (error) {
293
+ return toolError(`Failed to send progress update: ${errorMessage(error)}`);
294
+ }
295
+ }
296
+ private progressReceipt(message: string, result: SendResult): ToolResultLike {
297
+ if (!result.accepted) {
298
+ return toolError(
299
+ `Message to "${this.metadata.orchestratorTarget}" was not delivered: ${result.reason ?? "Session may not exist or has disconnected."}`,
300
+ {
301
+ messageId: result.id,
302
+ accepted: result.accepted,
303
+ delivered: false,
304
+ reason: result.reason,
305
+ },
306
+ );
307
+ }
308
+ this.owners.lifecycle.markActivity();
309
+ this.owners.connection.syncStatus();
310
+ this.owners.pi.appendEntry("intercom_sent", {
311
+ to: this.metadata.orchestratorTarget,
312
+ message: { text: message, reason: "progress_update" },
313
+ messageId: result.id,
314
+ timestamp: Date.now(),
315
+ subagent: {
316
+ runId: this.metadata.runId,
317
+ agent: this.metadata.agent,
318
+ index: this.metadata.index,
319
+ },
320
+ });
321
+ return toolText(
322
+ `Progress update accepted for supervisor ${this.metadata.orchestratorTarget}. Queued for the next tool boundary; broker acceptance does not confirm the supervisor has read or acted on it.`,
323
+ {
324
+ messageId: result.id,
325
+ accepted: result.accepted,
326
+ delivered: result.delivered,
327
+ queued: result.queued === true,
328
+ },
329
+ );
330
+ }
331
+ private cancelled(signal: AbortSignal | undefined): boolean {
332
+ return signal?.aborted === true;
333
+ }
334
+ async execute(
335
+ params: ContactSupervisorToolParams,
336
+ signal: AbortSignal | undefined,
337
+ ctx: ExtensionContext,
338
+ ): Promise<ToolResultLike> {
339
+ const { reason, message } = params;
340
+ const invalid = validateContact(params);
341
+ if (invalid) {
342
+ return invalid;
343
+ }
344
+ if (reason === "progress_update") {
345
+ return await this.progress(message ?? "", signal, ctx);
346
+ }
347
+ const validation =
348
+ reason === "interview_request"
349
+ ? validateSupervisorInterviewRequest(params.interview)
350
+ : undefined;
351
+ if (validation?.ok === false) {
352
+ return toolError(`Invalid interview request: ${validation.error}`);
353
+ }
354
+ return await this.decision({
355
+ reason,
356
+ message,
357
+ interview: validation?.ok === true ? validation.interview : undefined,
358
+ signal,
359
+ ctx,
360
+ });
361
+ }
362
+ }
@@ -0,0 +1,120 @@
1
+ import type { IntercomToolParams, ToolResultLike } from "./runtime-types.ts";
2
+ import { failureDetails } from "./tool-results.ts";
3
+ export function toolError(
4
+ text: string,
5
+ details: Readonly<Record<string, unknown>> = { error: true },
6
+ ): ToolResultLike {
7
+ return { content: [{ type: "text", text }], isError: true, details };
8
+ }
9
+ export function toolText(
10
+ text: string,
11
+ details: Readonly<Record<string, unknown>> = {},
12
+ ): ToolResultLike {
13
+ return { content: [{ type: "text", text }], isError: false, details };
14
+ }
15
+ function deliveryError(params: IntercomToolParams): ToolResultLike | undefined {
16
+ const { action, delivery, passive } = params;
17
+ if (passive !== undefined && action !== "send") {
18
+ return toolError("'passive' is only valid for action='send'");
19
+ }
20
+ if (delivery === "passive" && action !== "send") {
21
+ return toolError(
22
+ "delivery='passive' is only valid for action='send'. Passive delivery is for human-visible breadcrumbs and is discouraged for agent-to-agent coordination; normal send defaults to steer. Use ask with delivery='steer' only when the sender must stay alive and cannot safely continue without the reply.",
23
+ );
24
+ }
25
+ const actionError = deliveryActionError(params);
26
+ if (actionError) {
27
+ return actionError;
28
+ }
29
+ if (passive === true && delivery !== undefined && delivery !== "passive") {
30
+ return toolError("'passive' cannot be combined with a non-passive delivery mode");
31
+ }
32
+ return;
33
+ }
34
+ function deliveryActionError(params: IntercomToolParams): ToolResultLike | undefined {
35
+ const { action, delivery, queueMode, threadId } = params;
36
+ if (
37
+ (delivery !== undefined || queueMode !== undefined || threadId !== undefined) &&
38
+ action !== "send" &&
39
+ action !== "ask"
40
+ ) {
41
+ const queue = queueMode !== undefined || delivery === "queue" || threadId !== undefined;
42
+ return toolError(
43
+ "'delivery', 'queueMode', and 'threadId' are only valid for action='send' or action='ask'",
44
+ failureDetails(
45
+ queue ? "invalid_queue_arguments" : "invalid_delivery_arguments",
46
+ [{ action: "send", guidance: "Use delivery options only with send or ask." }],
47
+ { error: true },
48
+ ),
49
+ );
50
+ }
51
+ return;
52
+ }
53
+ function queueError(params: IntercomToolParams): ToolResultLike | undefined {
54
+ const { threadId, queueMode } = params;
55
+ if (threadId !== undefined && queueMode !== "replace") {
56
+ return toolError(
57
+ "'threadId' is only valid with queueMode='replace'",
58
+ failureDetails(
59
+ "invalid_queue_arguments",
60
+ [
61
+ {
62
+ action: "send",
63
+ guidance: "Use threadId only with delivery='queue' and queueMode='replace'.",
64
+ },
65
+ ],
66
+ { error: true },
67
+ ),
68
+ );
69
+ }
70
+ if (queueMode === "replace" && (threadId === undefined || threadId.trim() === "")) {
71
+ return toolError(
72
+ "queueMode='replace' requires a non-empty threadId",
73
+ failureDetails(
74
+ "invalid_queue_arguments",
75
+ [
76
+ {
77
+ action: "send",
78
+ guidance: "Provide a non-empty threadId with delivery='queue' and queueMode='replace'.",
79
+ },
80
+ ],
81
+ { error: true },
82
+ ),
83
+ );
84
+ }
85
+ const delivery = params.passive === true ? "passive" : params.delivery;
86
+ if (queueMode !== undefined && delivery !== "queue") {
87
+ return toolError(
88
+ "'queueMode' is only valid with delivery='queue'. Use queue only for intentionally deferred work; otherwise omit queueMode and use default-steered send for live agent coordination. Avoid passive for agent-to-agent coordination.",
89
+ failureDetails(
90
+ "invalid_queue_arguments",
91
+ [{ action: "send", guidance: "Set delivery='queue', or omit queueMode and threadId." }],
92
+ { error: true },
93
+ ),
94
+ );
95
+ }
96
+ return;
97
+ }
98
+ export function validateIntercomArguments(params: IntercomToolParams): ToolResultLike | undefined {
99
+ if (params.scope !== undefined && params.action !== "list" && params.action !== "status") {
100
+ return toolError("'scope' is only valid for action='list' or action='status'");
101
+ }
102
+ return deliveryError(params) ?? queueError(params);
103
+ }
104
+ export function sendOptions(params: IntercomToolParams): {
105
+ readonly text: string;
106
+ readonly attachments: IntercomToolParams["attachments"];
107
+ readonly replyTo: string | undefined;
108
+ readonly delivery: IntercomToolParams["delivery"];
109
+ readonly queueMode: IntercomToolParams["queueMode"];
110
+ readonly threadId: string | undefined;
111
+ } {
112
+ return {
113
+ text: params.message ?? "",
114
+ attachments: params.attachments,
115
+ replyTo: params.replyTo,
116
+ delivery: params.passive === true ? "passive" : params.delivery,
117
+ queueMode: params.queueMode,
118
+ threadId: params.threadId?.trim(),
119
+ };
120
+ }
@@ -0,0 +1,121 @@
1
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
+ import type { IntercomTools } from "./tools.ts";
3
+ import type { IntercomSupervisor } from "./supervisor.ts";
4
+ import type { ToolResultLike } from "./runtime-types.ts";
5
+ import { Type } from "../shared/native-typebox.ts";
6
+ import { activateTools } from "../shared/lazy-tools.ts";
7
+ import { throwIfToolError } from "./tool-results.ts";
8
+ import { intercomSchema, contactSupervisorSchema } from "./tool-schemas.ts";
9
+ import {
10
+ renderContactCall,
11
+ renderContactResult,
12
+ renderIntercomCall,
13
+ renderIntercomResult,
14
+ } from "./ui/tool-renderers.ts";
15
+ type MessagingTool = Readonly<Pick<IntercomTools, "execute">>;
16
+ type SupervisorTool = Readonly<Pick<IntercomSupervisor, "execute">>;
17
+
18
+ function nativeResult(result: ToolResultLike): {
19
+ content: { type: "text"; text: string }[];
20
+ details: Readonly<Record<string, unknown>> | undefined;
21
+ isError: false;
22
+ } {
23
+ const success = throwIfToolError(result);
24
+ return { content: [...success.content], details: success.details, isError: false };
25
+ }
26
+ function registerContact(pi: ExtensionAPI, supervisor: SupervisorTool): void {
27
+ pi.registerTool({
28
+ name: "contact_supervisor",
29
+ label: "Contact Supervisor",
30
+ description:
31
+ "Subagent-only tool for contacting the supervisor agent that delegated this task. Use need_decision only when this child cannot safely continue without a decision, approval, or product/API/scope clarification; this steers the supervisor at its next tool boundary and keeps the child alive for the reply. Use interview_request only when multiple structured answers are all required before safe progress; this also steers and waits. Use progress_update only for a discovery or change the supervisor needs while working; it steers at the next tool boundary without waiting for a reply. Skip starts, redundant status, and routine completion; retain material findings in the final result.",
32
+ promptSnippet:
33
+ "Subagent-only: steer the supervisor for required decisions, structured interviews, or material discoveries needed during active work. Skip routine status and completion messages.",
34
+ promptGuidelines: [
35
+ "Use contact_supervisor with reason='need_decision' when a subagent cannot safely continue without a decision, approval, or product/API/scope clarification; it steers the supervisor and waits for the reply.",
36
+ "Use contact_supervisor with reason='interview_request' only when the child cannot safely continue until it receives multiple structured answers in one blocking steered exchange.",
37
+ "Use contact_supervisor with reason='progress_update' only for a discovery or change the supervisor needs while working. It steers at the next tool boundary without waiting. Skip starts, redundant narration, and routine completion; keep material findings in the final result.",
38
+ "Do not use contact_supervisor for routine completion handoffs; return the final subagent result normally.",
39
+ ],
40
+ parameters: contactSupervisorSchema,
41
+ async execute(_id, params, signal, _update, ctx) {
42
+ return nativeResult(await supervisor.execute(params, signal, ctx));
43
+ },
44
+ renderCall: renderContactCall,
45
+ renderResult: renderContactResult,
46
+ });
47
+ }
48
+ function registerLoader(pi: ExtensionAPI): void {
49
+ pi.registerTool({
50
+ name: "load_intercom",
51
+ label: "Load Intercom",
52
+ description:
53
+ "Enable local peer coordination: list/check sessions before shared-state work, send or reply to messages, and inspect/publish topics. Does not send a message or check peers itself.",
54
+ parameters: Type.Object({}),
55
+ async execute() {
56
+ if (
57
+ !pi.getAllTools().some((tool) => tool.name === "intercom" && tool.namespace === undefined)
58
+ ) {
59
+ throw new Error("Intercom is excluded from this session.");
60
+ }
61
+ activateTools(pi, ["intercom"]);
62
+ return {
63
+ content: [
64
+ {
65
+ type: "text",
66
+ text: "Intercom enabled. Use intercom({action:'list'}) to check peers, or status, pending, reply, send, ask and topics for coordination.",
67
+ },
68
+ ],
69
+ details: {},
70
+ };
71
+ },
72
+ });
73
+ }
74
+ function registerMessaging(pi: ExtensionAPI, tools: MessagingTool): void {
75
+ pi.registerTool({
76
+ name: "intercom",
77
+ defaultActive: false,
78
+ label: "Intercom",
79
+ description: `Send a message to another pi session running on this machine.
80
+ Use this to communicate findings, request help, or coordinate work with other sessions.
81
+ Non-blocking send defaults to steer for guidance, answers, corrections, or blockers that may affect active work. Use queue only when delay is intentional; use ask only when this process must remain alive waiting for the reply.
82
+
83
+ Usage:
84
+ intercom({ action: "list" }) → List sessions in this repository and its worktrees
85
+ intercom({ action: "list", scope: "all" }) → List connected sessions across every project
86
+ intercom({ action: "send", to: "session-name", message: "..." }) → Send live coordination (defaults to steer)
87
+ intercom({ action: "ask", to: "session-name", delivery: "steer", message: "..." }) → Blocking wait only when sender must stay alive
88
+ intercom({ action: "reply", message: "..." }) → Reply to the active/single pending ask
89
+ intercom({ action: "pending" }) → List unresolved inbound asks
90
+ intercom({ action: "status" }) → Show connection status
91
+ intercom({ action: "subscribe", topic: "project/work", awaitRelease: true }) → Opt into a topic
92
+ intercom({ action: "publish", topic: "project/work", message: "Current self-contained state" }) → Quiet latest state
93
+ intercom({ action: "topics" }) → Inspect topics and current resource owners`,
94
+ promptSnippet:
95
+ "Coordinate with local Pi sessions. Non-blocking send defaults to steer for live agent guidance; queue only for intentional delay and ask only for a required blocking reply.",
96
+ promptGuidelines: [
97
+ "Intercom list/status defaults to the current Git repository and its worktrees. Use scope='all' only when intentionally discovering sessions in other projects.",
98
+ "Action='send' defaults to delivery='steer' for agent-to-agent guidance, answers, corrections, blockers, or other context that may affect active work.",
99
+ "Use delivery='queue' only when delay is intentional. For routine status, explicitly subscribe/publish topics: updates replace quiet inspectable state outside model context, not passive conversation messages. Topic blockers/decisions and awaited ownership releases interrupt; direct messages always bypass subscriptions.",
100
+ "Treat inbound steered messages as supplemental coordination within the active task: incorporate relevant context and continue; replace the task only when the message explicitly says so.",
101
+ "Use action='reply' for an active inbound ask. Otherwise respond with send plus steer; use blocking ask only when this process must stay alive and cannot safely continue without the answer.",
102
+ ],
103
+ parameters: intercomSchema,
104
+ async execute(_id, params, signal, _update, ctx) {
105
+ return nativeResult(await tools.execute(params, signal, ctx));
106
+ },
107
+ renderCall: renderIntercomCall,
108
+ renderResult: renderIntercomResult,
109
+ });
110
+ }
111
+ export function registerIntercomTools(
112
+ pi: ExtensionAPI,
113
+ tools: MessagingTool,
114
+ supervisor: SupervisorTool | null,
115
+ ): void {
116
+ if (supervisor) {
117
+ registerContact(pi, supervisor);
118
+ }
119
+ registerLoader(pi);
120
+ registerMessaging(pi, tools);
121
+ }
@@ -0,0 +1,54 @@
1
+ import type { SendResult } from "./types.ts";
2
+ import type { ToolResultLike } from "./runtime-types.ts";
3
+ export interface RecoveryAction {
4
+ readonly action: "list" | "pending" | "send" | "status";
5
+ readonly guidance?: string;
6
+ }
7
+ export function failureDetails(
8
+ reasonCode: string,
9
+ nextActions: readonly RecoveryAction[],
10
+ details: Readonly<Record<string, unknown>> = {},
11
+ ): Readonly<Record<string, unknown>> {
12
+ return { ...details, reasonCode, nextActions };
13
+ }
14
+ export function replyFailureReason(
15
+ message: string,
16
+ ): "no_pending_reply" | "ambiguous_reply_target" | "reply_failed" {
17
+ if (message.startsWith("No active intercom context") || message.startsWith("No pending ask")) {
18
+ return "no_pending_reply";
19
+ }
20
+ if (message.startsWith("Multiple pending asks") || message.includes("too short")) {
21
+ return "ambiguous_reply_target";
22
+ }
23
+ return "reply_failed";
24
+ }
25
+ export function firstTextContent(result: {
26
+ readonly content?: readonly { readonly type: string; readonly text?: string }[];
27
+ }): string {
28
+ return (
29
+ result.content
30
+ ?.find((item) => item.type === "text" && typeof item.text === "string")
31
+ ?.text?.replace(/\*\*/g, "") ?? ""
32
+ );
33
+ }
34
+ export class ToolExecutionFailure extends Error {
35
+ readonly details?: Readonly<Record<string, unknown>>;
36
+ constructor(message: string, details?: Readonly<Record<string, unknown>>) {
37
+ super(message);
38
+ this.details = details;
39
+ }
40
+ }
41
+ export class AskDeliveryError extends Error {
42
+ readonly result: SendResult;
43
+ constructor(result: SendResult) {
44
+ super(result.reason ?? "Session may not exist or has disconnected.");
45
+ this.result = result;
46
+ }
47
+ }
48
+ export function throwIfToolError(result: ToolResultLike): ToolResultLike {
49
+ if (result.isError !== true) {
50
+ return result;
51
+ }
52
+ const text = firstTextContent(result);
53
+ throw new ToolExecutionFailure(text === "" ? "Tool failed" : text, result.details);
54
+ }