@selesai/code 0.13.15 → 0.13.18

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 (473) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +2 -14
  3. package/dist/bun/cli.d.ts +3 -1
  4. package/dist/bun/cli.js +3 -9
  5. package/dist/bun/{register-bedrock.js → runtime-setup.js} +5 -0
  6. package/dist/bun/sandbox-env-setup.d.ts +1 -0
  7. package/dist/bun/sandbox-env-setup.js +3 -0
  8. package/dist/cli/auth-command.d.ts +23 -0
  9. package/dist/cli/auth-command.js +102 -0
  10. package/dist/cli/config-selector.js +2 -1
  11. package/dist/cli/setup.d.ts +1 -0
  12. package/dist/cli/setup.js +11 -0
  13. package/dist/cli.js +2 -14
  14. package/dist/config.d.ts +3 -2
  15. package/dist/config.js +9 -4
  16. package/dist/core/agent-session-runtime.js +15 -7
  17. package/dist/core/agent-session.d.ts +2 -6
  18. package/dist/core/agent-session.js +15 -4
  19. package/dist/core/compaction/branch-summarization.d.ts +1 -1
  20. package/dist/core/compaction/branch-summarization.js +2 -1
  21. package/dist/core/extensions/loader.js +3 -0
  22. package/dist/core/extensions/types.d.ts +16 -2
  23. package/dist/core/http-dispatcher.js +2 -0
  24. package/dist/core/keybindings.d.ts +5 -0
  25. package/dist/core/keybindings.js +4 -0
  26. package/dist/core/messages.d.ts +1 -1
  27. package/dist/core/model-config.d.ts +15 -0
  28. package/dist/core/model-config.js +3 -0
  29. package/dist/core/model-runtime.d.ts +1 -0
  30. package/dist/core/model-runtime.js +5 -2
  31. package/dist/core/provider-composer.js +8 -2
  32. package/dist/core/session-export.d.ts +3 -0
  33. package/dist/core/session-export.js +31 -0
  34. package/dist/core/session-manager.d.ts +3 -2
  35. package/dist/core/session-manager.js +40 -13
  36. package/dist/core/skills.d.ts +1 -1
  37. package/dist/core/skills.js +4 -2
  38. package/dist/core/system-prompt.js +10 -10
  39. package/dist/core/tools/bash.js +3 -117
  40. package/dist/core/tools/edit.d.ts +1 -12
  41. package/dist/core/tools/edit.js +5 -163
  42. package/dist/core/tools/find.js +4 -55
  43. package/dist/core/tools/grep.js +4 -60
  44. package/dist/core/tools/ls.js +4 -49
  45. package/dist/core/tools/read.d.ts +4 -0
  46. package/dist/core/tools/read.js +10 -122
  47. package/dist/core/tools/renderers/bash.d.ts +11 -0
  48. package/dist/core/tools/renderers/bash.js +129 -0
  49. package/dist/core/tools/renderers/edit.d.ts +22 -0
  50. package/dist/core/tools/renderers/edit.js +166 -0
  51. package/dist/core/tools/renderers/find.d.ts +9 -0
  52. package/dist/core/tools/renderers/find.js +63 -0
  53. package/dist/core/tools/renderers/grep.d.ts +9 -0
  54. package/dist/core/tools/renderers/grep.js +68 -0
  55. package/dist/core/tools/renderers/index.d.ts +27 -0
  56. package/dist/core/tools/renderers/index.js +46 -0
  57. package/dist/core/tools/renderers/ls.d.ts +9 -0
  58. package/dist/core/tools/renderers/ls.js +57 -0
  59. package/dist/core/tools/renderers/read.d.ts +10 -0
  60. package/dist/core/tools/renderers/read.js +128 -0
  61. package/dist/core/tools/renderers/write.d.ts +9 -0
  62. package/dist/core/tools/renderers/write.js +152 -0
  63. package/dist/core/tools/write.js +5 -146
  64. package/dist/extensions/capability-gateway/index.ts +12 -1
  65. package/dist/extensions/capability-gateway/integration.test.ts +23 -0
  66. package/dist/extensions/pi-hermes-memory/CHANGELOG.md +18 -0
  67. package/dist/extensions/pi-hermes-memory/README.md +16 -12
  68. package/dist/extensions/pi-hermes-memory/docs/ROADMAP.md +1 -1
  69. package/dist/extensions/pi-hermes-memory/package-lock.json +587 -62
  70. package/dist/extensions/pi-hermes-memory/package.json +4 -4
  71. package/dist/extensions/pi-hermes-memory/src/config.ts +32 -0
  72. package/dist/extensions/pi-hermes-memory/src/constants.ts +12 -2
  73. package/dist/extensions/pi-hermes-memory/src/handlers/background-review.ts +109 -51
  74. package/dist/extensions/pi-hermes-memory/src/handlers/index-sessions.ts +9 -3
  75. package/dist/extensions/pi-hermes-memory/src/handlers/review-memory-ops.ts +257 -98
  76. package/dist/extensions/pi-hermes-memory/src/handlers/session-backfill.ts +9 -2
  77. package/dist/extensions/pi-hermes-memory/src/handlers/sync-markdown-memories.ts +5 -0
  78. package/dist/extensions/pi-hermes-memory/src/index.ts +22 -2
  79. package/dist/extensions/pi-hermes-memory/src/paths.ts +1 -1
  80. package/dist/extensions/pi-hermes-memory/src/store/db.ts +6 -0
  81. package/dist/extensions/pi-hermes-memory/src/store/fts-query.ts +58 -1
  82. package/dist/extensions/pi-hermes-memory/src/store/memory-store.ts +60 -8
  83. package/dist/extensions/pi-hermes-memory/src/store/session-indexer.ts +169 -7
  84. package/dist/extensions/pi-hermes-memory/src/store/session-search.ts +7 -21
  85. package/dist/extensions/pi-hermes-memory/src/store/sqlite-memory-store.ts +134 -15
  86. package/dist/extensions/pi-hermes-memory/src/tools/memory-search-tool.ts +4 -2
  87. package/dist/extensions/pi-hermes-memory/src/tools/memory-tool.ts +24 -9
  88. package/dist/extensions/pi-hermes-memory/src/types.ts +11 -0
  89. package/dist/extensions/pi-hermes-memory/tests/config.test.ts +42 -0
  90. package/dist/extensions/pi-hermes-memory/tests/handlers/background-review.test.ts +159 -3
  91. package/dist/extensions/pi-hermes-memory/tests/handlers/review-memory-ops.test.ts +452 -0
  92. package/dist/extensions/pi-hermes-memory/tests/handlers/session-backfill.test.ts +39 -0
  93. package/dist/extensions/pi-hermes-memory/tests/integration/corruption-recovery-integration.test.ts +91 -0
  94. package/dist/extensions/pi-hermes-memory/tests/store/db.test.ts +29 -0
  95. package/dist/extensions/pi-hermes-memory/tests/store/fts-query.test.ts +116 -0
  96. package/dist/extensions/pi-hermes-memory/tests/store/memory-store.test.ts +163 -0
  97. package/dist/extensions/pi-hermes-memory/tests/store/session-indexer.test.ts +233 -0
  98. package/dist/extensions/pi-hermes-memory/tests/store/session-search.test.ts +12 -0
  99. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-memory-store.test.ts +175 -0
  100. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-native.test.ts +2 -2
  101. package/dist/extensions/pi-hermes-memory/tests/tools/memory-search-tool.test.ts +22 -0
  102. package/dist/extensions/pi-hermes-memory/tests/tools/memory-tool.test.ts +37 -1
  103. package/dist/extensions/pi-intercom/CHANGELOG.md +13 -0
  104. package/dist/extensions/pi-intercom/README.md +16 -2
  105. package/dist/extensions/pi-intercom/broker/spawn.test.ts +19 -2
  106. package/dist/extensions/pi-intercom/broker/spawn.ts +4 -4
  107. package/dist/extensions/pi-intercom/index.ts +1 -1
  108. package/dist/extensions/pi-intercom/intercom.integration.test.ts +121 -2
  109. package/dist/extensions/pi-intercom/package.json +1 -1
  110. package/dist/extensions/pi-intercom/project-agent.test.ts +1 -1
  111. package/dist/extensions/pi-intercom/project-agent.ts +1 -6
  112. package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +7 -6
  113. package/dist/extensions/pi-rewind-hook/index.test.ts +7 -0
  114. package/dist/extensions/pi-subagents/.github/workflows/test.yml +36 -4
  115. package/dist/extensions/pi-subagents/CHANGELOG.md +120 -0
  116. package/dist/extensions/pi-subagents/README.md +3 -3
  117. package/dist/extensions/pi-subagents/agents/researcher.md +23 -13
  118. package/dist/extensions/pi-subagents/agents/reviewer.md +1 -1
  119. package/dist/extensions/pi-subagents/agents/scout.md +1 -1
  120. package/dist/extensions/pi-subagents/docs/agents.md +32 -16
  121. package/dist/extensions/pi-subagents/docs/configuration.md +41 -15
  122. package/dist/extensions/pi-subagents/docs/extension-api.md +109 -6
  123. package/dist/extensions/pi-subagents/docs/missions.md +2 -0
  124. package/dist/extensions/pi-subagents/docs/models.md +58 -1
  125. package/dist/extensions/pi-subagents/docs/observability.md +50 -12
  126. package/dist/extensions/pi-subagents/docs/tool-reference.md +17 -10
  127. package/dist/extensions/pi-subagents/docs/watchdog.md +1 -1
  128. package/dist/extensions/pi-subagents/docs/workflows.md +26 -9
  129. package/dist/extensions/pi-subagents/package-lock.json +747 -177
  130. package/dist/extensions/pi-subagents/package.json +6 -4
  131. package/dist/extensions/pi-subagents/runner-server-preload.mjs +13 -0
  132. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +2 -1
  133. package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +1 -1
  134. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +21 -4
  135. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +2 -1
  136. package/dist/extensions/pi-subagents/skills/pi-subagents/references/multi-lane-orchestration.md +2 -0
  137. package/dist/extensions/pi-subagents/src/agents/advertised-agent-prompt.ts +63 -0
  138. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +61 -16
  139. package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +2 -0
  140. package/dist/extensions/pi-subagents/src/agents/agents.ts +8 -0
  141. package/dist/extensions/pi-subagents/src/api/capability-ceiling.ts +0 -1
  142. package/dist/extensions/pi-subagents/src/api/{pi-args.ts → child-tool-plan.ts} +1 -1
  143. package/dist/extensions/pi-subagents/src/api/preflight.ts +7 -4
  144. package/dist/extensions/pi-subagents/src/api/shared-types.ts +2 -2
  145. package/dist/extensions/pi-subagents/src/api/workflow-resources.ts +6 -0
  146. package/dist/extensions/pi-subagents/src/extension/config.ts +4 -2
  147. package/dist/extensions/pi-subagents/src/extension/doctor.ts +2 -10
  148. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +9 -11
  149. package/dist/extensions/pi-subagents/src/extension/index.ts +99 -10
  150. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +13 -0
  151. package/dist/extensions/pi-subagents/src/extension/rpc.ts +7 -23
  152. package/dist/extensions/pi-subagents/src/extension/schemas.ts +11 -8
  153. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +25 -7
  154. package/dist/extensions/pi-subagents/src/integrations/pi-web-session-liveness.ts +73 -0
  155. package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +228 -136
  156. package/dist/extensions/pi-subagents/src/intercom/supervisor-ui.ts +244 -0
  157. package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +37 -16
  158. package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +18 -18
  159. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +51 -25
  160. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +46 -3
  161. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +14 -3
  162. package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +9 -0
  163. package/dist/extensions/pi-subagents/src/runs/background/async-status-snapshot.ts +10 -12
  164. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +18 -15
  165. package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +40 -29
  166. package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +8 -0
  167. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +79 -247
  168. package/dist/extensions/pi-subagents/src/runs/background/notify.ts +88 -12
  169. package/dist/extensions/pi-subagents/src/runs/background/owned-process-tree.ts +6 -6
  170. package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +24 -24
  171. package/dist/extensions/pi-subagents/src/runs/background/retained-nested-route-tracker.ts +96 -0
  172. package/dist/extensions/pi-subagents/src/runs/background/run-child-session.ts +642 -0
  173. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +75 -6
  174. package/dist/extensions/pi-subagents/src/runs/background/runner-aliases.ts +163 -0
  175. package/dist/extensions/pi-subagents/src/runs/background/runner-child-launch.ts +86 -0
  176. package/dist/extensions/pi-subagents/src/runs/background/runner-child-sessions.ts +31 -0
  177. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +18 -4
  178. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +3 -1
  179. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +597 -1092
  180. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +3 -0
  181. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +4 -0
  182. package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +20 -17
  183. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +296 -394
  184. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +4 -0
  185. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +3 -1
  186. package/dist/extensions/pi-subagents/src/runs/foreground/prompt-audit.ts +9 -5
  187. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +630 -283
  188. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +8 -5
  189. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +78 -98
  190. package/dist/extensions/pi-subagents/src/runs/shared/abort-recovery.ts +3 -3
  191. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +16 -3
  192. package/dist/extensions/pi-subagents/src/runs/shared/agent-contract.ts +1 -1
  193. package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +47 -47
  194. package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +1 -2
  195. package/dist/extensions/pi-subagents/src/runs/shared/child-hooks.ts +174 -0
  196. package/dist/extensions/pi-subagents/src/runs/shared/child-identity.ts +14 -3
  197. package/dist/extensions/pi-subagents/src/runs/shared/child-launch.ts +319 -0
  198. package/dist/extensions/pi-subagents/src/runs/shared/child-lifecycle.ts +25 -0
  199. package/dist/extensions/pi-subagents/src/runs/shared/child-runtime-config.ts +126 -0
  200. package/dist/extensions/pi-subagents/src/runs/shared/child-session.ts +373 -0
  201. package/dist/extensions/pi-subagents/src/runs/shared/child-tool-plan.ts +530 -0
  202. package/dist/extensions/pi-subagents/src/runs/shared/completion-evidence.ts +2 -2
  203. package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +2 -1
  204. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-preflight.ts +16 -0
  205. package/dist/extensions/pi-subagents/src/runs/shared/host-step-status.ts +11 -11
  206. package/dist/extensions/pi-subagents/src/runs/shared/llm-intent-arbiter.ts +30 -20
  207. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +5 -4
  208. package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +84 -15
  209. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +88 -12
  210. package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +37 -53
  211. package/dist/extensions/pi-subagents/src/runs/shared/nested-path.ts +1 -1
  212. package/dist/extensions/pi-subagents/src/runs/shared/orca-progress-tabs.ts +18 -7
  213. package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +57 -12
  214. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +3 -4
  215. package/dist/extensions/pi-subagents/src/runs/shared/permissions.ts +0 -11
  216. package/dist/extensions/pi-subagents/src/runs/shared/process-signal.ts +4 -1
  217. package/dist/extensions/pi-subagents/src/runs/shared/readonly-drain-observation.ts +42 -0
  218. package/dist/extensions/pi-subagents/src/runs/shared/readonly-model-continuation.ts +69 -0
  219. package/dist/extensions/pi-subagents/src/runs/shared/readonly-session-evidence.ts +307 -0
  220. package/dist/extensions/pi-subagents/src/runs/shared/run-fanout-budget.ts +8 -21
  221. package/dist/extensions/pi-subagents/src/runs/shared/runtime-acknowledged-extensions.ts +3 -30
  222. package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +17 -4
  223. package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +2 -0
  224. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +99 -386
  225. package/dist/extensions/pi-subagents/src/runs/shared/tool-availability.ts +18 -62
  226. package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +0 -14
  227. package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-plan.ts +31 -9
  228. package/dist/extensions/pi-subagents/src/runs/shared/worktree-setup-command.ts +190 -0
  229. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +506 -226
  230. package/dist/extensions/pi-subagents/src/shared/child-session-name.ts +1 -1
  231. package/dist/extensions/pi-subagents/src/shared/jsonl-writer.ts +11 -0
  232. package/dist/extensions/pi-subagents/src/shared/model-response-aliases.ts +13 -0
  233. package/dist/extensions/pi-subagents/src/shared/thinking-ceiling.ts +0 -6
  234. package/dist/extensions/pi-subagents/src/shared/types.ts +145 -89
  235. package/dist/extensions/pi-subagents/src/shared/utils.ts +13 -6
  236. package/dist/extensions/pi-subagents/src/shared/watch-strategy.ts +2 -0
  237. package/dist/extensions/pi-subagents/src/shared/workflow-child-permit.ts +18 -13
  238. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +0 -6
  239. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +1 -1
  240. package/dist/extensions/pi-subagents/src/tui/fleet.ts +11 -6
  241. package/dist/extensions/pi-subagents/src/tui/render.ts +277 -46
  242. package/dist/extensions/pi-subagents/src/watchdog/child-status.ts +0 -1
  243. package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +12 -12
  244. package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +3 -3
  245. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +116 -15
  246. package/dist/extensions/pi-subagents/src/workflows/workflow-checklist.ts +15 -18
  247. package/dist/extensions/pi-subagents/src/workflows/workflow-child-summary.ts +57 -8
  248. package/dist/extensions/pi-subagents/src/workflows/workflow-preflight.ts +19 -19
  249. package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +3 -3
  250. package/dist/extensions/pi-subagents/src/workflows/workflow-resources.ts +97 -22
  251. package/dist/extensions/pi-subagents/src/workflows/workflow-settlement.ts +3 -0
  252. package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +336 -21
  253. package/dist/extensions/pi-subagents/test/integration/async-execution.part-1.test.ts +1181 -0
  254. package/dist/extensions/pi-subagents/test/integration/async-execution.part-2.test.ts +2240 -0
  255. package/dist/extensions/pi-subagents/test/integration/async-execution.part-3.test.ts +2268 -0
  256. package/dist/extensions/pi-subagents/test/integration/async-execution.part-4.test.ts +1512 -0
  257. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +231 -16
  258. package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +4 -18
  259. package/dist/extensions/pi-subagents/test/integration/foreign-workflow-steering.test.ts +95 -0
  260. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +9 -15
  261. package/dist/extensions/pi-subagents/test/integration/in-process-child.test.ts +374 -0
  262. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +20 -10
  263. package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +18 -6
  264. package/dist/extensions/pi-subagents/test/integration/recovered-assistant-error.test.ts +151 -0
  265. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +42 -1
  266. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +150 -25
  267. package/dist/extensions/pi-subagents/test/integration/result-publication.test.ts +354 -0
  268. package/dist/extensions/pi-subagents/test/integration/shared-cwd-terminal-evidence.test.ts +117 -0
  269. package/dist/extensions/pi-subagents/test/integration/single-execution.part-1.test.ts +3678 -0
  270. package/dist/extensions/pi-subagents/test/integration/{single-execution.test.ts → single-execution.part-2.test.ts} +500 -4207
  271. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +1 -2
  272. package/dist/extensions/pi-subagents/test/integration/workflow-result-publication.test.ts +127 -0
  273. package/dist/extensions/pi-subagents/test/integration/workflow-steer-inbox.test.ts +365 -0
  274. package/dist/extensions/pi-subagents/test/smoke/pi085-child.ts +31 -0
  275. package/dist/extensions/pi-subagents/test/smoke/pi085-clean-install.mjs +74 -0
  276. package/dist/extensions/pi-subagents/test/smoke/pi085-extension.ts +16 -0
  277. package/dist/extensions/pi-subagents/test/support/async-execution-fixture.ts +699 -0
  278. package/dist/extensions/pi-subagents/test/support/fake-child-session.ts +418 -0
  279. package/dist/extensions/pi-subagents/test/support/foreign-workflow-steer-host.mjs +13 -0
  280. package/dist/extensions/pi-subagents/test/support/mock-pi.ts +30 -76
  281. package/dist/extensions/pi-subagents/test/support/notify-diagnostics-fixture.ts +84 -0
  282. package/dist/extensions/pi-subagents/test/support/result-publication-capacity-preload.mjs +70 -0
  283. package/dist/extensions/pi-subagents/test/support/runner-child-session-factory.ts +17 -0
  284. package/dist/extensions/pi-subagents/test/support/single-execution-fixture.ts +390 -0
  285. package/dist/extensions/pi-subagents/test/unit/acceptance-compaction.test.ts +120 -0
  286. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +24 -3
  287. package/dist/extensions/pi-subagents/test/unit/advertised-agent-prompt.test.ts +87 -0
  288. package/dist/extensions/pi-subagents/test/unit/advertised-agent-refresh.test.ts +163 -0
  289. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +70 -31
  290. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +78 -3
  291. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +2 -8
  292. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +1 -1
  293. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +73 -66
  294. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +51 -1
  295. package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +49 -1
  296. package/dist/extensions/pi-subagents/test/unit/async-spawn-preload.test.ts +103 -0
  297. package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +3 -3
  298. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +9 -8
  299. package/dist/extensions/pi-subagents/test/unit/capability-ceiling.test.ts +10 -7
  300. package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +48 -6
  301. package/dist/extensions/pi-subagents/test/unit/child-runtime-config.test.ts +90 -0
  302. package/dist/extensions/pi-subagents/test/unit/{pi-args-permission-system.test.ts → child-tool-plan-permission-system.test.ts} +48 -86
  303. package/dist/extensions/pi-subagents/test/unit/child-tool-plan.test.ts +33 -0
  304. package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +18 -18
  305. package/dist/extensions/pi-subagents/test/unit/completion-evidence.test.ts +9 -9
  306. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +8 -7
  307. package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +225 -65
  308. package/dist/extensions/pi-subagents/test/unit/extension-bindings.test.ts +17 -22
  309. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +11 -1
  310. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +47 -3
  311. package/dist/extensions/pi-subagents/test/unit/foreign-workflow-steering.test.ts +74 -0
  312. package/dist/extensions/pi-subagents/test/unit/fork-cache-key.test.ts +23 -29
  313. package/dist/extensions/pi-subagents/test/unit/host-peer-runtime-imports.test.ts +96 -4
  314. package/dist/extensions/pi-subagents/test/unit/host-step-status.test.ts +4 -4
  315. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +116 -55
  316. package/dist/extensions/pi-subagents/test/unit/index-segment.test.ts +58 -1
  317. package/dist/extensions/pi-subagents/test/unit/llm-intent-arbiter.test.ts +104 -3
  318. package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +10 -1
  319. package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +31 -1
  320. package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +102 -51
  321. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +196 -6
  322. package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +181 -38
  323. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +62 -70
  324. package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +58 -53
  325. package/dist/extensions/pi-subagents/test/unit/notify-diagnostics.test.ts +42 -0
  326. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +84 -0
  327. package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +13 -5
  328. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +21 -5
  329. package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +5 -4
  330. package/dist/extensions/pi-subagents/test/unit/permissions.test.ts +2 -6
  331. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +28 -2
  332. package/dist/extensions/pi-subagents/test/unit/pi-web-session-liveness.test.ts +209 -0
  333. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +38 -1
  334. package/dist/extensions/pi-subagents/test/unit/prompt-audit-optional-peers.test.ts +43 -0
  335. package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +24 -2
  336. package/dist/extensions/pi-subagents/test/unit/readonly-drain-observation.test.ts +174 -0
  337. package/dist/extensions/pi-subagents/test/unit/readonly-model-continuation.test.ts +94 -0
  338. package/dist/extensions/pi-subagents/test/unit/readonly-session-evidence.test.ts +1329 -0
  339. package/dist/extensions/pi-subagents/test/unit/recursion-guard.test.ts +29 -80
  340. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +11 -8
  341. package/dist/extensions/pi-subagents/test/unit/result-files.test.ts +2 -2
  342. package/dist/extensions/pi-subagents/test/unit/retained-nested-route-tracker.test.ts +175 -0
  343. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +38 -12
  344. package/dist/extensions/pi-subagents/test/unit/run-fanout-budget.test.ts +2 -5
  345. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +89 -1
  346. package/dist/extensions/pi-subagents/test/unit/runtime-acknowledged-extensions.test.ts +2 -16
  347. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +27 -3
  348. package/dist/extensions/pi-subagents/test/unit/scheduled-supervisor-demand.test.ts +215 -0
  349. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +15 -11
  350. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +237 -1
  351. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +2 -5
  352. package/dist/extensions/pi-subagents/test/unit/streamed-progress-bounds.test.ts +2 -2
  353. package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +14 -1
  354. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +130 -739
  355. package/dist/extensions/pi-subagents/test/unit/supervisor-ask-registration.test.ts +682 -0
  356. package/dist/extensions/pi-subagents/test/unit/supervisor-ui.test.ts +137 -0
  357. package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +1 -11
  358. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +23 -3
  359. package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +8 -1
  360. package/dist/extensions/pi-subagents/test/unit/watchdog-tool-actions.test.ts +19 -1
  361. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +72 -4
  362. package/dist/extensions/pi-subagents/test/unit/workflow-checklist.test.ts +17 -3
  363. package/dist/extensions/pi-subagents/test/unit/workflow-child-summary.test.ts +34 -0
  364. package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +12 -2
  365. package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +46 -6
  366. package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +3 -3
  367. package/dist/extensions/pi-subagents/test/unit/workflow-resources.test.ts +133 -1
  368. package/dist/extensions/pi-subagents/test/unit/workflow-resume-hint.test.ts +53 -2
  369. package/dist/extensions/pi-subagents/test/unit/worktree-cleanup-plan.test.ts +222 -14
  370. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +526 -85
  371. package/dist/extensions/pi-web-agent/src/backends/config.ts +1 -0
  372. package/dist/extensions/pi-web-agent/src/backends/settings-reader.ts +5 -3
  373. package/dist/extensions/pi-web-agent/src/search/tokenin.ts +7 -3
  374. package/dist/extensions/pi-web-agent/src/types.ts +1 -1
  375. package/dist/extensions/pi-zentui/README.md +17 -0
  376. package/dist/extensions/pi-zentui/assets/screenshots/footer-status-hyperlink.png +0 -0
  377. package/dist/extensions/pi-zentui/docs/configuration.md +71 -2
  378. package/dist/extensions/pi-zentui/extensions/zentui/config.ts +11 -0
  379. package/dist/extensions/pi-zentui/extensions/zentui/editor-transfer.ts +14 -0
  380. package/dist/extensions/pi-zentui/extensions/zentui/extension-status.ts +29 -13
  381. package/dist/extensions/pi-zentui/extensions/zentui/footer-layout.ts +5 -4
  382. package/dist/extensions/pi-zentui/extensions/zentui/footer-text.ts +11 -0
  383. package/dist/extensions/pi-zentui/extensions/zentui/footer.ts +11 -10
  384. package/dist/extensions/pi-zentui/extensions/zentui/index.ts +77 -3
  385. package/dist/extensions/pi-zentui/extensions/zentui/presets.ts +77 -0
  386. package/dist/extensions/pi-zentui/extensions/zentui/settings-command.ts +103 -2
  387. package/dist/extensions/pi-zentui/extensions/zentui/working-line-extension-segments.ts +115 -0
  388. package/dist/extensions/pi-zentui/extensions/zentui/working-line.ts +87 -5
  389. package/dist/extensions/pi-zentui/package-lock.json +277 -517
  390. package/dist/extensions/pi-zentui/package.json +7 -4
  391. package/dist/extensions/pi-zentui/test/config-presets.test.ts +238 -0
  392. package/dist/extensions/pi-zentui/test/editor-transfer.test.ts +24 -1
  393. package/dist/extensions/pi-zentui/test/extension-compliance.test.ts +570 -2
  394. package/dist/extensions/pi-zentui/test/extension-status.test.ts +90 -0
  395. package/dist/extensions/pi-zentui/test/footer-hyperlink.test.ts +243 -0
  396. package/dist/extensions/pi-zentui/test/package-contents.mjs +1 -0
  397. package/dist/extensions/pi-zentui/test/presets.test.ts +121 -0
  398. package/dist/extensions/pi-zentui/test/settings-command.test.ts +205 -1
  399. package/dist/extensions/pi-zentui/test/working-line-extension-segments.test.ts +139 -0
  400. package/dist/extensions/pi-zentui/test/working-line-lifecycle.integration.test.ts +237 -3
  401. package/dist/extensions/pi-zentui/test/working-line.test.ts +94 -2
  402. package/dist/index.d.ts +1 -1
  403. package/dist/main.js +4 -1
  404. package/dist/modes/interactive/chat-viewport.d.ts +19 -0
  405. package/dist/modes/interactive/chat-viewport.js +27 -0
  406. package/dist/modes/interactive/components/assistant-message.d.ts +6 -2
  407. package/dist/modes/interactive/components/assistant-message.js +30 -13
  408. package/dist/modes/interactive/components/custom-editor.d.ts +10 -1
  409. package/dist/modes/interactive/components/custom-editor.js +39 -1
  410. package/dist/modes/interactive/components/first-time-setup.js +1 -1
  411. package/dist/modes/interactive/components/index.d.ts +1 -1
  412. package/dist/modes/interactive/components/markdown-transform.d.ts +2 -0
  413. package/dist/modes/interactive/components/markdown-transform.js +18 -0
  414. package/dist/modes/interactive/components/model-selector.js +19 -17
  415. package/dist/modes/interactive/components/scoped-models-selector.js +21 -23
  416. package/dist/modes/interactive/components/settings-selector.d.ts +7 -1
  417. package/dist/modes/interactive/components/settings-selector.js +128 -20
  418. package/dist/modes/interactive/components/settings-submenu.d.ts +71 -0
  419. package/dist/modes/interactive/components/settings-submenu.js +164 -0
  420. package/dist/modes/interactive/components/status-indicator.d.ts +3 -1
  421. package/dist/modes/interactive/components/status-indicator.js +10 -3
  422. package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
  423. package/dist/modes/interactive/components/thinking-selector.js +75 -18
  424. package/dist/modes/interactive/components/tool-execution.d.ts +21 -4
  425. package/dist/modes/interactive/components/tool-execution.js +35 -33
  426. package/dist/modes/interactive/components/trust-selector.js +2 -2
  427. package/dist/modes/interactive/interactive-mode.d.ts +13 -15
  428. package/dist/modes/interactive/interactive-mode.js +144 -80
  429. package/dist/modes/interactive/session-share.d.ts +15 -0
  430. package/dist/modes/interactive/session-share.js +183 -0
  431. package/dist/modes/interactive/theme/dark.json +2 -1
  432. package/dist/modes/interactive/theme/light.json +2 -1
  433. package/dist/modes/interactive/theme/theme-controller.d.ts +1 -0
  434. package/dist/modes/interactive/theme/theme-controller.js +5 -0
  435. package/dist/modes/interactive/theme/theme-json.d.ts +83 -0
  436. package/dist/modes/interactive/theme/theme-json.js +129 -0
  437. package/dist/modes/interactive/theme/theme-schema.json +9 -1
  438. package/dist/modes/interactive/theme/theme.d.ts +14 -5
  439. package/dist/modes/interactive/theme/theme.js +18 -119
  440. package/dist/modes/interactive/tui-renderer.d.ts +20 -0
  441. package/dist/modes/interactive/tui-renderer.js +65 -0
  442. package/dist/utils/exif-orientation.js +2 -3
  443. package/dist/utils/management-http.d.ts +24 -0
  444. package/dist/utils/management-http.js +53 -0
  445. package/dist/utils/text.d.ts +7 -0
  446. package/dist/utils/text.js +8 -0
  447. package/dist/utils/tools-manager.d.ts +1 -0
  448. package/dist/utils/tools-manager.js +43 -21
  449. package/docs/docs.json +0 -4
  450. package/package.json +4 -4
  451. package/dist/extensions/pi-subagents/src/runs/shared/child-protocol.ts +0 -415
  452. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +0 -1059
  453. package/dist/extensions/pi-subagents/src/runs/shared/subagent-startup-retry.ts +0 -116
  454. package/dist/extensions/pi-subagents/src/shared/post-exit-stdio-guard.ts +0 -85
  455. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +0 -224
  456. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +0 -6986
  457. package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +0 -447
  458. package/dist/extensions/pi-subagents/test/support/real-session-child-cli.mjs +0 -185
  459. package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +0 -311
  460. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-pi-args.test.ts +0 -84
  461. package/dist/extensions/pi-subagents/test/unit/child-protocol.test.ts +0 -202
  462. package/dist/extensions/pi-subagents/test/unit/close-grace-timer.test.ts +0 -101
  463. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +0 -2347
  464. package/dist/extensions/pi-subagents/test/unit/subagent-startup-retry.test.ts +0 -104
  465. package/dist/extensions/pi-subagents/test/unit/windows-hide-spawn.test.ts +0 -49
  466. package/dist/skills/imagegen-frontend-mobile/SKILL.md +0 -1465
  467. package/dist/skills/imagegen-frontend-web/SKILL.md +0 -987
  468. package/dist/skills/implanger/SKILL.md +0 -70
  469. package/dist/skills/output/SKILL.md +0 -49
  470. package/dist/skills/planger/SKILL.md +0 -167
  471. package/dist/skills/workflow/SKILL.md +0 -95
  472. package/docs/workflows.md +0 -18
  473. /package/dist/bun/{register-bedrock.d.ts → runtime-setup.d.ts} +0 -0
