@selesai/code 0.8.3 → 0.8.5

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 (518) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +7 -1
  3. package/dist/core/slash-commands.js +1 -0
  4. package/dist/defaults/models.json +41 -55
  5. package/dist/defaults/settings.json +7 -8
  6. package/dist/extensions/handoff-new.ts +1 -1
  7. package/dist/extensions/inline-skills.test.ts +1 -0
  8. package/dist/extensions/inline-skills.ts +1 -1
  9. package/dist/extensions/pi-intercom/CHANGELOG.md +25 -3
  10. package/dist/extensions/pi-intercom/README.md +34 -15
  11. package/dist/extensions/pi-intercom/broker/broker.ts +38 -141
  12. package/dist/extensions/pi-intercom/broker/client-liveness.test.ts +173 -0
  13. package/dist/extensions/pi-intercom/broker/client.ts +78 -150
  14. package/dist/extensions/pi-intercom/broker/extension-state.ts +18 -7
  15. package/dist/extensions/pi-intercom/broker/framing.ts +1 -1
  16. package/dist/extensions/pi-intercom/broker/protocol.ts +182 -0
  17. package/dist/extensions/pi-intercom/broker/spawn.test.ts +106 -7
  18. package/dist/extensions/pi-intercom/broker/spawn.ts +37 -11
  19. package/dist/extensions/pi-intercom/config.test.ts +8 -10
  20. package/dist/extensions/pi-intercom/config.ts +3 -3
  21. package/dist/extensions/pi-intercom/index.ts +218 -147
  22. package/dist/extensions/pi-intercom/intercom.integration.test.ts +891 -103
  23. package/dist/extensions/pi-intercom/package.json +3 -2
  24. package/dist/extensions/pi-intercom/project-agent.test.ts +145 -0
  25. package/dist/extensions/pi-intercom/project-agent.ts +324 -0
  26. package/dist/extensions/pi-intercom/reply-tracker.test.ts +86 -1
  27. package/dist/extensions/pi-intercom/reply-tracker.ts +41 -9
  28. package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +49 -9
  29. package/dist/extensions/pi-intercom/test/inline-message.test.ts +9 -9
  30. package/dist/extensions/pi-intercom/types.ts +3 -1
  31. package/dist/extensions/pi-intercom/ui/inline-message.ts +7 -7
  32. package/dist/extensions/pi-powerline-footer/.github/workflows/test.yml +2 -2
  33. package/dist/extensions/pi-powerline-footer/CHANGELOG.md +14 -1
  34. package/dist/extensions/pi-powerline-footer/README.md +20 -37
  35. package/dist/extensions/pi-powerline-footer/bash-mode/completion.ts +40 -25
  36. package/dist/extensions/pi-powerline-footer/bash-mode/editor.ts +149 -18
  37. package/dist/extensions/pi-powerline-footer/bash-mode/types.ts +1 -0
  38. package/dist/extensions/pi-powerline-footer/editor-performance.ts +99 -0
  39. package/dist/extensions/pi-powerline-footer/git-status.ts +15 -0
  40. package/dist/extensions/pi-powerline-footer/index.ts +394 -317
  41. package/dist/extensions/pi-powerline-footer/package.json +1 -1
  42. package/dist/extensions/pi-powerline-footer/powerline-config.ts +0 -12
  43. package/dist/extensions/pi-powerline-footer/queue/store.ts +8 -56
  44. package/dist/extensions/pi-powerline-footer/queue/types.ts +1 -2
  45. package/dist/extensions/pi-powerline-footer/segments.ts +0 -3
  46. package/dist/extensions/pi-powerline-footer/tests/bash-mode.test.ts +231 -1
  47. package/dist/extensions/pi-powerline-footer/tests/custom-items.test.ts +5 -19
  48. package/dist/extensions/pi-powerline-footer/tests/editor-performance.test.ts +43 -0
  49. package/dist/extensions/pi-powerline-footer/tests/git-optional-locks.test.ts +64 -0
  50. package/dist/extensions/pi-powerline-footer/tests/jump-shortcuts.test.ts +116 -0
  51. package/dist/extensions/pi-powerline-footer/tests/queue-store.test.ts +19 -149
  52. package/dist/extensions/pi-powerline-footer/tests/remaining-regressions.test.ts +6 -0
  53. package/dist/extensions/pi-powerline-footer/tests/usage-display.test.ts +5 -5
  54. package/dist/extensions/pi-powerline-footer/types.ts +1 -2
  55. package/dist/extensions/pi-subagents/CHANGELOG.md +225 -14
  56. package/dist/extensions/pi-subagents/README.md +66 -1613
  57. package/dist/extensions/pi-subagents/agents/builder.md +0 -1
  58. package/dist/extensions/pi-subagents/agents/delegate.md +14 -0
  59. package/dist/extensions/pi-subagents/agents/oracle.md +74 -0
  60. package/dist/extensions/pi-subagents/agents/reviewer.md +78 -0
  61. package/dist/extensions/pi-subagents/agents/scout.md +50 -0
  62. package/dist/extensions/pi-subagents/agents/worker.md +58 -0
  63. package/dist/extensions/pi-subagents/docs/configuration.md +372 -0
  64. package/dist/extensions/pi-subagents/docs/extension-api.md +308 -0
  65. package/dist/extensions/pi-subagents/docs/missions.md +119 -0
  66. package/dist/extensions/pi-subagents/docs/models.md +192 -0
  67. package/dist/extensions/pi-subagents/docs/observability.md +174 -0
  68. package/dist/extensions/pi-subagents/docs/tool-reference.md +343 -0
  69. package/dist/extensions/pi-subagents/docs/watchdog.md +176 -0
  70. package/dist/extensions/pi-subagents/docs/workflows.md +163 -0
  71. package/dist/extensions/pi-subagents/inspector-runner.mjs +11 -0
  72. package/dist/extensions/pi-subagents/package-lock.json +152 -194
  73. package/dist/extensions/pi-subagents/package.json +9 -10
  74. package/dist/extensions/pi-subagents/prompts/gather-context-and-clarify.md +1 -1
  75. package/dist/extensions/pi-subagents/prompts/parallel-cleanup.md +9 -9
  76. package/dist/extensions/pi-subagents/prompts/parallel-research.md +6 -6
  77. package/dist/extensions/pi-subagents/prompts/parallel-review.md +8 -8
  78. package/dist/extensions/pi-subagents/prompts/review-loop.md +12 -12
  79. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +22 -17
  80. package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +77 -72
  81. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +177 -69
  82. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +28 -8
  83. package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +88 -66
  84. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +3 -3
  85. package/dist/extensions/pi-subagents/src/agents/agent-refinements.ts +624 -0
  86. package/dist/extensions/pi-subagents/src/agents/agents.ts +38 -19
  87. package/dist/extensions/pi-subagents/src/agents/frontmatter.ts +7 -3
  88. package/dist/extensions/pi-subagents/src/agents/proactive-skills.ts +2 -2
  89. package/dist/extensions/pi-subagents/src/agents/skills.ts +2 -9
  90. package/dist/extensions/pi-subagents/src/api/delegation.ts +1 -2
  91. package/dist/extensions/pi-subagents/src/api/project-panes.ts +30 -0
  92. package/dist/extensions/pi-subagents/src/extension/config.ts +62 -8
  93. package/dist/extensions/pi-subagents/src/extension/control-notices.ts +2 -2
  94. package/dist/extensions/pi-subagents/src/extension/doctor.ts +40 -0
  95. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +51 -26
  96. package/dist/extensions/pi-subagents/src/extension/index.ts +140 -50
  97. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +77 -0
  98. package/dist/extensions/pi-subagents/src/extension/rpc.ts +18 -24
  99. package/dist/extensions/pi-subagents/src/extension/schemas.ts +58 -21
  100. package/dist/extensions/pi-subagents/src/extension/subagent-guide.ts +39 -0
  101. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +47 -25
  102. package/dist/extensions/pi-subagents/src/inspectors/herdr/actions.ts +3 -3
  103. package/dist/extensions/pi-subagents/src/inspectors/herdr/project-panes.ts +460 -64
  104. package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +4 -1
  105. package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +102 -4
  106. package/dist/extensions/pi-subagents/src/missions/actions.ts +77 -16
  107. package/dist/extensions/pi-subagents/src/missions/goal-driver.ts +162 -0
  108. package/dist/extensions/pi-subagents/src/missions/lifecycle.ts +65 -17
  109. package/dist/extensions/pi-subagents/src/missions/store.ts +151 -9
  110. package/dist/extensions/pi-subagents/src/missions/types.ts +58 -3
  111. package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +260 -0
  112. package/dist/extensions/pi-subagents/src/profiles/profiles.ts +8 -8
  113. package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +374 -0
  114. package/dist/extensions/pi-subagents/src/runs/background/active-run-index.ts +46 -0
  115. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +158 -36
  116. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +294 -134
  117. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +26 -4
  118. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +45 -6
  119. package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +33 -15
  120. package/dist/extensions/pi-subagents/src/runs/background/completion-replay.ts +267 -0
  121. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +145 -60
  122. package/dist/extensions/pi-subagents/src/runs/background/owned-process-tree.ts +104 -0
  123. package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +17 -3
  124. package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +114 -6
  125. package/dist/extensions/pi-subagents/src/runs/background/resume-guidance.ts +33 -0
  126. package/dist/extensions/pi-subagents/src/runs/background/retained-children.ts +68 -0
  127. package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +71 -0
  128. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +26 -3
  129. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +42 -14
  130. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +12 -24
  131. package/dist/extensions/pi-subagents/src/runs/background/steering.ts +7 -5
  132. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +233 -101
  133. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +17 -4
  134. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +146 -0
  135. package/dist/extensions/pi-subagents/src/runs/background/wait-subscriptions.ts +21 -5
  136. package/dist/extensions/pi-subagents/src/runs/foreground/async-dismiss-action.ts +85 -0
  137. package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +43 -18
  138. package/dist/extensions/pi-subagents/src/runs/foreground/chain-clarify.ts +20 -19
  139. package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +40 -2
  140. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +188 -46
  141. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +12 -0
  142. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +137 -0
  143. package/dist/extensions/pi-subagents/src/runs/foreground/prompt-audit.ts +171 -0
  144. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +1365 -252
  145. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +187 -0
  146. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +178 -26
  147. package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +1 -1
  148. package/dist/extensions/pi-subagents/src/runs/shared/llm-intent-arbiter.ts +286 -0
  149. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +2 -0
  150. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +32 -5
  151. package/dist/extensions/pi-subagents/src/runs/shared/model-scope.ts +12 -2
  152. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +3 -0
  153. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +509 -117
  154. package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +10 -10
  155. package/dist/extensions/pi-subagents/src/runs/shared/run-fanout-budget.ts +280 -0
  156. package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +4 -2
  157. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +189 -32
  158. package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +21 -5
  159. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +20 -8
  160. package/dist/extensions/pi-subagents/src/shared/artifacts.ts +128 -3
  161. package/dist/extensions/pi-subagents/src/shared/display-text.ts +100 -0
  162. package/dist/extensions/pi-subagents/src/shared/file-coalescer.ts +9 -0
  163. package/dist/extensions/pi-subagents/src/shared/fork-context.ts +13 -0
  164. package/dist/extensions/pi-subagents/src/shared/formatters.ts +4 -6
  165. package/dist/extensions/pi-subagents/src/shared/prompt-resources.ts +51 -0
  166. package/dist/extensions/pi-subagents/src/shared/settings.ts +41 -11
  167. package/dist/extensions/pi-subagents/src/shared/types.ts +192 -3
  168. package/dist/extensions/pi-subagents/src/shared/utf8.ts +11 -0
  169. package/dist/extensions/pi-subagents/src/shared/utils.ts +46 -34
  170. package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +1 -14
  171. package/dist/extensions/pi-subagents/src/slash/inline-subagents.ts +1 -1
  172. package/dist/extensions/pi-subagents/src/slash/prompt-template-bridge.ts +14 -12
  173. package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +176 -21
  174. package/dist/extensions/pi-subagents/src/slash/slash-bridge.ts +12 -6
  175. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +52 -18
  176. package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +36 -5
  177. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +37 -21
  178. package/dist/extensions/pi-subagents/src/tui/fleet.ts +375 -42
  179. package/dist/extensions/pi-subagents/src/tui/render.ts +201 -68
  180. package/dist/extensions/pi-subagents/src/types/pi-runtime-compat.d.ts +0 -6
  181. package/dist/extensions/pi-subagents/src/watchdog/change-signature.ts +5 -4
  182. package/dist/extensions/pi-subagents/src/watchdog/lsp-diagnostics.ts +0 -1
  183. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +332 -27
  184. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +15 -15
  185. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/cli.d.ts +3 -0
  186. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/register-bedrock.d.ts +2 -0
  187. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/restore-sandbox-env.d.ts +17 -0
  188. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/args.d.ts +57 -0
  189. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/config-selector.d.ts +16 -0
  190. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/file-processor.d.ts +15 -0
  191. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/initial-message.d.ts +18 -0
  192. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/list-models.d.ts +9 -0
  193. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/project-trust.d.ts +10 -0
  194. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/session-picker.d.ts +10 -0
  195. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/startup-ui.d.ts +20 -0
  196. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli.d.ts +3 -0
  197. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/config.d.ts +96 -0
  198. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-runtime.d.ts +119 -0
  199. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-services.d.ts +85 -0
  200. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session.d.ts +620 -0
  201. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-guidance.d.ts +5 -0
  202. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-storage.d.ts +56 -0
  203. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/bash-executor.d.ts +32 -0
  204. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/cache-stats.d.ts +49 -0
  205. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/branch-summarization.d.ts +93 -0
  206. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/compaction.d.ts +128 -0
  207. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/index.d.ts +7 -0
  208. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/utils.d.ts +38 -0
  209. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/defaults.d.ts +3 -0
  210. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/diagnostics.d.ts +15 -0
  211. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/event-bus.d.ts +9 -0
  212. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/exec.d.ts +29 -0
  213. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/experimental.d.ts +2 -0
  214. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/ansi-to-html.d.ts +22 -0
  215. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/index.d.ts +37 -0
  216. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/tool-renderer.d.ts +34 -0
  217. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/index.d.ts +12 -0
  218. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/loader.d.ts +23 -0
  219. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/runner.d.ts +171 -0
  220. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/types.d.ts +1261 -0
  221. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/wrapper.d.ts +20 -0
  222. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/footer-data-provider.d.ts +54 -0
  223. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/http-dispatcher.d.ts +22 -0
  224. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/index.d.ts +13 -0
  225. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/keybindings.d.ts +358 -0
  226. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/messages.d.ts +77 -0
  227. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-config.d.ts +512 -0
  228. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-registry.d.ts +43 -0
  229. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-resolver.d.ts +121 -0
  230. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-runtime.d.ts +82 -0
  231. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/models-store.d.ts +17 -0
  232. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/output-guard.d.ts +7 -0
  233. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/package-manager.d.ts +210 -0
  234. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/project-trust.d.ts +15 -0
  235. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/prompt-templates.d.ts +54 -0
  236. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-attribution.d.ts +4 -0
  237. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-composer.d.ts +55 -0
  238. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/radius.d.ts +2 -0
  239. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/remote-catalog-provider.d.ts +5 -0
  240. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resolve-config-value.d.ts +30 -0
  241. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resource-loader.d.ts +206 -0
  242. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/runtime-credentials.d.ts +15 -0
  243. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/sdk.d.ts +106 -0
  244. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-cwd.d.ts +19 -0
  245. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-manager.d.ts +356 -0
  246. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/settings-manager.d.ts +297 -0
  247. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/skills.d.ts +60 -0
  248. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/slash-commands.d.ts +15 -0
  249. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/source-info.d.ts +18 -0
  250. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/system-prompt.d.ts +28 -0
  251. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/telemetry.d.ts +3 -0
  252. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/timings.d.ts +10 -0
  253. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/bash.d.ts +68 -0
  254. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit-diff.d.ts +106 -0
  255. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit.d.ts +51 -0
  256. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/file-mutation-queue.d.ts +6 -0
  257. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/find.d.ts +35 -0
  258. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/grep.d.ts +37 -0
  259. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/index.d.ts +40 -0
  260. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/ls.d.ts +37 -0
  261. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/output-accumulator.d.ts +52 -0
  262. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/path-utils.d.ts +10 -0
  263. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/read.d.ts +35 -0
  264. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/render-utils.d.ts +24 -0
  265. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
  266. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/truncate.d.ts +70 -0
  267. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/write.d.ts +26 -0
  268. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/trust-manager.d.ts +36 -0
  269. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/usage-totals.d.ts +19 -0
  270. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/index.d.ts +3 -0
  271. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/client.d.ts +61 -0
  272. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/huggingface.d.ts +23 -0
  273. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/index.d.ts +3 -0
  274. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/provider.d.ts +10 -0
  275. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/ui.d.ts +42 -0
  276. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/index.d.ts +35 -0
  277. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/main.d.ts +12 -0
  278. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/migrations.d.ts +33 -0
  279. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/index.d.ts +9 -0
  280. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/armin.d.ts +34 -0
  281. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/assistant-message.d.ts +22 -0
  282. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bash-execution.d.ts +34 -0
  283. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  284. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
  285. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
  286. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/config-selector.d.ts +102 -0
  287. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  288. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-editor.d.ts +21 -0
  289. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-entry.d.ts +19 -0
  290. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-message.d.ts +20 -0
  291. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  292. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/diff.d.ts +12 -0
  293. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  294. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
  295. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-editor.d.ts +22 -0
  296. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-input.d.ts +23 -0
  297. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-selector.d.ts +26 -0
  298. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/first-time-setup.d.ts +25 -0
  299. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/footer.d.ts +32 -0
  300. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/index.d.ts +34 -0
  301. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
  302. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/login-dialog.d.ts +52 -0
  303. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/model-selector.d.ts +54 -0
  304. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/oauth-selector.d.ts +33 -0
  305. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/scoped-models-selector.d.ts +42 -0
  306. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
  307. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector.d.ts +95 -0
  308. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/settings-selector.d.ts +77 -0
  309. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  310. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  311. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/status-indicator.d.ts +28 -0
  312. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  313. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  314. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tool-execution.d.ts +63 -0
  315. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tree-selector.d.ts +94 -0
  316. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/trust-selector.d.ts +23 -0
  317. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  318. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message.d.ts +14 -0
  319. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  320. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/interactive-mode.d.ts +394 -0
  321. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/model-search.d.ts +12 -0
  322. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme-controller.d.ts +29 -0
  323. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme.d.ts +120 -0
  324. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/print-mode.d.ts +28 -0
  325. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/jsonl.d.ts +17 -0
  326. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-client.d.ts +246 -0
  327. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-mode.d.ts +20 -0
  328. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-types.d.ts +457 -0
  329. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/package-manager-cli.d.ts +8 -0
  330. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/rpc-entry.d.ts +3 -0
  331. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/ansi.d.ts +2 -0
  332. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/changelog.d.ts +22 -0
  333. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/child-process.d.ts +18 -0
  334. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-image.d.ts +11 -0
  335. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-native.d.ts +11 -0
  336. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard.d.ts +4 -0
  337. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/deprecation.d.ts +4 -0
  338. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/exif-orientation.d.ts +5 -0
  339. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/frontmatter.d.ts +8 -0
  340. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/fs-watch.d.ts +5 -0
  341. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/git.d.ts +26 -0
  342. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/html.d.ts +7 -0
  343. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-convert.d.ts +10 -0
  344. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-process.d.ts +18 -0
  345. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-core.d.ts +30 -0
  346. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-worker.d.ts +2 -0
  347. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize.d.ts +16 -0
  348. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/json.d.ts +3 -0
  349. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/mime.d.ts +3 -0
  350. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/open-browser.d.ts +9 -0
  351. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/paths.d.ts +31 -0
  352. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/photon.d.ts +21 -0
  353. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/pi-user-agent.d.ts +2 -0
  354. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/shell.d.ts +31 -0
  355. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/sleep.d.ts +5 -0
  356. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/syntax-highlight.d.ts +12 -0
  357. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/tools-manager.d.ts +3 -0
  358. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/version-check.d.ts +15 -0
  359. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/windows-self-update.d.ts +3 -0
  360. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/index.mjs +84 -0
  361. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/package.json +14 -0
  362. package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +102 -15
  363. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +507 -306
  364. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +309 -123
  365. package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +124 -58
  366. package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +62 -16
  367. package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +167 -113
  368. package/dist/extensions/pi-subagents/test/integration/detect-error.test.ts +1 -1
  369. package/dist/extensions/pi-subagents/test/integration/external-cli-runner.test.ts +4 -2
  370. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +139 -58
  371. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +324 -59
  372. package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +98 -22
  373. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +106 -106
  374. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +416 -106
  375. package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +287 -17
  376. package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +1122 -96
  377. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +107 -20
  378. package/dist/extensions/pi-subagents/test/integration/slash-live-state.test.ts +9 -9
  379. package/dist/extensions/pi-subagents/test/integration/template-resolution.test.ts +26 -6
  380. package/dist/extensions/pi-subagents/test/integration/top-level-async.test.ts +2 -2
  381. package/dist/extensions/pi-subagents/test/support/helpers.ts +2 -0
  382. package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +1 -1
  383. package/dist/extensions/pi-subagents/test/support/ts-loader.mjs +0 -8
  384. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +194 -59
  385. package/dist/extensions/pi-subagents/test/unit/active-async-capacity.test.ts +317 -0
  386. package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +15 -15
  387. package/dist/extensions/pi-subagents/test/unit/agent-eject-disable.test.ts +66 -66
  388. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +334 -248
  389. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +52 -52
  390. package/dist/extensions/pi-subagents/test/unit/agent-memory.test.ts +26 -26
  391. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +118 -99
  392. package/dist/extensions/pi-subagents/test/unit/agent-refinements.test.ts +160 -0
  393. package/dist/extensions/pi-subagents/test/unit/agent-selection.test.ts +9 -9
  394. package/dist/extensions/pi-subagents/test/unit/artifacts.test.ts +43 -1
  395. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +36 -10
  396. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +387 -30
  397. package/dist/extensions/pi-subagents/test/unit/async-permission-session.test.ts +9 -9
  398. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +18 -3
  399. package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +99 -40
  400. package/dist/extensions/pi-subagents/test/unit/background-work.test.ts +5 -3
  401. package/dist/extensions/pi-subagents/test/unit/builtin-agent-documentation.test.ts +7 -7
  402. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +19 -19
  403. package/dist/extensions/pi-subagents/test/unit/chain-append.test.ts +94 -23
  404. package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +9 -9
  405. package/dist/extensions/pi-subagents/test/unit/chain-serializer.test.ts +20 -20
  406. package/dist/extensions/pi-subagents/test/unit/child-transcript.test.ts +9 -9
  407. package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +35 -5
  408. package/dist/extensions/pi-subagents/test/unit/completion-dedupe.test.ts +2 -2
  409. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +70 -52
  410. package/dist/extensions/pi-subagents/test/unit/completion-replay.test.ts +187 -0
  411. package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +125 -71
  412. package/dist/extensions/pi-subagents/test/unit/control-notices.test.ts +18 -3
  413. package/dist/extensions/pi-subagents/test/unit/default-extensions.test.ts +12 -12
  414. package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +17 -23
  415. package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +30 -2
  416. package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +25 -25
  417. package/dist/extensions/pi-subagents/test/unit/extra-agent-dirs.test.ts +3 -3
  418. package/dist/extensions/pi-subagents/test/unit/file-coalescer.test.ts +15 -0
  419. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +91 -47
  420. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +468 -38
  421. package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +14 -4
  422. package/dist/extensions/pi-subagents/test/unit/foreground-tool-call-compaction.test.ts +37 -0
  423. package/dist/extensions/pi-subagents/test/unit/herdr-inspector-bootstrap.test.ts +69 -0
  424. package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +79 -2
  425. package/dist/extensions/pi-subagents/test/unit/herdr-status-bridge.test.ts +102 -49
  426. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +98 -32
  427. package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +7 -6
  428. package/dist/extensions/pi-subagents/test/unit/llm-intent-arbiter.test.ts +171 -0
  429. package/dist/extensions/pi-subagents/test/unit/mission-goal-driver.test.ts +116 -0
  430. package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +81 -7
  431. package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +289 -13
  432. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +42 -1
  433. package/dist/extensions/pi-subagents/test/unit/model-scope-settings.test.ts +2 -2
  434. package/dist/extensions/pi-subagents/test/unit/model-scope.test.ts +11 -2
  435. package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +84 -10
  436. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +122 -8
  437. package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +8 -8
  438. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +24 -24
  439. package/dist/extensions/pi-subagents/test/unit/owned-process-tree.test.ts +69 -0
  440. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +16 -2
  441. package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +7 -7
  442. package/dist/extensions/pi-subagents/test/unit/parallel-utils.test.ts +10 -10
  443. package/dist/extensions/pi-subagents/test/unit/path-handling.test.ts +3 -3
  444. package/dist/extensions/pi-subagents/test/unit/path-resolution.test.ts +26 -17
  445. package/dist/extensions/pi-subagents/test/unit/pi-args-permission-system.test.ts +405 -0
  446. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +440 -92
  447. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +24 -8
  448. package/dist/extensions/pi-subagents/test/unit/pi-spawn.test.ts +6 -6
  449. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +43 -43
  450. package/dist/extensions/pi-subagents/test/unit/proactive-skills.test.ts +13 -13
  451. package/dist/extensions/pi-subagents/test/unit/process-terminal.test.ts +59 -6
  452. package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +19 -19
  453. package/dist/extensions/pi-subagents/test/unit/project-panes-public-api.test.ts +243 -0
  454. package/dist/extensions/pi-subagents/test/unit/prompt-template-bridge.test.ts +68 -168
  455. package/dist/extensions/pi-subagents/test/unit/prompt-workflows.test.ts +58 -15
  456. package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +51 -0
  457. package/dist/extensions/pi-subagents/test/unit/reads-resolution.test.ts +66 -0
  458. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +47 -28
  459. package/dist/extensions/pi-subagents/test/unit/result-intercom.test.ts +12 -12
  460. package/dist/extensions/pi-subagents/test/unit/retained-children.test.ts +57 -0
  461. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +111 -31
  462. package/dist/extensions/pi-subagents/test/unit/run-fanout-budget.test.ts +121 -0
  463. package/dist/extensions/pi-subagents/test/unit/run-id-resolver.test.ts +1 -1
  464. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +65 -50
  465. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +69 -28
  466. package/dist/extensions/pi-subagents/test/unit/scheduled-store-root.test.ts +67 -0
  467. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +60 -44
  468. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +424 -49
  469. package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +28 -0
  470. package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +23 -1
  471. package/dist/extensions/pi-subagents/test/unit/slash-bridge.test.ts +32 -5
  472. package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +13 -13
  473. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +130 -92
  474. package/dist/extensions/pi-subagents/test/unit/steering.test.ts +2 -2
  475. package/dist/extensions/pi-subagents/test/unit/subagent-action-recovery.test.ts +85 -0
  476. package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +35 -35
  477. package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +24 -0
  478. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +312 -22
  479. package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +150 -15
  480. package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +65 -26
  481. package/dist/extensions/pi-subagents/test/unit/timeout-defaults.test.ts +138 -0
  482. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +76 -25
  483. package/dist/extensions/pi-subagents/test/unit/turn-budget.test.ts +5 -5
  484. package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +55 -6
  485. package/dist/extensions/pi-subagents/test/unit/watchdog-child-status.test.ts +13 -13
  486. package/dist/extensions/pi-subagents/test/unit/watchdog-lsp-diagnostics.test.ts +1 -1
  487. package/dist/extensions/pi-subagents/test/unit/watchdog-runtime.test.ts +1 -1
  488. package/dist/extensions/pi-subagents/test/unit/watchdog-settings.test.ts +8 -8
  489. package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +6 -6
  490. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +138 -11
  491. package/dist/extensions/pi-subagents/test/unit/workflow-graph.test.ts +8 -8
  492. package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +113 -0
  493. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +68 -7
  494. package/dist/extensions/pi-subagents/test/unit/writer-budget-guidance.test.ts +6 -6
  495. package/dist/extensions/workflow/extension.ts +21 -19
  496. package/dist/extensions/workflow/modes.ts +65 -0
  497. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  498. package/dist/modes/interactive/interactive-mode.js +48 -1
  499. package/dist/skills/pi-subagents/SKILL.md +20 -15
  500. package/dist/skills/pi-subagents/references/constraints-and-recipes.md +77 -83
  501. package/dist/skills/pi-subagents/references/execution-controls.md +215 -106
  502. package/dist/skills/pi-subagents/references/management-authoring-rpc.md +29 -9
  503. package/dist/skills/pi-subagents/references/prompting-and-roles.md +58 -43
  504. package/docs/plans/workflow-autoloop-reference.md +192 -0
  505. package/docs/plans/workflow-subagent-consolidation-planb.md +374 -0
  506. package/docs/plans/workflow-subagent-scripted-merge.md +406 -0
  507. package/docs/quickstart.md +27 -43
  508. package/docs/settings.md +4 -0
  509. package/docs/usage.md +1 -0
  510. package/package.json +2 -1
  511. package/dist/extensions/workflow/adapter.ts +0 -949
  512. package/dist/extensions/workflow/modes/loop.ts +0 -74
  513. package/dist/extensions/workflow/modes/prototype.ts +0 -170
  514. package/dist/extensions/workflow/modes/quicktype.ts +0 -150
  515. package/dist/extensions/workflow/modes/task.ts +0 -105
  516. package/dist/extensions/workflow/run-state.ts +0 -124
  517. package/dist/extensions/workflow/state-machine.ts +0 -484
  518. package/dist/extensions/workflow/validators.ts +0 -42
