@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
@@ -1,9 +1,11 @@
1
1
  import assert from "node:assert/strict";
2
2
  import * as fs from "node:fs";
3
3
  import * as path from "node:path";
4
- import { describe, it } from "node:test";
4
+ import { afterEach, describe, it } from "node:test";
5
5
  import { getProjectArtifactsDir } from "../../src/shared/artifacts.ts";
6
+ import { updateActiveRunIndex } from "../../src/runs/background/active-run-index.ts";
6
7
  import { SubagentFleetComponent } from "../../src/tui/fleet.ts";
8
+ import { createNestedRoute } from "../../src/runs/shared/nested-events.ts";
7
9
  import { createTempDir, removeTempDir, tryImport } from "../support/helpers.ts";
8
10
 
9
11
  interface AsyncJobTrackerModule {
@@ -31,6 +33,20 @@ interface AsyncJobTrackerModule {
31
33
  const trackerMod = await tryImport<AsyncJobTrackerModule>("./src/runs/background/async-job-tracker.ts");
32
34
  const available = !!trackerMod;
33
35
 
36
+ type AsyncJobTracker = ReturnType<AsyncJobTrackerModule["createAsyncJobTracker"]>;
37
+ const activeTrackers = new Set<AsyncJobTracker>();
38
+
39
+ function createTracker(...args: Parameters<AsyncJobTrackerModule["createAsyncJobTracker"]>): AsyncJobTracker {
40
+ const tracker = trackerMod!.createAsyncJobTracker(...args);
41
+ activeTrackers.add(tracker);
42
+ return tracker;
43
+ }
44
+
45
+ afterEach(() => {
46
+ for (const tracker of activeTrackers) tracker.resetJobs();
47
+ activeTrackers.clear();
48
+ });
49
+
34
50
  function createState() {
35
51
  return {
36
52
  baseCwd: "/repo",
@@ -119,14 +135,14 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
119
135
  try {
120
136
  const state = createState();
121
137
  const recorder = createEventRecorder();
122
- const tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot);
138
+ const tracker = createTracker(recorder.pi, state as never, asyncRoot);
123
139
  (state as { lastUiContext: unknown }).lastUiContext = {
124
140
  get hasUI() {
125
141
  throw new Error("This extension ctx is stale after session replacement or reload.");
126
142
  },
127
143
  };
128
144
 
129
- tracker.handleStarted({ id: "run-stale-context", asyncDir: path.join(asyncRoot, "run-stale-context"), agent: "builder" });
145
+ tracker.handleStarted({ id: "run-stale-context", asyncDir: path.join(asyncRoot, "run-stale-context"), agent: "worker" });
130
146
 
131
147
  assert.equal(state.lastUiContext, null);
132
148
  if (state.poller) clearInterval(state.poller);
@@ -141,11 +157,11 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
141
157
  const state = createState();
142
158
  const ui = createUiContext();
143
159
  const recorder = createEventRecorder();
144
- const tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
160
+ const tracker = createTracker(recorder.pi, state as never, asyncRoot, {
145
161
  completionRetentionMs: 5,
146
162
  });
147
163
  tracker.resetJobs(ui.ctx as never);
148
- tracker.handleStarted({ id: "run-1", asyncDir: path.join(asyncRoot, "run-1"), agent: "builder" });
164
+ tracker.handleStarted({ id: "run-1", asyncDir: path.join(asyncRoot, "run-1"), agent: "worker" });
149
165
  tracker.handleComplete({ id: "run-1", success: true });
150
166
 
151
167
  assert.equal(state.asyncJobs.size, 1);
@@ -167,11 +183,11 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
167
183
  const state = createState();
168
184
  const ui = createUiContext();
169
185
  const recorder = createEventRecorder();
170
- const tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
186
+ const tracker = createTracker(recorder.pi, state as never, asyncRoot, {
171
187
  widgetEnabled: false,
172
188
  });
173
189
  tracker.resetJobs(ui.ctx as never);
174
- tracker.handleStarted({ id: "run-hidden", asyncDir: path.join(asyncRoot, "run-hidden"), agent: "builder" });
190
+ tracker.handleStarted({ id: "run-hidden", asyncDir: path.join(asyncRoot, "run-hidden"), agent: "worker" });
175
191
 
176
192
  assert.equal(state.asyncJobs.size, 1, "disabled rendering must not disable lifecycle tracking");
177
193
  assert.ok(ui.widgets.length > 0, "expected widget clear calls");
@@ -205,9 +221,9 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
205
221
  chainStepCount: 3,
206
222
  parallelGroups: [{ start: 1, count: 2, stepIndex: 1 }],
207
223
  steps: [
208
- { agent: "explorer", status: "complete" },
209
- { agent: "commentator", status: "running", currentTool: "read", transcriptPath },
210
- { agent: "builder", status: "running" },
224
+ { agent: "scout", status: "complete" },
225
+ { agent: "reviewer", status: "running", currentTool: "read", transcriptPath },
226
+ { agent: "worker", status: "running" },
211
227
  { agent: "writer", status: "pending" },
212
228
  ],
213
229
  }), "utf-8");
@@ -219,16 +235,17 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
219
235
  to: "needs_attention",
220
236
  ts: 123,
221
237
  runId: "run-restored",
222
- agent: "commentator",
238
+ agent: "reviewer",
223
239
  message: "old notice",
224
240
  },