@@ -0,0 +1,151 @@
1
+ import assert from "node:assert/strict";
2
+ import { randomUUID } from "node:crypto";
3
+ import * as path from "node:path";
4
+ import { describe, it } from "node:test";
5
+ import { makeAgent } from "../support/helpers.ts";
6
+ import type { MockPiResponse } from "../support/mock-pi.ts";
7
+ import { runSync } from "../../src/runs/foreground/execution.ts";
8
+ import { createStructuredOutputRuntime } from "../../src/runs/shared/structured-output.ts";
9
+ import type { JsonSchemaObject } from "../../src/shared/types.ts";
10
+ import {
11
+ available,
12
+ executeAsyncSingle,
13
+ installAsyncExecutionHooks,
14
+ isAsyncAvailable,
15
+ mockPi,
16
+ readAsyncPayload,
17
+ tempDir,
18
+ } from "../support/async-execution-fixture.ts";
19
+
20
+ const providerError = "provider transport failed";
21
+ const structuredValue = { verdict: "ready" };
22
+ const structuredSchema: JsonSchemaObject = {
23
+ type: "object",
24
+ properties: { verdict: { const: "ready" } },
25
+ required: ["verdict"],
26
+ additionalProperties: false,
27
+ };
28
+ const usage = { input: 1, output: 1, cacheRead: 0, cacheWrite: 0, cost: { total: 0 } };
29
+
30
+ type Host = "background" | "foreground";
31
+
32
+ function assistantMessage(stopReason: string, content: unknown[] = [], errorMessage?: string) {
33
+ const message = {
34
+ role: "assistant",
35
+ content,
36
+ model: "mock/test-model",
37
+ stopReason,
38
+ usage,
39
+ };
40
+ if (!errorMessage) return { type: "message_end", message };
41
+ return { type: "message_end", message: { ...message, errorMessage } };
42
+ }
43
+
44
+ function toolCall(name = "read") {
45
+ return { type: "toolCall", id: `${name}-call`, name, arguments: name === "structured_output" ? { value: structuredValue } : {} };
46
+ }
47
+
48
+ function failedAssistantRequest() {
49
+ return assistantMessage("error", [], providerError);
50
+ }
51
+
52
+ interface FixtureResult {
53
+ success: boolean;
54
+ error?: string;
55
+ structuredOutput?: unknown;
56
+ }
57
+
58
+ async function runFixture(host: Host, response: MockPiResponse, withStructuredOutput = false): Promise<FixtureResult> {
59
+ mockPi.onCall(response);
60
+ const agent = makeAgent("recovery-fixture", { completionGuard: false });
61
+ const runId = `recovered-assistant-error-${host}-${randomUUID()}`;
62
+
63
+ if (host === "foreground") {
64
+ const structuredOutput = withStructuredOutput ? createStructuredOutputRuntime(structuredSchema, tempDir) : undefined;
65
+ const options = { runId, acceptance: false as const, waitToolEnabled: false };
66
+ const result = structuredOutput
67
+ ? await runSync(tempDir, [agent], agent.name, "Exercise the scripted child lifecycle", { ...options, structuredOutput })
68
+ : await runSync(tempDir, [agent], agent.name, "Exercise the scripted child lifecycle", options);
69
+ assert.equal(mockPi.callCount(), 1, "the fixture must not launch a fallback child");
70
+ return { success: result.exitCode === 0, error: result.error, structuredOutput: result.structuredOutput };
71
+ }
72
+
73
+ const params = {
74
+ agent: agent.name,
75
+ task: "Exercise the scripted child lifecycle",
76
+ agentConfig: agent,
77
+ ctx: { pi: { events: { emit() {} } }, cwd: tempDir, currentSessionId: "recovered-assistant-error-session" },
78
+ artifactConfig: { enabled: false, includeInput: false, includeOutput: false, includeJsonl: false, includeMetadata: false, cleanupDays: 7 },
79
+ shareEnabled: false,
80
+ sessionRoot: path.join(tempDir, "sessions"),
81
+ maxSubagentDepth: 2,
82
+ waitToolEnabled: false,
83
+ acceptance: false as const,
84
+ };
85
+ const launch = withStructuredOutput
86
+ ? executeAsyncSingle(runId, { ...params, structuredOutputSchema: structuredSchema })
87
+ : executeAsyncSingle(runId, params);
88
+ assert.equal(launch.isError, undefined, launch.content[0]?.text ?? "background launch failed");
89
+ const payload = await readAsyncPayload(runId);
90
+ assert.equal(mockPi.callCount(), 1, "the fixture must not launch a fallback child");
91
+ return {
92
+ success: payload.success,
93
+ error: payload.results[0]?.error,
94
+ structuredOutput: payload.results[0]?.structuredOutput,
95
+ };
96
+ }
97
+
98
+ // These cases use only the installed scripted ChildSessionFactory. They do not
99
+ // load a provider, credential, ambient extension, or real child agent.
100
+ describe("recovered assistant errors", { skip: !available ? "pi packages not available" : undefined }, () => {
101
+ installAsyncExecutionHooks();
102
+
103
+ for (const host of ["background", "foreground"] as const) {
104
+ it(`${host}: recovered request can terminate with structured_output`, { skip: host === "background" && !isAsyncAvailable() ? "jiti not available" : undefined }, async () => {
105
+ const result = await runFixture(host, {
106
+ jsonl: [
107
+ failedAssistantRequest(),
108
+ { type: "auto_retry_start", attempt: 1, maxAttempts: 3, delayMs: 0, errorMessage: providerError },
109
+ assistantMessage("toolUse", [toolCall("structured_output")]),
110
+ { type: "auto_retry_end", success: true, attempt: 1 },
111
+ ],
112
+ structuredOutput: structuredValue,
113
+ }, true);
114
+
115
+ assert.equal(result.success, true, result.error);
116
+ assert.equal(result.error, undefined);
117
+ assert.deepEqual(result.structuredOutput, structuredValue);
118
+ });
119
+
120
+ it(`${host}: retry success and toolUse without a call do not clear the error`, { skip: host === "background" && !isAsyncAvailable() ? "jiti not available" : undefined }, async () => {
121
+ const result = await runFixture(host, {
122
+ jsonl: [
123
+ failedAssistantRequest(),
124
+ { type: "auto_retry_end", success: true, attempt: 1 },
125
+ assistantMessage("toolUse"),
126
+ ],
127
+ });
128
+
129
+ assert.equal(result.success, false);
130
+ assert.match(result.error ?? "", new RegExp(providerError));
131
+ });
132
+
133
+ it(`${host}: a tool call with a non-toolUse stop does not clear the error`, { skip: host === "background" && !isAsyncAvailable() ? "jiti not available" : undefined }, async () => {
134
+ const result = await runFixture(host, {
135
+ jsonl: [failedAssistantRequest(), assistantMessage("length", [toolCall()])],
136
+ });
137
+
138
+ assert.equal(result.success, false);
139
+ assert.match(result.error ?? "", new RegExp(providerError));
140
+ });
141
+
142
+ it(`${host}: an error-bearing toolUse response replaces rather than clears the error`, { skip: host === "background" && !isAsyncAvailable() ? "jiti not available" : undefined }, async () => {
143
+ const result = await runFixture(host, {
144
+ jsonl: [failedAssistantRequest(), assistantMessage("toolUse", [toolCall()], "later provider failure")],
145
+ });
146
+
147
+ assert.equal(result.success, false);
148
+ assert.match(result.error ?? "", /later provider failure/);
149
+ });
150
+ }
151
+ });
@@ -696,6 +696,47 @@ describe("renderSubagentResult fork indicator", () => {
696
696
  assert.match(expanded, /✓ five · completed/);
697
697
  });
