@f5-sales-demo/xcsh 19.51.2

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 (899) hide show
  1. package/CHANGELOG.md +7073 -0
  2. package/README.md +14 -0
  3. package/examples/README.md +21 -0
  4. package/examples/custom-tools/README.md +109 -0
  5. package/examples/custom-tools/hello/index.ts +20 -0
  6. package/examples/custom-tools/todo/index.ts +206 -0
  7. package/examples/extensions/README.md +143 -0
  8. package/examples/extensions/api-demo.ts +89 -0
  9. package/examples/extensions/chalk-logger.ts +25 -0
  10. package/examples/extensions/hello.ts +32 -0
  11. package/examples/extensions/pirate.ts +43 -0
  12. package/examples/extensions/plan-mode.ts +551 -0
  13. package/examples/extensions/reload-runtime.ts +37 -0
  14. package/examples/extensions/todo.ts +296 -0
  15. package/examples/extensions/tools.ts +145 -0
  16. package/examples/extensions/with-deps/index.ts +36 -0
  17. package/examples/extensions/with-deps/package-lock.json +31 -0
  18. package/examples/extensions/with-deps/package.json +16 -0
  19. package/examples/hooks/README.md +56 -0
  20. package/examples/hooks/auto-commit-on-exit.ts +48 -0
  21. package/examples/hooks/confirm-destructive.ts +58 -0
  22. package/examples/hooks/custom-compaction.ts +115 -0
  23. package/examples/hooks/dirty-repo-guard.ts +51 -0
  24. package/examples/hooks/file-trigger.ts +40 -0
  25. package/examples/hooks/git-checkpoint.ts +52 -0
  26. package/examples/hooks/handoff.ts +149 -0
  27. package/examples/hooks/permission-gate.ts +33 -0
  28. package/examples/hooks/protected-paths.ts +29 -0
  29. package/examples/hooks/qna.ts +118 -0
  30. package/examples/hooks/status-line.ts +39 -0
  31. package/examples/sdk/01-minimal.ts +21 -0
  32. package/examples/sdk/02-custom-model.ts +49 -0
  33. package/examples/sdk/03-custom-prompt.ts +43 -0
  34. package/examples/sdk/04-skills.ts +43 -0
  35. package/examples/sdk/06-extensions.ts +80 -0
  36. package/examples/sdk/06-hooks.ts +61 -0
  37. package/examples/sdk/07-context-files.ts +35 -0
  38. package/examples/sdk/08-prompt-templates.ts +41 -0
  39. package/examples/sdk/08-slash-commands.ts +46 -0
  40. package/examples/sdk/09-api-keys-and-oauth.ts +54 -0
  41. package/examples/sdk/11-sessions.ts +47 -0
  42. package/examples/sdk/README.md +172 -0
  43. package/package.json +539 -0
  44. package/scripts/build-info/resolvers.ts +51 -0
  45. package/scripts/capture-ax-fixture.ts +84 -0
  46. package/scripts/capture-login-fixture.ts +30 -0
  47. package/scripts/check-workflow-field-coverage.ts +101 -0
  48. package/scripts/extension-uat-harness.ts +340 -0
  49. package/scripts/format-prompts.ts +68 -0
  50. package/scripts/generate-api-spec-index.ts +580 -0
  51. package/scripts/generate-branding-index.ts +81 -0
  52. package/scripts/generate-build-info.ts +106 -0
  53. package/scripts/generate-console-catalog.ts +88 -0
  54. package/scripts/generate-console-field-metadata.ts +74 -0
  55. package/scripts/generate-docs-index.ts +40 -0
  56. package/scripts/generate-template.ts +32 -0
  57. package/scripts/generate-terraform-index.ts +81 -0
  58. package/scripts/mermaid-gallery.ts +132 -0
  59. package/scripts/uat-matrix-modalities.ts +451 -0
  60. package/scripts/uat-matrix-report.ts +175 -0
  61. package/scripts/uat-matrix.ts +353 -0
  62. package/src/async/index.ts +2 -0
  63. package/src/async/job-manager.ts +416 -0
  64. package/src/async/support.ts +5 -0
  65. package/src/autoresearch/apply-contract-to-state.ts +1 -0
  66. package/src/autoresearch/command-resume.md +17 -0
  67. package/src/autoresearch/contract.ts +205 -0
  68. package/src/autoresearch/dashboard.ts +374 -0
  69. package/src/autoresearch/git.ts +191 -0
  70. package/src/autoresearch/helpers.ts +328 -0
  71. package/src/autoresearch/index.ts +402 -0
  72. package/src/autoresearch/prompt.md +236 -0
  73. package/src/autoresearch/resume-message.md +16 -0
  74. package/src/autoresearch/state.ts +303 -0
  75. package/src/autoresearch/tools/init-experiment.ts +400 -0
  76. package/src/autoresearch/tools/log-experiment.ts +793 -0
  77. package/src/autoresearch/tools/run-experiment.ts +679 -0
  78. package/src/autoresearch/types.ts +114 -0
  79. package/src/browser/acquire.ts +249 -0
  80. package/src/browser/actions.ts +126 -0
  81. package/src/browser/auth.ts +176 -0
  82. package/src/browser/ax.ts +134 -0
  83. package/src/browser/cdp-core.ts +45 -0
  84. package/src/browser/cdp-page-actions.ts +51 -0
  85. package/src/browser/chrome-locate.ts +66 -0
  86. package/src/browser/dom-context.ts +89 -0
  87. package/src/browser/dt-context.ts +100 -0
  88. package/src/browser/extension-bridge.ts +182 -0
  89. package/src/browser/extension-page-actions.ts +397 -0
  90. package/src/browser/extension-provider.ts +373 -0
  91. package/src/browser/index.ts +17 -0
  92. package/src/browser/input-commit.ts +74 -0
  93. package/src/browser/native-messaging.ts +20 -0
  94. package/src/browser/page-actions.ts +18 -0
  95. package/src/browser/provider.ts +155 -0
  96. package/src/browser/resolver.ts +126 -0
  97. package/src/browser/selector.ts +40 -0
  98. package/src/bun-imports.d.ts +22 -0
  99. package/src/capability/context-file.ts +43 -0
  100. package/src/capability/extension-module.ts +34 -0
  101. package/src/capability/extension.ts +47 -0
  102. package/src/capability/fs.ts +107 -0
  103. package/src/capability/hook.ts +40 -0
  104. package/src/capability/index.ts +438 -0
  105. package/src/capability/instruction.ts +37 -0
  106. package/src/capability/mcp.ts +74 -0
  107. package/src/capability/prompt.ts +35 -0
  108. package/src/capability/rule.ts +224 -0
  109. package/src/capability/settings.ts +34 -0
  110. package/src/capability/skill.ts +50 -0
  111. package/src/capability/slash-command.ts +40 -0
  112. package/src/capability/ssh.ts +41 -0
  113. package/src/capability/system-prompt.ts +34 -0
  114. package/src/capability/tool.ts +38 -0
  115. package/src/capability/types.ts +168 -0
  116. package/src/cli/agents-cli.ts +138 -0
  117. package/src/cli/args.ts +286 -0
  118. package/src/cli/chrome-cli.ts +88 -0
  119. package/src/cli/classify-install-target.ts +50 -0
  120. package/src/cli/commands/init-xdg.ts +27 -0
  121. package/src/cli/config-cli.ts +418 -0
  122. package/src/cli/file-processor.ts +121 -0
  123. package/src/cli/grep-cli.ts +160 -0
  124. package/src/cli/grievances-cli.ts +78 -0
  125. package/src/cli/initial-message.ts +58 -0
  126. package/src/cli/jupyter-cli.ts +106 -0
  127. package/src/cli/list-models.ts +128 -0
  128. package/src/cli/plugin-cli.ts +964 -0
  129. package/src/cli/read-cli.ts +68 -0
  130. package/src/cli/session-picker.ts +52 -0
  131. package/src/cli/setup-cli.ts +479 -0
  132. package/src/cli/shell-cli.ts +174 -0
  133. package/src/cli/ssh-cli.ts +179 -0
  134. package/src/cli/stats-cli.ts +182 -0
  135. package/src/cli/update-cli.ts +446 -0
  136. package/src/cli/web-search-cli.ts +203 -0
  137. package/src/cli.ts +123 -0
  138. package/src/commands/agents.ts +57 -0
  139. package/src/commands/chrome-host.ts +71 -0
  140. package/src/commands/chrome.ts +28 -0
  141. package/src/commands/commit.ts +36 -0
  142. package/src/commands/config.ts +51 -0
  143. package/src/commands/grep.ts +48 -0
  144. package/src/commands/grievances.ts +20 -0
  145. package/src/commands/jupyter.ts +32 -0
  146. package/src/commands/launch.ts +144 -0
  147. package/src/commands/plugin.ts +78 -0
  148. package/src/commands/read.ts +33 -0
  149. package/src/commands/setup.ts +42 -0
  150. package/src/commands/shell.ts +29 -0
  151. package/src/commands/ssh.ts +60 -0
  152. package/src/commands/stats.ts +29 -0
  153. package/src/commands/update.ts +21 -0
  154. package/src/commands/web-search.ts +46 -0
  155. package/src/commit/agentic/agent.ts +314 -0
  156. package/src/commit/agentic/fallback.ts +96 -0
  157. package/src/commit/agentic/index.ts +354 -0
  158. package/src/commit/agentic/prompts/analyze-file.md +22 -0
  159. package/src/commit/agentic/prompts/session-user.md +25 -0
  160. package/src/commit/agentic/prompts/split-confirm.md +1 -0
  161. package/src/commit/agentic/prompts/system.md +38 -0
  162. package/src/commit/agentic/state.ts +60 -0
  163. package/src/commit/agentic/tools/analyze-file.ts +127 -0
  164. package/src/commit/agentic/tools/git-file-diff.ts +191 -0
  165. package/src/commit/agentic/tools/git-hunk.ts +50 -0
  166. package/src/commit/agentic/tools/git-overview.ts +81 -0
  167. package/src/commit/agentic/tools/index.ts +54 -0
  168. package/src/commit/agentic/tools/propose-changelog.ts +139 -0
  169. package/src/commit/agentic/tools/propose-commit.ts +122 -0
  170. package/src/commit/agentic/tools/recent-commits.ts +81 -0
  171. package/src/commit/agentic/tools/schemas.ts +31 -0
  172. package/src/commit/agentic/tools/split-commit.ts +251 -0
  173. package/src/commit/agentic/topo-sort.ts +44 -0
  174. package/src/commit/agentic/trivial.ts +51 -0
  175. package/src/commit/agentic/validation.ts +183 -0
  176. package/src/commit/analysis/conventional.ts +122 -0
  177. package/src/commit/analysis/index.ts +4 -0
  178. package/src/commit/analysis/scope.ts +242 -0
  179. package/src/commit/analysis/summary.ts +105 -0
  180. package/src/commit/analysis/validation.ts +66 -0
  181. package/src/commit/changelog/detect.ts +40 -0
  182. package/src/commit/changelog/generate.ts +101 -0
  183. package/src/commit/changelog/index.ts +234 -0
  184. package/src/commit/changelog/parse.ts +44 -0
  185. package/src/commit/cli.ts +85 -0
  186. package/src/commit/git/diff.ts +148 -0
  187. package/src/commit/index.ts +5 -0
  188. package/src/commit/map-reduce/index.ts +69 -0
  189. package/src/commit/map-reduce/map-phase.ts +193 -0
  190. package/src/commit/map-reduce/reduce-phase.ts +108 -0
  191. package/src/commit/map-reduce/utils.ts +9 -0
  192. package/src/commit/message.ts +11 -0
  193. package/src/commit/model-selection.ts +66 -0
  194. package/src/commit/pipeline.ts +242 -0
  195. package/src/commit/prompts/analysis-system.md +148 -0
  196. package/src/commit/prompts/analysis-user.md +38 -0
  197. package/src/commit/prompts/changelog-system.md +50 -0
  198. package/src/commit/prompts/changelog-user.md +18 -0
  199. package/src/commit/prompts/file-observer-system.md +24 -0
  200. package/src/commit/prompts/file-observer-user.md +8 -0
  201. package/src/commit/prompts/reduce-system.md +50 -0
  202. package/src/commit/prompts/reduce-user.md +17 -0
  203. package/src/commit/prompts/summary-retry.md +3 -0
  204. package/src/commit/prompts/summary-system.md +38 -0
  205. package/src/commit/prompts/summary-user.md +13 -0
  206. package/src/commit/prompts/types-description.md +2 -0
  207. package/src/commit/types.ts +118 -0
  208. package/src/commit/utils/exclusions.ts +42 -0
  209. package/src/commit/utils.ts +44 -0
  210. package/src/config/auto-config.ts +698 -0
  211. package/src/config/context-schema.json +115 -0
  212. package/src/config/file-lock.ts +121 -0
  213. package/src/config/keybindings.ts +493 -0
  214. package/src/config/mcp-schema.json +230 -0
  215. package/src/config/model-equivalence.ts +675 -0
  216. package/src/config/model-registry.ts +2265 -0
  217. package/src/config/model-resolver.ts +1289 -0
  218. package/src/config/prompt-templates.ts +271 -0
  219. package/src/config/resolve-config-value.ts +110 -0
  220. package/src/config/settings-schema.ts +2155 -0
  221. package/src/config/settings.ts +730 -0
  222. package/src/config.ts +418 -0
  223. package/src/cursor.ts +323 -0
  224. package/src/dap/client.ts +674 -0
  225. package/src/dap/config.ts +150 -0
  226. package/src/dap/defaults.json +211 -0
  227. package/src/dap/index.ts +4 -0
  228. package/src/dap/session.ts +1255 -0
  229. package/src/dap/types.ts +600 -0
  230. package/src/debug/index.ts +440 -0
  231. package/src/debug/log-formatting.ts +58 -0
  232. package/src/debug/log-viewer.ts +908 -0
  233. package/src/debug/profiler.ts +158 -0
  234. package/src/debug/report-bundle.ts +365 -0
  235. package/src/debug/system-info.ts +107 -0
  236. package/src/discovery/agents-md.ts +67 -0
  237. package/src/discovery/agents.ts +219 -0
  238. package/src/discovery/builtin.ts +851 -0
  239. package/src/discovery/claude-plugins.ts +297 -0
  240. package/src/discovery/claude.ts +543 -0
  241. package/src/discovery/cline.ts +83 -0
  242. package/src/discovery/codex.ts +535 -0
  243. package/src/discovery/cursor.ts +220 -0
  244. package/src/discovery/gemini.ts +396 -0
  245. package/src/discovery/github.ts +118 -0
  246. package/src/discovery/helpers.ts +934 -0
  247. package/src/discovery/index.ts +79 -0
  248. package/src/discovery/language.ts +46 -0
  249. package/src/discovery/mcp-json.ts +171 -0
  250. package/src/discovery/opencode.ts +393 -0
  251. package/src/discovery/plugin-dir-roots.ts +28 -0
  252. package/src/discovery/ssh.ts +153 -0
  253. package/src/discovery/substitute-plugin-root.ts +29 -0
  254. package/src/discovery/vscode.ts +105 -0
  255. package/src/discovery/windsurf.ts +147 -0
  256. package/src/edit/diff.ts +818 -0
  257. package/src/edit/index.ts +481 -0
  258. package/src/edit/line-hash.ts +67 -0
  259. package/src/edit/modes/chunk.ts +762 -0
  260. package/src/edit/modes/hashline.ts +1366 -0
  261. package/src/edit/modes/patch.ts +1791 -0
  262. package/src/edit/modes/replace.ts +1115 -0
  263. package/src/edit/normalize.ts +375 -0
  264. package/src/edit/renderer.ts +627 -0
  265. package/src/exa/factory.ts +61 -0
  266. package/src/exa/index.ts +27 -0
  267. package/src/exa/mcp-client.ts +293 -0
  268. package/src/exa/render.ts +232 -0
  269. package/src/exa/researcher.ts +47 -0
  270. package/src/exa/search.ts +86 -0
  271. package/src/exa/types.ts +166 -0
  272. package/src/exa/websets.ts +247 -0
  273. package/src/exec/bash-executor.ts +332 -0
  274. package/src/exec/exec.ts +53 -0
  275. package/src/exec/idle-timeout-watchdog.ts +126 -0
  276. package/src/exec/non-interactive-env.ts +48 -0
  277. package/src/export/custom-share.ts +65 -0
  278. package/src/export/html/index.ts +161 -0
  279. package/src/export/html/template.css +1001 -0
  280. package/src/export/html/template.generated.ts +2 -0
  281. package/src/export/html/template.html +46 -0
  282. package/src/export/html/template.js +1950 -0
  283. package/src/export/html/template.macro.ts +24 -0
  284. package/src/export/html/vendor/highlight.min.js +1213 -0
  285. package/src/export/html/vendor/marked.min.js +6 -0
  286. package/src/export/ttsr.ts +434 -0
  287. package/src/extensibility/custom-commands/bundled/ci-green/index.ts +25 -0
  288. package/src/extensibility/custom-commands/bundled/review/index.ts +456 -0
  289. package/src/extensibility/custom-commands/index.ts +2 -0
  290. package/src/extensibility/custom-commands/loader.ts +236 -0
  291. package/src/extensibility/custom-commands/types.ts +111 -0
  292. package/src/extensibility/custom-tools/index.ts +7 -0
  293. package/src/extensibility/custom-tools/loader.ts +238 -0
  294. package/src/extensibility/custom-tools/types.ts +251 -0
  295. package/src/extensibility/custom-tools/wrapper.ts +47 -0
  296. package/src/extensibility/extensions/index.ts +15 -0
  297. package/src/extensibility/extensions/loader.ts +572 -0
  298. package/src/extensibility/extensions/runner.ts +848 -0
  299. package/src/extensibility/extensions/types.ts +1394 -0
  300. package/src/extensibility/extensions/wrapper.ts +191 -0
  301. package/src/extensibility/hooks/index.ts +5 -0
  302. package/src/extensibility/hooks/loader.ts +255 -0
  303. package/src/extensibility/hooks/runner.ts +425 -0
  304. package/src/extensibility/hooks/tool-wrapper.ts +108 -0
  305. package/src/extensibility/hooks/types.ts +826 -0
  306. package/src/extensibility/plugins/doctor.ts +66 -0
  307. package/src/extensibility/plugins/git-url.ts +281 -0
  308. package/src/extensibility/plugins/index.ts +9 -0
  309. package/src/extensibility/plugins/installer.ts +192 -0
  310. package/src/extensibility/plugins/loader.ts +267 -0
  311. package/src/extensibility/plugins/manager.ts +731 -0
  312. package/src/extensibility/plugins/marketplace/cache.ts +136 -0
  313. package/src/extensibility/plugins/marketplace/fetcher.ts +318 -0
  314. package/src/extensibility/plugins/marketplace/index.ts +6 -0
  315. package/src/extensibility/plugins/marketplace/manager.ts +781 -0
  316. package/src/extensibility/plugins/marketplace/prerequisites.ts +255 -0
  317. package/src/extensibility/plugins/marketplace/registry.ts +196 -0
  318. package/src/extensibility/plugins/marketplace/source-resolver.ts +147 -0
  319. package/src/extensibility/plugins/marketplace/types.ts +201 -0
  320. package/src/extensibility/plugins/parser.ts +105 -0
  321. package/src/extensibility/plugins/types.ts +194 -0
  322. package/src/extensibility/skills.ts +269 -0
  323. package/src/extensibility/slash-commands.ts +246 -0
  324. package/src/extensibility/tool-proxy.ts +25 -0
  325. package/src/extensibility/utils.ts +38 -0
  326. package/src/index.ts +61 -0
  327. package/src/internal-urls/agent-protocol.ts +136 -0
  328. package/src/internal-urls/api-catalog-resolve.ts +495 -0
  329. package/src/internal-urls/api-catalog-types.ts +94 -0
  330. package/src/internal-urls/api-spec-resolve.ts +1036 -0
  331. package/src/internal-urls/api-spec-types.ts +239 -0
  332. package/src/internal-urls/artifact-protocol.ts +97 -0
  333. package/src/internal-urls/branding-index.generated.ts +88 -0
  334. package/src/internal-urls/build-info-runtime.ts +302 -0
  335. package/src/internal-urls/build-info.generated.ts +33 -0
  336. package/src/internal-urls/computer-profile.ts +692 -0
  337. package/src/internal-urls/console-catalog-types.ts +21 -0
  338. package/src/internal-urls/console-catalog.generated.ts +532 -0
  339. package/src/internal-urls/console-field-metadata-types.ts +59 -0
  340. package/src/internal-urls/console-field-metadata.generated.ts +4841 -0
  341. package/src/internal-urls/console-resolve.ts +178 -0
  342. package/src/internal-urls/docs-index.generated.ts +698 -0
  343. package/src/internal-urls/extension-api.md +147 -0
  344. package/src/internal-urls/index.ts +46 -0
  345. package/src/internal-urls/jobs-protocol.ts +119 -0
  346. package/src/internal-urls/json-query.ts +126 -0
  347. package/src/internal-urls/local-protocol.ts +206 -0
  348. package/src/internal-urls/mcp-protocol.ts +156 -0
  349. package/src/internal-urls/memory-protocol.ts +133 -0
  350. package/src/internal-urls/parse.ts +72 -0
  351. package/src/internal-urls/profile-collectors.ts +106 -0
  352. package/src/internal-urls/router.ts +55 -0
  353. package/src/internal-urls/rule-protocol.ts +55 -0
  354. package/src/internal-urls/skill-protocol.ts +111 -0
  355. package/src/internal-urls/terraform-index.generated.ts +1852 -0
  356. package/src/internal-urls/terraform-resolve.ts +184 -0
  357. package/src/internal-urls/terraform-types.ts +45 -0
  358. package/src/internal-urls/types.ts +52 -0
  359. package/src/internal-urls/user-profile.ts +363 -0
  360. package/src/internal-urls/xcsh-protocol.ts +644 -0
  361. package/src/ipy/cancellation.ts +28 -0
  362. package/src/ipy/executor.ts +1155 -0
  363. package/src/ipy/gateway-coordinator.ts +424 -0
  364. package/src/ipy/kernel.ts +1091 -0
  365. package/src/ipy/modules.ts +144 -0
  366. package/src/ipy/prelude.py +849 -0
  367. package/src/ipy/prelude.ts +3 -0
  368. package/src/ipy/runtime.ts +221 -0
  369. package/src/locales/ar.json +512 -0
  370. package/src/locales/de.json +512 -0
  371. package/src/locales/en.json +549 -0
  372. package/src/locales/es.json +512 -0
  373. package/src/locales/fr.json +512 -0
  374. package/src/locales/hi.json +512 -0
  375. package/src/locales/index.ts +29 -0
  376. package/src/locales/it.json +512 -0
  377. package/src/locales/ja.json +512 -0
  378. package/src/locales/ko.json +512 -0
  379. package/src/locales/pt-br.json +512 -0
  380. package/src/locales/th.json +512 -0
  381. package/src/locales/zh-cn.json +512 -0
  382. package/src/locales/zh-tw.json +512 -0
  383. package/src/lsp/client.ts +941 -0
  384. package/src/lsp/clients/biome-client.ts +202 -0
  385. package/src/lsp/clients/index.ts +50 -0
  386. package/src/lsp/clients/lsp-linter-client.ts +93 -0
  387. package/src/lsp/clients/swiftlint-client.ts +120 -0
  388. package/src/lsp/config.ts +418 -0
  389. package/src/lsp/defaults.json +999 -0
  390. package/src/lsp/edits.ts +109 -0
  391. package/src/lsp/index.ts +1746 -0
  392. package/src/lsp/lspmux.ts +233 -0
  393. package/src/lsp/render.ts +692 -0
  394. package/src/lsp/startup-events.ts +13 -0
  395. package/src/lsp/types.ts +444 -0
  396. package/src/lsp/utils.ts +691 -0
  397. package/src/main.ts +944 -0
  398. package/src/mcp/client.ts +482 -0
  399. package/src/mcp/config-writer.ts +225 -0
  400. package/src/mcp/config.ts +365 -0
  401. package/src/mcp/discoverable-tool-metadata.ts +202 -0
  402. package/src/mcp/index.ts +29 -0
  403. package/src/mcp/json-rpc.ts +84 -0
  404. package/src/mcp/loader.ts +124 -0
  405. package/src/mcp/manager.ts +1152 -0
  406. package/src/mcp/oauth-discovery.ts +349 -0
  407. package/src/mcp/oauth-flow.ts +387 -0
  408. package/src/mcp/render.ts +157 -0
  409. package/src/mcp/smithery-auth.ts +104 -0
  410. package/src/mcp/smithery-connect.ts +145 -0
  411. package/src/mcp/smithery-registry.ts +477 -0
  412. package/src/mcp/tool-bridge.ts +417 -0
  413. package/src/mcp/tool-cache.ts +117 -0
  414. package/src/mcp/transports/http.ts +475 -0
  415. package/src/mcp/transports/index.ts +6 -0
  416. package/src/mcp/transports/stdio.ts +325 -0
  417. package/src/mcp/types.ts +423 -0
  418. package/src/memories/index.ts +1115 -0
  419. package/src/memories/storage.ts +577 -0
  420. package/src/modes/acp/acp-agent.ts +1361 -0
  421. package/src/modes/acp/acp-event-mapper.ts +538 -0
  422. package/src/modes/acp/acp-mode.ts +15 -0
  423. package/src/modes/acp/index.ts +2 -0
  424. package/src/modes/components/agent-dashboard.ts +1124 -0
  425. package/src/modes/components/assistant-message.ts +213 -0
  426. package/src/modes/components/bash-execution.ts +345 -0
  427. package/src/modes/components/bordered-loader.ts +41 -0
  428. package/src/modes/components/branch-summary-message.ts +45 -0
  429. package/src/modes/components/btw-panel.ts +103 -0
  430. package/src/modes/components/compaction-summary-message.ts +51 -0
  431. package/src/modes/components/context-add-wizard.ts +534 -0
  432. package/src/modes/components/countdown-timer.ts +75 -0
  433. package/src/modes/components/custom-editor.ts +238 -0
  434. package/src/modes/components/custom-message.ts +91 -0
  435. package/src/modes/components/diff.ts +210 -0
  436. package/src/modes/components/dynamic-border.ts +25 -0
  437. package/src/modes/components/extensions/extension-dashboard.ts +326 -0
  438. package/src/modes/components/extensions/extension-list.ts +492 -0
  439. package/src/modes/components/extensions/index.ts +9 -0
  440. package/src/modes/components/extensions/inspector-panel.ts +317 -0
  441. package/src/modes/components/extensions/state-manager.ts +587 -0
  442. package/src/modes/components/extensions/types.ts +191 -0
  443. package/src/modes/components/footer.ts +262 -0
  444. package/src/modes/components/gutter-block.ts +315 -0
  445. package/src/modes/components/history-search.ts +158 -0
  446. package/src/modes/components/hook-editor.ts +151 -0
  447. package/src/modes/components/hook-input.ts +81 -0
  448. package/src/modes/components/hook-message.ts +100 -0
  449. package/src/modes/components/hook-selector.ts +192 -0
  450. package/src/modes/components/index.ts +36 -0
  451. package/src/modes/components/keybinding-hints.ts +65 -0
  452. package/src/modes/components/login-dialog.ts +164 -0
  453. package/src/modes/components/mcp-add-wizard.ts +1314 -0
  454. package/src/modes/components/model-selector.ts +946 -0
  455. package/src/modes/components/oauth-selector.ts +211 -0
  456. package/src/modes/components/plugin-selector.ts +95 -0
  457. package/src/modes/components/plugin-settings.ts +477 -0
  458. package/src/modes/components/plugins/index.ts +5 -0
  459. package/src/modes/components/plugins/plugin-dashboard.ts +523 -0
  460. package/src/modes/components/plugins/plugin-inspector-pane.ts +84 -0
  461. package/src/modes/components/plugins/plugin-list-pane.ts +109 -0
  462. package/src/modes/components/plugins/state-manager.ts +229 -0
  463. package/src/modes/components/plugins/types.ts +51 -0
  464. package/src/modes/components/plugins/utils.ts +6 -0
  465. package/src/modes/components/python-execution.ts +244 -0
  466. package/src/modes/components/queue-mode-selector.ts +56 -0
  467. package/src/modes/components/read-tool-group.ts +137 -0
  468. package/src/modes/components/session-observer-overlay.ts +483 -0
  469. package/src/modes/components/session-selector.ts +343 -0
  470. package/src/modes/components/settings-defs.ts +568 -0
  471. package/src/modes/components/settings-selector.ts +641 -0
  472. package/src/modes/components/show-images-selector.ts +45 -0
  473. package/src/modes/components/skill-message.ts +90 -0
  474. package/src/modes/components/status-line/context-gradient.ts +64 -0
  475. package/src/modes/components/status-line/git-utils.ts +42 -0
  476. package/src/modes/components/status-line/hex-ansi.ts +29 -0
  477. package/src/modes/components/status-line/index.ts +4 -0
  478. package/src/modes/components/status-line/presets.ts +174 -0
  479. package/src/modes/components/status-line/segments.ts +494 -0
  480. package/src/modes/components/status-line/separators.ts +55 -0
  481. package/src/modes/components/status-line/token-rate.ts +66 -0
  482. package/src/modes/components/status-line/types.ts +96 -0
  483. package/src/modes/components/status-line-segment-editor.ts +361 -0
  484. package/src/modes/components/status-line.ts +729 -0
  485. package/src/modes/components/theme-selector.ts +63 -0
  486. package/src/modes/components/thinking-selector.ts +52 -0
  487. package/src/modes/components/todo-reminder.ts +54 -0
  488. package/src/modes/components/tool-execution.ts +781 -0
  489. package/src/modes/components/tree-selector.ts +908 -0
  490. package/src/modes/components/ttsr-notification.ts +80 -0
  491. package/src/modes/components/user-message-selector.ts +141 -0
  492. package/src/modes/components/user-message.ts +100 -0
  493. package/src/modes/components/visual-truncate.ts +63 -0
  494. package/src/modes/components/welcome-checks.ts +313 -0
  495. package/src/modes/components/welcome.ts +270 -0
  496. package/src/modes/controllers/btw-controller.ts +193 -0
  497. package/src/modes/controllers/chord-routing.ts +37 -0
  498. package/src/modes/controllers/command-controller.ts +1293 -0
  499. package/src/modes/controllers/context-command-controller.ts +61 -0
  500. package/src/modes/controllers/event-controller.ts +743 -0
  501. package/src/modes/controllers/extension-ui-controller.ts +983 -0
  502. package/src/modes/controllers/input-controller.ts +877 -0
  503. package/src/modes/controllers/mcp-command-controller.ts +1940 -0
  504. package/src/modes/controllers/selector-controller.ts +1292 -0
  505. package/src/modes/controllers/ssh-command-controller.ts +421 -0
  506. package/src/modes/index.ts +34 -0
  507. package/src/modes/interactive-mode.ts +1781 -0
  508. package/src/modes/oauth-manual-input.ts +42 -0
  509. package/src/modes/print-mode.ts +196 -0
  510. package/src/modes/prompt-action-autocomplete.ts +231 -0
  511. package/src/modes/rpc/host-tools.ts +186 -0
  512. package/src/modes/rpc/rpc-client.ts +762 -0
  513. package/src/modes/rpc/rpc-mode.ts +877 -0
  514. package/src/modes/rpc/rpc-types.ts +322 -0
  515. package/src/modes/session-observer-registry.ts +146 -0
  516. package/src/modes/shared.ts +30 -0
  517. package/src/modes/theme/defaults/index.ts +7 -0
  518. package/src/modes/theme/defaults/xcsh-dark.json +113 -0
  519. package/src/modes/theme/defaults/xcsh-light.json +115 -0
  520. package/src/modes/theme/mermaid-cache.ts +151 -0
  521. package/src/modes/theme/mermaid-palette.ts +39 -0
  522. package/src/modes/theme/theme-schema.json +553 -0
  523. package/src/modes/theme/theme.ts +2563 -0
  524. package/src/modes/types.ts +273 -0
  525. package/src/modes/utils/hotkeys-markdown.ts +60 -0
  526. package/src/modes/utils/keybinding-matchers.ts +30 -0
  527. package/src/modes/utils/read-group-outcome-aggregator.ts +55 -0
  528. package/src/modes/utils/sanitize-error-message.ts +60 -0
  529. package/src/modes/utils/tools-markdown.ts +28 -0
  530. package/src/modes/utils/ui-helpers.ts +734 -0
  531. package/src/plan-mode/approved-plan.ts +55 -0
  532. package/src/plan-mode/state.ts +6 -0
  533. package/src/priority.json +37 -0
  534. package/src/prompts/agents/designer.md +67 -0
  535. package/src/prompts/agents/explore.md +61 -0
  536. package/src/prompts/agents/frontmatter.md +10 -0
  537. package/src/prompts/agents/init.md +36 -0
  538. package/src/prompts/agents/librarian.md +121 -0
  539. package/src/prompts/agents/plan.md +49 -0
  540. package/src/prompts/agents/reviewer.md +127 -0
  541. package/src/prompts/agents/task.md +16 -0
  542. package/src/prompts/ci-green-request.md +35 -0
  543. package/src/prompts/compaction/branch-summary-context.md +5 -0
  544. package/src/prompts/compaction/branch-summary-preamble.md +2 -0
  545. package/src/prompts/compaction/branch-summary.md +30 -0
  546. package/src/prompts/compaction/compaction-short-summary.md +9 -0
  547. package/src/prompts/compaction/compaction-summary-context.md +5 -0
  548. package/src/prompts/compaction/compaction-summary.md +38 -0
  549. package/src/prompts/compaction/compaction-turn-prefix.md +17 -0
  550. package/src/prompts/compaction/compaction-update-summary.md +45 -0
  551. package/src/prompts/memories/consolidation.md +30 -0
  552. package/src/prompts/memories/read-path.md +11 -0
  553. package/src/prompts/memories/stage_one_input.md +6 -0
  554. package/src/prompts/memories/stage_one_system.md +21 -0
  555. package/src/prompts/review-request.md +70 -0
  556. package/src/prompts/system/agent-creation-architect.md +65 -0
  557. package/src/prompts/system/agent-creation-user.md +6 -0
  558. package/src/prompts/system/auto-handoff-threshold-focus.md +1 -0
  559. package/src/prompts/system/btw-user.md +8 -0
  560. package/src/prompts/system/commit-message-system.md +2 -0
  561. package/src/prompts/system/custom-system-prompt.md +82 -0
  562. package/src/prompts/system/eager-todo.md +13 -0
  563. package/src/prompts/system/file-operations.md +10 -0
  564. package/src/prompts/system/handoff-document.md +48 -0
  565. package/src/prompts/system/plan-mode-active.md +114 -0
  566. package/src/prompts/system/plan-mode-approved.md +23 -0
  567. package/src/prompts/system/plan-mode-reference.md +14 -0
  568. package/src/prompts/system/plan-mode-subagent.md +34 -0
  569. package/src/prompts/system/plan-mode-tool-decision-reminder.md +9 -0
  570. package/src/prompts/system/subagent-submit-reminder.md +7 -0
  571. package/src/prompts/system/subagent-system-prompt.md +36 -0
  572. package/src/prompts/system/subagent-user-prompt.md +12 -0
  573. package/src/prompts/system/summarization-system.md +3 -0
  574. package/src/prompts/system/system-prompt.md +698 -0
  575. package/src/prompts/system/title-system.md +2 -0
  576. package/src/prompts/system/ttsr-interrupt.md +7 -0
  577. package/src/prompts/system/web-search.md +28 -0
  578. package/src/prompts/tools/ask.md +28 -0
  579. package/src/prompts/tools/ast-edit.md +48 -0
  580. package/src/prompts/tools/ast-grep.md +54 -0
  581. package/src/prompts/tools/async-result.md +5 -0
  582. package/src/prompts/tools/bash.md +67 -0
  583. package/src/prompts/tools/browser.md +26 -0
  584. package/src/prompts/tools/calculator.md +10 -0
  585. package/src/prompts/tools/cancel-job.md +5 -0
  586. package/src/prompts/tools/catalog-workflow-runner.md +13 -0
  587. package/src/prompts/tools/checkpoint.md +16 -0
  588. package/src/prompts/tools/chunk-edit.md +279 -0
  589. package/src/prompts/tools/debug.md +43 -0
  590. package/src/prompts/tools/display-image.md +23 -0
  591. package/src/prompts/tools/exit-plan-mode.md +41 -0
  592. package/src/prompts/tools/find.md +26 -0
  593. package/src/prompts/tools/gemini-image.md +7 -0
  594. package/src/prompts/tools/grep.md +29 -0
  595. package/src/prompts/tools/hashline.md +131 -0
  596. package/src/prompts/tools/inspect-image-system.md +20 -0
  597. package/src/prompts/tools/inspect-image.md +32 -0
  598. package/src/prompts/tools/lsp.md +33 -0
  599. package/src/prompts/tools/patch.md +77 -0
  600. package/src/prompts/tools/poll.md +5 -0
  601. package/src/prompts/tools/python.md +60 -0
  602. package/src/prompts/tools/read-chunk.md +35 -0
  603. package/src/prompts/tools/read.md +63 -0
  604. package/src/prompts/tools/render-mermaid.md +9 -0
  605. package/src/prompts/tools/replace.md +36 -0
  606. package/src/prompts/tools/resolve.md +8 -0
  607. package/src/prompts/tools/rewind.md +13 -0
  608. package/src/prompts/tools/search-tool-bm25.md +34 -0
  609. package/src/prompts/tools/ssh.md +44 -0
  610. package/src/prompts/tools/task-summary.md +28 -0
  611. package/src/prompts/tools/task.md +131 -0
  612. package/src/prompts/tools/todo-write.md +89 -0
  613. package/src/prompts/tools/vim.md +98 -0
  614. package/src/prompts/tools/web-search.md +10 -0
  615. package/src/prompts/tools/write.md +14 -0
  616. package/src/prompts/tools/xcsh-api.md +283 -0
  617. package/src/resource-management/index.ts +42 -0
  618. package/src/sdk.ts +2123 -0
  619. package/src/secrets/index.ts +146 -0
  620. package/src/secrets/obfuscator.ts +290 -0
  621. package/src/secrets/regex.ts +21 -0
  622. package/src/services/context-env.ts +102 -0
  623. package/src/services/xcsh-api-client.ts +230 -0
  624. package/src/services/xcsh-context-command.ts +803 -0
  625. package/src/services/xcsh-context-display.ts +49 -0
  626. package/src/services/xcsh-context-indicators.ts +17 -0
  627. package/src/services/xcsh-context-segment.ts +39 -0
  628. package/src/services/xcsh-context.ts +1410 -0
  629. package/src/services/xcsh-env.ts +107 -0
  630. package/src/services/xcsh-knowledge.ts +177 -0
  631. package/src/services/xcsh-table.ts +164 -0
  632. package/src/session/agent-session.ts +6690 -0
  633. package/src/session/agent-storage.ts +451 -0
  634. package/src/session/artifacts.ts +132 -0
  635. package/src/session/auth-storage.ts +17 -0
  636. package/src/session/blob-store.ts +135 -0
  637. package/src/session/compaction/branch-summarization.ts +322 -0
  638. package/src/session/compaction/compaction.ts +1388 -0
  639. package/src/session/compaction/index.ts +7 -0
  640. package/src/session/compaction/pruning.ts +91 -0
  641. package/src/session/compaction/utils.ts +184 -0
  642. package/src/session/history-storage.ts +253 -0
  643. package/src/session/messages.ts +597 -0
  644. package/src/session/session-dump-format.ts +203 -0
  645. package/src/session/session-manager.ts +2816 -0
  646. package/src/session/session-storage.ts +370 -0
  647. package/src/session/streaming-output.ts +770 -0
  648. package/src/session/tool-choice-queue.ts +213 -0
  649. package/src/slash-commands/builtin-registry.ts +1614 -0
  650. package/src/slash-commands/export-command.ts +178 -0
  651. package/src/slash-commands/marketplace-install-parser.ts +99 -0
  652. package/src/slash-commands/resource-commands.ts +250 -0
  653. package/src/ssh/config-writer.ts +183 -0
  654. package/src/ssh/connection-manager.ts +445 -0
  655. package/src/ssh/ssh-executor.ts +131 -0
  656. package/src/ssh/sshfs-mount.ts +137 -0
  657. package/src/ssh/utils.ts +8 -0
  658. package/src/stt/downloader.ts +71 -0
  659. package/src/stt/index.ts +3 -0
  660. package/src/stt/recorder.ts +351 -0
  661. package/src/stt/setup.ts +52 -0
  662. package/src/stt/stt-controller.ts +160 -0
  663. package/src/stt/transcribe.py +70 -0
  664. package/src/stt/transcriber.ts +91 -0
  665. package/src/system-prompt.ts +688 -0
  666. package/src/task/agents.ts +166 -0
  667. package/src/task/commands.ts +131 -0
  668. package/src/task/discovery.ts +126 -0
  669. package/src/task/executor.ts +1324 -0
  670. package/src/task/index.ts +1197 -0
  671. package/src/task/isolation-backend.ts +72 -0
  672. package/src/task/name-generator.ts +1577 -0
  673. package/src/task/output-manager.ts +107 -0
  674. package/src/task/parallel.ts +116 -0
  675. package/src/task/render.ts +1035 -0
  676. package/src/task/subprocess-tool-registry.ts +88 -0
  677. package/src/task/template.ts +33 -0
  678. package/src/task/types.ts +230 -0
  679. package/src/task/worktree.ts +580 -0
  680. package/src/task/xcsh-command.ts +26 -0
  681. package/src/thinking.ts +87 -0
  682. package/src/tools/action-renderer.ts +198 -0
  683. package/src/tools/archive-reader.ts +315 -0
  684. package/src/tools/ask.ts +791 -0
  685. package/src/tools/ast-edit.ts +492 -0
  686. package/src/tools/ast-grep.ts +453 -0
  687. package/src/tools/auto-generated-guard.ts +305 -0
  688. package/src/tools/bash-interactive.ts +383 -0
  689. package/src/tools/bash-interceptor.ts +67 -0
  690. package/src/tools/bash-normalize.ts +107 -0
  691. package/src/tools/bash-skill-urls.ts +246 -0
  692. package/src/tools/bash.ts +878 -0
  693. package/src/tools/browser-renderer.ts +129 -0
  694. package/src/tools/browser.ts +1366 -0
  695. package/src/tools/calculator.ts +543 -0
  696. package/src/tools/cancel-job.ts +100 -0
  697. package/src/tools/catalog-workflow-runner.ts +718 -0
  698. package/src/tools/checkpoint.ts +133 -0
  699. package/src/tools/context.ts +39 -0
  700. package/src/tools/debug.ts +1004 -0
  701. package/src/tools/display-image-renderer.ts +96 -0
  702. package/src/tools/display-image.ts +109 -0
  703. package/src/tools/exit-plan-mode.ts +101 -0
  704. package/src/tools/fetch.ts +1462 -0
  705. package/src/tools/find.ts +437 -0
  706. package/src/tools/fs-cache-invalidation.ts +33 -0
  707. package/src/tools/gemini-image.ts +1004 -0
  708. package/src/tools/grep.ts +705 -0
  709. package/src/tools/index.ts +442 -0
  710. package/src/tools/inspect-image-renderer.ts +101 -0
  711. package/src/tools/inspect-image.ts +176 -0
  712. package/src/tools/json-tree.ts +266 -0
  713. package/src/tools/jtd-to-json-schema.ts +199 -0
  714. package/src/tools/jtd-to-typescript.ts +136 -0
  715. package/src/tools/jtd-utils.ts +102 -0
  716. package/src/tools/list-limit.ts +40 -0
  717. package/src/tools/mermaid-renderer.ts +127 -0
  718. package/src/tools/notebook.ts +288 -0
  719. package/src/tools/output-meta.ts +588 -0
  720. package/src/tools/path-utils.ts +560 -0
  721. package/src/tools/plan-mode-guard.ts +41 -0
  722. package/src/tools/poll-tool.ts +177 -0
  723. package/src/tools/puppeteer/00_stealth_tampering.txt +63 -0
  724. package/src/tools/puppeteer/01_stealth_activity.txt +20 -0
  725. package/src/tools/puppeteer/02_stealth_hairline.txt +11 -0
  726. package/src/tools/puppeteer/03_stealth_botd.txt +384 -0
  727. package/src/tools/puppeteer/04_stealth_iframe.txt +81 -0
  728. package/src/tools/puppeteer/05_stealth_webgl.txt +75 -0
  729. package/src/tools/puppeteer/06_stealth_screen.txt +72 -0
  730. package/src/tools/puppeteer/07_stealth_fonts.txt +97 -0
  731. package/src/tools/puppeteer/08_stealth_audio.txt +51 -0
  732. package/src/tools/puppeteer/09_stealth_locale.txt +46 -0
  733. package/src/tools/puppeteer/10_stealth_plugins.txt +206 -0
  734. package/src/tools/puppeteer/11_stealth_hardware.txt +8 -0
  735. package/src/tools/puppeteer/12_stealth_codecs.txt +40 -0
  736. package/src/tools/puppeteer/13_stealth_worker.txt +74 -0
  737. package/src/tools/python.ts +1184 -0
  738. package/src/tools/read.ts +1591 -0
  739. package/src/tools/render-mermaid.ts +93 -0
  740. package/src/tools/render-utils.ts +677 -0
  741. package/src/tools/renderers.ts +82 -0
  742. package/src/tools/report-tool-issue.ts +80 -0
  743. package/src/tools/resolve.ts +196 -0
  744. package/src/tools/review.ts +238 -0
  745. package/src/tools/search-tool-bm25.ts +288 -0
  746. package/src/tools/sqlite-reader.ts +623 -0
  747. package/src/tools/ssh.ts +322 -0
  748. package/src/tools/submit-result.ts +229 -0
  749. package/src/tools/todo-render.ts +33 -0
  750. package/src/tools/todo-write.ts +440 -0
  751. package/src/tools/tool-errors.ts +62 -0
  752. package/src/tools/tool-result.ts +93 -0
  753. package/src/tools/tool-timeouts.ts +30 -0
  754. package/src/tools/vim.ts +981 -0
  755. package/src/tools/write.ts +671 -0
  756. package/src/tools/xcsh-api-renderer.ts +402 -0
  757. package/src/tools/xcsh-api.ts +887 -0
  758. package/src/tui/code-cell.ts +101 -0
  759. package/src/tui/file-list.ts +47 -0
  760. package/src/tui/index.ts +11 -0
  761. package/src/tui/output-block.ts +175 -0
  762. package/src/tui/status-line.ts +39 -0
  763. package/src/tui/tree-list.ts +84 -0
  764. package/src/tui/types.ts +15 -0
  765. package/src/tui/utils.ts +103 -0
  766. package/src/utils/changelog.ts +98 -0
  767. package/src/utils/clipboard.ts +80 -0
  768. package/src/utils/command-args.ts +76 -0
  769. package/src/utils/commit-message-generator.ts +137 -0
  770. package/src/utils/edit-mode.ts +50 -0
  771. package/src/utils/event-bus.ts +33 -0
  772. package/src/utils/external-editor.ts +65 -0
  773. package/src/utils/file-display-mode.ts +37 -0
  774. package/src/utils/file-mentions.ts +376 -0
  775. package/src/utils/fuzzy.ts +108 -0
  776. package/src/utils/git.ts +1495 -0
  777. package/src/utils/gitstatus.ts +140 -0
  778. package/src/utils/image-convert.ts +27 -0
  779. package/src/utils/image-loading.ts +98 -0
  780. package/src/utils/image-passthrough.ts +118 -0
  781. package/src/utils/image-resize.ts +272 -0
  782. package/src/utils/image-viewer.ts +17 -0
  783. package/src/utils/lang-from-path.ts +239 -0
  784. package/src/utils/markit.ts +81 -0
  785. package/src/utils/open.ts +20 -0
  786. package/src/utils/session-color.ts +55 -0
  787. package/src/utils/shell-snapshot.ts +188 -0
  788. package/src/utils/title-generator.ts +193 -0
  789. package/src/utils/tool-choice.ts +28 -0
  790. package/src/utils/tools-manager.ts +356 -0
  791. package/src/vim/buffer.ts +309 -0
  792. package/src/vim/commands.ts +382 -0
  793. package/src/vim/engine.ts +2426 -0
  794. package/src/vim/parser.ts +151 -0
  795. package/src/vim/render.ts +252 -0
  796. package/src/vim/types.ts +197 -0
  797. package/src/web/kagi.ts +174 -0
  798. package/src/web/parallel.ts +346 -0
  799. package/src/web/scrapers/artifacthub.ts +207 -0
  800. package/src/web/scrapers/arxiv.ts +83 -0
  801. package/src/web/scrapers/aur.ts +162 -0
  802. package/src/web/scrapers/biorxiv.ts +133 -0
  803. package/src/web/scrapers/bluesky.ts +262 -0
  804. package/src/web/scrapers/brew.ts +172 -0
  805. package/src/web/scrapers/cheatsh.ts +68 -0
  806. package/src/web/scrapers/chocolatey.ts +196 -0
  807. package/src/web/scrapers/choosealicense.ts +95 -0
  808. package/src/web/scrapers/cisa-kev.ts +87 -0
  809. package/src/web/scrapers/clojars.ts +154 -0
  810. package/src/web/scrapers/coingecko.ts +177 -0
  811. package/src/web/scrapers/crates-io.ts +110 -0
  812. package/src/web/scrapers/crossref.ts +136 -0
  813. package/src/web/scrapers/devto.ts +147 -0
  814. package/src/web/scrapers/discogs.ts +306 -0
  815. package/src/web/scrapers/discourse.ts +197 -0
  816. package/src/web/scrapers/dockerhub.ts +138 -0
  817. package/src/web/scrapers/docs-rs.ts +653 -0
  818. package/src/web/scrapers/fdroid.ts +134 -0
  819. package/src/web/scrapers/firefox-addons.ts +191 -0
  820. package/src/web/scrapers/flathub.ts +223 -0
  821. package/src/web/scrapers/github-gist.ts +58 -0
  822. package/src/web/scrapers/github.ts +452 -0
  823. package/src/web/scrapers/gitlab.ts +401 -0
  824. package/src/web/scrapers/go-pkg.ts +266 -0
  825. package/src/web/scrapers/hackage.ts +140 -0
  826. package/src/web/scrapers/hackernews.ts +189 -0
  827. package/src/web/scrapers/hex.ts +105 -0
  828. package/src/web/scrapers/huggingface.ts +321 -0
  829. package/src/web/scrapers/iacr.ts +89 -0
  830. package/src/web/scrapers/index.ts +252 -0
  831. package/src/web/scrapers/jetbrains-marketplace.ts +159 -0
  832. package/src/web/scrapers/lemmy.ts +203 -0
  833. package/src/web/scrapers/lobsters.ts +175 -0
  834. package/src/web/scrapers/mastodon.ts +292 -0
  835. package/src/web/scrapers/maven.ts +138 -0
  836. package/src/web/scrapers/mdn.ts +169 -0
  837. package/src/web/scrapers/metacpan.ts +222 -0
  838. package/src/web/scrapers/musicbrainz.ts +250 -0
  839. package/src/web/scrapers/npm.ts +98 -0
  840. package/src/web/scrapers/nuget.ts +183 -0
  841. package/src/web/scrapers/nvd.ts +222 -0
  842. package/src/web/scrapers/ollama.ts +239 -0
  843. package/src/web/scrapers/open-vsx.ts +106 -0
  844. package/src/web/scrapers/opencorporates.ts +292 -0
  845. package/src/web/scrapers/openlibrary.ts +336 -0
  846. package/src/web/scrapers/orcid.ts +286 -0
  847. package/src/web/scrapers/osv.ts +176 -0
  848. package/src/web/scrapers/packagist.ts +160 -0
  849. package/src/web/scrapers/pub-dev.ts +143 -0
  850. package/src/web/scrapers/pubmed.ts +211 -0
  851. package/src/web/scrapers/pypi.ts +112 -0
  852. package/src/web/scrapers/rawg.ts +110 -0
  853. package/src/web/scrapers/readthedocs.ts +120 -0
  854. package/src/web/scrapers/reddit.ts +95 -0
  855. package/src/web/scrapers/repology.ts +251 -0
  856. package/src/web/scrapers/rfc.ts +201 -0
  857. package/src/web/scrapers/rubygems.ts +103 -0
  858. package/src/web/scrapers/searchcode.ts +190 -0
  859. package/src/web/scrapers/sec-edgar.ts +261 -0
  860. package/src/web/scrapers/semantic-scholar.ts +171 -0
  861. package/src/web/scrapers/snapcraft.ts +187 -0
  862. package/src/web/scrapers/sourcegraph.ts +336 -0
  863. package/src/web/scrapers/spdx.ts +108 -0
  864. package/src/web/scrapers/spotify.ts +198 -0
  865. package/src/web/scrapers/stackoverflow.ts +120 -0
  866. package/src/web/scrapers/terraform.ts +277 -0
  867. package/src/web/scrapers/tldr.ts +47 -0
  868. package/src/web/scrapers/twitter.ts +93 -0
  869. package/src/web/scrapers/types.ts +267 -0
  870. package/src/web/scrapers/utils.ts +109 -0
  871. package/src/web/scrapers/vimeo.ts +133 -0
  872. package/src/web/scrapers/vscode-marketplace.ts +187 -0
  873. package/src/web/scrapers/w3c.ts +156 -0
  874. package/src/web/scrapers/wikidata.ts +344 -0
  875. package/src/web/scrapers/wikipedia.ts +84 -0
  876. package/src/web/scrapers/youtube.ts +313 -0
  877. package/src/web/search/errors.ts +120 -0
  878. package/src/web/search/index.ts +346 -0
  879. package/src/web/search/params.ts +129 -0
  880. package/src/web/search/provider.ts +97 -0
  881. package/src/web/search/providers/anthropic.ts +339 -0
  882. package/src/web/search/providers/base.ts +35 -0
  883. package/src/web/search/providers/brave.ts +150 -0
  884. package/src/web/search/providers/codex.ts +402 -0
  885. package/src/web/search/providers/exa.ts +264 -0
  886. package/src/web/search/providers/firecrawl.ts +115 -0
  887. package/src/web/search/providers/gemini.ts +566 -0
  888. package/src/web/search/providers/jina.ts +99 -0
  889. package/src/web/search/providers/kagi.ts +70 -0
  890. package/src/web/search/providers/kimi.ts +157 -0
  891. package/src/web/search/providers/parallel.ts +63 -0
  892. package/src/web/search/providers/perplexity.ts +546 -0
  893. package/src/web/search/providers/synthetic.ts +113 -0
  894. package/src/web/search/providers/tavily.ts +162 -0
  895. package/src/web/search/providers/utils.ts +36 -0
  896. package/src/web/search/providers/zai.ts +311 -0
  897. package/src/web/search/render.ts +348 -0
  898. package/src/web/search/types.ts +438 -0
  899. package/src/web/search/utils.ts +17 -0
