@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
@@ -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;
@@ -314,11 +396,11 @@ export class MissionNotFoundError extends Error {
314
396
  readonly missionId: string;
315
397
  readonly missionDir: string;
316
398
 
317
- constructor(missionId: string, missionDir: string) {
318
- super(`Mission '${missionId}' was not found in ${missionDir}`);
399
+ constructor(missionId: string, location: MissionStoreLocation) {
400
+ super(`Mission '${missionId}' was not found in mission directory '${location.missionDir}' for project root '${location.projectRoot}'. If it was created in another worktree, run the request from that worktree.`);
319
401
  this.name = "MissionNotFoundError";
320
402
  this.missionId = missionId;
321
- this.missionDir = missionDir;
403
+ this.missionDir = location.missionDir;
322
404
  }
323
405
  }
324
406
 
@@ -328,7 +410,7 @@ export function readMission(location: MissionStoreLocation, missionId: string):
328
410
  try {
329
411
  raw = fs.readFileSync(filePath, "utf-8");
330
412
  } catch (error) {
331
- if ((error as NodeJS.ErrnoException).code === "ENOENT") throw new MissionNotFoundError(missionId, location.missionDir);
413
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") throw new MissionNotFoundError(missionId, location);
332
414
  throw error;
333
415
  }
334
416
  try {
@@ -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,260 @@
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
+ if (owner.processKey) {
99
+ const currentProcessKey = owner.pid === process.pid ? CURRENT_PROCESS_KEY : processStartKey(owner.pid);
100
+ if (currentProcessKey) return owner.processKey !== currentProcessKey;
101
+ if (owner.pid === process.pid) return true;
102
+ }
103
+ return false;
104
+ }
105
+ try {
106
+ return now - fs.statSync(lockPath).mtimeMs > STATE_LOCK_STALE_MS;
107
+ } catch (error) {
108
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return false;
109
+ throw error;
110
+ }
111
+ }
112
+
113
+ function removeOwnedStateLock(lockPath: string, owner: StateLockOwner): void {
114
+ const current = readStateLockOwner(lockPath);
115
+ if (current?.token !== owner.token) return;
116
+ fs.rmSync(lockPath, { recursive: true, force: true });
117
+ }
118
+
119
+ function staleDirectoryExists(dirPath: string, now = Date.now()): boolean {
120
+ try {
121
+ return now - fs.statSync(dirPath).mtimeMs > STATE_LOCK_STALE_MS;
122
+ } catch (error) {
123
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return false;
124
+ throw error;
125
+ }
126
+ }
127
+
128
+ function tryMakeDirectory(dirPath: string, mode: number): boolean {
129
+ try {
130
+ fs.mkdirSync(dirPath, { mode });
131
+ return true;
132
+ } catch (error) {
133
+ if ((error as NodeJS.ErrnoException).code === "EEXIST") return false;
134
+ throw error;
135
+ }
136
+ }
137
+
138
+ function waitForStateLock(delayMs: number | undefined, lockPath: string): void {
139
+ if (delayMs === undefined) throw new Error(`Timed out acquiring mission state lock '${lockPath}'.`);
140
+ waitForFileSystemRetry(delayMs);
141
+ }
142
+
143
+ function reclaimStaleStateLock(lockPath: string, reclaimPath: string): boolean {
144
+ if (!stateLockIsStale(lockPath)) return false;
145
+ if (!tryMakeDirectory(reclaimPath, 0o700)) return false;
146
+ try {
147
+ if (!stateLockIsStale(lockPath)) return false;
148
+ fs.rmSync(lockPath, { recursive: true, force: true });
149
+ return true;
150
+ } finally {
151
+ fs.rmSync(reclaimPath, { recursive: true, force: true });
152
+ }
153
+ }
154
+
155
+ function withStateFileLock<T>(filePath: string, operation: () => T): T {
156
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
157
+ const lockPath = `${filePath}.lock`;
158
+ const reclaimPath = `${lockPath}.reclaim`;
159
+ let owner: StateLockOwner | undefined;
160
+ for (let attempt = 0; ; attempt++) {
161
+ if (fs.existsSync(reclaimPath)) {
162
+ if (staleDirectoryExists(reclaimPath)) {
163
+ fs.rmSync(reclaimPath, { recursive: true, force: true });
164
+ continue;
165
+ }
166
+ waitForStateLock(DEFAULT_FILE_SYSTEM_RETRY_DELAYS_MS[attempt], lockPath);
167
+ continue;
168
+ }
169
+ let acquired = false;
170
+ try {
171
+ acquired = tryMakeDirectory(lockPath, 0o700);
172
+ } catch (error) {
173
+ if (isRetryableFileSystemError(error)) {
174
+ waitForStateLock(DEFAULT_FILE_SYSTEM_RETRY_DELAYS_MS[attempt], lockPath);
175
+ continue;
176
+ }
177
+ throw new Error(`Failed to acquire mission state lock '${lockPath}': ${error instanceof Error ? error.message : String(error)}`);
178
+ }
179
+ if (!acquired) {
180
+ if (reclaimStaleStateLock(lockPath, reclaimPath)) continue;
181
+ waitForStateLock(DEFAULT_FILE_SYSTEM_RETRY_DELAYS_MS[attempt], lockPath);
182
+ continue;
183
+ }
184
+ owner = { pid: process.pid, token: randomUUID(), createdAt: Date.now(), ...(CURRENT_PROCESS_KEY ? { processKey: CURRENT_PROCESS_KEY } : {}) };
185
+ try {
186
+ fs.writeFileSync(path.join(lockPath, "owner.json"), JSON.stringify(owner), { encoding: "utf-8", mode: 0o600 });
187
+ } catch (error) {
188
+ fs.rmSync(lockPath, { recursive: true, force: true });
189
+ owner = undefined;
190
+ throw error;
191
+ }
192
+ break;
193
+ }
194
+ try {
195
+ return operation();
196
+ } finally {
197
+ if (owner) removeOwnedStateLock(lockPath, owner);
198
+ }
199
+ }
200
+
201
+ function validateStateKey(value: unknown): string {
202
+ if (typeof value !== "string" || !STATE_KEY_PATTERN.test(value)) {
203
+ throw new Error("state key must be 1-128 characters using letters, numbers, '.', '_' or '-', and start with a letter or number.");
204
+ }
205
+ return value;
206
+ }
207
+
208
+ export function createMissionWorkflowState(location: MissionStoreLocation, missionId: string): MissionWorkflowState {
209
+ const filePath = missionStatePath(location, missionId);
210
+ let loaded = false;
211
+ let values: Record<string, unknown> = Object.create(null) as Record<string, unknown>;
212
+
213
+ const readStateFile = (): Record<string, unknown> => {
214
+ let raw: string;
215
+ try {
216
+ raw = fs.readFileSync(filePath, "utf-8");
217
+ } catch (error) {
218
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return Object.create(null) as Record<string, unknown>;
219
+ throw new Error(`Failed to read mission state '${filePath}': ${error instanceof Error ? error.message : String(error)}`);
220
+ }
221
+ const bytes = Buffer.byteLength(raw);
222
+ if (bytes > MISSION_STATE_MAX_BYTES) throw new Error(`Mission state file '${filePath}' exceeds the 256 KiB limit (${bytes} bytes).`);
223
+ try {
224
+ const parsed: unknown = JSON.parse(raw);
225
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("root must be a JSON object");
226
+ assertWorkflowJsonValue(parsed, "mission state");
227
+ return Object.assign(Object.create(null) as Record<string, unknown>, parsed);
228
+ } catch (error) {
229
+ throw new Error(`Invalid mission state file '${filePath}': ${error instanceof Error ? error.message : String(error)}`);
230
+ }
231
+ };
232
+
233
+ const load = (): Record<string, unknown> => {
234
+ if (loaded) return values;
235
+ values = readStateFile();
236
+ loaded = true;
237
+ return values;
238
+ };
239
+
240
+ return {
241
+ path: filePath,
242
+ get(key) {
243
+ const validKey = validateStateKey(key);
244
+ const current = load();
245
+ return Object.hasOwn(current, validKey) ? current[validKey] : undefined;
246
+ },
247
+ set(key, value) {
248
+ const validKey = validateStateKey(key);
249
+ assertWorkflowJsonValue(value, `state.set('${validKey}') value`);
250
+ withStateFileLock(filePath, () => {
251
+ const next = Object.assign(Object.create(null) as Record<string, unknown>, readStateFile(), { [validKey]: value });
252
+ const bytes = Buffer.byteLength(JSON.stringify(next, null, 2));
253
+ if (bytes > MISSION_STATE_MAX_BYTES) throw new Error(`Mission state exceeds the 256 KiB limit (${bytes} bytes; maximum ${MISSION_STATE_MAX_BYTES} bytes).`);
254
+ writePrivateAtomicJson(filePath, next);
255
+ values = next;
256
+ loaded = true;
257
+ });
258
+ },
259
+ };
260
+ }