698
698
 
699
+ it("keeps mixed workflow host diagnostics visible once while deduplicating child errors", () => {
700
+ const hostError = "CI command failed: executable not found";
701
+ const childError = "Child review failed";
702
+ for (const childFailed of [false, true]) {
703
+ const result = {
704
+ content: [{ type: "text" as const, text: "workflow failed" }],
705
+ isError: true,
706
+ details: {
707
+ mode: "workflow" as const,
708
+ results: [{
709
+ agent: "reviewer",
710
+ task: "Review changes",
711
+ exitCode: childFailed ? 1 : 0,
712
+ error: childFailed ? childError : undefined,
713
+ finalOutput: childFailed ? "" : "Review complete",
714
+ messages: [],
715
+ usage: emptyUsage,
716
+ }],
717
+ workflow: {
718
+ value: "workflow finished",
719
+ trace: [],
720
+ emits: [],
721
+ console: [],
722
+ receipt: {
723
+ hostSteps: [{
724
+ version: 1, kind: "host-step", monitorKind: "command",
725
+ id: "ci", label: "CI", state: "error", detail: hostError,
726
+ exitCode: 127, updatedAt: 1,
727
+ }],
728
+ },
729
+ },
730
+ },
731
+ };
732
+ for (const expanded of childFailed ? [true] : [false, true]) {
733
+ const text = withTerminalWidth(220, () => renderSubagentResult!(result, { expanded }, theme).render(220).join("\n"));
734
+ assert.equal(text.split(hostError).length - 1, 1, text);
735
+ if (expanded) assert.equal(text.split(childError).length - 1, childFailed ? 1 : 0, text);
736
+ }
737
+ }
738
+ });
739
+
699
740
  it("renders a stale-running interrupted aggregate as paused", () => {
700
741
  const result = {
701
742
  content: [{ type: "text" as const, text: "paused" }],
@@ -1405,4 +1446,4 @@ describe("renderSubagentResult fork indicator", () => {
1405
1446
  }
1406
1447
  });
1407
1448
 
1408
- });
1449
+ });
@@ -91,17 +91,78 @@ function resetWidgetLayout(): void {
91
91
  }
