@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
@@ -94,6 +94,10 @@ export function liveDetailHintText(): string {
94
94
  return `Press ${liveDetailKeyText()} for live detail · ${formatShortcutLabel(FLEET_OPEN_SHORTCUT)} Fleet`;
95
95
  }
96
96
 
97
+ function workflowDetailHintText(): string {
98
+ return `Press ${liveDetailKeyText()} for details · ${formatShortcutLabel(FLEET_OPEN_SHORTCUT)} Fleet`;
99
+ }
100
+
97
101
  function foregroundSingleHintText(shortcut?: string): string {
98
102
  if (!shortcut) return liveDetailHintText();
99
103
  const label = formatShortcutLabel(shortcut);
@@ -609,15 +613,8 @@ function widgetLaneDetailLines(job: AsyncJobState, theme: Theme, projection?: Wo
609
613
  return lane ? formatLaneProjectionLines(lane, theme, " ") : [];
610
614
  }
611
615
 
612
- function workflowPreflightLines(job: AsyncJobState, expanded = false): string[] {
616
+ function workflowPreflightLines(job: AsyncJobState): string[] {
613
617
  if (job.mode !== "workflow" || !job.preflight) return [];
614
- if (!expanded) {
615
- const warning = formatWorkflowPreflightWarningSummary(job.workflow?.preflightWarnings, { indent: " ", hint: "expand for debug" });
616
- return [
617
- formatWorkflowPreflightPlanSummary(job.preflight, { indent: " " }),
618
- ...(warning ? [warning] : []),
619
- ];
620
- }
621
618
  return [
622
619
  ...formatWorkflowPreflight(job.preflight, { indent: " " }).split("\n"),
623
620
  ...(job.workflow?.preflightWarnings ? formatWorkflowPreflightWarnings(job.workflow.preflightWarnings, { indent: " " }).split("\n") : []),
@@ -1058,6 +1055,7 @@ export function widgetRenderKey(job: AsyncJobState, expanded = false): string {
1058
1055
  return JSON.stringify({
1059
1056
  asyncDir: job.asyncDir,
1060
1057
  status: job.status,
1058
+ description: job.mode === "workflow" ? job.description : undefined,
1061
1059
  activityState: job.activityState,
1062
1060
  lastActivityAt: job.lastActivityAt,
1063
1061
  currentTool: job.currentTool,
@@ -1075,8 +1073,8 @@ export function widgetRenderKey(job: AsyncJobState, expanded = false): string {
1075
1073
  currentNodeId: job.workflowGraph.currentNodeId,
1076
1074
  stages: projection.stages.map((node) => [node.id, node.status, node.agent, node.phase, node.label, node.flatIndex, node.outputName, node.structured, node.error]),
1077
1075
  } : undefined,
1078
- preflight: expanded ? job.preflight : job.preflight ? formatWorkflowPreflightPlanSummary(job.preflight) : undefined,
1079
- preflightWarnings: expanded ? job.workflow?.preflightWarnings : job.workflow?.preflightWarnings?.length || undefined,
1076
+ preflight: expanded ? job.preflight : job.preflight?.lanes.map((lane) => [lane.key, lane.mode, lane.decision, lane.claims, lane.expectedOutput]),
1077
+ preflightWarnings: expanded ? job.workflow?.preflightWarnings : undefined,
1080
1078
  checklist: projection.checklist ? {
1081
1079
  total: projection.checklist.total,
1082
1080
  done: projection.checklist.done,
@@ -1084,7 +1082,7 @@ export function widgetRenderKey(job: AsyncJobState, expanded = false): string {
1084
1082
  queued: projection.checklist.queued,
1085
1083
  blocked: projection.checklist.blocked,
1086
1084
  failed: projection.checklist.failed,
1087
- phases: projection.checklist.phases.map((phase) => [phase.key, phase.state, phase.done, phase.total, phase.running, phase.queued, phase.blocked, phase.failed, phase.paused, phase.stopped, phase.items.map((item) => [item.key, item.state, item.currentTool, item.currentPath, item.durationMs, item.toolCount, item.error])]),
1085
+ phases: projection.checklist.phases.map((phase) => [phase.key, phase.state, phase.done, phase.total, phase.running, phase.queued, phase.blocked, phase.failed, phase.paused, phase.stopped, phase.items.map((item) => [item.key, item.label, item.agent, item.state, item.preflight?.key, item.preflight?.mode, item.preflight?.decision, item.preflight?.claims, item.preflight?.expectedOutput, item.currentTool, item.currentPath, item.durationMs, item.toolCount, item.error])]),
1088
1086
  } : undefined,
1089
1087
  steps: job.steps?.map((step, index) => widgetStepRenderKey(step, index, expanded)),
1090
1088
  nestedChildren: nestedRenderKey(job.nestedChildren, expanded),
@@ -1286,7 +1284,7 @@ function workflowChecklistItemPriority(state: WorkflowChecklistState): number {
1286
1284
  return 6;
1287
1285
  }
1288
1286
 
1289
- function workflowChecklistItemLine(item: WorkflowChecklistItem, theme: Theme, indent: string, frame?: number): string {
1287
+ function workflowChecklistItemLine(item: WorkflowChecklistItem, theme: Theme, indent: string, frame: number | undefined, includeError: boolean): string {
1290
1288
  const identity = [item.label, item.agent && item.agent !== item.label ? item.agent : undefined].filter(Boolean).join(" · ");
1291
1289
  const context = contextModeBadge(theme, item.context);
1292
1290
  const state = item.state === "complete" ? "" : ` ${theme.fg("dim", `· ${workflowChecklistStateLabel(item.state)}`)}`;
@@ -1296,15 +1294,26 @@ function workflowChecklistItemLine(item: WorkflowChecklistItem, theme: Theme, in
1296
1294
  !item.currentTool && item.durationMs !== undefined ? formatDuration(item.durationMs) : undefined,
1297
1295
  item.toolCount !== undefined ? `${item.toolCount} tools` : undefined,
1298
1296
  item.outputName ? `out:${item.outputName}` : undefined,
1299
- item.error ? `error:${oneLine(item.error)}` : undefined,
1297
+ includeError && item.error ? `error:${oneLine(item.error)}` : undefined,
1300
1298
  ].filter(Boolean).join(" · ");
1301
1299
  return `${indent}${workflowChecklistGlyph(item, theme, frame)} ${theme.bold(identity || item.key)}${context}${state}${details ? ` ${theme.fg("dim", `· ${details}`)}` : ""}`;
1302
1300
  }
1303
1301
 
1304
1302
  const COLLAPSED_WORKFLOW_PHASE_LIMIT = 4;
1305
1303
 
1306
- function workflowChecklistWidgetLines(checklist: WorkflowChecklistProjection | undefined, theme: Theme, indent: string, expanded: boolean, frame?: number, includeSummary = true, limitPhases = !expanded, includeBottleneckOutput = expanded): string[] {
1304
+ interface WorkflowChecklistWidgetOptions {
1305
+ includeSummary?: boolean;
1306
+ limitPhases?: boolean;
1307
+ includeBottleneckOutput?: boolean;
1308
+ includeItemErrors?: boolean;
1309
+ }
1310
+
1311
+ function workflowChecklistWidgetLines(checklist: WorkflowChecklistProjection | undefined, theme: Theme, indent: string, expanded: boolean, frame?: number, options: WorkflowChecklistWidgetOptions = {}): string[] {
1307
1312
  if (!checklist?.total) return [];
1313
+ const includeSummary = options.includeSummary ?? true;
1314
+ const limitPhases = options.limitPhases ?? !expanded;
1315
+ const includeBottleneckOutput = options.includeBottleneckOutput ?? expanded;
1316
+ const includeItemErrors = options.includeItemErrors ?? true;
1308
1317
  const lines = includeSummary ? [`${indent}${theme.fg("dim", `Checklist ${formatWorkflowChecklistSummary(checklist)}`)}`] : [];
1309
1318
  const phases = !limitPhases || checklist.phases.length <= COLLAPSED_WORKFLOW_PHASE_LIMIT
1310
1319
  ? checklist.phases
@@ -1328,11 +1337,11 @@ function workflowChecklistWidgetLines(checklist: WorkflowChecklistProjection | u
1328
1337
  lines.push(`${indent}${glyph} ${theme.bold(formatWorkflowChecklistPhase(phase))}`);
1329
1338
  if (expanded) {
1330
1339
  for (const item of [...phase.items].sort((left, right) => workflowChecklistItemPriority(left.state) - workflowChecklistItemPriority(right.state))) {
1331
- lines.push(workflowChecklistItemLine(item, theme, `${indent} `, frame));
1340
+ lines.push(workflowChecklistItemLine(item, theme, `${indent} `, frame, includeItemErrors || item.kind === "host"));
1332
1341
  }
1333
1342
  }
1334
1343
  }
1335
- const bottleneck = formatWorkflowChecklistBottleneck(checklist.bottleneck, { includeOutput: includeBottleneckOutput });
1344
+ const bottleneck = formatWorkflowChecklistBottleneck(checklist.bottleneck, { includeOutput: includeBottleneckOutput, includeError: !expanded });
1336
1345
  if (bottleneck) {
1337
1346
  const tone = checklist.bottleneck?.state === "blocked" || checklist.bottleneck?.state === "failed" ? "error" : checklist.bottleneck?.state === "running" ? "accent" : "warning";
1338
1347
  lines.push(`${indent}${theme.fg(tone, `bottleneck · ${bottleneck}`)}`);
@@ -1340,6 +1349,208 @@ function workflowChecklistWidgetLines(checklist: WorkflowChecklistProjection | u
1340
1349
  return lines;
1341
1350
  }
1342
1351
 
1352
+ interface CompactWorkflowLaneRow {
1353
+ key: string;
1354
+ state: WorkflowChecklistState;
1355
+ agent?: string;
1356
+ mode?: string;
1357
+ decision?: string;
1358
+ claims?: string;
1359
+ expectedOutput?: string;
1360
+ label?: string;
1361
+ toolUses?: number;
1362
+ durationMs?: number;
1363
+ }
1364
+
1365
+ interface CompactWorkflowLaneCounts {
1366
+ total: number;
1367
+ done: number;
1368
+ active: number;
1369
+ queued: number;
1370
+ blocked: number;
1371
+ failed: number;
1372
+ paused: number;
1373
+ stopped: number;
1374
+ }
1375
+
1376
+ function compactWorkflowLaneState(items: readonly WorkflowChecklistItem[]): WorkflowChecklistState {
1377
+ let state: WorkflowChecklistState | undefined;
1378
+ for (const item of items) {
1379
+ if (state === undefined || workflowChecklistItemPriority(item.state) < workflowChecklistItemPriority(state)) state = item.state;
1380
+ }
1381
+ return state ?? "queued";
1382
+ }
1383
+
1384
+ function compactWorkflowLaneOwner(items: readonly WorkflowChecklistItem[]): string | undefined {
1385
+ const owners = [...new Set(items.map((item) => item.agent ?? item.role).filter((value): value is string => Boolean(value?.trim())))];
1386
+ if (owners.length === 0) return undefined;
1387
+ return boundedLaneValue(owners.length > 2 ? `${owners.slice(0, 2).join(", ")} +${owners.length - 2}` : owners.join(", "), 32);
1388
+ }
1389
+
1390
+ function compactWorkflowLaneLabel(items: readonly WorkflowChecklistItem[], key: string): string | undefined {
1391
+ const labels = [...new Set(items.map((item) => item.label).filter((value): value is string => Boolean(value?.trim() && value.trim() !== key)))];
1392
+ if (labels.length === 0) return undefined;
1393
+ return boundedLaneValue(labels.length > 1 ? `${labels[0]} +${labels.length - 1}` : labels[0], 48);
1394
+ }
1395
+
1396
+ function compactWorkflowLaneRow(key: string, items: readonly WorkflowChecklistItem[], lane = items.find((item) => item.preflight)?.preflight, fallbackState: WorkflowChecklistState = "queued"): CompactWorkflowLaneRow {
1397
+ const state = items.length ? compactWorkflowLaneState(items) : fallbackState;
1398
+ const toolCounts = items.map((item) => item.toolCount).filter((value): value is number => value !== undefined);
1399
+ const durations = items.map((item) => item.durationMs).filter((value): value is number => value !== undefined);
1400
+ const label = compactWorkflowLaneLabel(items, key);
1401
+ return {
1402
+ key: boundedLaneValue(key, 40) ?? key,
1403
+ state,
1404
+ agent: compactWorkflowLaneOwner(items),
1405
+ ...(lane?.mode ? { mode: lane.mode } : {}),
1406
+ ...(lane?.decision ? { decision: boundedLaneValue(lane.decision, 56) } : {}),
1407
+ ...(lane?.claims?.length ? { claims: boundedLaneValue(lane.claims.join(", "), 56) } : {}),
1408
+ ...(lane?.expectedOutput ? { expectedOutput: boundedLaneValue(lane.expectedOutput, 56) } : {}),
1409
+ ...(label ? { label } : {}),
1410
+ ...(toolCounts.length ? { toolUses: toolCounts.reduce((sum, value) => sum + value, 0) } : {}),
1411
+ ...(durations.length ? { durationMs: Math.max(...durations) } : {}),
1412
+ };
1413
+ }
1414
+
1415
+ function compactWorkflowFallbackState(job: AsyncJobState): WorkflowChecklistState {
1416
+ if (job.activityState === "needs_attention" || job.timedOut || job.toolBudgetBlocked || job.turnBudgetExceeded) return "blocked";
1417
+ switch (job.status) {
1418
+ case "complete": return "complete";
1419
+ case "failed": return "failed";
1420
+ case "paused": return "paused";
1421
+ case "stopped": return "stopped";
1422
+ case "partial":
1423
+ case "rejected": return "blocked";
1424
+ default: return "queued";
1425
+ }
1426
+ }
1427
+
1428
+ /** Flatten the loaded checklist into one compact row per declared lane. */
1429
+ function compactWorkflowLaneRows(job: AsyncJobState, checklist: WorkflowChecklistProjection | undefined): CompactWorkflowLaneRow[] {
1430
+ const groups = new Map<string, WorkflowChecklistItem[]>();
1431
+ for (const item of checklist?.phases.flatMap((phase) => phase.items) ?? []) {
1432
+ const key = item.preflight?.key ?? item.key;
1433
+ const group = groups.get(key);
1434
+ if (group) group.push(item);
1435
+ else groups.set(key, [item]);
1436
+ }
1437
+
1438
+ const rows: CompactWorkflowLaneRow[] = [];
1439
+ const preflightKeys = new Set(job.preflight?.lanes.map((lane) => lane.key) ?? []);
1440
+ if (job.preflight?.lanes.length) {
1441
+ for (const lane of job.preflight.lanes) {
1442
+ rows.push(compactWorkflowLaneRow(lane.key, groups.get(lane.key) ?? [], lane, compactWorkflowFallbackState(job)));
1443
+ }
1444
+ }
1445
+
1446
+ for (const [key, items] of groups) {
1447
+ if (preflightKeys.has(key)) continue;
1448
+ rows.push(compactWorkflowLaneRow(key, items));
1449
+ }
1450
+ return rows;
1451
+ }
1452
+
1453
+ function compactWorkflowLaneCounts(rows: readonly CompactWorkflowLaneRow[]): CompactWorkflowLaneCounts {
1454
+ const counts: CompactWorkflowLaneCounts = { total: rows.length, done: 0, active: 0, queued: 0, blocked: 0, failed: 0, paused: 0, stopped: 0 };
1455
+ for (const row of rows) {
1456
+ switch (row.state) {
1457
+ case "complete": counts.done++; break;
1458
+ case "running": counts.active++; break;
1459
+ case "queued": counts.queued++; break;
1460
+ case "blocked": counts.blocked++; break;
1461
+ case "failed": counts.failed++; break;
1462
+ case "paused": counts.paused++; break;
1463
+ case "stopped": counts.stopped++; break;
1464
+ }
1465
+ }
1466
+ return counts;
1467
+ }
1468
+
1469
+ function compactWorkflowLaneLine(row: CompactWorkflowLaneRow, theme: Theme, indent: string, frame?: number): string {
1470
+ const owner = row.agent && row.mode ? `${row.agent}/${row.mode}` : row.agent ?? row.mode;
1471
+ const state = row.state === "complete" ? undefined : row.state === "running" ? "active" : row.state;
1472
+ const intent = [
1473
+ row.decision,
1474
+ row.claims,
1475
+ row.expectedOutput,
1476
+ !row.mode && row.label ? row.label : undefined,
1477
+ ].filter((value): value is string => Boolean(value));
1478
+ return `${indent}${workflowChecklistGlyph({ state: row.state, durationMs: row.durationMs, toolCount: row.toolUses }, theme, frame)} ${theme.bold(row.key)}${owner ? ` ${theme.fg("dim", `· ${owner}`)}` : ""}${state ? ` ${theme.fg("dim", `· ${state}`)}` : ""}${intent.length ? ` ${theme.fg("dim", `· ${intent.join(" · ")}`)}` : ""}`;
1479
+ }
1480
+
1481
+ function compactWorkflowShortId(job: AsyncJobState): string {
1482
+ return job.asyncId.slice(0, 8);
1483
+ }
1484
+
1485
+ function compactWorkflowDisplayLabel(job: AsyncJobState): string {
1486
+ return boundedLaneValue(job.description, 64) ?? compactWorkflowShortId(job);
1487
+ }
1488
+
1489
+ function compactWorkflowStats(job: AsyncJobState, rows: readonly CompactWorkflowLaneRow[], theme: Theme, projection: WorkflowWidgetProjection): string {
1490
+ const counts = compactWorkflowLaneCounts(rows);
1491
+ const total = counts.total || projection.stageProgress?.total || job.stepsTotal || job.agents?.length || 0;
1492
+ const progress = [
1493
+ total > 0 ? `${counts.done}/${total} done` : undefined,
1494
+ counts.active ? `${counts.active} active` : undefined,
1495
+ counts.queued ? `${counts.queued} queued` : undefined,
1496
+ counts.blocked ? `${counts.blocked} blocked` : undefined,
1497
+ counts.failed ? `${counts.failed} failed` : undefined,
1498
+ counts.paused ? `${counts.paused} paused` : undefined,
1499
+ counts.stopped ? `${counts.stopped} stopped` : undefined,
1500
+ ].filter((value): value is string => Boolean(value));
1501
+ const rowToolUses = rows.map((row) => row.toolUses).filter((value): value is number => value !== undefined);
1502
+ const toolUses = job.toolCount ?? (rowToolUses.length ? rowToolUses.reduce((sum, value) => sum + value, 0) : undefined);
1503
+ const rowDuration = rows.map((row) => row.durationMs).filter((value): value is number => value !== undefined);
1504
+ const durationMs = job.startedAt !== undefined && job.updatedAt !== undefined
1505
+ ? Math.max(0, job.updatedAt - job.startedAt)
1506
+ : rowDuration.length ? Math.max(...rowDuration) : undefined;
1507
+ return statJoin(theme, [
1508
+ `id: ${compactWorkflowShortId(job)}`,
1509
+ ...progress,
1510
+ toolUses !== undefined ? formatToolUseStat(toolUses) : undefined,
1511
+ durationMs !== undefined ? formatDuration(durationMs) : undefined,
1512
+ ].filter((value): value is string => Boolean(value)));
1513
+ }
1514
+
1515
+ interface CompactWorkflowBottleneck {
1516
+ text: string;
1517
+ tone: "warning" | "error";
1518
+ }
1519
+
1520
+ function compactWorkflowBottleneck(rows: readonly CompactWorkflowLaneRow[], job: AsyncJobState): CompactWorkflowBottleneck | undefined {
1521
+ let row: CompactWorkflowLaneRow | undefined;
1522
+ for (const candidate of rows) {
1523
+ if (candidate.state !== "blocked" && candidate.state !== "failed" && candidate.state !== "paused" && candidate.state !== "stopped") continue;
1524
+ if (!row || workflowChecklistItemPriority(candidate.state) < workflowChecklistItemPriority(row.state)) row = candidate;
1525
+ }
1526
+ if (row) return { text: `${row.key} · ${row.state}`, tone: row.state === "blocked" || row.state === "failed" ? "error" : "warning" };
1527
+ if (job.activityState === "needs_attention" || job.timedOut || job.toolBudgetBlocked || job.turnBudgetExceeded) return { text: `workflow · ${job.activityState === "needs_attention" ? "needs attention" : "blocked"}`, tone: job.activityState === "needs_attention" ? "warning" : "error" };
1528
+ if (job.status === "failed" || job.status === "partial" || job.status === "rejected") return { text: `workflow · ${job.status}`, tone: "error" };
1529
+ if (job.status === "paused" || job.status === "stopped") return { text: `workflow · ${job.status}`, tone: "warning" };
1530
+ return undefined;
1531
+ }
1532
+
1533
+ function compactWorkflowHeaderLine(job: AsyncJobState, theme: Theme, width?: number): string {
1534
+ const label = compactWorkflowDisplayLabel(job);
1535
+ const full = `${theme.fg("toolTitle", themeBold(theme, `async workflow: ${label}`))} ${theme.fg("dim", "─ background")}`;
1536
+ if (width === undefined || visibleWidth(full) <= width) return full;
1537
+ return `${theme.fg("toolTitle", themeBold(theme, `async workflow ${label}`))} ${theme.fg("dim", "· background")}`;
1538
+ }
1539
+
1540
+ function compactWorkflowWidgetBodyLines(job: AsyncJobState, theme: Theme, frame: number | undefined, projection: WorkflowWidgetProjection): string[] {
1541
+ const rows = compactWorkflowLaneRows(job, projection.checklist);
1542
+ const lines = [` ${compactWorkflowStats(job, rows, theme, projection)}`];
1543
+ if (rows.length) {
1544
+ for (const row of rows) lines.push(compactWorkflowLaneLine(row, theme, " ", frame));
1545
+ } else {
1546
+ lines.push(` ${theme.fg("dim", "◦ waiting for workflow lanes")}`);
1547
+ }
1548
+ const bottleneck = compactWorkflowBottleneck(rows, job);
1549
+ if (bottleneck) lines.push(` ${theme.fg(bottleneck.tone, `bottleneck · ${bottleneck.text}`)}`);
1550
+ if (job.status === "running" || rows.some((row) => row.state === "running")) lines.push(` ${theme.fg("accent", workflowDetailHintText())}`);
1551
+ return lines;
1552
+ }
1553
+
1343
1554
  function widgetStepActivity(step: NonNullable<AsyncJobState["steps"]>[number], snapshotNow?: number): string {
1344
1555
  const facts: string[] = [];
1345
1556
  if (step.currentTool && step.currentToolStartedAt !== undefined && snapshotNow !== undefined) facts.push(`${step.currentTool} ${formatDuration(Math.max(0, snapshotNow - step.currentToolStartedAt))}`);
@@ -2154,19 +2365,13 @@ function hostStepWidgetLines(job: AsyncJobState, theme: Theme, indent: string):
2154
2365
 
2155
2366
  function foregroundStyleWidgetDetails(job: AsyncJobState, theme: Theme, expanded: boolean, width: number, frame?: number, projection = buildWorkflowWidgetProjection(job)): string[] {
2156
2367
  const { steps } = projection;
2157
- const checklistPrimary = !expanded && job.mode === "workflow" && projection.checklist !== undefined;
2158
- if (checklistPrimary) {
2159
- const lines = [
2160
- ...workflowPreflightLines(job, false),
2161
- ...workflowChecklistWidgetLines(projection.checklist, theme, " ", false, frame, false),
2162
- ];
2163
- if (job.status === "running" || projection.checklist!.running > 0) lines.push(` ${theme.fg("accent", liveDetailHintText())}`);
2164
- return lines;
2368
+ if (!expanded && job.mode === "workflow") {
2369
+ return compactWorkflowWidgetBodyLines(job, theme, frame, projection);
2165
2370
  }
2166
2371
  if (!steps.length) {
2167
2372
  const lane = projectAsyncLane(job, laneStepForJob(job, steps));
2168
2373
  return [
2169
- ...workflowPreflightLines(job, expanded),
2374
+ ...(expanded ? workflowPreflightLines(job) : []),
2170
2375
  ...workflowChecklistWidgetLines(projection.checklist, theme, " ", expanded, frame),
2171
2376
  ...(lane ? formatLaneProjectionLines(lane, theme, " ") : []),
2172
2377
  ...hostStepWidgetLines(job, theme, " "),
@@ -2176,8 +2381,8 @@ function foregroundStyleWidgetDetails(job: AsyncJobState, theme: Theme, expanded
2176
2381
  }
2177
2382
  if (job.mode === "chain" && !job.activeParallelGroup && job.parallelGroups?.length) return widgetChainDetails(job, theme, expanded, width, frame);
2178
2383
  const lines: string[] = [
2179
- ...workflowPreflightLines(job, expanded),
2180
- ...workflowChecklistWidgetLines(projection.checklist, theme, " ", expanded, frame),
2384
+ ...(expanded ? workflowPreflightLines(job) : []),
2385
+ ...workflowChecklistWidgetLines(projection.checklist, theme, " ", expanded, frame, { includeItemErrors: !expanded }),
2181
2386
  ];
2182
2387
  const group = activeParallelWidgetGroup(job);
2183
2388
  if (group) {
@@ -2210,6 +2415,7 @@ function foregroundStyleWidgetDetails(job: AsyncJobState, theme: Theme, expanded
2210
2415
  }
2211
2416
 
2212
2417
  function buildSingleWidgetLines(job: AsyncJobState, theme: Theme, width: number, expanded: boolean, frame?: number, projection = buildWorkflowWidgetProjection(job)): string[] {
2418
+ if (!expanded && job.mode === "workflow") return [compactWorkflowHeaderLine(job, theme, width), ...compactWorkflowWidgetBodyLines(job, theme, frame, projection)].map((line) => truncLine(line, width));
2213
2419
  const stats = widgetStats(job, theme, projection, !expanded);
2214
2420
  const count = job.mode === "workflow"
2215
2421
  ? projection.checklist?.total ?? projection.stageProgress?.total ?? job.stepsTotal ?? job.agents?.length ?? job.steps?.length
@@ -2386,11 +2592,17 @@ function progressiveHeaderLine(jobs: AsyncJobState[], theme: Theme, width: numbe
2386
2592
  }
2387
2593
 
2388
2594
  function progressiveJobLine(job: AsyncJobState, theme: Theme, width: number, frame?: number, projection = buildWorkflowWidgetProjection(job)): string {
2389
- const checklistPrimary = job.mode === "workflow" && projection.checklist !== undefined;
2390
- const stats = widgetStats(job, theme, projection, true);
2391
- const activity = checklistPrimary ? "" : widgetActivity(job);
2595
+ const compactWorkflow = job.mode === "workflow";
2596
+ const compactRows = compactWorkflow ? compactWorkflowLaneRows(job, projection.checklist) : undefined;
2597
+ const stats = compactWorkflow ? compactWorkflowStats(job, compactRows ?? [], theme, projection) : widgetStats(job, theme, projection, true);
2598
+ if (compactWorkflow) {
2599
+ const bottleneck = compactWorkflowBottleneck(compactRows ?? [], job);
2600
+ const suffix = [stats, bottleneck ? theme.fg(bottleneck.tone, `bottleneck · ${bottleneck.text}`) : undefined].filter((value): value is string => Boolean(value)).join(` ${theme.fg("dim", "·")} `);
2601
+ return truncLine(` ${widgetStatusGlyph(job, theme, frame)} ${compactWorkflowHeaderLine(job, theme, Math.max(0, width - 4))}${suffix ? ` ${theme.fg("dim", "·")} ${suffix}` : ""}`, width);
2602
+ }
2603
+ const activity = widgetActivity(job);
2392
2604
  const status = job.status === "complete" ? "done" : job.status;
2393
- const lane = checklistPrimary ? undefined : projectAsyncLane(job, laneStepForJob(job, projection.steps));
2605
+ const lane = projectAsyncLane(job, laneStepForJob(job, projection.steps));
2394
2606
  const laneSummary = lane
2395
2607
  ? [lane.label ?? lane.role, lane.phase ? `phase:${lane.phase}` : undefined, lane.output ? `out:${lane.output}` : undefined, lane.workspace ? `workspace:${lane.workspace}` : `ref:${lane.ref}`].filter(Boolean).join(" · ")
2396
2608
  : "";
@@ -2510,16 +2722,29 @@ function fitAdaptiveWidgetLines(jobs: AsyncJobState[], buildLines: () => string[
2510
2722
  return rendered.lines;
2511
2723
  }
2512
2724
 
2513
- function buildWidgetComponent(jobs: AsyncJobState[], isExpanded: () => boolean): (_tui: unknown, theme: Theme) => Component {
2514
- return (_tui, theme) => {
2725
+ const asyncWidgetUpdates = new WeakMap<ExtensionContext["ui"], (jobs: AsyncJobState[]) => void>();
2726
+
2727
+ function buildWidgetComponent(jobs: AsyncJobState[], ui: ExtensionContext["ui"]): (tui: { requestRender(): void }, theme: Theme) => Component {
2728
+ return (tui, theme) => {
2515
2729
  const container = new Container();
2516
2730
  let cachedRenderWidth: number | undefined;
2517
2731
  let cachedFrame: number | undefined;
2518
2732
  let cachedExpanded: boolean | undefined;
2519
2733
  let cachedLines: string[] | undefined;
2734
+ const update = (nextJobs: AsyncJobState[]): void => {
2735
+ jobs = nextJobs;
2736
+ cachedLines = undefined;
2737
+ tui.requestRender();
2738
+ };
2739
+ asyncWidgetUpdates.set(ui, update);
2740
+ const component = Object.assign(container, {
2741
+ dispose(): void {
2742
+ if (asyncWidgetUpdates.get(ui) === update) asyncWidgetUpdates.delete(ui);
2743
+ },
2744
+ });
2520
2745
  container.render = (renderWidth: number): string[] => {
2521
2746
  const frame = Math.floor(Date.now() / WIDGET_ANIMATION_INTERVAL_MS);
2522
- const expanded = isExpanded();
2747
+ const expanded = ui.getToolsExpanded?.() ?? false;
2523
2748
  if (cachedLines && cachedRenderWidth === renderWidth && cachedFrame === frame && cachedExpanded === expanded) return cachedLines;
2524
2749
  const width = Math.max(0, renderWidth - 2);
2525
2750
  const projectionFor = workflowWidgetProjectionLookup();
@@ -2534,7 +2759,7 @@ function buildWidgetComponent(jobs: AsyncJobState[], isExpanded: () => boolean):
2534
2759
  cachedLines = fitAdaptiveWidgetLines(jobs, buildLines, theme, width, expanded, frame, projectionFor).map((line) => paddedWidgetLine(line, renderWidth));
2535
2760
  return cachedLines;
2536
2761
  };
2537
- return container;
2762
+ return component;
2538
2763
  };
2539
2764
  }
2540
2765
 
@@ -2557,21 +2782,22 @@ function buildWidgetLinesWithProjection(jobs: AsyncJobState[], theme: Theme, wid
2557
2782
  let slots = MAX_WIDGET_JOBS;
2558
2783
  const appendJob = (job: AsyncJobState): void => {
2559
2784
  const projection = projectionFor(job);
2560
- const checklistPrimary = !expanded && job.mode === "workflow" && projection.checklist !== undefined;
2561
- const stats = widgetStats(job, theme, projection, !expanded);
2562
- const details = checklistPrimary
2785
+ const compactWorkflow = !expanded && job.mode === "workflow";
2786
+ const stats = compactWorkflow ? "" : widgetStats(job, theme, projection, !expanded);
2787
+ const details = compactWorkflow
2563
2788
  ? [
2564
- ...workflowChecklistWidgetLines(projection.checklist, theme, " ", false, frame, false),
2565
- ...(job.status === "running" || projection.checklist!.running > 0 ? [` ${theme.fg("accent", liveDetailHintText())}`] : []),
2789
+ ...compactWorkflowWidgetBodyLines(job, theme, frame, projection),
2566
2790
  ]
2567
2791
  : [
2568
2792
  ` ${theme.fg("dim", `⎿ ${widgetActivity(job)}`)}`,
2569
2793
  ...widgetLaneDetailLines(job, theme, projection),
2570
- ...workflowChecklistWidgetLines(projection.checklist, theme, " ", expanded, frame),
2794
+ ...workflowChecklistWidgetLines(projection.checklist, theme, " ", expanded, frame, { includeItemErrors: !expanded || !job.steps?.length }),
2571
2795
  ...widgetParallelAgentDetails(job, theme, expanded, width, frame),
2572
2796
  ];
2573
2797
  items.push([
2574
- `${widgetStatusGlyph(job, theme, frame)} ${themeBold(theme, widgetJobName(job))}${contextModeBadge(theme, job.context)}${stats ? ` ${theme.fg("dim", "·")} ${stats}` : ""}`,
2798
+ compactWorkflow
2799
+ ? compactWorkflowHeaderLine(job, theme, width)
2800
+ : `${widgetStatusGlyph(job, theme, frame)} ${themeBold(theme, widgetJobName(job))}${contextModeBadge(theme, job.context)}${stats ? ` ${theme.fg("dim", "·")} ${stats}` : ""}`,
2575
2801
  ...details,
2576
2802
  ]);
2577
2803
  };
@@ -2628,6 +2854,7 @@ export function buildWidgetLines(jobs: AsyncJobState[], theme: Theme, width = ge
2628
2854
  export function renderWidget(ctx: ExtensionContext, jobs: AsyncJobState[]): void {
2629
2855
  if (jobs.length === 0) {
2630
2856
  resetWidgetLayoutSession();
2857
+ asyncWidgetUpdates.delete(ctx.ui);
2631
2858
  if (ctx.hasUI) ctx.ui.setWidget(WIDGET_KEY, undefined);
2632
2859
  return;
2633
2860
  }
@@ -2636,7 +2863,11 @@ export function renderWidget(ctx: ExtensionContext, jobs: AsyncJobState[]): void
2636
2863
  ctx.ui.setWidget(WIDGET_KEY, encodeAsyncStatusSnapshotWidget(jobs));
2637
2864
  return;
2638
2865
  }
2639
- ctx.ui.setWidget(WIDGET_KEY, buildWidgetComponent(jobs, () => ctx.ui.getToolsExpanded?.() ?? false));
2866
+ // Pi replaces a widget by deleting and reinserting its key. Update the mounted
2867
+ // component instead so progress cannot move it past other extensions' widgets.
2868
+ const update = asyncWidgetUpdates.get(ctx.ui);
2869
+ if (update) update(jobs);
2870
+ else ctx.ui.setWidget(WIDGET_KEY, buildWidgetComponent(jobs, ctx.ui));
2640
2871
  }
2641
2872
 
2642
2873
  function renderSingleCompact(
@@ -2789,7 +3020,7 @@ function renderWorkflowChatProgress(d: Details, result: AgentToolResult<Details>
2789
3020
  if (d.preflight) c.addChild(new Text(truncLine(theme.fg("dim", formatWorkflowPreflightPlanSummary(d.preflight, { indent: rowIndent })), width), 0, 0));
2790
3021
  if (phase) c.addChild(new Text(truncLine(theme.fg("dim", `${rowIndent}Phase ${phase}`), width), 0, 0));
2791
3022
  const checklist = projectWorkflowChecklist({ hostSteps: workflow?.receipt?.hostSteps, preflight: d.preflight, trace: workflow?.trace, now: Date.now() });
2792
- for (const line of workflowChecklistWidgetLines(checklist, theme, rowIndent, false, frame, true, !expanded, expanded)) {
3023
+ for (const line of workflowChecklistWidgetLines(checklist, theme, rowIndent, false, frame, { limitPhases: !expanded, includeBottleneckOutput: expanded })) {
2793
3024
  c.addChild(new Text(truncLine(line, width), 0, 0));
2794
3025
  }
2795
3026
  if (rows.length === 0) {
@@ -2871,7 +3102,7 @@ function renderMultiCompact(d: Details, theme: Theme, layout: MainWindowRenderLa
2871
3102
  const detailIndent = mainWindowIndent(layout, 2);
2872
3103
  c.addChild(new Text(truncLine(`${glyph} ${theme.fg("toolTitle", theme.bold(d.mode))}${contextBadge}${stats ? ` ${theme.fg("dim", "·")} ${stats}` : ""}`, width), 0, 0));
2873
3104
  if (checklistPrimary) {
2874
- for (const line of workflowChecklistWidgetLines(workflowChecklist, theme, rowIndent, false, frame, false)) {
3105
+ for (const line of workflowChecklistWidgetLines(workflowChecklist, theme, rowIndent, false, frame, { includeSummary: false })) {
2875
3106
  c.addChild(new Text(truncLine(line, width), 0, 0));
2876
3107
  }
2877
3108
  if (hasRunning || workflowChecklist.running > 0) c.addChild(new Text(truncLine(theme.fg("accent", `${rowIndent}${liveDetailHintText()}`), width), 0, 0));
@@ -3222,7 +3453,7 @@ export function renderSubagentResult(
3222
3453
  c.addChild(new Text(fit(` ${chainVis}`), 0, 0));
3223
3454
  }
3224
3455
  const workflowChecklist = foregroundWorkflowChecklist(d);
3225
- for (const line of workflowChecklistWidgetLines(workflowChecklist, theme, " ", true, frame)) {
3456
+ for (const line of workflowChecklistWidgetLines(workflowChecklist, theme, " ", true, frame, { includeItemErrors: false })) {
3226
3457
  c.addChild(new Text(fit(line), 0, 0));
3227
3458
  }
3228
3459
 
@@ -3,7 +3,6 @@ import { SUBAGENT_WATCHDOG_WARNING_TYPE, type ResolvedWatchdogConfig, type Watch
3
3
 
4
4
  export const CHILD_WATCHDOG_WARNING_LIMIT = 20;
5
5
 
6
- export const CHILD_WATCHDOG_CONFIG_ENV = "SELESAI_SUBAGENT_WATCHDOG_CHILD_CONFIG";
7
6
  export const CHILD_WATCHDOG_STATUS_EVENT = "subagent.watchdog.status";
8
7
 
9
8
  export const CHILD_WATCHDOG_PHASES = ["idle", "reviewing", "stale", "failed"] as const;
@@ -5,11 +5,10 @@ import { createMainWatchdogReview } from "./review.ts";
5
5
  import { DEFAULT_WATCHDOG_CONFIG } from "./settings.ts";
6
6
  import { createWatchdogWarningMessage } from "./warning-format.ts";
7
7
  import {
8
- CHILD_WATCHDOG_CONFIG_ENV,
9
8
  CHILD_WATCHDOG_STATUS_EVENT,
10
- decodeChildWatchdogConfig,
11
9
  type ChildWatchdogConfig,
12
10
  type ChildWatchdogPhase,
11
+ type ChildWatchdogStatusEvent,
13
12
  } from "./child-status.ts";
14
13
  import type { ResolvedWatchdogConfig, WatchdogWarningDetails } from "./types.ts";
15
14
 
@@ -43,17 +42,18 @@ function childWarningDetails(details: WatchdogWarningDetails, config: ChildWatch
43
42
  };
44
43
  }
45
44
 
46
- function writeStatus(event: unknown): void {
47
- try {
48
- process.stdout.write(`${JSON.stringify(event)}\n`);
49
- } catch {
50
- // Child watchdog status is advisory; stdout failures are handled by the child process itself.
51
- }
52
- }
53
-
54
- export function registerChildWatchdog(pi: ExtensionAPI, rawConfig = process.env[CHILD_WATCHDOG_CONFIG_ENV]): MainWatchdogRuntime | undefined {
55
- const childConfig = decodeChildWatchdogConfig(rawConfig);
45
+ /**
46
+ * Register the child-side watchdog. Status events go to the sink the hosting
47
+ * process passed in the child runtime config; the host folds them into the
48
+ * child's event stream.
49
+ */
50
+ export function registerChildWatchdog(
51
+ pi: ExtensionAPI,
52
+ childConfig: ChildWatchdogConfig | undefined,
53
+ writeStatus: ((event: ChildWatchdogStatusEvent) => void) | undefined,
54
+ ): MainWatchdogRuntime | undefined {
56
55
  if (!childConfig) return undefined;
56
+ if (!writeStatus) throw new Error("Child watchdog status sink is missing; the host must pass ChildRuntimeConfig.watchdogStatus.");
57
57
  let currentContext: ExtensionContext | undefined;
58
58
  let diffBaseline: WatchdogDiffBaseline | undefined;
59
59
  let seq = 0;
@@ -1,7 +1,7 @@
1
1
  import { spawnSync } from "node:child_process";
2
2
  import * as fs from "node:fs";
3
3
  import * as path from "node:path";
4
- import type { Details, WorkflowPreflightLaneV1, WorkflowPreflightV1 } from "../shared/types.ts";
4
+ import type { Details, WorkflowPreflightLane, WorkflowPreflight } from "../shared/types.ts";
5
5
  import { workflowPreflightLaneForRuntimeKey } from "./workflow-preflight.ts";
6
6
 
7
7
  export const WORKFLOW_CHAT_PROGRESS_MODES = ["auto", "off", "live-card"] as const;
@@ -103,14 +103,14 @@ export interface WorkflowChatProgressRow {
103
103
  runId?: string;
104
104
  durationMs?: number;
105
105
  error?: string;
106
- preflight?: WorkflowPreflightLaneV1;
106
+ preflight?: WorkflowPreflightLane;
107
107
  }
108
108
 
109
109
  function cleanLabel(value: unknown): string | undefined {
110
110
  return typeof value === "string" && value.trim() ? value.trim() : undefined;
111
111
  }
112
112
 
113
- export function buildWorkflowChatProgressRows(trace: NonNullable<Details["workflow"]>["trace"], preflight?: WorkflowPreflightV1): WorkflowChatProgressRow[] {
113
+ export function buildWorkflowChatProgressRows(trace: NonNullable<Details["workflow"]>["trace"], preflight?: WorkflowPreflight): WorkflowChatProgressRow[] {
114
114
  const rows = new Map<string, WorkflowChatProgressRow>();
115
115
  for (const entry of trace) {
116
116
  if (entry.operation !== "run") continue;