225
241
  })}\n`, "utf-8");
242
+ updateActiveRunIndex(runDir, "running");
226
243
 
227
244
  const state = createState();
228
245
  state.currentSessionId = "session-restored";
229
246
  const ui = createUiContext();
230
247
  const recorder = createEventRecorder();
231
- const tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
248
+ const tracker = createTracker(recorder.pi, state as never, asyncRoot, {
232
249
  pollIntervalMs: 10,
233
250
  });
234
251
  tracker.resetJobs(ui.ctx as never);
@@ -239,7 +256,7 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
239
256
  assert.equal(job.status, "running");
240
257
  assert.equal(job.sessionId, "session-restored");
241
258
  assert.equal(job.cwd, customCwd);
242
- assert.deepEqual(job.agents, ["commentator", "builder"]);
259
+ assert.deepEqual(job.agents, ["reviewer", "worker"]);
243
260
  assert.deepEqual(job.steps?.map((step: { index?: number }) => step.index), [1, 2]);
244
261
  assert.equal(job.stepsTotal, 2);
245
262
  assert.equal(job.runningSteps, 2);
@@ -269,7 +286,58 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
269
286
  }
270
287
  });
271
288
 
272
- it("restores workflow state and refreshes live workflow progress after reload", async () => {
289
+ it("refreshes restored nested async children from event files before the liveness sweep", async () => {
290
+ const asyncRoot = createTempDir("pi-async-job-restore-nested-events-");
291
+ const nestedRoute = createNestedRoute("run-restored-nested");
292
+ const routeRoot = path.dirname(nestedRoute.eventSink);
293
+ try {
294
+ const runDir = path.join(asyncRoot, "run-restored-nested");
295
+ fs.mkdirSync(runDir, { recursive: true });
296
+ fs.writeFileSync(path.join(runDir, "status.json"), JSON.stringify({
297
+ runId: "run-restored-nested",
298
+ mode: "single",
299
+ state: "running",
300
+ sessionId: "session-restored-nested",
301
+ startedAt: 1000,
302
+ lastUpdate: 2000,
303
+ steps: [{ agent: "worker", status: "running" }],
304
+ }), "utf-8");
305
+ updateActiveRunIndex(runDir, "running");
306
+ const state = createState();
307
+ state.currentSessionId = "session-restored-nested";
308
+ const tracker = createTracker(createEventRecorder().pi, state as never, asyncRoot, { pollIntervalMs: 60_000 });
309
+ tracker.restoreActiveJobs();
310
+ assert.equal(state.asyncJobs.get("run-restored-nested")?.nestedRoute?.eventSink, nestedRoute.eventSink);
311
+
312
+ await new Promise((resolve) => setTimeout(resolve, 150));
313
+ fs.writeFileSync(path.join(nestedRoute.eventSink, "0000000003000-child.json"), JSON.stringify({
314
+ type: "subagent.nested.started",
315
+ ts: 3000,
316
+ rootRunId: nestedRoute.rootRunId,
317
+ parentRunId: "run-restored-nested",
318
+ parentStepIndex: 0,
319
+ capabilityToken: nestedRoute.capabilityToken,
320
+ child: {
321
+ id: "nested-child",
322
+ parentRunId: "run-restored-nested",
323
+ parentStepIndex: 0,
324
+ depth: 1,
325
+ path: [{ runId: "run-restored-nested", stepIndex: 0 }],
326
+ state: "running",
327
+ agent: "nested-worker",
328
+ },
329
+ }), "utf-8");
330
+
331
+ await waitForCondition(() => state.asyncJobs.get("run-restored-nested")?.nestedChildren?.[0]?.id === "nested-child", "restored evented nested child refresh", 1000);
332
+ assert.equal(state.asyncJobs.get("run-restored-nested")?.steps?.[0]?.children?.[0]?.id, "nested-child");
333
+ tracker.resetJobs();
334
+ } finally {
335
+ removeTempDir(asyncRoot);
336
+ removeTempDir(routeRoot);
337
+ }
338
+ });
339
+
340
+ it("refreshes restored workflow status from filesystem events before the liveness sweep", async () => {
273
341
  const asyncRoot = createTempDir("pi-async-job-restore-workflow-");
274
342
  try {
275
343
  const runDir = path.join(asyncRoot, "workflow-run");
@@ -285,9 +353,10 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
285
353
  steps: [{ agent: "scan", label: "scan", status: "running" }],
286
354
  workflow: { trace: [{ operation: "run", key: "scan", state: "started" }], emits: [{ stage: "scan" }], console: [] },
287
355
  }), "utf-8");
356
+ updateActiveRunIndex(runDir, "running");
288
357
  const state = createState();
289
358
  state.currentSessionId = "session-workflow";
290
- const tracker = trackerMod!.createAsyncJobTracker(createEventRecorder().pi, state as never, asyncRoot, { pollIntervalMs: 10 });
359
+ const tracker = createTracker(createEventRecorder().pi, state as never, asyncRoot, { pollIntervalMs: 60_000 });
291
360
  tracker.restoreActiveJobs();
292
361
  assert.deepEqual(state.asyncJobs.get("workflow-run")?.workflow?.emits, [{ stage: "scan" }]);
293
362
 
@@ -301,7 +370,7 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
301
370
  steps: [{ agent: "scan", label: "scan", status: "complete" }, { agent: "review", label: "review", status: "running" }],
302
371
  workflow: { trace: [{ operation: "run", key: "review", state: "started" }], emits: [{ stage: "review" }], console: [] },
303
372
  }), "utf-8");
304
- await waitForCondition(() => JSON.stringify(state.asyncJobs.get("workflow-run")?.workflow?.emits) === JSON.stringify([{ stage: "review" }]), "workflow poll refresh", 1000);
373
+ await waitForCondition(() => JSON.stringify(state.asyncJobs.get("workflow-run")?.workflow?.emits) === JSON.stringify([{ stage: "review" }]), "evented workflow refresh", 1000);
305
374
  assert.equal(state.asyncJobs.get("workflow-run")?.workflow?.trace[0]?.key, "review");
306
375
  tracker.resetJobs();
307
376
  } finally {
@@ -309,6 +378,81 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
309
378
  }
310
379
  });
311
380
 
381
+ it("refreshes newly started runs when status appears after the run directory", async () => {
382
+ const asyncRoot = createTempDir("pi-async-job-late-status-");
383
+ try {
384
+ const runDir = path.join(asyncRoot, "late-status-run");
385
+ fs.mkdirSync(runDir, { recursive: true });
386
+ const state = createState();
387
+ state.currentSessionId = "session-late-status";
388
+ const tracker = createTracker(createEventRecorder().pi, state as never, asyncRoot, { pollIntervalMs: 60_000 });
389
+ tracker.handleStarted({ id: "late-status-run", asyncDir: runDir, sessionId: "session-late-status", agent: "worker" });
390
+
391
+ await new Promise((resolve) => setTimeout(resolve, 150));
392
+ fs.writeFileSync(path.join(runDir, "status.json"), JSON.stringify({
393
+ runId: "late-status-run",
394
+ mode: "single",
395
+ state: "running",
396
+ sessionId: "session-late-status",
397
+ startedAt: 1000,
398
+ lastUpdate: 3000,
399
+ steps: [{ agent: "worker", status: "running", currentTool: "read" }],
400
+ }), "utf-8");
401
+
402
+ await waitForCondition(() => state.asyncJobs.get("late-status-run")?.steps?.[0]?.currentTool === "read", "late status refresh before liveness", 1000);
403
+ tracker.resetJobs();
404
+ } finally {
405
+ removeTempDir(asyncRoot);
406
+ }
407
+ });
408
+
409
+ it("refreshes nested async children from event files before the liveness sweep", async () => {
410
+ const asyncRoot = createTempDir("pi-async-job-nested-events-");
411
+ const nestedRoute = createNestedRoute("run-nested-events");
412
+ const routeRoot = path.dirname(nestedRoute.eventSink);
413
+ try {
414
+ const runDir = path.join(asyncRoot, "run-nested-events");
415
+ fs.mkdirSync(runDir, { recursive: true });
416
+ fs.writeFileSync(path.join(runDir, "status.json"), JSON.stringify({
417
+ runId: "run-nested-events",
418
+ mode: "single",
419
+ state: "running",
420
+ startedAt: 1000,
421
+ lastUpdate: 2000,
422
+ steps: [{ agent: "worker", status: "running" }],
423
+ }), "utf-8");
424
+ const state = createState();
425
+ const tracker = createTracker(createEventRecorder().pi, state as never, asyncRoot, { pollIntervalMs: 60_000 });
426
+ tracker.handleStarted({ id: "run-nested-events", asyncDir: runDir, agent: "worker", nestedRoute });
427
+
428
+ await new Promise((resolve) => setTimeout(resolve, 150));
429
+ fs.writeFileSync(path.join(nestedRoute.eventSink, "0000000003000-child.json"), JSON.stringify({
430
+ type: "subagent.nested.started",
431
+ ts: 3000,
432
+ rootRunId: nestedRoute.rootRunId,
433
+ parentRunId: "run-nested-events",
434
+ parentStepIndex: 0,
435
+ capabilityToken: nestedRoute.capabilityToken,
436
+ child: {
437
+ id: "nested-child",
438
+ parentRunId: "run-nested-events",
439
+ parentStepIndex: 0,
440
+ depth: 1,
441
+ path: [{ runId: "run-nested-events", stepIndex: 0 }],
442
+ state: "running",
443
+ agent: "nested-worker",
444
+ },
445
+ }), "utf-8");
446
+
447
+ await waitForCondition(() => state.asyncJobs.get("run-nested-events")?.nestedChildren?.[0]?.id === "nested-child", "evented nested child refresh", 1000);
448
+ assert.equal(state.asyncJobs.get("run-nested-events")?.steps?.[0]?.children?.[0]?.id, "nested-child");
449
+ tracker.resetJobs();
450
+ } finally {
451
+ removeTempDir(asyncRoot);
452
+ removeTempDir(routeRoot);
453
+ }
454
+ });
455
+
312
456
  it("restores async workflow child ownership after reload", () => {
313
457
  const asyncRoot = createTempDir("pi-async-job-restore-workflow-child-");
314
458
  try {
@@ -322,11 +466,12 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
322
466
  startedAt: 1000,
323
467
  parentWorkflowRunId: "workflow-parent",
324
468
  workflowKey: "review",
325
- steps: [{ agent: "commentator", status: "running" }],
469
+ steps: [{ agent: "reviewer", status: "running" }],
326
470
  }), "utf-8");
471
+ updateActiveRunIndex(runDir, "running");
327
472
  const state = createState();
328
473
  state.currentSessionId = "session-workflow";
329
- const tracker = trackerMod!.createAsyncJobTracker(createEventRecorder().pi, state as never, asyncRoot, { pollIntervalMs: 10 });
474
+ const tracker = createTracker(createEventRecorder().pi, state as never, asyncRoot, { pollIntervalMs: 10 });
330
475
  tracker.restoreActiveJobs();
331
476
  assert.equal(state.asyncJobs.get("workflow-child")?.parentWorkflowRunId, "workflow-parent");
332
477
  assert.equal(state.asyncJobs.get("workflow-child")?.workflowKey, "review");
@@ -349,7 +494,7 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
349
494
  state: "running",
350
495
  sessionId: "session-owner",
351
496
  startedAt: 1000,
352
- steps: [{ agent: "builder", status: "running" }],
497
+ steps: [{ agent: "worker", status: "running" }],
353
498
  }), "utf-8");
354
499
  fs.writeFileSync(path.join(otherDir, "status.json"), JSON.stringify({
355
500
  runId: "run-other",
@@ -357,12 +502,14 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
357
502
  state: "running",
358
503
  sessionId: "session-other",
359
504
  startedAt: 1000,
360
- steps: [{ agent: "builder", status: "running" }],
505
+ steps: [{ agent: "worker", status: "running" }],
361
506
  }), "utf-8");
507
+ updateActiveRunIndex(ownerDir, "running");
508
+ updateActiveRunIndex(otherDir, "running");
362
509
 
363
510
  const state = createState();
364
511
  state.currentSessionId = "session-owner";
365
- const tracker = trackerMod!.createAsyncJobTracker(createEventRecorder().pi, state as never, asyncRoot, {
512
+ const tracker = createTracker(createEventRecorder().pi, state as never, asyncRoot, {
366
513
  pollIntervalMs: 10,
367
514
  });
368
515
  tracker.restoreActiveJobs();
@@ -379,14 +526,14 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
379
526
  try {
380
527
  const state = createState();
381
528
  state.currentSessionId = "session-owner";
382
- const tracker = trackerMod!.createAsyncJobTracker(createEventRecorder().pi, state as never, asyncRoot, {
529
+ const tracker = createTracker(createEventRecorder().pi, state as never, asyncRoot, {
383
530
  completionRetentionMs: 5,
384
531
  pollIntervalMs: 10,
385
532
  });
386
533
 
387
- tracker.handleStarted({ id: "run-sessionless", asyncDir: path.join(asyncRoot, "run-sessionless"), agent: "builder" });
388
- tracker.handleStarted({ id: "run-other", asyncDir: path.join(asyncRoot, "run-other"), agent: "builder", sessionId: "session-other" });
389
- tracker.handleStarted({ id: "run-owner", asyncDir: path.join(asyncRoot, "run-owner"), agent: "builder", sessionId: "session-owner" });
534
+ tracker.handleStarted({ id: "run-sessionless", asyncDir: path.join(asyncRoot, "run-sessionless"), agent: "worker" });
535
+ tracker.handleStarted({ id: "run-other", asyncDir: path.join(asyncRoot, "run-other"), agent: "worker", sessionId: "session-other" });
536
+ tracker.handleStarted({ id: "run-owner", asyncDir: path.join(asyncRoot, "run-owner"), agent: "worker", sessionId: "session-owner" });
390
537
 
391
538
  assert.deepEqual([...state.asyncJobs.keys()], ["run-owner"]);
392
539
 
@@ -408,6 +555,7 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
408
555
  const runDir = path.join(asyncRoot, "run-bad-status");
409
556
  fs.mkdirSync(runDir, { recursive: true });
410
557
  fs.writeFileSync(path.join(runDir, "status.json"), "{bad json", "utf-8");
558
+ updateActiveRunIndex(runDir, "running");
411
559
 
412
560
  const state = createState();
413
561
  state.currentSessionId = "session-bad";
@@ -418,7 +566,7 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
418
566
  errors.push(args);
419
567
  };
420
568
 
421
- const tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
569
+ const tracker = createTracker(recorder.pi, state as never, asyncRoot, {
422
570
  pollIntervalMs: 10,
423
571
  });
424
572
  tracker.resetJobs(ui.ctx as never);
@@ -437,21 +585,21 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
437
585
  try {
438
586
  const state = createState();
439
587
  const recorder = createEventRecorder();
440
- const tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot);
588
+ const tracker = createTracker(recorder.pi, state as never, asyncRoot);
441
589
 
442
590
  tracker.handleStarted({
443
591
  id: "run-parallel-start",
444
592
  asyncDir: path.join(asyncRoot, "run-parallel-start"),
445
593
  cwd: path.join(asyncRoot, "custom-cwd"),
446
- agent: "explorer",
447
- agents: ["explorer", "commentator", "builder", "writer"],
448
- chain: ["[explorer+commentator+builder]", "writer"],
594
+ agent: "scout",
595
+ agents: ["scout", "reviewer", "worker", "writer"],
596
+ chain: ["[scout+reviewer+worker]", "writer"],
449
597
  chainStepCount: 2,
450
598
  parallelGroups: [{ start: 0, count: 3, stepIndex: 0 }],
451
599
  });
452
600
 
453
601
  const job = state.asyncJobs.get("run-parallel-start");
454
- assert.deepEqual(job?.agents, ["explorer", "commentator", "builder"]);
602
+ assert.deepEqual(job?.agents, ["scout", "reviewer", "worker"]);
455
603
  assert.equal(job?.cwd, path.join(asyncRoot, "custom-cwd"));
456
604
  assert.equal(job?.chainStepCount, 2);
457
605
  assert.deepEqual(job?.parallelGroups, [{ start: 0, count: 3, stepIndex: 0 }]);
@@ -477,14 +625,14 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
477
625
  chainStepCount: 3,
478
626
  parallelGroups: [{ start: 1, count: 2, stepIndex: 1 }],
479
627
  steps: [
480
- { agent: "explorer", status: "complete" },
628
+ { agent: "scout", status: "complete" },
481
629
  {
482
- agent: "commentator",
630
+ agent: "reviewer",
483
631
  status: "running",
484
632
  currentTool: "read",
485
633
  currentToolArgs: "src/tui/render.ts",
486
634
  recentTools: [{ tool: "grep", args: "async widget", endMs: Date.now() - 100 }],
487
- recentOutput: ["commentator line"],
635
+ recentOutput: ["reviewer line"],
488
636
  },
489
637
  { agent: "auditor", status: "running" },
490
638
  { agent: "writer", status: "pending" },
@@ -494,56 +642,58 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
494
642
  const state = createState();
495
643
  const ui = createUiContext();
496
644
  const recorder = createEventRecorder();
497
- const tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
645
+ const tracker = createTracker(recorder.pi, state as never, asyncRoot, {
498
646
  pollIntervalMs: 10,
499
647
  });
500
648
  tracker.resetJobs(ui.ctx as never);
501
- tracker.handleStarted({ id: "run-chain", asyncDir: runDir, mode: "chain", agents: ["explorer", "commentator", "auditor", "writer"] });
649
+ tracker.handleStarted({ id: "run-chain", asyncDir: runDir, mode: "chain", agents: ["scout", "reviewer", "auditor", "writer"] });
502
650
 
503
651
  await new Promise((resolve) => setTimeout(resolve, 50));
504
652
 
505
653
  const job = state.asyncJobs.get("run-chain");
506
654
  assert.deepEqual(job?.steps?.map((step: { index?: number }) => step.index), [1, 2]);
507
- assert.deepEqual(job?.agents, ["commentator", "auditor"]);
655
+ assert.deepEqual(job?.agents, ["reviewer", "auditor"]);
508
656
  assert.equal(job?.steps?.[0]?.currentTool, "read");
509
657
  assert.equal(job?.steps?.[0]?.currentToolArgs, "src/tui/render.ts");
510
658
  assert.deepEqual(job?.steps?.[0]?.recentTools?.map((tool: { tool: string; args: string }) => ({ tool: tool.tool, args: tool.args })), [{ tool: "grep", args: "async widget" }]);
511
- assert.deepEqual(job?.steps?.[0]?.recentOutput, ["commentator line"]);
659
+ assert.deepEqual(job?.steps?.[0]?.recentOutput, ["reviewer line"]);
512
660
  } finally {
513
661
  removeTempDir(asyncRoot);
514
662
  }
515
663
  });
516
664
 
517
- it("rerenders changed polled status but not unchanged bookkeeping", async () => {
665
+ it("repaints unchanged running widgets without rebuilding them and stops at terminal status", async () => {
518
666
  const asyncRoot = createTempDir("pi-async-job-tracker-");
667
+ let tracker: ReturnType<AsyncJobTrackerModule["createAsyncJobTracker"]> | undefined;
519
668
  try {
520
669
  const runDir = path.join(asyncRoot, "run-unchanged");
521
670
  fs.mkdirSync(runDir, { recursive: true });
522
- const writeStatus = (lastUpdate: number, toolCount?: number) => fs.writeFileSync(path.join(runDir, "status.json"), JSON.stringify({
671
+ const writeStatus = (lastUpdate: number, toolCount?: number, state = "running") => fs.writeFileSync(path.join(runDir, "status.json"), JSON.stringify({
523
672
  runId: "run-unchanged",
524
673
  mode: "single",
525
- state: "running",
674
+ state,
526
675
  startedAt: 1000,
527
676
  lastUpdate,
528
677
  ...(toolCount !== undefined ? { toolCount } : {}),
529
- steps: [{ agent: "builder", status: "running", startedAt: 1000 }],
678
+ steps: [{ agent: "worker", status: state === "running" ? "running" : "complete", startedAt: 1000 }],
530
679
  }), "utf-8");
531
680
  writeStatus(2000);
532
681
 
533
682
  const state = createState();
534
683
  const ui = createUiContext();
535
684
  const recorder = createEventRecorder();
536
- const tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
685
+ tracker = createTracker(recorder.pi, state as never, asyncRoot, {
537
686
  pollIntervalMs: 10,
538
687
  });
539
688
  tracker.resetJobs(ui.ctx as never);
540
- tracker.handleStarted({ id: "run-unchanged", asyncDir: runDir, agent: "builder" });
689
+ tracker.handleStarted({ id: "run-unchanged", asyncDir: runDir, agent: "worker" });
541
690
 
542
691
  const requestsAfterStart = ui.renderRequests;
543
- await new Promise((resolve) => setTimeout(resolve, 35));
692
+ await waitForCondition(() => state.asyncJobs.get("run-unchanged")?.updatedAt === 2000, "first status load");
544
693
  assert.ok(ui.renderRequests > requestsAfterStart, "first status load should redraw the widget");
545
694
 
546
695
  const requestsAfterStatusLoaded = ui.renderRequests;
696
+ const widgetsAfterStatusLoaded = ui.widgets.length;
547
697
  fs.writeFileSync(path.join(runDir, "events.jsonl"), `${JSON.stringify({
548
698
  type: "subagent.control",
549
699
  channels: ["event"],
@@ -552,18 +702,25 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
552
702
  to: "needs_attention",
553
703
  ts: 123,
554
704
  runId: "run-unchanged",
555
- agent: "builder",
556
- message: "builder needs attention",
705
+ agent: "worker",
706
+ message: "worker needs attention",
557
707
  },
558
708
  })}\n`, "utf-8");
559
- await new Promise((resolve) => setTimeout(resolve, 40));
560
- assert.equal(recorder.events.some((event) => event.channel === "subagent:control-event"), true);
561
- assert.equal(ui.renderRequests, requestsAfterStatusLoaded, "unchanged status and control cursors should not request widget redraws");
709
+ await waitForCondition(() => recorder.events.some((event) => event.channel === "subagent:control-event"), "control event delivery");
710
+ await waitForCondition(() => ui.renderRequests > requestsAfterStatusLoaded, "running widget cadence repaint");
711
+ assert.equal(ui.widgets.length, widgetsAfterStatusLoaded, "unchanged running status must not replace the widget component");
562
712
 
563
713
  writeStatus(3000, 1);
564
- await new Promise((resolve) => setTimeout(resolve, 40));
565
- assert.ok(ui.renderRequests > requestsAfterStatusLoaded, "changed non-terminal status should redraw the widget");
714
+ await waitForCondition(() => state.asyncJobs.get("run-unchanged")?.toolCount === 1, "changed status load");
715
+ assert.ok(ui.widgets.length > widgetsAfterStatusLoaded, "changed status should replace the widget component");
716
+
717
+ writeStatus(4000, 1, "complete");
718
+ await waitForCondition(() => state.asyncJobs.get("run-unchanged")?.status === "complete", "terminal status load");
719
+ const requestsAfterTerminal = ui.renderRequests;
720
+ await new Promise((resolve) => setTimeout(resolve, 35));
721
+ assert.equal(ui.renderRequests, requestsAfterTerminal, "terminal-only jobs must not request cadence repaints");
566
722
  } finally {
723
+ tracker?.resetJobs();
567
724
  removeTempDir(asyncRoot);
568
725
  }
569
726
  });
@@ -579,18 +736,18 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
579
736
  state: "complete",
580
737
  startedAt: Date.now() - 1000,
581
738
  lastUpdate: Date.now(),
582
- steps: [{ agent: "builder", status: "complete" }],
739
+ steps: [{ agent: "worker", status: "complete" }],
583
740
  }), "utf-8");
584
741
 
585
742
  const state = createState();
586
743
  const ui = createUiContext();
587
744
  const recorder = createEventRecorder();
588
- const tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
745
+ const tracker = createTracker(recorder.pi, state as never, asyncRoot, {
589
746
  completionRetentionMs: 5,
590
747
  pollIntervalMs: 10,
591
748
  });
592
749
  tracker.resetJobs(ui.ctx as never);
593
- tracker.handleStarted({ id: "run-2", asyncDir: runDir, agent: "builder" });
750
+ tracker.handleStarted({ id: "run-2", asyncDir: runDir, agent: "worker" });
594
751
 
595
752
  await new Promise((resolve) => setTimeout(resolve, 80));
596
753
 
@@ -602,6 +759,35 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
602
759
  }
603
760
  });
604
761
 
762
+ it("watches run directories created after the start event", async () => {
763
+ const asyncRoot = createTempDir("pi-async-job-late-dir-");
764
+ try {
765
+ const runDir = path.join(asyncRoot, "run-late-dir");
766
+ const state = createState();
767
+ const tracker = createTracker(createEventRecorder().pi, state as never, asyncRoot, {
768
+ completionRetentionMs: 5,
769
+ pollIntervalMs: 60_000,
770
+ });
771
+ tracker.handleStarted({ id: "run-late-dir", asyncDir: runDir, agent: "worker" });
772
+ await waitForCondition(() => state.asyncJobs.get("run-late-dir")?.status === "running", "initial event refresh");
773
+
774
+ fs.mkdirSync(runDir, { recursive: true });
775
+ fs.writeFileSync(path.join(runDir, "status.json"), JSON.stringify({
776
+ runId: "run-late-dir",
777
+ mode: "single",
778
+ state: "complete",
779
+ startedAt: Date.now() - 1000,
780
+ lastUpdate: Date.now(),
781
+ steps: [{ agent: "worker", status: "complete" }],
782
+ }), "utf-8");
783
+
784
+ await waitForCondition(() => !state.asyncJobs.has("run-late-dir"), "evented terminal cleanup");
785
+ tracker.resetJobs();
786
+ } finally {
787
+ removeTempDir(asyncRoot);
788
+ }
789
+ });
790
+
605
791
  it("repairs stale running jobs during polling", async () => {
606
792
  const asyncRoot = createTempDir("pi-async-job-stale-");
607
793
  try {
@@ -615,13 +801,13 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
615
801
  pid: 12345,
616
802
  startedAt: Date.now() - 1000,
617
803
  lastUpdate: Date.now() - 1000,
618
- steps: [{ agent: "builder", status: "running", startedAt: Date.now() - 1000 }],
804
+ steps: [{ agent: "worker", status: "running", startedAt: Date.now() - 1000 }],
619
805
  }), "utf-8");
620
806
 
621
807
  const state = createState();
622
808
  const ui = createUiContext();
623
809
  const recorder = createEventRecorder();
624
- const tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
810
+ const tracker = createTracker(recorder.pi, state as never, asyncRoot, {
625
811
  completionRetentionMs: 5,
626
812
  pollIntervalMs: 10,
627
813
  resultsDir,
@@ -629,7 +815,7 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
629
815
  now: () => Date.now(),
630
816
  });
631
817
  tracker.resetJobs(ui.ctx as never);
632
- tracker.handleStarted({ id: "run-stale", asyncDir: runDir, agent: "builder" });
818
+ tracker.handleStarted({ id: "run-stale", asyncDir: runDir, agent: "worker" });
633
819
 
634
820
  await waitForCondition(() => state.asyncJobs.size === 0, "stale async job cleanup");
635
821
 
@@ -650,7 +836,7 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
650
836
  const state = createState();
651
837
  const ui = createUiContext();
652
838
  const recorder = createEventRecorder();
653
- const tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
839
+ const tracker = createTracker(recorder.pi, state as never, asyncRoot, {
654
840
  completionRetentionMs: 5,
655
841
  pollIntervalMs: 10,
656
842
  resultsDir,
@@ -664,7 +850,7 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
664
850
  pid: 12345,
665
851
  sessionId: "session-current",
666
852
  mode: "parallel",
667
- agents: ["explorer", "commentator", "builder"],
853
+ agents: ["scout", "reviewer", "worker"],
668
854
  chainStepCount: 1,
669
855
  parallelGroups: [{ start: 0, count: 3, stepIndex: 0 }],
670
856
  });
@@ -681,9 +867,9 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
681
867
  assert.equal(status.chainStepCount, 1);
682
868
  assert.deepEqual(status.parallelGroups, [{ start: 0, count: 3, stepIndex: 0 }]);
683
869
  assert.deepEqual(status.steps.map((step: { agent: string; status: string }) => [step.agent, step.status]), [
684
- ["explorer", "failed"],
685
- ["commentator", "failed"],
686
- ["builder", "failed"],
870
+ ["scout", "failed"],
871
+ ["reviewer", "failed"],
872
+ ["worker", "failed"],
687
873
  ]);
688
874
  assert.equal(result.success, false);
689
875
  assert.equal(result.sessionId, "session-current");
@@ -702,12 +888,12 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
702
888
  const state = createState();
703
889
  const ui = createUiContext();
704
890
  const recorder = createEventRecorder();
705
- const tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
891
+ const tracker = createTracker(recorder.pi, state as never, asyncRoot, {
706
892
  completionRetentionMs: 5,
707
893
  pollIntervalMs: 10,
708
894
  });
709
895
  tracker.resetJobs(ui.ctx as never);
710
- tracker.handleStarted({ id: "run-bad-status", asyncDir: runDir, agent: "builder" });
896
+ tracker.handleStarted({ id: "run-bad-status", asyncDir: runDir, agent: "worker" });
711
897
 
712
898
  await new Promise((resolve) => setTimeout(resolve, 80));
713
899
 
@@ -729,11 +915,11 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
729
915
  fs.writeFileSync(path.join(runDir, "status.json"), "{", "utf-8");
730
916
  const state = createState();
731
917
  const recorder = createEventRecorder();
732
- tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
918
+ tracker = createTracker(recorder.pi, state as never, asyncRoot, {
733
919
  completionRetentionMs: 5,
734
920
  pollIntervalMs: 10,
735
921
  });
736
- tracker.handleStarted({ id: "run-bad-status-nested", asyncDir: runDir, agent: "builder" });
922
+ tracker.handleStarted({ id: "run-bad-status-nested", asyncDir: runDir, agent: "worker" });
737
923
  const job = state.asyncJobs.get("run-bad-status-nested");
738
924
  assert.ok(job);
739
925
  job.nestedChildren = [{
@@ -742,7 +928,7 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
742
928
  depth: 1,
743
929
  path: [{ runId: "run-bad-status-nested" }],
744
930
  state: "running",
745
- agent: "nested-builder",
931
+ agent: "nested-worker",
746
932
  }];
747
933
 
748
934
  await new Promise((resolve) => setTimeout(resolve, 80));
@@ -771,19 +957,19 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
771
957
  state: "running",
772
958
  startedAt: Date.now() - 1000,
773
959
  lastUpdate: Date.now(),
774
- steps: [{ agent: "builder", status: "running" }],
960
+ steps: [{ agent: "worker", status: "running" }],
775
961
  }), "utf-8");
776
962
 
777
963
  const state = createState();
778
964
  const recorder = createEventRecorder();
779
- tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
965
+ tracker = createTracker(recorder.pi, state as never, asyncRoot, {
780
966
  completionRetentionMs: 5,
781
967
  pollIntervalMs: 10,
782
968
  });
783
969
  tracker.handleStarted({
784
970
  id: "run-nested-refresh",
785
971
  asyncDir: runDir,
786
- agent: "builder",
972
+ agent: "worker",
787
973
  nestedRoute: {
788
974
  rootRunId: "run-nested-refresh",
789
975
  eventSink: path.join(asyncRoot, "not-contained-events"),
@@ -811,11 +997,11 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
811
997
  fs.mkdirSync(runDir, { recursive: true });
812
998
  const state = createState();
813
999
  const recorder = createEventRecorder();
814
- tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
1000
+ tracker = createTracker(recorder.pi, state as never, asyncRoot, {
815
1001
  completionRetentionMs: 1_000,
816
1002
  pollIntervalMs: 10,
817
1003
  });
818
- tracker.handleStarted({ id: "run-recovered", asyncDir: runDir, agent: "builder" });
1004
+ tracker.handleStarted({ id: "run-recovered", asyncDir: runDir, agent: "worker" });
819
1005
  tracker.handleComplete({ id: "run-recovered", success: true });
820
1006
  assert.equal(state.cleanupTimers.has("run-recovered"), true);
821
1007
 
@@ -825,7 +1011,7 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
825
1011
  state: "running",
826
1012
  startedAt: Date.now() - 1000,
827
1013
  lastUpdate: Date.now(),
828
- steps: [{ agent: "builder", status: "running" }],
1014
+ steps: [{ agent: "worker", status: "running" }],
829
1015
  }), "utf-8");
830
1016
 
831
1017
  const deadline = Date.now() + 200;
@@ -852,7 +1038,7 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
852
1038
  state: "running",
853
1039
  startedAt: Date.now() - 1000,
854
1040
  lastUpdate: Date.now(),
855
- steps: [{ agent: "builder", status: "running" }],
1041
+ steps: [{ agent: "worker", status: "running" }],
856
1042
  }), "utf-8");
857
1043
  const eventPath = path.join(runDir, "events.jsonl");
858
1044
  const partialRecord = JSON.stringify({
@@ -863,18 +1049,18 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
863
1049
  to: "needs_attention",
864
1050
  ts: 123,
865
1051
  runId: "run-partial",
866
- agent: "builder",
867
- message: "builder needs attention",
1052
+ agent: "worker",
1053
+ message: "worker needs attention",
868
1054
  },
869
1055
  });
870
1056
  fs.writeFileSync(eventPath, partialRecord, "utf-8");
871
1057
 
872
1058
  const state = createState();
873
1059
  const recorder = createEventRecorder();
874
- const tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
1060
+ const tracker = createTracker(recorder.pi, state as never, asyncRoot, {
875
1061
  pollIntervalMs: 10,
876
1062
  });
877
- tracker.handleStarted({ id: "run-partial", asyncDir: runDir, agent: "builder" });
1063
+ tracker.handleStarted({ id: "run-partial", asyncDir: runDir, agent: "worker" });
878
1064
 
879
1065
  await new Promise((resolve) => setTimeout(resolve, 30));
880
1066
  assert.equal(recorder.events.length, 0);
@@ -900,7 +1086,7 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
900
1086
  state: "running",
901
1087
  startedAt: Date.now() - 1000,
902
1088
  lastUpdate: Date.now(),
903
- steps: [{ agent: "builder", status: "running" }],
1089
+ steps: [{ agent: "worker", status: "running" }],
904
1090
  }), "utf-8");
905
1091
  const largeDiagnostic = JSON.stringify({
906
1092
  type: "message_update",
@@ -914,8 +1100,8 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
914
1100
  to: "needs_attention",
915
1101
  ts: 123,
916
1102
  runId: "run-chunked-control",
917
- agent: "builder",
918
- message: "builder needs attention",
1103
+ agent: "worker",
1104
+ message: "worker needs attention",
919
1105
  },
920
1106
  });
921
1107
  fs.writeFileSync(path.join(runDir, "events.jsonl"), `${largeDiagnostic}\n${controlEvent}\n`, "utf-8");
@@ -927,10 +1113,10 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
927
1113
 
928
1114
  const state = createState();
929
1115
  const recorder = createEventRecorder();
930
- const tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
1116
+ const tracker = createTracker(recorder.pi, state as never, asyncRoot, {
931
1117
  pollIntervalMs: 10,
932
1118
  });
933
- tracker.handleStarted({ id: "run-chunked-control", asyncDir: runDir, agent: "builder" });
1119
+ tracker.handleStarted({ id: "run-chunked-control", asyncDir: runDir, agent: "worker" });
934
1120
 
935
1121
  await waitForCondition(
936
1122
  () => recorder.events.some((event) => event.channel === "subagent:control-event"),
@@ -960,7 +1146,7 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
960
1146
  state: "running",
961
1147
  startedAt: Date.now() - 1000,
962
1148
  lastUpdate: Date.now(),
963
- steps: [{ agent: "builder", status: "running" }],
1149
+ steps: [{ agent: "worker", status: "running" }],
964
1150
  }), "utf-8");
965
1151
  const largeDiagnostic = JSON.stringify({
966
1152
  type: "message_update",
@@ -974,8 +1160,8 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
974
1160
  to: "needs_attention",
975
1161
  ts: 123,
976
1162
  runId: "run-midline-oversized-control",
977
- agent: "builder",
978
- message: "builder needs attention",
1163
+ agent: "worker",
1164
+ message: "worker needs attention",
979
1165
  },
980
1166
  });
981
1167
  fs.writeFileSync(path.join(runDir, "events.jsonl"), `${largeDiagnostic}\n${controlEvent}\n`, "utf-8");
@@ -985,13 +1171,13 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
985
1171
  asyncId: "run-midline-oversized-control",
986
1172
  asyncDir: runDir,
987
1173
  status: "running",
988
- agents: ["builder"],
1174
+ agents: ["worker"],
989
1175
  startedAt: Date.now() - 1000,
990
1176
  updatedAt: Date.now(),
991
1177
  controlEventCursor: 0,
992
1178
  });
993
1179
  const recorder = createEventRecorder();
994
- const tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
1180
+ const tracker = createTracker(recorder.pi, state as never, asyncRoot, {
995
1181
  pollIntervalMs: 10,
996
1182
  });
997
1183
  tracker.ensurePoller();
@@ -1018,7 +1204,7 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
1018
1204
  state: "running",
1019
1205
  startedAt: Date.now() - 1000,
1020
1206
  lastUpdate: Date.now(),
1021
- steps: [{ agent: "builder", status: "running" }],
1207
+ steps: [{ agent: "worker", status: "running" }],
1022
1208
  }), "utf-8");
1023
1209
  const controlEvent = JSON.stringify({
1024
1210
  type: "subagent.control",
@@ -1028,8 +1214,8 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
1028
1214
  to: "needs_attention",
1029
1215
  ts: 123,
1030
1216
  runId: "run-new-large-control",
1031
- agent: "builder",
1032
- message: "builder needs attention",
1217
+ agent: "worker",
1218
+ message: "worker needs attention",
1033
1219
  },
1034
1220
  });
1035
1221
  const diagnosticLine = JSON.stringify({
@@ -1042,10 +1228,10 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
1042
1228
 
1043
1229
  const state = createState();
1044
1230
  const recorder = createEventRecorder();
1045
- const tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
1231
+ const tracker = createTracker(recorder.pi, state as never, asyncRoot, {
1046
1232
  pollIntervalMs: 10,
1047
1233
  });
1048
- tracker.handleStarted({ id: "run-new-large-control", asyncDir: runDir, agent: "builder" });
1234
+ tracker.handleStarted({ id: "run-new-large-control", asyncDir: runDir, agent: "worker" });
1049
1235
 
1050
1236
  await waitForCondition(
1051
1237
  () => recorder.events.some((event) => event.channel === "subagent:control-event"),
@@ -1071,7 +1257,7 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
1071
1257
  state: "running",
1072
1258
  startedAt: Date.now() - 1000,
1073
1259
  lastUpdate: Date.now(),
1074
- steps: [{ agent: "builder", status: "running" }],
1260
+ steps: [{ agent: "worker", status: "running" }],
1075
1261
  }), "utf-8");
1076
1262
  const diagnosticLine = JSON.stringify({
1077
1263
  type: "message_update",
@@ -1085,8 +1271,8 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
1085
1271
  to: "needs_attention",
1086
1272
  ts: 123,
1087
1273
  runId: "run-large-legacy-control",
1088
- agent: "builder",
1089
- message: "builder needs attention",
1274
+ agent: "worker",
1275
+ message: "worker needs attention",
1090
1276
  },
1091
1277
  });
1092
1278
  const eventsPath = path.join(runDir, "events.jsonl");
@@ -1104,12 +1290,12 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
1104
1290
  asyncId: "run-large-legacy-control",
1105
1291
  asyncDir: runDir,
1106
1292
  status: "running",
1107
- agents: ["builder"],
1293
+ agents: ["worker"],
1108
1294
  startedAt: Date.now() - 1000,
1109
1295
  updatedAt: Date.now(),
1110
1296
  });
1111
1297
  const recorder = createEventRecorder();
1112
- const tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
1298
+ const tracker = createTracker(recorder.pi, state as never, asyncRoot, {
1113
1299
  pollIntervalMs: 10,
1114
1300
  });
1115
1301
  tracker.ensurePoller();
@@ -1144,15 +1330,15 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
1144
1330
  currentTool: "edit",
1145
1331
  currentToolStartedAt: Date.now() - 100,
1146
1332
  currentPath: "src/runs/background/subagent-runner.ts",
1147
- steps: [{ agent: "builder", status: "running" }],
1333
+ steps: [{ agent: "worker", status: "running" }],
1148
1334
  }), "utf-8");
1149
1335
 
1150
1336
  const state = createState();
1151
1337
  const recorder = createEventRecorder();
1152
- const tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
1338
+ const tracker = createTracker(recorder.pi, state as never, asyncRoot, {
1153
1339
  pollIntervalMs: 10,
1154
1340
  });
1155
- tracker.handleStarted({ id: "run-clear-tool", asyncDir: runDir, agent: "builder" });
1341
+ tracker.handleStarted({ id: "run-clear-tool", asyncDir: runDir, agent: "worker" });
1156
1342
 
1157
1343
  await new Promise((resolve) => setTimeout(resolve, 30));
1158
1344
  let job = state.asyncJobs.get("run-clear-tool");
@@ -1165,7 +1351,7 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
1165
1351
  state: "running",
1166
1352
  startedAt: Date.now() - 1000,
1167
1353
  lastUpdate: Date.now(),
1168
- steps: [{ agent: "builder", status: "running" }],
1354
+ steps: [{ agent: "worker", status: "running" }],
1169
1355
  }), "utf-8");
1170
1356
 
1171
1357
  await new Promise((resolve) => setTimeout(resolve, 30));
@@ -1189,7 +1375,7 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
1189
1375
  state: "running",
1190
1376
  startedAt: Date.now() - 1000,
1191
1377
  lastUpdate: Date.now(),
1192
- steps: [{ agent: "builder", status: "running" }],
1378
+ steps: [{ agent: "worker", status: "running" }],
1193
1379
  }), "utf-8");
1194
1380
  fs.writeFileSync(path.join(runDir, "events.jsonl"), `${JSON.stringify({
1195
1381
  type: "subagent.control",
@@ -1199,18 +1385,18 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
1199
1385
  to: "needs_attention",
1200
1386
  ts: 123,
1201
1387
  runId: "run-channels",
1202
- agent: "builder",
1203
- message: "builder needs attention",
1388
+ agent: "worker",
1389
+ message: "worker needs attention",
1204
1390
  },
1205
- intercom: { to: "main", message: "SUBAGENT NEEDS ATTENTION: builder in run run-channels." },
1391
+ intercom: { to: "main", message: "SUBAGENT NEEDS ATTENTION: worker in run run-channels." },
1206
1392
  })}\n`, "utf-8");
1207
1393
 
1208
1394
  const state = createState();
1209
1395
  const recorder = createEventRecorder();
1210
- const tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
1396
+ const tracker = createTracker(recorder.pi, state as never, asyncRoot, {
1211
1397
  pollIntervalMs: 10,
1212
1398
  });
1213
- tracker.handleStarted({ id: "run-channels", asyncDir: runDir, agent: "builder" });
1399
+ tracker.handleStarted({ id: "run-channels", asyncDir: runDir, agent: "worker" });
1214
1400
 
1215
1401
  await new Promise((resolve) => setTimeout(resolve, 30));
1216
1402
  assert.equal(recorder.events.some((event) => event.channel === "subagent:control-event"), false);
@@ -1231,7 +1417,7 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
1231
1417
  state: "running",
1232
1418
  startedAt: Date.now() - 1000,
1233
1419
  lastUpdate: Date.now(),
1234
- steps: [{ agent: "builder", status: "running" }],
1420
+ steps: [{ agent: "worker", status: "running" }],
1235
1421
  }), "utf-8");
1236
1422
  fs.writeFileSync(path.join(runDir, "events.jsonl"), `${JSON.stringify({
1237
1423
  type: "subagent.control",
@@ -1241,18 +1427,18 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
1241
1427
  to: "active_long_running",
1242
1428
  ts: 123,
1243
1429
  runId: "run-active-intercom",
1244
- agent: "builder",
1245
- message: "builder is still active but long-running",
1430
+ agent: "worker",
1431
+ message: "worker is still active but long-running",
1246
1432
  },
1247
1433
  intercom: { to: "main", message: "stale active notice" },
1248
1434
  })}\n`, "utf-8");
1249
1435
 
1250
1436
  const state = createState();
1251
1437
  const recorder = createEventRecorder();
1252
- const tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
1438
+ const tracker = createTracker(recorder.pi, state as never, asyncRoot, {
1253
1439
  pollIntervalMs: 10,
1254
1440
  });
1255
- tracker.handleStarted({ id: "run-active-intercom", asyncDir: runDir, agent: "builder" });
1441
+ tracker.handleStarted({ id: "run-active-intercom", asyncDir: runDir, agent: "worker" });
1256
1442
 
1257
1443
  await new Promise((resolve) => setTimeout(resolve, 30));
1258
1444
  assert.equal(recorder.events.some((event) => event.channel === "subagent:control-event"), true);
@@ -1273,36 +1459,36 @@ describe("async job tracker", { skip: !available ? "pi packages not available" :
1273
1459
  state: "running",
1274
1460
  startedAt: Date.now() - 1000,
1275
1461
  lastUpdate: Date.now(),
1276
- steps: [{ agent: "builder", status: "running" }],
1462
+ steps: [{ agent: "worker", status: "running" }],
1277
1463
  }), "utf-8");
1278
1464
  fs.writeFileSync(path.join(runDir, "events.jsonl"), `${JSON.stringify({
1279
1465
  type: "subagent.control",
1280
1466
  channels: ["event", "intercom"],
1281
- childIntercomTarget: "subagent-builder-run-3-1",
1282
- noticeText: "Subagent needs attention: builder\nNudge: intercom({ action: \"send\", to: \"subagent-builder-run-3-1\", message: \"<message>\" })",
1467
+ childIntercomTarget: "subagent-worker-run-3-1",
1468
+ noticeText: "Subagent needs attention: worker\nNudge: intercom({ action: \"send\", to: \"subagent-worker-run-3-1\", message: \"<message>\" })",
1283
1469
  event: {
1284
1470
  type: "needs_attention",
1285
1471
  to: "needs_attention",
1286
1472
  ts: 123,
1287
1473
  runId: "run-3",
1288
- agent: "builder",
1289
- message: "builder needs attention",
1474
+ agent: "worker",
1475
+ message: "worker needs attention",
1290
1476
  },
1291
- intercom: { to: "main", message: "SUBAGENT NEEDS ATTENTION: builder in run run-3." },
1477
+ intercom: { to: "main", message: "SUBAGENT NEEDS ATTENTION: worker in run run-3." },
1292
1478
  })}\n`, "utf-8");
1293
1479
 
1294
1480
  const state = createState();
1295
1481
  const recorder = createEventRecorder();
1296
- const tracker = trackerMod!.createAsyncJobTracker(recorder.pi, state as never, asyncRoot, {
1482
+ const tracker = createTracker(recorder.pi, state as never, asyncRoot, {
1297
1483
  pollIntervalMs: 10,
1298
1484
  });
1299
- tracker.handleStarted({ id: "run-3", asyncDir: runDir, agent: "builder" });
1485
+ tracker.handleStarted({ id: "run-3", asyncDir: runDir, agent: "worker" });
1300
1486
 
1301
1487
  await new Promise((resolve) => setTimeout(resolve, 40));
1302
1488
 
1303
1489
  const controlEvent = recorder.events.find((event) => event.channel === "subagent:control-event");
1304
1490
  assert.ok(controlEvent);
1305
- assert.match((controlEvent.data as { noticeText?: string }).noticeText ?? "", /subagent-builder-run-3-1/);
1491
+ assert.match((controlEvent.data as { noticeText?: string }).noticeText ?? "", /subagent-worker-run-3-1/);
1306
1492
  assert.equal(recorder.events.some((event) => event.channel === "subagent:control-intercom"), true);
1307
1493
  } finally {
1308
1494
  removeTempDir(asyncRoot);