@selesai/code 0.13.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 (461) hide show
  1. package/CHANGELOG.md +12 -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/extensions/ascii.txt +9 -0
  9. package/dist/extensions/package.json +1 -2
  10. package/dist/extensions/pi-hermes-memory/CHANGELOG.md +371 -0
  11. package/dist/extensions/pi-hermes-memory/LICENSE +21 -0
  12. package/dist/extensions/pi-hermes-memory/README.md +643 -0
  13. package/dist/extensions/pi-hermes-memory/docs/0.1/TASKS.md +197 -0
  14. package/dist/extensions/pi-hermes-memory/docs/0.2/PLAN.md +290 -0
  15. package/dist/extensions/pi-hermes-memory/docs/0.2/TASKS.md +134 -0
  16. package/dist/extensions/pi-hermes-memory/docs/0.2/TEST-PLAN.md +216 -0
  17. package/dist/extensions/pi-hermes-memory/docs/0.3/PLAN.md +330 -0
  18. package/dist/extensions/pi-hermes-memory/docs/0.3/TASKS.md +125 -0
  19. package/dist/extensions/pi-hermes-memory/docs/0.4/PLAN.md +160 -0
  20. package/dist/extensions/pi-hermes-memory/docs/0.4/TASKS.md +113 -0
  21. package/dist/extensions/pi-hermes-memory/docs/0.6/CHANGELOG.md +57 -0
  22. package/dist/extensions/pi-hermes-memory/docs/0.6/PLAN.md +202 -0
  23. package/dist/extensions/pi-hermes-memory/docs/0.6/TASKS.md +144 -0
  24. package/dist/extensions/pi-hermes-memory/docs/0.7/PLAN.md +349 -0
  25. package/dist/extensions/pi-hermes-memory/docs/0.7/TASKS.md +110 -0
  26. package/dist/extensions/pi-hermes-memory/docs/PUBLISHING.md +149 -0
  27. package/dist/extensions/pi-hermes-memory/docs/ROADMAP.md +468 -0
  28. package/dist/extensions/pi-hermes-memory/docs/images/memory-architecture.svg +1 -0
  29. package/dist/extensions/pi-hermes-memory/docs/images/pi-logo.svg +22 -0
  30. package/dist/extensions/pi-hermes-memory/docs/images/pi_memory.png +0 -0
  31. package/dist/extensions/pi-hermes-memory/docs/images/pi_memory.svg +19 -0
  32. package/dist/extensions/pi-hermes-memory/docs/images/security-flow.svg +1 -0
  33. package/dist/extensions/pi-hermes-memory/docs/images/session-lifecycle.svg +1 -0
  34. package/dist/extensions/pi-hermes-memory/docs/images/source-architecture.svg +1 -0
  35. package/dist/extensions/pi-hermes-memory/docs/mermaid/memory-architecture.mmd +49 -0
  36. package/dist/extensions/pi-hermes-memory/docs/mermaid/security-flow.mmd +40 -0
  37. package/dist/extensions/pi-hermes-memory/docs/mermaid/session-lifecycle.mmd +56 -0
  38. package/dist/extensions/pi-hermes-memory/docs/mermaid/source-architecture.mmd +54 -0
  39. package/dist/extensions/pi-hermes-memory/package-lock.json +3799 -0
  40. package/dist/extensions/pi-hermes-memory/package.json +66 -0
  41. package/dist/extensions/pi-hermes-memory/scripts/check-min-sdk.mjs +99 -0
  42. package/dist/extensions/pi-hermes-memory/scripts/ensure-dev.mjs +57 -0
  43. package/dist/extensions/pi-hermes-memory/src/auto-consolidation-warning.ts +6 -0
  44. package/dist/extensions/pi-hermes-memory/src/config.ts +178 -0
  45. package/dist/extensions/pi-hermes-memory/src/constants.ts +424 -0
  46. package/dist/extensions/pi-hermes-memory/src/extension-root-migration.ts +639 -0
  47. package/dist/extensions/pi-hermes-memory/src/handlers/auto-consolidate.ts +401 -0
  48. package/dist/extensions/pi-hermes-memory/src/handlers/background-review.ts +297 -0
  49. package/dist/extensions/pi-hermes-memory/src/handlers/child-process-watchdog.mjs +90 -0
  50. package/dist/extensions/pi-hermes-memory/src/handlers/correction-detector.ts +300 -0
  51. package/dist/extensions/pi-hermes-memory/src/handlers/index-sessions.ts +86 -0
  52. package/dist/extensions/pi-hermes-memory/src/handlers/insights.ts +78 -0
  53. package/dist/extensions/pi-hermes-memory/src/handlers/interview.ts +37 -0
  54. package/dist/extensions/pi-hermes-memory/src/handlers/learn-memory.ts +186 -0
  55. package/dist/extensions/pi-hermes-memory/src/handlers/message-parts.ts +27 -0
  56. package/dist/extensions/pi-hermes-memory/src/handlers/pi-child-process.ts +485 -0
  57. package/dist/extensions/pi-hermes-memory/src/handlers/preview-context.ts +105 -0
  58. package/dist/extensions/pi-hermes-memory/src/handlers/review-memory-ops.ts +506 -0
  59. package/dist/extensions/pi-hermes-memory/src/handlers/session-backfill.ts +145 -0
  60. package/dist/extensions/pi-hermes-memory/src/handlers/session-flush.ts +151 -0
  61. package/dist/extensions/pi-hermes-memory/src/handlers/session-live-index.ts +94 -0
  62. package/dist/extensions/pi-hermes-memory/src/handlers/skills-command.ts +1334 -0
  63. package/dist/extensions/pi-hermes-memory/src/handlers/standing-pin.ts +111 -0
  64. package/dist/extensions/pi-hermes-memory/src/handlers/switch-project.ts +75 -0
  65. package/dist/extensions/pi-hermes-memory/src/handlers/sync-markdown-memories.ts +266 -0
  66. package/dist/extensions/pi-hermes-memory/src/index.ts +378 -0
  67. package/dist/extensions/pi-hermes-memory/src/lifecycle-timing.ts +54 -0
  68. package/dist/extensions/pi-hermes-memory/src/paths.ts +61 -0
  69. package/dist/extensions/pi-hermes-memory/src/project-context.ts +13 -0
  70. package/dist/extensions/pi-hermes-memory/src/project-memory-migration.ts +93 -0
  71. package/dist/extensions/pi-hermes-memory/src/project.ts +157 -0
  72. package/dist/extensions/pi-hermes-memory/src/prompt-context.ts +55 -0
  73. package/dist/extensions/pi-hermes-memory/src/store/atomic-lock-coordinator.ts +375 -0
  74. package/dist/extensions/pi-hermes-memory/src/store/canonical-storage-path.ts +54 -0
  75. package/dist/extensions/pi-hermes-memory/src/store/content-scanner.ts +101 -0
  76. package/dist/extensions/pi-hermes-memory/src/store/db.ts +1180 -0
  77. package/dist/extensions/pi-hermes-memory/src/store/fts-query.ts +101 -0
  78. package/dist/extensions/pi-hermes-memory/src/store/markdown-mutation-lock.ts +38 -0
  79. package/dist/extensions/pi-hermes-memory/src/store/memory-lookup.ts +24 -0
  80. package/dist/extensions/pi-hermes-memory/src/store/memory-store.ts +1191 -0
  81. package/dist/extensions/pi-hermes-memory/src/store/recovery-maintenance.ts +66 -0
  82. package/dist/extensions/pi-hermes-memory/src/store/schema.ts +118 -0
  83. package/dist/extensions/pi-hermes-memory/src/store/session-anchor-search.ts +472 -0
  84. package/dist/extensions/pi-hermes-memory/src/store/session-indexer.ts +511 -0
  85. package/dist/extensions/pi-hermes-memory/src/store/session-parser.ts +213 -0
  86. package/dist/extensions/pi-hermes-memory/src/store/session-search.ts +234 -0
  87. package/dist/extensions/pi-hermes-memory/src/store/skill-store.ts +950 -0
  88. package/dist/extensions/pi-hermes-memory/src/store/skill-utils.ts +133 -0
  89. package/dist/extensions/pi-hermes-memory/src/store/sqlite-memory-store.ts +1002 -0
  90. package/dist/extensions/pi-hermes-memory/src/store/sqlite-native.ts +241 -0
  91. package/dist/extensions/pi-hermes-memory/src/store/standing-instructions.ts +247 -0
  92. package/dist/extensions/pi-hermes-memory/src/tools/memory-search-tool.ts +95 -0
  93. package/dist/extensions/pi-hermes-memory/src/tools/memory-tool.ts +469 -0
  94. package/dist/extensions/pi-hermes-memory/src/tools/session-search-tool.ts +246 -0
  95. package/dist/extensions/pi-hermes-memory/src/tools/shared-output-view.ts +170 -0
  96. package/dist/extensions/pi-hermes-memory/src/tools/skill-tool.ts +333 -0
  97. package/dist/extensions/pi-hermes-memory/src/tools/tool-result-views.ts +105 -0
  98. package/dist/extensions/pi-hermes-memory/src/types.ts +214 -0
  99. package/dist/extensions/pi-hermes-memory/tests/config.test.ts +434 -0
  100. package/dist/extensions/pi-hermes-memory/tests/extension-root-migration.test.ts +368 -0
  101. package/dist/extensions/pi-hermes-memory/tests/handlers/auto-consolidate.test.ts +984 -0
  102. package/dist/extensions/pi-hermes-memory/tests/handlers/background-review.test.ts +950 -0
  103. package/dist/extensions/pi-hermes-memory/tests/handlers/correction-detector.test.ts +671 -0
  104. package/dist/extensions/pi-hermes-memory/tests/handlers/insights.test.ts +157 -0
  105. package/dist/extensions/pi-hermes-memory/tests/handlers/interview.test.ts +127 -0
  106. package/dist/extensions/pi-hermes-memory/tests/handlers/pi-child-process.test.ts +905 -0
  107. package/dist/extensions/pi-hermes-memory/tests/handlers/preview-context.test.ts +152 -0
  108. package/dist/extensions/pi-hermes-memory/tests/handlers/prompt-context.test.ts +166 -0
  109. package/dist/extensions/pi-hermes-memory/tests/handlers/resources-discover.test.ts +71 -0
  110. package/dist/extensions/pi-hermes-memory/tests/handlers/review-memory-ops.test.ts +614 -0
  111. package/dist/extensions/pi-hermes-memory/tests/handlers/session-backfill.test.ts +192 -0
  112. package/dist/extensions/pi-hermes-memory/tests/handlers/session-flush.test.ts +677 -0
  113. package/dist/extensions/pi-hermes-memory/tests/handlers/session-live-index.test.ts +225 -0
  114. package/dist/extensions/pi-hermes-memory/tests/handlers/skills-command.test.ts +827 -0
  115. package/dist/extensions/pi-hermes-memory/tests/handlers/standing-pin.test.ts +134 -0
  116. package/dist/extensions/pi-hermes-memory/tests/handlers/sync-markdown-memories.test.ts +491 -0
  117. package/dist/extensions/pi-hermes-memory/tests/handlers/system-prompt.test.ts +199 -0
  118. package/dist/extensions/pi-hermes-memory/tests/handlers/thinking-max.test.ts +64 -0
  119. package/dist/extensions/pi-hermes-memory/tests/index.test.ts +30 -0
  120. package/dist/extensions/pi-hermes-memory/tests/integration/flow.test.ts +126 -0
  121. package/dist/extensions/pi-hermes-memory/tests/lifecycle-timing.test.ts +76 -0
  122. package/dist/extensions/pi-hermes-memory/tests/paths.test.ts +23 -0
  123. package/dist/extensions/pi-hermes-memory/tests/project-memory-migration.test.ts +80 -0
  124. package/dist/extensions/pi-hermes-memory/tests/project-rebinding.test.ts +115 -0
  125. package/dist/extensions/pi-hermes-memory/tests/project.test.ts +120 -0
  126. package/dist/extensions/pi-hermes-memory/tests/run-all-timeout.test.ts +107 -0
  127. package/dist/extensions/pi-hermes-memory/tests/run-all.sh +45 -0
  128. package/dist/extensions/pi-hermes-memory/tests/store/atomic-lock-coordinator.test.ts +381 -0
  129. package/dist/extensions/pi-hermes-memory/tests/store/content-scanner.test.ts +388 -0
  130. package/dist/extensions/pi-hermes-memory/tests/store/db.test.ts +1046 -0
  131. package/dist/extensions/pi-hermes-memory/tests/store/markdown-mutation-lock.test.ts +34 -0
  132. package/dist/extensions/pi-hermes-memory/tests/store/memory-store.test.ts +2150 -0
  133. package/dist/extensions/pi-hermes-memory/tests/store/recovery-maintenance.test.ts +170 -0
  134. package/dist/extensions/pi-hermes-memory/tests/store/session-anchor-search.test.ts +210 -0
  135. package/dist/extensions/pi-hermes-memory/tests/store/session-indexer.test.ts +643 -0
  136. package/dist/extensions/pi-hermes-memory/tests/store/session-parser.test.ts +282 -0
  137. package/dist/extensions/pi-hermes-memory/tests/store/session-search.test.ts +287 -0
  138. package/dist/extensions/pi-hermes-memory/tests/store/skill-store.test.ts +678 -0
  139. package/dist/extensions/pi-hermes-memory/tests/store/skill-utils.test.ts +21 -0
  140. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-lazy-load.test.ts +78 -0
  141. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-memory-store.test.ts +543 -0
  142. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-native.test.ts +164 -0
  143. package/dist/extensions/pi-hermes-memory/tests/store/standing-instructions.test.ts +171 -0
  144. package/dist/extensions/pi-hermes-memory/tests/tools/memory-search-tool.test.ts +84 -0
  145. package/dist/extensions/pi-hermes-memory/tests/tools/memory-tool.test.ts +709 -0
  146. package/dist/extensions/pi-hermes-memory/tests/tools/session-search-tool.test.ts +345 -0
  147. package/dist/extensions/pi-hermes-memory/tests/tools/shared-output-view.test.ts +362 -0
  148. package/dist/extensions/pi-hermes-memory/tests/tools/skill-tool.test.ts +478 -0
  149. package/dist/extensions/pi-hermes-memory/tests/tools/tool-result-renderer-wiring.test.ts +40 -0
  150. package/dist/extensions/pi-hermes-memory/tsconfig.json +19 -0
  151. package/dist/extensions/pi-subagents/.oxlintrc.json +43 -0
  152. package/dist/extensions/pi-subagents/AGENTS.md +5 -0
  153. package/dist/extensions/pi-subagents/CHANGELOG.md +157 -0
  154. package/dist/extensions/pi-subagents/README.md +12 -6
  155. package/dist/extensions/pi-subagents/VISION.md +81 -0
  156. package/dist/extensions/pi-subagents/agents/claude-code-writer.md +15 -0
  157. package/dist/extensions/pi-subagents/agents/claude-code.md +15 -0
  158. package/dist/extensions/pi-subagents/agents/codex-exec-writer.md +15 -0
  159. package/dist/extensions/pi-subagents/agents/codex-exec.md +15 -0
  160. package/dist/extensions/pi-subagents/agents/cursor-agent-writer.md +14 -0
  161. package/dist/extensions/pi-subagents/agents/cursor-agent.md +14 -0
  162. package/dist/extensions/pi-subagents/agents/reviewer.md +1 -3
  163. package/dist/extensions/pi-subagents/docs/agents.md +488 -0
  164. package/dist/extensions/pi-subagents/docs/configuration.md +46 -9
  165. package/dist/extensions/pi-subagents/docs/extension-api.md +42 -3
  166. package/dist/extensions/pi-subagents/docs/models.md +27 -4
  167. package/dist/extensions/pi-subagents/docs/observability.md +10 -9
  168. package/dist/extensions/pi-subagents/docs/tool-reference.md +102 -6
  169. package/dist/extensions/pi-subagents/docs/workflows.md +135 -0
  170. package/dist/extensions/pi-subagents/package-lock.json +389 -2
  171. package/dist/extensions/pi-subagents/package.json +3 -1
  172. package/dist/extensions/pi-subagents/prompts/review-loop.md +2 -2
  173. package/dist/extensions/pi-subagents/skills/council-mode/SKILL.md +1 -1
  174. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +3 -1
  175. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +7 -3
  176. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +2 -2
  177. package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +26 -5
  178. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +41 -22
  179. package/dist/extensions/pi-subagents/src/agents/agent-refinements.ts +4 -4
  180. package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +9 -2
  181. package/dist/extensions/pi-subagents/src/agents/agents.ts +322 -75
  182. package/dist/extensions/pi-subagents/src/agents/builtin-names.ts +6 -0
  183. package/dist/extensions/pi-subagents/src/agents/runtime-agent-events.ts +70 -0
  184. package/dist/extensions/pi-subagents/src/agents/runtime-agent-registry.ts +27 -20
  185. package/dist/extensions/pi-subagents/src/api/agents.ts +10 -5
  186. package/dist/extensions/pi-subagents/src/api/background-work.ts +5 -1
  187. package/dist/extensions/pi-subagents/src/api/delegation.ts +0 -7
  188. package/dist/extensions/pi-subagents/src/api/preflight.ts +34 -12
  189. package/dist/extensions/pi-subagents/src/extension/config.ts +70 -0
  190. package/dist/extensions/pi-subagents/src/extension/doctor.ts +3 -3
  191. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +5 -3
  192. package/dist/extensions/pi-subagents/src/extension/index.ts +83 -30
  193. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +44 -15
  194. package/dist/extensions/pi-subagents/src/extension/rpc.ts +55 -19
  195. package/dist/extensions/pi-subagents/src/extension/schemas.ts +41 -15
  196. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +28 -31
  197. package/dist/extensions/pi-subagents/src/inspectors/herdr/actions.ts +2 -1
  198. package/dist/extensions/pi-subagents/src/inspectors/herdr/inspector-runner.ts +2 -10
  199. package/dist/extensions/pi-subagents/src/inspectors/herdr/session-roots-codec.ts +42 -0
  200. package/dist/extensions/pi-subagents/src/integrations/herdr-status.ts +51 -3
  201. package/dist/extensions/pi-subagents/src/intercom/result-intercom.ts +2 -0
  202. package/dist/extensions/pi-subagents/src/profiles/profiles.ts +5 -6
  203. package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +77 -10
  204. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +176 -53
  205. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +19 -12
  206. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +29 -27
  207. package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +20 -3
  208. package/dist/extensions/pi-subagents/src/runs/background/async-status-snapshot.ts +23 -261
  209. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +73 -7
  210. package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +8 -3
  211. package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +74 -8
  212. package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +37 -21
  213. package/dist/extensions/pi-subagents/src/runs/background/inspect-rpc.ts +8 -8
  214. package/dist/extensions/pi-subagents/src/runs/background/notify.ts +184 -9
  215. package/dist/extensions/pi-subagents/src/runs/background/result-delivery-ownership.ts +45 -0
  216. package/dist/extensions/pi-subagents/src/runs/background/result-files.ts +28 -14
  217. package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +38 -15
  218. package/dist/extensions/pi-subagents/src/runs/background/resume-guidance.ts +1 -1
  219. package/dist/extensions/pi-subagents/src/runs/background/retained-children.ts +1 -1
  220. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +50 -13
  221. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +93 -8
  222. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +10 -4
  223. package/dist/extensions/pi-subagents/src/runs/background/steering.ts +4 -14
  224. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +549 -377
  225. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +58 -10
  226. package/dist/extensions/pi-subagents/src/runs/background/terminal-run-index.ts +1 -1
  227. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +26 -1
  228. package/dist/extensions/pi-subagents/src/runs/background/wait-config.ts +23 -9
  229. package/dist/extensions/pi-subagents/src/runs/background/wait-tool.ts +9 -2
  230. package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +2 -2
  231. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +204 -129
  232. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +9 -0
  233. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +23 -1
  234. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +773 -311
  235. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +140 -115
  236. package/dist/extensions/pi-subagents/src/runs/shared/abort-recovery.ts +119 -0
  237. package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +463 -0
  238. package/dist/extensions/pi-subagents/src/runs/shared/child-identity.ts +19 -4
  239. package/dist/extensions/pi-subagents/src/runs/shared/child-launch-plan.ts +151 -0
  240. package/dist/extensions/pi-subagents/src/runs/shared/child-protocol.ts +21 -7
  241. package/dist/extensions/pi-subagents/src/runs/shared/claude-code-adapter.ts +129 -0
  242. package/dist/extensions/pi-subagents/src/runs/shared/codex-exec-adapter.ts +129 -0
  243. package/dist/extensions/pi-subagents/src/runs/shared/completion-evidence.ts +89 -0
  244. package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +5 -4
  245. package/dist/extensions/pi-subagents/src/runs/shared/cursor-agent-adapter.ts +114 -0
  246. package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +3 -3
  247. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-contract.ts +167 -0
  248. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-preflight.ts +122 -0
  249. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-runner.ts +348 -55
  250. package/dist/extensions/pi-subagents/src/runs/shared/fast-mode-extension.ts +5 -5
  251. package/dist/extensions/pi-subagents/src/runs/shared/host-step-status.ts +230 -0
  252. package/dist/extensions/pi-subagents/src/runs/shared/lane-metadata.ts +105 -0
  253. package/dist/extensions/pi-subagents/src/runs/shared/launch-cwd.ts +16 -0
  254. package/dist/extensions/pi-subagents/src/runs/shared/long-running-guard.ts +2 -1
  255. package/dist/extensions/pi-subagents/src/runs/shared/mcp-config-sources.ts +422 -0
  256. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +221 -158
  257. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-grant.ts +197 -0
  258. package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +69 -7
  259. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +47 -6
  260. package/dist/extensions/pi-subagents/src/runs/shared/mutation-evidence.ts +7 -2
  261. package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +9 -3
  262. package/dist/extensions/pi-subagents/src/runs/shared/nested-render.ts +9 -5
  263. package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +419 -7
  264. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +15 -1
  265. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +81 -8
  266. package/dist/extensions/pi-subagents/src/runs/shared/process-signal.ts +13 -0
  267. package/dist/extensions/pi-subagents/src/runs/shared/run-history.ts +21 -1
  268. package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +44 -4
  269. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +98 -13
  270. package/dist/extensions/pi-subagents/src/runs/shared/subagent-startup-retry.ts +1 -1
  271. package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-plan.ts +847 -0
  272. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +18 -0
  273. package/dist/extensions/pi-subagents/src/shared/child-session-name.ts +46 -0
  274. package/dist/extensions/pi-subagents/src/shared/extension-context.ts +24 -0
  275. package/dist/extensions/pi-subagents/src/shared/fork-context.ts +21 -0
  276. package/dist/extensions/pi-subagents/src/shared/formatters.ts +18 -3
  277. package/dist/extensions/pi-subagents/src/shared/launch-contract.ts +5 -1
  278. package/dist/extensions/pi-subagents/src/shared/pruned-fork.ts +450 -0
  279. package/dist/extensions/pi-subagents/src/shared/session-file-trust.ts +19 -0
  280. package/dist/extensions/pi-subagents/src/shared/session-tokens.ts +14 -3
  281. package/dist/extensions/pi-subagents/src/shared/settings.ts +19 -105
  282. package/dist/extensions/pi-subagents/src/shared/shortcuts.ts +17 -0
  283. package/dist/extensions/pi-subagents/src/shared/types.ts +359 -40
  284. package/dist/extensions/pi-subagents/src/shared/utils.ts +41 -84
  285. package/dist/extensions/pi-subagents/src/shared/workflow-child-permit.ts +116 -0
  286. package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +1 -9
  287. package/dist/extensions/pi-subagents/src/slash/delegation-request.ts +0 -4
  288. package/dist/extensions/pi-subagents/src/slash/slash-bridge.ts +1 -2
  289. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +378 -88
  290. package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +22 -11
  291. package/dist/extensions/pi-subagents/src/slash/subagents-admin.ts +3 -0
  292. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +147 -79
  293. package/dist/extensions/pi-subagents/src/tui/fleet-transcript.ts +11 -5
  294. package/dist/extensions/pi-subagents/src/tui/fleet.ts +39 -18
  295. package/dist/extensions/pi-subagents/src/tui/render.ts +369 -46
  296. package/dist/extensions/pi-subagents/src/watchdog/turn-delta.ts +1 -1
  297. package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +6 -3
  298. package/dist/extensions/pi-subagents/src/workflows/host-command.ts +230 -0
  299. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +740 -58
  300. package/dist/extensions/pi-subagents/src/workflows/workflow-child-summary.ts +121 -0
  301. package/dist/extensions/pi-subagents/src/workflows/workflow-preflight.ts +270 -0
  302. package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +195 -6
  303. package/dist/extensions/pi-subagents/src/workflows/workflow-settlement.ts +246 -0
  304. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +2 -2
  305. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +1114 -260
  306. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +34 -0
  307. package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +150 -3
  308. package/dist/extensions/pi-subagents/test/integration/claude-code-smoke.test.ts +52 -0
  309. package/dist/extensions/pi-subagents/test/integration/claude-code-writer-smoke.test.ts +55 -0
  310. package/dist/extensions/pi-subagents/test/integration/codex-exec-smoke.test.ts +53 -0
  311. package/dist/extensions/pi-subagents/test/integration/codex-exec-writer-smoke.test.ts +57 -0
  312. package/dist/extensions/pi-subagents/test/integration/cursor-agent-smoke.test.ts +59 -0
  313. package/dist/extensions/pi-subagents/test/integration/cursor-agent-writer-smoke.test.ts +62 -0
  314. package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +57 -1
  315. package/dist/extensions/pi-subagents/test/integration/external-cli-runner.test.ts +1 -0
  316. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +20 -0
  317. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +4 -3
  318. package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +2 -2
  319. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +54 -4
  320. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +482 -4
  321. package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +157 -9
  322. package/dist/extensions/pi-subagents/test/integration/session-tokens.test.ts +5 -5
  323. package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +1508 -291
  324. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +423 -1
  325. package/dist/extensions/pi-subagents/test/integration/template-resolution.test.ts +8 -0
  326. package/dist/extensions/pi-subagents/test/support/cursor-smoke-inputs.ts +51 -0
  327. package/dist/extensions/pi-subagents/test/support/helpers.ts +2 -0
  328. package/dist/extensions/pi-subagents/test/support/mock-pi.ts +5 -5
  329. package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +6 -6
  330. package/dist/extensions/pi-subagents/test/unit/abort-recovery.test.ts +152 -0
  331. package/dist/extensions/pi-subagents/test/unit/active-async-capacity.test.ts +48 -0
  332. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +184 -6
  333. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +66 -6
  334. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +77 -0
  335. package/dist/extensions/pi-subagents/test/unit/agent-refinements.test.ts +18 -0
  336. package/dist/extensions/pi-subagents/test/unit/anti-slop-oxlint.test.ts +86 -0
  337. package/dist/extensions/pi-subagents/test/unit/artifacts.test.ts +1 -1
  338. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +101 -1
  339. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +121 -0
  340. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +28 -0
  341. package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +14 -7
  342. package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +53 -0
  343. package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +190 -0
  344. package/dist/extensions/pi-subagents/test/unit/async-status-snapshot.test.ts +42 -0
  345. package/dist/extensions/pi-subagents/test/unit/auto-drain.test.ts +8 -4
  346. package/dist/extensions/pi-subagents/test/unit/background-work.test.ts +23 -0
  347. package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +78 -1
  348. package/dist/extensions/pi-subagents/test/unit/child-launch-plan.test.ts +94 -0
  349. package/dist/extensions/pi-subagents/test/unit/child-protocol.test.ts +21 -0
  350. package/dist/extensions/pi-subagents/test/unit/child-session-name.test.ts +50 -0
  351. package/dist/extensions/pi-subagents/test/unit/claude-code-adapter.test.ts +245 -0
  352. package/dist/extensions/pi-subagents/test/unit/codex-exec-adapter.test.ts +192 -0
  353. package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +27 -0
  354. package/dist/extensions/pi-subagents/test/unit/completion-evidence.test.ts +150 -0
  355. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +21 -0
  356. package/dist/extensions/pi-subagents/test/unit/cursor-agent-adapter.test.ts +259 -0
  357. package/dist/extensions/pi-subagents/test/unit/cursor-smoke-inputs.test.ts +77 -0
  358. package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +1 -4
  359. package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +1 -1
  360. package/dist/extensions/pi-subagents/test/unit/extension-context.test.ts +27 -0
  361. package/dist/extensions/pi-subagents/test/unit/external-cli-runner.test.ts +223 -0
  362. package/dist/extensions/pi-subagents/test/unit/fast-mode-extension.test.ts +27 -0
  363. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +208 -2
  364. package/dist/extensions/pi-subagents/test/unit/fleet-transcript.test.ts +29 -1
  365. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +110 -1
  366. package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +10 -0
  367. package/dist/extensions/pi-subagents/test/unit/formatters.test.ts +14 -0
  368. package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +18 -9
  369. package/dist/extensions/pi-subagents/test/unit/herdr-session-roots-codec.test.ts +63 -0
  370. package/dist/extensions/pi-subagents/test/unit/herdr-shell-command.test.ts +2 -2
  371. package/dist/extensions/pi-subagents/test/unit/herdr-status-bridge.test.ts +132 -0
  372. package/dist/extensions/pi-subagents/test/unit/host-command.test.ts +156 -0
  373. package/dist/extensions/pi-subagents/test/unit/host-step-status.test.ts +98 -0
  374. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +178 -26
  375. package/dist/extensions/pi-subagents/test/unit/index-segment.test.ts +2 -1
  376. package/dist/extensions/pi-subagents/test/unit/inspect-rpc.test.ts +21 -0
  377. package/dist/extensions/pi-subagents/test/unit/mcp-direct-tool-grant.test.ts +138 -0
  378. package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +1 -1
  379. package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +91 -0
  380. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +72 -7
  381. package/dist/extensions/pi-subagents/test/unit/mutation-evidence.test.ts +21 -0
  382. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +1 -0
  383. package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +20 -2
  384. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +129 -1
  385. package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +2 -2
  386. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +4 -0
  387. package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +358 -0
  388. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +574 -21
  389. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +109 -1
  390. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +71 -1
  391. package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +7 -7
  392. package/dist/extensions/pi-subagents/test/unit/pruned-fork.test.ts +214 -0
  393. package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +29 -8
  394. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +53 -0
  395. package/dist/extensions/pi-subagents/test/unit/result-delivery-ownership.test.ts +34 -0
  396. package/dist/extensions/pi-subagents/test/unit/result-files.test.ts +101 -3
  397. package/dist/extensions/pi-subagents/test/unit/retained-children.test.ts +1 -0
  398. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +10 -8
  399. package/dist/extensions/pi-subagents/test/unit/run-fanout-budget.test.ts +71 -1
  400. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +41 -7
  401. package/dist/extensions/pi-subagents/test/unit/runtime-agent-registration.test.ts +136 -2
  402. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +137 -0
  403. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +33 -12
  404. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +504 -1
  405. package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +8 -0
  406. package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +1 -1
  407. package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +12 -1
  408. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +3 -5
  409. package/dist/extensions/pi-subagents/test/unit/steering.test.ts +5 -6
  410. package/dist/extensions/pi-subagents/test/unit/subagent-action-recovery.test.ts +0 -8
  411. package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +5 -0
  412. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +157 -2
  413. package/dist/extensions/pi-subagents/test/unit/subagent-startup-retry.test.ts +1 -1
  414. package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +63 -4
  415. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +27 -23
  416. package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +44 -0
  417. package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +1 -0
  418. package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +7 -5
  419. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +106 -0
  420. package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +484 -9
  421. package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +38 -4
  422. package/dist/extensions/pi-subagents/test/unit/workflow-preflight.test.ts +155 -0
  423. package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +318 -0
  424. package/dist/extensions/pi-subagents/test/unit/workflow-resume-hint.test.ts +365 -0
  425. package/dist/extensions/pi-subagents/test/unit/worktree-cleanup-plan.test.ts +349 -0
  426. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +21 -0
  427. package/dist/extensions/pi-subagents/test/unit/writer-budget-guidance.test.ts +2 -7
  428. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/effect/index.ts +13 -0
  429. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/effect/rules/no-service-constructor-imports.ts +52 -0
  430. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/index.ts +41 -0
  431. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-chained-type-assertions.ts +77 -0
  432. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-conditional-empty-object-spread.ts +49 -0
  433. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-known-value-widening.ts +247 -0
  434. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-module-mocking.ts +91 -0
  435. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-object-parameters.ts +126 -0
  436. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-reflect-apply.ts +28 -0
  437. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-reflect-get.ts +28 -0
  438. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-runtime-typeof.ts +67 -0
  439. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-shape-in-symbol-names.ts +39 -0
  440. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-unknown-parameters.ts +83 -0
  441. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-unknown-returns.ts +115 -0
  442. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-unknown-type-aliases.ts +72 -0
  443. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-unsafe-dictionary-type.ts +134 -0
  444. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-widen-then-assert.ts +366 -0
  445. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/require-safety-comment-for-type-assertion.ts +62 -0
  446. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/shared/dictionary-types.ts +502 -0
  447. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/shared/lexical-type-parameters.ts +60 -0
  448. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/shared/reflect-method.ts +35 -0
  449. package/dist/extensions/pi-tool-display/tests/capabilities.test.ts +1 -1
  450. package/dist/extensions/pi-tool-display/tests/settings-inspector.test.ts +2 -2
  451. package/dist/extensions/pi-tool-display/tests/tool-overrides-mcp.test.ts +1 -1
  452. package/dist/modes/interactive/interactive-mode.js +7 -7
  453. package/dist/skills/workflow/SKILL.md +65 -50
  454. package/package.json +112 -110
  455. package/dist/extensions/enable-readonly-tools.test.ts +0 -63
  456. package/dist/extensions/enable-readonly-tools.ts +0 -24
  457. package/dist/extensions/model-prompt-injector/config.json +0 -16
  458. package/dist/extensions/model-prompt-injector/index.test.ts +0 -102
  459. package/dist/extensions/model-prompt-injector/index.ts +0 -148
  460. package/dist/extensions/pi-subagents/src/runs/shared/turn-budget.ts +0 -98
  461. package/dist/extensions/pi-subagents/test/unit/turn-budget.test.ts +0 -250
