@oh-my-pi/pi-coding-agent 6.9.69 → 8.0.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 (502) hide show
  1. package/CHANGELOG.md +219 -51
  2. package/README.md +1 -1
  3. package/docs/hooks.md +2 -2
  4. package/docs/sdk.md +1 -1
  5. package/examples/sdk/04-skills.ts +1 -1
  6. package/package.json +10 -10
  7. package/scripts/format-prompts.ts +143 -0
  8. package/scripts/generate-template.ts +1 -1
  9. package/src/cli/args.ts +3 -3
  10. package/src/cli/config-cli.ts +4 -4
  11. package/src/cli/file-processor.ts +3 -3
  12. package/src/cli/list-models.ts +2 -2
  13. package/src/cli/plugin-cli.ts +3 -3
  14. package/src/cli/session-picker.ts +2 -2
  15. package/src/cli/setup-cli.ts +2 -2
  16. package/src/cli/stats-cli.ts +1 -1
  17. package/src/cli/update-cli.ts +2 -2
  18. package/src/{core → config}/keybindings.ts +1 -1
  19. package/src/{core → config}/model-registry.ts +8 -1
  20. package/src/{core → config}/model-resolver.ts +3 -3
  21. package/src/{core → config}/prompt-templates.ts +2 -2
  22. package/src/{core → config}/settings-manager.ts +6 -6
  23. package/src/{core/cursor/exec-bridge.ts → cursor.ts} +4 -4
  24. package/src/discovery/agents-md.ts +4 -4
  25. package/src/discovery/builtin.ts +17 -17
  26. package/src/discovery/claude.ts +12 -12
  27. package/src/discovery/cline.ts +6 -6
  28. package/src/discovery/codex.ts +21 -21
  29. package/src/discovery/cursor.ts +9 -9
  30. package/src/discovery/gemini.ts +9 -9
  31. package/src/discovery/github.ts +6 -6
  32. package/src/discovery/helpers.ts +4 -4
  33. package/src/discovery/index.ts +16 -16
  34. package/src/discovery/mcp-json.ts +4 -4
  35. package/src/discovery/ssh.ts +4 -4
  36. package/src/discovery/vscode.ts +4 -4
  37. package/src/discovery/windsurf.ts +6 -6
  38. package/src/{core/tools/exa → exa}/company.ts +2 -3
  39. package/src/{core/tools/exa → exa}/index.ts +2 -2
  40. package/src/{core/tools/exa → exa}/linkedin.ts +2 -3
  41. package/src/{core/tools/exa → exa}/mcp-client.ts +2 -2
  42. package/src/{core/tools/exa → exa}/render.ts +3 -3
  43. package/src/{core/tools/exa → exa}/researcher.ts +1 -1
  44. package/src/{core/tools/exa → exa}/search.ts +2 -10
  45. package/src/{core/tools/exa → exa}/websets.ts +1 -1
  46. package/src/{core → exec}/bash-executor.ts +23 -7
  47. package/src/{core → export}/custom-share.ts +1 -1
  48. package/src/{core/export-html → export/html}/index.ts +3 -3
  49. package/src/{core → export}/ttsr.ts +2 -2
  50. package/src/{core → extensibility}/custom-commands/bundled/review/index.ts +4 -4
  51. package/src/{core → extensibility}/custom-commands/loader.ts +3 -3
  52. package/src/{core → extensibility}/custom-commands/types.ts +1 -1
  53. package/src/{core → extensibility}/custom-tools/loader.ts +9 -9
  54. package/src/{core → extensibility}/custom-tools/types.ts +6 -6
  55. package/src/{core → extensibility}/custom-tools/wrapper.ts +1 -1
  56. package/src/{core → extensibility}/extensions/loader.ts +8 -8
  57. package/src/{core → extensibility}/extensions/runner.ts +3 -3
  58. package/src/{core → extensibility}/extensions/types.ts +15 -15
  59. package/src/{core → extensibility}/extensions/wrapper.ts +1 -1
  60. package/src/{core → extensibility}/hooks/index.ts +1 -1
  61. package/src/{core → extensibility}/hooks/loader.ts +7 -7
  62. package/src/{core → extensibility}/hooks/runner.ts +4 -4
  63. package/src/{core → extensibility}/hooks/types.ts +9 -9
  64. package/src/{core → extensibility}/plugins/doctor.ts +1 -1
  65. package/src/{core → extensibility}/plugins/installer.ts +2 -3
  66. package/src/{core → extensibility}/plugins/paths.ts +1 -1
  67. package/src/{core → extensibility}/skills.ts +8 -48
  68. package/src/{core → extensibility}/slash-commands.ts +6 -6
  69. package/src/index.ts +127 -128
  70. package/src/internal-urls/agent-protocol.ts +126 -0
  71. package/src/internal-urls/artifact-protocol.ts +93 -0
  72. package/src/internal-urls/index.ts +28 -0
  73. package/src/internal-urls/json-query.ts +126 -0
  74. package/src/internal-urls/router.ts +69 -0
  75. package/src/internal-urls/rule-protocol.ts +56 -0
  76. package/src/internal-urls/skill-protocol.ts +112 -0
  77. package/src/internal-urls/types.ts +48 -0
  78. package/src/{core/python-executor.ts → ipy/executor.ts} +74 -13
  79. package/src/{core/python-gateway-coordinator.ts → ipy/gateway-coordinator.ts} +40 -270
  80. package/src/{core/python-kernel.ts → ipy/kernel.ts} +38 -10
  81. package/src/{core/python-prelude.py → ipy/prelude.py} +201 -8
  82. package/src/ipy/prelude.ts +3 -0
  83. package/src/{core/tools/lsp → lsp}/client.ts +7 -6
  84. package/src/{core/tools/lsp → lsp}/clients/biome-client.ts +1 -1
  85. package/src/{core/tools/lsp → lsp}/clients/index.ts +1 -1
  86. package/src/{core/tools/lsp → lsp}/clients/lsp-linter-client.ts +4 -4
  87. package/src/{core/tools/lsp → lsp}/config.ts +1 -1
  88. package/src/{core/tools/lsp → lsp}/index.ts +29 -17
  89. package/src/{core/tools/lsp → lsp}/render.ts +2 -2
  90. package/src/{core/tools/lsp → lsp}/types.ts +14 -16
  91. package/src/{core/tools/lsp → lsp}/utils.ts +1 -1
  92. package/src/main.ts +12 -12
  93. package/src/{core/mcp → mcp}/config.ts +8 -8
  94. package/src/{core/mcp → mcp}/loader.ts +5 -6
  95. package/src/{core/mcp → mcp}/manager.ts +2 -2
  96. package/src/{core/mcp → mcp}/tool-bridge.ts +35 -6
  97. package/src/{core/mcp → mcp}/tool-cache.ts +1 -1
  98. package/src/{core/mcp → mcp}/transports/http.ts +7 -1
  99. package/src/{core/mcp → mcp}/transports/stdio.ts +1 -1
  100. package/src/{core/mcp → mcp}/types.ts +1 -1
  101. package/src/migrations.ts +2 -2
  102. package/src/modes/{interactive/components → components}/armin.ts +1 -1
  103. package/src/modes/{interactive/components → components}/assistant-message.ts +1 -1
  104. package/src/modes/{interactive/components → components}/bash-execution.ts +37 -29
  105. package/src/modes/{interactive/components → components}/bordered-loader.ts +1 -1
  106. package/src/modes/{interactive/components → components}/branch-summary-message.ts +2 -2
  107. package/src/modes/{interactive/components → components}/compaction-summary-message.ts +2 -2
  108. package/src/modes/{interactive/components → components}/custom-message.ts +3 -3
  109. package/src/modes/{interactive/components → components}/diff.ts +1 -1
  110. package/src/modes/{interactive/components → components}/dynamic-border.ts +1 -1
  111. package/src/modes/{interactive/components → components}/extensions/extension-dashboard.ts +3 -3
  112. package/src/modes/{interactive/components → components}/extensions/extension-list.ts +2 -2
  113. package/src/modes/{interactive/components → components}/extensions/inspector-panel.ts +1 -1
  114. package/src/modes/{interactive/components → components}/extensions/state-manager.ts +11 -17
  115. package/src/modes/{interactive/components → components}/extensions/types.ts +1 -1
  116. package/src/modes/{interactive/components → components}/footer.ts +3 -3
  117. package/src/modes/{interactive/components → components}/history-search.ts +2 -2
  118. package/src/modes/{interactive/components → components}/hook-editor.ts +1 -1
  119. package/src/modes/{interactive/components → components}/hook-input.ts +1 -1
  120. package/src/modes/{interactive/components → components}/hook-message.ts +3 -3
  121. package/src/modes/{interactive/components → components}/hook-selector.ts +1 -1
  122. package/src/modes/{interactive/components → components}/keybinding-hints.ts +2 -2
  123. package/src/modes/{interactive/components → components}/login-dialog.ts +1 -1
  124. package/src/modes/{interactive/components → components}/model-selector.ts +5 -5
  125. package/src/modes/{interactive/components → components}/oauth-selector.ts +2 -2
  126. package/src/modes/{interactive/components → components}/plugin-settings.ts +3 -3
  127. package/src/modes/{interactive/components → components}/python-execution.ts +35 -24
  128. package/src/modes/{interactive/components → components}/queue-mode-selector.ts +1 -1
  129. package/src/modes/{interactive/components → components}/read-tool-group.ts +2 -2
  130. package/src/modes/{interactive/components → components}/session-selector.ts +3 -3
  131. package/src/modes/{interactive/components → components}/settings-defs.ts +2 -2
  132. package/src/modes/{interactive/components → components}/settings-selector.ts +2 -2
  133. package/src/modes/{interactive/components → components}/show-images-selector.ts +1 -1
  134. package/src/modes/{interactive/components → components}/status-line/segments.ts +2 -2
  135. package/src/modes/{interactive/components → components}/status-line/separators.ts +1 -1
  136. package/src/modes/{interactive/components → components}/status-line/types.ts +2 -2
  137. package/src/modes/{interactive/components → components}/status-line-segment-editor.ts +2 -2
  138. package/src/modes/{interactive/components → components}/status-line.ts +3 -3
  139. package/src/modes/{interactive/components → components}/theme-selector.ts +1 -1
  140. package/src/modes/{interactive/components → components}/thinking-selector.ts +1 -1
  141. package/src/modes/{interactive/components → components}/todo-display.ts +3 -4
  142. package/src/modes/{interactive/components → components}/todo-reminder.ts +2 -2
  143. package/src/modes/{interactive/components → components}/tool-execution.ts +8 -8
  144. package/src/modes/{interactive/components → components}/tree-selector.ts +3 -3
  145. package/src/modes/{interactive/components → components}/ttsr-notification.ts +2 -2
  146. package/src/modes/{interactive/components → components}/user-message-selector.ts +1 -1
  147. package/src/modes/{interactive/components → components}/user-message.ts +1 -1
  148. package/src/modes/{interactive/components → components}/welcome.ts +2 -2
  149. package/src/modes/{interactive/controllers → controllers}/command-controller.ts +381 -30
  150. package/src/modes/{interactive/controllers → controllers}/event-controller.ts +9 -9
  151. package/src/modes/{interactive/controllers → controllers}/extension-ui-controller.ts +8 -8
  152. package/src/modes/{interactive/controllers → controllers}/input-controller.ts +61 -13
  153. package/src/modes/{interactive/controllers → controllers}/selector-controller.ts +16 -16
  154. package/src/modes/index.ts +1 -1
  155. package/src/modes/{interactive/interactive-mode.ts → interactive-mode.ts} +20 -15
  156. package/src/modes/print-mode.ts +1 -1
  157. package/src/modes/rpc/rpc-client.ts +3 -3
  158. package/src/modes/rpc/rpc-mode.ts +3 -3
  159. package/src/modes/rpc/rpc-types.ts +3 -3
  160. package/src/modes/{interactive/theme → theme}/theme.ts +1 -1
  161. package/src/modes/{interactive/types.ts → types.ts} +10 -10
  162. package/src/modes/{interactive/utils → utils}/ui-helpers.ts +20 -27
  163. package/src/{core/tools/patch → patch}/applicator.ts +1 -1
  164. package/src/{core/tools/patch → patch}/diff.ts +1 -1
  165. package/src/{core/tools/patch → patch}/index.ts +31 -36
  166. package/src/{core/tools/patch → patch}/shared.ts +9 -6
  167. package/src/prompts/agents/explore.md +83 -46
  168. package/src/prompts/agents/init.md +9 -4
  169. package/src/prompts/agents/plan.md +8 -7
  170. package/src/prompts/agents/reviewer.md +36 -18
  171. package/src/prompts/agents/task.md +4 -4
  172. package/src/prompts/compaction/branch-summary-preamble.md +0 -1
  173. package/src/prompts/review-request.md +0 -1
  174. package/src/prompts/system/custom-system-prompt.md +2 -14
  175. package/src/prompts/system/file-operations.md +0 -2
  176. package/src/prompts/system/system-prompt.md +182 -171
  177. package/src/prompts/system/web-search.md +26 -0
  178. package/src/prompts/tools/ask.md +31 -24
  179. package/src/prompts/tools/bash.md +20 -17
  180. package/src/prompts/tools/calculator.md +9 -5
  181. package/src/prompts/tools/fetch.md +16 -0
  182. package/src/prompts/tools/find.md +15 -5
  183. package/src/prompts/tools/gemini-image.md +21 -6
  184. package/src/prompts/tools/grep.md +28 -12
  185. package/src/prompts/tools/lsp.md +35 -14
  186. package/src/prompts/tools/patch.md +39 -41
  187. package/src/prompts/tools/python.md +59 -77
  188. package/src/prompts/tools/read.md +23 -22
  189. package/src/prompts/tools/replace.md +19 -12
  190. package/src/prompts/tools/ssh.md +21 -28
  191. package/src/prompts/tools/task.md +54 -44
  192. package/src/prompts/tools/todo-write.md +52 -163
  193. package/src/prompts/tools/web-search.md +16 -9
  194. package/src/prompts/tools/write.md +13 -2
  195. package/src/{core/sdk.ts → sdk.ts} +65 -34
  196. package/src/{core → session}/agent-session.ts +157 -41
  197. package/src/{core → session}/agent-storage.ts +2 -2
  198. package/src/session/artifacts.ts +110 -0
  199. package/src/{core → session}/auth-storage.ts +525 -203
  200. package/src/{core → session}/compaction/branch-summarization.ts +5 -5
  201. package/src/{core → session}/compaction/compaction.ts +6 -6
  202. package/src/{core → session}/compaction/utils.ts +3 -3
  203. package/src/{core → session}/history-storage.ts +1 -1
  204. package/src/{core → session}/messages.ts +6 -8
  205. package/src/{core → session}/session-manager.ts +2 -2
  206. package/src/{core → session}/storage-migration.ts +2 -2
  207. package/src/session/streaming-output.ts +177 -0
  208. package/src/{core/ssh → ssh}/connection-manager.ts +1 -1
  209. package/src/{core/ssh → ssh}/ssh-executor.ts +19 -4
  210. package/src/{core/ssh → ssh}/sshfs-mount.ts +1 -1
  211. package/src/{core/system-prompt.ts → system-prompt.ts} +8 -37
  212. package/src/{core/tools/task → task}/agents.ts +8 -8
  213. package/src/{core/tools/task → task}/commands.ts +5 -6
  214. package/src/{core/tools/task → task}/discovery.ts +3 -3
  215. package/src/{core/tools/task → task}/executor.ts +34 -44
  216. package/src/{core/tools/task → task}/index.ts +206 -50
  217. package/src/{core/tools/task → task}/render.ts +80 -23
  218. package/src/{core/tools/task → task}/subprocess-tool-registry.ts +1 -1
  219. package/src/task/template.ts +47 -0
  220. package/src/{core/tools/task → task}/types.ts +19 -27
  221. package/src/{core/tools/task → task}/worker-protocol.ts +8 -4
  222. package/src/{core/tools/task → task}/worker.ts +34 -29
  223. package/src/task/worktree.ts +166 -0
  224. package/src/{core/tools → tools}/ask.ts +13 -21
  225. package/src/{core/tools → tools}/bash-interceptor.ts +1 -1
  226. package/src/{core/tools → tools}/bash.ts +61 -63
  227. package/src/{core/tools → tools}/calculator.ts +4 -4
  228. package/src/{core/tools → tools}/complete.ts +1 -1
  229. package/src/{core/tools → tools}/context.ts +2 -2
  230. package/src/{core/tools/web-fetch.ts → tools/fetch.ts} +97 -76
  231. package/src/{core/tools → tools}/find.ts +96 -107
  232. package/src/{core/tools → tools}/gemini-image.ts +420 -29
  233. package/src/{core/tools → tools}/grep.ts +155 -164
  234. package/src/{core/tools → tools}/index.ts +63 -56
  235. package/src/tools/list-limit.ts +40 -0
  236. package/src/{core/tools → tools}/ls.ts +44 -35
  237. package/src/{core/tools → tools}/notebook.ts +3 -3
  238. package/src/tools/output-meta.ts +443 -0
  239. package/src/tools/output-utils.ts +63 -0
  240. package/src/{core/tools → tools}/python.ts +106 -89
  241. package/src/tools/read.ts +882 -0
  242. package/src/{core/tools → tools}/render-utils.ts +1 -1
  243. package/src/{core/tools → tools}/renderers.ts +8 -10
  244. package/src/{core/tools → tools}/review.ts +2 -2
  245. package/src/{core/tools → tools}/ssh.ts +56 -59
  246. package/src/{core/tools → tools}/todo-write.ts +12 -23
  247. package/src/tools/tool-errors.ts +95 -0
  248. package/src/tools/tool-result.ts +92 -0
  249. package/src/{core/tools → tools}/truncate.ts +2 -2
  250. package/src/{core/tools → tools}/write.ts +15 -13
  251. package/src/utils/changelog.ts +1 -1
  252. package/src/{core → utils}/file-mentions.ts +4 -4
  253. package/src/utils/image-convert.ts +1 -1
  254. package/src/utils/image-resize.ts +1 -1
  255. package/src/utils/shell.ts +1 -1
  256. package/src/{core → utils}/title-generator.ts +4 -4
  257. package/src/utils/tools-manager.ts +1 -1
  258. package/src/{core/tools/web-scrapers → web/scrapers}/choosealicense.ts +1 -1
  259. package/src/{core/tools/web-scrapers → web/scrapers}/twitter.ts +3 -2
  260. package/src/{core/tools/web-scrapers → web/scrapers}/types.ts +4 -2
  261. package/src/{core/tools/web-scrapers → web/scrapers}/utils.ts +1 -1
  262. package/src/{core/tools/web-scrapers → web/scrapers}/youtube.ts +14 -13
  263. package/src/{core/tools/web-search → web/search}/auth.ts +4 -4
  264. package/src/{core/tools/web-search → web/search}/index.ts +22 -71
  265. package/src/{core/tools/web-search → web/search}/providers/anthropic.ts +7 -10
  266. package/src/{core/tools/web-search → web/search}/providers/exa.ts +2 -2
  267. package/src/{core/tools/web-search → web/search}/providers/perplexity.ts +4 -16
  268. package/src/{core/tools/web-search → web/search}/render.ts +3 -3
  269. package/scripts/migrate-sessions.sh +0 -93
  270. package/src/core/index.ts +0 -56
  271. package/src/core/python-prelude.ts +0 -3
  272. package/src/core/ssh-executor.ts +0 -5
  273. package/src/core/streaming-output.ts +0 -115
  274. package/src/core/tools/output.ts +0 -519
  275. package/src/core/tools/read.ts +0 -717
  276. package/src/core/tools/task/template.ts +0 -37
  277. package/src/prompts/tools/output.md +0 -47
  278. package/src/prompts/tools/web-fetch.md +0 -9
  279. /package/src/{core/tools/exa → exa}/types.ts +0 -0
  280. /package/src/{core → exec}/exec.ts +0 -0
  281. /package/src/{core/export-html → export/html}/template.css +0 -0
  282. /package/src/{core/export-html → export/html}/template.generated.ts +0 -0
  283. /package/src/{core/export-html → export/html}/template.html +0 -0
  284. /package/src/{core/export-html → export/html}/template.js +0 -0
  285. /package/src/{core/export-html → export/html}/template.macro.ts +0 -0
  286. /package/src/{core/export-html → export/html}/vendor/highlight.min.js +0 -0
  287. /package/src/{core/export-html → export/html}/vendor/marked.min.js +0 -0
  288. /package/src/{core → extensibility}/custom-commands/index.ts +0 -0
  289. /package/src/{core → extensibility}/custom-tools/index.ts +0 -0
  290. /package/src/{core → extensibility}/extensions/index.ts +0 -0
  291. /package/src/{core → extensibility}/hooks/tool-wrapper.ts +0 -0
  292. /package/src/{core → extensibility}/plugins/index.ts +0 -0
  293. /package/src/{core → extensibility}/plugins/loader.ts +0 -0
  294. /package/src/{core → extensibility}/plugins/manager.ts +0 -0
  295. /package/src/{core → extensibility}/plugins/parser.ts +0 -0
  296. /package/src/{core → extensibility}/plugins/types.ts +0 -0
  297. /package/src/{core/python-modules.ts → ipy/modules.ts} +0 -0
  298. /package/src/{core/tools/lsp → lsp}/defaults.json +0 -0
  299. /package/src/{core/tools/lsp → lsp}/edits.ts +0 -0
  300. /package/src/{core/tools/lsp → lsp}/lspmux.ts +0 -0
  301. /package/src/{core/tools/lsp → lsp}/rust-analyzer.ts +0 -0
  302. /package/src/{core/mcp → mcp}/client.ts +0 -0
  303. /package/src/{core/mcp → mcp}/index.ts +0 -0
  304. /package/src/{core/mcp → mcp}/json-rpc.ts +0 -0
  305. /package/src/{core/mcp → mcp}/transports/index.ts +0 -0
  306. /package/src/modes/{interactive/components → components}/countdown-timer.ts +0 -0
  307. /package/src/modes/{interactive/components → components}/custom-editor.ts +0 -0
  308. /package/src/modes/{interactive/components → components}/extensions/index.ts +0 -0
  309. /package/src/modes/{interactive/components → components}/index.ts +0 -0
  310. /package/src/modes/{interactive/components → components}/status-line/index.ts +0 -0
  311. /package/src/modes/{interactive/components → components}/status-line/presets.ts +0 -0
  312. /package/src/modes/{interactive/components → components}/visual-truncate.ts +0 -0
  313. /package/src/modes/{interactive/theme → theme}/dark.json +0 -0
  314. /package/src/modes/{interactive/theme → theme}/defaults/alabaster.json +0 -0
  315. /package/src/modes/{interactive/theme → theme}/defaults/amethyst.json +0 -0
  316. /package/src/modes/{interactive/theme → theme}/defaults/anthracite.json +0 -0
  317. /package/src/modes/{interactive/theme → theme}/defaults/basalt.json +0 -0
  318. /package/src/modes/{interactive/theme → theme}/defaults/birch.json +0 -0
  319. /package/src/modes/{interactive/theme → theme}/defaults/dark-abyss.json +0 -0
  320. /package/src/modes/{interactive/theme → theme}/defaults/dark-arctic.json +0 -0
  321. /package/src/modes/{interactive/theme → theme}/defaults/dark-aurora.json +0 -0
  322. /package/src/modes/{interactive/theme → theme}/defaults/dark-catppuccin.json +0 -0
  323. /package/src/modes/{interactive/theme → theme}/defaults/dark-cavern.json +0 -0
  324. /package/src/modes/{interactive/theme → theme}/defaults/dark-copper.json +0 -0
  325. /package/src/modes/{interactive/theme → theme}/defaults/dark-cosmos.json +0 -0
  326. /package/src/modes/{interactive/theme → theme}/defaults/dark-cyberpunk.json +0 -0
  327. /package/src/modes/{interactive/theme → theme}/defaults/dark-dracula.json +0 -0
  328. /package/src/modes/{interactive/theme → theme}/defaults/dark-eclipse.json +0 -0
  329. /package/src/modes/{interactive/theme → theme}/defaults/dark-ember.json +0 -0
  330. /package/src/modes/{interactive/theme → theme}/defaults/dark-equinox.json +0 -0
  331. /package/src/modes/{interactive/theme → theme}/defaults/dark-forest.json +0 -0
  332. /package/src/modes/{interactive/theme → theme}/defaults/dark-github.json +0 -0
  333. /package/src/modes/{interactive/theme → theme}/defaults/dark-gruvbox.json +0 -0
  334. /package/src/modes/{interactive/theme → theme}/defaults/dark-lavender.json +0 -0
  335. /package/src/modes/{interactive/theme → theme}/defaults/dark-lunar.json +0 -0
  336. /package/src/modes/{interactive/theme → theme}/defaults/dark-midnight.json +0 -0
  337. /package/src/modes/{interactive/theme → theme}/defaults/dark-monochrome.json +0 -0
  338. /package/src/modes/{interactive/theme → theme}/defaults/dark-monokai.json +0 -0
  339. /package/src/modes/{interactive/theme → theme}/defaults/dark-nebula.json +0 -0
  340. /package/src/modes/{interactive/theme → theme}/defaults/dark-nord.json +0 -0
  341. /package/src/modes/{interactive/theme → theme}/defaults/dark-ocean.json +0 -0
  342. /package/src/modes/{interactive/theme → theme}/defaults/dark-one.json +0 -0
  343. /package/src/modes/{interactive/theme → theme}/defaults/dark-rainforest.json +0 -0
  344. /package/src/modes/{interactive/theme → theme}/defaults/dark-reef.json +0 -0
  345. /package/src/modes/{interactive/theme → theme}/defaults/dark-retro.json +0 -0
  346. /package/src/modes/{interactive/theme → theme}/defaults/dark-rose-pine.json +0 -0
  347. /package/src/modes/{interactive/theme → theme}/defaults/dark-sakura.json +0 -0
  348. /package/src/modes/{interactive/theme → theme}/defaults/dark-slate.json +0 -0
  349. /package/src/modes/{interactive/theme → theme}/defaults/dark-solarized.json +0 -0
  350. /package/src/modes/{interactive/theme → theme}/defaults/dark-solstice.json +0 -0
  351. /package/src/modes/{interactive/theme → theme}/defaults/dark-starfall.json +0 -0
  352. /package/src/modes/{interactive/theme → theme}/defaults/dark-sunset.json +0 -0
  353. /package/src/modes/{interactive/theme → theme}/defaults/dark-swamp.json +0 -0
  354. /package/src/modes/{interactive/theme → theme}/defaults/dark-synthwave.json +0 -0
  355. /package/src/modes/{interactive/theme → theme}/defaults/dark-taiga.json +0 -0
  356. /package/src/modes/{interactive/theme → theme}/defaults/dark-terminal.json +0 -0
  357. /package/src/modes/{interactive/theme → theme}/defaults/dark-tokyo-night.json +0 -0
  358. /package/src/modes/{interactive/theme → theme}/defaults/dark-tundra.json +0 -0
  359. /package/src/modes/{interactive/theme → theme}/defaults/dark-twilight.json +0 -0
  360. /package/src/modes/{interactive/theme → theme}/defaults/dark-volcanic.json +0 -0
  361. /package/src/modes/{interactive/theme → theme}/defaults/graphite.json +0 -0
  362. /package/src/modes/{interactive/theme → theme}/defaults/index.ts +0 -0
  363. /package/src/modes/{interactive/theme → theme}/defaults/light-arctic.json +0 -0
  364. /package/src/modes/{interactive/theme → theme}/defaults/light-aurora-day.json +0 -0
  365. /package/src/modes/{interactive/theme → theme}/defaults/light-canyon.json +0 -0
  366. /package/src/modes/{interactive/theme → theme}/defaults/light-catppuccin.json +0 -0
  367. /package/src/modes/{interactive/theme → theme}/defaults/light-cirrus.json +0 -0
  368. /package/src/modes/{interactive/theme → theme}/defaults/light-coral.json +0 -0
  369. /package/src/modes/{interactive/theme → theme}/defaults/light-cyberpunk.json +0 -0
  370. /package/src/modes/{interactive/theme → theme}/defaults/light-dawn.json +0 -0
  371. /package/src/modes/{interactive/theme → theme}/defaults/light-dunes.json +0 -0
  372. /package/src/modes/{interactive/theme → theme}/defaults/light-eucalyptus.json +0 -0
  373. /package/src/modes/{interactive/theme → theme}/defaults/light-forest.json +0 -0
  374. /package/src/modes/{interactive/theme → theme}/defaults/light-frost.json +0 -0
  375. /package/src/modes/{interactive/theme → theme}/defaults/light-github.json +0 -0
  376. /package/src/modes/{interactive/theme → theme}/defaults/light-glacier.json +0 -0
  377. /package/src/modes/{interactive/theme → theme}/defaults/light-gruvbox.json +0 -0
  378. /package/src/modes/{interactive/theme → theme}/defaults/light-haze.json +0 -0
  379. /package/src/modes/{interactive/theme → theme}/defaults/light-honeycomb.json +0 -0
  380. /package/src/modes/{interactive/theme → theme}/defaults/light-lagoon.json +0 -0
  381. /package/src/modes/{interactive/theme → theme}/defaults/light-lavender.json +0 -0
  382. /package/src/modes/{interactive/theme → theme}/defaults/light-meadow.json +0 -0
  383. /package/src/modes/{interactive/theme → theme}/defaults/light-mint.json +0 -0
  384. /package/src/modes/{interactive/theme → theme}/defaults/light-monochrome.json +0 -0
  385. /package/src/modes/{interactive/theme → theme}/defaults/light-ocean.json +0 -0
  386. /package/src/modes/{interactive/theme → theme}/defaults/light-one.json +0 -0
  387. /package/src/modes/{interactive/theme → theme}/defaults/light-opal.json +0 -0
  388. /package/src/modes/{interactive/theme → theme}/defaults/light-orchard.json +0 -0
  389. /package/src/modes/{interactive/theme → theme}/defaults/light-paper.json +0 -0
  390. /package/src/modes/{interactive/theme → theme}/defaults/light-prism.json +0 -0
  391. /package/src/modes/{interactive/theme → theme}/defaults/light-retro.json +0 -0
  392. /package/src/modes/{interactive/theme → theme}/defaults/light-sand.json +0 -0
  393. /package/src/modes/{interactive/theme → theme}/defaults/light-savanna.json +0 -0
  394. /package/src/modes/{interactive/theme → theme}/defaults/light-solarized.json +0 -0
  395. /package/src/modes/{interactive/theme → theme}/defaults/light-soleil.json +0 -0
  396. /package/src/modes/{interactive/theme → theme}/defaults/light-sunset.json +0 -0
  397. /package/src/modes/{interactive/theme → theme}/defaults/light-synthwave.json +0 -0
  398. /package/src/modes/{interactive/theme → theme}/defaults/light-tokyo-night.json +0 -0
  399. /package/src/modes/{interactive/theme → theme}/defaults/light-wetland.json +0 -0
  400. /package/src/modes/{interactive/theme → theme}/defaults/light-zenith.json +0 -0
  401. /package/src/modes/{interactive/theme → theme}/defaults/limestone.json +0 -0
  402. /package/src/modes/{interactive/theme → theme}/defaults/mahogany.json +0 -0
  403. /package/src/modes/{interactive/theme → theme}/defaults/marble.json +0 -0
  404. /package/src/modes/{interactive/theme → theme}/defaults/obsidian.json +0 -0
  405. /package/src/modes/{interactive/theme → theme}/defaults/onyx.json +0 -0
  406. /package/src/modes/{interactive/theme → theme}/defaults/pearl.json +0 -0
  407. /package/src/modes/{interactive/theme → theme}/defaults/porcelain.json +0 -0
  408. /package/src/modes/{interactive/theme → theme}/defaults/quartz.json +0 -0
  409. /package/src/modes/{interactive/theme → theme}/defaults/sandstone.json +0 -0
  410. /package/src/modes/{interactive/theme → theme}/defaults/titanium.json +0 -0
  411. /package/src/modes/{interactive/theme → theme}/light.json +0 -0
  412. /package/src/modes/{interactive/theme → theme}/theme-schema.json +0 -0
  413. /package/src/{core/tools/patch → patch}/fuzzy.ts +0 -0
  414. /package/src/{core/tools/patch → patch}/normalize.ts +0 -0
  415. /package/src/{core/tools/patch → patch}/normative.ts +0 -0
  416. /package/src/{core/tools/patch → patch}/parser.ts +0 -0
  417. /package/src/{core/tools/patch → patch}/types.ts +0 -0
  418. /package/src/{core → session}/compaction/index.ts +0 -0
  419. /package/src/{core → session}/session-storage.ts +0 -0
  420. /package/src/{core/tools/task → task}/name-generator.ts +0 -0
  421. /package/src/{core/tools/task → task}/omp-command.ts +0 -0
  422. /package/src/{core/tools/task → task}/parallel.ts +0 -0
  423. /package/src/{core/tools → tools}/jtd-to-json-schema.ts +0 -0
  424. /package/src/{core/tools → tools}/path-utils.ts +0 -0
  425. /package/src/{core → utils}/event-bus.ts +0 -0
  426. /package/src/{core → utils}/frontmatter.ts +0 -0
  427. /package/src/{core → utils}/terminal-notify.ts +0 -0
  428. /package/src/{core → utils}/timings.ts +0 -0
  429. /package/src/{core → utils}/utils.ts +0 -0
  430. /package/src/{core/tools/web-scrapers → web/scrapers}/artifacthub.ts +0 -0
  431. /package/src/{core/tools/web-scrapers → web/scrapers}/arxiv.ts +0 -0
  432. /package/src/{core/tools/web-scrapers → web/scrapers}/aur.ts +0 -0
  433. /package/src/{core/tools/web-scrapers → web/scrapers}/biorxiv.ts +0 -0
  434. /package/src/{core/tools/web-scrapers → web/scrapers}/bluesky.ts +0 -0
  435. /package/src/{core/tools/web-scrapers → web/scrapers}/brew.ts +0 -0
  436. /package/src/{core/tools/web-scrapers → web/scrapers}/cheatsh.ts +0 -0
  437. /package/src/{core/tools/web-scrapers → web/scrapers}/chocolatey.ts +0 -0
  438. /package/src/{core/tools/web-scrapers → web/scrapers}/cisa-kev.ts +0 -0
  439. /package/src/{core/tools/web-scrapers → web/scrapers}/clojars.ts +0 -0
  440. /package/src/{core/tools/web-scrapers → web/scrapers}/coingecko.ts +0 -0
  441. /package/src/{core/tools/web-scrapers → web/scrapers}/crates-io.ts +0 -0
  442. /package/src/{core/tools/web-scrapers → web/scrapers}/crossref.ts +0 -0
  443. /package/src/{core/tools/web-scrapers → web/scrapers}/devto.ts +0 -0
  444. /package/src/{core/tools/web-scrapers → web/scrapers}/discogs.ts +0 -0
  445. /package/src/{core/tools/web-scrapers → web/scrapers}/discourse.ts +0 -0
  446. /package/src/{core/tools/web-scrapers → web/scrapers}/dockerhub.ts +0 -0
  447. /package/src/{core/tools/web-scrapers → web/scrapers}/fdroid.ts +0 -0
  448. /package/src/{core/tools/web-scrapers → web/scrapers}/firefox-addons.ts +0 -0
  449. /package/src/{core/tools/web-scrapers → web/scrapers}/flathub.ts +0 -0
  450. /package/src/{core/tools/web-scrapers → web/scrapers}/github-gist.ts +0 -0
  451. /package/src/{core/tools/web-scrapers → web/scrapers}/github.ts +0 -0
  452. /package/src/{core/tools/web-scrapers → web/scrapers}/gitlab.ts +0 -0
  453. /package/src/{core/tools/web-scrapers → web/scrapers}/go-pkg.ts +0 -0
  454. /package/src/{core/tools/web-scrapers → web/scrapers}/hackage.ts +0 -0
  455. /package/src/{core/tools/web-scrapers → web/scrapers}/hackernews.ts +0 -0
  456. /package/src/{core/tools/web-scrapers → web/scrapers}/hex.ts +0 -0
  457. /package/src/{core/tools/web-scrapers → web/scrapers}/huggingface.ts +0 -0
  458. /package/src/{core/tools/web-scrapers → web/scrapers}/iacr.ts +0 -0
  459. /package/src/{core/tools/web-scrapers → web/scrapers}/index.ts +0 -0
  460. /package/src/{core/tools/web-scrapers → web/scrapers}/jetbrains-marketplace.ts +0 -0
  461. /package/src/{core/tools/web-scrapers → web/scrapers}/lemmy.ts +0 -0
  462. /package/src/{core/tools/web-scrapers → web/scrapers}/lobsters.ts +0 -0
  463. /package/src/{core/tools/web-scrapers → web/scrapers}/mastodon.ts +0 -0
  464. /package/src/{core/tools/web-scrapers → web/scrapers}/maven.ts +0 -0
  465. /package/src/{core/tools/web-scrapers → web/scrapers}/mdn.ts +0 -0
  466. /package/src/{core/tools/web-scrapers → web/scrapers}/metacpan.ts +0 -0
  467. /package/src/{core/tools/web-scrapers → web/scrapers}/musicbrainz.ts +0 -0
  468. /package/src/{core/tools/web-scrapers → web/scrapers}/npm.ts +0 -0
  469. /package/src/{core/tools/web-scrapers → web/scrapers}/nuget.ts +0 -0
  470. /package/src/{core/tools/web-scrapers → web/scrapers}/nvd.ts +0 -0
  471. /package/src/{core/tools/web-scrapers → web/scrapers}/ollama.ts +0 -0
  472. /package/src/{core/tools/web-scrapers → web/scrapers}/open-vsx.ts +0 -0
  473. /package/src/{core/tools/web-scrapers → web/scrapers}/opencorporates.ts +0 -0
  474. /package/src/{core/tools/web-scrapers → web/scrapers}/openlibrary.ts +0 -0
  475. /package/src/{core/tools/web-scrapers → web/scrapers}/orcid.ts +0 -0
  476. /package/src/{core/tools/web-scrapers → web/scrapers}/osv.ts +0 -0
  477. /package/src/{core/tools/web-scrapers → web/scrapers}/packagist.ts +0 -0
  478. /package/src/{core/tools/web-scrapers → web/scrapers}/pub-dev.ts +0 -0
  479. /package/src/{core/tools/web-scrapers → web/scrapers}/pubmed.ts +0 -0
  480. /package/src/{core/tools/web-scrapers → web/scrapers}/pypi.ts +0 -0
  481. /package/src/{core/tools/web-scrapers → web/scrapers}/rawg.ts +0 -0
  482. /package/src/{core/tools/web-scrapers → web/scrapers}/readthedocs.ts +0 -0
  483. /package/src/{core/tools/web-scrapers → web/scrapers}/reddit.ts +0 -0
  484. /package/src/{core/tools/web-scrapers → web/scrapers}/repology.ts +0 -0
  485. /package/src/{core/tools/web-scrapers → web/scrapers}/rfc.ts +0 -0
  486. /package/src/{core/tools/web-scrapers → web/scrapers}/rubygems.ts +0 -0
  487. /package/src/{core/tools/web-scrapers → web/scrapers}/searchcode.ts +0 -0
  488. /package/src/{core/tools/web-scrapers → web/scrapers}/sec-edgar.ts +0 -0
  489. /package/src/{core/tools/web-scrapers → web/scrapers}/semantic-scholar.ts +0 -0
  490. /package/src/{core/tools/web-scrapers → web/scrapers}/snapcraft.ts +0 -0
  491. /package/src/{core/tools/web-scrapers → web/scrapers}/sourcegraph.ts +0 -0
  492. /package/src/{core/tools/web-scrapers → web/scrapers}/spdx.ts +0 -0
  493. /package/src/{core/tools/web-scrapers → web/scrapers}/spotify.ts +0 -0
  494. /package/src/{core/tools/web-scrapers → web/scrapers}/stackoverflow.ts +0 -0
  495. /package/src/{core/tools/web-scrapers → web/scrapers}/terraform.ts +0 -0
  496. /package/src/{core/tools/web-scrapers → web/scrapers}/tldr.ts +0 -0
  497. /package/src/{core/tools/web-scrapers → web/scrapers}/vimeo.ts +0 -0
  498. /package/src/{core/tools/web-scrapers → web/scrapers}/vscode-marketplace.ts +0 -0
  499. /package/src/{core/tools/web-scrapers → web/scrapers}/w3c.ts +0 -0
  500. /package/src/{core/tools/web-scrapers → web/scrapers}/wikidata.ts +0 -0
  501. /package/src/{core/tools/web-scrapers → web/scrapers}/wikipedia.ts +0 -0
  502. /package/src/{core/tools/web-search → web/search}/types.ts +0 -0