92
92
 
93
93
  describe("subagent async widget rendering", () => {
94
- it("renders compact workflow plan status by default and keeps details expanded", () => {
94
+ it("updates the mounted async widget without changing host insertion order", () => {
95
+ type Widget = { render(width: number): string[]; dispose?(): void };
96
+ const widgets = new Map<string, Widget>();
97
+ let registrations = 0;
98
+ let renderRequests = 0;
99
+ const tui = { requestRender: () => { renderRequests += 1; } };
100
+ const ctx = {
101
+ hasUI: true,
102
+ ui: {
103
+ // Pi 0.85 setExtensionWidget disposes/deletes before inserting.
104
+ setWidget(key: string, factory: ((tui: typeof tui, theme: typeof theme) => Widget) | undefined) {
105
+ widgets.get(key)?.dispose?.();
106
+ widgets.delete(key);
107
+ if (factory) {
108
+ registrations += 1;
109
+ widgets.set(key, factory(tui, theme));
110
+ }
111
+ },
112
+ },
113
+ };
114
+ const job = { asyncId: "same-run", asyncDir: "/tmp/run", status: "running", agents: ["before-update"] };
115
+ const originalNow = Date.now;
116
+ try {
117
+ Date.now = () => 1_000;
118
+ renderWidget(ctx, [job]);
119
+ const mounted = widgets.get("subagent-async")!;
120
+ assert.match(mounted.render(180).join("\n"), /before-update/);
121
+ ctx.ui.setWidget("other-extension", () => ({ render: () => ["other"] }));
122
+ for (const agent of ["after-update", "latest-update"]) {
123
+ renderWidget({ ...ctx }, [{ ...job, agents: [agent] }]);
124
+ assert.deepEqual([...widgets.keys()], ["subagent-async", "other-extension"]);
125
+ assert.equal(widgets.get("subagent-async"), mounted);
126
+ assert.match(mounted.render(180).join("\n"), new RegExp(agent), "same-frame cache must be invalidated");
127
+ }
128
+ assert.equal(registrations, 2, "progress must not re-register either widget");
129
+ assert.equal(renderRequests, 2, "each update requests a repaint without a timer");
130
+
131
+ ctx.ui.setWidget("subagent-async", undefined);
132
+ renderWidget(ctx, [job]);
133
+ assert.notEqual(widgets.get("subagent-async"), mounted, "host disposal allows remounting");
134
+ renderWidget(ctx, []);
135
+ assert.deepEqual([...widgets.keys()], ["other-extension"]);
136
+ renderWidget(ctx, [job]);
137
+ assert.ok(widgets.has("subagent-async"), "cleared widgets can mount again");
138
+ } finally {
139
+ Date.now = originalNow;
140
+ renderWidget(ctx, []);
141
+ }
142
+ });
143
+
144
+ it("renders compact workflow lanes by default and keeps details expanded", () => {
95
145
  const job = {
96
- asyncId: "workflow-preflight",
146
+ asyncId: "a6b9aa6b-workflow",
97
147
  asyncDir: "/tmp/workflow-preflight",
98
148
  status: "running",
99
149
  mode: "workflow",
150
+ description: "Review workflow",
151
+ toolCount: 5,
152
+ startedAt: 100,
153
+ updatedAt: 2_600,
100
154
  preflight: {
101
155
  version: 1,
102
156
  coverage: "partial",
103
- lanes: [{ key: "review", mode: "review", claims: ["src/tui"], expectedOutput: "review.md" }],
157
+ lanes: [
158
+ { key: "write", mode: "mutation", decision: "apply the smallest fix", claims: ["src/tui"], expectedOutput: "fix.md" },
159
+ { key: "review", mode: "review", decision: "check the compact surface", claims: ["src/tui"], expectedOutput: "review.md" },
160
+ ],
104
161
  },
162
+ steps: [
163
+ { index: 0, workflowKey: "review", agent: "reviewer", label: "Review the compact surface", status: "running", toolCount: 2 },
164
+ { index: 1, workflowKey: "write", agent: "worker", label: "Apply the smallest fix", status: "complete", toolCount: 3 },
165
+ ],
105
166
  workflow: {
106
167
  trace: [],
107
168
  emits: [],
@@ -110,20 +171,52 @@ describe("subagent async widget rendering", () => {
110
171
  },
111
172
  };
112
173
  const compact = buildWidgetLines([job], theme, 180).join("\n");
113
- assert.match(compact, /Plan: 1 lane · review/);
114
- assert.match(compact, /Plan note: 1 preflight mismatch · expand for debug\./);
115
- assert.doesNotMatch(compact, /key \| mode \| decision \| claims \| expected output \| independence/);
116
- assert.doesNotMatch(compact, /review \| review \|/);
117
- assert.doesNotMatch(compact, /Preflight advisory/);
174
+ assert.match(compact, /async workflow: Review workflow ─ background/);
175
+ assert.match(compact, /id: a6b9aa6b · 1\/2 done · 1 active · 5 tool uses · 2\.5s/);
176
+ assert.match(compact, /write · worker\/mutation · apply the smallest fix · src\/tui · fix\.md/);
177
+ assert.match(compact, /review · reviewer\/review · active · check the compact surface · src\/tui · review\.md/);
178
+ assert.doesNotMatch(compact, /Plan:|Plan note:|preflight mismatch|Preflight advisory/);
179
+ assert.doesNotMatch(compact, /decision:|claims:|expected:/);
180
+ assert.doesNotMatch(compact, /output:\s|next:/i);
118
181
 
119
182
  const expanded = buildWidgetLines([job], theme, 180, true).join("\n");
120
- assert.match(expanded, /Preflight: v1 · partial · 1 lane/);
121
- assert.match(expanded, /review \| review \|/);
183
+ assert.match(expanded, /Preflight: v1 · partial · 2 lanes/);
184
+ assert.match(expanded, /write \| mutation \| apply the smallest fix \| src\/tui \| fix\.md/);
185
+ assert.match(expanded, /review \| review \| check the compact surface \| src\/tui \| review\.md/);
122
186
  assert.match(expanded, /expected output \| independence/);
123
187
  assert.match(expanded, /Preflight warnings:/);
124
188
  assert.match(expanded, /review\.extra.*without a declared lane/);
125
189
  });
126
190
 
191
+ it("degrades compact workflow rows without preflight metadata", () => {
192
+ const job = {
193
+ asyncId: "workflow-fallback-123",
194
+ asyncDir: "/tmp/workflow-fallback",
195
+ status: "running",
196
+ mode: "workflow",
197
+ steps: [
198
+ { index: 0, workflowKey: "scope", agent: "scout", label: "Scope the request", description: "Inspect the repository", status: "complete", outputName: "scope.md" },
199
+ { index: 1, workflowKey: "implement", agent: "worker", label: "Implement the fix", description: "Change only the renderer", status: "running", outputName: "fix.md" },
200
+ ],
201
+ };
202
+ const compact = buildWidgetLines([job], theme, 180).join("\n");
203
+ assert.match(compact, /async workflow: workflow ─ background/);
204
+ assert.match(compact, /scope · scout · Scope the request/);
205
+ assert.match(compact, /implement · worker · active · Implement the fix/);
206
+ assert.doesNotMatch(compact, /Plan:|next:|output:/i);
207
+
208
+ const narrow = buildWidgetLines([job], theme, 72);
209
+ assert.match(narrow[1] ?? "", /id: workflow · 1\/2 done · 1 active/);
210
+ for (const line of narrow) assert.ok(visibleWidth(line) <= 72, `workflow row exceeds width: ${visibleWidth(line)}`);
211
+ const tightHeader = buildWidgetLines([{ ...job, description: "backlog-wave" }], theme, 40)[0] ?? "";
212
+ assert.match(tightHeader, /async workflow backlog-wave · background/);
213
+ assert.doesNotMatch(tightHeader, /workflow:/);
214
+ const longJob = { ...job, steps: job.steps.map((step, index) => ({ ...step, label: `${step.label} ${"with a deliberately long lane description ".repeat(4)}`, description: index === 1 ? `${step.description} ${"and more detail ".repeat(8)}` : step.description })) };
215
+ const truncated = buildWidgetLines([longJob], theme, 72);
216
+ assert.match(truncated[1] ?? "", /id: workflow · 1\/2 done · 1 active/);
217
+ assert.ok(truncated.some((line) => line.includes("...")), "narrow lane rows should be truncated");
218
+ });
219
+
127
220
  it("projects known workflow metadata into a compact lane row", () => {
128
221
  const job = {
129
222
  asyncId: "lane-run-123456",
@@ -307,15 +400,48 @@ describe("subagent async widget rendering", () => {
307
400
  };
308
401
 
309
402
  const text = buildWidgetLines([job], theme, 180).join("\n");
310
- assert.match(text, /CI checks 1 active/);
311
- assert.match(text, /Review gate 1 blocked/);
312
- assert.doesNotMatch(text, /async subagent .*CI checks/);
403
+ assert.match(text, /async workflow: host-run ─ background/);
404
+ assert.match(text, /id: host-run · 0\/2 done · 1 active · 1 blocked/);
405
+ assert.match(text, /ci-1 · active · CI checks/);
406
+ assert.match(text, /gate-1 · blocked · Review gate/);
407
+ assert.match(text, /bottleneck · gate-1 · blocked/);
408
+ assert.doesNotMatch(text, /Plan:|next:|output:/i);
313
409
 
314
410
  const expanded = buildWidgetLines([job], theme, 180, true).join("\n");
315
411
  assert.match(expanded, /ci: CI checks · running · provider:local-tests · PR #1614/);
316
412
  assert.match(expanded, /gate: Review gate · inconclusive · provider:opaque-provider · reason:stale-head · stale · out:gate.json/);
317
413
  });
318
414
 
415
+ it("chooses the most severe compact workflow bottleneck", () => {
416
+ const text = buildWidgetLines([{
417
+ asyncId: "workflow-bottleneck-severity",
418
+ asyncDir: "/tmp/workflow-bottleneck-severity",
419
+ status: "running",
420
+ mode: "workflow",
421
+ steps: [
422
+ { index: 0, workflowKey: "paused-first", agent: "worker", status: "paused" },
423
+ { index: 1, workflowKey: "failed-later", agent: "reviewer", status: "failed", error: "review failed" },
424
+ ],
425
+ }], theme, 180).join("\n");
426
+ assert.match(text, /paused-first · worker · paused/);
427
+ assert.match(text, /failed-later · reviewer · failed/);
428
+ assert.match(text, /bottleneck · failed-later · failed/);
429
+ assert.doesNotMatch(text, /bottleneck · paused-first/);
430
+ });
431
+
432
+ it("renders a workflow failure detail once in expanded checklist output", () => {
433
+ const detail = "review failed with one canonical diagnostic";
434
+ const text = buildWidgetLines([{
435
+ asyncId: "workflow-error-dedup",
436
+ asyncDir: "/tmp/workflow-error-dedup",
437
+ status: "failed",
438
+ mode: "workflow",
439
+ steps: [{ index: 0, workflowKey: "review", agent: "reviewer", status: "failed", error: detail }],
440
+ }], theme, 180, true).join("\n");
441
+
442
+ assert.equal(text.match(new RegExp(detail, "g"))?.length, 1, text);
443
+ });
444
+
319
445
  it("keeps simple one-off async rows on the existing fallback projection", () => {
320
446
  const job = {
321
447
  asyncId: "simple-run",
@@ -930,7 +1056,7 @@ describe("subagent async widget rendering", () => {
930
1056
  resetWidgetLayout();
931
1057
  });
932
1058
 
933
- it("keeps the active runs.lanes stage in focus before collapsed history", () => {
1059
+ it("renders loaded workflow lanes without normal-running bottleneck noise", () => {
934
1060
  resetWidgetLayout();
935
1061
  withStdoutSize(30, 120, () => {
936
1062
  const stageKeys = ["scope-scout", "red-tests", "label-helpers", "summary-title", "detail-row", "tiers-noise", "validation", "minimality-challenge", "fresh-review"];
@@ -973,17 +1099,16 @@ describe("subagent async widget rendering", () => {
973
1099
  ...(index < 3 ? { lastActivityAt: 100 } : { currentTool: "read", currentToolStartedAt: 190, lastActivityAt: 195 }),
974
1100
  })),
975
1101
  };
976
- const ui = createUiContext();
977
- renderWidget(ui.ctx as never, [job]);
978
- const lines = renderWidgetLines(ui.widgets.at(-1));
1102
+ const lines = buildWidgetLines([job], theme, 220);
979
1103
  const text = lines.join("\n");
980
- assert.match(text, /7\/9 done · 1 active · 1 queued/);
981
- assert.match(text, /minimality-challenge 1 active/);
982
- assert.match(text, /fresh-review 1 queued/);
983
- assert.match(text, /bottleneck · minimality-challenge/);
984
- assert.match(text, /Press configured-expand-key for live detail/);
985
- assert.doesNotMatch(text, /label-helpers/);
986
- assert.doesNotMatch(text, /Step \d+\/9|task:|workspace:|out(?:put)?:/i);
1104
+ assert.match(text, /async workflow: workflow ─ background/);
1105
+ assert.match(text, /id: workflow · 7\/9 done · 1 active · 1 queued/);
1106
+ assert.match(text, /issue-1695\.minimality-challenge · worker · active/);
1107
+ assert.match(text, /issue-1695\.fresh-review · worker · queued/);
1108
+ assert.doesNotMatch(text, /bottleneck ·/);
1109
+ assert.match(text, /Press configured-expand-key for details/);
1110
+ assert.match(text, /label-helpers/);
1111
+ assert.doesNotMatch(text, /Step \d+\/9|task:|workspace:|out(?:put)?:|next:/i);
987
1112
  });
988
1113
  resetWidgetLayout();
989
1114
  });
@@ -2091,4 +2216,4 @@ describe("subagent async widget rendering", () => {
2091
2216
  assert.equal(ui.widgets.length, afterClearCount, "cleared widget should stay quiet");
2092
2217
  assert.equal(ui.widgets.at(-1), undefined);
2093
2218
  });
2094
- });
2219
+ });