@@ -0,0 +1,1197 @@
1
+ /**
2
+ * Task tool - Delegate tasks to specialized agents.
3
+ *
4
+ * Discovers agent definitions from:
5
+ * - Bundled agents (shipped with xcsh-coding-agent)
6
+ * - ~/.xcsh/agent/agents/*.md (user-level)
7
+ * - .xcsh/agents/*.md (project-level)
8
+ *
9
+ * Supports:
10
+ * - Single agent execution
11
+ * - Parallel execution with concurrency limits
12
+ * - Progress tracking via JSON events
13
+ * - Session artifacts for debugging
14
+ */
15
+ import * as fs from "node:fs/promises";
16
+ import * as os from "node:os";
17
+ import path from "node:path";
18
+ import type { AgentTool, AgentToolResult, AgentToolUpdateCallback } from "@f5xc-salesdemos/pi-agent-core";
19
+ import type { Usage } from "@f5xc-salesdemos/pi-ai";
20
+ import { $env, prompt, Snowflake } from "@f5xc-salesdemos/pi-utils";
21
+ import type { ToolSession } from "..";
22
+ import { resolveAgentModelPatterns } from "../config/model-resolver";
23
+ import type { Theme } from "../modes/theme/theme";
24
+ import planModeSubagentPrompt from "../prompts/system/plan-mode-subagent.md" with { type: "text" };
25
+ import taskDescriptionTemplate from "../prompts/tools/task.md" with { type: "text" };
26
+ import taskSummaryTemplate from "../prompts/tools/task-summary.md" with { type: "text" };
27
+ import { formatBytes, formatDuration } from "../tools/render-utils";
28
+ // Import review tools for side effects (registers subagent tool handlers)
29
+ import "../tools/review";
30
+ import { generateCommitMessage } from "../utils/commit-message-generator";
31
+ import * as git from "../utils/git";
32
+ import { discoverAgents, getAgent } from "./discovery";
33
+ import { runSubprocess } from "./executor";
34
+ import { resolveIsolationBackendForTaskExecution } from "./isolation-backend";
35
+ import { AgentOutputManager } from "./output-manager";
36
+ import { mapWithConcurrencyLimit, Semaphore } from "./parallel";
37
+ import { renderCall, renderResult } from "./render";
38
+ import { renderTemplate } from "./template";
39
+ import {
40
+ type AgentDefinition,
41
+ type AgentProgress,
42
+ type SingleResult,
43
+ type TaskParams,
44
+ type TaskSchema,
45
+ type TaskToolDetails,
46
+ taskSchema,
47
+ taskSchemaNoIsolation,
48
+ } from "./types";
49
+ import {
50
+ applyBaseline,
51
+ applyNestedPatches,
52
+ captureBaseline,
53
+ captureDeltaPatch,
54
+ cleanupFuseOverlay,
55
+ cleanupProjfsOverlay,
56
+ cleanupTaskBranches,
57
+ cleanupWorktree,
58
+ commitToBranch,
59
+ ensureFuseOverlay,
60
+ ensureProjfsOverlay,
61
+ ensureWorktree,
62
+ getRepoRoot,
63
+ mergeTaskBranches,
64
+ type WorktreeBaseline,
65
+ } from "./worktree";
66
+
67
+ function createUsageTotals(): Usage {
68
+ return {
69
+ input: 0,
70
+ output: 0,
71
+ cacheRead: 0,
72
+ cacheWrite: 0,
73
+ totalTokens: 0,
74
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
75
+ };
76
+ }
77
+
78
+ function addUsageTotals(target: Usage, usage: Partial<Usage>): void {
79
+ const input = usage.input ?? 0;
80
+ const output = usage.output ?? 0;
81
+ const cacheRead = usage.cacheRead ?? 0;
82
+ const cacheWrite = usage.cacheWrite ?? 0;
83
+ const totalTokens = usage.totalTokens ?? input + output + cacheRead + cacheWrite;
84
+ const cost =
85
+ usage.cost ??
86
+ ({
87
+ input: 0,
88
+ output: 0,
89
+ cacheRead: 0,
90
+ cacheWrite: 0,
91
+ total: 0,
92
+ } satisfies Usage["cost"]);
93
+
94
+ target.input += input;
95
+ target.output += output;
96
+ target.cacheRead += cacheRead;
97
+ target.cacheWrite += cacheWrite;
98
+ target.totalTokens += totalTokens;
99
+ target.cost.input += cost.input;
100
+ target.cost.output += cost.output;
101
+ target.cost.cacheRead += cost.cacheRead;
102
+ target.cost.cacheWrite += cost.cacheWrite;
103
+ target.cost.total += cost.total;
104
+ }
105
+
106
+ // Re-export types and utilities
107
+ export { loadBundledAgents as BUNDLED_AGENTS } from "./agents";
108
+ export { discoverCommands, expandCommand, getCommand } from "./commands";
109
+ export { discoverAgents, getAgent } from "./discovery";
110
+ export { AgentOutputManager } from "./output-manager";
111
+ export type {
112
+ AgentDefinition,
113
+ AgentProgress,
114
+ SingleResult,
115
+ SubagentLifecyclePayload,
116
+ SubagentProgressPayload,
117
+ TaskParams,
118
+ TaskToolDetails,
119
+ } from "./types";
120
+ export {
121
+ TASK_SUBAGENT_EVENT_CHANNEL,
122
+ TASK_SUBAGENT_LIFECYCLE_CHANNEL,
123
+ TASK_SUBAGENT_PROGRESS_CHANNEL,
124
+ taskSchema,
125
+ } from "./types";
126
+
127
+ /**
128
+ * Render the tool description from a cached agent list and current settings.
129
+ */
130
+ function renderDescription(
131
+ agents: AgentDefinition[],
132
+ maxConcurrency: number,
133
+ isolationEnabled: boolean,
134
+ asyncEnabled: boolean,
135
+ disabledAgents: string[],
136
+ ): string {
137
+ const filteredAgents = disabledAgents.length > 0 ? agents.filter(a => !disabledAgents.includes(a.name)) : agents;
138
+ return prompt.render(taskDescriptionTemplate, {
139
+ agents: filteredAgents,
140
+ MAX_CONCURRENCY: maxConcurrency,
141
+ isolationEnabled,
142
+ asyncEnabled,
143
+ });
144
+ }
145
+
146
+ // ═══════════════════════════════════════════════════════════════════════════
147
+ // Tool Class
148
+ // ═══════════════════════════════════════════════════════════════════════════
149
+
150
+ /**
151
+ * Task tool - Delegate tasks to specialized agents.
152
+ *
153
+ * Requires async initialization to discover available agents.
154
+ * Use `TaskTool.create(session)` to instantiate.
155
+ */
156
+ export class TaskTool implements AgentTool<TaskSchema, TaskToolDetails, Theme> {
157
+ readonly name = "task";
158
+ readonly label = "Task";
159
+ readonly strict = true;
160
+ readonly parameters: TaskSchema;
161
+ readonly renderCall = renderCall;
162
+ readonly renderResult = renderResult;
163
+ readonly #discoveredAgents: AgentDefinition[];
164
+ readonly #blockedAgent: string | undefined;
165
+
166
+ /** Dynamic description that reflects current disabled-agent settings */
167
+ get description(): string {
168
+ const disabledAgents = this.session.settings.get("task.disabledAgents") as string[];
169
+ const maxConcurrency = this.session.settings.get("task.maxConcurrency");
170
+ const isolationMode = this.session.settings.get("task.isolation.mode");
171
+ return renderDescription(
172
+ this.#discoveredAgents,
173
+ maxConcurrency,
174
+ isolationMode !== "none",
175
+ this.session.settings.get("async.enabled"),
176
+ disabledAgents,
177
+ );
178
+ }
179
+ private constructor(
180
+ private readonly session: ToolSession,
181
+ discoveredAgents: AgentDefinition[],
182
+ isolationEnabled: boolean,
183
+ ) {
184
+ this.parameters = isolationEnabled ? taskSchema : taskSchemaNoIsolation;
185
+ this.#blockedAgent = $env.PI_BLOCKED_AGENT;
186
+ this.#discoveredAgents = discoveredAgents;
187
+ }
188
+
189
+ /**
190
+ * Create a TaskTool instance with async agent discovery.
191
+ */
192
+ static async create(session: ToolSession): Promise<TaskTool> {
193
+ const isolationMode = session.settings.get("task.isolation.mode");
194
+ const { agents } = await discoverAgents(session.cwd);
195
+ return new TaskTool(session, agents, isolationMode !== "none");
196
+ }
197
+
198
+ async execute(
199
+ _toolCallId: string,
200
+ params: TaskParams,
201
+ signal?: AbortSignal,
202
+ onUpdate?: AgentToolUpdateCallback<TaskToolDetails>,
203
+ ): Promise<AgentToolResult<TaskToolDetails>> {
204
+ const asyncEnabled = this.session.settings.get("async.enabled");
205
+ const selectedAgent = this.#discoveredAgents.find(agent => agent.name === params.agent);
206
+ if (!asyncEnabled || selectedAgent?.blocking === true) {
207
+ return this.#executeSync(_toolCallId, params, signal, onUpdate);
208
+ }
209
+
210
+ const manager = this.session.asyncJobManager;
211
+ if (!manager) {
212
+ return {
213
+ content: [{ type: "text", text: "Async execution is enabled but no async job manager is available." }],
214
+ details: { projectAgentsDir: null, results: [], totalDurationMs: 0 },
215
+ };
216
+ }
217
+
218
+ const taskItems = params.tasks ?? [];
219
+ if (taskItems.length === 0) {
220
+ return this.#executeSync(_toolCallId, params, signal, onUpdate);
221
+ }
222
+
223
+ const outputManager =
224
+ this.session.agentOutputManager ?? new AgentOutputManager(this.session.getArtifactsDir ?? (() => null));
225
+ const uniqueIds = await outputManager.allocateBatch(taskItems.map(t => t.id));
226
+ const fallbackAgentSource =
227
+ this.#discoveredAgents.find(agent => agent.name === params.agent)?.source ?? "bundled";
228
+ const renderedTasks = taskItems.map(taskItem => renderTemplate(params.context, taskItem));
229
+ const progressByTaskId = new Map<string, AgentProgress>();
230
+ for (let index = 0; index < renderedTasks.length; index++) {
231
+ const renderedTask = renderedTasks[index];
232
+ progressByTaskId.set(renderedTask.id, {
233
+ index,
234
+ id: renderedTask.id,
235
+ agent: params.agent,
236
+ agentSource: fallbackAgentSource,
237
+ status: "pending",
238
+ task: renderedTask.task,
239
+ assignment: renderedTask.assignment,
240
+ description: renderedTask.description,
241
+ recentTools: [],
242
+ recentOutput: [],
243
+ toolCount: 0,
244
+ tokens: 0,
245
+ durationMs: 0,
246
+ });
247
+ }
248
+
249
+ const startedJobs: Array<{ jobId: string; taskId: string }> = [];
250
+ const failedSchedules: string[] = [];
251
+ let completedJobs = 0;
252
+ let failedJobs = 0;
253
+
254
+ const getProgressSnapshot = (): AgentProgress[] => {
255
+ return Array.from(progressByTaskId.values())
256
+ .sort((a, b) => a.index - b.index)
257
+ .map(progress => structuredClone(progress));
258
+ };
259
+
260
+ const buildAsyncDetails = (state: "running" | "completed" | "failed", jobId: string): TaskToolDetails => ({
261
+ projectAgentsDir: null,
262
+ results: [],
263
+ totalDurationMs: 0,
264
+ progress: getProgressSnapshot(),
265
+ async: { state, jobId, type: "task" },
266
+ });
267
+
268
+ const emitAsyncUpdate = (state: "running" | "completed" | "failed", text: string): void => {
269
+ const primaryJobId = startedJobs[0]?.jobId ?? "task";
270
+ onUpdate?.({
271
+ content: [{ type: "text", text }],
272
+ details: buildAsyncDetails(state, primaryJobId),
273
+ });
274
+ };
275
+
276
+ const maxConcurrency = this.session.settings.get("task.maxConcurrency");
277
+ const semaphore = new Semaphore(maxConcurrency);
278
+
279
+ for (let i = 0; i < taskItems.length; i++) {
280
+ const taskItem = taskItems[i];
281
+ if (signal?.aborted) {
282
+ failedSchedules.push(`${taskItem.id}: cancelled before scheduling`);
283
+ const progress = progressByTaskId.get(taskItem.id);
284
+ if (progress) {
285
+ progress.status = "aborted";
286
+ }
287
+ continue;
288
+ }
289
+
290
+ const uniqueId = uniqueIds[i];
291
+ const singleParams: TaskParams = { ...params, tasks: [taskItem] };
292
+ const label = uniqueId;
293
+ try {
294
+ const jobId = manager.register(
295
+ "task",
296
+ label,
297
+ async ({ signal: runSignal, reportProgress }) => {
298
+ const startedAt = Date.now();
299
+ const progress = progressByTaskId.get(taskItem.id);
300
+ await semaphore.acquire();
301
+ if (runSignal.aborted) {
302
+ semaphore.release();
303
+ if (progress) {
304
+ progress.status = "aborted";
305
+ }
306
+ throw new Error("Aborted before execution");
307
+ }
308
+ if (progress) {
309
+ progress.status = "running";
310
+ }
311
+ await reportProgress(
312
+ `Running background task ${taskItem.id}...`,
313
+ buildAsyncDetails("running", startedJobs[0]?.jobId ?? label) as unknown as Record<string, unknown>,
314
+ );
315
+ try {
316
+ const result = await this.#executeSync(_toolCallId, singleParams, runSignal, undefined, [
317
+ uniqueId,
318
+ ]);
319
+ const finalText = result.content.find(part => part.type === "text")?.text ?? "(no output)";
320
+ const singleResult = result.details?.results[0];
321
+ if (progress) {
322
+ progress.status = singleResult?.aborted
323
+ ? "aborted"
324
+ : (singleResult?.exitCode ?? 0) === 0
325
+ ? "completed"
326
+ : "failed";
327
+ progress.durationMs = singleResult?.durationMs ?? Math.max(0, Date.now() - startedAt);
328
+ progress.tokens = singleResult?.tokens ?? 0;
329
+ progress.extractedToolData = singleResult?.extractedToolData;
330
+ }
331
+ completedJobs += 1;
332
+ if (singleResult && ((singleResult.aborted ?? false) || singleResult.exitCode !== 0)) {
333
+ failedJobs += 1;
334
+ }
335
+ const remaining = taskItems.length - completedJobs;
336
+ const isDone = remaining === 0;
337
+ await reportProgress(
338
+ isDone
339
+ ? `Background task batch complete: ${completedJobs}/${taskItems.length} finished.`
340
+ : `Background task batch progress: ${completedJobs}/${taskItems.length} finished (${remaining} running).`,
341
+ buildAsyncDetails(
342
+ isDone ? (failedJobs > 0 || failedSchedules.length > 0 ? "failed" : "completed") : "running",
343
+ startedJobs[0]?.jobId ?? label,
344
+ ) as unknown as Record<string, unknown>,
345
+ );
346
+ if (isDone) {
347
+ emitAsyncUpdate(
348
+ failedJobs > 0 || failedSchedules.length > 0 ? "failed" : "completed",
349
+ `Background task batch complete: ${completedJobs}/${taskItems.length} finished.`,
350
+ );
351
+ }
352
+ return finalText;
353
+ } catch (error) {
354
+ if (progress) {
355
+ progress.status = "failed";
356
+ progress.durationMs = Math.max(0, Date.now() - startedAt);
357
+ }
358
+ completedJobs += 1;
359
+ failedJobs += 1;
360
+ const remaining = taskItems.length - completedJobs;
361
+ const isDone = remaining === 0;
362
+ await reportProgress(
363
+ isDone
364
+ ? `Background task batch complete with failures: ${failedJobs} failed.`
365
+ : `Background task batch progress: ${completedJobs}/${taskItems.length} finished (${remaining} running).`,
366
+ buildAsyncDetails(
367
+ isDone ? "failed" : "running",
368
+ startedJobs[0]?.jobId ?? label,
369
+ ) as unknown as Record<string, unknown>,
370
+ );
371
+ if (isDone) {
372
+ emitAsyncUpdate(
373
+ "failed",
374
+ `Background task batch complete with failures: ${failedJobs} failed.`,
375
+ );
376
+ }
377
+ throw error;
378
+ } finally {
379
+ semaphore.release();
380
+ }
381
+ },
382
+ {
383
+ id: label,
384
+ onProgress: (text, details) => {
385
+ const progressDetails =
386
+ (details as TaskToolDetails | undefined) ??
387
+ buildAsyncDetails("running", startedJobs[0]?.jobId ?? label);
388
+ onUpdate?.({ content: [{ type: "text", text }], details: progressDetails });
389
+ },
390
+ },
391
+ );
392
+ startedJobs.push({ jobId, taskId: taskItem.id });
393
+ } catch (error) {
394
+ const message = error instanceof Error ? error.message : String(error);
395
+ failedSchedules.push(`${taskItem.id}: ${message}`);
396
+ const progress = progressByTaskId.get(taskItem.id);
397
+ if (progress) {
398
+ progress.status = "failed";
399
+ }
400
+ }
401
+ }
402
+
403
+ if (startedJobs.length === 0) {
404
+ const failureText = `Failed to start background task jobs: ${failedSchedules.join("; ")}`;
405
+ return {
406
+ content: [{ type: "text", text: failureText }],
407
+ details: { projectAgentsDir: null, results: [], totalDurationMs: 0 },
408
+ };
409
+ }
410
+
411
+ emitAsyncUpdate(
412
+ "running",
413
+ `Launching ${startedJobs.length} background ${startedJobs.length === 1 ? "task" : "tasks"}...`,
414
+ );
415
+
416
+ const scheduleFailureSummary =
417
+ failedSchedules.length > 0
418
+ ? ` Failed to schedule ${failedSchedules.length} task${failedSchedules.length === 1 ? "" : "s"}.`
419
+ : "";
420
+
421
+ return {
422
+ content: [
423
+ {
424
+ type: "text",
425
+ text: `Started ${startedJobs.length} background task job${startedJobs.length === 1 ? "" : "s"} using ${params.agent}.${scheduleFailureSummary} Results will be delivered when complete.`,
426
+ },
427
+ ],
428
+ details: {
429
+ projectAgentsDir: null,
430
+ results: [],
431
+ totalDurationMs: 0,
432
+ progress: getProgressSnapshot(),
433
+ async: { state: "running", jobId: startedJobs[0].jobId, type: "task" },
434
+ },
435
+ };
436
+ }
437
+
438
+ async #executeSync(
439
+ _toolCallId: string,
440
+ params: TaskParams,
441
+ signal?: AbortSignal,
442
+ onUpdate?: AgentToolUpdateCallback<TaskToolDetails>,
443
+ preAllocatedIds?: string[],
444
+ ): Promise<AgentToolResult<TaskToolDetails>> {
445
+ const startTime = Date.now();
446
+ const { agents, projectAgentsDir } = await discoverAgents(this.session.cwd);
447
+ const { agent: agentName, context, schema: outputSchema } = params;
448
+ const isolationMode = this.session.settings.get("task.isolation.mode");
449
+ const isolationRequested = "isolated" in params ? params.isolated === true : false;
450
+ const isIsolated = isolationMode !== "none" && isolationRequested;
451
+ const mergeMode = this.session.settings.get("task.isolation.merge");
452
+ const commitStyle = this.session.settings.get("task.isolation.commits");
453
+ const maxConcurrency = this.session.settings.get("task.maxConcurrency");
454
+ const taskDepth = this.session.taskDepth ?? 0;
455
+
456
+ if (isolationMode === "none" && "isolated" in params) {
457
+ return {
458
+ content: [
459
+ {
460
+ type: "text",
461
+ text: "Task isolation is disabled. Remove the isolated argument or set task.isolation.mode to 'worktree', 'fuse-overlay', or 'fuse-projfs'.",
462
+ },
463
+ ],
464
+ details: {
465
+ projectAgentsDir,
466
+ results: [],
467
+ totalDurationMs: 0,
468
+ },
469
+ };
470
+ }
471
+
472
+ // Validate agent exists
473
+ const agent = getAgent(agents, agentName);
474
+ if (!agent) {
475
+ const available = agents.map(a => a.name).join(", ") || "none";
476
+ return {
477
+ content: [
478
+ {
479
+ type: "text",
480
+ text: `Unknown agent "${agentName}". Available: ${available}`,
481
+ },
482
+ ],
483
+ details: {
484
+ projectAgentsDir,
485
+ results: [],
486
+ totalDurationMs: 0,
487
+ },
488
+ };
489
+ }
490
+
491
+ // Check if agent is disabled in settings
492
+ const disabledAgents = this.session.settings.get("task.disabledAgents") as string[];
493
+ if (disabledAgents.length > 0 && disabledAgents.includes(agentName)) {
494
+ const enabled = agents.filter(a => !disabledAgents.includes(a.name)).map(a => a.name);
495
+ return {
496
+ content: [
497
+ {
498
+ type: "text",
499
+ text: `Agent "${agentName}" is disabled in settings. Enable it via /agents, or use a different agent type.${enabled.length > 0 ? ` Available: ${enabled.join(", ")}` : ""}`,
500
+ },
501
+ ],
502
+ details: {
503
+ projectAgentsDir,
504
+ results: [],
505
+ totalDurationMs: 0,
506
+ },
507
+ };
508
+ }
509
+
510
+ const planModeState = this.session.getPlanModeState?.();
511
+ const planModeTools = ["read", "grep", "find", "ls", "lsp", "web_search"];
512
+ const effectiveAgent: typeof agent = planModeState?.enabled
513
+ ? {
514
+ ...agent,
515
+ systemPrompt: `${planModeSubagentPrompt}\n\n${agent.systemPrompt}`,
516
+ tools: planModeTools,
517
+ spawns: undefined,
518
+ }
519
+ : agent;
520
+
521
+ // Apply per-agent model override from settings (highest priority)
522
+ const agentModelOverrides = this.session.settings.get("task.agentModelOverrides");
523
+ const settingsModelOverride = agentModelOverrides[agentName];
524
+ const modelOverride = resolveAgentModelPatterns({
525
+ settingsOverride: settingsModelOverride,
526
+ agentModel: effectiveAgent.model,
527
+ settings: this.session.settings,
528
+ activeModelPattern: this.session.getActiveModelString?.(),
529
+ fallbackModelPattern: this.session.getModelString?.(),
530
+ });
531
+ const thinkingLevelOverride = effectiveAgent.thinkingLevel;
532
+
533
+ // Output schema priority: caller params > agent frontmatter > inherited from parent session
534
+ const effectiveOutputSchema = outputSchema ?? effectiveAgent.output ?? this.session.outputSchema;
535
+
536
+ // Handle empty or missing tasks
537
+ if (!params.tasks || params.tasks.length === 0) {
538
+ return {
539
+ content: [
540
+ {
541
+ type: "text",
542
+ text: `No tasks provided. Use: { agent, context, tasks: [{id, description, args}, ...] }`,
543
+ },
544
+ ],
545
+ details: {
546
+ projectAgentsDir,
547
+ results: [],
548
+ totalDurationMs: 0,
549
+ },
550
+ };
551
+ }
552
+
553
+ const tasks = params.tasks;
554
+ const missingTaskIndexes: number[] = [];
555
+ const idIndexes = new Map<string, number[]>();
556
+
557
+ for (let i = 0; i < tasks.length; i++) {
558
+ const id = tasks[i]?.id;
559
+ if (typeof id !== "string" || id.trim() === "") {
560
+ missingTaskIndexes.push(i);
561
+ continue;
562
+ }
563
+ const normalizedId = id.toLowerCase();
564
+ const indexes = idIndexes.get(normalizedId);
565
+ if (indexes) {
566
+ indexes.push(i);
567
+ } else {
568
+ idIndexes.set(normalizedId, [i]);
569
+ }
570
+ }
571
+
572
+ const duplicateIds: Array<{ id: string; indexes: number[] }> = [];
573
+ for (const [normalizedId, indexes] of idIndexes.entries()) {
574
+ if (indexes.length > 1) {
575
+ duplicateIds.push({
576
+ id: tasks[indexes[0]]?.id ?? normalizedId,
577
+ indexes,
578
+ });
579
+ }
580
+ }
581
+
582
+ if (missingTaskIndexes.length > 0 || duplicateIds.length > 0) {
583
+ const problems: string[] = [];
584
+ if (missingTaskIndexes.length > 0) {
585
+ problems.push(`Missing task ids at indexes: ${missingTaskIndexes.join(", ")}`);
586
+ }
587
+ if (duplicateIds.length > 0) {
588
+ const details = duplicateIds.map(entry => `${entry.id} (indexes ${entry.indexes.join(", ")})`).join("; ");
589
+ problems.push(`Duplicate task ids detected (case-insensitive): ${details}`);
590
+ }
591
+ return {
592
+ content: [{ type: "text", text: `Invalid tasks: ${problems.join(". ")}` }],
593
+ details: {
594
+ projectAgentsDir,
595
+ results: [],
596
+ totalDurationMs: 0,
597
+ },
598
+ };
599
+ }
600
+
601
+ let repoRoot: string | null = null;
602
+ let baseline: WorktreeBaseline | null = null;
603
+ if (isIsolated) {
604
+ try {
605
+ repoRoot = await getRepoRoot(this.session.cwd);
606
+ baseline = await captureBaseline(repoRoot);
607
+ } catch (err) {
608
+ const message = err instanceof Error ? err.message : String(err);
609
+ return {
610
+ content: [
611
+ {
612
+ type: "text",
613
+ text: `Isolated task execution requires a git repository. ${message}`,
614
+ },
615
+ ],
616
+ details: {
617
+ projectAgentsDir,
618
+ results: [],
619
+ totalDurationMs: Date.now() - startTime,
620
+ },
621
+ };
622
+ }
623
+ }
624
+
625
+ let effectiveIsolationMode = isolationMode;
626
+ let isolationBackendWarning = "";
627
+ try {
628
+ const resolvedIsolation = await resolveIsolationBackendForTaskExecution(isolationMode, isIsolated, repoRoot);
629
+ effectiveIsolationMode = resolvedIsolation.effectiveIsolationMode;
630
+ isolationBackendWarning = resolvedIsolation.warning;
631
+ } catch (err) {
632
+ const message = err instanceof Error ? err.message : String(err);
633
+ return {
634
+ content: [
635
+ {
636
+ type: "text",
637
+ text: message,
638
+ },
639
+ ],
640
+ details: {
641
+ projectAgentsDir,
642
+ results: [],
643
+ totalDurationMs: Date.now() - startTime,
644
+ },
645
+ };
646
+ }
647
+
648
+ // Derive artifacts directory
649
+ const sessionFile = this.session.getSessionFile();
650
+ const artifactsDir = sessionFile ? sessionFile.slice(0, -6) : null;
651
+ const tempArtifactsDir = artifactsDir ? null : path.join(os.tmpdir(), `xcsh-task-${Snowflake.next()}`);
652
+ const effectiveArtifactsDir = artifactsDir || tempArtifactsDir!;
653
+
654
+ // Initialize progress tracking
655
+ const progressMap = new Map<number, AgentProgress>();
656
+
657
+ // Update callback
658
+ const emitProgress = () => {
659
+ const progress = Array.from(progressMap.values()).sort((a, b) => a.index - b.index);
660
+ onUpdate?.({
661
+ content: [{ type: "text", text: `Running ${params.tasks.length} agents...` }],
662
+ details: {
663
+ projectAgentsDir,
664
+ results: [],
665
+ totalDurationMs: Date.now() - startTime,
666
+ progress,
667
+ },
668
+ });
669
+ };
670
+
671
+ try {
672
+ // Check self-recursion prevention
673
+ if (this.#blockedAgent && agentName === this.#blockedAgent) {
674
+ return {
675
+ content: [
676
+ {
677
+ type: "text",
678
+ text: `Cannot spawn ${this.#blockedAgent} agent from within itself (recursion prevention). Use a different agent type.`,
679
+ },
680
+ ],
681
+ details: {
682
+ projectAgentsDir,
683
+ results: [],
684
+ totalDurationMs: Date.now() - startTime,
685
+ },
686
+ };
687
+ }
688
+
689
+ // Check spawn restrictions from parent
690
+ const parentSpawns = this.session.getSessionSpawns() ?? "*";
691
+ const allowedSpawns = parentSpawns.split(",").map(s => s.trim());
692
+ const isSpawnAllowed = (): boolean => {
693
+ if (parentSpawns === "") return false; // Empty = deny all
694
+ if (parentSpawns === "*") return true; // Wildcard = allow all
695
+ return allowedSpawns.includes(agentName);
696
+ };
697
+
698
+ if (!isSpawnAllowed()) {
699
+ const allowed = parentSpawns === "" ? "none (spawns disabled for this agent)" : parentSpawns;
700
+ return {
701
+ content: [{ type: "text", text: `Cannot spawn '${agentName}'. Allowed: ${allowed}` }],
702
+ details: {
703
+ projectAgentsDir,
704
+ results: [],
705
+ totalDurationMs: Date.now() - startTime,
706
+ },
707
+ };
708
+ }
709
+
710
+ // Write parent conversation context for subagents
711
+ await fs.mkdir(effectiveArtifactsDir, { recursive: true });
712
+ const compactContext = this.session.getCompactContext?.();
713
+ let contextFilePath: string | undefined;
714
+ if (compactContext) {
715
+ contextFilePath = path.join(effectiveArtifactsDir, "context.md");
716
+ await Bun.write(contextFilePath, compactContext);
717
+ }
718
+
719
+ // Build full prompts with context prepended
720
+ // Allocate unique IDs across the session to prevent artifact collisions
721
+ let uniqueIds: string[];
722
+ if (preAllocatedIds && preAllocatedIds.length === tasks.length) {
723
+ uniqueIds = preAllocatedIds;
724
+ } else {
725
+ const outputManager =
726
+ this.session.agentOutputManager ?? new AgentOutputManager(this.session.getArtifactsDir ?? (() => null));
727
+ uniqueIds = await outputManager.allocateBatch(tasks.map(t => t.id));
728
+ }
729
+ const tasksWithUniqueIds = tasks.map((t, i) => ({ ...t, id: uniqueIds[i] }));
730
+
731
+ // Build full prompts with context prepended
732
+ const tasksWithContext = tasksWithUniqueIds.map(t => renderTemplate(context, t));
733
+ const availableSkills = [...(this.session.skills ?? [])];
734
+ const contextFiles = this.session.contextFiles?.filter(
735
+ file => path.basename(file.path).toLowerCase() !== "agents.md",
736
+ );
737
+ const promptTemplates = this.session.promptTemplates;
738
+
739
+ // Initialize progress for all tasks
740
+ for (let i = 0; i < tasksWithContext.length; i++) {
741
+ const t = tasksWithContext[i];
742
+ progressMap.set(i, {
743
+ index: i,
744
+ id: t.id,
745
+ agent: agentName,
746
+ agentSource: agent.source,
747
+ status: "pending",
748
+ task: t.task,
749
+ assignment: t.assignment,
750
+ recentTools: [],
751
+ recentOutput: [],
752
+ toolCount: 0,
753
+ tokens: 0,
754
+ durationMs: 0,
755
+ modelOverride,
756
+ description: t.description,
757
+ });
758
+ }
759
+ emitProgress();
760
+
761
+ const runTask = async (task: (typeof tasksWithContext)[number], index: number) => {
762
+ if (!isIsolated) {
763
+ return runSubprocess({
764
+ cwd: this.session.cwd,
765
+ agent,
766
+ task: task.task,
767
+ assignment: task.assignment,
768
+ description: task.description,
769
+ index,
770
+ id: task.id,
771
+ taskDepth,
772
+ modelOverride,
773
+ thinkingLevel: thinkingLevelOverride,
774
+ outputSchema: effectiveOutputSchema,
775
+ sessionFile,
776
+ persistArtifacts: !!artifactsDir,
777
+ artifactsDir: effectiveArtifactsDir,
778
+ contextFile: contextFilePath,
779
+ enableLsp: false,
780
+ signal,
781
+ eventBus: this.session.eventBus,
782
+ onProgress: progress => {
783
+ progressMap.set(index, {
784
+ ...structuredClone(progress),
785
+ });
786
+ emitProgress();
787
+ },
788
+ authStorage: this.session.authStorage,
789
+ modelRegistry: this.session.modelRegistry,
790
+ settings: this.session.settings,
791
+ mcpManager: this.session.mcpManager,
792
+ contextFiles,
793
+ skills: availableSkills,
794
+ promptTemplates,
795
+ });
796
+ }
797
+
798
+ const taskStart = Date.now();
799
+ let isolationDir: string | undefined;
800
+ try {
801
+ if (!repoRoot || !baseline) {
802
+ throw new Error("Isolated task execution not initialized.");
803
+ }
804
+ const taskBaseline = structuredClone(baseline);
805
+
806
+ if (effectiveIsolationMode === "fuse-overlay") {
807
+ isolationDir = await ensureFuseOverlay(repoRoot, task.id);
808
+ } else if (effectiveIsolationMode === "fuse-projfs") {
809
+ isolationDir = await ensureProjfsOverlay(repoRoot, task.id);
810
+ } else {
811
+ isolationDir = await ensureWorktree(repoRoot, task.id);
812
+ await applyBaseline(isolationDir, taskBaseline);
813
+ }
814
+
815
+ const result = await runSubprocess({
816
+ cwd: this.session.cwd,
817
+ worktree: isolationDir,
818
+ agent,
819
+ task: task.task,
820
+ assignment: task.assignment,
821
+ description: task.description,
822
+ index,
823
+ id: task.id,
824
+ taskDepth,
825
+ modelOverride,
826
+ thinkingLevel: thinkingLevelOverride,
827
+ outputSchema: effectiveOutputSchema,
828
+ sessionFile,
829
+ persistArtifacts: !!artifactsDir,
830
+ artifactsDir: effectiveArtifactsDir,
831
+ contextFile: contextFilePath,
832
+ enableLsp: false,
833
+ signal,
834
+ eventBus: this.session.eventBus,
835
+ onProgress: progress => {
836
+ progressMap.set(index, {
837
+ ...structuredClone(progress),
838
+ });
839
+ emitProgress();
840
+ },
841
+ authStorage: this.session.authStorage,
842
+ modelRegistry: this.session.modelRegistry,
843
+ settings: this.session.settings,
844
+ mcpManager: this.session.mcpManager,
845
+ contextFiles,
846
+ skills: availableSkills,
847
+ promptTemplates,
848
+ });
849
+ if (mergeMode === "branch" && result.exitCode === 0) {
850
+ try {
851
+ const commitMsg =
852
+ commitStyle === "ai" && this.session.modelRegistry
853
+ ? async (diff: string) => {
854
+ return generateCommitMessage(
855
+ diff,
856
+ this.session.modelRegistry!,
857
+ this.session.settings,
858
+ this.session.getSessionId?.() ?? undefined,
859
+ );
860
+ }
861
+ : undefined;
862
+ const commitResult = await commitToBranch(
863
+ isolationDir,
864
+ taskBaseline,
865
+ task.id,
866
+ task.description,
867
+ commitMsg,
868
+ );
869
+ return {
870
+ ...result,
871
+ branchName: commitResult?.branchName,
872
+ nestedPatches: commitResult?.nestedPatches,
873
+ };
874
+ } catch (mergeErr) {
875
+ // Agent succeeded but branch commit failed — clean up stale branch
876
+ const branchName = `xcsh/task/${task.id}`;
877
+ await git.branch.tryDelete(repoRoot, branchName);
878
+ const msg = mergeErr instanceof Error ? mergeErr.message : String(mergeErr);
879
+ return { ...result, error: `Merge failed: ${msg}` };
880
+ }
881
+ }
882
+ if (result.exitCode === 0) {
883
+ try {
884
+ const delta = await captureDeltaPatch(isolationDir, taskBaseline);
885
+ const patchPath = path.join(effectiveArtifactsDir, `${task.id}.patch`);
886
+ await Bun.write(patchPath, delta.rootPatch);
887
+ return {
888
+ ...result,
889
+ patchPath,
890
+ nestedPatches: delta.nestedPatches,
891
+ };
892
+ } catch (patchErr) {
893
+ const msg = patchErr instanceof Error ? patchErr.message : String(patchErr);
894
+ return { ...result, error: `Patch capture failed: ${msg}` };
895
+ }
896
+ }
897
+ return result;
898
+ } catch (err) {
899
+ const message = err instanceof Error ? err.message : String(err);
900
+ return {
901
+ index,
902
+ id: task.id,
903
+ agent: agent.name,
904
+ agentSource: agent.source,
905
+ task: task.task,
906
+ assignment: task.assignment,
907
+ description: task.description,
908
+ exitCode: 1,
909
+ output: "",
910
+ stderr: message,
911
+ truncated: false,
912
+ durationMs: Date.now() - taskStart,
913
+ tokens: 0,
914
+ modelOverride,
915
+ error: message,
916
+ };
917
+ } finally {
918
+ if (isolationDir) {
919
+ if (effectiveIsolationMode === "fuse-overlay") {
920
+ await cleanupFuseOverlay(isolationDir);
921
+ } else if (effectiveIsolationMode === "fuse-projfs") {
922
+ await cleanupProjfsOverlay(isolationDir);
923
+ } else {
924
+ await cleanupWorktree(isolationDir);
925
+ }
926
+ }
927
+ }
928
+ };
929
+
930
+ // Execute in parallel with concurrency limit
931
+ const { results: partialResults, aborted } = await mapWithConcurrencyLimit(
932
+ tasksWithContext,
933
+ maxConcurrency,
934
+ runTask,
935
+ signal,
936
+ );
937
+
938
+ // Fill in skipped tasks (undefined entries from abort) with placeholder results
939
+ const results: SingleResult[] = partialResults.map((result, index) => {
940
+ if (result !== undefined) {
941
+ return result;
942
+ }
943
+ const task = tasksWithContext[index];
944
+ return {
945
+ index,
946
+ id: task.id,
947
+ agent: agentName,
948
+ agentSource: agent.source,
949
+ task: task.task,
950
+ assignment: task.assignment,
951
+ description: task.description,
952
+ exitCode: 1,
953
+ output: "",
954
+ stderr: "Skipped (cancelled before start)",
955
+ truncated: false,
956
+ durationMs: 0,
957
+ tokens: 0,
958
+ modelOverride,
959
+ error: "Cancelled before start",
960
+ aborted: true,
961
+ abortReason: "Cancelled before start",
962
+ };
963
+ });
964
+
965
+ // Aggregate usage from executor results (already accumulated incrementally)
966
+ const aggregatedUsage = createUsageTotals();
967
+ let hasAggregatedUsage = false;
968
+ for (const result of results) {
969
+ if (result.usage) {
970
+ addUsageTotals(aggregatedUsage, result.usage);
971
+ hasAggregatedUsage = true;
972
+ }
973
+ }
974
+
975
+ // Collect output paths (artifacts already written by executor in real-time)
976
+ const outputPaths: string[] = [];
977
+ const patchPaths: string[] = [];
978
+ for (const result of results) {
979
+ if (result.outputPath) {
980
+ outputPaths.push(result.outputPath);
981
+ }
982
+ if (result.patchPath) {
983
+ patchPaths.push(result.patchPath);
984
+ }
985
+ }
986
+
987
+ let mergeSummary = "";
988
+ let changesApplied: boolean | null = null;
989
+ let mergedBranchesForNestedPatches: Set<string> | null = null;
990
+ if (isIsolated && repoRoot) {
991
+ try {
992
+ if (mergeMode === "branch") {
993
+ // Branch mode: merge task branches sequentially
994
+ const branchEntries = results
995
+ .filter(r => r.branchName && r.exitCode === 0 && !r.aborted)
996
+ .map(r => ({ branchName: r.branchName!, taskId: r.id, description: r.description }));
997
+
998
+ if (branchEntries.length === 0) {
999
+ changesApplied = true;
1000
+ } else {
1001
+ const mergeResult = await mergeTaskBranches(repoRoot, branchEntries);
1002
+ mergedBranchesForNestedPatches = new Set(mergeResult.merged);
1003
+ changesApplied = mergeResult.failed.length === 0;
1004
+
1005
+ if (changesApplied) {
1006
+ mergeSummary = `\n\nMerged ${mergeResult.merged.length} branch${mergeResult.merged.length === 1 ? "" : "es"}: ${mergeResult.merged.join(", ")}`;
1007
+ } else {
1008
+ const mergedPart =
1009
+ mergeResult.merged.length > 0 ? `Merged: ${mergeResult.merged.join(", ")}.\n` : "";
1010
+ const failedPart = `Failed: ${mergeResult.failed.join(", ")}.`;
1011
+ const conflictPart = mergeResult.conflict ? `\nConflict: ${mergeResult.conflict}` : "";
1012
+ mergeSummary = `\n\n<system-notification>Branch merge failed. ${mergedPart}${failedPart}${conflictPart}\nUnmerged branches remain for manual resolution.</system-notification>`;
1013
+ }
1014
+ }
1015
+
1016
+ // Clean up merged branches (keep failed ones for manual resolution)
1017
+ const allBranches = branchEntries.map(b => b.branchName);
1018
+ if (changesApplied) {
1019
+ await cleanupTaskBranches(repoRoot, allBranches);
1020
+ }
1021
+ } else {
1022
+ // Patch mode: combine and apply patches
1023
+ const patchesInOrder = results.map(result => result.patchPath).filter(Boolean) as string[];
1024
+ const missingPatch = results.some(result => !result.patchPath);
1025
+ if (missingPatch) {
1026
+ changesApplied = false;
1027
+ } else {
1028
+ const patchStats = await Promise.all(
1029
+ patchesInOrder.map(async patchPath => ({
1030
+ patchPath,
1031
+ size: (await fs.stat(patchPath)).size,
1032
+ })),
1033
+ );
1034
+ const nonEmptyPatches = patchStats.filter(patch => patch.size > 0).map(patch => patch.patchPath);
1035
+ if (nonEmptyPatches.length === 0) {
1036
+ changesApplied = true;
1037
+ } else {
1038
+ const patchTexts = await Promise.all(
1039
+ nonEmptyPatches.map(async patchPath => Bun.file(patchPath).text()),
1040
+ );
1041
+ const combinedPatch = patchTexts
1042
+ .map(text => (text.endsWith("\n") ? text : `${text}\n`))
1043
+ .join("");
1044
+ if (!combinedPatch.trim()) {
1045
+ changesApplied = true;
1046
+ } else {
1047
+ changesApplied = await git.patch.canApplyText(repoRoot, combinedPatch);
1048
+ if (changesApplied) {
1049
+ try {
1050
+ await git.patch.applyText(repoRoot, combinedPatch);
1051
+ } catch {
1052
+ changesApplied = false;
1053
+ }
1054
+ }
1055
+ }
1056
+ }
1057
+ }
1058
+
1059
+ if (changesApplied) {
1060
+ mergeSummary = "\n\nApplied patches: yes";
1061
+ } else {
1062
+ const notification =
1063
+ "<system-notification>Patches were not applied and must be handled manually.</system-notification>";
1064
+ const patchList =
1065
+ patchPaths.length > 0
1066
+ ? `\n\nPatch artifacts:\n${patchPaths.map(patch => `- ${patch}`).join("\n")}`
1067
+ : "";
1068
+ mergeSummary = `\n\n${notification}${patchList}`;
1069
+ }
1070
+ }
1071
+ } catch (mergeErr) {
1072
+ const msg = mergeErr instanceof Error ? mergeErr.message : String(mergeErr);
1073
+ changesApplied = false;
1074
+ mergeSummary = `\n\n<system-notification>Merge phase failed: ${msg}\nTask outputs are preserved but changes were not applied.</system-notification>`;
1075
+ }
1076
+ }
1077
+
1078
+ // Apply nested repo patches (separate from parent git)
1079
+ if (isIsolated && repoRoot && (mergeMode === "branch" || changesApplied !== false)) {
1080
+ const allNestedPatches = results
1081
+ .filter(r => {
1082
+ if (!r.nestedPatches || r.nestedPatches.length === 0 || r.exitCode !== 0 || r.aborted) {
1083
+ return false;
1084
+ }
1085
+ if (mergeMode !== "branch") {
1086
+ return true;
1087
+ }
1088
+ if (!r.branchName || !mergedBranchesForNestedPatches) {
1089
+ return false;
1090
+ }
1091
+ return mergedBranchesForNestedPatches.has(r.branchName);
1092
+ })
1093
+ .flatMap(r => r.nestedPatches!);
1094
+ if (allNestedPatches.length > 0) {
1095
+ try {
1096
+ const commitMsg =
1097
+ commitStyle === "ai" && this.session.modelRegistry
1098
+ ? async (diff: string) => {
1099
+ return generateCommitMessage(
1100
+ diff,
1101
+ this.session.modelRegistry!,
1102
+ this.session.settings,
1103
+ this.session.getSessionId?.() ?? undefined,
1104
+ );
1105
+ }
1106
+ : undefined;
1107
+ await applyNestedPatches(repoRoot, allNestedPatches, commitMsg);
1108
+ } catch {
1109
+ // Nested patch failures are non-fatal to the parent merge
1110
+ mergeSummary +=
1111
+ "\n\n<system-notification>Some nested repository patches failed to apply.</system-notification>";
1112
+ }
1113
+ }
1114
+ }
1115
+
1116
+ // Build final output - match plugin format
1117
+ const cancelledCount = results.filter(r => r.aborted).length;
1118
+ const successCount = results.filter(r => r.exitCode === 0 && !r.error && !r.aborted).length;
1119
+ const totalDuration = Date.now() - startTime;
1120
+
1121
+ const summaries = results.map(r => {
1122
+ const status = r.aborted
1123
+ ? "cancelled"
1124
+ : r.exitCode === 0 && r.error
1125
+ ? "merge failed"
1126
+ : r.exitCode === 0
1127
+ ? "completed"
1128
+ : `failed (exit ${r.exitCode})`;
1129
+ const output = r.output.trim() || r.stderr.trim() || "(no output)";
1130
+ const outputCharCount = r.outputMeta?.charCount ?? output.length;
1131
+ const fullOutputThreshold = 5000;
1132
+ let preview = output;
1133
+ let truncated = false;
1134
+ if (outputCharCount > fullOutputThreshold) {
1135
+ const slice = output.slice(0, fullOutputThreshold);
1136
+ const lastNewline = slice.lastIndexOf("\n");
1137
+ preview = lastNewline >= 0 ? slice.slice(0, lastNewline) : slice;
1138
+ truncated = true;
1139
+ }
1140
+ return {
1141
+ agent: r.agent,
1142
+ status,
1143
+ id: r.id,
1144
+ preview,
1145
+ truncated,
1146
+ meta: r.outputMeta
1147
+ ? {
1148
+ lineCount: r.outputMeta.lineCount,
1149
+ charSize: formatBytes(r.outputMeta.charCount),
1150
+ }
1151
+ : undefined,
1152
+ };
1153
+ });
1154
+
1155
+ const outputIds = results.filter(r => !r.aborted || r.output.trim()).map(r => `agent://${r.id}`);
1156
+ const backendSummaryPrefix = isolationBackendWarning ? `\n\n${isolationBackendWarning}` : "";
1157
+ const summary = prompt.render(taskSummaryTemplate, {
1158
+ successCount,
1159
+ totalCount: results.length,
1160
+ cancelledCount,
1161
+ hasCancelledNote: aborted && cancelledCount > 0,
1162
+ duration: formatDuration(totalDuration),
1163
+ summaries,
1164
+ outputIds,
1165
+ agentName,
1166
+ mergeSummary: `${backendSummaryPrefix}${mergeSummary}`,
1167
+ });
1168
+
1169
+ // Cleanup temp directory if used
1170
+ const shouldCleanupTempArtifacts =
1171
+ tempArtifactsDir && (!isIsolated || changesApplied === true || changesApplied === null);
1172
+ if (shouldCleanupTempArtifacts) {
1173
+ await fs.rm(tempArtifactsDir, { recursive: true, force: true });
1174
+ }
1175
+
1176
+ return {
1177
+ content: [{ type: "text", text: summary }],
1178
+ details: {
1179
+ projectAgentsDir,
1180
+ results: results,
1181
+ totalDurationMs: totalDuration,
1182
+ usage: hasAggregatedUsage ? aggregatedUsage : undefined,
1183
+ outputPaths,
1184
+ },
1185
+ };
1186
+ } catch (err) {
1187
+ return {
1188
+ content: [{ type: "text", text: `Task execution failed: ${err}` }],
1189
+ details: {
1190
+ projectAgentsDir,
1191
+ results: [],
1192
+ totalDurationMs: Date.now() - startTime,
1193
+ },
1194
+ };
1195
+ }
1196
+ }
1197
+ }