@selesai/code 0.12.0 → 0.13.1

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 (466) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/core/agent-session.d.ts +1 -1
  3. package/dist/core/agent-session.js +1 -1
  4. package/dist/core/sdk.d.ts +2 -2
  5. package/dist/core/sdk.js +1 -1
  6. package/dist/core/system-prompt.d.ts +1 -1
  7. package/dist/core/system-prompt.js +1 -1
  8. package/dist/core/usage-totals.d.ts +2 -0
  9. package/dist/core/usage-totals.js +10 -0
  10. package/dist/extensions/ascii.txt +9 -0
  11. package/dist/extensions/package.json +1 -2
  12. package/dist/extensions/pi-hermes-memory/CHANGELOG.md +371 -0
  13. package/dist/extensions/pi-hermes-memory/LICENSE +21 -0
  14. package/dist/extensions/pi-hermes-memory/README.md +643 -0
  15. package/dist/extensions/pi-hermes-memory/docs/0.1/TASKS.md +197 -0
  16. package/dist/extensions/pi-hermes-memory/docs/0.2/PLAN.md +290 -0
  17. package/dist/extensions/pi-hermes-memory/docs/0.2/TASKS.md +134 -0
  18. package/dist/extensions/pi-hermes-memory/docs/0.2/TEST-PLAN.md +216 -0
  19. package/dist/extensions/pi-hermes-memory/docs/0.3/PLAN.md +330 -0
  20. package/dist/extensions/pi-hermes-memory/docs/0.3/TASKS.md +125 -0
  21. package/dist/extensions/pi-hermes-memory/docs/0.4/PLAN.md +160 -0
  22. package/dist/extensions/pi-hermes-memory/docs/0.4/TASKS.md +113 -0
  23. package/dist/extensions/pi-hermes-memory/docs/0.6/CHANGELOG.md +57 -0
  24. package/dist/extensions/pi-hermes-memory/docs/0.6/PLAN.md +202 -0
  25. package/dist/extensions/pi-hermes-memory/docs/0.6/TASKS.md +144 -0
  26. package/dist/extensions/pi-hermes-memory/docs/0.7/PLAN.md +349 -0
  27. package/dist/extensions/pi-hermes-memory/docs/0.7/TASKS.md +110 -0
  28. package/dist/extensions/pi-hermes-memory/docs/PUBLISHING.md +149 -0
  29. package/dist/extensions/pi-hermes-memory/docs/ROADMAP.md +468 -0
  30. package/dist/extensions/pi-hermes-memory/docs/images/memory-architecture.svg +1 -0
  31. package/dist/extensions/pi-hermes-memory/docs/images/pi-logo.svg +22 -0
  32. package/dist/extensions/pi-hermes-memory/docs/images/pi_memory.png +0 -0
  33. package/dist/extensions/pi-hermes-memory/docs/images/pi_memory.svg +19 -0
  34. package/dist/extensions/pi-hermes-memory/docs/images/security-flow.svg +1 -0
  35. package/dist/extensions/pi-hermes-memory/docs/images/session-lifecycle.svg +1 -0
  36. package/dist/extensions/pi-hermes-memory/docs/images/source-architecture.svg +1 -0
  37. package/dist/extensions/pi-hermes-memory/docs/mermaid/memory-architecture.mmd +49 -0
  38. package/dist/extensions/pi-hermes-memory/docs/mermaid/security-flow.mmd +40 -0
  39. package/dist/extensions/pi-hermes-memory/docs/mermaid/session-lifecycle.mmd +56 -0
  40. package/dist/extensions/pi-hermes-memory/docs/mermaid/source-architecture.mmd +54 -0
  41. package/dist/extensions/pi-hermes-memory/package-lock.json +3799 -0
  42. package/dist/extensions/pi-hermes-memory/package.json +66 -0
  43. package/dist/extensions/pi-hermes-memory/scripts/check-min-sdk.mjs +99 -0
  44. package/dist/extensions/pi-hermes-memory/scripts/ensure-dev.mjs +57 -0
  45. package/dist/extensions/pi-hermes-memory/src/auto-consolidation-warning.ts +6 -0
  46. package/dist/extensions/pi-hermes-memory/src/config.ts +178 -0
  47. package/dist/extensions/pi-hermes-memory/src/constants.ts +424 -0
  48. package/dist/extensions/pi-hermes-memory/src/extension-root-migration.ts +639 -0
  49. package/dist/extensions/pi-hermes-memory/src/handlers/auto-consolidate.ts +401 -0
  50. package/dist/extensions/pi-hermes-memory/src/handlers/background-review.ts +297 -0
  51. package/dist/extensions/pi-hermes-memory/src/handlers/child-process-watchdog.mjs +90 -0
  52. package/dist/extensions/pi-hermes-memory/src/handlers/correction-detector.ts +300 -0
  53. package/dist/extensions/pi-hermes-memory/src/handlers/index-sessions.ts +86 -0
  54. package/dist/extensions/pi-hermes-memory/src/handlers/insights.ts +78 -0
  55. package/dist/extensions/pi-hermes-memory/src/handlers/interview.ts +37 -0
  56. package/dist/extensions/pi-hermes-memory/src/handlers/learn-memory.ts +186 -0
  57. package/dist/extensions/pi-hermes-memory/src/handlers/message-parts.ts +27 -0
  58. package/dist/extensions/pi-hermes-memory/src/handlers/pi-child-process.ts +485 -0
  59. package/dist/extensions/pi-hermes-memory/src/handlers/preview-context.ts +105 -0
  60. package/dist/extensions/pi-hermes-memory/src/handlers/review-memory-ops.ts +506 -0
  61. package/dist/extensions/pi-hermes-memory/src/handlers/session-backfill.ts +145 -0
  62. package/dist/extensions/pi-hermes-memory/src/handlers/session-flush.ts +151 -0
  63. package/dist/extensions/pi-hermes-memory/src/handlers/session-live-index.ts +94 -0
  64. package/dist/extensions/pi-hermes-memory/src/handlers/skills-command.ts +1334 -0
  65. package/dist/extensions/pi-hermes-memory/src/handlers/standing-pin.ts +111 -0
  66. package/dist/extensions/pi-hermes-memory/src/handlers/switch-project.ts +75 -0
  67. package/dist/extensions/pi-hermes-memory/src/handlers/sync-markdown-memories.ts +266 -0
  68. package/dist/extensions/pi-hermes-memory/src/index.ts +378 -0
  69. package/dist/extensions/pi-hermes-memory/src/lifecycle-timing.ts +54 -0
  70. package/dist/extensions/pi-hermes-memory/src/paths.ts +61 -0
  71. package/dist/extensions/pi-hermes-memory/src/project-context.ts +13 -0
  72. package/dist/extensions/pi-hermes-memory/src/project-memory-migration.ts +93 -0
  73. package/dist/extensions/pi-hermes-memory/src/project.ts +157 -0
  74. package/dist/extensions/pi-hermes-memory/src/prompt-context.ts +55 -0
  75. package/dist/extensions/pi-hermes-memory/src/store/atomic-lock-coordinator.ts +375 -0
  76. package/dist/extensions/pi-hermes-memory/src/store/canonical-storage-path.ts +54 -0
  77. package/dist/extensions/pi-hermes-memory/src/store/content-scanner.ts +101 -0
  78. package/dist/extensions/pi-hermes-memory/src/store/db.ts +1180 -0
  79. package/dist/extensions/pi-hermes-memory/src/store/fts-query.ts +101 -0
  80. package/dist/extensions/pi-hermes-memory/src/store/markdown-mutation-lock.ts +38 -0
  81. package/dist/extensions/pi-hermes-memory/src/store/memory-lookup.ts +24 -0
  82. package/dist/extensions/pi-hermes-memory/src/store/memory-store.ts +1191 -0
  83. package/dist/extensions/pi-hermes-memory/src/store/recovery-maintenance.ts +66 -0
  84. package/dist/extensions/pi-hermes-memory/src/store/schema.ts +118 -0
  85. package/dist/extensions/pi-hermes-memory/src/store/session-anchor-search.ts +472 -0
  86. package/dist/extensions/pi-hermes-memory/src/store/session-indexer.ts +511 -0
  87. package/dist/extensions/pi-hermes-memory/src/store/session-parser.ts +213 -0
  88. package/dist/extensions/pi-hermes-memory/src/store/session-search.ts +234 -0
  89. package/dist/extensions/pi-hermes-memory/src/store/skill-store.ts +950 -0
  90. package/dist/extensions/pi-hermes-memory/src/store/skill-utils.ts +133 -0
  91. package/dist/extensions/pi-hermes-memory/src/store/sqlite-memory-store.ts +1002 -0
  92. package/dist/extensions/pi-hermes-memory/src/store/sqlite-native.ts +241 -0
  93. package/dist/extensions/pi-hermes-memory/src/store/standing-instructions.ts +247 -0
  94. package/dist/extensions/pi-hermes-memory/src/tools/memory-search-tool.ts +95 -0
  95. package/dist/extensions/pi-hermes-memory/src/tools/memory-tool.ts +469 -0
  96. package/dist/extensions/pi-hermes-memory/src/tools/session-search-tool.ts +246 -0
  97. package/dist/extensions/pi-hermes-memory/src/tools/shared-output-view.ts +170 -0
  98. package/dist/extensions/pi-hermes-memory/src/tools/skill-tool.ts +333 -0
  99. package/dist/extensions/pi-hermes-memory/src/tools/tool-result-views.ts +105 -0
  100. package/dist/extensions/pi-hermes-memory/src/types.ts +214 -0
  101. package/dist/extensions/pi-hermes-memory/tests/config.test.ts +434 -0
  102. package/dist/extensions/pi-hermes-memory/tests/extension-root-migration.test.ts +368 -0
  103. package/dist/extensions/pi-hermes-memory/tests/handlers/auto-consolidate.test.ts +984 -0
  104. package/dist/extensions/pi-hermes-memory/tests/handlers/background-review.test.ts +950 -0
  105. package/dist/extensions/pi-hermes-memory/tests/handlers/correction-detector.test.ts +671 -0
  106. package/dist/extensions/pi-hermes-memory/tests/handlers/insights.test.ts +157 -0
  107. package/dist/extensions/pi-hermes-memory/tests/handlers/interview.test.ts +127 -0
  108. package/dist/extensions/pi-hermes-memory/tests/handlers/pi-child-process.test.ts +905 -0
  109. package/dist/extensions/pi-hermes-memory/tests/handlers/preview-context.test.ts +152 -0
  110. package/dist/extensions/pi-hermes-memory/tests/handlers/prompt-context.test.ts +166 -0
  111. package/dist/extensions/pi-hermes-memory/tests/handlers/resources-discover.test.ts +71 -0
  112. package/dist/extensions/pi-hermes-memory/tests/handlers/review-memory-ops.test.ts +614 -0
  113. package/dist/extensions/pi-hermes-memory/tests/handlers/session-backfill.test.ts +192 -0
  114. package/dist/extensions/pi-hermes-memory/tests/handlers/session-flush.test.ts +677 -0
  115. package/dist/extensions/pi-hermes-memory/tests/handlers/session-live-index.test.ts +225 -0
  116. package/dist/extensions/pi-hermes-memory/tests/handlers/skills-command.test.ts +827 -0
  117. package/dist/extensions/pi-hermes-memory/tests/handlers/standing-pin.test.ts +134 -0
  118. package/dist/extensions/pi-hermes-memory/tests/handlers/sync-markdown-memories.test.ts +491 -0
  119. package/dist/extensions/pi-hermes-memory/tests/handlers/system-prompt.test.ts +199 -0
  120. package/dist/extensions/pi-hermes-memory/tests/handlers/thinking-max.test.ts +64 -0
  121. package/dist/extensions/pi-hermes-memory/tests/index.test.ts +30 -0
  122. package/dist/extensions/pi-hermes-memory/tests/integration/flow.test.ts +126 -0
  123. package/dist/extensions/pi-hermes-memory/tests/lifecycle-timing.test.ts +76 -0
  124. package/dist/extensions/pi-hermes-memory/tests/paths.test.ts +23 -0
  125. package/dist/extensions/pi-hermes-memory/tests/project-memory-migration.test.ts +80 -0
  126. package/dist/extensions/pi-hermes-memory/tests/project-rebinding.test.ts +115 -0
  127. package/dist/extensions/pi-hermes-memory/tests/project.test.ts +120 -0
  128. package/dist/extensions/pi-hermes-memory/tests/run-all-timeout.test.ts +107 -0
  129. package/dist/extensions/pi-hermes-memory/tests/run-all.sh +45 -0
  130. package/dist/extensions/pi-hermes-memory/tests/store/atomic-lock-coordinator.test.ts +381 -0
  131. package/dist/extensions/pi-hermes-memory/tests/store/content-scanner.test.ts +388 -0
  132. package/dist/extensions/pi-hermes-memory/tests/store/db.test.ts +1046 -0
  133. package/dist/extensions/pi-hermes-memory/tests/store/markdown-mutation-lock.test.ts +34 -0
  134. package/dist/extensions/pi-hermes-memory/tests/store/memory-store.test.ts +2150 -0
  135. package/dist/extensions/pi-hermes-memory/tests/store/recovery-maintenance.test.ts +170 -0
  136. package/dist/extensions/pi-hermes-memory/tests/store/session-anchor-search.test.ts +210 -0
  137. package/dist/extensions/pi-hermes-memory/tests/store/session-indexer.test.ts +643 -0
  138. package/dist/extensions/pi-hermes-memory/tests/store/session-parser.test.ts +282 -0
  139. package/dist/extensions/pi-hermes-memory/tests/store/session-search.test.ts +287 -0
  140. package/dist/extensions/pi-hermes-memory/tests/store/skill-store.test.ts +678 -0
  141. package/dist/extensions/pi-hermes-memory/tests/store/skill-utils.test.ts +21 -0
  142. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-lazy-load.test.ts +78 -0
  143. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-memory-store.test.ts +543 -0
  144. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-native.test.ts +164 -0
  145. package/dist/extensions/pi-hermes-memory/tests/store/standing-instructions.test.ts +171 -0
  146. package/dist/extensions/pi-hermes-memory/tests/tools/memory-search-tool.test.ts +84 -0
  147. package/dist/extensions/pi-hermes-memory/tests/tools/memory-tool.test.ts +709 -0
  148. package/dist/extensions/pi-hermes-memory/tests/tools/session-search-tool.test.ts +345 -0
  149. package/dist/extensions/pi-hermes-memory/tests/tools/shared-output-view.test.ts +362 -0
  150. package/dist/extensions/pi-hermes-memory/tests/tools/skill-tool.test.ts +478 -0
  151. package/dist/extensions/pi-hermes-memory/tests/tools/tool-result-renderer-wiring.test.ts +40 -0
  152. package/dist/extensions/pi-hermes-memory/tsconfig.json +19 -0
  153. package/dist/extensions/pi-subagents/.oxlintrc.json +43 -0
  154. package/dist/extensions/pi-subagents/AGENTS.md +5 -0
  155. package/dist/extensions/pi-subagents/CHANGELOG.md +157 -0
  156. package/dist/extensions/pi-subagents/README.md +12 -6
  157. package/dist/extensions/pi-subagents/VISION.md +81 -0
  158. package/dist/extensions/pi-subagents/agents/claude-code-writer.md +15 -0
  159. package/dist/extensions/pi-subagents/agents/claude-code.md +15 -0
  160. package/dist/extensions/pi-subagents/agents/codex-exec-writer.md +15 -0
  161. package/dist/extensions/pi-subagents/agents/codex-exec.md +15 -0
  162. package/dist/extensions/pi-subagents/agents/cursor-agent-writer.md +14 -0
  163. package/dist/extensions/pi-subagents/agents/cursor-agent.md +14 -0
  164. package/dist/extensions/pi-subagents/agents/reviewer.md +1 -3
  165. package/dist/extensions/pi-subagents/docs/agents.md +488 -0
  166. package/dist/extensions/pi-subagents/docs/configuration.md +46 -9
  167. package/dist/extensions/pi-subagents/docs/extension-api.md +42 -3
  168. package/dist/extensions/pi-subagents/docs/models.md +27 -4
  169. package/dist/extensions/pi-subagents/docs/observability.md +10 -9
  170. package/dist/extensions/pi-subagents/docs/tool-reference.md +102 -6
  171. package/dist/extensions/pi-subagents/docs/workflows.md +135 -0
  172. package/dist/extensions/pi-subagents/package-lock.json +389 -2
  173. package/dist/extensions/pi-subagents/package.json +3 -1
  174. package/dist/extensions/pi-subagents/prompts/review-loop.md +2 -2
  175. package/dist/extensions/pi-subagents/skills/council-mode/SKILL.md +1 -1
  176. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +3 -1
  177. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +7 -3
  178. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +2 -2
  179. package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +26 -5
  180. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +41 -22
  181. package/dist/extensions/pi-subagents/src/agents/agent-refinements.ts +4 -4
  182. package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +9 -2
  183. package/dist/extensions/pi-subagents/src/agents/agents.ts +322 -75
  184. package/dist/extensions/pi-subagents/src/agents/builtin-names.ts +6 -0
  185. package/dist/extensions/pi-subagents/src/agents/runtime-agent-events.ts +70 -0
  186. package/dist/extensions/pi-subagents/src/agents/runtime-agent-registry.ts +27 -20
  187. package/dist/extensions/pi-subagents/src/api/agents.ts +10 -5
  188. package/dist/extensions/pi-subagents/src/api/background-work.ts +5 -1
  189. package/dist/extensions/pi-subagents/src/api/delegation.ts +0 -7
  190. package/dist/extensions/pi-subagents/src/api/preflight.ts +34 -12
  191. package/dist/extensions/pi-subagents/src/extension/config.ts +70 -0
  192. package/dist/extensions/pi-subagents/src/extension/doctor.ts +3 -3
  193. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +5 -3
  194. package/dist/extensions/pi-subagents/src/extension/index.ts +83 -30
  195. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +44 -15
  196. package/dist/extensions/pi-subagents/src/extension/rpc.ts +55 -19
  197. package/dist/extensions/pi-subagents/src/extension/schemas.ts +41 -15
  198. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +28 -31
  199. package/dist/extensions/pi-subagents/src/inspectors/herdr/actions.ts +2 -1
  200. package/dist/extensions/pi-subagents/src/inspectors/herdr/inspector-runner.ts +2 -10
  201. package/dist/extensions/pi-subagents/src/inspectors/herdr/session-roots-codec.ts +42 -0
  202. package/dist/extensions/pi-subagents/src/integrations/herdr-status.ts +51 -3
  203. package/dist/extensions/pi-subagents/src/intercom/result-intercom.ts +2 -0
  204. package/dist/extensions/pi-subagents/src/profiles/profiles.ts +5 -6
  205. package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +77 -10
  206. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +176 -53
  207. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +19 -12
  208. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +29 -27
  209. package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +20 -3
  210. package/dist/extensions/pi-subagents/src/runs/background/async-status-snapshot.ts +23 -261
  211. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +73 -7
  212. package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +8 -3
  213. package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +74 -8
  214. package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +37 -21
  215. package/dist/extensions/pi-subagents/src/runs/background/inspect-rpc.ts +8 -8
  216. package/dist/extensions/pi-subagents/src/runs/background/notify.ts +184 -9
  217. package/dist/extensions/pi-subagents/src/runs/background/result-delivery-ownership.ts +45 -0
  218. package/dist/extensions/pi-subagents/src/runs/background/result-files.ts +28 -14
  219. package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +38 -15
  220. package/dist/extensions/pi-subagents/src/runs/background/resume-guidance.ts +1 -1
  221. package/dist/extensions/pi-subagents/src/runs/background/retained-children.ts +1 -1
  222. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +50 -13
  223. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +93 -8
  224. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +10 -4
  225. package/dist/extensions/pi-subagents/src/runs/background/steering.ts +4 -14
  226. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +549 -377
  227. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +58 -10
  228. package/dist/extensions/pi-subagents/src/runs/background/terminal-run-index.ts +1 -1
  229. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +26 -1
  230. package/dist/extensions/pi-subagents/src/runs/background/wait-config.ts +23 -9
  231. package/dist/extensions/pi-subagents/src/runs/background/wait-tool.ts +9 -2
  232. package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +2 -2
  233. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +204 -129
  234. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +9 -0
  235. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +23 -1
  236. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +773 -311
  237. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +140 -115
  238. package/dist/extensions/pi-subagents/src/runs/shared/abort-recovery.ts +119 -0
  239. package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +463 -0
  240. package/dist/extensions/pi-subagents/src/runs/shared/child-identity.ts +19 -4
  241. package/dist/extensions/pi-subagents/src/runs/shared/child-launch-plan.ts +151 -0
  242. package/dist/extensions/pi-subagents/src/runs/shared/child-protocol.ts +21 -7
  243. package/dist/extensions/pi-subagents/src/runs/shared/claude-code-adapter.ts +129 -0
  244. package/dist/extensions/pi-subagents/src/runs/shared/codex-exec-adapter.ts +129 -0
  245. package/dist/extensions/pi-subagents/src/runs/shared/completion-evidence.ts +89 -0
  246. package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +5 -4
  247. package/dist/extensions/pi-subagents/src/runs/shared/cursor-agent-adapter.ts +114 -0
  248. package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +3 -3
  249. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-contract.ts +167 -0
  250. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-preflight.ts +122 -0
  251. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-runner.ts +348 -55
  252. package/dist/extensions/pi-subagents/src/runs/shared/fast-mode-extension.ts +5 -5
  253. package/dist/extensions/pi-subagents/src/runs/shared/host-step-status.ts +230 -0
  254. package/dist/extensions/pi-subagents/src/runs/shared/lane-metadata.ts +105 -0
  255. package/dist/extensions/pi-subagents/src/runs/shared/launch-cwd.ts +16 -0
  256. package/dist/extensions/pi-subagents/src/runs/shared/long-running-guard.ts +2 -1
  257. package/dist/extensions/pi-subagents/src/runs/shared/mcp-config-sources.ts +422 -0
  258. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +221 -158
  259. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-grant.ts +197 -0
  260. package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +69 -7
  261. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +47 -6
  262. package/dist/extensions/pi-subagents/src/runs/shared/mutation-evidence.ts +7 -2
  263. package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +9 -3
  264. package/dist/extensions/pi-subagents/src/runs/shared/nested-render.ts +9 -5
  265. package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +419 -7
  266. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +15 -1
  267. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +81 -8
  268. package/dist/extensions/pi-subagents/src/runs/shared/process-signal.ts +13 -0
  269. package/dist/extensions/pi-subagents/src/runs/shared/run-history.ts +21 -1
  270. package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +44 -4
  271. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +98 -13
  272. package/dist/extensions/pi-subagents/src/runs/shared/subagent-startup-retry.ts +1 -1
  273. package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-plan.ts +847 -0
  274. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +18 -0
  275. package/dist/extensions/pi-subagents/src/shared/child-session-name.ts +46 -0
  276. package/dist/extensions/pi-subagents/src/shared/extension-context.ts +24 -0
  277. package/dist/extensions/pi-subagents/src/shared/fork-context.ts +21 -0
  278. package/dist/extensions/pi-subagents/src/shared/formatters.ts +18 -3
  279. package/dist/extensions/pi-subagents/src/shared/launch-contract.ts +5 -1
  280. package/dist/extensions/pi-subagents/src/shared/pruned-fork.ts +450 -0
  281. package/dist/extensions/pi-subagents/src/shared/session-file-trust.ts +19 -0
  282. package/dist/extensions/pi-subagents/src/shared/session-tokens.ts +14 -3
  283. package/dist/extensions/pi-subagents/src/shared/settings.ts +19 -105
  284. package/dist/extensions/pi-subagents/src/shared/shortcuts.ts +17 -0
  285. package/dist/extensions/pi-subagents/src/shared/types.ts +359 -40
  286. package/dist/extensions/pi-subagents/src/shared/utils.ts +41 -84
  287. package/dist/extensions/pi-subagents/src/shared/workflow-child-permit.ts +116 -0
  288. package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +1 -9
  289. package/dist/extensions/pi-subagents/src/slash/delegation-request.ts +0 -4
  290. package/dist/extensions/pi-subagents/src/slash/slash-bridge.ts +1 -2
  291. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +378 -88
  292. package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +22 -11
  293. package/dist/extensions/pi-subagents/src/slash/subagents-admin.ts +3 -0
  294. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +147 -79
  295. package/dist/extensions/pi-subagents/src/tui/fleet-transcript.ts +11 -5
  296. package/dist/extensions/pi-subagents/src/tui/fleet.ts +39 -18
  297. package/dist/extensions/pi-subagents/src/tui/render.ts +369 -46
  298. package/dist/extensions/pi-subagents/src/watchdog/turn-delta.ts +1 -1
  299. package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +6 -3
  300. package/dist/extensions/pi-subagents/src/workflows/host-command.ts +230 -0
  301. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +740 -58
  302. package/dist/extensions/pi-subagents/src/workflows/workflow-child-summary.ts +121 -0
  303. package/dist/extensions/pi-subagents/src/workflows/workflow-preflight.ts +270 -0
  304. package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +195 -6
  305. package/dist/extensions/pi-subagents/src/workflows/workflow-settlement.ts +246 -0
  306. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +2 -2
  307. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +1114 -260
  308. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +34 -0
  309. package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +150 -3
  310. package/dist/extensions/pi-subagents/test/integration/claude-code-smoke.test.ts +52 -0
  311. package/dist/extensions/pi-subagents/test/integration/claude-code-writer-smoke.test.ts +55 -0
  312. package/dist/extensions/pi-subagents/test/integration/codex-exec-smoke.test.ts +53 -0
  313. package/dist/extensions/pi-subagents/test/integration/codex-exec-writer-smoke.test.ts +57 -0
  314. package/dist/extensions/pi-subagents/test/integration/cursor-agent-smoke.test.ts +59 -0
  315. package/dist/extensions/pi-subagents/test/integration/cursor-agent-writer-smoke.test.ts +62 -0
  316. package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +57 -1
  317. package/dist/extensions/pi-subagents/test/integration/external-cli-runner.test.ts +1 -0
  318. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +20 -0
  319. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +4 -3
  320. package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +2 -2
  321. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +54 -4
  322. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +482 -4
  323. package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +157 -9
  324. package/dist/extensions/pi-subagents/test/integration/session-tokens.test.ts +5 -5
  325. package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +1508 -291
  326. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +423 -1
  327. package/dist/extensions/pi-subagents/test/integration/template-resolution.test.ts +8 -0
  328. package/dist/extensions/pi-subagents/test/support/cursor-smoke-inputs.ts +51 -0
  329. package/dist/extensions/pi-subagents/test/support/helpers.ts +2 -0
  330. package/dist/extensions/pi-subagents/test/support/mock-pi.ts +5 -5
  331. package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +6 -6
  332. package/dist/extensions/pi-subagents/test/unit/abort-recovery.test.ts +152 -0
  333. package/dist/extensions/pi-subagents/test/unit/active-async-capacity.test.ts +48 -0
  334. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +184 -6
  335. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +66 -6
  336. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +77 -0
  337. package/dist/extensions/pi-subagents/test/unit/agent-refinements.test.ts +18 -0
  338. package/dist/extensions/pi-subagents/test/unit/anti-slop-oxlint.test.ts +86 -0
  339. package/dist/extensions/pi-subagents/test/unit/artifacts.test.ts +1 -1
  340. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +101 -1
  341. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +121 -0
  342. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +28 -0
  343. package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +14 -7
  344. package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +53 -0
  345. package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +190 -0
  346. package/dist/extensions/pi-subagents/test/unit/async-status-snapshot.test.ts +42 -0
  347. package/dist/extensions/pi-subagents/test/unit/auto-drain.test.ts +8 -4
  348. package/dist/extensions/pi-subagents/test/unit/background-work.test.ts +23 -0
  349. package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +78 -1
  350. package/dist/extensions/pi-subagents/test/unit/child-launch-plan.test.ts +94 -0
  351. package/dist/extensions/pi-subagents/test/unit/child-protocol.test.ts +21 -0
  352. package/dist/extensions/pi-subagents/test/unit/child-session-name.test.ts +50 -0
  353. package/dist/extensions/pi-subagents/test/unit/claude-code-adapter.test.ts +245 -0
  354. package/dist/extensions/pi-subagents/test/unit/codex-exec-adapter.test.ts +192 -0
  355. package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +27 -0
  356. package/dist/extensions/pi-subagents/test/unit/completion-evidence.test.ts +150 -0
  357. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +21 -0
  358. package/dist/extensions/pi-subagents/test/unit/cursor-agent-adapter.test.ts +259 -0
  359. package/dist/extensions/pi-subagents/test/unit/cursor-smoke-inputs.test.ts +77 -0
  360. package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +1 -4
  361. package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +1 -1
  362. package/dist/extensions/pi-subagents/test/unit/extension-context.test.ts +27 -0
  363. package/dist/extensions/pi-subagents/test/unit/external-cli-runner.test.ts +223 -0
  364. package/dist/extensions/pi-subagents/test/unit/fast-mode-extension.test.ts +27 -0
  365. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +208 -2
  366. package/dist/extensions/pi-subagents/test/unit/fleet-transcript.test.ts +29 -1
  367. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +110 -1
  368. package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +10 -0
  369. package/dist/extensions/pi-subagents/test/unit/formatters.test.ts +14 -0
  370. package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +18 -9
  371. package/dist/extensions/pi-subagents/test/unit/herdr-session-roots-codec.test.ts +63 -0
  372. package/dist/extensions/pi-subagents/test/unit/herdr-shell-command.test.ts +2 -2
  373. package/dist/extensions/pi-subagents/test/unit/herdr-status-bridge.test.ts +132 -0
  374. package/dist/extensions/pi-subagents/test/unit/host-command.test.ts +156 -0
  375. package/dist/extensions/pi-subagents/test/unit/host-step-status.test.ts +98 -0
  376. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +178 -26
  377. package/dist/extensions/pi-subagents/test/unit/index-segment.test.ts +2 -1
  378. package/dist/extensions/pi-subagents/test/unit/inspect-rpc.test.ts +21 -0
  379. package/dist/extensions/pi-subagents/test/unit/mcp-direct-tool-grant.test.ts +138 -0
  380. package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +1 -1
  381. package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +91 -0
  382. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +72 -7
  383. package/dist/extensions/pi-subagents/test/unit/mutation-evidence.test.ts +21 -0
  384. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +1 -0
  385. package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +20 -2
  386. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +129 -1
  387. package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +2 -2
  388. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +4 -0
  389. package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +358 -0
  390. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +574 -21
  391. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +109 -1
  392. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +71 -1
  393. package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +7 -7
  394. package/dist/extensions/pi-subagents/test/unit/pruned-fork.test.ts +214 -0
  395. package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +29 -8
  396. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +53 -0
  397. package/dist/extensions/pi-subagents/test/unit/result-delivery-ownership.test.ts +34 -0
  398. package/dist/extensions/pi-subagents/test/unit/result-files.test.ts +101 -3
  399. package/dist/extensions/pi-subagents/test/unit/retained-children.test.ts +1 -0
  400. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +10 -8
  401. package/dist/extensions/pi-subagents/test/unit/run-fanout-budget.test.ts +71 -1
  402. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +41 -7
  403. package/dist/extensions/pi-subagents/test/unit/runtime-agent-registration.test.ts +136 -2
  404. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +137 -0
  405. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +33 -12
  406. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +504 -1
  407. package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +8 -0
  408. package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +1 -1
  409. package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +12 -1
  410. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +3 -5
  411. package/dist/extensions/pi-subagents/test/unit/steering.test.ts +5 -6
  412. package/dist/extensions/pi-subagents/test/unit/subagent-action-recovery.test.ts +0 -8
  413. package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +5 -0
  414. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +157 -2
  415. package/dist/extensions/pi-subagents/test/unit/subagent-startup-retry.test.ts +1 -1
  416. package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +63 -4
  417. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +27 -23
  418. package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +44 -0
  419. package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +1 -0
  420. package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +7 -5
  421. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +106 -0
  422. package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +484 -9
  423. package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +38 -4
  424. package/dist/extensions/pi-subagents/test/unit/workflow-preflight.test.ts +155 -0
  425. package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +318 -0
  426. package/dist/extensions/pi-subagents/test/unit/workflow-resume-hint.test.ts +365 -0
  427. package/dist/extensions/pi-subagents/test/unit/worktree-cleanup-plan.test.ts +349 -0
  428. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +21 -0
  429. package/dist/extensions/pi-subagents/test/unit/writer-budget-guidance.test.ts +2 -7
  430. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/effect/index.ts +13 -0
  431. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/effect/rules/no-service-constructor-imports.ts +52 -0
  432. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/index.ts +41 -0
  433. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-chained-type-assertions.ts +77 -0
  434. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-conditional-empty-object-spread.ts +49 -0
  435. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-known-value-widening.ts +247 -0
  436. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-module-mocking.ts +91 -0
  437. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-object-parameters.ts +126 -0
  438. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-reflect-apply.ts +28 -0
  439. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-reflect-get.ts +28 -0
  440. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-runtime-typeof.ts +67 -0
  441. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-shape-in-symbol-names.ts +39 -0
  442. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-unknown-parameters.ts +83 -0
  443. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-unknown-returns.ts +115 -0
  444. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-unknown-type-aliases.ts +72 -0
  445. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-unsafe-dictionary-type.ts +134 -0
  446. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-widen-then-assert.ts +366 -0
  447. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/require-safety-comment-for-type-assertion.ts +62 -0
  448. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/shared/dictionary-types.ts +502 -0
  449. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/shared/lexical-type-parameters.ts +60 -0
  450. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/shared/reflect-method.ts +35 -0
  451. package/dist/extensions/pi-tool-display/tests/capabilities.test.ts +1 -1
  452. package/dist/extensions/pi-tool-display/tests/settings-inspector.test.ts +2 -2
  453. package/dist/extensions/pi-tool-display/tests/tool-overrides-mcp.test.ts +1 -1
  454. package/dist/extensions/pi-zentui/extensions/zentui/format.ts +2 -1
  455. package/dist/extensions/pi-zentui/test/format.test.ts +15 -1
  456. package/dist/modes/interactive/components/footer.js +2 -2
  457. package/dist/modes/interactive/interactive-mode.js +11 -11
  458. package/dist/skills/workflow/SKILL.md +65 -50
  459. package/package.json +112 -110
  460. package/dist/extensions/enable-readonly-tools.test.ts +0 -63
  461. package/dist/extensions/enable-readonly-tools.ts +0 -24
  462. package/dist/extensions/model-prompt-injector/config.json +0 -16
  463. package/dist/extensions/model-prompt-injector/index.test.ts +0 -102
  464. package/dist/extensions/model-prompt-injector/index.ts +0 -148
  465. package/dist/extensions/pi-subagents/src/runs/shared/turn-budget.ts +0 -98
  466. package/dist/extensions/pi-subagents/test/unit/turn-budget.test.ts +0 -250
