@selesai/code 0.8.3 → 0.8.4

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 (493) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/extensions/handoff-new.ts +1 -1
  3. package/dist/extensions/inline-skills.test.ts +1 -0
  4. package/dist/extensions/inline-skills.ts +1 -1
  5. package/dist/extensions/pi-intercom/CHANGELOG.md +25 -3
  6. package/dist/extensions/pi-intercom/README.md +34 -15
  7. package/dist/extensions/pi-intercom/broker/broker.ts +38 -141
  8. package/dist/extensions/pi-intercom/broker/client-liveness.test.ts +173 -0
  9. package/dist/extensions/pi-intercom/broker/client.ts +78 -150
  10. package/dist/extensions/pi-intercom/broker/extension-state.ts +18 -7
  11. package/dist/extensions/pi-intercom/broker/framing.ts +1 -1
  12. package/dist/extensions/pi-intercom/broker/protocol.ts +182 -0
  13. package/dist/extensions/pi-intercom/broker/spawn.test.ts +106 -7
  14. package/dist/extensions/pi-intercom/broker/spawn.ts +37 -11
  15. package/dist/extensions/pi-intercom/config.test.ts +8 -10
  16. package/dist/extensions/pi-intercom/config.ts +3 -3
  17. package/dist/extensions/pi-intercom/index.ts +218 -147
  18. package/dist/extensions/pi-intercom/intercom.integration.test.ts +891 -103
  19. package/dist/extensions/pi-intercom/package.json +3 -2
  20. package/dist/extensions/pi-intercom/project-agent.test.ts +145 -0
  21. package/dist/extensions/pi-intercom/project-agent.ts +324 -0
  22. package/dist/extensions/pi-intercom/reply-tracker.test.ts +86 -1
  23. package/dist/extensions/pi-intercom/reply-tracker.ts +41 -9
  24. package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +49 -9
  25. package/dist/extensions/pi-intercom/test/inline-message.test.ts +9 -9
  26. package/dist/extensions/pi-intercom/types.ts +3 -1
  27. package/dist/extensions/pi-intercom/ui/inline-message.ts +7 -7
  28. package/dist/extensions/pi-powerline-footer/.github/workflows/test.yml +2 -2
  29. package/dist/extensions/pi-powerline-footer/CHANGELOG.md +14 -1
  30. package/dist/extensions/pi-powerline-footer/README.md +20 -37
  31. package/dist/extensions/pi-powerline-footer/bash-mode/completion.ts +40 -25
  32. package/dist/extensions/pi-powerline-footer/bash-mode/editor.ts +149 -18
  33. package/dist/extensions/pi-powerline-footer/bash-mode/types.ts +1 -0
  34. package/dist/extensions/pi-powerline-footer/editor-performance.ts +99 -0
  35. package/dist/extensions/pi-powerline-footer/git-status.ts +15 -0
  36. package/dist/extensions/pi-powerline-footer/index.ts +394 -317
  37. package/dist/extensions/pi-powerline-footer/package.json +1 -1
  38. package/dist/extensions/pi-powerline-footer/powerline-config.ts +0 -12
  39. package/dist/extensions/pi-powerline-footer/queue/store.ts +8 -56
  40. package/dist/extensions/pi-powerline-footer/queue/types.ts +1 -2
  41. package/dist/extensions/pi-powerline-footer/segments.ts +0 -3
  42. package/dist/extensions/pi-powerline-footer/tests/bash-mode.test.ts +231 -1
  43. package/dist/extensions/pi-powerline-footer/tests/custom-items.test.ts +5 -19
  44. package/dist/extensions/pi-powerline-footer/tests/editor-performance.test.ts +43 -0
  45. package/dist/extensions/pi-powerline-footer/tests/git-optional-locks.test.ts +64 -0
  46. package/dist/extensions/pi-powerline-footer/tests/jump-shortcuts.test.ts +116 -0
  47. package/dist/extensions/pi-powerline-footer/tests/queue-store.test.ts +19 -149
  48. package/dist/extensions/pi-powerline-footer/tests/remaining-regressions.test.ts +6 -0
  49. package/dist/extensions/pi-powerline-footer/tests/usage-display.test.ts +5 -5
  50. package/dist/extensions/pi-powerline-footer/types.ts +1 -2
  51. package/dist/extensions/pi-subagents/CHANGELOG.md +202 -14
  52. package/dist/extensions/pi-subagents/README.md +65 -1614
  53. package/dist/extensions/pi-subagents/agents/builder.md +0 -1
  54. package/dist/extensions/pi-subagents/agents/delegate.md +14 -0
  55. package/dist/extensions/pi-subagents/agents/oracle.md +74 -0
  56. package/dist/extensions/pi-subagents/agents/reviewer.md +78 -0
  57. package/dist/extensions/pi-subagents/agents/scout.md +50 -0
  58. package/dist/extensions/pi-subagents/agents/worker.md +58 -0
  59. package/dist/extensions/pi-subagents/docs/configuration.md +328 -0
  60. package/dist/extensions/pi-subagents/docs/extension-api.md +308 -0
  61. package/dist/extensions/pi-subagents/docs/missions.md +119 -0
  62. package/dist/extensions/pi-subagents/docs/models.md +192 -0
  63. package/dist/extensions/pi-subagents/docs/observability.md +174 -0
  64. package/dist/extensions/pi-subagents/docs/tool-reference.md +343 -0
  65. package/dist/extensions/pi-subagents/docs/watchdog.md +176 -0
  66. package/dist/extensions/pi-subagents/docs/workflows.md +163 -0
  67. package/dist/extensions/pi-subagents/inspector-runner.mjs +11 -0
  68. package/dist/extensions/pi-subagents/package-lock.json +152 -194
  69. package/dist/extensions/pi-subagents/package.json +9 -10
  70. package/dist/extensions/pi-subagents/prompts/gather-context-and-clarify.md +1 -1
  71. package/dist/extensions/pi-subagents/prompts/parallel-cleanup.md +9 -9
  72. package/dist/extensions/pi-subagents/prompts/parallel-research.md +6 -6
  73. package/dist/extensions/pi-subagents/prompts/parallel-review.md +8 -8
  74. package/dist/extensions/pi-subagents/prompts/review-loop.md +12 -12
  75. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +22 -17
  76. package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +77 -72
  77. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +177 -69
  78. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +28 -8
  79. package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +88 -66
  80. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +3 -3
  81. package/dist/extensions/pi-subagents/src/agents/agent-refinements.ts +624 -0
  82. package/dist/extensions/pi-subagents/src/agents/agents.ts +29 -16
  83. package/dist/extensions/pi-subagents/src/agents/frontmatter.ts +7 -3
  84. package/dist/extensions/pi-subagents/src/agents/proactive-skills.ts +2 -2
  85. package/dist/extensions/pi-subagents/src/agents/skills.ts +2 -9
  86. package/dist/extensions/pi-subagents/src/api/delegation.ts +1 -2
  87. package/dist/extensions/pi-subagents/src/api/project-panes.ts +30 -0
  88. package/dist/extensions/pi-subagents/src/extension/config.ts +56 -8
  89. package/dist/extensions/pi-subagents/src/extension/control-notices.ts +2 -2
  90. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +51 -26
  91. package/dist/extensions/pi-subagents/src/extension/index.ts +119 -50
  92. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +72 -0
  93. package/dist/extensions/pi-subagents/src/extension/rpc.ts +15 -15
  94. package/dist/extensions/pi-subagents/src/extension/schemas.ts +58 -21
  95. package/dist/extensions/pi-subagents/src/extension/subagent-guide.ts +39 -0
  96. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +47 -25
  97. package/dist/extensions/pi-subagents/src/inspectors/herdr/actions.ts +3 -3
  98. package/dist/extensions/pi-subagents/src/inspectors/herdr/project-panes.ts +460 -64
  99. package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +102 -4
  100. package/dist/extensions/pi-subagents/src/missions/actions.ts +77 -16
  101. package/dist/extensions/pi-subagents/src/missions/goal-driver.ts +162 -0
  102. package/dist/extensions/pi-subagents/src/missions/lifecycle.ts +65 -14
  103. package/dist/extensions/pi-subagents/src/missions/store.ts +147 -5
  104. package/dist/extensions/pi-subagents/src/missions/types.ts +58 -3
  105. package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +256 -0
  106. package/dist/extensions/pi-subagents/src/profiles/profiles.ts +8 -8
  107. package/dist/extensions/pi-subagents/src/runs/background/active-run-index.ts +42 -0
  108. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +41 -7
  109. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +294 -134
  110. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +19 -3
  111. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +39 -6
  112. package/dist/extensions/pi-subagents/src/runs/background/completion-replay.ts +267 -0
  113. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +145 -60
  114. package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +114 -6
  115. package/dist/extensions/pi-subagents/src/runs/background/resume-guidance.ts +33 -0
  116. package/dist/extensions/pi-subagents/src/runs/background/retained-children.ts +68 -0
  117. package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +71 -0
  118. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +21 -2
  119. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +42 -14
  120. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +12 -24
  121. package/dist/extensions/pi-subagents/src/runs/background/steering.ts +7 -5
  122. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +152 -68
  123. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +17 -4
  124. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +146 -0
  125. package/dist/extensions/pi-subagents/src/runs/background/wait-subscriptions.ts +21 -5
  126. package/dist/extensions/pi-subagents/src/runs/foreground/async-dismiss-action.ts +85 -0
  127. package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +43 -18
  128. package/dist/extensions/pi-subagents/src/runs/foreground/chain-clarify.ts +20 -19
  129. package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +3 -0
  130. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +55 -26
  131. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +137 -0
  132. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +798 -112
  133. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +187 -0
  134. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +165 -22
  135. package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +1 -1
  136. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +2 -0
  137. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +9 -5
  138. package/dist/extensions/pi-subagents/src/runs/shared/model-scope.ts +12 -2
  139. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +1 -0
  140. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +465 -116
  141. package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +10 -10
  142. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +189 -32
  143. package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +2 -2
  144. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +3 -3
  145. package/dist/extensions/pi-subagents/src/shared/artifacts.ts +128 -3
  146. package/dist/extensions/pi-subagents/src/shared/display-text.ts +100 -0
  147. package/dist/extensions/pi-subagents/src/shared/file-coalescer.ts +9 -0
  148. package/dist/extensions/pi-subagents/src/shared/fork-context.ts +13 -0
  149. package/dist/extensions/pi-subagents/src/shared/formatters.ts +4 -6
  150. package/dist/extensions/pi-subagents/src/shared/prompt-resources.ts +51 -0
  151. package/dist/extensions/pi-subagents/src/shared/settings.ts +41 -11
  152. package/dist/extensions/pi-subagents/src/shared/types.ts +100 -3
  153. package/dist/extensions/pi-subagents/src/shared/utf8.ts +11 -0
  154. package/dist/extensions/pi-subagents/src/shared/utils.ts +43 -33
  155. package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +1 -14
  156. package/dist/extensions/pi-subagents/src/slash/inline-subagents.ts +1 -1
  157. package/dist/extensions/pi-subagents/src/slash/prompt-template-bridge.ts +14 -12
  158. package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +176 -21
  159. package/dist/extensions/pi-subagents/src/slash/slash-bridge.ts +12 -6
  160. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +52 -18
  161. package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +36 -5
  162. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +30 -16
  163. package/dist/extensions/pi-subagents/src/tui/fleet.ts +151 -31
  164. package/dist/extensions/pi-subagents/src/tui/render.ts +201 -68
  165. package/dist/extensions/pi-subagents/src/types/pi-runtime-compat.d.ts +0 -6
  166. package/dist/extensions/pi-subagents/src/watchdog/change-signature.ts +5 -4
  167. package/dist/extensions/pi-subagents/src/watchdog/lsp-diagnostics.ts +0 -1
  168. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +313 -25
  169. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +15 -15
  170. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/cli.d.ts +3 -0
  171. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/register-bedrock.d.ts +2 -0
  172. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/restore-sandbox-env.d.ts +17 -0
  173. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/args.d.ts +57 -0
  174. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/config-selector.d.ts +16 -0
  175. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/file-processor.d.ts +15 -0
  176. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/initial-message.d.ts +18 -0
  177. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/list-models.d.ts +9 -0
  178. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/project-trust.d.ts +10 -0
  179. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/session-picker.d.ts +10 -0
  180. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/startup-ui.d.ts +20 -0
  181. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli.d.ts +3 -0
  182. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/config.d.ts +96 -0
  183. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-runtime.d.ts +119 -0
  184. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-services.d.ts +85 -0
  185. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session.d.ts +620 -0
  186. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-guidance.d.ts +5 -0
  187. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-storage.d.ts +56 -0
  188. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/bash-executor.d.ts +32 -0
  189. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/cache-stats.d.ts +49 -0
  190. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/branch-summarization.d.ts +93 -0
  191. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/compaction.d.ts +128 -0
  192. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/index.d.ts +7 -0
  193. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/utils.d.ts +38 -0
  194. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/defaults.d.ts +3 -0
  195. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/diagnostics.d.ts +15 -0
  196. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/event-bus.d.ts +9 -0
  197. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/exec.d.ts +29 -0
  198. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/experimental.d.ts +2 -0
  199. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/ansi-to-html.d.ts +22 -0
  200. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/index.d.ts +37 -0
  201. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/tool-renderer.d.ts +34 -0
  202. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/index.d.ts +12 -0
  203. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/loader.d.ts +23 -0
  204. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/runner.d.ts +171 -0
  205. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/types.d.ts +1261 -0
  206. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/wrapper.d.ts +20 -0
  207. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/footer-data-provider.d.ts +54 -0
  208. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/http-dispatcher.d.ts +22 -0
  209. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/index.d.ts +13 -0
  210. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/keybindings.d.ts +358 -0
  211. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/messages.d.ts +77 -0
  212. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-config.d.ts +512 -0
  213. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-registry.d.ts +43 -0
  214. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-resolver.d.ts +121 -0
  215. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-runtime.d.ts +82 -0
  216. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/models-store.d.ts +17 -0
  217. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/output-guard.d.ts +7 -0
  218. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/package-manager.d.ts +210 -0
  219. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/project-trust.d.ts +15 -0
  220. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/prompt-templates.d.ts +54 -0
  221. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-attribution.d.ts +4 -0
  222. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-composer.d.ts +55 -0
  223. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/radius.d.ts +2 -0
  224. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/remote-catalog-provider.d.ts +5 -0
  225. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resolve-config-value.d.ts +30 -0
  226. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resource-loader.d.ts +206 -0
  227. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/runtime-credentials.d.ts +15 -0
  228. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/sdk.d.ts +106 -0
  229. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-cwd.d.ts +19 -0
  230. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-manager.d.ts +356 -0
  231. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/settings-manager.d.ts +297 -0
  232. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/skills.d.ts +60 -0
  233. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/slash-commands.d.ts +15 -0
  234. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/source-info.d.ts +18 -0
  235. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/system-prompt.d.ts +28 -0
  236. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/telemetry.d.ts +3 -0
  237. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/timings.d.ts +10 -0
  238. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/bash.d.ts +68 -0
  239. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit-diff.d.ts +106 -0
  240. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit.d.ts +51 -0
  241. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/file-mutation-queue.d.ts +6 -0
  242. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/find.d.ts +35 -0
  243. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/grep.d.ts +37 -0
  244. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/index.d.ts +40 -0
  245. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/ls.d.ts +37 -0
  246. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/output-accumulator.d.ts +52 -0
  247. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/path-utils.d.ts +10 -0
  248. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/read.d.ts +35 -0
  249. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/render-utils.d.ts +24 -0
  250. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
  251. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/truncate.d.ts +70 -0
  252. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/write.d.ts +26 -0
  253. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/trust-manager.d.ts +36 -0
  254. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/usage-totals.d.ts +19 -0
  255. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/index.d.ts +3 -0
  256. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/client.d.ts +61 -0
  257. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/huggingface.d.ts +23 -0
  258. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/index.d.ts +3 -0
  259. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/provider.d.ts +10 -0
  260. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/ui.d.ts +42 -0
  261. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/index.d.ts +35 -0
  262. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/main.d.ts +12 -0
  263. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/migrations.d.ts +33 -0
  264. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/index.d.ts +9 -0
  265. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/armin.d.ts +34 -0
  266. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/assistant-message.d.ts +22 -0
  267. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bash-execution.d.ts +34 -0
  268. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  269. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
  270. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
  271. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/config-selector.d.ts +102 -0
  272. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  273. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-editor.d.ts +21 -0
  274. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-entry.d.ts +19 -0
  275. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-message.d.ts +20 -0
  276. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  277. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/diff.d.ts +12 -0
  278. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  279. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
  280. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-editor.d.ts +22 -0
  281. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-input.d.ts +23 -0
  282. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-selector.d.ts +26 -0
  283. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/first-time-setup.d.ts +25 -0
  284. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/footer.d.ts +32 -0
  285. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/index.d.ts +34 -0
  286. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
  287. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/login-dialog.d.ts +52 -0
  288. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/model-selector.d.ts +54 -0
  289. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/oauth-selector.d.ts +33 -0
  290. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/scoped-models-selector.d.ts +42 -0
  291. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
  292. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector.d.ts +95 -0
  293. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/settings-selector.d.ts +77 -0
  294. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  295. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  296. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/status-indicator.d.ts +28 -0
  297. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  298. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  299. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tool-execution.d.ts +63 -0
  300. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tree-selector.d.ts +94 -0
  301. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/trust-selector.d.ts +23 -0
  302. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  303. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message.d.ts +14 -0
  304. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  305. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/interactive-mode.d.ts +394 -0
  306. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/model-search.d.ts +12 -0
  307. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme-controller.d.ts +29 -0
  308. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme.d.ts +120 -0
  309. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/print-mode.d.ts +28 -0
  310. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/jsonl.d.ts +17 -0
  311. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-client.d.ts +246 -0
  312. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-mode.d.ts +20 -0
  313. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-types.d.ts +457 -0
  314. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/package-manager-cli.d.ts +8 -0
  315. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/rpc-entry.d.ts +3 -0
  316. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/ansi.d.ts +2 -0
  317. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/changelog.d.ts +22 -0
  318. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/child-process.d.ts +18 -0
  319. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-image.d.ts +11 -0
  320. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-native.d.ts +11 -0
  321. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard.d.ts +4 -0
  322. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/deprecation.d.ts +4 -0
  323. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/exif-orientation.d.ts +5 -0
  324. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/frontmatter.d.ts +8 -0
  325. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/fs-watch.d.ts +5 -0
  326. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/git.d.ts +26 -0
  327. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/html.d.ts +7 -0
  328. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-convert.d.ts +10 -0
  329. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-process.d.ts +18 -0
  330. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-core.d.ts +30 -0
  331. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-worker.d.ts +2 -0
  332. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize.d.ts +16 -0
  333. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/json.d.ts +3 -0
  334. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/mime.d.ts +3 -0
  335. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/open-browser.d.ts +9 -0
  336. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/paths.d.ts +31 -0
  337. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/photon.d.ts +21 -0
  338. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/pi-user-agent.d.ts +2 -0
  339. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/shell.d.ts +31 -0
  340. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/sleep.d.ts +5 -0
  341. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/syntax-highlight.d.ts +12 -0
  342. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/tools-manager.d.ts +3 -0
  343. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/version-check.d.ts +15 -0
  344. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/windows-self-update.d.ts +3 -0
  345. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/index.mjs +84 -0
  346. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/package.json +14 -0
  347. package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +15 -15
  348. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +411 -300
  349. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +309 -123
  350. package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +99 -56
  351. package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +62 -16
  352. package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +159 -108
  353. package/dist/extensions/pi-subagents/test/integration/detect-error.test.ts +1 -1
  354. package/dist/extensions/pi-subagents/test/integration/external-cli-runner.test.ts +4 -2
  355. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +56 -56
  356. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +114 -45
  357. package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +57 -19
  358. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +106 -106
  359. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +416 -106
  360. package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +287 -17
  361. package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +809 -87
  362. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +107 -20
  363. package/dist/extensions/pi-subagents/test/integration/slash-live-state.test.ts +9 -9
  364. package/dist/extensions/pi-subagents/test/integration/template-resolution.test.ts +26 -6
  365. package/dist/extensions/pi-subagents/test/integration/top-level-async.test.ts +2 -2
  366. package/dist/extensions/pi-subagents/test/support/helpers.ts +2 -0
  367. package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +1 -1
  368. package/dist/extensions/pi-subagents/test/support/ts-loader.mjs +0 -8
  369. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +163 -58
  370. package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +15 -15
  371. package/dist/extensions/pi-subagents/test/unit/agent-eject-disable.test.ts +66 -66
  372. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +334 -248
  373. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +52 -52
  374. package/dist/extensions/pi-subagents/test/unit/agent-memory.test.ts +26 -26
  375. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +99 -99
  376. package/dist/extensions/pi-subagents/test/unit/agent-refinements.test.ts +160 -0
  377. package/dist/extensions/pi-subagents/test/unit/agent-selection.test.ts +9 -9
  378. package/dist/extensions/pi-subagents/test/unit/artifacts.test.ts +43 -1
  379. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +36 -10
  380. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +387 -30
  381. package/dist/extensions/pi-subagents/test/unit/async-permission-session.test.ts +9 -9
  382. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +2 -2
  383. package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +94 -40
  384. package/dist/extensions/pi-subagents/test/unit/background-work.test.ts +5 -3
  385. package/dist/extensions/pi-subagents/test/unit/builtin-agent-documentation.test.ts +7 -7
  386. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +19 -19
  387. package/dist/extensions/pi-subagents/test/unit/chain-append.test.ts +19 -19
  388. package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +9 -9
  389. package/dist/extensions/pi-subagents/test/unit/chain-serializer.test.ts +20 -20
  390. package/dist/extensions/pi-subagents/test/unit/child-transcript.test.ts +9 -9
  391. package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +35 -5
  392. package/dist/extensions/pi-subagents/test/unit/completion-dedupe.test.ts +2 -2
  393. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +52 -52
  394. package/dist/extensions/pi-subagents/test/unit/completion-replay.test.ts +187 -0
  395. package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +125 -71
  396. package/dist/extensions/pi-subagents/test/unit/control-notices.test.ts +18 -3
  397. package/dist/extensions/pi-subagents/test/unit/default-extensions.test.ts +12 -12
  398. package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +17 -23
  399. package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +1 -1
  400. package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +25 -25
  401. package/dist/extensions/pi-subagents/test/unit/extra-agent-dirs.test.ts +3 -3
  402. package/dist/extensions/pi-subagents/test/unit/file-coalescer.test.ts +15 -0
  403. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +62 -44
  404. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +329 -37
  405. package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +4 -4
  406. package/dist/extensions/pi-subagents/test/unit/foreground-tool-call-compaction.test.ts +37 -0
  407. package/dist/extensions/pi-subagents/test/unit/herdr-inspector-bootstrap.test.ts +69 -0
  408. package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +79 -2
  409. package/dist/extensions/pi-subagents/test/unit/herdr-status-bridge.test.ts +102 -49
  410. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +98 -32
  411. package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +5 -5
  412. package/dist/extensions/pi-subagents/test/unit/mission-goal-driver.test.ts +116 -0
  413. package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +55 -7
  414. package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +289 -13
  415. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +28 -1
  416. package/dist/extensions/pi-subagents/test/unit/model-scope-settings.test.ts +2 -2
  417. package/dist/extensions/pi-subagents/test/unit/model-scope.test.ts +11 -2
  418. package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +84 -10
  419. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +122 -8
  420. package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +8 -8
  421. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +24 -24
  422. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +16 -2
  423. package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +7 -7
  424. package/dist/extensions/pi-subagents/test/unit/parallel-utils.test.ts +10 -10
  425. package/dist/extensions/pi-subagents/test/unit/path-handling.test.ts +3 -3
  426. package/dist/extensions/pi-subagents/test/unit/path-resolution.test.ts +26 -17
  427. package/dist/extensions/pi-subagents/test/unit/pi-args-permission-system.test.ts +405 -0
  428. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +357 -92
  429. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +22 -6
  430. package/dist/extensions/pi-subagents/test/unit/pi-spawn.test.ts +6 -6
  431. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +43 -43
  432. package/dist/extensions/pi-subagents/test/unit/proactive-skills.test.ts +13 -13
  433. package/dist/extensions/pi-subagents/test/unit/process-terminal.test.ts +4 -4
  434. package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +19 -19
  435. package/dist/extensions/pi-subagents/test/unit/project-panes-public-api.test.ts +243 -0
  436. package/dist/extensions/pi-subagents/test/unit/prompt-template-bridge.test.ts +68 -168
  437. package/dist/extensions/pi-subagents/test/unit/prompt-workflows.test.ts +58 -15
  438. package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +40 -0
  439. package/dist/extensions/pi-subagents/test/unit/reads-resolution.test.ts +66 -0
  440. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +47 -28
  441. package/dist/extensions/pi-subagents/test/unit/result-intercom.test.ts +12 -12
  442. package/dist/extensions/pi-subagents/test/unit/retained-children.test.ts +57 -0
  443. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +107 -27
  444. package/dist/extensions/pi-subagents/test/unit/run-id-resolver.test.ts +1 -1
  445. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +56 -50
  446. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +69 -28
  447. package/dist/extensions/pi-subagents/test/unit/scheduled-store-root.test.ts +67 -0
  448. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +59 -44
  449. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +424 -49
  450. package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +23 -1
  451. package/dist/extensions/pi-subagents/test/unit/slash-bridge.test.ts +32 -5
  452. package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +13 -13
  453. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +120 -91
  454. package/dist/extensions/pi-subagents/test/unit/steering.test.ts +2 -2
  455. package/dist/extensions/pi-subagents/test/unit/subagent-action-recovery.test.ts +85 -0
  456. package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +35 -35
  457. package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +24 -0
  458. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +312 -22
  459. package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +150 -15
  460. package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +26 -26
  461. package/dist/extensions/pi-subagents/test/unit/timeout-defaults.test.ts +73 -0
  462. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +76 -25
  463. package/dist/extensions/pi-subagents/test/unit/turn-budget.test.ts +5 -5
  464. package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +55 -6
  465. package/dist/extensions/pi-subagents/test/unit/watchdog-child-status.test.ts +13 -13
  466. package/dist/extensions/pi-subagents/test/unit/watchdog-lsp-diagnostics.test.ts +1 -1
  467. package/dist/extensions/pi-subagents/test/unit/watchdog-runtime.test.ts +1 -1
  468. package/dist/extensions/pi-subagents/test/unit/watchdog-settings.test.ts +8 -8
  469. package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +6 -6
  470. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +138 -11
  471. package/dist/extensions/pi-subagents/test/unit/workflow-graph.test.ts +8 -8
  472. package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +113 -0
  473. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +7 -7
  474. package/dist/extensions/pi-subagents/test/unit/writer-budget-guidance.test.ts +6 -6
  475. package/dist/extensions/workflow/extension.ts +21 -19
  476. package/dist/extensions/workflow/modes.ts +65 -0
  477. package/dist/skills/pi-subagents/SKILL.md +20 -15
  478. package/dist/skills/pi-subagents/references/constraints-and-recipes.md +77 -83
  479. package/dist/skills/pi-subagents/references/execution-controls.md +215 -106
  480. package/dist/skills/pi-subagents/references/management-authoring-rpc.md +29 -9
  481. package/dist/skills/pi-subagents/references/prompting-and-roles.md +58 -43
  482. package/docs/plans/workflow-autoloop-reference.md +192 -0
  483. package/docs/plans/workflow-subagent-consolidation-planb.md +374 -0
  484. package/docs/plans/workflow-subagent-scripted-merge.md +406 -0
  485. package/package.json +1 -1
  486. package/dist/extensions/workflow/adapter.ts +0 -949
  487. package/dist/extensions/workflow/modes/loop.ts +0 -74
  488. package/dist/extensions/workflow/modes/prototype.ts +0 -170
  489. package/dist/extensions/workflow/modes/quicktype.ts +0 -150
  490. package/dist/extensions/workflow/modes/task.ts +0 -105
  491. package/dist/extensions/workflow/run-state.ts +0 -124
  492. package/dist/extensions/workflow/state-machine.ts +0 -484
  493. package/dist/extensions/workflow/validators.ts +0 -42