@@ -2,7 +2,13 @@ export const BUILTIN_AGENT_NAMES = [
2
2
  "architect",
3
3
  "advisor",
4
4
  "builder",
5
+ "claude-code",
6
+ "claude-code-writer",
7
+ "codex-exec",
8
+ "codex-exec-writer",
5
9
  "commentator",
10
+ "cursor-agent",
11
+ "cursor-agent-writer",
6
12
  "delegate",
7
13
  "explorer",
8
14
  "oracle",
@@ -0,0 +1,70 @@
1
+ import type { ExtensionAPI } from "@selesai/code";
2
+ import { registerRuntimeAgent, type RuntimeAgentDefinition, type RuntimeAgentRegistration } from "./runtime-agent-registry.ts";
3
+
4
+ export const RUNTIME_AGENT_REGISTER_EVENT = "pi-subagents:runtime-agent-register:v1";
5
+ export const RUNTIME_AGENT_REGISTER_VERSION = 1;
6
+
7
+ export type RuntimeAgentRegistrationResult =
8
+ | { ok: true; registration: RuntimeAgentRegistration }
9
+ | { ok: false; error: Error };
10
+
11
+ export interface RuntimeAgentRegistrationRequest {
12
+ version: 1;
13
+ name: string;
14
+ definition: RuntimeAgentDefinition;
15
+ result?: RuntimeAgentRegistrationResult;
16
+ }
17
+
18
+ export interface RegisterRuntimeAgentViaEventsInput {
19
+ pi: Pick<ExtensionAPI, "events">;
20
+ name: string;
21
+ definition: RuntimeAgentDefinition;
22
+ }
23
+
24
+ function errorFrom(value: unknown): Error {
25
+ return value instanceof Error ? value : new Error(String(value));
26
+ }
27
+
28
+ /** Register through the installed pi-subagents owner in this Pi process. */
29
+ export function registerAgentViaEvents(input: RegisterRuntimeAgentViaEventsInput): RuntimeAgentRegistration {
30
+ const request: RuntimeAgentRegistrationRequest = {
31
+ version: RUNTIME_AGENT_REGISTER_VERSION,
32
+ name: input.name,
33
+ definition: input.definition,
34
+ };
35
+ input.pi.events.emit(RUNTIME_AGENT_REGISTER_EVENT, request);
36
+ const result = request.result as unknown;
37
+ if (result === undefined) {
38
+ throw new Error("pi-subagents is not installed, not ready, or does not support runtime agent event registration.");
39
+ }
40
+ if (result && typeof result === "object" && !Array.isArray(result)) {
41
+ const candidate = result as Record<string, unknown>;
42
+ if (candidate.ok === true && candidate.registration && typeof candidate.registration === "object" && typeof (candidate.registration as { dispose?: unknown }).dispose === "function") {
43
+ return candidate.registration as RuntimeAgentRegistration;
44
+ }
45
+ if (candidate.ok === false && candidate.error instanceof Error) throw candidate.error;
46
+ }
47
+ throw new Error("pi-subagents returned a malformed runtime agent registration result.");
48
+ }
49
+
50
+ /** Install the process-local registration listener for the owning pi-subagents runtime. */
51
+ export function registerRuntimeAgentEventListener(pi: ExtensionAPI): () => void {
52
+ return pi.events.on(RUNTIME_AGENT_REGISTER_EVENT, (rawRequest) => {
53
+ if (!rawRequest || typeof rawRequest !== "object" || Array.isArray(rawRequest)) return;
54
+ const request = rawRequest as Record<string, unknown>;
55
+ if (request.result !== undefined) return;
56
+ try {
57
+ if (request.version !== RUNTIME_AGENT_REGISTER_VERSION) {
58
+ throw new Error(`Unsupported runtime agent registration event version '${String(request.version)}'.`);
59
+ }
60
+ const registration = registerRuntimeAgent({
61
+ pi,
62
+ name: request.name as string,
63
+ definition: request.definition as RuntimeAgentDefinition,
64
+ });
65
+ request.result = { ok: true, registration } satisfies RuntimeAgentRegistrationResult;
66
+ } catch (error) {
67
+ request.result = { ok: false, error: errorFrom(error) } satisfies RuntimeAgentRegistrationResult;
68
+ }
69
+ });
70
+ }
@@ -1,9 +1,9 @@
1
1
  import type { ExtensionAPI } from "@selesai/code";
2
- import type { AcceptanceInput, AcceptanceRole, AgentRunnerConfig, OutputMode, ToolBudgetConfig, TurnBudgetConfig } from "../shared/types.ts";
2
+ import type { AcceptanceInput, AcceptanceRole, AgentRunnerConfig, OutputMode, ToolBudgetConfig } from "../shared/types.ts";
3
+ import { CODE_OWNED_EXTERNAL_CLI_ADAPTER_LABEL, isCodeOwnedExternalCliAdapterId, parseExternalCliCapabilityNarrowing, validateCodeOwnedProfileRunner } from "../runs/shared/external-cli-contract.ts";
3
4
  import { validateAcceptanceInput } from "../runs/shared/acceptance.ts";
4
5
  import { validatePermissionRules, type PermissionRules } from "../runs/shared/permissions.ts";
5
6
  import { validateToolBudgetConfig } from "../runs/shared/tool-budget.ts";
6
- import { resolveTurnBudgetConfig } from "../runs/shared/turn-budget.ts";
7
7
  import { BUILTIN_AGENT_NAMES } from "./builtin-names.ts";
8
8
  import type { AgentConfig, AgentDefaultContext, AgentDiscoveryDiagnostic } from "./agents.ts";
9
9
 
@@ -20,18 +20,19 @@ export interface RuntimeAgentDefinition {
20
20
  systemPrompt: string;
21
21
  aliases?: readonly string[];
22
22
  tools?: readonly string[];
23
+ allowNestedSubagents?: boolean;
23
24
  mcpDirectTools?: readonly string[];
24
25
  model?: string;
25
26
  fallbackModels?: readonly string[];
26
27
  thinking?: string | false;
27
28
  systemPromptMode?: "append" | "replace";
28
29
  inheritProjectContext?: boolean;
30
+ inheritGlobalContext?: boolean;
29
31
  inheritSkills?: boolean;
30
32
  defaultContext?: AgentDefaultContext;
31
33
  defaultAsync?: boolean;
32
34
  defaultTimeoutMs?: number;
33
35
  defaultToolTimeoutMs?: number;
34
- defaultTurnBudget?: TurnBudgetConfig;
35
36
  defaultAcceptance?: AcceptanceInput;
36
37
  acceptanceRole?: AcceptanceRole;
37
38
  runner?: AgentRunnerConfig;
@@ -39,6 +40,7 @@ export interface RuntimeAgentDefinition {
39
40
  skillPath?: readonly string[];
40
41
  extensions?: readonly string[];
41
42
  subagentOnlyExtensions?: readonly string[];
43
+ mutationTools?: readonly string[];
42
44
  output?: string;
43
45
  outputMode?: OutputMode;
44
46
  defaultReads?: readonly string[];
@@ -132,8 +134,8 @@ function validateStringList(value: unknown, field: string): string[] | undefined
132
134
 
133
135
  function validatePositiveInteger(value: unknown, field: string): number | undefined {
134
136
  if (value === undefined) return undefined;
135
- if (!Number.isInteger(value) || (value as number) <= 0) throw new Error(`${field} must be a positive integer when provided.`);
136
- return value as number;
137
+ if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) throw new Error(`${field} must be a positive integer when provided.`);
138
+ return value;
137
139
  }
138
140
 
139
141
  function validateBoolean(value: unknown, field: string): boolean | undefined {
@@ -169,18 +171,15 @@ function validateRunner(value: unknown): AgentRunnerConfig | undefined {
169
171
  if (runner.type !== "external-cli") throw new Error("Runtime agent definition runner.type must be 'pi', 'external-cli', or 'external-job'.");
170
172
  if (typeof runner.command !== "string" || !runner.command.trim()) throw new Error("Runtime agent definition external-cli runner requires a non-empty command string.");
171
173
  if (runner.args !== undefined && (!Array.isArray(runner.args) || runner.args.some((arg) => typeof arg !== "string"))) throw new Error("Runtime agent definition external-cli runner args must be an array of strings.");
174
+ if (runner.adapter !== undefined && !isCodeOwnedExternalCliAdapterId(runner.adapter)) throw new Error(`Runtime agent definition external-cli runner adapter must be ${CODE_OWNED_EXTERNAL_CLI_ADAPTER_LABEL}.`);
175
+ if (runner.adapter !== undefined && Array.isArray(runner.args) && runner.args.length > 0) throw new Error(`Runtime agent definition ${runner.adapter} adapter owns its argv; runner args are not supported.`);
172
176
  if (runner.promptDelivery !== undefined && runner.promptDelivery !== "stdin") throw new Error("Runtime agent definition external-cli runner promptDelivery must be 'stdin'.");
173
- const supported = new Set(["type", "command", "args", "promptDelivery"]);
177
+ const capabilities = parseExternalCliCapabilityNarrowing(runner.capabilities, "Runtime agent definition external-cli runner capabilities");
178
+ const supported = new Set(["type", "adapter", "command", "args", "promptDelivery", "capabilities"]);
174
179
  const unknown = Object.keys(runner).filter((key) => !supported.has(key));
175
180
  if (unknown.length > 0) throw new Error(`Runtime agent definition external-cli runner has unsupported fields: ${unknown.join(", ")}.`);
176
181
  const args = runner.args as string[] | undefined;
177
- return { type: "external-cli", command: runner.command.trim(), ...(args?.length ? { args } : {}), ...(runner.promptDelivery ? { promptDelivery: "stdin" as const } : {}) };
178
- }
179
-
180
- function validateTurnBudget(value: unknown): TurnBudgetConfig | undefined {
181
- const result = resolveTurnBudgetConfig(value, "Runtime agent definition defaultTurnBudget");
182
- if (result.error) throw new Error(result.error);
183
- return result.turnBudget;
182
+ return { type: "external-cli", ...(isCodeOwnedExternalCliAdapterId(runner.adapter) ? { adapter: runner.adapter } : {}), command: runner.command.trim(), ...(args?.length ? { args } : {}), ...(runner.promptDelivery ? { promptDelivery: "stdin" as const } : {}), ...(capabilities ? { capabilities } : {}) };
184
183
  }
185
184
 
186
185
  function validateAcceptance(value: unknown): AcceptanceInput | undefined {
@@ -199,10 +198,10 @@ function validateDefinition(value: unknown): RuntimeAgentDefinition {
199
198
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("Runtime agent definition must be an object.");
200
199
  const definition = value as Record<string, unknown>;
201
200
  const supported = new Set([
202
- "description", "systemPrompt", "aliases", "tools", "mcpDirectTools", "model", "fallbackModels", "thinking",
203
- "systemPromptMode", "inheritProjectContext", "inheritSkills", "defaultContext", "defaultAsync", "defaultTimeoutMs",
204
- "defaultToolTimeoutMs", "defaultTurnBudget", "defaultAcceptance", "acceptanceRole", "runner", "skills", "skillPath",
205
- "extensions", "subagentOnlyExtensions", "output", "outputMode", "defaultReads", "defaultProgress", "interactive",
201
+ "description", "systemPrompt", "aliases", "tools", "allowNestedSubagents", "mcpDirectTools", "model", "fallbackModels", "thinking",
202
+ "systemPromptMode", "inheritProjectContext", "inheritGlobalContext", "inheritSkills", "defaultContext", "defaultAsync", "defaultTimeoutMs",
203
+ "defaultToolTimeoutMs", "defaultAcceptance", "acceptanceRole", "runner", "skills", "skillPath",
204
+ "extensions", "subagentOnlyExtensions", "mutationTools", "output", "outputMode", "defaultReads", "defaultProgress", "interactive",
206
205
  "maxSubagentDepth", "completionGuard", "toolBudget", "permissions",
207
206
  ]);
208
207
  const unknown = Object.keys(definition).filter((key) => !supported.has(key));
@@ -219,21 +218,23 @@ function validateDefinition(value: unknown): RuntimeAgentDefinition {
219
218
  if (outputMode !== undefined && outputMode !== "inline" && outputMode !== "file-only") throw new Error("Runtime agent definition outputMode must be 'inline' or 'file-only'.");
220
219
  const aliases = validateStringList(definition.aliases, "Runtime agent definition aliases");
221
220
  const tools = validateStringList(definition.tools, "Runtime agent definition tools");
221
+ const allowNestedSubagents = validateBoolean(definition.allowNestedSubagents, "Runtime agent definition allowNestedSubagents");
222
222
  const mcpDirectTools = validateStringList(definition.mcpDirectTools, "Runtime agent definition mcpDirectTools");
223
223
  const model = validateOptionalString(definition.model, "Runtime agent definition model");
224
224
  const fallbackModels = validateStringList(definition.fallbackModels, "Runtime agent definition fallbackModels");
225
225
  const inheritProjectContext = validateBoolean(definition.inheritProjectContext, "Runtime agent definition inheritProjectContext");
226
+ const inheritGlobalContext = validateBoolean(definition.inheritGlobalContext, "Runtime agent definition inheritGlobalContext");
226
227
  const inheritSkills = validateBoolean(definition.inheritSkills, "Runtime agent definition inheritSkills");
227
228
  const defaultAsync = validateBoolean(definition.defaultAsync, "Runtime agent definition defaultAsync");
228
229
  const defaultTimeoutMs = validatePositiveInteger(definition.defaultTimeoutMs, "Runtime agent definition defaultTimeoutMs");
229
230
  const defaultToolTimeoutMs = validatePositiveInteger(definition.defaultToolTimeoutMs, "Runtime agent definition defaultToolTimeoutMs");
230
- const defaultTurnBudget = validateTurnBudget(definition.defaultTurnBudget);
231
231
  const defaultAcceptance = validateAcceptance(definition.defaultAcceptance);
232
232
  const runner = validateRunner(definition.runner);
233
233
  const skills = validateStringList(definition.skills, "Runtime agent definition skills");
234
234
  const skillPath = validateStringList(definition.skillPath, "Runtime agent definition skillPath");
235
235
  const extensions = validateStringList(definition.extensions, "Runtime agent definition extensions");
236
236
  const subagentOnlyExtensions = validateStringList(definition.subagentOnlyExtensions, "Runtime agent definition subagentOnlyExtensions");
237
+ const mutationTools = validateStringList(definition.mutationTools, "Runtime agent definition mutationTools");
237
238
  const output = validateOptionalString(definition.output, "Runtime agent definition output");
238
239
  const defaultReads = validateStringList(definition.defaultReads, "Runtime agent definition defaultReads");
239
240
  const defaultProgress = validateBoolean(definition.defaultProgress, "Runtime agent definition defaultProgress");
@@ -247,18 +248,19 @@ function validateDefinition(value: unknown): RuntimeAgentDefinition {
247
248
  systemPrompt: validateString(definition.systemPrompt, "Runtime agent definition systemPrompt", MAX_SYSTEM_PROMPT_LENGTH),
248
249
  ...(aliases ? { aliases } : {}),
249
250
  ...(tools ? { tools } : {}),
251
+ ...(allowNestedSubagents !== undefined ? { allowNestedSubagents } : {}),
250
252
  ...(mcpDirectTools ? { mcpDirectTools } : {}),
251
253
  ...(model ? { model } : {}),
252
254
  ...(fallbackModels ? { fallbackModels } : {}),
253
255
  ...(thinking !== undefined ? { thinking: thinking as string | false } : {}),
254
256
  ...(systemPromptMode !== undefined ? { systemPromptMode: systemPromptMode as "append" | "replace" } : {}),
255
257
  ...(inheritProjectContext !== undefined ? { inheritProjectContext } : {}),
258
+ ...(inheritGlobalContext !== undefined ? { inheritGlobalContext } : {}),
256
259
  ...(inheritSkills !== undefined ? { inheritSkills } : {}),
257
260
  ...(defaultContext !== undefined ? { defaultContext: defaultContext as AgentDefaultContext } : {}),
258
261
  ...(defaultAsync !== undefined ? { defaultAsync } : {}),
259
262
  ...(defaultTimeoutMs !== undefined ? { defaultTimeoutMs } : {}),
260
263
  ...(defaultToolTimeoutMs !== undefined ? { defaultToolTimeoutMs } : {}),
261
- ...(defaultTurnBudget !== undefined ? { defaultTurnBudget } : {}),
262
264
  ...(defaultAcceptance !== undefined ? { defaultAcceptance } : {}),
263
265
  ...(acceptanceRole !== undefined ? { acceptanceRole: acceptanceRole as AcceptanceRole } : {}),
264
266
  ...(runner !== undefined ? { runner } : {}),
@@ -266,6 +268,7 @@ function validateDefinition(value: unknown): RuntimeAgentDefinition {
266
268
  ...(skillPath ? { skillPath } : {}),
267
269
  ...(extensions ? { extensions } : {}),
268
270
  ...(subagentOnlyExtensions ? { subagentOnlyExtensions } : {}),
271
+ ...(mutationTools ? { mutationTools } : {}),
269
272
  ...(output ? { output } : {}),
270
273
  ...(outputMode !== undefined ? { outputMode: outputMode as OutputMode } : {}),
271
274
  ...(defaultReads ? { defaultReads } : {}),
@@ -324,18 +327,19 @@ function toAgentConfig(name: string, definition: RuntimeAgentDefinition): AgentC
324
327
  ...(aliases ? { aliases } : {}),
325
328
  ...(definition.runner !== undefined ? { runner: definition.runner } : {}),
326
329
  ...(definition.tools !== undefined ? { tools: [...definition.tools] } : {}),
330
+ ...(definition.allowNestedSubagents !== undefined ? { allowNestedSubagents: definition.allowNestedSubagents } : {}),
327
331
  ...(definition.mcpDirectTools !== undefined ? { mcpDirectTools: [...definition.mcpDirectTools] } : {}),
328
332
  ...(definition.model !== undefined ? { model: definition.model } : {}),
329
333
  ...(definition.fallbackModels !== undefined ? { fallbackModels: [...definition.fallbackModels] } : {}),
330
334
  ...(definition.thinking !== undefined ? { thinking: definition.thinking } : {}),
331
335
  systemPromptMode: definition.systemPromptMode ?? defaultSystemPromptMode(name),
332
336
  inheritProjectContext: definition.inheritProjectContext ?? defaultInheritProjectContext(name),
337
+ inheritGlobalContext: definition.inheritGlobalContext ?? false,
333
338
  inheritSkills: definition.inheritSkills ?? defaultInheritSkills(),
334
339
  ...(definition.defaultContext !== undefined ? { defaultContext: definition.defaultContext } : {}),
335
340
  ...(definition.defaultAsync !== undefined ? { defaultAsync: definition.defaultAsync } : {}),
336
341
  ...(definition.defaultTimeoutMs !== undefined ? { defaultTimeoutMs: definition.defaultTimeoutMs } : {}),
337
342
  ...(definition.defaultToolTimeoutMs !== undefined ? { defaultToolTimeoutMs: definition.defaultToolTimeoutMs } : {}),
338
- ...(definition.defaultTurnBudget !== undefined ? { defaultTurnBudget: definition.defaultTurnBudget } : {}),
339
343
  ...(definition.defaultAcceptance !== undefined ? { defaultAcceptance: definition.defaultAcceptance } : {}),
340
344
  ...(definition.acceptanceRole !== undefined ? { acceptanceRole: definition.acceptanceRole } : {}),
341
345
  systemPrompt: definition.systemPrompt,
@@ -345,6 +349,7 @@ function toAgentConfig(name: string, definition: RuntimeAgentDefinition): AgentC
345
349
  ...(definition.skillPath !== undefined ? { skillPath: [...definition.skillPath] } : {}),
346
350
  ...(definition.extensions !== undefined ? { extensions: [...definition.extensions] } : {}),
347
351
  ...(definition.subagentOnlyExtensions !== undefined ? { subagentOnlyExtensions: [...definition.subagentOnlyExtensions] } : {}),
352
+ ...(definition.mutationTools !== undefined ? { mutationTools: [...definition.mutationTools] } : {}),
348
353
  ...(definition.output !== undefined ? { output: definition.output } : {}),
349
354
  ...(definition.outputMode !== undefined ? { outputMode: definition.outputMode } : {}),
350
355
  ...(definition.defaultReads !== undefined ? { defaultReads: [...definition.defaultReads] } : {}),
@@ -364,6 +369,8 @@ export function registerRuntimeAgent(input: RegisterRuntimeAgentInput): RuntimeA
364
369
  const name = validateString(input.name, "Runtime agent name", MAX_AGENT_NAME_LENGTH);
365
370
  const definition = validateDefinition(input.definition);
366
371
  const agent = toAgentConfig(name, definition);
372
+ const profileError = validateCodeOwnedProfileRunner(agent);
373
+ if (profileError) throw new Error(profileError);
367
374
  assertNoBuiltinCollision(agent);
368
375
  const current = registry();
369
376
  const records = current.byPi.get(pi) ?? [];
@@ -1,7 +1,12 @@
1
- import { registerRuntimeAgent, type RegisterRuntimeAgentInput, type RuntimeAgentDefinition, type RuntimeAgentRegistration } from "../agents/runtime-agent-registry.ts";
1
+ import type { RegisterRuntimeAgentInput, RuntimeAgentDefinition, RuntimeAgentRegistration } from "../agents/runtime-agent-registry.ts";
2
+ export { registerRuntimeAgent as registerAgent } from "../agents/runtime-agent-registry.ts";
3
+ export {
4
+ RUNTIME_AGENT_REGISTER_EVENT,
5
+ RUNTIME_AGENT_REGISTER_VERSION,
6
+ registerAgentViaEvents,
7
+ type RegisterRuntimeAgentViaEventsInput,
8
+ type RuntimeAgentRegistrationRequest,
9
+ type RuntimeAgentRegistrationResult,
10
+ } from "../agents/runtime-agent-events.ts";
2
11
 
3
12
  export type { RegisterRuntimeAgentInput, RuntimeAgentDefinition, RuntimeAgentRegistration };
4
-
5
- export function registerAgent(input: RegisterRuntimeAgentInput): RuntimeAgentRegistration {
6
- return registerRuntimeAgent(input);
7
- }
@@ -4,7 +4,11 @@ export const BACKGROUND_WORK_REGISTRY_KEY = "pi-subagents.background-work.v1";
4
4
  const MAX_PROVIDER_NAME_LENGTH = 128;
5
5
  const MAX_PROVIDERS = 100;
6
6
  const MAX_ITEM_ID_LENGTH = 256;
7
- const MAX_SESSION_ID_LENGTH = 256;
7
+ /**
8
+ * A Pi session id is the session file path, which routinely exceeds a short
9
+ * identity budget in nested worktrees, so it is bounded like the other paths.
10
+ */
11
+ const MAX_SESSION_ID_LENGTH = 4_096;
8
12
  const MAX_WAKE_CHANNEL_LENGTH = 256;
9
13
  const MAX_ITEMS_PER_PROVIDER = 10_000;
10
14
 
@@ -7,11 +7,6 @@ export const SUBAGENT_DELEGATION_UPDATE_EVENT = "prompt-template:subagent:update
7
7
  export const SUBAGENT_DELEGATION_RESPONSE_EVENT = "prompt-template:subagent:response";
8
8
  export const SUBAGENT_DELEGATION_CANCEL_EVENT = "prompt-template:subagent:cancel";
9
9
 
10
- export interface SubagentDelegationTurnBudget {
11
- maxTurns: number;
12
- graceTurns?: number;
13
- }
14
-
15
10
  export interface SubagentDelegationToolBudget {
16
11
  soft?: number;
17
12
  hard: number;
@@ -37,7 +32,6 @@ export interface SubagentDelegationRequest {
37
32
  model?: string;
38
33
  thinking?: SubagentDelegationThinking;
39
34
  timeoutMs?: number;
40
- turnBudget?: SubagentDelegationTurnBudget;
41
35
  toolBudget?: SubagentDelegationToolBudget;
42
36
  skill?: string | string[] | boolean;
43
37
  artifacts?: boolean;
@@ -69,7 +63,6 @@ export type SubagentDelegationStatus =
69
63
  | "timed_out"
70
64
  | "cancelled"
71
65
  | "interrupted"
72
- | "turn_budget_exhausted"
73
66
  | "tool_budget_exhausted"
74
67
  | "structured_output_failed"
75
68
  | "acceptance_failed"
@@ -1,7 +1,7 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
- import { discoverAgents, discoverAgentsAll, findBlockingAgentDiagnostic, resolveAgentName, type AgentConfig, type AgentScope, type AgentSource } from "../agents/agents.ts";
4
+ import { discoverAgents, discoverAgentsAll, findBlockingAgentDiagnostic, formatUnknownAgentError, resolveAgentName, unknownAgentDiagnosticContext, type AgentConfig, type AgentScope, type AgentSource } from "../agents/agents.ts";
5
5
  import { resolveExecutionAgentScope } from "../agents/agent-scope.ts";
6
6
  import { buildSkillInjection, normalizeSkillInput, resolveSkillsWithFallback } from "../agents/skills.ts";
7
7
  import { buildAgentMemoryInjection } from "../agents/agent-memory.ts";
@@ -14,9 +14,7 @@ import { resolveEffectiveThinking } from "../shared/model-info.ts";
14
14
  import { assertThinkingWithinCeiling, decodeThinkingCeiling, intersectThinkingCeilings, SUBAGENT_THINKING_CEILING_ENV, type ThinkingLevel } from "../shared/thinking-ceiling.ts";
15
15
  import { SUBAGENT_LIFECYCLE_ARTIFACT_VERSION, type ArtifactDirPreference, type ArtifactPaths, type JsonSchemaObject, type OutputMode } from "../shared/types.ts";
16
16
  import { capabilityCeilingAgentRestrictionMessage, intersectSubagentCapabilityCeilings, type ResolvedSubagentCapabilityCeiling, type SubagentCapabilityAudit } from "../runs/shared/capability-ceiling.ts";
17
- import { appendTurnBudgetSystemPrompt } from "../runs/shared/turn-budget.ts";
18
17
  import { resolvePermissionRules } from "../runs/shared/permissions.ts";
19
- import type { ResolvedTurnBudget } from "../shared/types.ts";
20
18
  import type { ResolvedMcpDirectToolSelection } from "../runs/shared/mcp-direct-tool-allowlist.ts";
21
19
  import { resolveStepBehavior } from "../shared/settings.ts";
22
20
  import { canPreferForkFromSnapshot, resolveSubagentLaunchContext } from "../shared/fork-context.ts";
@@ -42,8 +40,10 @@ export type SubagentLaunchContractReasonCode =
42
40
  | "thinking_ceiling"
43
41
  | "invalid_extension_bindings";
44
42
 
43
+ export type SubagentLaunchContractDiagnosticCode = SubagentLaunchContractReasonCode | "host_required" | "snapshot_warning" | "workspace_scope_authority";
44
+
45
45
  export interface SubagentLaunchContractDiagnostic {
46
- code: SubagentLaunchContractReasonCode | "host_required" | "snapshot_warning";
46
+ code: SubagentLaunchContractDiagnosticCode;
47
47
  severity: "error" | "warning" | "host-required";
48
48
  message: string;
49
49
  }
@@ -67,7 +67,6 @@ export interface SubagentLaunchContractInput {
67
67
  outputMode?: OutputMode;
68
68
  outputSchema?: JsonSchemaObject;
69
69
  extensionBindings?: ExtensionBindings;
70
- turnBudget?: ResolvedTurnBudget;
71
70
  artifacts?: boolean;
72
71
  artifactDir?: ArtifactDirPreference;
73
72
  parentSessionFile?: string | null;
@@ -157,6 +156,7 @@ export interface SubagentLaunchContract {
157
156
  thinkingCeiling?: ThinkingLevel;
158
157
  systemPromptMode: AgentConfig["systemPromptMode"];
159
158
  inheritProjectContext: boolean;
159
+ inheritGlobalContext: boolean;
160
160
  inheritSkills: boolean;
161
161
  skills: SubagentLaunchContractSkills;
162
162
  tools: SubagentLaunchContractTools;
@@ -204,8 +204,26 @@ function resolveLaunchContractContext(input: SubagentLaunchContractInput, agent:
204
204
  });
205
205
  }
206
206
 
207
- function candidateList(inputAgent: string, selected: AgentConfig | undefined, cwd: string): SubagentLaunchContractAgentCandidate[] {
208
- const all = discoverAgentsAll(cwd);
207
+ function taskWorkspaceScopeAuthorityDiagnostic(task: string | undefined): SubagentLaunchContractDiagnostic | undefined {
208
+ if (!task) return undefined;
209
+ const text = task.replace(/\s+/g, " ").trim();
210
+ if (!text) return undefined;
211
+ const createsWorkspacePackage = /\b(?:add|create|introduce|make|set up)\b.{0,80}\b(?:new\s+)?(?:workspace\s+)?package\b/i.test(text)
212
+ || /\b(?:new\s+)?package\b.{0,80}\b(?:workspace|monorepo)\b/i.test(text);
213
+ if (!createsWorkspacePackage) return undefined;
214
+ const packageOnlyAuthority = /\b(?:only|solely)\b.{0,40}\b(?:edit|change|modify|touch|write(?:\s+to)?)\b.{0,80}\b(?:package(?:\s+directory)?|packages\/[\w.-]+)\b/i.test(text)
215
+ || /\b(?:do not|don't|must not)\b.{0,40}\b(?:edit|change|modify|touch|write(?:\s+to)?)\b.{0,80}\b(?:root|workspace|lockfile|metadata)\b/i.test(text)
216
+ || /\bwithout\b.{0,40}\b(?:root|workspace|lockfile|metadata)\b.{0,40}\b(?:edit|change|modification|write)s?\b/i.test(text);
217
+ if (!packageOnlyAuthority) return undefined;
218
+ return {
219
+ code: "workspace_scope_authority",
220
+ severity: "warning",
221
+ message: "Task asks for a workspace package change while limiting authority to package-scope edits. New workspace packages often need root workspace metadata or lockfile changes, so confirm that authority before launch.",
222
+ };
223
+ }
224
+
225
+ function candidateList(inputAgent: string, selected: AgentConfig | undefined, cwd: string, provider?: string): SubagentLaunchContractAgentCandidate[] {
226
+ const all = discoverAgentsAll(cwd, provider);
209
227
  return [...all.builtin, ...all.package, ...all.user, ...all.project]
210
228
  .filter((agent) => Boolean(resolveAgentName(inputAgent, [agent]).agent))
211
229
  .map((agent) => ({
@@ -221,6 +239,8 @@ function candidateList(inputAgent: string, selected: AgentConfig | undefined, cw
221
239
 
222
240
  export async function resolveSubagentLaunchContract(input: SubagentLaunchContractInput): Promise<SubagentLaunchContractResult> {
223
241
  const diagnostics: SubagentLaunchContractDiagnostic[] = [];
242
+ const authorityDiagnostic = taskWorkspaceScopeAuthorityDiagnostic(input.task);
243
+ if (authorityDiagnostic) diagnostics.push(authorityDiagnostic);
224
244
  const effectiveCwd = path.resolve(input.cwd);
225
245
  try {
226
246
  if (!fs.statSync(effectiveCwd).isDirectory()) {
@@ -237,7 +257,8 @@ export async function resolveSubagentLaunchContract(input: SubagentLaunchContrac
237
257
  return { ok: false, code: "invalid_artifact_dir", message: `Unsupported artifactDir '${String(input.artifactDir)}'; expected 'project', 'session', or 'temp'.`, diagnostics };
238
258
  }
239
259
  const scope = resolveExecutionAgentScope(input.agentScope);
240
- const discovered = discoverAgents(effectiveCwd, scope);
260
+ const parentProvider = input.preferredProvider ?? input.parentModel?.provider;
261
+ const discovered = discoverAgents(effectiveCwd, scope, parentProvider);
241
262
  const resolvedAgent = resolveAgentName(input.agent, discovered.agents);
242
263
  const ambiguousCandidates = resolvedAgent.error
243
264
  ? discovered.agents.filter((agent) => resolveAgentName(input.agent, [agent]).agent)
@@ -251,7 +272,7 @@ export async function resolveSubagentLaunchContract(input: SubagentLaunchContrac
251
272
  return { ok: false, code: "ambiguous_agent", message: resolvedAgent.error, diagnostics };
252
273
  }
253
274
  if (!resolvedAgent.agent) {
254
- return { ok: false, code: "missing_agent", message: `Unknown agent: ${input.agent}`, diagnostics };
275
+ return { ok: false, code: "missing_agent", message: formatUnknownAgentError(input.agent, unknownAgentDiagnosticContext(discovered)), diagnostics };
255
276
  }
256
277
  const agent = resolvedAgent.agent;
257
278
  let extensionBindings: ExtensionBindings | undefined;
@@ -330,6 +351,7 @@ export async function resolveSubagentLaunchContract(input: SubagentLaunchContrac
330
351
  try {
331
352
  toolPlan = resolvePiLaunchToolPlan({
332
353
  tools: agent.tools,
354
+ allowNestedSubagents: agent.allowNestedSubagents,
333
355
  extensions: agent.extensions,
334
356
  subagentOnlyExtensions: agent.subagentOnlyExtensions,
335
357
  mcpDirectTools: agent.mcpDirectTools,
@@ -375,9 +397,7 @@ export async function resolveSubagentLaunchContract(input: SubagentLaunchContrac
375
397
  const memoryInjection = buildAgentMemoryInjection(agent, effectiveCwd);
376
398
  if (memoryInjection) effectiveSystemPrompt = effectiveSystemPrompt ? `${effectiveSystemPrompt}\n\n${memoryInjection}` : memoryInjection;
377
399
  effectiveSystemPrompt = injectOutputPathSystemPrompt(effectiveSystemPrompt, outputPath, agent);
378
- const turnBudget = input.turnBudget ?? agent.defaultTurnBudget;
379
- effectiveSystemPrompt = appendTurnBudgetSystemPrompt(effectiveSystemPrompt, turnBudget);
380
- const candidates = candidateList(input.agent, agent, effectiveCwd);
400
+ const candidates = candidateList(input.agent, agent, effectiveCwd, parentProvider);
381
401
  const shadowedCandidates = candidates.filter((candidate) => !candidate.selected);
382
402
  const definitionDigest = agentDefinitionDigest(agent);
383
403
  const contractBase: Omit<SubagentLaunchContract, "digest"> = {
@@ -400,6 +420,7 @@ export async function resolveSubagentLaunchContract(input: SubagentLaunchContrac
400
420
  ...(thinkingCeiling ? { thinkingCeiling } : {}),
401
421
  systemPromptMode: agent.systemPromptMode,
402
422
  inheritProjectContext: agent.inheritProjectContext,
423
+ inheritGlobalContext: agent.inheritGlobalContext,
403
424
  inheritSkills: agent.inheritSkills,
404
425
  skills: {
405
426
  requested: requestedSkills,
@@ -455,6 +476,7 @@ export async function resolveSubagentLaunchContract(input: SubagentLaunchContrac
455
476
  systemPrompt: effectiveSystemPrompt,
456
477
  systemPromptMode: agent.systemPromptMode,
457
478
  inheritProjectContext: agent.inheritProjectContext,
479
+ inheritGlobalContext: agent.inheritGlobalContext,
458
480
  inheritSkills: agent.inheritSkills,
459
481
  skills: requestedSkills,
460
482
  tools: toolPlan.effectiveToolAllowlist,
@@ -6,7 +6,9 @@ import { FLEET_KEYBINDING_ACTIONS, type ArtifactDirPreference, type ExtensionCon
6
6
  import { validateMissionStoreConfig } from "../missions/store.ts";
7
7
  import { validateAuthorityPolicy } from "../policy/authority.ts";
8
8
  import { getAgentDir } from "../shared/utils.ts";
9
+ import { DEFAULT_MODEL_EXCLUSION_TTL_MS, MAX_MODEL_EXCLUSION_TTL_MS, setDefaultTTL } from "../runs/shared/model-exclusions.ts";
9
10
  import { validatePermissionConfig } from "../runs/shared/permissions.ts";
11
+ import { MAX_ABANDONED_SLOT_RELEASE_AFTER_MS, MIN_ABANDONED_SLOT_RELEASE_AFTER_MS } from "../runs/background/active-async-capacity.ts";
10
12
 
11
13
  const ARTIFACT_DIR_PREFERENCES = new Set<ArtifactDirPreference>(["project", "session", "temp"]);
12
14
  const FLEET_KEYBINDING_ACTION_SET = new Set<string>(FLEET_KEYBINDING_ACTIONS);
@@ -16,6 +18,23 @@ const BASE_KEY_IDS = new Set([
16
18
  ...Object.values(Key).flatMap((value) => typeof value === "string" ? [value.toLowerCase()] : []),
17
19
  ]);
18
20
 
21
+ class PrunedForkConfigError extends Error {}
22
+
23
+ function validateForkContextConfig(value: unknown): void {
24
+ if (value === undefined) return;
25
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("config.forkContext must be a JSON object");
26
+ const config = value as Record<string, unknown>;
27
+ if (config.mode !== undefined && config.mode !== "full" && config.mode !== "pruned") {
28
+ throw new Error('config.forkContext.mode must be "full" or "pruned"');
29
+ }
30
+ if (config.model !== undefined && (typeof config.model !== "string" || !config.model.trim())) {
31
+ throw new PrunedForkConfigError("config.forkContext.model must be a non-empty string");
32
+ }
33
+ if (config.mode === "pruned" && config.model === undefined) {
34
+ throw new PrunedForkConfigError('config.forkContext.model is required when config.forkContext.mode is "pruned"');
35
+ }
36
+ }
37
+
19
38
  function isValidKeyId(value: string): boolean {
20
39
  if (value !== value.trim()) return false;
21
40
  const parts = value.toLowerCase().split("+");
@@ -62,6 +81,31 @@ function validateArtifactConfig(value: unknown): void {
62
81
  }
63
82
  }
64
83
 
84
+ function validateCapacityConfig(value: unknown): void {
85
+ if (value === undefined) return;
86
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("config.capacity must be a JSON object");
87
+ const abandonedSlotReleaseAfterMs = (value as Record<string, unknown>).abandonedSlotReleaseAfterMs;
88
+ if (abandonedSlotReleaseAfterMs !== undefined
89
+ && abandonedSlotReleaseAfterMs !== false
90
+ && (typeof abandonedSlotReleaseAfterMs !== "number"
91
+ || !Number.isInteger(abandonedSlotReleaseAfterMs)
92
+ || abandonedSlotReleaseAfterMs < MIN_ABANDONED_SLOT_RELEASE_AFTER_MS
93
+ || abandonedSlotReleaseAfterMs > MAX_ABANDONED_SLOT_RELEASE_AFTER_MS)) {
94
+ throw new Error(`config.capacity.abandonedSlotReleaseAfterMs must be false or an integer from ${MIN_ABANDONED_SLOT_RELEASE_AFTER_MS} to ${MAX_ABANDONED_SLOT_RELEASE_AFTER_MS}`);
95
+ }
96
+ }
97
+
98
+ /** Validate the user-controlled TTL policy before it reaches the exclusion store. */
99
+ // TEST:test/unit/pi-coding-agent-dir.test.ts[loads and applies model exclusion TTL config]
100
+ function validateModelExclusionsConfig(value: unknown): void {
101
+ if (value === undefined) return;
102
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("config.modelExclusions must be a JSON object");
103
+ const defaultTtlMs = (value as Record<string, unknown>).defaultTtlMs;
104
+ if (defaultTtlMs !== undefined && (typeof defaultTtlMs !== "number" || !Number.isFinite(defaultTtlMs) || defaultTtlMs <= 0 || defaultTtlMs > MAX_MODEL_EXCLUSION_TTL_MS)) {
105
+ throw new Error(`config.modelExclusions.defaultTtlMs must be a finite positive number no greater than ${MAX_MODEL_EXCLUSION_TTL_MS}`);
106
+ }
107
+ }
108
+
65
109
  function validateOrcaProgressTabsConfig(value: unknown): void {
66
110
  if (value === undefined) return;
67
111
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("config.orcaProgressTabs must be a JSON object");
@@ -97,6 +141,7 @@ function validateConfig(config: Record<string, unknown>): void {
97
141
  if (config.defaultSubagentContext !== undefined && config.defaultSubagentContext !== "fresh" && config.defaultSubagentContext !== "fork") {
98
142
  throw new Error('config.defaultSubagentContext must be "fresh" or "fork"');
99
143
  }
144
+ validateForkContextConfig(config.forkContext);
100
145
  if (config.foregroundDetachShortcut !== undefined
101
146
  && (typeof config.foregroundDetachShortcut !== "string" || !isValidKeyId(config.foregroundDetachShortcut))) {
102
147
  throw new Error("config.foregroundDetachShortcut must be a valid keybinding string such as \"ctrl+b\"");
@@ -119,6 +164,8 @@ function validateConfig(config: Record<string, unknown>): void {
119
164
  validateScheduledRunsConfig(config.scheduledRuns);
120
165
  validateFleetKeybindingsConfig(config.fleetKeybindings);
121
166
  validateArtifactConfig(config.artifactConfig);
167
+ validateCapacityConfig(config.capacity);
168
+ validateModelExclusionsConfig(config.modelExclusions);
122
169
  validateMainWindowRendererConfig(config.mainWindowRenderer);
123
170
  validateOrcaProgressTabsConfig(config.orcaProgressTabs);
124
171
  }
@@ -150,6 +197,28 @@ export function updateConfig(updater: (config: ExtensionConfig) => ExtensionConf
150
197
  return next;
151
198
  }
152
199
 
200
+ /**
201
+ * Resolve the default TTL that the process-wide exclusion store should use.
202
+ *
203
+ * @param config Extension configuration after validation.
204
+ * @returns The configured TTL in milliseconds, or the built-in 24-hour default.
205
+ */
206
+ // TEST:test/unit/pi-coding-agent-dir.test.ts[loads and applies model exclusion TTL config]
207
+ export function resolveModelExclusionTTL(config: Pick<ExtensionConfig, "modelExclusions">): number {
208
+ return config.modelExclusions?.defaultTtlMs ?? DEFAULT_MODEL_EXCLUSION_TTL_MS;
209
+ }
210
+
211
+ /**
212
+ * Apply the configured exclusion policy to the process-wide model store.
213
+ *
214
+ * @param config Extension configuration after validation.
215
+ * @returns Nothing.
216
+ */
217
+ // TEST:test/unit/pi-coding-agent-dir.test.ts[loads and applies model exclusion TTL config]
218
+ export function applyModelExclusionsConfig(config: Pick<ExtensionConfig, "modelExclusions">): void {
219
+ setDefaultTTL(resolveModelExclusionTTL(config), { shortenExisting: config.modelExclusions?.defaultTtlMs !== undefined });
220
+ }
221
+
153
222
  export function resolveAsyncByDefault(config: Pick<ExtensionConfig, "asyncByDefault">): boolean {
154
223
  return config.asyncByDefault !== false;
155
224
  }
@@ -159,6 +228,7 @@ export function loadConfig(): ExtensionConfig {
159
228
  try {
160
229
  return readConfigForUpdate(configPath);
161
230
  } catch (error) {
231
+ if (error instanceof PrunedForkConfigError) throw error;
162
232
  console.error(`Failed to load subagent config from '${configPath}':`, error);
163
233
  }
164
234
  return {};
@@ -3,7 +3,7 @@ import * as path from "node:path";
3
3
  import { discoverAgentsAll, type AgentSource } from "../agents/agents.ts";
4
4
  import { isAsyncAvailable } from "../runs/background/async-execution.ts";
5
5
  import { formatSpawnBudgetSummary, getSpawnBudgetSnapshot } from "../runs/shared/spawn-budget.ts";
6
- import { getActiveAsyncCapacitySnapshot, resolveMaxActiveAsyncRunsPerSession } from "../runs/background/active-async-capacity.ts";
6
+ import { getActiveAsyncCapacitySnapshot, resolveAbandonedSlotReleaseAfterMs, resolveMaxActiveAsyncRunsPerSession } from "../runs/background/active-async-capacity.ts";
7
7
  import { decodeRunFanoutBudgetDescriptor, formatRunFanoutBudget, getRunFanoutBudgetSnapshot, RUN_FANOUT_BUDGET_ENV } from "../runs/shared/run-fanout-budget.ts";
8
8
  import { diagnoseIntercomBridge, type IntercomBridgeDiagnostic } from "../intercom/intercom-bridge.ts";
9
9
  import { discoverAvailableSkills, type SkillSource } from "../agents/skills.ts";
@@ -197,13 +197,13 @@ function formatActiveAsyncCapacitySection(input: DoctorReportInput): string[] {
197
197
  const limit = resolveMaxActiveAsyncRunsPerSession(input.config.maxActiveAsyncRunsPerSession);
198
198
  const sessionId = input.currentSessionId ?? input.state.currentSessionId;
199
199
  const snapshot = sessionId
200
- ? getActiveAsyncCapacitySnapshot(sessionId, limit, { liveWorkflowRunIds: new Set(input.state.workflowControllers?.keys() ?? []) })
200
+ ? getActiveAsyncCapacitySnapshot(sessionId, limit, { liveWorkflowRunIds: new Set(input.state.workflowControllers?.keys() ?? []), abandonedSlotReleaseAfterMs: resolveAbandonedSlotReleaseAfterMs(input.config.capacity?.abandonedSlotReleaseAfterMs) })
201
201
  : { used: 0, limit: limit ?? 0 };
202
202
  input.state.activeAsyncCapacity = snapshot;
203
203
  return [
204
204
  `- usage: ${snapshot.used}/${snapshot.limit || "unlimited"} used`,
205
205
  "- scope: top-level async runs in the current parent session; foreground and nested workflow children are not charged again",
206
- "- release: terminal logical state plus verified process exit; missing or unknown cleanup proof retains capacity",
206
+ "- release: terminal state plus matching observed process-terminal proof, or abandoned-timeout for failed runs with a dead runner PID and stale activity when enabled; false keeps unknown-proof slots",
207
207
  ];
208
208
  }
209
209
 
@@ -158,13 +158,15 @@ export default function registerFanoutChildSubagentExtension(pi: ExtensionAPI):
158
158
  registeredApis.add(pi);
159
159
 
160
160
  const config = loadConfig();
161
+ const waitToolConfig = resolveWaitToolConfig(config.waitTool);
161
162
  const state = createChildSafeState();
162
163
  const executor = createSubagentExecutor({
163
164
  pi,
164
165
  state,
165
166
  config,
166
167
  asyncByDefault: resolveAsyncByDefault(config),
167
- waitToolEnabled: resolveWaitToolConfig(config.waitTool).enabled,
168
+ waitToolEnabled: waitToolConfig.enabled,
169
+ waitToolDefaultTimeoutMs: waitToolConfig.defaultTimeoutMs,
168
170
  tempArtifactsDir: getArtifactsDir(null),
169
171
  getSubagentSessionRoot,
170
172
  expandTilde,
@@ -178,8 +180,8 @@ export default function registerFanoutChildSubagentExtension(pi: ExtensionAPI):
178
180
  label: "Subagent",
179
181
  description: [
180
182
  "Delegate to subagents from child-safe fanout mode.",
181
- "Allowed management/control actions: list, get, status, interrupt, resume, steer, doctor.",
182
- "Mutating management actions (create, update, delete, eject, disable, enable, reset, grant-spawn-budget) are blocked in this mode.",
183
+ "Allowed management/control actions: list, get, status, lane.status, interrupt, resume, steer, doctor.",
184
+ "Mutating management actions (create, update, delete, eject, disable, enable, reset, grant-spawn-budget, lane.recordMerge, lane.recordSupersession) are blocked in this mode.",
183
185
  ].join("\n"),
184
186
  parameters: params,
185
187
  async execute(id, params, signal, onUpdate, ctx) {