@@ -22,6 +22,7 @@ export const NATIVE_SUPERVISOR_TOOL_NAME = "subagent_supervisor";
22
22
  const MAX_MESSAGE_BYTES = 64 * 1024;
23
23
  const DEFAULT_ASK_TIMEOUT_MS = 10 * 60 * 1000;
24
24
  const CHANNEL_POLL_MS = Math.min(POLL_INTERVAL_MS, 500);
25
+ const CHANNEL_SAFETY_POLL_MS = 5000;
25
26
  const STALE_EMPTY_CHANNEL_AGE_MS = 60 * 1000;
26
27
  const STALE_EMPTY_CHANNEL_CLEANUP_INTERVAL_MS = 60 * 1000;
27
28
 
@@ -69,6 +70,13 @@ interface IntercomParams {
69
70
  replyTo?: string;
70
71
  }
71
72
 
73
+ type SupervisorWatch = (filename: fs.PathLike, listener: fs.WatchListener<string>) => fs.FSWatcher;
74
+
75
+ interface NativeSupervisorChannelDeps {
76
+ platform?: NodeJS.Platform;
77
+ watch?: SupervisorWatch;
78
+ }
79
+
72
80
  const ContactSupervisorParamsSchema = Type.Object({
73
81
  reason: Type.String({ enum: ["need_decision", "interview_request", "progress_update"] }),
74
82
  message: Type.Optional(Type.String()),
@@ -626,10 +634,16 @@ function buildParentIntercomTool(pending: Map<string, PendingSupervisorRequest>,
626
634
  };
627
635
  }
628
636
 
629
- export function createNativeSupervisorChannel(pi: ExtensionAPI, state: SubagentState): { start: () => void; dispose: () => void; pending: Map<string, PendingSupervisorRequest> } {
637
+ export function createNativeSupervisorChannel(pi: ExtensionAPI, state: SubagentState, deps: NativeSupervisorChannelDeps = {}): { start: () => void; dispose: () => void; pending: Map<string, PendingSupervisorRequest> } {
638
+ const watch = deps.watch ?? fs.watch;
630
639
  const pending = new Map<string, PendingSupervisorRequest>();
631
640
  const seenFiles = new Set<string>();
641
+ const requestWatchers = new Map<string, fs.FSWatcher>();
642
+ let rootWatcher: fs.FSWatcher | undefined;
632
643
  let poller: ReturnType<typeof setInterval> | undefined;
644
+ let safetyPoller: ReturnType<typeof setInterval> | undefined;
645
+ let deferredWatcherRefresh: ReturnType<typeof setImmediate> | undefined;
646
+ let started = false;
633
647
  let lastStaleCleanupAt = 0;
634
648
 
635
649
  const registerParentTools = (): void => {
@@ -696,17 +710,101 @@ export function createNativeSupervisorChannel(pi: ExtensionAPI, state: SubagentS
696
710
  }
697
711
  };
698
712
 
713
+ const startPolling = (): void => {
714
+ if (poller) return;
715
+ poller = setInterval(poll, CHANNEL_POLL_MS);
716
+ poller.unref?.();
717
+ };
718
+ const startSafetyPolling = (): void => {
719
+ if (safetyPoller) return;
720
+ safetyPoller = setInterval(() => {
721
+ watchExistingRequestDirs();
722
+ poll();
723
+ }, CHANNEL_SAFETY_POLL_MS);
724
+ safetyPoller.unref?.();
725
+ };
726
+ const watchRequestDir = (requestsDir: string): void => {
727
+ if (requestWatchers.has(requestsDir)) return;
728
+ try {
729
+ const watcher = watch(requestsDir, () => poll());
730
+ watcher.on("error", () => {
731
+ try { watcher.close(); } catch {}
732
+ requestWatchers.delete(requestsDir);
733
+ startPolling();
734
+ });
735
+ watcher.unref?.();
736
+ requestWatchers.set(requestsDir, watcher);
737
+ } catch (error) {
738
+ if ((error as NodeJS.ErrnoException).code !== "ENOENT") startPolling();
739
+ }
740
+ };
741
+ const watchExistingRequestDirs = (): void => {
742
+ let channelEntries: fs.Dirent[];
743
+ try {
744
+ channelEntries = fs.readdirSync(SUPERVISOR_CHANNEL_ROOT, { withFileTypes: true });
745
+ } catch (error) {
746
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return;
747
+ startPolling();
748
+ return;
749
+ }
750
+ for (const entry of channelEntries) {
751
+ if (entry.isDirectory()) watchRequestDir(path.join(SUPERVISOR_CHANNEL_ROOT, entry.name, REQUESTS_DIR));
752
+ }
753
+ };
754
+ const scheduleWatcherRefresh = (): void => {
755
+ if (deferredWatcherRefresh) return;
756
+ deferredWatcherRefresh = setImmediate(() => {
757
+ deferredWatcherRefresh = undefined;
758
+ if (!started) return;
759
+ watchExistingRequestDirs();
760
+ poll();
761
+ });
762
+ deferredWatcherRefresh.unref?.();
763
+ };
764
+
699
765
  return {
700
766
  start: () => {
701
- if (poller) return;
767
+ if (started) return;
768
+ started = true;
702
769
  registerParentTools();
703
770
  poll();
704
- poller = setInterval(poll, CHANNEL_POLL_MS);
705
- poller.unref?.();
771
+ try {
772
+ fs.mkdirSync(SUPERVISOR_CHANNEL_ROOT, { recursive: true });
773
+ if ((deps.platform ?? process.platform) === "win32") {
774
+ startPolling();
775
+ return;
776
+ }
777
+ watchExistingRequestDirs();
778
+ rootWatcher = watch(SUPERVISOR_CHANNEL_ROOT, () => {
779
+ watchExistingRequestDirs();
780
+ poll();
781
+ scheduleWatcherRefresh();
782
+ });
783
+ rootWatcher.on("error", startPolling);
784
+ startSafetyPolling();
785
+ scheduleWatcherRefresh();
786
+ } catch {
787
+ startPolling();
788
+ }
706
789
  },
707
790
  dispose: () => {
791
+ started = false;
792
+ try {
793
+ rootWatcher?.close();
794
+ } catch {
795
+ // Best effort during shutdown.
796
+ }
797
+ rootWatcher = undefined;
798
+ for (const watcher of requestWatchers.values()) {
799
+ try { watcher.close(); } catch {}
800
+ }
801
+ requestWatchers.clear();
708
802
  if (poller) clearInterval(poller);
709
803
  poller = undefined;
804
+ if (safetyPoller) clearInterval(safetyPoller);
805
+ safetyPoller = undefined;
806
+ if (deferredWatcherRefresh) clearImmediate(deferredWatcherRefresh);
807
+ deferredWatcherRefresh = undefined;
710
808
  pending.clear();
711
809
  seenFiles.clear();
712
810
  },
@@ -14,8 +14,10 @@ import {
14
14
  type MissionStatus,
15
15
  type MissionStoreConfig,
16
16
  type MissionStoreLocation,
17
+ type MissionTokenBudget,
17
18
  type MissionUpdateInput,
18
19
  } from "./types.ts";
20
+ import { missionStatePath } from "./workflow-state.ts";
19
21
  import {
20
22
  createMission,
21
23
  listGlobalMissions,
@@ -32,6 +34,7 @@ export const MISSION_ACTIONS = [
32
34
  "mission.list",
33
35
  "mission.show",
34
36
  "mission.update",
37
+ "mission.resolve-decision",
35
38
  "mission.attach-run",
36
39
  "mission.close",
37
40
  ] as const;
@@ -40,13 +43,17 @@ export type MissionAction = typeof MISSION_ACTIONS[number];
40
43
 
41
44
  export interface MissionLaunchInput {
42
45
  title: string;
43
- goal?: string;
46
+ objective?: string;
47
+ goal?: true;
48
+ budget?: MissionTokenBudget;
44
49
  labels?: string[];
45
50
  }
46
51
 
47
52
  export interface MissionUpdateToolInput {
48
53
  title?: string;
49
- goal?: string;
54
+ objective?: string;
55
+ goal?: boolean | { paused: boolean };
56
+ budget?: MissionTokenBudget;
50
57
  status?: MissionStatus;
51
58
  summary?: string;
52
59
  labels?: string[];
@@ -101,17 +108,27 @@ export function validateMissionLaunch(value: unknown): MissionLaunchInput {
101
108
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("mission must be an object");
102
109
  const input = value as Record<string, unknown>;
103
110
  for (const key of Object.keys(input)) {
104
- if (key !== "title" && key !== "goal" && key !== "labels") throw new Error(`mission.${key} is unknown`);
111
+ if (key !== "title" && key !== "summary" && key !== "objective" && key !== "goal" && key !== "budget" && key !== "labels") throw new Error(`mission.${key} is unknown`);
105
112
  }
106
- if (typeof input.title !== "string" || !input.title.trim()) throw new Error("mission.title must be a non-empty string");
107
- if (input.goal !== undefined && (typeof input.goal !== "string" || !input.goal.trim())) throw new Error("mission.goal must be a non-empty string");
113
+ if (input.title !== undefined && input.summary !== undefined) throw new Error("mission.title and mission.summary cannot both be set");
114
+ const title = input.title ?? input.summary;
115
+ if (typeof title !== "string" || !title.trim()) throw new Error("mission.title or mission.summary must be a non-empty string");
116
+ if (input.objective !== undefined && (typeof input.objective !== "string" || !input.objective.trim())) throw new Error("mission.objective must be a non-empty string");
117
+ if (input.goal !== undefined && input.goal !== true) throw new Error("mission.goal must be true when supplied");
118
+ const budget = input.budget;
119
+ if (budget !== undefined && (!budget || typeof budget !== "object" || Array.isArray(budget) || !Number.isSafeInteger((budget as { tokens?: unknown }).tokens) || ((budget as { tokens: number }).tokens < 1))) {
120
+ throw new Error("mission.budget.tokens must be a positive integer");
121
+ }
122
+ if (input.goal === true && budget === undefined) throw new Error("mission.budget is required when mission.goal is true");
108
123
  if (input.labels !== undefined && (!Array.isArray(input.labels) || input.labels.some((label) => typeof label !== "string" || !label.trim()))) {
109
124
  throw new Error("mission.labels must contain only non-empty strings");
110
125
  }
111
126
  return {
112
- title: input.title.trim(),
113
- ...(typeof input.goal === "string" ? { goal: input.goal.trim() } : {}),
114
- ...(Array.isArray(input.labels) ? { labels: input.labels as string[] } : {}),
127
+ title: title.trim(),
128
+ ...(typeof input.objective === "string" ? { objective: input.objective.trim() } : {}),
129
+ ...(input.goal === true ? { goal: true as const } : {}),
130
+ ...(budget !== undefined ? { budget: { tokens: (budget as { tokens: number }).tokens } } : {}),
131
+ ...(input.labels !== undefined ? { labels: input.labels.map((label) => label.trim()) } : {}),
115
132
  };
116
133
  }
117
134
 
@@ -161,15 +178,30 @@ function validateMissionUpdate(value: unknown): MissionUpdateInput {
161
178
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("missionUpdate must be an object");
162
179
  const input = value as Record<string, unknown>;
163
180
  for (const key of Object.keys(input)) {
164
- if (!["title", "goal", "status", "summary", "labels", "artifacts", "receipts", "decisions"].includes(key)) throw new Error(`missionUpdate.${key} is unknown`);
181
+ if (!["title", "objective", "goal", "budget", "status", "summary", "labels", "artifacts", "receipts", "decisions"].includes(key)) throw new Error(`missionUpdate.${key} is unknown`);
165
182
  }
166
183
  const update: MissionUpdateInput = {};
167
- for (const field of ["title", "goal", "summary"] as const) {
184
+ for (const field of ["title", "objective", "summary"] as const) {
168
185
  const candidate = input[field];
169
186
  if (candidate === undefined) continue;
170
187
  if (typeof candidate !== "string" || !candidate.trim()) throw new Error(`missionUpdate.${field} must be a non-empty string`);
171
188
  update[field] = candidate.trim();
172
189
  }
190
+ if (input.goal !== undefined) {
191
+ if (typeof input.goal === "boolean") update.goal = input.goal ? { status: "active" } : false;
192
+ else {
193
+ if (!input.goal || typeof input.goal !== "object" || Array.isArray(input.goal) || typeof (input.goal as { paused?: unknown }).paused !== "boolean" || Object.keys(input.goal).some((key) => key !== "paused")) {
194
+ throw new Error("missionUpdate.goal must be boolean or { paused: boolean }");
195
+ }
196
+ update.goal = { status: (input.goal as { paused: boolean }).paused ? "paused" : "active" };
197
+ }
198
+ }
199
+ if (input.budget !== undefined) {
200
+ if (!input.budget || typeof input.budget !== "object" || Array.isArray(input.budget) || !Number.isSafeInteger((input.budget as { tokens?: unknown }).tokens) || (input.budget as { tokens: number }).tokens < 1) {
201
+ throw new Error("missionUpdate.budget.tokens must be a positive integer");
202
+ }
203
+ update.budget = { tokens: (input.budget as { tokens: number }).tokens };
204
+ }
173
205
  if (input.status !== undefined) update.status = validateStatus(input.status, "missionUpdate.status");
174
206
  if (input.labels !== undefined) {
175
207
  if (!Array.isArray(input.labels) || input.labels.some((label) => typeof label !== "string" || !label.trim())) throw new Error("missionUpdate.labels must contain only non-empty strings");
@@ -234,7 +266,11 @@ function refreshLinkedRunStatus(location: MissionStoreLocation, record: MissionR
234
266
  if (updates.length === 0) return { record, warnings };
235
267
  const merged = record.runs.map((run) => updates.find((update) => update.runId === run.runId && update.childIndex === run.childIndex) ?? run);
236
268
  const states = merged.map((run) => run.status);
237
- const status: MissionStatus = states.some((state) => state === "queued" || state === "running" || state === "active")
269
+ const status: MissionStatus = record.status === "completed" || record.status === "failed" || record.status === "cancelled"
270
+ ? record.status
271
+ : record.goal && !states.some((state) => state === "queued" || state === "running" || state === "active")
272
+ ? "active"
273
+ : states.some((state) => state === "queued" || state === "running" || state === "active")
238
274
  ? "active"
239
275
  : states.some((state) => state === "paused")
240
276
  ? "waiting"
@@ -253,18 +289,30 @@ function formatMission(record: MissionRecord): string {
253
289
  `Mission: ${record.id}`,
254
290
  `Title: ${record.title}`,
255
291
  `Status: ${record.status}`,
256
- `Goal: ${record.goal}`,
292
+ `Objective: ${record.objective}`,
257
293
  `Updated: ${record.updatedAt}`,
258
294
  ];
295
+ if (record.goal && record.budget) lines.push(`Goal mode: ${record.goal.status}`, `Budget: ${record.usage?.tokens ?? 0}/${record.budget.tokens} tokens`);
259
296
  if (record.summary) lines.push(`Summary: ${record.summary}`);
260
297
  if (record.labels?.length) lines.push(`Labels: ${record.labels.join(", ")}`);
261
298
  if (record.runs.length) {
262
299
  lines.push("Runs:");
263
300
  for (const run of record.runs) lines.push(` ${run.runId} (${run.mode}${run.status ? `, ${run.status}` : ""})${run.asyncDir ? ` — ${run.asyncDir}` : ""}`);
264
301
  }
302
+ if (record.workflowChildren.length) {
303
+ lines.push("Workflow children:");
304
+ for (const child of record.workflowChildren) {
305
+ const identity = child.runId ? `${child.key} (${child.runId})` : child.key;
306
+ const heartbeat = child.heartbeat ? `; heartbeat ${child.heartbeat.status ?? child.status}${child.heartbeat.phase ? `/${child.heartbeat.phase}` : ""} at ${child.heartbeat.updatedAt}` : "";
307
+ const recovery = child.sessionPath ? `; session ${child.sessionPath}` : child.artifactPaths.length ? `; artifacts ${child.artifactPaths.length}` : "";
308
+ lines.push(` ${identity}: ${child.status}${child.agent ? ` — ${child.agent}` : ""}${child.phase ? ` [${child.phase}]` : ""}; updated ${child.updatedAt}${heartbeat}${recovery}`);
309
+ }
310
+ }
265
311
  if (record.decisions.length) {
266
312
  lines.push("Decisions:");
267
- for (const decision of record.decisions) lines.push(` ${decision.id}: ${decision.status} — ${decision.title}`);
313
+ for (const decision of record.decisions) {
314
+ lines.push(` ${decision.id}: ${decision.status} — ${decision.title}${decision.resolution ? `; resolution: ${decision.resolution}` : ""}`);
315
+ }
268
316
  }
269
317
  if (record.artifacts.length) {
270
318
  lines.push("Artifacts:");
@@ -291,7 +339,9 @@ export function handleMissionAction(
291
339
  const mission = validateMissionLaunch(params.mission);
292
340
  const record = createMission(location, {
293
341
  title: mission.title,
294
- goal: mission.goal ?? mission.title,
342
+ objective: mission.objective ?? mission.title,
343
+ ...(mission.goal === true ? { goal: true as const } : {}),
344
+ ...(mission.budget ? { budget: mission.budget } : {}),
295
345
  status: params.missionStatus ? validateStatus(params.missionStatus, "missionStatus") : "planned",
296
346
  ...(mission.labels ? { labels: mission.labels } : {}),
297
347
  ...(ctx.currentSessionId ? { ownerSessionId: ctx.currentSessionId } : {}),
@@ -313,13 +363,17 @@ export function handleMissionAction(
313
363
  const listed = listMissions(location);
314
364
  const lines = listed.records.length === 0
315
365
  ? ["No project missions."]
316
- : listed.records.map((record) => `${record.id} ${record.status} ${record.title} ${record.updatedAt}`);
366
+ : listed.records.map((record) => {
367
+ const open = record.decisions.filter((decision) => decision.status === "open").length;
368
+ const resolved = record.decisions.length - open;
369
+ return `${record.id} ${record.status} ${record.title} ${record.updatedAt}${record.decisions.length ? ` decisions: ${open} open, ${resolved} resolved` : ""}`;
370
+ });
317
371
  if (listed.warnings.length) lines.push("", ...listed.warnings.map((warning) => `Warning: ${warning}`));
318
372
  return textResult(lines.join("\n"), { mode: "management", results: [], missions: { records: listed.records, warnings: listed.warnings } });
319
373
  }
320
374
  if (action === "mission.show") {
321
375
  const refreshed = refreshLinkedRunStatus(location, readMission(location, requireMissionId(params)));
322
- const lines = [formatMission(refreshed.record)];
376
+ const lines = [formatMission(refreshed.record), `State: ${missionStatePath(location, refreshed.record.id)}`];
323
377
  if (refreshed.warnings.length) lines.push("", ...refreshed.warnings.map((warning) => `Warning: ${warning}`));
324
378
  return textResult(lines.join("\n"), {
325
379
  mode: "management",
@@ -334,6 +388,13 @@ export function handleMissionAction(
334
388
  const record = updateMission(location, requireMissionId(params), validateMissionUpdate(params.missionUpdate));
335
389
  return textResult(`Updated mission ${record.id}.\n\n${formatMission(record)}`, { mode: "management", results: [], missionId: record.id, missionPath: pathFor(record.id), mission: record });
336
390
  }
391
+ if (action === "mission.resolve-decision") {
392
+ const missionId = requireMissionId(params);
393
+ const decisionId = validateMissionId(params.id, "id");
394
+ if (typeof params.summary !== "string" || !params.summary.trim()) throw new Error("mission.resolve-decision requires a non-empty summary");
395
+ const record = updateMission(location, missionId, { resolveDecision: { id: decisionId, resolution: params.summary.trim() } });
396
+ return textResult(`Resolved decision ${decisionId} for mission ${record.id}.\n\n${formatMission(record)}`, { mode: "management", results: [], missionId: record.id, missionPath: pathFor(record.id), mission: record });
397
+ }
337
398
  if (action === "mission.attach-run") {
338
399
  const missionId = requireMissionId(params);
339
400
  const runId = params.runId ?? params.id;
@@ -0,0 +1,162 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import type { RetainedChild } from "../runs/background/retained-children.ts";
4
+ import type { ControlEvent } from "../shared/types.ts";
5
+ import { listMissions, readMission, updateMission } from "./store.ts";
6
+ import type { MissionRecord, MissionRunLink, MissionStoreLocation } from "./types.ts";
7
+ import { missionStatePath } from "./workflow-state.ts";
8
+
9
+ const TERMINAL_MISSION_STATUSES = new Set(["completed", "failed", "cancelled"]);
10
+ const ACTIVE_RUN_STATUSES = new Set(["queued", "running", "active"]);
11
+ const MAX_ACTION_LENGTH = 180;
12
+
13
+ export interface GoalContinuationNotice {
14
+ missionId: string;
15
+ message: string;
16
+ event: ControlEvent;
17
+ }
18
+
19
+ function bounded(value: string): string {
20
+ const normalized = value.replace(/\s+/g, " ").trim();
21
+ return normalized.length > MAX_ACTION_LENGTH ? `${normalized.slice(0, MAX_ACTION_LENGTH - 1)}…` : normalized;
22
+ }
23
+
24
+ function tokenUsage(value: unknown): number | undefined {
25
+ if (!value || typeof value !== "object" || Array.isArray(value)) return undefined;
26
+ const total = (value as { total?: unknown }).total;
27
+ return Number.isSafeInteger(total) && (total as number) >= 0 ? total as number : undefined;
28
+ }
29
+
30
+ function readLinkedRun(run: MissionRunLink): MissionRunLink {
31
+ if (!run.asyncDir) return run;
32
+ const statusPath = path.join(run.asyncDir, "status.json");
33
+ if (!fs.existsSync(statusPath)) return run;
34
+ const status = JSON.parse(fs.readFileSync(statusPath, "utf-8")) as Record<string, unknown>;
35
+ if (typeof status.state !== "string" || !status.state.trim()) throw new Error(`Linked run status '${statusPath}' is missing state`);
36
+ const tokens = tokenUsage(status.totalTokens)
37
+ ?? (Array.isArray(status.steps)
38
+ ? status.steps.reduce((total, step) => {
39
+ if (!step || typeof step !== "object") return total;
40
+ return total + (tokenUsage((step as { tokens?: unknown }).tokens) ?? 0);
41
+ }, 0)
42
+ : undefined);
43
+ return {
44
+ ...run,
45
+ status: status.state,
46
+ ...(!ACTIVE_RUN_STATUSES.has(status.state) && !run.completedAt ? { completedAt: new Date().toISOString() } : {}),
47
+ ...(tokens !== undefined ? { usage: { tokens } } : {}),
48
+ };
49
+ }
50
+
51
+ function refreshGoalMission(location: MissionStoreLocation, record: MissionRecord): MissionRecord {
52
+ const runs = record.runs.map(readLinkedRun);
53
+ const changed = runs.some((run, index) => JSON.stringify(run) !== JSON.stringify(record.runs[index]));
54
+ if (!changed) return record;
55
+ const active = runs.some((run) => run.status && ACTIVE_RUN_STATUSES.has(run.status));
56
+ return updateMission(location, record.id, {
57
+ status: active ? "active" : record.goal ? "active" : record.status,
58
+ addRuns: runs,
59
+ });
60
+ }
61
+
62
+ function readyActionFromValue(value: unknown, pathLabel = "state", depth = 0): string | undefined {
63
+ if (depth > 8 || !value || typeof value !== "object") return undefined;
64
+ if (Array.isArray(value)) {
65
+ for (let index = 0; index < value.length; index += 1) {
66
+ const found = readyActionFromValue(value[index], `${pathLabel}[${index}]`, depth + 1);
67
+ if (found) return found;
68
+ }
69
+ return undefined;
70
+ }
71
+ const input = value as Record<string, unknown>;
72
+ for (const key of ["nextReadyAction", "nextAction"] as const) {
73
+ if (typeof input[key] === "string" && input[key].trim()) return bounded(input[key]);
74
+ }
75
+ if (input.status === "ready") {
76
+ for (const key of ["action", "task", "title", "summary"] as const) {
77
+ if (typeof input[key] === "string" && input[key].trim()) return bounded(input[key]);
78
+ }
79
+ return `Continue ready mission state at ${pathLabel}`;
80
+ }
81
+ for (const [key, child] of Object.entries(input)) {
82
+ const found = readyActionFromValue(child, `${pathLabel}.${key}`, depth + 1);
83
+ if (found) return found;
84
+ }
85
+ return undefined;
86
+ }
87
+
88
+ function missionStateAction(location: MissionStoreLocation, record: MissionRecord): string | undefined {
89
+ const statePath = missionStatePath(location, record.id);
90
+ if (fs.existsSync(statePath)) {
91
+ const action = readyActionFromValue(JSON.parse(fs.readFileSync(statePath, "utf-8")));
92
+ if (action) return action;
93
+ }
94
+ const decision = record.decisions.find((item) => item.status === "open");
95
+ if (decision) return bounded(decision.recommendation ?? `Resolve decision: ${decision.title}`);
96
+ return undefined;
97
+ }
98
+
99
+ function retainedResumeTarget(record: MissionRecord, retainedChildren: RetainedChild[]): RetainedChild | undefined {
100
+ const latestRun = record.runs.at(-1);
101
+ if (!latestRun) return undefined;
102
+ return retainedChildren.find((child) => child.runId === latestRun.runId || child.parentRunId === latestRun.runId);
103
+ }
104
+
105
+ function nextReadyAction(location: MissionStoreLocation, record: MissionRecord, retainedChildren: RetainedChild[]): string {
106
+ const stateAction = missionStateAction(location, record);
107
+ const latestRun = record.runs.at(-1);
108
+ const action = stateAction
109
+ ?? (latestRun?.status === "failed" || latestRun?.status === "paused"
110
+ ? `Inspect linked run ${latestRun.runId} and continue the mission`
111
+ : `Continue objective: ${record.objective}`);
112
+ const retained = retainedResumeTarget(record, retainedChildren);
113
+ return retained
114
+ ? `Resume retained child ${retained.runId} (${retained.agent}) for: ${bounded(action)}`
115
+ : bounded(action);
116
+ }
117
+
118
+ export function collectGoalContinuationNotices(input: {
119
+ location: MissionStoreLocation;
120
+ ownerSessionId: string;
121
+ retainedChildren: RetainedChild[];
122
+ turnId: number;
123
+ now?: number;
124
+ }): GoalContinuationNotice[] {
125
+ const notices: GoalContinuationNotice[] = [];
126
+ const seen = new Set<string>();
127
+ for (const listed of listMissions(input.location).records) {
128
+ if (listed.ownerSessionId !== input.ownerSessionId || !listed.goal || TERMINAL_MISSION_STATUSES.has(listed.status)) continue;
129
+ let record = refreshGoalMission(input.location, readMission(input.location, listed.id));
130
+ if (!record.goal || record.goal.status !== "active" || !record.budget) continue;
131
+ if ((record.usage?.tokens ?? 0) >= record.budget.tokens) {
132
+ record = updateMission(input.location, record.id, { usage: record.usage ?? { tokens: 0 } });
133
+ if (record.goal?.status === "budget-exhausted") continue;
134
+ }
135
+ if (record.runs.some((run) => run.status && ACTIVE_RUN_STATUSES.has(run.status))) continue;
136
+ if (seen.has(record.id) || !record.budget) continue;
137
+ seen.add(record.id);
138
+ const budget = record.budget.tokens;
139
+ const used = record.usage?.tokens ?? 0;
140
+ const remaining = Math.max(0, budget - used);
141
+ const message = [
142
+ `Goal mission needs attention: ${bounded(record.title)}`,
143
+ `Mission: ${record.id}`,
144
+ `Remaining budget: ${remaining} tokens (${used}/${budget} used)`,
145
+ `Next ready action: ${nextReadyAction(input.location, record, input.retainedChildren)}`,
146
+ ].join("\n");
147
+ notices.push({
148
+ missionId: record.id,
149
+ message,
150
+ event: {
151
+ type: "needs_attention",
152
+ to: "needs_attention",
153
+ ts: input.now ?? Date.now(),
154
+ runId: `goal-${record.id}-turn-${input.turnId}`,
155
+ agent: "goal mission",
156
+ message,
157
+ reason: "idle",
158
+ },
159
+ });
160
+ }
161
+ return notices;
162
+ }
@@ -2,6 +2,7 @@ import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import type { AgentToolResult } from "@earendil-works/pi-agent-core";
4
4
  import { writePrivateAtomicJson } from "../shared/atomic-json.ts";
5
+ import { PROMPT_REDACTED } from "../shared/utils.ts";
5
6
  import type { Details, SubagentRunMode } from "../shared/types.ts";
6
7
  import { validateMissionLaunch } from "./actions.ts";
7
8
  import type { MissionArtifact, MissionRecord, MissionRunLink, MissionRunMode, MissionStatus, MissionStoreConfig, MissionStoreLocation } from "./types.ts";
@@ -34,15 +35,17 @@ interface PersistedMissionBinding {
34
35
  retainTerminal?: number;
35
36
  }
36
37
 
37
- function workflowGoal(params: MissionLaunchParams): string | undefined {
38
- return params.task?.trim()
38
+ function workflowObjective(params: MissionLaunchParams): string | undefined {
39
+ const objective = params.task?.trim()
39
40
  || params.tasks?.find((task) => task.task?.trim())?.task?.trim()
40
41
  || params.chain?.find((step) => step.task?.trim())?.task?.trim();
41
- }
42
-
43
- function conciseTitle(goal: string): string {
44
- const firstLine = goal.split(/\r?\n/, 1)[0]?.trim() || goal.trim();
45
- return firstLine.length > 100 ? `${firstLine.slice(0, 97)}...` : firstLine;
42
+ if (objective) return objective;
43
+ for (const step of params.chain ?? []) {
44
+ const parallel = Array.isArray(step.parallel) ? step.parallel : step.parallel ? [step.parallel] : [];
45
+ const task = parallel.find((child) => child.task?.trim())?.task?.trim();
46
+ if (task) return task;
47
+ }
48
+ return undefined;
46
49
  }
47
50
 
48
51
  export function prepareMissionLaunch(input: {
@@ -51,24 +54,28 @@ export function prepareMissionLaunch(input: {
51
54
  config?: MissionStoreConfig;
52
55
  ownerSessionId?: string;
53
56
  }): MissionLaunchBinding | undefined {
54
- if (input.params.missionId && input.params.mission !== undefined) throw new Error("Use missionId or mission, not both");
57
+ const hasMissionId = input.params.missionId !== undefined;
58
+ if (hasMissionId && input.params.mission !== undefined) throw new Error("Use missionId or mission, not both");
55
59
  if (input.params.mission === false) return undefined;
56
- const goal = workflowGoal(input.params);
60
+ const objective = workflowObjective(input.params);
57
61
  const missionsEnabled = input.config?.enabled !== false;
58
- const shouldCreate = input.params.mission !== undefined || (missionsEnabled && goal !== undefined);
59
- if (!input.params.missionId && !shouldCreate) return undefined;
62
+ const shouldCreate = input.params.mission !== undefined || (missionsEnabled && objective !== undefined);
63
+ if (!hasMissionId && !shouldCreate) return undefined;
60
64
  const location = resolveMissionStoreLocation({ projectRoot: input.projectRoot, ...(input.config ? { config: input.config } : {}) });
61
- if (input.params.missionId) {
65
+ if (hasMissionId) {
62
66
  const missionId = validateMissionId(input.params.missionId);
63
67
  readMission(location, missionId);
64
68
  updateMission(location, missionId, { status: "active" });
65
69
  return { missionId, location, autoCreated: false, announceInContent: true };
66
70
  }
67
71
  const mission = input.params.mission !== undefined ? validateMissionLaunch(input.params.mission) : undefined;
68
- const title = mission?.title || conciseTitle(goal!);
72
+ const promptDerivedObjective = mission?.objective ?? (mission ? mission.title : objective ? PROMPT_REDACTED : undefined);
73
+ const title = mission?.title || PROMPT_REDACTED;
69
74
  const record = createMission(location, {
70
75
  title,
71
- goal: mission?.goal || goal || title,
76
+ objective: promptDerivedObjective || title,
77
+ ...(mission?.goal === true ? { goal: true as const } : {}),
78
+ ...(mission?.budget ? { budget: mission.budget } : {}),
72
79
  status: "active",
73
80
  ...(mission?.labels ? { labels: mission.labels } : {}),
74
81
  ...(input.ownerSessionId ? { ownerSessionId: input.ownerSessionId } : {}),
@@ -92,7 +99,9 @@ function runStatusForResult(result: AgentToolResult<Details>): string {
92
99
  }
93
100
 
94
101
  function missionStatusForRun(record: MissionRecord, runId: string, runStatus: string): MissionStatus {
102
+ if (record.status === "completed" || record.status === "failed" || record.status === "cancelled") return record.status;
95
103
  if (runStatus === "active" || runStatus === "queued" || runStatus === "running") return "active";
104
+ if (record.goal) return "active";
96
105
  if (runStatus === "paused") return "waiting";
97
106
  const otherActive = record.runs.some((run) => run.runId !== runId && (run.status === "active" || run.status === "queued" || run.status === "running"));
98
107
  if (otherActive) return "active";
@@ -101,6 +110,17 @@ function missionStatusForRun(record: MissionRecord, runId: string, runStatus: st
101
110
  return "failed";
102
111
  }
103
112
 
113
+ function usageForResult(result: AgentToolResult<Details>): { tokens: number } | undefined {
114
+ const tokens = result.details.results.reduce((total, child) => total + child.usage.input + child.usage.output, 0);
115
+ return tokens > 0 ? { tokens } : undefined;
116
+ }
117
+
118
+ function usageFromUnknown(value: unknown): { tokens: number } | undefined {
119
+ if (!value || typeof value !== "object" || Array.isArray(value)) return undefined;
120
+ const total = (value as { total?: unknown }).total;
121
+ return Number.isSafeInteger(total) && (total as number) >= 0 ? { tokens: total as number } : undefined;
122
+ }
123
+
104
124
  function artifactsForResult(result: AgentToolResult<Details>): MissionArtifact[] {
105
125
  const artifacts: MissionArtifact[] = [];
106
126
  if (result.details.asyncDir) {
@@ -137,7 +157,7 @@ function persistedBinding(binding: MissionLaunchBinding): PersistedMissionBindin
137
157
  };
138
158
  }
139
159
 
140
- function writeAsyncBinding(asyncDir: string, binding: MissionLaunchBinding): void {
160
+ export function writeMissionAsyncBinding(asyncDir: string, binding: MissionLaunchBinding): void {
141
161
  writePrivateAtomicJson(path.join(asyncDir, MISSION_BINDING_FILE), persistedBinding(binding));
142
162
  }
143
163
 
@@ -168,6 +188,7 @@ export function attachMissionToLaunchResult(input: {
168
188
  const runStatus = runStatusForResult(input.result);
169
189
  const current = readMission(input.binding.location, input.binding.missionId);
170
190
  const startedAt = new Date().toISOString();
191
+ const usage = usageForResult(input.result);
171
192
  const run: MissionRunLink = {
172
193
  runId,
173
194
  mode: missionRunModeForResult(input.result.details.mode),
@@ -176,6 +197,7 @@ export function attachMissionToLaunchResult(input: {
176
197
  ...(input.result.details.asyncDir ? { asyncDir: input.result.details.asyncDir } : {}),
177
198
  ...(input.result.details.results.length === 1 && input.result.details.results[0]?.agent ? { agent: input.result.details.results[0].agent } : {}),
178
199
  ...(runStatus !== "active" ? { completedAt: startedAt } : {}),
200
+ ...(usage ? { usage } : {}),
179
201
  };
180
202
  let mission = updateMission(input.binding.location, input.binding.missionId, {
181
203
  status: missionStatusForRun(current, runId, runStatus),
@@ -185,7 +207,7 @@ export function attachMissionToLaunchResult(input: {
185
207
  ...(input.result.details.results.length === 1 && input.result.details.results[0]?.acceptance ? { acceptance: input.result.details.results[0].acceptance } : {}),
186
208
  });
187
209
  if (input.result.details.asyncDir) {
188
- writeAsyncBinding(input.result.details.asyncDir, input.binding);
210
+ writeMissionAsyncBinding(input.result.details.asyncDir, input.binding);
189
211
  const statusPath = path.join(input.result.details.asyncDir, "status.json");
190
212
  if (fs.existsSync(statusPath)) {
191
213
  try {
@@ -305,10 +327,36 @@ export function syncMissionFromAsyncCompletion(value: unknown): MissionRecord |
305
327
  }
306
328
  }
307
329
  const summary = typeof event.summary === "string" && event.summary.trim() ? event.summary.slice(0, 2000) : undefined;
330
+ const usage = usageFromUnknown(event.totalTokens)
331
+ ?? (Array.isArray(event.results)
332
+ ? { tokens: event.results.reduce((total, result) => {
333
+ if (!result || typeof result !== "object") return total;
334
+ return total + (usageFromUnknown((result as { tokens?: unknown }).tokens)?.tokens ?? 0);
335
+ }, 0) }
336
+ : undefined);
337
+ const workflowRunId = typeof event.parentWorkflowRunId === "string" && event.parentWorkflowRunId.trim() ? event.parentWorkflowRunId.trim() : undefined;
338
+ const workflowKey = typeof event.workflowKey === "string" && event.workflowKey.trim() ? event.workflowKey.trim() : undefined;
339
+ const workflowChildStatus = runStatus === "complete" || runStatus === "completed" || event.success === true
340
+ ? "completed"
341
+ : runStatus === "paused"
342
+ ? "paused"
343
+ : runStatus === "stopped"
344
+ ? "stopped"
345
+ : "failed";
346
+ const workflowChildTerminal = !["running", "queued", "active", "paused"].includes(workflowChildStatus);
308
347
  return updateMission(binding.location, binding.missionId, {
309
348
  status: missionStatusForRun(current, runId, runStatus),
310
- addRuns: [{ runId, mode: typeof event.mode === "string" && ["single", "parallel", "chain"].includes(event.mode) ? event.mode as SubagentRunMode : "external", asyncDir: event.asyncDir, status: runStatus, completedAt }],
349
+ addRuns: [{ runId, mode: typeof event.mode === "string" && ["single", "parallel", "chain", "workflow"].includes(event.mode) ? event.mode as SubagentRunMode : "external", asyncDir: event.asyncDir, status: runStatus, completedAt, ...(usage && usage.tokens > 0 ? { usage } : {}) }],
311
350
  addArtifacts: artifacts,
351
+ ...(workflowRunId && workflowKey ? { upsertWorkflowChildren: [{
352
+ workflowRunId,
353
+ key: workflowKey,
354
+ runId,
355
+ status: workflowChildStatus,
356
+ artifactPaths: artifacts.map((artifact) => artifact.path),
357
+ ...(workflowChildTerminal ? { completedAt } : {}),
358
+ heartbeat: { status: workflowChildStatus, ...(summary ? { message: summary } : {}) },
359
+ }] } : {}),
312
360
  ...(summary ? { summary } : {}),
313
361
  });
314
362
  }