@@ -4,7 +4,8 @@ import * as os from "node:os";
4
4
  import * as path from "node:path";
5
5
  import { afterEach, beforeEach, describe, it } from "node:test";
6
6
  import type { ExtensionAPI } from "@selesai/code";
7
- import { registerAgent } from "../../src/api/agents.ts";
7
+ import { RUNTIME_AGENT_REGISTER_EVENT, registerAgent, registerAgentViaEvents, type RuntimeAgentRegistrationRequest } from "../../src/api/agents.ts";
8
+ import { registerRuntimeAgentEventListener } from "../../src/agents/runtime-agent-events.ts";
8
9
  import { handleList } from "../../src/agents/agent-management.ts";
9
10
  import { discoverAgents, discoverAgentsAll } from "../../src/agents/agents.ts";
10
11
  import { clearRuntimeAgentsForPi, mergeRuntimeAgents } from "../../src/agents/runtime-agent-registry.ts";
@@ -24,6 +25,25 @@ function makePi(): ExtensionAPI {
24
25
  } as unknown as ExtensionAPI;
25
26
  }
26
27
 
28
+ function makeEventBus(): ExtensionAPI["events"] {
29
+ const handlers = new Map<string, Set<(data: unknown) => void>>();
30
+ return {
31
+ emit(channel, data) {
32
+ for (const handler of handlers.get(channel) ?? []) handler(data);
33
+ },
34
+ on(channel, handler) {
35
+ const listeners = handlers.get(channel) ?? new Set();
36
+ listeners.add(handler);
37
+ handlers.set(channel, listeners);
38
+ return () => listeners.delete(handler);
39
+ },
40
+ };
41
+ }
42
+
43
+ function makePiWithEvents(events: ExtensionAPI["events"]): ExtensionAPI {
44
+ return { on() {}, registerTool() {}, events } as unknown as ExtensionAPI;
45
+ }
46
+
27
47
  function writeProjectAgent(name: string, aliases: string[] = []): void {
28
48
  const filePath = path.join(tempProject, ".selesai", "agents", `${name}.md`);
29
49
  fs.mkdirSync(path.dirname(filePath), { recursive: true });
@@ -83,6 +103,103 @@ describe("runtime agent registration", () => {
83
103
  registration.dispose();
84
104
  });
85
105
 
106
+ it("accepts inheritGlobalContext in a runtime agent definition", () => {
107
+ const registration = registerAgent({
108
+ pi,
109
+ name: "runtime-global-helper",
110
+ definition: {
111
+ description: "Runtime global helper",
112
+ systemPrompt: "Help at runtime.",
113
+ inheritProjectContext: true,
114
+ inheritGlobalContext: true,
115
+ },
116
+ });
117
+
118
+ const agents = mergeRuntimeAgents(pi, discoverAgents(tempProject, "both")).agents;
119
+ const agent = agents.find((candidate) => candidate.name === "runtime-global-helper");
120
+ assert.equal(agent?.inheritProjectContext, true);
121
+ assert.equal(agent?.inheritGlobalContext, true);
122
+
123
+ registration.dispose();
124
+ });
125
+
126
+ it("registers through the owner runtime when consumer and owner API objects differ", () => {
127
+ const events = makeEventBus();
128
+ const ownerPi = makePiWithEvents(events);
129
+ const consumerPi = makePiWithEvents(events);
130
+ const unsubscribe = registerRuntimeAgentEventListener(ownerPi);
131
+ const registration = registerAgentViaEvents({
132
+ pi: consumerPi,
133
+ name: "runtime-event-helper",
134
+ definition: { description: "Event helper", systemPrompt: "Help through the owner." },
135
+ });
136
+
137
+ assert.equal(mergeRuntimeAgents(ownerPi, discoverAgents(tempProject, "both")).agents.some((agent) => agent.name === "runtime-event-helper"), true);
138
+ assert.equal(mergeRuntimeAgents(consumerPi, discoverAgents(tempProject, "both")).agents.some((agent) => agent.name === "runtime-event-helper"), false);
139
+ assert.throws(
140
+ () => registerAgentViaEvents({ pi: consumerPi, name: "runtime-event-helper", definition: { description: "Duplicate", systemPrompt: "Duplicate." } }),
141
+ /collides with runtime agent 'runtime-event-helper'/,
142
+ );
143
+
144
+ registration.dispose();
145
+ assert.equal(mergeRuntimeAgents(ownerPi, discoverAgents(tempProject, "both")).agents.some((agent) => agent.name === "runtime-event-helper"), false);
146
+ unsubscribe();
147
+ clearRuntimeAgentsForPi(ownerPi);
148
+ });
149
+
150
+ it("uses first-handler-wins semantics for duplicate owners", () => {
151
+ const events = makeEventBus();
152
+ const firstOwner = makePiWithEvents(events);
153
+ const secondOwner = makePiWithEvents(events);
154
+ const consumer = makePiWithEvents(events);
155
+ const unsubscribeFirst = registerRuntimeAgentEventListener(firstOwner);
156
+ const unsubscribeSecond = registerRuntimeAgentEventListener(secondOwner);
157
+
158
+ const registration = registerAgentViaEvents({
159
+ pi: consumer,
160
+ name: "first-owner-agent",
161
+ definition: { description: "First owner", systemPrompt: "Use the first owner." },
162
+ });
163
+ assert.equal(mergeRuntimeAgents(firstOwner, discoverAgents(tempProject, "both")).agents.some((agent) => agent.name === "first-owner-agent"), true);
164
+ assert.equal(mergeRuntimeAgents(secondOwner, discoverAgents(tempProject, "both")).agents.some((agent) => agent.name === "first-owner-agent"), false);
165
+
166
+ registration.dispose();
167
+ unsubscribeFirst();
168
+ unsubscribeSecond();
169
+ clearRuntimeAgentsForPi(firstOwner);
170
+ clearRuntimeAgentsForPi(secondOwner);
171
+ });
172
+
173
+ it("returns useful event registration errors and detects a missing owner", () => {
174
+ const events = makeEventBus();
175
+ const owner = makePiWithEvents(events);
176
+ const consumer = makePiWithEvents(events);
177
+ const unsubscribe = registerRuntimeAgentEventListener(owner);
178
+ const unsupported = { version: 2, name: "bad-version", definition: {} } as unknown as RuntimeAgentRegistrationRequest;
179
+ events.emit(RUNTIME_AGENT_REGISTER_EVENT, unsupported);
180
+ assert.equal(unsupported.result?.ok, false);
181
+ if (unsupported.result?.ok === false) assert.match(unsupported.result.error.message, /Unsupported runtime agent registration event version '2'/);
182
+
183
+ const malformed = { version: 1, name: "bad-definition" } as unknown as RuntimeAgentRegistrationRequest;
184
+ events.emit(RUNTIME_AGENT_REGISTER_EVENT, malformed);
185
+ assert.equal(malformed.result?.ok, false);
186
+ if (malformed.result?.ok === false) assert.match(malformed.result.error.message, /definition must be an object/i);
187
+ unsubscribe();
188
+ assert.throws(
189
+ () => registerAgentViaEvents({ pi: consumer, name: "no-owner", definition: { description: "Missing", systemPrompt: "Missing." } }),
190
+ /not installed, not ready, or does not support/,
191
+ );
192
+ const unsubscribeMalformed = events.on(RUNTIME_AGENT_REGISTER_EVENT, (raw) => {
193
+ (raw as { result?: unknown }).result = {};
194
+ });
195
+ assert.throws(
196
+ () => registerAgentViaEvents({ pi: consumer, name: "malformed-result", definition: { description: "Malformed", systemPrompt: "Malformed." } }),
197
+ /malformed runtime agent registration result/,
198
+ );
199
+ unsubscribeMalformed();
200
+ clearRuntimeAgentsForPi(owner);
201
+ });
202
+
86
203
  it("lists runtime agents for the matching Pi runtime", () => {
87
204
  registerAgent({
88
205
  pi,
@@ -96,6 +213,24 @@ describe("runtime agent registration", () => {
96
213
  });
97
214
 
98
215
  it("fails closed for builtin and duplicate runtime identities", () => {
216
+ assert.throws(
217
+ () => registerAgent({ pi, name: "claude-code", definition: { description: "Unsafe", systemPrompt: "Write.", runner: { type: "external-cli", adapter: "claude-code-writer", command: "claude" } } }),
218
+ /reserved for the read-only 'claude-code' adapter/,
219
+ );
220
+ assert.throws(
221
+ () => registerAgent({ pi, name: "runtime-writer", definition: { description: "Unsafe alias", systemPrompt: "Write.", aliases: ["claude-code"], runner: { type: "external-cli", adapter: "claude-code-writer", command: "claude" } } }),
222
+ /Selection name 'claude-code' is reserved/,
223
+ );
224
+ for (const [readOnly, writer, command] of [["codex-exec", "codex-exec-writer", "codex"], ["cursor-agent", "cursor-agent-writer", "cursor-agent"]] as const) {
225
+ assert.throws(
226
+ () => registerAgent({ pi, name: readOnly, definition: { description: "Unsafe", systemPrompt: "Write.", runner: { type: "external-cli", adapter: writer, command } } }),
227
+ /reserved for the read-only/,
228
+ );
229
+ assert.throws(
230
+ () => registerAgent({ pi, name: `runtime-${writer}`, definition: { description: "Unsafe alias", systemPrompt: "Write.", aliases: [readOnly], runner: { type: "external-cli", adapter: writer, command } } }),
231
+ /Selection name .* is reserved/,
232
+ );
233
+ }
99
234
  assert.throws(
100
235
  () => registerAgent({ pi, name: "worker", definition: { description: "Bad", systemPrompt: "Bad." } }),
101
236
  /Worker|builtin agent 'worker'|collides with builtin agent 'worker'/i,
@@ -110,7 +245,6 @@ describe("runtime agent registration", () => {
110
245
 
111
246
  it("rejects malformed nested runtime definition fields at registration", () => {
112
247
  const cases: Array<[string, Record<string, unknown>, RegExp]> = [
113
- ["defaultTurnBudget", { defaultTurnBudget: { maxTurns: 0 } }, /defaultTurnBudget\.maxTurns must be an integer >= 1/],
114
248
  ["defaultAcceptance", { defaultAcceptance: { level: "verified" } }, /defaultAcceptance\.verify must contain at least one runtime command/],
115
249
  ["runner", { runner: { type: "external-cli" } }, /external-cli runner requires a non-empty command string/],
116
250
  ["toolBudget", { toolBudget: { hard: 0 } }, /toolBudget\.hard must be an integer >= 1/],
@@ -1,4 +1,5 @@
1
1
  import assert from "node:assert/strict";
2
+ import { execFileSync } from "node:child_process";
2
3
  import * as fs from "node:fs";
3
4
  import * as os from "node:os";
4
5
  import * as path from "node:path";
@@ -56,6 +57,10 @@ afterEach(() => {
56
57
  for (const root of roots.splice(0)) fs.rmSync(root, { recursive: true, force: true });
57
58
  });
58
59
 
60
+ function git(cwd: string, args: string[]): void {
61
+ execFileSync("git", args, { cwd, stdio: "ignore" });
62
+ }
63
+
59
64
  function context(cwd: string, sessionId = "session-a"): ExtensionContext {
60
65
  return {
61
66
  cwd,
@@ -153,6 +158,28 @@ describe("project schedule management", () => {
153
158
  assert.match(text(shown), /Night review/);
154
159
  });
155
160
 
161
+ it("does not let completed one-shot schedules consume maxPending capacity", async () => {
162
+ const h = harness({ config: { scheduledRuns: { enabled: true, maxPending: 1 } } });
163
+ await h.manager.handleToolCall({ action: "schedule.create", id: "completed", at: "+1h", workflowScript: "return runs.run('main', { agent: 'worker' })" }, h.ctx);
164
+ h.clock.now += 3_600_000;
165
+ h.timers.fireAll();
166
+ await flush();
167
+ assert.equal(h.launches.length, 1);
168
+ const activeResult = await h.manager.handleToolCall({ action: "schedule.create", id: "active-blocked", at: "+2h", workflowScript: "return runs.run('main', { agent: 'worker' })" }, h.ctx);
169
+ assert.equal(activeResult.isError, true);
170
+ h.launches[0]!.resolve({ content: [{ type: "text", text: "Async" }], details: { mode: "single", results: [], asyncId: "completed-async" } });
171
+ await flush();
172
+ h.manager.handleAsyncCompletion({ runId: "completed-async", success: true });
173
+
174
+ const result = await h.manager.handleToolCall({ action: "schedule.create", id: "replacement", at: "+2h", workflowScript: "return runs.run('main', { agent: 'worker' })" }, h.ctx);
175
+ assert.equal(result.isError, undefined);
176
+ const completedDir = path.join(scheduledRunStorePath(h.ctx.cwd, undefined, path.join(h.root, "stores")), "completed");
177
+ assert.equal(fs.existsSync(path.join(completedDir, "history.json")), true);
178
+ assert.equal(fs.existsSync(path.join(completedDir, "events.jsonl")), true);
179
+ const completedHistory = await h.manager.handleToolCall({ action: "schedule.history", id: "completed" }, h.ctx);
180
+ assert.match(text(completedHistory), /completed.*async completed-async/);
181
+ });
182
+
156
183
  it("stores explicit cwd schedules in the target project", async () => {
157
184
  const h = harness();
158
185
  const target = path.join(h.root, "other-project");
@@ -360,6 +387,116 @@ describe("project schedule management", () => {
360
387
  assert.match(text(result), /resolves outside the real project/);
361
388
  assert.equal(fs.existsSync(path.join(outside, "schedules")), false);
362
389
  });
390
+
391
+ it("allows a default project schedule root through a shared Git worktree .pi symlink", async () => {
392
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), "pi-schedule-worktree-link-"));
393
+ roots.push(root);
394
+ const repository = path.join(root, "repository");
395
+ const worktree = path.join(repository, ".worktrees", "feature");
396
+ fs.mkdirSync(repository, { recursive: true });
397
+ git(repository, ["init"]);
398
+ git(repository, ["config", "user.email", "test@example.com"]);
399
+ git(repository, ["config", "user.name", "Test User"]);
400
+ fs.writeFileSync(path.join(repository, "tracked.txt"), "base\n", "utf-8");
401
+ git(repository, ["add", "tracked.txt"]);
402
+ git(repository, ["commit", "-m", "base"]);
403
+ fs.mkdirSync(path.dirname(worktree), { recursive: true });
404
+ git(repository, ["worktree", "add", "-b", "feature", worktree]);
405
+ fs.mkdirSync(path.join(repository, ".selesai"), { recursive: true });
406
+ fs.symlinkSync(path.join(repository, ".selesai"), path.join(worktree, ".selesai"), process.platform === "win32" ? "junction" : "dir");
407
+
408
+ const ctx = context(worktree);
409
+ const manager = createScheduledRunManager({
410
+ config: { scheduledRuns: { enabled: true } },
411
+ launch: async () => ({ content: [{ type: "text", text: "unused" }], details: { mode: "management", results: [] } }),
412
+ });
413
+ manager.bindSession(ctx);
414
+ const result = await manager.handleToolCall({ action: "schedule.create", id: "shared", every: "1h", workflowScript: "return 1" }, ctx);
415
+ assert.equal(result.isError, undefined);
416
+ assert.equal(fs.existsSync(path.join(worktree, ".pi-subagents", "schedules", "shared", "schedule.json")), true);
417
+ });
418
+
419
+ it("rejects a Git worktree .pi symlink outside the shared config root", () => {
420
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), "pi-schedule-worktree-escape-"));
421
+ roots.push(root);
422
+ const repository = path.join(root, "repository");
423
+ const worktree = path.join(repository, ".worktrees", "feature");
424
+ const outside = path.join(root, "outside");
425
+ fs.mkdirSync(repository, { recursive: true });
426
+ git(repository, ["init"]);
427
+ git(repository, ["config", "user.email", "test@example.com"]);
428
+ git(repository, ["config", "user.name", "Test User"]);
429
+ fs.writeFileSync(path.join(repository, "tracked.txt"), "base\n", "utf-8");
430
+ git(repository, ["add", "tracked.txt"]);
431
+ git(repository, ["commit", "-m", "base"]);
432
+ fs.mkdirSync(path.dirname(worktree), { recursive: true });
433
+ git(repository, ["worktree", "add", "-b", "feature", worktree]);
434
+ fs.mkdirSync(path.join(repository, ".selesai"), { recursive: true });
435
+ fs.mkdirSync(outside);
436
+ fs.symlinkSync(outside, path.join(worktree, ".selesai"), process.platform === "win32" ? "junction" : "dir");
437
+
438
+ const manager = createScheduledRunManager({
439
+ config: { scheduledRuns: { enabled: true } },
440
+ launch: async () => ({ content: [{ type: "text", text: "unused" }], details: { mode: "management", results: [] } }),
441
+ });
442
+ assert.doesNotThrow(() => manager.bindSession(context(worktree)));
443
+ assert.equal(fs.existsSync(path.join(outside, "subagents")), false);
444
+ });
445
+
446
+ it("rejects separate-git-dir primary checkout sharing without a registered root", () => {
447
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), "pi-schedule-separate-git-dir-"));
448
+ roots.push(root);
449
+ const repository = path.join(root, "repository");
450
+ const gitDir = path.join(root, "git-data", "metadata");
451
+ const worktree = path.join(root, "worktree");
452
+ fs.mkdirSync(repository, { recursive: true });
453
+ fs.mkdirSync(path.dirname(gitDir), { recursive: true });
454
+ git(repository, ["init", "--separate-git-dir", gitDir]);
455
+ git(repository, ["config", "user.email", "test@example.com"]);
456
+ git(repository, ["config", "user.name", "Test User"]);
457
+ fs.writeFileSync(path.join(repository, "tracked.txt"), "base\n", "utf-8");
458
+ git(repository, ["add", "tracked.txt"]);
459
+ git(repository, ["commit", "-m", "base"]);
460
+ git(repository, ["worktree", "add", "-b", "feature", worktree]);
461
+ const primaryConfig = path.join(repository, ".selesai");
462
+ fs.mkdirSync(primaryConfig, { recursive: true });
463
+ fs.symlinkSync(primaryConfig, path.join(worktree, ".selesai"), process.platform === "win32" ? "junction" : "dir");
464
+
465
+ const manager = createScheduledRunManager({
466
+ config: { scheduledRuns: { enabled: true } },
467
+ launch: async () => ({ content: [{ type: "text", text: "unused" }], details: { mode: "management", results: [] } }),
468
+ });
469
+ assert.doesNotThrow(() => manager.bindSession(context(worktree)));
470
+ assert.equal(fs.existsSync(path.join(primaryConfig, "subagents")), false);
471
+ });
472
+
473
+ it("rejects an unregistered checkout ancestor with the same Git directory", () => {
474
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), "pi-schedule-unregistered-git-dir-"));
475
+ roots.push(root);
476
+ const repository = path.join(root, "repository");
477
+ const worktree = path.join(repository, ".worktrees", "feature");
478
+ const outside = path.join(root, "outside");
479
+ fs.mkdirSync(repository, { recursive: true });
480
+ git(repository, ["init"]);
481
+ git(repository, ["config", "user.email", "test@example.com"]);
482
+ git(repository, ["config", "user.name", "Test User"]);
483
+ fs.writeFileSync(path.join(repository, "tracked.txt"), "base\n", "utf-8");
484
+ git(repository, ["add", "tracked.txt"]);
485
+ git(repository, ["commit", "-m", "base"]);
486
+ fs.mkdirSync(path.dirname(worktree), { recursive: true });
487
+ git(repository, ["worktree", "add", "-b", "feature", worktree]);
488
+ const outsideConfig = path.join(outside, ".selesai");
489
+ fs.mkdirSync(outsideConfig, { recursive: true });
490
+ fs.writeFileSync(path.join(outside, ".git"), `gitdir: ${path.join(repository, ".git")}\n`, "utf-8");
491
+ fs.symlinkSync(outsideConfig, path.join(worktree, ".selesai"), process.platform === "win32" ? "junction" : "dir");
492
+
493
+ const manager = createScheduledRunManager({
494
+ config: { scheduledRuns: { enabled: true } },
495
+ launch: async () => ({ content: [{ type: "text", text: "unused" }], details: { mode: "management", results: [] } }),
496
+ });
497
+ assert.doesNotThrow(() => manager.bindSession(context(worktree)));
498
+ assert.equal(fs.existsSync(path.join(outsideConfig, "subagents")), false);
499
+ });
363
500
  });
364
501
 
365
502
  describe("recurring schedule execution", () => {
@@ -29,6 +29,12 @@ interface SubagentParamsSchema {
29
29
  minLength?: number;
30
30
  description?: string;
31
31
  };
32
+ workflowScriptPath?: {
33
+ type?: string;
34
+ minLength?: number;
35
+ description?: string;
36
+ };
37
+ preflight?: JsonSchemaNode;
32
38
  chatProgress?: {
33
39
  type?: string;
34
40
  enum?: string[];
@@ -176,17 +182,33 @@ describe("SubagentParams schema", { skip: !schemasAvailable ? "typebox not avail
176
182
  assert.match(description, /else fresh/);
177
183
  });
178
184
 
179
- it("exposes a concise trusted inline workflow script mode", () => {
185
+ it("exposes trusted inline and file workflow script modes", () => {
180
186
  const workflowScript = SubagentParams?.properties?.workflowScript;
181
187
  assert.equal(workflowScript?.type, "string");
182
188
  assert.equal(workflowScript?.minLength, 1);
183
189
  assert.match(String(workflowScript?.description ?? ""), /runs\.run/);
190
+ assert.match(String(workflowScript?.description ?? ""), /runs\.lanes\(\[\{key,stages:/);
191
+ assert.match(String(workflowScript?.description ?? ""), /first stages run together.*later stages sequence per lane/i);
192
+ assert.match(String(workflowScript?.description ?? ""), /Each workflow key identifies one result lane.*new stable workflow key.*retained resume pass/i);
184
193
  assert.match(String(workflowScript?.description ?? ""), /await runs\.all\(\[\{key, agent, task\}, \.\.\.\]\)/);
185
194
  assert.match(String(workflowScript?.description ?? ""), /do not read \.output from unawaited runs\.run launches/i);
186
195
  assert.match(String(workflowScript?.description ?? ""), /advanced rolling fanout/);
187
196
  assert.match(String(workflowScript?.description ?? ""), /sequential and parallel phases dynamically/i);
188
197
  assert.match(String(workflowScript?.description ?? ""), /worktree:true/i);
189
198
  assert.match(String(workflowScript?.description ?? ""), /no filesystem, shell, Pi tools, or host globals/i);
199
+ const workflowScriptPath = SubagentParams?.properties?.workflowScriptPath;
200
+ assert.equal(workflowScriptPath?.type, "string");
201
+ assert.equal(workflowScriptPath?.minLength, 1);
202
+ assert.match(String(workflowScriptPath?.description ?? ""), /mutually exclusive with workflowScript/i);
203
+ assert.match(String(workflowScriptPath?.description ?? ""), /request cwd/i);
204
+ assert.match(String(workflowScriptPath?.description ?? ""), /host reads the file/i);
205
+ const preflight = SubagentParams?.properties?.preflight;
206
+ assert.equal(preflight?.type, "object");
207
+ assert.equal(preflight?.additionalProperties, false);
208
+ assert.match(String(preflight?.description ?? ""), /display-only/i);
209
+ assert.equal((preflight?.properties as JsonSchemaNode | undefined)?.version?.minimum, 1);
210
+ assert.equal((preflight?.properties as JsonSchemaNode | undefined)?.version?.maximum, 1);
211
+ assert.equal((preflight?.properties as JsonSchemaNode | undefined)?.lanes?.maxItems, 64);
190
212
  const chatProgress = SubagentParams?.properties?.chatProgress;
191
213
  assert.equal(chatProgress?.type, "string");
192
214
  assert.deepEqual(chatProgress?.enum, ["auto", "off", "live-card"]);
@@ -209,14 +231,15 @@ describe("SubagentParams schema", { skip: !schemasAvailable ? "typebox not avail
209
231
  assert.match(String((properties?.agent as JsonSchemaNode | undefined)?.description ?? ""), /one-child/i);
210
232
  assert.equal(properties?.clarify, undefined, "clarify should not be model-facing");
211
233
  assert.ok(properties?.output, "output remains a workflow child default");
234
+ assert.match(String(properties?.output?.description ?? ""), /Relative workflow child paths use managed artifact routing/i);
235
+ assert.match(String(properties?.output?.description ?? ""), /Task filename prose is not an output declaration/i);
236
+ assert.match(String(properties?.output?.description ?? ""), /outputReference.*outputPathMapping.*artifactPaths/i);
212
237
  });
213
238
 
214
239
  it("omits removed legacy and workflow-child-only fields", () => {
215
240
  for (const name of ["tasks", "chain", "concurrency", "chainDir", "step", "schedule", "scheduleName", "resume"]) {
216
241
  assert.equal((SubagentParams?.properties as Record<string, unknown> | undefined)?.[name], undefined, `${name} should not be public`);
217
242
  }
218
-
219
- assert.doesNotMatch(JSON.stringify(SubagentParams), /append-step|approve-checkpoint|reject-checkpoint|scheduleName/);
220
243
  });
221
244
 
222
245
  it("allows runtime validation of management and control action strings", () => {
@@ -227,7 +250,7 @@ describe("SubagentParams schema", { skip: !schemasAvailable ? "typebox not avail
227
250
  assert.equal(actionSchema.enum, undefined);
228
251
  const description = String(actionSchema.description ?? "");
229
252
  assert.match(description, /Optional management\/control action/);
230
- assert.match(description, /Omit this field for structured single-child or workflowScript execution/);
253
+ assert.match(description, /Omit this field for structured single-child or workflow execution/);
231
254
  assert.match(description, /use it only for management\/control actions/);
232
255
  assert.doesNotMatch(description, /orchestration\./);
233
256
  });
@@ -243,7 +266,7 @@ describe("SubagentParams schema", { skip: !schemasAvailable ? "typebox not avail
243
266
  assert.equal(version.enum, undefined);
244
267
  });
245
268
 
246
- it("documents workflow timeout aliases and turn budget", () => {
269
+ it("documents workflow timeout aliases and omits removed turn budgets", () => {
247
270
  const timeoutSchema = SubagentParams?.properties?.timeoutMs;
248
271
  const maxRuntimeSchema = SubagentParams?.properties?.maxRuntimeMs;
249
272
  const turnBudgetSchema = SubagentParams?.properties?.turnBudget;
@@ -260,8 +283,7 @@ describe("SubagentParams schema", { skip: !schemasAvailable ? "typebox not avail
260
283
  assert.match(String(maxRuntimeSchema.description ?? ""), /foreground and single async runs/i);
261
284
  assert.match(String(maxRuntimeSchema.description ?? ""), /use config timeoutMs, else 30m/i);
262
285
  assert.match(String(maxRuntimeSchema.description ?? ""), /async composites have no default parent deadline/i);
263
- assert.equal(turnBudgetSchema?.properties?.maxTurns?.minimum, 1);
264
- assert.equal(turnBudgetSchema?.properties?.graceTurns?.minimum, 0);
286
+ assert.equal(turnBudgetSchema, undefined);
265
287
  assert.equal(toolBudgetSchema?.properties?.soft?.minimum, 1);
266
288
  assert.equal(toolBudgetSchema?.properties?.hard?.minimum, 1);
267
289
  });
@@ -328,9 +350,12 @@ describe("SubagentParams schema", { skip: !schemasAvailable ? "typebox not avail
328
350
  it("exposes tolerant wait mode on subagent_wait", () => {
329
351
  const properties = SubagentWaitParams?.properties as Record<string, JsonSchemaNode> | undefined;
330
352
  const stopOnAttention = properties?.stopOnAttention;
353
+ const timeoutMs = properties?.timeoutMs;
331
354
  assert.ok(stopOnAttention, "stopOnAttention schema should exist");
332
355
  assert.equal(stopOnAttention.type, "boolean");
333
356
  assert.match(String(stopOnAttention.description ?? ""), /idle or long-thinking attention/);
357
+ assert.match(String(timeoutMs?.description ?? ""), /waitTool\.defaultTimeoutMs/);
358
+ assert.match(String(timeoutMs?.description ?? ""), /non-error active-work result/);
334
359
  });
335
360
 
336
361
  it("does not emit description-only schema nodes", () => {
@@ -524,6 +549,7 @@ describe("SubagentParams schema", { skip: !schemasAvailable ? "typebox not avail
524
549
  const validValues = [
525
550
  { skill: "review" },
526
551
  { workflowScript: "return await runs.run(\"one\", {agent: \"reviewer\", task: \"check\"})" },
552
+ { workflowScriptPath: "workflows/review.js" },
527
553
  { skill: false },
528
554
  { action: "get", agent: "worker" },
529
555
  { workflowScript: "return runs.run('main', { agent: 'worker', task: 'Fix', acceptance: false })", timeoutMs: 1000 },
@@ -544,11 +570,6 @@ describe("SubagentParams schema", { skip: !schemasAvailable ? "typebox not avail
544
570
  { agent: "worker", task: "Fix", acceptance: true },
545
571
  { config: [] },
546
572
  { config: null },
547
- { agent: "worker", task: "Fix", turnBudget: { maxTurns: 0 } },
548
- { agent: "worker", task: "Fix", turnBudget: { maxTurns: 5, graceTurns: -1 } },
549
- { agent: "worker", task: "Fix", turnBudget: { maxTurns: 1.5 } },
550
- { agent: "worker", task: "Fix", turnBudget: { graceTurns: 1 } },
551
- { agent: "worker", task: "Fix", turnBudget: { maxTurns: 5, graceTurns: 1, extra: true } },
552
573
  { agent: "worker", task: "Fix", toolBudget: { hard: 0 } },
553
574
  { agent: "worker", task: "Fix", toolBudget: { hard: 3, soft: 0 } },
554
575
  { agent: "worker", task: "Fix", toolBudget: { hard: 3, block: [123] } },