one-code-extension 0.4.0 → 0.5.0

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 (419) hide show
  1. package/README.md +219 -219
  2. package/agents/general-purpose.md +2 -2
  3. package/docs/guide/README.md +2 -1
  4. package/docs/guide/bring-your-claude-code-setup.md +60 -9
  5. package/docs/guide/configuration.md +48 -14
  6. package/docs/guide/differences-from-claude-code.md +32 -23
  7. package/docs/guide/doctor.md +20 -13
  8. package/docs/guide/hooks.md +18 -3
  9. package/docs/guide/installation.md +27 -4
  10. package/docs/guide/permissions-modes-and-auto-mode.md +225 -49
  11. package/docs/guide/providers-and-models.md +137 -54
  12. package/docs/guide/reference.md +27 -15
  13. package/docs/guide/sessions-and-context.md +69 -16
  14. package/docs/guide/skills-plugins-and-mcp.md +57 -20
  15. package/docs/guide/subagents-and-workflows.md +95 -29
  16. package/docs/guide/tasks-and-background-work.md +101 -26
  17. package/docs/guide/terminal-interface.md +24 -12
  18. package/docs/guide/tools.md +46 -5
  19. package/docs/guide/troubleshooting.md +13 -9
  20. package/docs/guide/windows.md +66 -34
  21. package/extensions/artifacts/gallery.ts +227 -0
  22. package/extensions/artifacts/index.ts +288 -0
  23. package/extensions/artifacts/store.ts +570 -0
  24. package/extensions/artifacts/viewer.ts +199 -0
  25. package/extensions/ask-user/description.ts +67 -0
  26. package/extensions/ask-user/dialogs.ts +80 -0
  27. package/extensions/ask-user/index.ts +37 -33
  28. package/extensions/ask-user/questions.ts +32 -7
  29. package/extensions/ask-user/widget.ts +45 -25
  30. package/extensions/auto-mode/actions.ts +6 -0
  31. package/extensions/auto-mode/cache.ts +88 -0
  32. package/extensions/auto-mode/classifier-prompt.ts +5 -4
  33. package/extensions/auto-mode/classifier.ts +290 -65
  34. package/extensions/auto-mode/config.ts +72 -20
  35. package/extensions/auto-mode/decision-log.ts +2 -0
  36. package/extensions/auto-mode/defaults.ts +1 -1
  37. package/extensions/auto-mode/denials.ts +123 -0
  38. package/extensions/auto-mode/git-checkout-programs.ts +187 -0
  39. package/extensions/auto-mode/git-status-meta.ts +159 -0
  40. package/extensions/auto-mode/history.ts +189 -0
  41. package/extensions/auto-mode/instructions.ts +58 -52
  42. package/extensions/auto-mode/model-select.ts +159 -134
  43. package/extensions/auto-mode/paths.ts +57 -5
  44. package/extensions/auto-mode/pause.ts +57 -2
  45. package/extensions/auto-mode/prompt.ts +37 -21
  46. package/extensions/auto-mode/read-only-options.ts +724 -0
  47. package/extensions/auto-mode/resolved-paths-meta.ts +133 -0
  48. package/extensions/auto-mode/rules.ts +18 -1
  49. package/extensions/auto-mode/safety-floor.ts +361 -18
  50. package/extensions/auto-mode/setup-run.ts +20 -14
  51. package/extensions/auto-mode/shell-analysis.ts +764 -490
  52. package/extensions/auto-mode/shell-parse.ts +885 -0
  53. package/extensions/auto-mode/system-note.ts +33 -0
  54. package/extensions/auto-mode/transcript.ts +80 -51
  55. package/extensions/background/cron.ts +515 -0
  56. package/extensions/background/index.ts +514 -236
  57. package/extensions/background/loop-fire.ts +136 -0
  58. package/extensions/background/loop-preamble.ts +59 -0
  59. package/extensions/background/loop-skill.ts +163 -0
  60. package/extensions/background/monitor-batch.ts +53 -0
  61. package/extensions/background/noop-fold.ts +128 -0
  62. package/extensions/background/switch-guard.ts +52 -0
  63. package/extensions/background/wakeup.ts +159 -55
  64. package/extensions/bash/background.ts +53 -17
  65. package/extensions/bash/child.ts +7 -0
  66. package/extensions/bash/description.ts +188 -0
  67. package/extensions/bash/guards.ts +15 -67
  68. package/extensions/bash/index.ts +88 -35
  69. package/extensions/branding/compaction-keep.ts +63 -0
  70. package/extensions/branding/declined.ts +22 -0
  71. package/extensions/branding/index.ts +133 -9
  72. package/extensions/branding/prompt-editor.ts +53 -6
  73. package/extensions/branding/queued-edit.ts +31 -0
  74. package/extensions/branding/replaced-builtins.ts +68 -0
  75. package/extensions/branding/startup.ts +33 -71
  76. package/extensions/btw/index.ts +229 -71
  77. package/extensions/btw/panel.ts +228 -100
  78. package/extensions/btw/prompt.ts +41 -4
  79. package/extensions/claude-compat/index.ts +7 -11
  80. package/extensions/claude-context/index.ts +446 -58
  81. package/extensions/compaction/cut.ts +157 -0
  82. package/extensions/compaction/index.ts +216 -75
  83. package/extensions/compaction/kept-thinking.ts +62 -0
  84. package/extensions/compaction/prompt.ts +15 -12
  85. package/extensions/context-budget/index.ts +24 -5
  86. package/extensions/context-management/index.ts +25 -0
  87. package/extensions/doctor/build.ts +59 -8
  88. package/extensions/doctor/builtins.ts +84 -0
  89. package/extensions/doctor/cli.ts +7 -1
  90. package/extensions/doctor/compat.ts +88 -23
  91. package/extensions/doctor/dependencies.ts +41 -5
  92. package/extensions/doctor/fix-prompt.ts +9 -2
  93. package/extensions/doctor/index.ts +102 -58
  94. package/extensions/doctor/models.ts +102 -63
  95. package/extensions/doctor/presets.ts +42 -27
  96. package/extensions/doctor/report.ts +19 -2
  97. package/extensions/doctor/viewer.ts +49 -27
  98. package/extensions/effort/index.ts +72 -19
  99. package/extensions/effort/settings.ts +21 -0
  100. package/extensions/effort/slider.ts +24 -20
  101. package/extensions/exit/index.ts +32 -1
  102. package/extensions/file-tracker/index.ts +337 -26
  103. package/extensions/file-tracker/replay.ts +96 -10
  104. package/extensions/file-tracker/restore.ts +63 -0
  105. package/extensions/file-tracker/results.ts +66 -0
  106. package/extensions/file-tracker/shell-reads.ts +211 -0
  107. package/extensions/file-tracker/tracker.ts +32 -15
  108. package/extensions/footer/footer-line.ts +45 -24
  109. package/extensions/footer/index.ts +47 -2
  110. package/extensions/footer/pr.ts +34 -5
  111. package/extensions/hooks/compaction.ts +7 -0
  112. package/extensions/hooks/executor.ts +32 -30
  113. package/extensions/hooks/index.ts +198 -31
  114. package/extensions/hooks/matcher.ts +3 -0
  115. package/extensions/hooks/protocol.ts +41 -3
  116. package/extensions/hooks/settings.ts +50 -19
  117. package/extensions/hooks/subagent-bridge.ts +2 -0
  118. package/extensions/hooks/trust.ts +13 -5
  119. package/extensions/idle-compact/index.ts +119 -0
  120. package/extensions/idle-compact/policy.ts +143 -0
  121. package/extensions/init/index.ts +11 -10
  122. package/extensions/init/prompt.ts +25 -32
  123. package/extensions/interrupted/index.ts +13 -1
  124. package/extensions/kept-thinking/index.ts +27 -0
  125. package/extensions/lib/agent-cron.ts +130 -0
  126. package/extensions/lib/agent-loader.ts +15 -1
  127. package/extensions/lib/agent-view.ts +85 -0
  128. package/extensions/lib/anthropic-payload.ts +82 -1
  129. package/extensions/lib/anthropic-server-call.ts +230 -0
  130. package/extensions/lib/anthropic-server-tools.ts +485 -0
  131. package/extensions/lib/app-launch.mjs +94 -0
  132. package/extensions/lib/argument-hints.ts +190 -0
  133. package/extensions/lib/atomic-write.ts +6 -2
  134. package/extensions/lib/auto-memory.ts +75 -0
  135. package/extensions/lib/bash-parser.ts +84 -0
  136. package/extensions/lib/btw-fork.ts +93 -0
  137. package/extensions/lib/child-extensions.ts +42 -0
  138. package/extensions/lib/child-writes.ts +45 -0
  139. package/extensions/lib/claude-context.ts +515 -100
  140. package/extensions/lib/claude-external-includes.ts +68 -0
  141. package/extensions/lib/claude-id.ts +22 -0
  142. package/extensions/lib/claude-rules.ts +323 -0
  143. package/extensions/lib/claude-settings.ts +76 -4
  144. package/extensions/lib/compaction-boundary.ts +36 -0
  145. package/extensions/lib/compaction-keep.mjs +83 -0
  146. package/extensions/lib/config-mode.ts +112 -0
  147. package/extensions/lib/consent-dialogs.ts +63 -0
  148. package/extensions/lib/consent-preview.ts +5 -1
  149. package/extensions/lib/consent-stores.ts +48 -0
  150. package/extensions/lib/context-facts.ts +78 -0
  151. package/extensions/lib/context-stack.ts +81 -0
  152. package/extensions/lib/deferred.ts +219 -25
  153. package/extensions/lib/dock-rows.ts +60 -0
  154. package/extensions/lib/empty-tool-result.ts +27 -0
  155. package/extensions/lib/environment-block.ts +76 -0
  156. package/extensions/lib/fetch-timeout.ts +24 -6
  157. package/extensions/{system-prompt → lib}/git-status.ts +51 -13
  158. package/extensions/lib/git.ts +75 -13
  159. package/extensions/lib/grammars/LICENSE-tree-sitter-bash +21 -0
  160. package/extensions/lib/grammars/README.md +2 -0
  161. package/extensions/lib/grammars/tree-sitter-bash.wasm +0 -0
  162. package/extensions/lib/guide-docs.ts +45 -0
  163. package/extensions/lib/headless-output.ts +46 -0
  164. package/extensions/lib/hook-gate.ts +7 -7
  165. package/extensions/lib/interrupt.ts +20 -4
  166. package/extensions/lib/key-input.ts +455 -0
  167. package/extensions/lib/keys.ts +14 -1
  168. package/extensions/lib/local-command.ts +47 -13
  169. package/extensions/lib/mcp-overrides.ts +1 -1
  170. package/extensions/lib/mcp-share.ts +46 -0
  171. package/extensions/lib/memory-content.ts +146 -0
  172. package/extensions/lib/memory-index.ts +18 -0
  173. package/extensions/lib/memory.ts +134 -123
  174. package/extensions/lib/model-catalog/huggingface.json +174 -0
  175. package/extensions/lib/model-catalog/models-dev.json +18297 -0
  176. package/extensions/lib/model-catalog/openrouter.json +5252 -0
  177. package/extensions/lib/model-catalog-data.ts +513 -0
  178. package/extensions/lib/model-catalog.ts +462 -0
  179. package/extensions/lib/model-choice-warnings.ts +137 -0
  180. package/extensions/lib/model-pairings.ts +152 -0
  181. package/extensions/{auto-mode → lib}/model-picker.ts +26 -43
  182. package/extensions/lib/model-policy.ts +112 -15
  183. package/extensions/lib/model-tier.ts +283 -355
  184. package/extensions/lib/model-unusable.ts +1 -1
  185. package/extensions/lib/newer-model.ts +100 -0
  186. package/extensions/lib/notices.ts +87 -0
  187. package/extensions/lib/notifications.ts +308 -64
  188. package/extensions/lib/one-code-settings.ts +74 -8
  189. package/extensions/lib/open-browser.ts +63 -0
  190. package/extensions/lib/openrouter-generation.ts +94 -0
  191. package/extensions/lib/operation-deadline.ts +30 -0
  192. package/extensions/lib/original-command.ts +4 -4
  193. package/extensions/lib/package-version.ts +1 -1
  194. package/extensions/lib/panel-focus.ts +134 -0
  195. package/extensions/lib/paths.ts +17 -2
  196. package/extensions/lib/permission-gate.ts +72 -6
  197. package/extensions/lib/persisted-output.ts +60 -8
  198. package/extensions/lib/pi-ai-estimate.ts +19 -3
  199. package/extensions/lib/pi-version.ts +21 -2
  200. package/extensions/lib/plan-mode-channels.ts +20 -5
  201. package/extensions/lib/plugins.ts +26 -17
  202. package/extensions/lib/powershell-parse-script.ts +208 -0
  203. package/extensions/lib/powershell-parser.ts +344 -0
  204. package/extensions/lib/process-tree.ts +131 -8
  205. package/extensions/lib/prompt-options.ts +82 -0
  206. package/extensions/lib/queued-delivery.ts +44 -0
  207. package/extensions/lib/reminders.ts +364 -58
  208. package/extensions/lib/replaced-builtins.mjs +199 -0
  209. package/extensions/lib/replay-call.ts +70 -0
  210. package/extensions/lib/request-replay.ts +439 -0
  211. package/extensions/lib/scratchpad.ts +81 -14
  212. package/extensions/lib/send-now-channel.ts +7 -0
  213. package/extensions/lib/session-model-tier.ts +51 -0
  214. package/extensions/lib/session-work.ts +64 -0
  215. package/extensions/lib/settings-channels.ts +4 -4
  216. package/extensions/lib/shell-exit-semantics.ts +170 -0
  217. package/extensions/lib/shell-quote.ts +11 -0
  218. package/extensions/lib/shell-result.ts +70 -0
  219. package/extensions/lib/shell-spawn.ts +70 -6
  220. package/extensions/lib/shell-tool.ts +75 -25
  221. package/extensions/lib/side-call-cache.ts +124 -0
  222. package/extensions/lib/side-call-run.ts +96 -0
  223. package/extensions/lib/side-call-usage.ts +38 -0
  224. package/extensions/lib/side-call.ts +13 -1
  225. package/extensions/lib/single-flight.ts +18 -0
  226. package/extensions/lib/skill-body.ts +42 -0
  227. package/extensions/lib/skill-scan.ts +63 -24
  228. package/extensions/lib/spill-file.ts +140 -0
  229. package/extensions/lib/subagent-handback.ts +113 -0
  230. package/extensions/lib/system-role.ts +156 -0
  231. package/extensions/lib/terminal-text.ts +114 -0
  232. package/extensions/lib/text-width.ts +47 -16
  233. package/extensions/lib/timer-ops.ts +20 -0
  234. package/extensions/lib/tool-additions.ts +149 -0
  235. package/extensions/lib/tool-call-corruption.ts +134 -0
  236. package/extensions/lib/tool-path.ts +66 -0
  237. package/extensions/lib/tool-variants.ts +69 -0
  238. package/extensions/lib/tui-render.ts +255 -27
  239. package/extensions/lib/turn-budget-layout.ts +143 -0
  240. package/extensions/lib/update-check.mjs +15 -2
  241. package/extensions/lib/usage-bus.ts +1 -1
  242. package/extensions/lib/user-denial.ts +38 -0
  243. package/extensions/lib/workspace-channel.ts +16 -0
  244. package/extensions/lib/worktree-channel.ts +31 -3
  245. package/extensions/lib/worktree-isolation.ts +40 -10
  246. package/extensions/lsp/client.ts +8 -9
  247. package/extensions/lsp/index.ts +70 -4
  248. package/extensions/lsp/keep-alive.ts +1 -1
  249. package/extensions/lsp/trust.ts +119 -0
  250. package/extensions/lsp/watcher.ts +1 -1
  251. package/extensions/mcp/announce.ts +87 -5
  252. package/extensions/mcp/client.ts +161 -48
  253. package/extensions/mcp/config.ts +132 -8
  254. package/extensions/mcp/discovery.ts +19 -0
  255. package/extensions/mcp/index.ts +209 -71
  256. package/extensions/mcp/oauth/browser.ts +38 -17
  257. package/extensions/mcp/oauth/flow.ts +25 -17
  258. package/extensions/mcp/oauth/provider.ts +14 -8
  259. package/extensions/mcp/oauth/store.ts +34 -16
  260. package/extensions/mcp/panel/keys.ts +12 -11
  261. package/extensions/mcp/panel/render.ts +9 -6
  262. package/extensions/mcp/schema.ts +104 -5
  263. package/extensions/mcp/trust.ts +151 -67
  264. package/extensions/memory/entries.ts +23 -14
  265. package/extensions/memory/index.ts +134 -28
  266. package/extensions/memory/open-external.ts +33 -18
  267. package/extensions/memory/panel.ts +135 -26
  268. package/extensions/newer-model/index.ts +31 -0
  269. package/extensions/notebook/description.ts +18 -0
  270. package/extensions/notebook/index.ts +6 -5
  271. package/extensions/notebook/notebook.ts +1 -1
  272. package/extensions/permissions/index.ts +1300 -381
  273. package/extensions/permissions/matcher.ts +425 -74
  274. package/extensions/permissions/modes.ts +6 -4
  275. package/extensions/permissions/panel/host.ts +130 -0
  276. package/extensions/permissions/panel/keys.ts +48 -0
  277. package/extensions/permissions/panel/render.ts +450 -0
  278. package/extensions/permissions/panel/state.ts +550 -0
  279. package/extensions/permissions/powershell-cmdlets.ts +198 -0
  280. package/extensions/permissions/powershell-paths.ts +197 -0
  281. package/extensions/permissions/powershell-rules.ts +207 -280
  282. package/extensions/permissions/powershell-tree.ts +557 -0
  283. package/extensions/permissions/project-trust.ts +27 -11
  284. package/extensions/permissions/protected-paths.ts +14 -2
  285. package/extensions/permissions/session-grant.ts +6 -0
  286. package/extensions/permissions/settings.ts +166 -31
  287. package/extensions/permissions/subagent-gate.ts +25 -0
  288. package/extensions/permissions/workspace.ts +78 -0
  289. package/extensions/plan-mode/index.ts +156 -69
  290. package/extensions/plan-mode/reminder.ts +89 -21
  291. package/extensions/plan-mode/texts.ts +177 -0
  292. package/extensions/plan-mode/viewer.ts +92 -27
  293. package/extensions/plugins/counts.ts +3 -3
  294. package/extensions/plugins/index.ts +61 -46
  295. package/extensions/plugins/install/install.ts +16 -0
  296. package/extensions/plugins/marketplace/sync.ts +9 -3
  297. package/extensions/plugins/marketplace/types.ts +3 -1
  298. package/extensions/plugins/panel/keys.ts +21 -24
  299. package/extensions/plugins/panel/render.ts +12 -6
  300. package/extensions/plugins/shell-expand.ts +107 -0
  301. package/extensions/plugins/template.ts +32 -15
  302. package/extensions/powershell/child.ts +7 -0
  303. package/extensions/powershell/description.ts +38 -6
  304. package/extensions/powershell/guards.ts +1 -1
  305. package/extensions/powershell/index.ts +12 -7
  306. package/extensions/recap/index.ts +65 -60
  307. package/extensions/recap/prompt.ts +2 -2
  308. package/extensions/recap/scheduler.ts +3 -5
  309. package/extensions/search-tools/grep-merge.ts +39 -0
  310. package/extensions/search-tools/index.ts +0 -0
  311. package/extensions/send-now/chord.ts +62 -0
  312. package/extensions/send-now/index.ts +133 -0
  313. package/extensions/session-title/index.ts +3 -0
  314. package/extensions/session-title/title.ts +4 -1
  315. package/extensions/skill/code-review.ts +97 -0
  316. package/extensions/skill/index.ts +421 -101
  317. package/extensions/skill/invoke.ts +128 -18
  318. package/extensions/skill/listing.ts +133 -9
  319. package/extensions/skill/panel/keys.ts +15 -16
  320. package/extensions/skill/panel/render.ts +5 -2
  321. package/extensions/skill/panel/state.ts +12 -1
  322. package/extensions/subagents/agent-args.ts +39 -0
  323. package/extensions/subagents/agent-description.ts +132 -0
  324. package/extensions/subagents/agents.ts +116 -23
  325. package/extensions/subagents/announce.ts +69 -0
  326. package/extensions/subagents/default-model.ts +2 -3
  327. package/extensions/subagents/delegation-steer.ts +4 -4
  328. package/extensions/subagents/fork-cache.ts +76 -0
  329. package/extensions/subagents/guide-agent.ts +189 -0
  330. package/extensions/subagents/hand-back-review.ts +3 -0
  331. package/extensions/subagents/index.ts +1493 -824
  332. package/extensions/subagents/live-runs.ts +26 -6
  333. package/extensions/subagents/model-select.ts +38 -25
  334. package/extensions/subagents/outcome.ts +2 -2
  335. package/extensions/subagents/panel-keys.ts +73 -31
  336. package/extensions/subagents/panel-render.ts +120 -96
  337. package/extensions/subagents/panel-widget.ts +60 -89
  338. package/extensions/subagents/runner.ts +108 -80
  339. package/extensions/subagents/runs.ts +39 -5
  340. package/extensions/subagents/send-to-main-tool.ts +1 -1
  341. package/extensions/subagents/session-turns.ts +32 -8
  342. package/extensions/subagents/shell-panel.ts +36 -178
  343. package/extensions/subagents/tasks-dialog.ts +170 -0
  344. package/extensions/subagents/viewport-mirror.ts +95 -0
  345. package/extensions/subagents/worktree.ts +57 -13
  346. package/extensions/system-prompt/environment.ts +19 -19
  347. package/extensions/system-prompt/idle-turn.ts +65 -0
  348. package/extensions/system-prompt/index.ts +131 -47
  349. package/extensions/system-prompt/template.ts +24 -50
  350. package/extensions/system-prompt/tiers/common.ts +23 -64
  351. package/extensions/system-prompt/tiers/frontier.ts +32 -11
  352. package/extensions/system-prompt/tiers/low.ts +67 -45
  353. package/extensions/system-prompt/tiers/mid.ts +96 -38
  354. package/extensions/system-reminder/index.ts +175 -13
  355. package/extensions/tasks/descriptions.ts +190 -0
  356. package/extensions/tasks/index.ts +120 -41
  357. package/extensions/tasks/store.ts +83 -16
  358. package/extensions/tool-call-corruption/child.ts +7 -0
  359. package/extensions/tool-call-corruption/index.ts +237 -0
  360. package/extensions/tool-search/announce.ts +16 -0
  361. package/extensions/tool-search/index.ts +189 -41
  362. package/extensions/tool-style/index.ts +68 -10
  363. package/extensions/tool-style/write-description.ts +40 -0
  364. package/extensions/tool-style/write-render.ts +237 -0
  365. package/extensions/turn-duration/index.ts +7 -3
  366. package/extensions/turn-duration/line.ts +47 -4
  367. package/extensions/web/backends.ts +6 -9
  368. package/extensions/web/description.ts +50 -0
  369. package/extensions/web/index.ts +118 -53
  370. package/extensions/web/native-call.ts +15 -0
  371. package/extensions/web/native-results.ts +41 -0
  372. package/extensions/web-fetch/description.ts +42 -0
  373. package/extensions/web-fetch/extract.ts +53 -6
  374. package/extensions/web-fetch/index.ts +125 -76
  375. package/extensions/web-fetch/page-content.ts +19 -0
  376. package/extensions/web-fetch/response.ts +49 -0
  377. package/extensions/web-fetch/summarize.ts +9 -10
  378. package/extensions/workflow/agent-session.ts +105 -18
  379. package/extensions/workflow/args.ts +24 -0
  380. package/extensions/workflow/description.ts +67 -0
  381. package/extensions/workflow/globals.ts +17 -3
  382. package/extensions/workflow/index.ts +145 -162
  383. package/extensions/workflow/records.ts +1 -0
  384. package/extensions/workflow/run-manager.ts +29 -6
  385. package/extensions/workflow/saved-workflows.ts +3 -2
  386. package/extensions/workflow/types.ts +22 -1
  387. package/extensions/workflow/viewer.ts +54 -24
  388. package/extensions/workflow/widget.ts +20 -0
  389. package/extensions/worktree/descriptions.ts +91 -0
  390. package/extensions/worktree/guards.ts +316 -54
  391. package/extensions/worktree/index.ts +121 -39
  392. package/extensions/worktree/powershell-guards.ts +167 -0
  393. package/extensions/worktree/rewrite.ts +14 -16
  394. package/package.json +19 -7
  395. package/skills/artifact-design/SKILL.md +85 -0
  396. package/skills/code-review/SKILL.md +20 -20
  397. package/skills/code-review/cells/arguments-and-flags.md +19 -0
  398. package/skills/code-review/cells/high-3x5-recall-verify.md +137 -0
  399. package/skills/code-review/cells/high-8-inline.md +122 -0
  400. package/skills/code-review/cells/low-1-pass-max4.md +27 -0
  401. package/skills/code-review/cells/low-1-pass-min-files-4.md +28 -0
  402. package/skills/code-review/cells/max-5x5-verify-sweep.md +162 -0
  403. package/skills/code-review/cells/medium-3x5-verify.md +132 -0
  404. package/skills/code-review/cells/minimal-prompt.md +32 -0
  405. package/skills/code-review/cells/xhigh-10-inline-sweep.md +149 -0
  406. package/skills/code-review/cells/xhigh-5x5-verify-sweep.md +162 -0
  407. package/skills/fewer-permission-prompts/SKILL.md +1 -1
  408. package/skills/loop/SKILL.md +11 -0
  409. package/skills/security-review/SKILL.md +2 -5
  410. package/skills/simplify/SKILL.md +7 -5
  411. package/skills/workflow-authoring/SKILL.md +143 -0
  412. package/themes/onecode-light.json +1 -1
  413. package/themes/onecode.json +1 -1
  414. package/types/app.d.ts +58 -0
  415. package/types/community-packages.d.ts +26 -1
  416. package/extensions/auto-mode/recoverability.ts +0 -229
  417. package/extensions/lib/capability-index.ts +0 -466
  418. package/extensions/lib/model-facts.generated.json +0 -2675
  419. package/extensions/lib/model-facts.ts +0 -162