@@ -2,6 +2,7 @@ import { createHash, randomUUID } from "node:crypto";
2
2
  import * as fs from "node:fs";
3
3
  import * as os from "node:os";
4
4
  import * as path from "node:path";
5
+ import { getProjectSubagentsDir } from "../shared/artifacts.ts";
5
6
  import { writePrivateAtomicJson } from "../shared/atomic-json.ts";
6
7
  import { getAgentDir } from "../shared/utils.ts";
7
8
  import {
@@ -12,6 +13,7 @@ import {
12
13
  type MissionArtifactKind,
13
14
  type MissionCreateInput,
14
15
  type MissionDecision,
16
+ type MissionGoal,
15
17
  type MissionIndexEntry,
16
18
  type MissionListResult,
17
19
  type MissionReceipt,
@@ -23,7 +25,10 @@ import {
23
25
  type MissionStatus,
24
26
  type MissionStoreConfig,
25
27
  type MissionStoreLocation,
28
+ type MissionTokenBudget,
29
+ type MissionTokenUsage,
26
30
  type MissionUpdateInput,
31
+ type MissionWorkflowChild,
27
32
  } from "./types.ts";
28
33
 
29
34
  const MISSION_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
@@ -63,6 +68,37 @@ function missionStatus(value: unknown, label: string): MissionStatus {
63
68
  return value as MissionStatus;
64
69
  }
65
70
 
71
+ function positiveTokenCount(value: unknown, label: string): number {
72
+ if (!Number.isSafeInteger(value) || (value as number) < 1) throw new Error(`${label} must be a positive integer`);
73
+ return value as number;
74
+ }
75
+
76
+ function nonNegativeTokenCount(value: unknown, label: string): number {
77
+ if (!Number.isSafeInteger(value) || (value as number) < 0) throw new Error(`${label} must be a non-negative integer`);
78
+ return value as number;
79
+ }
80
+
81
+ function parseStoredGoal(value: unknown, label: string): { goal?: MissionGoal; legacyObjective?: string } {
82
+ if (typeof value === "string") return { legacyObjective: requiredString(value, label).trim() };
83
+ return { goal: parseGoal(value, label) };
84
+ }
85
+
86
+ function parseGoal(value: unknown, label: string): MissionGoal {
87
+ const input = asObject(value, label);
88
+ if (input.status !== "active" && input.status !== "paused" && input.status !== "budget-exhausted") throw new Error(`${label}.status is invalid`);
89
+ return { status: input.status };
90
+ }
91
+
92
+ function parseBudget(value: unknown, label: string): MissionTokenBudget {
93
+ const input = asObject(value, label);
94
+ return { tokens: positiveTokenCount(input.tokens, `${label}.tokens`) };
95
+ }
96
+
97
+ function parseUsage(value: unknown, label: string): MissionTokenUsage {
98
+ const input = asObject(value, label);
99
+ return { tokens: nonNegativeTokenCount(input.tokens, `${label}.tokens`) };
100
+ }
101
+
66
102
  function stringArray(value: unknown, label: string): string[] {
67
103
  if (!Array.isArray(value)) throw new Error(`${label} must be an array of non-empty strings`);
68
104
  const result = value.map((item, index) => requiredString(item, `${label}[${index}]`).trim());
@@ -94,6 +130,7 @@ function parseRunLink(value: unknown, label: string): MissionRunLink {
94
130
  ...(optionalString(input.status, `${label}.status`) ? { status: input.status as string } : {}),
95
131
  ...(input.startedAt !== undefined ? { startedAt: timestamp(input.startedAt, `${label}.startedAt`) } : {}),
96
132
  ...(input.completedAt !== undefined ? { completedAt: timestamp(input.completedAt, `${label}.completedAt`) } : {}),
133
+ ...(input.usage !== undefined ? { usage: parseUsage(input.usage, `${label}.usage`) } : {}),
97
134
  };
98
135
  }
99
136
 
@@ -114,6 +151,33 @@ function parseDecision(value: unknown, label: string): MissionDecision {
114
151
  };
115
152
  }
116
153
 
154
+ function parseWorkflowChild(value: unknown, label: string): MissionWorkflowChild {
155
+ const input = asObject(value, label);
156
+ const artifactPaths = input.artifactPaths === undefined ? [] : stringArray(input.artifactPaths, `${label}.artifactPaths`);
157
+ const heartbeat = input.heartbeat === undefined ? undefined : asObject(input.heartbeat, `${label}.heartbeat`);
158
+ return {
159
+ workflowRunId: requiredString(input.workflowRunId, `${label}.workflowRunId`),
160
+ key: validateMissionId(input.key, `${label}.key`),
161
+ status: requiredString(input.status, `${label}.status`),
162
+ startedAt: timestamp(input.startedAt, `${label}.startedAt`),
163
+ updatedAt: timestamp(input.updatedAt, `${label}.updatedAt`),
164
+ artifactPaths,
165
+ ...(optionalString(input.runId, `${label}.runId`) ? { runId: input.runId as string } : {}),
166
+ ...(optionalString(input.agent, `${label}.agent`) ? { agent: input.agent as string } : {}),
167
+ ...(optionalString(input.task, `${label}.task`) ? { task: input.task as string } : {}),
168
+ ...(optionalString(input.label, `${label}.label`) ? { label: input.label as string } : {}),
169
+ ...(optionalString(input.phase, `${label}.phase`) ? { phase: input.phase as string } : {}),
170
+ ...(input.completedAt !== undefined ? { completedAt: timestamp(input.completedAt, `${label}.completedAt`) } : {}),
171
+ ...(optionalString(input.sessionPath, `${label}.sessionPath`) ? { sessionPath: input.sessionPath as string } : {}),
172
+ ...(heartbeat ? { heartbeat: {
173
+ updatedAt: timestamp(heartbeat.updatedAt, `${label}.heartbeat.updatedAt`),
174
+ ...(optionalString(heartbeat.status, `${label}.heartbeat.status`) ? { status: heartbeat.status as string } : {}),
175
+ ...(optionalString(heartbeat.phase, `${label}.heartbeat.phase`) ? { phase: heartbeat.phase as string } : {}),
176
+ ...(optionalString(heartbeat.message, `${label}.heartbeat.message`) ? { message: heartbeat.message as string } : {}),
177
+ } } : {}),
178
+ };
179
+ }
180
+
117
181
  function parseArtifact(value: unknown, label: string): MissionArtifact {
118
182
  const input = asObject(value, label);
119
183
  const kind = requiredString(input.kind, `${label}.kind`) as MissionArtifactKind;
@@ -151,22 +215,34 @@ export function parseMissionRecord(value: unknown, source = "mission record"): M
151
215
  const input = asObject(value, source);
152
216
  if (input.schemaVersion !== 1) throw new Error(`${source}.schemaVersion must be 1`);
153
217
  if (!Array.isArray(input.runs)) throw new Error(`${source}.runs must be an array`);
218
+ if (input.workflowChildren !== undefined && !Array.isArray(input.workflowChildren)) throw new Error(`${source}.workflowChildren must be an array`);
154
219
  if (!Array.isArray(input.decisions)) throw new Error(`${source}.decisions must be an array`);
155
220
  if (!Array.isArray(input.artifacts)) throw new Error(`${source}.artifacts must be an array`);
156
221
  if (input.receipts !== undefined && !Array.isArray(input.receipts)) throw new Error(`${source}.receipts must be an array`);
157
222
  const runs = input.runs as unknown[];
223
+ const workflowChildren = (input.workflowChildren ?? []) as unknown[];
158
224
  const decisions = input.decisions as unknown[];
159
225
  const artifacts = input.artifacts as unknown[];
160
226
  const receipts = (input.receipts ?? []) as unknown[];
227
+ const parsedGoal = input.goal !== undefined ? parseStoredGoal(input.goal, `${source}.goal`) : {};
228
+ const budget = input.budget !== undefined ? parseBudget(input.budget, `${source}.budget`) : undefined;
229
+ const usage = input.usage !== undefined ? parseUsage(input.usage, `${source}.usage`) : undefined;
230
+ const objective = optionalString(input.objective, `${source}.objective`)?.trim() ?? parsedGoal.legacyObjective;
231
+ if (!objective) throw new Error(`${source}.objective must be a non-empty string`);
232
+ if (parsedGoal.goal && !budget) throw new Error(`${source}.budget is required for a goal mission`);
161
233
  return {
162
234
  schemaVersion: 1,
163
235
  id: validateMissionId(input.id, `${source}.id`),
164
236
  title: requiredString(input.title, `${source}.title`),
165
- goal: requiredString(input.goal, `${source}.goal`),
237
+ objective,
238
+ ...(parsedGoal.goal ? { goal: parsedGoal.goal } : {}),
239
+ ...(budget ? { budget } : {}),
240
+ ...(usage ? { usage } : {}),
166
241
  status: missionStatus(input.status, `${source}.status`),
167
242
  createdAt: timestamp(input.createdAt, `${source}.createdAt`),
168
243
  updatedAt: timestamp(input.updatedAt, `${source}.updatedAt`),
169
244
  runs: runs.map((item, index) => parseRunLink(item, `${source}.runs[${index}]`)),
245
+ workflowChildren: workflowChildren.map((item, index) => parseWorkflowChild(item, `${source}.workflowChildren[${index}]`)),
170
246
  decisions: decisions.map((item, index) => parseDecision(item, `${source}.decisions[${index}]`)),
171
247
  artifacts: artifacts.map((item, index) => parseArtifact(item, `${source}.artifacts[${index}]`)),
172
248
  receipts: receipts.map((item, index) => parseReceipt(item, `${source}.receipts[${index}]`)),
@@ -215,7 +291,7 @@ export function resolveMissionStoreLocation(input: {
215
291
  const projectRoot = path.resolve(input.projectRoot);
216
292
  const missionDir = input.config?.directory
217
293
  ? expandConfiguredPath(input.config.directory, projectRoot)
218
- : path.join(projectRoot, ".pi-subagents", "missions");
294
+ : path.join(getProjectSubagentsDir(projectRoot), "missions");
219
295
  const globalIndexDir = input.config?.globalIndexDir
220
296
  ? expandConfiguredPath(input.config.globalIndexDir, projectRoot)
221
297
  : path.join(input.agentDir ?? getAgentDir(), "missions", "index");
@@ -279,6 +355,7 @@ function pruneTerminalMissions(location: MissionStoreLocation, maxTerminal: numb
279
355
  for (const record of terminal.slice(maxTerminal)) {
280
356
  try {
281
357
  fs.rmSync(missionRecordPath(location, record.id), { force: true });
358
+ fs.rmSync(path.join(location.missionDir, record.id), { recursive: true, force: true });
282
359
  if (location.writeGlobalIndex) fs.rmSync(indexPath(location, record), { force: true });
283
360
  } catch {
284
361
  // Retention is best-effort and must never block a launch.
@@ -292,18 +369,23 @@ export function createMission(location: MissionStoreLocation, input: MissionCrea
292
369
  schemaVersion: 1,
293
370
  id: randomUUID(),
294
371
  title: requiredString(input.title, "mission.title").trim(),
295
- goal: requiredString(input.goal, "mission.goal").trim(),
372
+ objective: requiredString(input.objective, "mission.objective").trim(),
373
+ ...(input.goal === true ? { goal: { status: "active" as const } } : {}),
374
+ ...(input.budget ? { budget: parseBudget(input.budget, "mission.budget") } : {}),
375
+ ...(input.goal === true ? { usage: { tokens: 0 } } : {}),
296
376
  status: input.status ?? "planned",
297
377
  createdAt,
298
378
  updatedAt: createdAt,
299
379
  cwd: location.projectRoot,
300
380
  runs: [],
381
+ workflowChildren: [],
301
382
  decisions: [],
302
383
  artifacts: [],
303
384
  receipts: [],
304
385
  ...(input.ownerSessionId ? { ownerSessionId: requiredString(input.ownerSessionId, "mission.ownerSessionId") } : {}),
305
386
  ...(input.labels ? { labels: stringArray(input.labels, "mission.labels") } : {}),
306
387
  };
388
+ if (input.goal === true && !input.budget) throw new Error("mission.budget is required when mission.goal is true");
307
389
  const created = writeMission(location, record);
308
390
  pruneTerminalMissions(location, retainTerminal);
309
391
  return created;
@@ -363,6 +445,28 @@ export function updateMission(location: MissionStoreLocation, missionId: string,
363
445
  if (existingIndex === -1) runs.push(run);
364
446
  else runs[existingIndex] = { ...runs[existingIndex]!, ...run };
365
447
  }
448
+ const workflowChildren = [...current.workflowChildren];
449
+ for (const candidate of update.upsertWorkflowChildren ?? []) {
450
+ const nowIso = now.toISOString();
451
+ const parsed = parseWorkflowChild({
452
+ ...candidate,
453
+ startedAt: candidate.startedAt ?? nowIso,
454
+ updatedAt: nowIso,
455
+ artifactPaths: candidate.artifactPaths ?? [],
456
+ ...(candidate.heartbeat ? { heartbeat: { ...candidate.heartbeat, updatedAt: nowIso } } : {}),
457
+ }, "mission.update.upsertWorkflowChildren[]");
458
+ const existingIndex = workflowChildren.findIndex((child) => child.workflowRunId === parsed.workflowRunId && child.key === parsed.key);
459
+ if (existingIndex === -1) workflowChildren.push(parsed);
460
+ else {
461
+ const existing = workflowChildren[existingIndex]!;
462
+ workflowChildren[existingIndex] = parseWorkflowChild({
463
+ ...existing,
464
+ ...parsed,
465
+ startedAt: existing.startedAt,
466
+ artifactPaths: [...new Set([...existing.artifactPaths, ...parsed.artifactPaths])],
467
+ }, "mission.update.upsertWorkflowChildren[]");
468
+ }
469
+ }
366
470
  const artifacts = [...current.artifacts];
367
471
  for (const candidate of update.addArtifacts ?? []) {
368
472
  const artifact = parseArtifact(candidate, "mission.update.addArtifacts[]");
@@ -390,20 +494,58 @@ export function updateMission(location: MissionStoreLocation, missionId: string,
390
494
  ...(decision.recommendation ? { recommendation: requiredString(decision.recommendation, "mission.update.addDecisions[].recommendation") } : {}),
391
495
  })),
392
496
  ];
497
+ if (update.resolveDecision) {
498
+ const decisionId = validateMissionId(update.resolveDecision.id, "mission.update.resolveDecision.id");
499
+ const decisionIndex = decisions.findIndex((decision) => decision.id === decisionId);
500
+ if (decisionIndex === -1) throw new Error(`Decision '${decisionId}' was not found in mission '${missionId}'`);
501
+ if (decisions[decisionIndex]!.status === "resolved") throw new Error(`Decision '${decisionId}' is already resolved`);
502
+ decisions[decisionIndex] = {
503
+ ...decisions[decisionIndex]!,
504
+ status: "resolved",
505
+ resolvedAt: createdAt,
506
+ resolution: requiredString(update.resolveDecision.resolution, "mission.update.resolveDecision.resolution").trim(),
507
+ };
508
+ }
509
+ const budget = update.budget !== undefined ? parseBudget(update.budget, "mission.update.budget") : current.budget;
510
+ const usage = update.usage !== undefined
511
+ ? parseUsage(update.usage, "mission.update.usage")
512
+ : { tokens: runs.reduce((total, run) => total + (run.usage?.tokens ?? 0), 0) };
513
+ let goal = update.goal === false ? undefined : update.goal !== undefined ? parseGoal(update.goal, "mission.update.goal") : current.goal;
514
+ if (goal && !budget) throw new Error("mission.update.budget is required when enabling a goal mission");
515
+ if (goal && budget) {
516
+ goal = usage.tokens >= budget.tokens
517
+ ? { status: "budget-exhausted" }
518
+ : goal.status === "budget-exhausted"
519
+ ? { status: "active" }
520
+ : goal;
521
+ }
522
+ const hasOpenDecisions = decisions.some((decision) => decision.status === "open");
523
+ const requestedStatus = update.status !== undefined ? missionStatus(update.status, "mission.update.status") : undefined;
524
+ const candidateStatus = requestedStatus
525
+ ?? (update.addDecisions?.length && current.status === "active"
526
+ ? "needs_decision"
527
+ : update.resolveDecision && current.status === "needs_decision" && !hasOpenDecisions
528
+ ? "active"
529
+ : current.status);
530
+ const decisionStatus = hasOpenDecisions && (candidateStatus === "active" || candidateStatus === "completed") ? "needs_decision" : candidateStatus;
393
531
  const next: MissionRecord = {
394
532
  ...current,
395
533
  updatedAt: createdAt,
396
534
  runs,
535
+ workflowChildren,
397
536
  artifacts,
398
537
  receipts,
399
538
  decisions,
400
539
  ...(update.title !== undefined ? { title: requiredString(update.title, "mission.update.title").trim() } : {}),
401
- ...(update.goal !== undefined ? { goal: requiredString(update.goal, "mission.update.goal").trim() } : {}),
402
- ...(update.status !== undefined ? { status: missionStatus(update.status, "mission.update.status") } : {}),
540
+ ...(update.objective !== undefined ? { objective: requiredString(update.objective, "mission.update.objective").trim() } : {}),
541
+ ...(budget ? { budget } : {}),
542
+ ...(goal ? { goal, usage } : {}),
543
+ status: decisionStatus,
403
544
  ...(update.summary !== undefined ? { summary: requiredString(update.summary, "mission.update.summary") } : {}),
404
545
  ...(update.labels !== undefined ? { labels: stringArray(update.labels, "mission.update.labels") } : {}),
405
546
  ...(update.acceptance !== undefined ? { acceptance: update.acceptance } : {}),
406
547
  };
548
+ if (!goal) delete next.goal;
407
549
  const updated = writeMission(location, next);
408
550
  if (TERMINAL_MISSION_STATUSES.has(updated.status)) pruneTerminalMissions(location, retainTerminal);
409
551
  return updated;
@@ -13,6 +13,19 @@ export type MissionRunMode = "single" | "parallel" | "chain" | "workflow" | "sch
13
13
  export type MissionArtifactKind = "status" | "output" | "patch" | "manifest" | "review" | "note" | "other";
14
14
  export type MissionReceiptKind = "pull_request" | "ci" | "deployment" | "release";
15
15
  export type MissionReceiptStatus = "pending" | "ready" | "succeeded" | "failed";
16
+ export type MissionGoalStatus = "active" | "paused" | "budget-exhausted";
17
+
18
+ export interface MissionGoal {
19
+ status: MissionGoalStatus;
20
+ }
21
+
22
+ export interface MissionTokenBudget {
23
+ tokens: number;
24
+ }
25
+
26
+ export interface MissionTokenUsage {
27
+ tokens: number;
28
+ }
16
29
 
17
30
  export interface MissionRunLink {
18
31
  runId: string;
@@ -23,6 +36,7 @@ export interface MissionRunLink {
23
36
  status?: string;
24
37
  startedAt?: string;
25
38
  completedAt?: string;
39
+ usage?: MissionTokenUsage;
26
40
  }
27
41
 
28
42
  export interface MissionDecision {
@@ -37,6 +51,36 @@ export interface MissionDecision {
37
51
  resolution?: string;
38
52
  }
39
53
 
54
+ export interface MissionChildHeartbeat {
55
+ updatedAt: string;
56
+ status?: string;
57
+ phase?: string;
58
+ message?: string;
59
+ }
60
+
61
+ export interface MissionWorkflowChild {
62
+ workflowRunId: string;
63
+ key: string;
64
+ status: string;
65
+ startedAt: string;
66
+ updatedAt: string;
67
+ runId?: string;
68
+ agent?: string;
69
+ task?: string;
70
+ label?: string;
71
+ phase?: string;
72
+ completedAt?: string;
73
+ sessionPath?: string;
74
+ artifactPaths: string[];
75
+ heartbeat?: MissionChildHeartbeat;
76
+ }
77
+
78
+ export type MissionWorkflowChildUpdate = Pick<MissionWorkflowChild, "workflowRunId" | "key" | "status"> & Partial<Omit<MissionWorkflowChild, "workflowRunId" | "key" | "status" | "startedAt" | "updatedAt" | "artifactPaths" | "heartbeat">> & {
79
+ startedAt?: string;
80
+ artifactPaths?: string[];
81
+ heartbeat?: Omit<MissionChildHeartbeat, "updatedAt"> & { updatedAt?: string };
82
+ };
83
+
40
84
  export interface MissionArtifact {
41
85
  kind: MissionArtifactKind;
42
86
  path: string;
@@ -56,13 +100,17 @@ export interface MissionRecord {
56
100
  schemaVersion: 1;
57
101
  id: string;
58
102
  title: string;
59
- goal: string;
103
+ objective: string;
104
+ goal?: MissionGoal;
105
+ budget?: MissionTokenBudget;
106
+ usage?: MissionTokenUsage;
60
107
  status: MissionStatus;
61
108
  createdAt: string;
62
109
  updatedAt: string;
63
110
  cwd?: string;
64
111
  ownerSessionId?: string;
65
112
  runs: MissionRunLink[];
113
+ workflowChildren: MissionWorkflowChild[];
66
114
  decisions: MissionDecision[];
67
115
  artifacts: MissionArtifact[];
68
116
  receipts: MissionReceipt[];
@@ -115,7 +163,9 @@ export interface GlobalMissionListResult {
115
163
 
116
164
  export interface MissionCreateInput {
117
165
  title: string;
118
- goal: string;
166
+ objective: string;
167
+ goal?: boolean;
168
+ budget?: MissionTokenBudget;
119
169
  status?: MissionStatus;
120
170
  labels?: string[];
121
171
  ownerSessionId?: string;
@@ -123,13 +173,18 @@ export interface MissionCreateInput {
123
173
 
124
174
  export interface MissionUpdateInput {
125
175
  title?: string;
126
- goal?: string;
176
+ objective?: string;
177
+ goal?: MissionGoal | false;
178
+ budget?: MissionTokenBudget;
179
+ usage?: MissionTokenUsage;
127
180
  status?: MissionStatus;
128
181
  summary?: string;
129
182
  labels?: string[];
130
183
  acceptance?: unknown;
131
184
  addRuns?: MissionRunLink[];
185
+ upsertWorkflowChildren?: MissionWorkflowChildUpdate[];
132
186
  addArtifacts?: MissionArtifact[];
133
187
  addDecisions?: Array<Omit<MissionDecision, "id" | "status" | "createdAt">>;
188
+ resolveDecision?: { id: string; resolution: string };
134
189
  addReceipts?: Array<Omit<MissionReceipt, "createdAt">>;
135
190
  }
@@ -0,0 +1,256 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { randomUUID } from "node:crypto";
3
+ import * as fs from "node:fs";
4
+ import * as path from "node:path";
5
+ import { writePrivateAtomicJson } from "../shared/atomic-json.ts";
6
+ import { DEFAULT_FILE_SYSTEM_RETRY_DELAYS_MS, isRetryableFileSystemError, waitForFileSystemRetry } from "../shared/file-system-retry.ts";
7
+ import { assertWorkflowJsonValue } from "../workflows/scripted-workflow.ts";
8
+ import type { MissionStoreLocation } from "./types.ts";
9
+ import { validateMissionId } from "./store.ts";
10
+
11
+ const STATE_KEY_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
12
+ const STATE_LOCK_STALE_MS = 60_000;
13
+ export const MISSION_STATE_MAX_BYTES = 256 * 1024;
14
+
15
+ export interface MissionWorkflowState {
16
+ path: string;
17
+ get(key: string): unknown;
18
+ set(key: string, value: unknown): void;
19
+ }
20
+
21
+ export function missionStatePath(location: MissionStoreLocation, missionId: string): string {
22
+ return path.join(location.missionDir, validateMissionId(missionId), "state.json");
23
+ }
24
+
25
+ function isProcessAlive(pid: number): boolean {
26
+ try {
27
+ process.kill(pid, 0);
28
+ return true;
29
+ } catch (error) {
30
+ return (error as NodeJS.ErrnoException).code === "EPERM";
31
+ }
32
+ }
33
+
34
+ interface StateLockOwner {
35
+ pid: number;
36
+ token: string;
37
+ createdAt: number;
38
+ processKey?: string;
39
+ }
40
+
41
+ function linuxProcessStartKey(pid: number): string | undefined {
42
+ try {
43
+ const raw = fs.readFileSync(`/proc/${pid}/stat`, "utf-8");
44
+ const tail = raw.slice(raw.lastIndexOf(")") + 2).trim().split(/\s+/);
45
+ return tail[19] ? `linux:${tail[19]}` : undefined;
46
+ } catch {
47
+ return undefined;
48
+ }
49
+ }
50
+
51
+ function psProcessStartKey(pid: number): string | undefined {
52
+ try {
53
+ const raw = execFileSync("ps", ["-p", String(pid), "-o", "lstart="], { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"], timeout: 1000 }).trim();
54
+ return raw ? `ps:${raw}` : undefined;
55
+ } catch {
56
+ return undefined;
57
+ }
58
+ }
59
+
60
+ function windowsProcessStartKey(pid: number): string | undefined {
61
+ try {
62
+ const raw = execFileSync("powershell.exe", ["-NoProfile", "-Command", `(Get-CimInstance Win32_Process -Filter \"ProcessId=${pid}\").CreationDate`], { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"], timeout: 1000 }).trim();
63
+ return raw ? `win:${raw}` : undefined;
64
+ } catch {
65
+ return undefined;
66
+ }
67
+ }
68
+
69
+ function processStartKey(pid: number): string | undefined {
70
+ if (process.platform === "linux") return linuxProcessStartKey(pid) ?? psProcessStartKey(pid);
71
+ if (process.platform === "win32") return windowsProcessStartKey(pid);
72
+ return psProcessStartKey(pid);
73
+ }
74
+
75
+ const CURRENT_PROCESS_KEY = processStartKey(process.pid);
76
+
77
+ function readStateLockOwner(lockPath: string): StateLockOwner | undefined {
78
+ try {
79
+ const owner = JSON.parse(fs.readFileSync(path.join(lockPath, "owner.json"), "utf-8")) as { pid?: unknown; token?: unknown; createdAt?: unknown; processKey?: unknown };
80
+ if (Number.isSafeInteger(owner.pid) && (owner.pid as number) > 0 && typeof owner.token === "string" && owner.token && Number.isSafeInteger(owner.createdAt)) {
81
+ return {
82
+ pid: owner.pid as number,
83
+ token: owner.token,
84
+ createdAt: owner.createdAt as number,
85
+ ...(typeof owner.processKey === "string" && owner.processKey ? { processKey: owner.processKey } : {}),
86
+ };
87
+ }
88
+ } catch {
89
+ return undefined;
90
+ }
91
+ return undefined;
92
+ }
93
+
94
+ function stateLockIsStale(lockPath: string, now = Date.now()): boolean {
95
+ const owner = readStateLockOwner(lockPath);
96
+ if (owner) {
97
+ if (!isProcessAlive(owner.pid)) return true;
98
+ const currentProcessKey = processStartKey(owner.pid);
99
+ return Boolean(owner.processKey && currentProcessKey && owner.processKey !== currentProcessKey);
100
+ }
101
+ try {
102
+ return now - fs.statSync(lockPath).mtimeMs > STATE_LOCK_STALE_MS;
103
+ } catch (error) {
104
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return false;
105
+ throw error;
106
+ }
107
+ }
108
+
109
+ function removeOwnedStateLock(lockPath: string, owner: StateLockOwner): void {
110
+ const current = readStateLockOwner(lockPath);
111
+ if (current?.token !== owner.token) return;
112
+ fs.rmSync(lockPath, { recursive: true, force: true });
113
+ }
114
+
115
+ function staleDirectoryExists(dirPath: string, now = Date.now()): boolean {
116
+ try {
117
+ return now - fs.statSync(dirPath).mtimeMs > STATE_LOCK_STALE_MS;
118
+ } catch (error) {
119
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return false;
120
+ throw error;
121
+ }
122
+ }
123
+
124
+ function tryMakeDirectory(dirPath: string, mode: number): boolean {
125
+ try {
126
+ fs.mkdirSync(dirPath, { mode });
127
+ return true;
128
+ } catch (error) {
129
+ if ((error as NodeJS.ErrnoException).code === "EEXIST") return false;
130
+ throw error;
131
+ }
132
+ }
133
+
134
+ function waitForStateLock(delayMs: number | undefined, lockPath: string): void {
135
+ if (delayMs === undefined) throw new Error(`Timed out acquiring mission state lock '${lockPath}'.`);
136
+ waitForFileSystemRetry(delayMs);
137
+ }
138
+
139
+ function reclaimStaleStateLock(lockPath: string, reclaimPath: string): boolean {
140
+ if (!stateLockIsStale(lockPath)) return false;
141
+ if (!tryMakeDirectory(reclaimPath, 0o700)) return false;
142
+ try {
143
+ if (!stateLockIsStale(lockPath)) return false;
144
+ fs.rmSync(lockPath, { recursive: true, force: true });
145
+ return true;
146
+ } finally {
147
+ fs.rmSync(reclaimPath, { recursive: true, force: true });
148
+ }
149
+ }
150
+
151
+ function withStateFileLock<T>(filePath: string, operation: () => T): T {
152
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
153
+ const lockPath = `${filePath}.lock`;
154
+ const reclaimPath = `${lockPath}.reclaim`;
155
+ let owner: StateLockOwner | undefined;
156
+ for (let attempt = 0; ; attempt++) {
157
+ if (fs.existsSync(reclaimPath)) {
158
+ if (staleDirectoryExists(reclaimPath)) {
159
+ fs.rmSync(reclaimPath, { recursive: true, force: true });
160
+ continue;
161
+ }
162
+ waitForStateLock(DEFAULT_FILE_SYSTEM_RETRY_DELAYS_MS[attempt], lockPath);
163
+ continue;
164
+ }
165
+ let acquired = false;
166
+ try {
167
+ acquired = tryMakeDirectory(lockPath, 0o700);
168
+ } catch (error) {
169
+ if (isRetryableFileSystemError(error)) {
170
+ waitForStateLock(DEFAULT_FILE_SYSTEM_RETRY_DELAYS_MS[attempt], lockPath);
171
+ continue;
172
+ }
173
+ throw new Error(`Failed to acquire mission state lock '${lockPath}': ${error instanceof Error ? error.message : String(error)}`);
174
+ }
175
+ if (!acquired) {
176
+ if (reclaimStaleStateLock(lockPath, reclaimPath)) continue;
177
+ waitForStateLock(DEFAULT_FILE_SYSTEM_RETRY_DELAYS_MS[attempt], lockPath);
178
+ continue;
179
+ }
180
+ owner = { pid: process.pid, token: randomUUID(), createdAt: Date.now(), ...(CURRENT_PROCESS_KEY ? { processKey: CURRENT_PROCESS_KEY } : {}) };
181
+ try {
182
+ fs.writeFileSync(path.join(lockPath, "owner.json"), JSON.stringify(owner), { encoding: "utf-8", mode: 0o600 });
183
+ } catch (error) {
184
+ fs.rmSync(lockPath, { recursive: true, force: true });
185
+ owner = undefined;
186
+ throw error;
187
+ }
188
+ break;
189
+ }
190
+ try {
191
+ return operation();
192
+ } finally {
193
+ if (owner) removeOwnedStateLock(lockPath, owner);
194
+ }
195
+ }
196
+
197
+ function validateStateKey(value: unknown): string {
198
+ if (typeof value !== "string" || !STATE_KEY_PATTERN.test(value)) {
199
+ throw new Error("state key must be 1-128 characters using letters, numbers, '.', '_' or '-', and start with a letter or number.");
200
+ }
201
+ return value;
202
+ }
203
+
204
+ export function createMissionWorkflowState(location: MissionStoreLocation, missionId: string): MissionWorkflowState {
205
+ const filePath = missionStatePath(location, missionId);
206
+ let loaded = false;
207
+ let values: Record<string, unknown> = Object.create(null) as Record<string, unknown>;
208
+
209
+ const readStateFile = (): Record<string, unknown> => {
210
+ let raw: string;
211
+ try {
212
+ raw = fs.readFileSync(filePath, "utf-8");
213
+ } catch (error) {
214
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return Object.create(null) as Record<string, unknown>;
215
+ throw new Error(`Failed to read mission state '${filePath}': ${error instanceof Error ? error.message : String(error)}`);
216
+ }
217
+ const bytes = Buffer.byteLength(raw);
218
+ if (bytes > MISSION_STATE_MAX_BYTES) throw new Error(`Mission state file '${filePath}' exceeds the 256 KiB limit (${bytes} bytes).`);
219
+ try {
220
+ const parsed: unknown = JSON.parse(raw);
221
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("root must be a JSON object");
222
+ assertWorkflowJsonValue(parsed, "mission state");
223
+ return Object.assign(Object.create(null) as Record<string, unknown>, parsed);
224
+ } catch (error) {
225
+ throw new Error(`Invalid mission state file '${filePath}': ${error instanceof Error ? error.message : String(error)}`);
226
+ }
227
+ };
228
+
229
+ const load = (): Record<string, unknown> => {
230
+ if (loaded) return values;
231
+ values = readStateFile();
232
+ loaded = true;
233
+ return values;
234
+ };
235
+
236
+ return {
237
+ path: filePath,
238
+ get(key) {
239
+ const validKey = validateStateKey(key);
240
+ const current = load();
241
+ return Object.hasOwn(current, validKey) ? current[validKey] : undefined;
242
+ },
243
+ set(key, value) {
244
+ const validKey = validateStateKey(key);
245
+ assertWorkflowJsonValue(value, `state.set('${validKey}') value`);
246
+ withStateFileLock(filePath, () => {
247
+ const next = Object.assign(Object.create(null) as Record<string, unknown>, readStateFile(), { [validKey]: value });
248
+ const bytes = Buffer.byteLength(JSON.stringify(next, null, 2));
249
+ if (bytes > MISSION_STATE_MAX_BYTES) throw new Error(`Mission state exceeds the 256 KiB limit (${bytes} bytes; maximum ${MISSION_STATE_MAX_BYTES} bytes).`);
250
+ writePrivateAtomicJson(filePath, next);
251
+ values = next;
252
+ loaded = true;
253
+ });
254
+ },
255
+ };
256
+ }
@@ -259,9 +259,9 @@ function qualityTierToRoleTier(quality: QualityTier, cost: CostTier): Recommende
259
259
  }
260
260
 
261
261
  function agentsForRoleTier(roleTier: RecommendedRoleTier): BuiltinAgentName[] {
262
- if (roleTier === "cheap") return ["explorer"];
263
- if (roleTier === "medium") return ["architect", "researcher"];
264
- return ["builder", "commentator", "recapper"];
262
+ if (roleTier === "cheap") return ["scout", "delegate"];
263
+ if (roleTier === "medium") return ["researcher", "reviewer"];
264
+ return ["worker", "reviewer", "oracle"];
265
265
  }
266
266
 
267
267
  function classifyModel(input: ModelClassificationInput, context: ClassificationContext): {
@@ -403,12 +403,12 @@ function buildProfileFile(kind: ProfileKind, models: { cheap: string; medium: st
403
403
  return {
404
404
  subagents: {
405
405
  agentOverrides: {
406
- explorer: { model: models.cheap },
407
- architect: { model: models.medium },
406
+ scout: { model: models.cheap },
407
+ delegate: { model: models.cheap },
408
408
  researcher: { model: models.medium },
409
- builder: { model: models.strong },
410
- commentator: { model: models.strong },
411
- recapper: { model: models.strong },
409
+ worker: { model: models.strong },
410
+ reviewer: { model: models.strong },
411
+ oracle: { model: models.strong },
412
412
  },
413
413
  },
414
414
  };