@@ -6,17 +6,17 @@
6
6
 
7
7
  import path from "node:path";
8
8
  import type { AgentEvent, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
9
- import type { AuthStorage } from "../../auth-storage";
10
- import type { EventBus } from "../../event-bus";
11
- import { callTool } from "../../mcp/client";
12
- import type { MCPManager } from "../../mcp/manager";
13
- import type { ModelRegistry } from "../../model-registry";
14
- import { formatModelString, parseModelPattern } from "../../model-resolver";
15
- import { checkPythonKernelAvailability } from "../../python-kernel";
9
+ import type { ModelRegistry } from "$c/config/model-registry";
10
+ import { formatModelString, parseModelPattern } from "$c/config/model-resolver";
11
+ import { checkPythonKernelAvailability } from "$c/ipy/kernel";
12
+ import { LspTool } from "$c/lsp/index";
13
+ import type { LspParams } from "$c/lsp/types";
14
+ import { callTool } from "$c/mcp/client";
15
+ import type { MCPManager } from "$c/mcp/manager";
16
+ import type { AuthStorage } from "$c/session/auth-storage";
17
+ import { PythonTool, type PythonToolParams } from "$c/tools/python";
18
+ import type { EventBus } from "$c/utils/event-bus";
16
19
  import type { ToolSession } from "..";
17
- import { LspTool } from "../lsp/index";
18
- import type { LspParams } from "../lsp/types";
19
- import { PythonTool, type PythonToolParams } from "../python";
20
20
  import { subprocessToolRegistry } from "./subprocess-tool-registry";
21
21
  import {
22
22
  type AgentDefinition,
@@ -41,11 +41,12 @@ import type {
41
41
  /** Options for worker execution */
42
42
  export interface ExecutorOptions {
43
43
  cwd: string;
44
+ worktree?: string;
44
45
  agent: AgentDefinition;
45
46
  task: string;
46
47
  description?: string;
47
48
  index: number;
48
- taskId: string;
49
+ id: string;
49
50
  context?: string;
50
51
  modelOverride?: string;
51
52
  thinkingLevel?: ThinkingLevel;
@@ -61,7 +62,7 @@ export interface ExecutorOptions {
61
62
  authStorage?: AuthStorage;
62
63
  modelRegistry?: ModelRegistry;
63
64
  settingsManager?: {
64
- serialize: () => import("../../settings-manager").Settings;
65
+ serialize: () => import("$c/config/settings-manager").Settings;
65
66
  getPythonToolMode?: () => "ipy-only" | "bash-only" | "both";
66
67
  getPythonKernelMode?: () => "session" | "per-call";
67
68
  getPythonSharedGateway?: () => boolean;
@@ -162,35 +163,24 @@ function getUsageTokens(usage: unknown): number {
162
163
  return input + output + cacheRead + cacheWrite;
163
164
  }
164
165
 
165
- /**
166
- * Parse MCP tool name to extract server and tool names.
167
- * Format: mcp_<serverName>_<toolName>
168
- * Note: Uses lastIndexOf to handle server names with underscores.
169
- */
170
- function parseMCPToolName(fullName: string): { serverName: string; toolName: string } | undefined {
171
- if (!fullName.startsWith("mcp_")) return undefined;
172
- const rest = fullName.slice(4);
173
- const underscoreIndex = rest.lastIndexOf("_");
174
- if (underscoreIndex === -1) return undefined;
175
- return {
176
- serverName: rest.slice(0, underscoreIndex),
177
- toolName: rest.slice(underscoreIndex + 1),
178
- };
179
- }
180
-
181
166
  /**
182
167
  * Extract MCP tool metadata from MCPManager for passing to worker.
168
+ *
169
+ * MCPTool and DeferredMCPTool expose mcpToolName (original MCP tool name)
170
+ * and mcpServerName properties. We use these directly when available,
171
+ * falling back to empty strings if not.
183
172
  */
184
173
  function extractMCPToolMetadata(mcpManager: MCPManager): MCPToolMetadata[] {
185
174
  return mcpManager.getTools().map((tool) => {
186
- const parsed = parseMCPToolName(tool.name);
175
+ // MCPTool and DeferredMCPTool have these properties
176
+ const mcpTool = tool as { mcpToolName?: string; mcpServerName?: string };
187
177
  return {
188
178
  name: tool.name,
189
179
  label: tool.label ?? tool.name,
190
180
  description: tool.description ?? "",
191
181
  parameters: tool.parameters,
192
- serverName: parsed?.serverName ?? "",
193
- mcpToolName: parsed?.toolName ?? "",
182
+ serverName: mcpTool.mcpServerName ?? "",
183
+ mcpToolName: mcpTool.mcpToolName ?? "",
194
184
  };
195
185
  });
196
186
  }
@@ -204,7 +194,8 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
204
194
  agent,
205
195
  task,
206
196
  index,
207
- taskId,
197
+ id,
198
+ worktree,
208
199
  context,
209
200
  modelOverride,
210
201
  thinkingLevel,
@@ -218,7 +209,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
218
209
  // Initialize progress
219
210
  const progress: AgentProgress = {
220
211
  index,
221
- taskId,
212
+ id,
222
213
  agent: agent.name,
223
214
  agentSource: agent.source,
224
215
  status: "running",
@@ -236,7 +227,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
236
227
  if (signal?.aborted) {
237
228
  return {
238
229
  index,
239
- taskId,
230
+ id,
240
231
  agent: agent.name,
241
232
  agentSource: agent.source,
242
233
  task,
@@ -258,7 +249,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
258
249
  // Set up artifact paths and write input file upfront if artifacts dir provided
259
250
  let subtaskSessionFile: string | undefined;
260
251
  if (options.artifactsDir) {
261
- subtaskSessionFile = path.join(options.artifactsDir, `${taskId}.jsonl`);
252
+ subtaskSessionFile = path.join(options.artifactsDir, `${id}.jsonl`);
262
253
  }
263
254
 
264
255
  // Add tools if specified
@@ -324,7 +315,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
324
315
  } catch (err) {
325
316
  return {
326
317
  index,
327
- taskId,
318
+ id,
328
319
  agent: agent.name,
329
320
  agentSource: agent.source,
330
321
  task,
@@ -385,7 +376,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
385
376
  return AbortSignal.timeout(timeoutMs);
386
377
  };
387
378
 
388
- const pythonSessionFile = sessionFile ?? `subtask:${taskId}`;
379
+ const pythonSessionFile = sessionFile ?? `subtask:${id}`;
389
380
  const pythonToolSession: ToolSession = {
390
381
  cwd,
391
382
  hasUI: false,
@@ -689,6 +680,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
689
680
  type: "start",
690
681
  payload: {
691
682
  cwd,
683
+ worktree,
692
684
  task: fullTask,
693
685
  systemPrompt: agent.systemPrompt,
694
686
  model: resolvedModel,
@@ -743,12 +735,10 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
743
735
  return;
744
736
  }
745
737
  try {
746
- const parsed = parseMCPToolName(request.toolName);
747
- if (!parsed) throw new Error(`Invalid MCP tool name: ${request.toolName}`);
748
738
  const result = await withTimeout(
749
739
  (async () => {
750
- const connection = await mcpManager.waitForConnection(parsed.serverName);
751
- return callTool(connection, parsed.toolName, request.params);
740
+ const connection = await mcpManager.waitForConnection(request.serverName);
741
+ return callTool(connection, request.mcpToolName, request.params);
752
742
  })(),
753
743
  request.timeoutMs,
754
744
  );
@@ -1025,11 +1015,11 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
1025
1015
  const { text: truncatedOutput, truncated } = truncateOutput(rawOutput);
1026
1016
 
1027
1017
  // Write output artifact (input and jsonl already written in real-time)
1028
- // Compute output metadata for Output tool integration
1018
+ // Compute output metadata for agent:// URL integration
1029
1019
  let outputMeta: { lineCount: number; charCount: number } | undefined;
1030
1020
  let outputPath: string | undefined;
1031
1021
  if (options.artifactsDir) {
1032
- outputPath = path.join(options.artifactsDir, `${taskId}.md`);
1022
+ outputPath = path.join(options.artifactsDir, `${id}.md`);
1033
1023
  try {
1034
1024
  await Bun.write(outputPath, rawOutput);
1035
1025
  outputMeta = {
@@ -1048,7 +1038,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
1048
1038
 
1049
1039
  return {
1050
1040
  index,
1051
- taskId,
1041
+ id,
1052
1042
  agent: agent.name,
1053
1043
  agentSource: agent.source,
1054
1044
  task,
@@ -13,25 +13,25 @@
13
13
  * - Session artifacts for debugging
14
14
  */
15
15
 
16
- import { mkdir, rm } from "node:fs/promises";
16
+ import { mkdir, rm, stat } from "node:fs/promises";
17
17
  import { tmpdir } from "node:os";
18
18
  import path from "node:path";
19
19
  import type { AgentTool, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
20
20
  import type { Usage } from "@oh-my-pi/pi-ai";
21
+ import { $ } from "bun";
21
22
  import { nanoid } from "nanoid";
22
- import type { Theme } from "../../../modes/interactive/theme/theme";
23
- import taskDescriptionTemplate from "../../../prompts/tools/task.md" with { type: "text" };
24
- import { renderPromptTemplate } from "../../prompt-templates";
23
+ import { renderPromptTemplate } from "$c/config/prompt-templates";
24
+ import type { Theme } from "$c/modes/theme/theme";
25
+ import taskDescriptionTemplate from "$c/prompts/tools/task.md" with { type: "text" };
26
+ import { formatDuration } from "$c/tools/render-utils";
25
27
  import type { ToolSession } from "..";
26
- import { formatDuration } from "../render-utils";
27
28
  import { discoverAgents, getAgent } from "./discovery";
28
29
  import { runSubprocess } from "./executor";
29
30
  import { mapWithConcurrencyLimit } from "./parallel";
30
31
  import { renderCall, renderResult } from "./render";
31
- import { renderTemplate, validateTaskTemplate } from "./template";
32
+ import { renderTemplate } from "./template";
32
33
  import {
33
34
  type AgentProgress,
34
- MAX_AGENTS_IN_DESCRIPTION,
35
35
  MAX_CONCURRENCY,
36
36
  MAX_PARALLEL_TASKS,
37
37
  type SingleResult,
@@ -39,9 +39,17 @@ import {
39
39
  type TaskToolDetails,
40
40
  taskSchema,
41
41
  } from "./types";
42
+ import {
43
+ applyBaseline,
44
+ captureBaseline,
45
+ captureDeltaPatch,
46
+ cleanupWorktree,
47
+ ensureWorktree,
48
+ getRepoRoot,
49
+ } from "./worktree";
42
50
 
43
51
  // Import review tools for side effects (registers subagent tool handlers)
44
- import "../review";
52
+ import "../tools/review";
45
53
 
46
54
  /** Format byte count for display */
47
55
  function formatBytes(bytes: number): string {
@@ -103,8 +111,7 @@ async function buildDescription(cwd: string): Promise<string> {
103
111
  const { agents } = await discoverAgents(cwd);
104
112
 
105
113
  return renderPromptTemplate(taskDescriptionTemplate, {
106
- agents: agents.slice(0, MAX_AGENTS_IN_DESCRIPTION),
107
- moreAgents: agents.length > MAX_AGENTS_IN_DESCRIPTION ? agents.length - MAX_AGENTS_IN_DESCRIPTION : 0,
114
+ agents,
108
115
  MAX_PARALLEL_TASKS,
109
116
  MAX_CONCURRENCY,
110
117
  });
@@ -153,7 +160,8 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
153
160
  ): Promise<AgentToolResult<TaskToolDetails>> {
154
161
  const startTime = Date.now();
155
162
  const { agents, projectAgentsDir } = await discoverAgents(this.session.cwd);
156
- const { agent: agentName, context, model, output: outputSchema } = params;
163
+ const { agent: agentName, context, output: outputSchema, isolated } = params;
164
+ const isIsolated = isolated === true;
157
165
 
158
166
  const isDefaultModelAlias = (value: string | undefined): boolean => {
159
167
  if (!value) return true;
@@ -180,9 +188,9 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
180
188
  };
181
189
  }
182
190
 
183
- const shouldInheritSessionModel = model === undefined && isDefaultModelAlias(agent.model);
184
- const sessionModel = shouldInheritSessionModel ? this.session.getActiveModelString?.() : undefined;
185
- const modelOverride = model ?? sessionModel ?? this.session.getModelString?.();
191
+ const effectiveAgentModel = isDefaultModelAlias(agent.model) ? undefined : agent.model;
192
+ const modelOverride =
193
+ effectiveAgentModel ?? this.session.getActiveModelString?.() ?? this.session.getModelString?.();
186
194
  const thinkingLevelOverride = agent.thinkingLevel;
187
195
 
188
196
  // Output schema priority: agent frontmatter > params > inherited from parent session
@@ -195,7 +203,7 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
195
203
  content: [
196
204
  {
197
205
  type: "text",
198
- text: `No tasks provided. Use: { agent, context, tasks: [{id, description, vars}, ...] }`,
206
+ text: `No tasks provided. Use: { agent, context, tasks: [{id, description, args}, ...] }`,
199
207
  },
200
208
  ],
201
209
  details: {
@@ -271,16 +279,28 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
271
279
  };
272
280
  }
273
281
 
274
- const templateError = validateTaskTemplate(context, tasks);
275
- if (templateError) {
276
- return {
277
- content: [{ type: "text", text: templateError }],
278
- details: {
279
- projectAgentsDir,
280
- results: [],
281
- totalDurationMs: 0,
282
- },
283
- };
282
+ let repoRoot: string | null = null;
283
+ let baseline = null as Awaited<ReturnType<typeof captureBaseline>> | null;
284
+ if (isIsolated) {
285
+ try {
286
+ repoRoot = await getRepoRoot(this.session.cwd);
287
+ baseline = await captureBaseline(repoRoot);
288
+ } catch (err) {
289
+ const message = err instanceof Error ? err.message : String(err);
290
+ return {
291
+ content: [
292
+ {
293
+ type: "text",
294
+ text: `Isolated task execution requires a git repository. ${message}`,
295
+ },
296
+ ],
297
+ details: {
298
+ projectAgentsDir,
299
+ results: [],
300
+ totalDurationMs: Date.now() - startTime,
301
+ },
302
+ };
303
+ }
284
304
  }
285
305
 
286
306
  // Derive artifacts directory
@@ -347,25 +367,19 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
347
367
  }
348
368
 
349
369
  // Build full prompts with context prepended
350
- const contextTemplate = context ?? "";
351
- const tasksWithContext = tasks.map((t) => ({
352
- task: renderTemplate(contextTemplate, t.vars),
353
- description: t.description,
354
- taskId: t.id,
355
- vars: t.vars,
356
- }));
370
+ const tasksWithContext = tasks.map((t) => renderTemplate(context, t));
357
371
 
358
372
  // Initialize progress for all tasks
359
373
  for (let i = 0; i < tasksWithContext.length; i++) {
360
374
  const t = tasksWithContext[i];
361
375
  progressMap.set(i, {
362
376
  index: i,
363
- taskId: t.taskId,
377
+ id: t.id,
364
378
  agent: agentName,
365
379
  agentSource: agent.source,
366
380
  status: "pending",
367
381
  task: t.task,
368
- vars: t.vars,
382
+ args: t.args,
369
383
  recentTools: [],
370
384
  recentOutput: [],
371
385
  toolCount: 0,
@@ -377,18 +391,15 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
377
391
  }
378
392
  emitProgress();
379
393
 
380
- // Execute in parallel with concurrency limit
381
- const { results: partialResults, aborted } = await mapWithConcurrencyLimit(
382
- tasksWithContext,
383
- MAX_CONCURRENCY,
384
- async (task, index) => {
394
+ const runTask = async (task: (typeof tasksWithContext)[number], index: number) => {
395
+ if (!isIsolated) {
385
396
  return runSubprocess({
386
397
  cwd: this.session.cwd,
387
398
  agent,
388
399
  task: task.task,
389
400
  description: task.description,
390
401
  index,
391
- taskId: task.taskId,
402
+ id: task.id,
392
403
  context: undefined, // Already prepended above
393
404
  modelOverride,
394
405
  thinkingLevel: thinkingLevelOverride,
@@ -402,7 +413,7 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
402
413
  onProgress: (progress) => {
403
414
  progressMap.set(index, {
404
415
  ...structuredClone(progress),
405
- vars: tasksWithContext[index]?.vars,
416
+ args: tasksWithContext[index]?.args,
406
417
  });
407
418
  emitProgress();
408
419
  },
@@ -411,7 +422,83 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
411
422
  settingsManager: this.session.settingsManager,
412
423
  mcpManager: this.session.mcpManager,
413
424
  });
414
- },
425
+ }
426
+
427
+ const taskStart = Date.now();
428
+ let worktreeDir: string | undefined;
429
+ try {
430
+ if (!repoRoot || !baseline) {
431
+ throw new Error("Isolated task execution not initialized.");
432
+ }
433
+ worktreeDir = await ensureWorktree(repoRoot, task.id);
434
+ await applyBaseline(worktreeDir, baseline);
435
+ const result = await runSubprocess({
436
+ cwd: this.session.cwd,
437
+ worktree: worktreeDir,
438
+ agent,
439
+ task: task.task,
440
+ description: task.description,
441
+ index,
442
+ id: task.id,
443
+ context: undefined, // Already prepended above
444
+ modelOverride,
445
+ thinkingLevel: thinkingLevelOverride,
446
+ outputSchema: effectiveOutputSchema,
447
+ sessionFile,
448
+ persistArtifacts: !!artifactsDir,
449
+ artifactsDir: effectiveArtifactsDir,
450
+ enableLsp: false,
451
+ signal,
452
+ eventBus: undefined,
453
+ onProgress: (progress) => {
454
+ progressMap.set(index, {
455
+ ...structuredClone(progress),
456
+ args: tasksWithContext[index]?.args,
457
+ });
458
+ emitProgress();
459
+ },
460
+ authStorage: this.session.authStorage,
461
+ modelRegistry: this.session.modelRegistry,
462
+ settingsManager: this.session.settingsManager,
463
+ mcpManager: this.session.mcpManager,
464
+ });
465
+ const patch = await captureDeltaPatch(worktreeDir, baseline);
466
+ const patchPath = path.join(effectiveArtifactsDir, `${task.id}.patch`);
467
+ await Bun.write(patchPath, patch);
468
+ return {
469
+ ...result,
470
+ patchPath,
471
+ };
472
+ } catch (err) {
473
+ const message = err instanceof Error ? err.message : String(err);
474
+ return {
475
+ index,
476
+ id: task.id,
477
+ agent: agent.name,
478
+ agentSource: agent.source,
479
+ task: task.task,
480
+ description: task.description,
481
+ exitCode: 1,
482
+ output: "",
483
+ stderr: message,
484
+ truncated: false,
485
+ durationMs: Date.now() - taskStart,
486
+ tokens: 0,
487
+ modelOverride,
488
+ error: message,
489
+ };
490
+ } finally {
491
+ if (worktreeDir) {
492
+ await cleanupWorktree(worktreeDir);
493
+ }
494
+ }
495
+ };
496
+
497
+ // Execute in parallel with concurrency limit
498
+ const { results: partialResults, aborted } = await mapWithConcurrencyLimit(
499
+ tasksWithContext,
500
+ MAX_CONCURRENCY,
501
+ runTask,
415
502
  signal,
416
503
  );
417
504
 
@@ -420,17 +507,17 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
420
507
  if (result !== undefined) {
421
508
  return {
422
509
  ...result,
423
- vars: tasksWithContext[index]?.vars,
510
+ args: tasksWithContext[index]?.args,
424
511
  };
425
512
  }
426
513
  const task = tasksWithContext[index];
427
514
  return {
428
515
  index,
429
- taskId: task.taskId,
516
+ id: task.id,
430
517
  agent: agentName,
431
518
  agentSource: agent.source,
432
519
  task: task.task,
433
- vars: task.vars,
520
+ args: task.args,
434
521
  description: task.description,
435
522
  exitCode: 1,
436
523
  output: "",
@@ -456,10 +543,75 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
456
543
 
457
544
  // Collect output paths (artifacts already written by executor in real-time)
458
545
  const outputPaths: string[] = [];
546
+ const patchPaths: string[] = [];
459
547
  for (const result of results) {
460
548
  if (result.outputPath) {
461
549
  outputPaths.push(result.outputPath);
462
550
  }
551
+ if (result.patchPath) {
552
+ patchPaths.push(result.patchPath);
553
+ }
554
+ }
555
+
556
+ let patchApplySummary = "";
557
+ let patchesApplied: boolean | null = null;
558
+ if (isIsolated) {
559
+ const patchesInOrder = results.map((result) => result.patchPath).filter(Boolean) as string[];
560
+ const missingPatch = results.some((result) => !result.patchPath);
561
+ if (!repoRoot || missingPatch) {
562
+ patchesApplied = false;
563
+ } else {
564
+ const patchStats = await Promise.all(
565
+ patchesInOrder.map(async (patchPath) => ({
566
+ patchPath,
567
+ size: (await stat(patchPath)).size,
568
+ })),
569
+ );
570
+ const nonEmptyPatches = patchStats.filter((patch) => patch.size > 0).map((patch) => patch.patchPath);
571
+ if (nonEmptyPatches.length === 0) {
572
+ patchesApplied = true;
573
+ } else {
574
+ const patchTexts = await Promise.all(
575
+ nonEmptyPatches.map(async (patchPath) => Bun.file(patchPath).text()),
576
+ );
577
+ const combinedPatch = patchTexts.map((text) => (text.endsWith("\n") ? text : `${text}\n`)).join("");
578
+ if (!combinedPatch.trim()) {
579
+ patchesApplied = true;
580
+ } else {
581
+ const combinedPatchPath = path.join(tmpdir(), `omp-task-combined-${nanoid()}.patch`);
582
+ try {
583
+ await Bun.write(combinedPatchPath, combinedPatch);
584
+ const checkResult = await $`git apply --check --binary ${combinedPatchPath}`
585
+ .cwd(repoRoot)
586
+ .quiet()
587
+ .nothrow();
588
+ if (checkResult.exitCode !== 0) {
589
+ patchesApplied = false;
590
+ } else {
591
+ const applyResult = await $`git apply --binary ${combinedPatchPath}`
592
+ .cwd(repoRoot)
593
+ .quiet()
594
+ .nothrow();
595
+ patchesApplied = applyResult.exitCode === 0;
596
+ }
597
+ } finally {
598
+ await rm(combinedPatchPath, { force: true });
599
+ }
600
+ }
601
+ }
602
+ }
603
+
604
+ if (patchesApplied) {
605
+ patchApplySummary = "\n\nApplied patches: yes";
606
+ } else {
607
+ const notification =
608
+ "<system-notification>Patches were not applied and must be handled manually.</system-notification>";
609
+ const patchList =
610
+ patchPaths.length > 0
611
+ ? `\n\nPatch artifacts:\n${patchPaths.map((patch) => `- ${patch}`).join("\n")}`
612
+ : "";
613
+ patchApplySummary = `\n\n${notification}${patchList}`;
614
+ }
463
615
  }
464
616
 
465
617
  // Build final output - match plugin format
@@ -474,22 +626,26 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
474
626
  const meta = r.outputMeta
475
627
  ? ` [${r.outputMeta.lineCount} lines, ${formatBytes(r.outputMeta.charCount)}]`
476
628
  : "";
477
- return `[${r.agent}] ${status}${meta} ${r.taskId}\n${preview}`;
629
+ return `[${r.agent}] ${status}${meta} ${r.id}\n${preview}`;
478
630
  });
479
631
 
480
- const outputIds = results.filter((r) => !r.aborted || r.output.trim()).map((r) => r.taskId);
632
+ const outputIds = results.filter((r) => !r.aborted || r.output.trim()).map((r) => r.id);
481
633
  const outputHint =
482
- outputIds.length > 0 ? `\n\nUse output tool for full logs: output ids ${outputIds.join(", ")}` : "";
634
+ outputIds.length > 0
635
+ ? `\n\nUse read with agent:// for full logs: ${outputIds.map((id) => `agent://${id}`).join(", ")}`
636
+ : "";
483
637
  const schemaNote = schemaOverridden
484
638
  ? `\n\nNote: Agent '${agentName}' has a fixed output schema; your 'output' parameter was ignored.\nRequired schema: ${JSON.stringify(agent.output)}`
485
639
  : "";
486
640
  const cancelledNote = aborted && cancelledCount > 0 ? ` (${cancelledCount} cancelled)` : "";
487
641
  const summary = `${successCount}/${results.length} succeeded${cancelledNote} [${formatDuration(
488
642
  totalDuration,
489
- )}]\n\n${summaries.join("\n\n---\n\n")}${outputHint}${schemaNote}`;
643
+ )}]\n\n${summaries.join("\n\n---\n\n")}${outputHint}${schemaNote}${patchApplySummary}`;
490
644
 
491
645
  // Cleanup temp directory if used
492
- if (tempArtifactsDir) {
646
+ const shouldCleanupTempArtifacts =
647
+ tempArtifactsDir && (!isIsolated || patchesApplied === true || patchesApplied === null);
648
+ if (shouldCleanupTempArtifacts) {
493
649
  await rm(tempArtifactsDir, { recursive: true, force: true });
494
650
  }
495
651