@@ -14,13 +14,16 @@
14
14
  * `extensionFactories`, which DefaultResourceLoader always loads.
15
15
  */
16
16
 
17
+ import { childWriteWatcher } from "../lib/child-writes.ts";
18
+ import { randomBytes } from "node:crypto";
17
19
  import os from "node:os";
18
20
  import { getAgentDir, type ModelRuntime, SessionManager, type ToolDefinition } from "@earendil-works/pi-coding-agent";
19
21
  import type { AgentMessage } from "@earendil-works/pi-agent-core";
20
22
  import type { Api, Model } from "@earendil-works/pi-ai";
21
23
  import { Type } from "typebox";
22
24
  import { whenAborted } from "../lib/abort.ts";
23
- import { createSharedModelRuntime, finalAssistantText, openChildSession } from "../lib/agent-loader.ts";
25
+ import { persistIfLarge, sessionResultsDir } from "../lib/persisted-output.ts";
26
+ import { createSharedModelRuntime, disposeChildSession, finalAssistantText, openChildSession } from "../lib/agent-loader.ts";
24
27
  import { modelSpec as modelSpecOf, supportsImageInput } from "../lib/model-policy.ts";
25
28
  import { isModelUnavailableError } from "../auto-mode/model-select.ts";
26
29
  import { agentPromptIdentity, PrefixWarmGate, prefixWarmKey } from "../lib/prefix-warm-gate.ts";
@@ -28,12 +31,15 @@ import type { PermissionBridge } from "../permissions/subagent-gate.ts";
28
31
  import { localGateMode, MODE_ENV } from "../lib/permission-gate.ts";
29
32
  import type { HookBridge } from "../hooks/subagent-bridge.ts";
30
33
  import { summarizeArgs } from "../lib/tui-render.ts";
31
- import { agentDirs, type AgentDefinition, discoverAgents } from "../subagents/agents.ts";
34
+ import { type AgentDefinition, agentFileSources, agentToolOptions, discoverAgents, unusableAllowlistError } from "../subagents/agents.ts";
35
+ import { defaultDiscoverRoots, discoverPlugins } from "../lib/plugins.ts";
36
+ import { CHILD_EXTENSION_PATHS } from "../lib/child-extensions.ts";
37
+ import { oneTurnHandbackSlot, subagentHandbackExtension } from "../lib/subagent-handback.ts";
32
38
  import type { SubagentDefault } from "../subagents/default-model.ts";
33
39
  import { expensiveModelGate, resolveSubagentModel, subagentModelMenu } from "../subagents/model-select.ts";
34
40
  import { withoutUnusable } from "../lib/model-unusable.ts";
35
41
  import { cleanupWorktree, createWorktree, isGitRepo, type Worktree } from "../subagents/worktree.ts";
36
- import type { AgentCallOptions, AgentCallResult, AgentEffort, AgentRunUpdate } from "./types.ts";
42
+ import type { AgentCallOptions, AgentCallResult, AgentEffort, AgentRunUpdate, KeptWorktree } from "./types.ts";
37
43
  import { WorkflowScriptError } from "./types.ts";
38
44
 
39
45
  const MAX_SCHEMA_RETRIES = 2;
@@ -52,6 +58,8 @@ export interface AgentRunnerOptions {
52
58
  unusableModels?: () => ReadonlySet<string>;
53
59
  /** An agent's provider refused its model as not usable on this account (`isModelUnavailableError`): report it so every picker skips it. */
54
60
  onModelUnusable?: (model: string, reason: string) => void;
61
+ /** An agent's edit or write changed a file (lib/child-writes.ts), for the parent's file-tracker. */
62
+ onChildWrite?: (path: string, agent: string | undefined) => void;
55
63
  /**
56
64
  * The parent permissions extension's decision closure (same bridge the
57
65
  * subagent runner uses): when present, a workflow agent's tool calls route
@@ -65,6 +73,13 @@ export interface AgentRunnerOptions {
65
73
  getHookBridge?: () => HookBridge | undefined;
66
74
  /** Each finished agent's dollar cost (review S13: workflow agents never reached the footer). */
67
75
  onUsage?: (cost: number) => void;
76
+ /**
77
+ * The parent's live MCP tools (lib/mcp-share.ts `watchMcpTools`), injected
78
+ * as custom tools over the parent's connections, as the subagent runner does.
79
+ */
80
+ getMcpTools?: () => ToolDefinition[] | Promise<ToolDefinition[]>;
81
+ /** Where an answer past OUTPUT_CAP is saved (`<dir>/tool-results/`): the run's directory. */
82
+ resultsDir?: string;
68
83
  }
69
84
 
70
85
  /**
@@ -199,7 +214,9 @@ export class AgentRunner {
199
214
  static async create(options: AgentRunnerOptions): Promise<AgentRunner> {
200
215
  const agentDir = getAgentDir();
201
216
  const modelRuntime = await createSharedModelRuntime(agentDir);
202
- const agentCatalog = discoverAgents(agentDirs(options.cwd, os.homedir()));
217
+ // The Agent tool's registry: bundled and plugin agents too, not only the user and project folders.
218
+ const plugins = discoverPlugins(defaultDiscoverRoots(agentDir, options.cwd));
219
+ const agentCatalog = discoverAgents(agentFileSources(options.cwd, os.homedir(), plugins.agentDirs));
203
220
  const availableModels = [...(await modelRuntime.getAvailable())];
204
221
  return new AgentRunner(options, modelRuntime, agentCatalog, availableModels);
205
222
  }
@@ -245,6 +262,12 @@ export class AgentRunner {
245
262
 
246
263
  await this.judgeDelegation(prompt, opts, agentDef, signal);
247
264
 
265
+ // Before the worktree exists: a malformed schema would otherwise leak it.
266
+ if (opts.schema) assertObjectSchema(opts.schema);
267
+
268
+ // Also before the worktree: a rejection here would leak it the same way.
269
+ const mcpTools = (await this.options.getMcpTools?.()) ?? [];
270
+
248
271
  let worktree: Worktree | undefined;
249
272
  let cwd = this.options.cwd;
250
273
  if (opts.isolation === "worktree") {
@@ -256,13 +279,27 @@ export class AgentRunner {
256
279
  }
257
280
 
258
281
  const capture: { called: boolean; value: unknown } = { called: false, value: undefined };
259
- const customTools: ToolDefinition[] = opts.schema ? [buildStructuredOutputTool(opts.schema, capture)] : [];
282
+ // An agent without a schema hands its answer back through SubagentHandback,
283
+ // as every child does; with a schema, structured_output is the hand-back.
284
+ const handback = opts.schema ? undefined : oneTurnHandbackSlot();
285
+ const customTools: ToolDefinition[] = [
286
+ ...(opts.schema ? [buildStructuredOutputTool(opts.schema, capture)] : []),
287
+ ...mcpTools,
288
+ ];
260
289
 
290
+ // The same child session a subagent gets (SUBAGENTS-WORKFLOWS-REVIEW-2026-09-26
291
+ // H2, H3, M6): the curated child extensions, the parent's MCP tools, and the
292
+ // agent file's tool lists through the one shared builder, which keeps
293
+ // `structured_output` on an allowlist and applies `disallowedTools`.
261
294
  const session = await openChildSession({
262
295
  loader: {
263
296
  cwd: this.options.cwd,
264
297
  agentDir: getAgentDir(),
265
298
  systemPrompt: agentDef?.systemPrompt,
299
+ extraExtensionPaths: CHILD_EXTENSION_PATHS,
300
+ // claude-context (a child extension) injects the CLAUDE.md instructions itself.
301
+ noContextFiles: true,
302
+ ...(handback ? { extraFactories: [subagentHandbackExtension(handback)] } : {}),
266
303
  getPermissionBridge: this.options.getPermissionBridge,
267
304
  getHookBridge: this.options.getHookBridge,
268
305
  },
@@ -272,11 +309,16 @@ export class AgentRunner {
272
309
  modelRuntime: this.modelRuntime,
273
310
  model: modelSpec.model as never,
274
311
  thinkingLevel: modelSpec.thinkingLevel as never,
275
- tools: agentDef?.tools,
312
+ ...agentToolOptions(agentDef),
276
313
  customTools,
277
314
  sessionManager: SessionManager.inMemory(cwd),
278
315
  },
279
316
  onError: (error) => this.options.onNotice?.(`${opts.label ?? "agent"}: extension error in ${error.event}: ${error.error}`),
317
+ }).catch(async (error: unknown) => {
318
+ // Not yet under the prompt's try/finally: a session that fails to open
319
+ // must not leak the worktree and its branch.
320
+ if (worktree) await this.settleWorktree(worktree, opts.label, error);
321
+ throw error;
280
322
  });
281
323
 
282
324
  const unhookAbort = whenAborted(signal, () => void session.abort());
@@ -284,8 +326,11 @@ export class AgentRunner {
284
326
  // refusing the agent's model (the same check the subagent runner makes, so
285
327
  // the refusal reaches every automatic picker — lib/model-unusable.ts).
286
328
  // Never let a bad event shape kill the agent.
329
+ const childWrote = childWriteWatcher(session.sessionManager?.getCwd?.() ?? this.options.cwd);
287
330
  const unsubscribe = session.subscribe((event) => {
288
331
  try {
332
+ const wrote = childWrote(event as never);
333
+ if (wrote) this.options.onChildWrite?.(wrote, opts.label);
289
334
  if (event.type === "message_end") {
290
335
  const reply = (event as { message?: { role?: string; stopReason?: string; errorMessage?: string; provider?: string; model?: string } }).message;
291
336
  if (reply?.role === "assistant" && reply.stopReason === "error" && reply.errorMessage && reply.provider && reply.model && isModelUnavailableError(reply.errorMessage)) {
@@ -310,7 +355,17 @@ export class AgentRunner {
310
355
  prefixWarmKey(agentPromptIdentity(agentDef?.name), cwd, model ? modelSpecOf(model) : undefined),
311
356
  session,
312
357
  );
358
+ let failure: unknown;
313
359
  try {
360
+ // An allowlist that matched no real tool would run a tool-less agent.
361
+ const unusable = unusableAllowlistError(
362
+ agentDef,
363
+ session.getAllTools().map((t) => t.name),
364
+ );
365
+ if (unusable) throw new WorkflowScriptError(unusable);
366
+ // A stop during the waits above (MCP tools still connecting, the warm
367
+ // gate) aborted a session that was idle: never send the first request.
368
+ if (signal.aborted) throw new WorkflowScriptError("aborted");
314
369
  await session.prompt(this.buildPrompt(prompt, Boolean(opts.schema)));
315
370
  if (signal.aborted) throw new WorkflowScriptError("aborted");
316
371
 
@@ -318,27 +373,39 @@ export class AgentRunner {
318
373
  if (opts.schema) {
319
374
  value = await this.resolveStructuredOutput(session, capture, signal);
320
375
  } else {
321
- value = finalAssistantText(session.messages);
376
+ // The handed-back report, else the agent's last message.
377
+ value = handback?.report ?? finalAssistantText(session.messages);
322
378
  if (typeof value !== "string" || !value.trim()) {
323
379
  throw new Error("subagent produced no output");
324
380
  }
325
- value = (value as string).slice(0, OUTPUT_CAP);
381
+ // Never cut: a long answer is saved to the run directory and the script
382
+ // gets Claude Code's <persisted-output> block naming the file, which a
383
+ // later agent can read (SUBAGENTS-WORKFLOWS-REVIEW-2026-09-26 M1).
384
+ value = persistIfLarge(value as string, {
385
+ dir: this.options.resultsDir ?? sessionResultsDir(undefined),
386
+ id: `agent-${randomBytes(4).toString("hex")}`,
387
+ maxBytes: OUTPUT_CAP,
388
+ });
326
389
  }
327
390
 
328
391
  const stats = session.getSessionStats();
329
- // cleanupWorktree keeps trees holding uncommitted changes; report those.
330
- let worktreePath: string | undefined;
392
+ // cleanupWorktree keeps trees holding uncommitted changes or commits; report those.
393
+ let kept: Worktree | undefined;
331
394
  if (worktree) {
332
395
  const removed = await cleanupWorktree(this.options.cwd, worktree);
333
- if (!removed) worktreePath = worktree.path;
396
+ if (!removed) kept = worktree;
334
397
  worktree = undefined;
335
398
  }
336
399
  return {
337
400
  value,
338
401
  tokens: { input: stats.tokens.input, output: stats.tokens.output, total: stats.tokens.total },
339
402
  cost: stats.cost,
340
- worktreePath,
403
+ worktreePath: kept?.path,
404
+ worktreeBranch: kept?.branch,
341
405
  };
406
+ } catch (error) {
407
+ failure = error;
408
+ throw error;
342
409
  } finally {
343
410
  // Whatever the outcome — success, failure, or an abort (a user stop, or
344
411
  // the run finishing with this agent un-awaited) — the provider was
@@ -348,11 +415,26 @@ export class AgentRunner {
348
415
  releasePrefix(false);
349
416
  unsubscribe?.();
350
417
  unhookAbort();
351
- session.dispose();
352
- if (worktree) await cleanupWorktree(this.options.cwd, worktree);
418
+ disposeChildSession(session);
419
+ // A failed or aborted agent can still have edited or committed in its
420
+ // worktree: settled after the session is gone, before the error reaches
421
+ // the caller, so the kept path rides on it.
422
+ if (worktree) await this.settleWorktree(worktree, opts.label, failure);
353
423
  }
354
424
  }
355
425
 
426
+ /**
427
+ * Remove a failed agent's worktree, or keep it when it holds changes or
428
+ * commits: then the run log names it, and the kept path rides on `error`
429
+ * (`keptWorktreeOf`) so the agent's end event and the run report list it.
430
+ */
431
+ private async settleWorktree(worktree: Worktree, label: string | undefined, error: unknown): Promise<void> {
432
+ if (await cleanupWorktree(this.options.cwd, worktree)) return;
433
+ const kept: KeptWorktree = { path: worktree.path, branch: worktree.branch };
434
+ this.options.onNotice?.(`${label ?? "agent"}: worktree kept at ${kept.path} (branch ${kept.branch}) with its changes or commits`);
435
+ if (error instanceof Error) (error as Error & { keptWorktree?: KeptWorktree }).keptWorktree = kept;
436
+ }
437
+
356
438
  private judgeDelegation(prompt: string, opts: AgentCallOptions, agentDef: AgentDefinition | undefined, signal: AbortSignal): Promise<void> {
357
439
  return judgeWorkflowDelegation({
358
440
  bridge: this.options.getPermissionBridge?.(),
@@ -367,7 +449,7 @@ export class AgentRunner {
367
449
 
368
450
  private buildPrompt(prompt: string, structured: boolean): string {
369
451
  if (!structured) {
370
- return `${prompt}\n\nYour final message is returned verbatim to an orchestration script, not shown to a human — reply with the requested data/report only.`;
452
+ return `${prompt}\n\nThe report you hand back through SubagentHandback is returned verbatim to an orchestration script, not shown to a human — hand back the requested data/report only.`;
371
453
  }
372
454
  return `${prompt}\n\nWhen you are done, you MUST call the \`structured_output\` tool exactly once with your final result. Its arguments are the only output the caller receives.`;
373
455
  }
@@ -398,9 +480,7 @@ export class AgentRunner {
398
480
 
399
481
  /** Terminating tool capturing schema-validated output (pi validates params pre-execute). */
400
482
  function buildStructuredOutputTool(schema: Record<string, unknown>, capture: { called: boolean; value: unknown }): ToolDefinition {
401
- if (schema.type !== "object" || typeof schema.properties !== "object") {
402
- throw new WorkflowScriptError("agent() schema must be a JSON Schema with top-level type \"object\" and properties");
403
- }
483
+ assertObjectSchema(schema);
404
484
  return {
405
485
  name: "structured_output",
406
486
  label: "Structured Output",
@@ -418,6 +498,13 @@ function buildStructuredOutputTool(schema: Record<string, unknown>, capture: { c
418
498
  } as ToolDefinition;
419
499
  }
420
500
 
501
+ /** A structured_output schema must be an object schema with properties. */
502
+ function assertObjectSchema(schema: Record<string, unknown>): void {
503
+ if (schema.type !== "object" || typeof schema.properties !== "object") {
504
+ throw new WorkflowScriptError("agent() schema must be a JSON Schema with top-level type \"object\" and properties");
505
+ }
506
+ }
507
+
421
508
  /** Pull the first parseable JSON object/array out of free text (```json fences first). */
422
509
  function extractJsonObject(text: string): unknown {
423
510
  const fenced = text.match(/```(?:json)?\s*\n([\s\S]*?)\n```/);
@@ -0,0 +1,24 @@
1
+ /** The workflow tool's argument preparation (pure). */
2
+
3
+ /**
4
+ * The call's arguments with `args` as the script should see it, decoded before
5
+ * the gate, hooks and the stored call see them. Weak models send a list or
6
+ * object as a JSON-encoded string despite the description (every Qwen 3.8
7
+ * model, battery round 7), which breaks `args.map` and `pipeline(args, …)`; a
8
+ * string that parses to an array or object is decoded. Any other value passes
9
+ * verbatim.
10
+ */
11
+ export function prepareWorkflowArguments(raw: unknown): unknown {
12
+ if (!raw || typeof raw !== "object" || !("args" in raw)) return raw;
13
+ return { ...raw, args: decodedArgs((raw as { args: unknown }).args) };
14
+ }
15
+
16
+ function decodedArgs(args: unknown): unknown {
17
+ if (typeof args !== "string" || !/^\s*[[{]/.test(args)) return args;
18
+ try {
19
+ const parsed: unknown = JSON.parse(args);
20
+ return parsed !== null && typeof parsed === "object" ? parsed : args;
21
+ } catch {
22
+ return args;
23
+ }
24
+ }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * The workflow tool's model-facing description: Claude Code's Workflow text
3
+ * and its size-guideline line (pure).
4
+ *
5
+ * The authoring reference (script API, quality patterns, resume, worked
6
+ * examples) is the bundled `workflow-authoring` skill, which the description
7
+ * tells the model to load before writing a script. The size line follows
8
+ * `workflowSizeGuideline` in One Code's settings (lib/one-code-settings.ts);
9
+ * "unrestricted" sends no line, as in Claude Code. Changes from Claude Code's
10
+ * text: the setting is named where Claude Code points to its /config row, and
11
+ * tool names are One Code's.
12
+ */
13
+
14
+ import type { WorkflowSizeGuideline } from "../lib/one-code-settings.ts";
15
+
16
+ export const WORKFLOW_DESCRIPTION_BODY = `Execute a workflow script that orchestrates multiple subagents deterministically. Workflows run in the background — this tool returns immediately with a task ID, and a <task-notification> arrives when the workflow completes. Use /workflows to watch live progress.
17
+
18
+ ONLY call this tool when the user has explicitly opted into multi-agent orchestration. Workflows can spawn dozens of agents and consume a large amount of tokens; the user must request that scale, not have it inferred. Explicit opt-in means one of:
19
+ - The user included the keyword "ultracode" in their prompt (you'll see a system-reminder confirming it).
20
+ - Ultracode is on for the session (a system-reminder confirms it) — see **Ultracode** in the workflow authoring reference.
21
+ - The user directly asked you to run a workflow or use multi-agent orchestration in their own words ("use a workflow", "run a workflow", "fan out agents", "orchestrate this with subagents"). The ask must be in the user's words — a task that would merely benefit from a workflow does not count.
22
+ - The user invoked a skill or slash command whose instructions tell you to call Workflow.
23
+ - The user asked you to run a specific named or saved workflow.
24
+
25
+ For any other task — even one that would clearly benefit from parallelism — do NOT call this tool. Use the Agent tool (if available) for individual subagents, or briefly describe what a multi-agent workflow could do and how much it would roughly cost, and ask the user whether to run it. Mention they can ask for one with "use a workflow" in a future message to skip the ask.
26
+
27
+ Every script must begin with \`export const meta = {...}\`: a PURE LITERAL (no variables, calls or interpolation) giving the workflow's \`name\`, a one-line \`description\` (shown in the permission dialog) and optionally \`phases\` — one \`{ title, detail? }\` per phase() call, titles matched exactly. Pass the script inline via \`script\` — do not write it to a file first, and do not also set the tool's \`name\` input (that selects a saved workflow); it is plain JavaScript, not TypeScript.
28
+
29
+ The canonical multi-stage pattern — pipeline by default, each dimension verifies as soon as its review completes:
30
+ export const meta = {
31
+ name: 'review-changes',
32
+ description: 'Review changed files across dimensions, verify each finding',
33
+ phases: [{ title: 'Review' }, { title: 'Verify' }],
34
+ }
35
+ const DIMENSIONS = [{key: 'bugs', prompt: '...'}, {key: 'perf', prompt: '...'}]
36
+ const results = await pipeline(
37
+ DIMENSIONS,
38
+ d => agent(d.prompt, {label: \`review:\${d.key}\`, phase: 'Review', schema: FINDINGS_SCHEMA}),
39
+ review => parallel(review.findings.map(f => () =>
40
+ agent(\`Adversarially verify: \${f.title}\`, {label: \`verify:\${f.file}\`, phase: 'Verify', schema: VERDICT_SCHEMA})
41
+ .then(v => ({...f, verdict: v}))
42
+ ))
43
+ )
44
+ const confirmed = results.flat().filter(Boolean).filter(f => f.verdict?.isReal)
45
+ return { confirmed }
46
+ // Dimension 'bugs' findings verify while dimension 'perf' is still reviewing. No wasted wall-clock.
47
+
48
+ Before writing a script, load the \`workflow-authoring\` skill — the workflow authoring reference: script API and gotchas, resume, the **Ultracode** section, quality patterns, worked examples.`;
49
+
50
+ /** The agent count each size keeps a workflow under. */
51
+ export const WORKFLOW_SIZE_AGENTS: Record<Exclude<WorkflowSizeGuideline, "unrestricted">, number> = {
52
+ small: 5,
53
+ medium: 10,
54
+ large: 50,
55
+ };
56
+
57
+ /** The size-guideline line; undefined when no guideline applies. */
58
+ export function workflowSizeLine(guideline: WorkflowSizeGuideline, configured: boolean): string | undefined {
59
+ if (guideline === "unrestricted") return undefined;
60
+ const opening = configured ? "A workflow size guideline is configured for this session" : "This session has the default workflow size guideline";
61
+ return `${opening}: ${guideline} — keep workflows under ${WORKFLOW_SIZE_AGENTS[guideline]} agents. This is a guideline, not a hard limit — follow it unless the user's prompt calls for a different scale. The user can raise or remove it with \`workflowSizeGuideline\` in ~/.onecode/settings.json.`;
62
+ }
63
+
64
+ export function workflowDescription(guideline: WorkflowSizeGuideline, configured: boolean): string {
65
+ const line = workflowSizeLine(guideline, configured);
66
+ return line ? `${WORKFLOW_DESCRIPTION_BODY}\n\n${line}` : WORKFLOW_DESCRIPTION_BODY;
67
+ }
@@ -25,7 +25,7 @@ import type {
25
25
  JournalEntry,
26
26
  RunProgressEvent,
27
27
  } from "./types.ts";
28
- import { WorkflowScriptError } from "./types.ts";
28
+ import { keptWorktreeOf, type KeptWorktree, WorkflowScriptError } from "./types.ts";
29
29
  import type { ReplayCursor } from "./journal.ts";
30
30
 
31
31
  export const MAX_AGENTS_PER_RUN = 1000;
@@ -186,6 +186,7 @@ export function createScriptGlobals(options: ScriptGlobalsOptions): { globals: S
186
186
  replayed: true,
187
187
  prompt,
188
188
  preview: previewValue(replayed.value),
189
+ ...keptWorktreeField(replayed.worktreePath, replayed.worktreeBranch),
189
190
  });
190
191
  return replayed.value;
191
192
  }
@@ -216,13 +217,14 @@ export function createScriptGlobals(options: ScriptGlobalsOptions): { globals: S
216
217
  tokens: result.tokens,
217
218
  cost: result.cost,
218
219
  preview: previewValue(result.value),
220
+ ...keptWorktreeField(result.worktreePath, result.worktreeBranch),
219
221
  });
220
222
  return result.value;
221
223
  } catch (error) {
222
224
  if (options.signal.aborted) {
223
225
  // Close the record: the viewer would otherwise show a completed or
224
226
  // stopped run with this agent still "running".
225
- options.onEvent({ type: "agentEnd", callIndex, label, phase, text: "aborted" });
227
+ options.onEvent({ type: "agentEnd", callIndex, label, phase, text: "aborted", ...keptWorktreeField(keptWorktreeOf(error)?.path, keptWorktreeOf(error)?.branch) });
226
228
  throw new WorkflowScriptError("Workflow run was aborted");
227
229
  }
228
230
  // A script-authoring mistake (bad agentType/model, worktree without a
@@ -233,7 +235,14 @@ export function createScriptGlobals(options: ScriptGlobalsOptions): { globals: S
233
235
  if (error instanceof WorkflowScriptError) throw error;
234
236
  // A failed agent resolves to null (Claude Code semantics); the
235
237
  // failure is surfaced as a progress event, not an exception.
236
- options.onEvent({ type: "agentEnd", callIndex, label, phase, text: `failed: ${(error as Error).message}` });
238
+ options.onEvent({
239
+ type: "agentEnd",
240
+ callIndex,
241
+ label,
242
+ phase,
243
+ text: `failed: ${(error as Error).message}`,
244
+ ...keptWorktreeField(keptWorktreeOf(error)?.path, keptWorktreeOf(error)?.branch),
245
+ });
237
246
  return null;
238
247
  }
239
248
  });
@@ -272,3 +281,8 @@ export function createScriptGlobals(options: ScriptGlobalsOptions): { globals: S
272
281
 
273
282
  return { globals, state };
274
283
  }
284
+
285
+ /** The `worktree` field of an agentEnd event, present only for a kept worktree. */
286
+ function keptWorktreeField(path: string | undefined, branch: string | undefined): { worktree?: KeptWorktree } {
287
+ return path ? { worktree: branch ? { path, branch } : { path } } : {};
288
+ }