@oh-my-pi/pi-coding-agent 7.0.0 → 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 (501) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/README.md +1 -1
  3. package/docs/hooks.md +2 -2
  4. package/docs/sdk.md +1 -1
  5. package/package.json +10 -10
  6. package/scripts/format-prompts.ts +143 -0
  7. package/scripts/generate-template.ts +1 -1
  8. package/src/cli/args.ts +3 -3
  9. package/src/cli/config-cli.ts +4 -4
  10. package/src/cli/file-processor.ts +3 -3
  11. package/src/cli/list-models.ts +2 -2
  12. package/src/cli/plugin-cli.ts +3 -3
  13. package/src/cli/session-picker.ts +2 -2
  14. package/src/cli/setup-cli.ts +2 -2
  15. package/src/cli/stats-cli.ts +1 -1
  16. package/src/cli/update-cli.ts +2 -2
  17. package/src/{core → config}/keybindings.ts +1 -1
  18. package/src/{core → config}/model-registry.ts +1 -1
  19. package/src/{core → config}/model-resolver.ts +3 -3
  20. package/src/{core → config}/prompt-templates.ts +2 -2
  21. package/src/{core → config}/settings-manager.ts +6 -6
  22. package/src/{core/cursor/exec-bridge.ts → cursor.ts} +4 -4
  23. package/src/discovery/agents-md.ts +4 -4
  24. package/src/discovery/builtin.ts +17 -17
  25. package/src/discovery/claude.ts +12 -12
  26. package/src/discovery/cline.ts +6 -6
  27. package/src/discovery/codex.ts +21 -21
  28. package/src/discovery/cursor.ts +9 -9
  29. package/src/discovery/gemini.ts +9 -9
  30. package/src/discovery/github.ts +6 -6
  31. package/src/discovery/helpers.ts +4 -4
  32. package/src/discovery/index.ts +16 -16
  33. package/src/discovery/mcp-json.ts +4 -4
  34. package/src/discovery/ssh.ts +4 -4
  35. package/src/discovery/vscode.ts +4 -4
  36. package/src/discovery/windsurf.ts +6 -6
  37. package/src/{core/tools/exa → exa}/company.ts +2 -3
  38. package/src/{core/tools/exa → exa}/index.ts +2 -2
  39. package/src/{core/tools/exa → exa}/linkedin.ts +2 -3
  40. package/src/{core/tools/exa → exa}/mcp-client.ts +2 -2
  41. package/src/{core/tools/exa → exa}/render.ts +3 -3
  42. package/src/{core/tools/exa → exa}/researcher.ts +1 -1
  43. package/src/{core/tools/exa → exa}/search.ts +2 -10
  44. package/src/{core/tools/exa → exa}/websets.ts +1 -1
  45. package/src/{core → exec}/bash-executor.ts +22 -6
  46. package/src/{core → export}/custom-share.ts +1 -1
  47. package/src/{core/export-html → export/html}/index.ts +3 -3
  48. package/src/{core → export}/ttsr.ts +2 -2
  49. package/src/{core → extensibility}/custom-commands/bundled/review/index.ts +4 -4
  50. package/src/{core → extensibility}/custom-commands/loader.ts +3 -3
  51. package/src/{core → extensibility}/custom-commands/types.ts +1 -1
  52. package/src/{core → extensibility}/custom-tools/loader.ts +9 -9
  53. package/src/{core → extensibility}/custom-tools/types.ts +6 -6
  54. package/src/{core → extensibility}/custom-tools/wrapper.ts +1 -1
  55. package/src/{core → extensibility}/extensions/loader.ts +8 -8
  56. package/src/{core → extensibility}/extensions/runner.ts +3 -3
  57. package/src/{core → extensibility}/extensions/types.ts +15 -15
  58. package/src/{core → extensibility}/extensions/wrapper.ts +1 -1
  59. package/src/{core → extensibility}/hooks/index.ts +1 -1
  60. package/src/{core → extensibility}/hooks/loader.ts +7 -7
  61. package/src/{core → extensibility}/hooks/runner.ts +4 -4
  62. package/src/{core → extensibility}/hooks/types.ts +9 -9
  63. package/src/{core → extensibility}/plugins/doctor.ts +1 -1
  64. package/src/{core → extensibility}/plugins/installer.ts +2 -3
  65. package/src/{core → extensibility}/plugins/paths.ts +1 -1
  66. package/src/{core → extensibility}/skills.ts +8 -48
  67. package/src/{core → extensibility}/slash-commands.ts +6 -6
  68. package/src/index.ts +127 -128
  69. package/src/internal-urls/agent-protocol.ts +126 -0
  70. package/src/internal-urls/artifact-protocol.ts +93 -0
  71. package/src/internal-urls/index.ts +28 -0
  72. package/src/internal-urls/json-query.ts +126 -0
  73. package/src/internal-urls/router.ts +69 -0
  74. package/src/internal-urls/rule-protocol.ts +56 -0
  75. package/src/internal-urls/skill-protocol.ts +112 -0
  76. package/src/internal-urls/types.ts +48 -0
  77. package/src/{core/python-executor.ts → ipy/executor.ts} +51 -11
  78. package/src/{core/python-gateway-coordinator.ts → ipy/gateway-coordinator.ts} +41 -325
  79. package/src/{core/python-kernel.ts → ipy/kernel.ts} +38 -10
  80. package/src/ipy/prelude.ts +3 -0
  81. package/src/{core/tools/lsp → lsp}/client.ts +7 -6
  82. package/src/{core/tools/lsp → lsp}/clients/biome-client.ts +1 -1
  83. package/src/{core/tools/lsp → lsp}/clients/index.ts +1 -1
  84. package/src/{core/tools/lsp → lsp}/clients/lsp-linter-client.ts +4 -4
  85. package/src/{core/tools/lsp → lsp}/config.ts +1 -1
  86. package/src/{core/tools/lsp → lsp}/index.ts +16 -15
  87. package/src/{core/tools/lsp → lsp}/render.ts +2 -2
  88. package/src/{core/tools/lsp → lsp}/types.ts +14 -16
  89. package/src/{core/tools/lsp → lsp}/utils.ts +1 -1
  90. package/src/main.ts +12 -12
  91. package/src/{core/mcp → mcp}/config.ts +8 -8
  92. package/src/{core/mcp → mcp}/loader.ts +5 -6
  93. package/src/{core/mcp → mcp}/manager.ts +2 -2
  94. package/src/{core/mcp → mcp}/tool-bridge.ts +35 -6
  95. package/src/{core/mcp → mcp}/tool-cache.ts +1 -1
  96. package/src/{core/mcp → mcp}/transports/http.ts +7 -1
  97. package/src/{core/mcp → mcp}/transports/stdio.ts +1 -1
  98. package/src/{core/mcp → mcp}/types.ts +1 -1
  99. package/src/migrations.ts +2 -2
  100. package/src/modes/{interactive/components → components}/armin.ts +1 -1
  101. package/src/modes/{interactive/components → components}/assistant-message.ts +1 -1
  102. package/src/modes/{interactive/components → components}/bash-execution.ts +37 -29
  103. package/src/modes/{interactive/components → components}/bordered-loader.ts +1 -1
  104. package/src/modes/{interactive/components → components}/branch-summary-message.ts +2 -2
  105. package/src/modes/{interactive/components → components}/compaction-summary-message.ts +2 -2
  106. package/src/modes/{interactive/components → components}/custom-message.ts +3 -3
  107. package/src/modes/{interactive/components → components}/diff.ts +1 -1
  108. package/src/modes/{interactive/components → components}/dynamic-border.ts +1 -1
  109. package/src/modes/{interactive/components → components}/extensions/extension-dashboard.ts +3 -3
  110. package/src/modes/{interactive/components → components}/extensions/extension-list.ts +2 -2
  111. package/src/modes/{interactive/components → components}/extensions/inspector-panel.ts +1 -1
  112. package/src/modes/{interactive/components → components}/extensions/state-manager.ts +11 -17
  113. package/src/modes/{interactive/components → components}/extensions/types.ts +1 -1
  114. package/src/modes/{interactive/components → components}/footer.ts +3 -3
  115. package/src/modes/{interactive/components → components}/history-search.ts +2 -2
  116. package/src/modes/{interactive/components → components}/hook-editor.ts +1 -1
  117. package/src/modes/{interactive/components → components}/hook-input.ts +1 -1
  118. package/src/modes/{interactive/components → components}/hook-message.ts +3 -3
  119. package/src/modes/{interactive/components → components}/hook-selector.ts +1 -1
  120. package/src/modes/{interactive/components → components}/keybinding-hints.ts +2 -2
  121. package/src/modes/{interactive/components → components}/login-dialog.ts +1 -1
  122. package/src/modes/{interactive/components → components}/model-selector.ts +5 -5
  123. package/src/modes/{interactive/components → components}/oauth-selector.ts +2 -2
  124. package/src/modes/{interactive/components → components}/plugin-settings.ts +3 -3
  125. package/src/modes/{interactive/components → components}/python-execution.ts +35 -24
  126. package/src/modes/{interactive/components → components}/queue-mode-selector.ts +1 -1
  127. package/src/modes/{interactive/components → components}/read-tool-group.ts +2 -2
  128. package/src/modes/{interactive/components → components}/session-selector.ts +3 -3
  129. package/src/modes/{interactive/components → components}/settings-defs.ts +2 -2
  130. package/src/modes/{interactive/components → components}/settings-selector.ts +2 -2
  131. package/src/modes/{interactive/components → components}/show-images-selector.ts +1 -1
  132. package/src/modes/{interactive/components → components}/status-line/segments.ts +2 -2
  133. package/src/modes/{interactive/components → components}/status-line/separators.ts +1 -1
  134. package/src/modes/{interactive/components → components}/status-line/types.ts +2 -2
  135. package/src/modes/{interactive/components → components}/status-line-segment-editor.ts +2 -2
  136. package/src/modes/{interactive/components → components}/status-line.ts +3 -3
  137. package/src/modes/{interactive/components → components}/theme-selector.ts +1 -1
  138. package/src/modes/{interactive/components → components}/thinking-selector.ts +1 -1
  139. package/src/modes/{interactive/components → components}/todo-display.ts +3 -4
  140. package/src/modes/{interactive/components → components}/todo-reminder.ts +2 -2
  141. package/src/modes/{interactive/components → components}/tool-execution.ts +8 -8
  142. package/src/modes/{interactive/components → components}/tree-selector.ts +3 -3
  143. package/src/modes/{interactive/components → components}/ttsr-notification.ts +2 -2
  144. package/src/modes/{interactive/components → components}/user-message-selector.ts +1 -1
  145. package/src/modes/{interactive/components → components}/user-message.ts +1 -1
  146. package/src/modes/{interactive/components → components}/welcome.ts +2 -2
  147. package/src/modes/{interactive/controllers → controllers}/command-controller.ts +32 -30
  148. package/src/modes/{interactive/controllers → controllers}/event-controller.ts +9 -9
  149. package/src/modes/{interactive/controllers → controllers}/extension-ui-controller.ts +8 -8
  150. package/src/modes/{interactive/controllers → controllers}/input-controller.ts +6 -6
  151. package/src/modes/{interactive/controllers → controllers}/selector-controller.ts +16 -16
  152. package/src/modes/index.ts +1 -1
  153. package/src/modes/{interactive/interactive-mode.ts → interactive-mode.ts} +14 -14
  154. package/src/modes/print-mode.ts +1 -1
  155. package/src/modes/rpc/rpc-client.ts +3 -3
  156. package/src/modes/rpc/rpc-mode.ts +3 -3
  157. package/src/modes/rpc/rpc-types.ts +3 -3
  158. package/src/modes/{interactive/theme → theme}/theme.ts +1 -1
  159. package/src/modes/{interactive/types.ts → types.ts} +8 -9
  160. package/src/modes/{interactive/utils → utils}/ui-helpers.ts +20 -27
  161. package/src/{core/tools/patch → patch}/applicator.ts +1 -1
  162. package/src/{core/tools/patch → patch}/diff.ts +1 -1
  163. package/src/{core/tools/patch → patch}/index.ts +31 -36
  164. package/src/{core/tools/patch → patch}/shared.ts +9 -6
  165. package/src/prompts/agents/explore.md +83 -46
  166. package/src/prompts/agents/init.md +9 -4
  167. package/src/prompts/agents/plan.md +8 -7
  168. package/src/prompts/agents/reviewer.md +36 -18
  169. package/src/prompts/agents/task.md +4 -4
  170. package/src/prompts/compaction/branch-summary-preamble.md +0 -1
  171. package/src/prompts/review-request.md +0 -1
  172. package/src/prompts/system/custom-system-prompt.md +2 -14
  173. package/src/prompts/system/file-operations.md +0 -2
  174. package/src/prompts/system/system-prompt.md +147 -138
  175. package/src/prompts/system/web-search.md +26 -0
  176. package/src/prompts/tools/ask.md +31 -24
  177. package/src/prompts/tools/bash.md +20 -17
  178. package/src/prompts/tools/calculator.md +9 -5
  179. package/src/prompts/tools/fetch.md +16 -0
  180. package/src/prompts/tools/find.md +15 -5
  181. package/src/prompts/tools/gemini-image.md +21 -6
  182. package/src/prompts/tools/grep.md +28 -12
  183. package/src/prompts/tools/lsp.md +35 -14
  184. package/src/prompts/tools/patch.md +39 -41
  185. package/src/prompts/tools/python.md +59 -76
  186. package/src/prompts/tools/read.md +23 -22
  187. package/src/prompts/tools/replace.md +19 -12
  188. package/src/prompts/tools/ssh.md +21 -28
  189. package/src/prompts/tools/task.md +54 -44
  190. package/src/prompts/tools/todo-write.md +52 -163
  191. package/src/prompts/tools/web-search.md +16 -9
  192. package/src/prompts/tools/write.md +13 -2
  193. package/src/{core/sdk.ts → sdk.ts} +65 -34
  194. package/src/{core → session}/agent-session.ts +45 -37
  195. package/src/{core → session}/agent-storage.ts +2 -2
  196. package/src/session/artifacts.ts +110 -0
  197. package/src/{core → session}/auth-storage.ts +1 -1
  198. package/src/{core → session}/compaction/branch-summarization.ts +5 -5
  199. package/src/{core → session}/compaction/compaction.ts +6 -6
  200. package/src/{core → session}/compaction/utils.ts +3 -3
  201. package/src/{core → session}/history-storage.ts +1 -1
  202. package/src/{core → session}/messages.ts +6 -8
  203. package/src/{core → session}/session-manager.ts +2 -2
  204. package/src/{core → session}/storage-migration.ts +2 -2
  205. package/src/session/streaming-output.ts +177 -0
  206. package/src/{core/ssh → ssh}/connection-manager.ts +1 -1
  207. package/src/{core/ssh → ssh}/ssh-executor.ts +19 -4
  208. package/src/{core/ssh → ssh}/sshfs-mount.ts +1 -1
  209. package/src/{core/system-prompt.ts → system-prompt.ts} +8 -37
  210. package/src/{core/tools/task → task}/agents.ts +8 -8
  211. package/src/{core/tools/task → task}/commands.ts +5 -6
  212. package/src/{core/tools/task → task}/discovery.ts +3 -3
  213. package/src/{core/tools/task → task}/executor.ts +34 -44
  214. package/src/{core/tools/task → task}/index.ts +206 -50
  215. package/src/{core/tools/task → task}/render.ts +80 -23
  216. package/src/{core/tools/task → task}/subprocess-tool-registry.ts +1 -1
  217. package/src/task/template.ts +47 -0
  218. package/src/{core/tools/task → task}/types.ts +19 -27
  219. package/src/{core/tools/task → task}/worker-protocol.ts +8 -4
  220. package/src/{core/tools/task → task}/worker.ts +34 -29
  221. package/src/task/worktree.ts +166 -0
  222. package/src/{core/tools → tools}/ask.ts +13 -21
  223. package/src/{core/tools → tools}/bash-interceptor.ts +1 -1
  224. package/src/{core/tools → tools}/bash.ts +61 -63
  225. package/src/{core/tools → tools}/calculator.ts +4 -4
  226. package/src/{core/tools → tools}/complete.ts +1 -1
  227. package/src/{core/tools → tools}/context.ts +2 -2
  228. package/src/{core/tools/web-fetch.ts → tools/fetch.ts} +97 -76
  229. package/src/{core/tools → tools}/find.ts +80 -104
  230. package/src/{core/tools → tools}/gemini-image.ts +420 -29
  231. package/src/{core/tools → tools}/grep.ts +155 -164
  232. package/src/{core/tools → tools}/index.ts +63 -56
  233. package/src/tools/list-limit.ts +40 -0
  234. package/src/{core/tools → tools}/ls.ts +44 -35
  235. package/src/{core/tools → tools}/notebook.ts +3 -3
  236. package/src/tools/output-meta.ts +443 -0
  237. package/src/tools/output-utils.ts +63 -0
  238. package/src/{core/tools → tools}/python.ts +105 -89
  239. package/src/tools/read.ts +882 -0
  240. package/src/{core/tools → tools}/render-utils.ts +1 -1
  241. package/src/{core/tools → tools}/renderers.ts +8 -10
  242. package/src/{core/tools → tools}/review.ts +2 -2
  243. package/src/{core/tools → tools}/ssh.ts +56 -59
  244. package/src/{core/tools → tools}/todo-write.ts +12 -23
  245. package/src/tools/tool-errors.ts +95 -0
  246. package/src/tools/tool-result.ts +92 -0
  247. package/src/{core/tools → tools}/truncate.ts +2 -2
  248. package/src/{core/tools → tools}/write.ts +15 -13
  249. package/src/utils/changelog.ts +1 -1
  250. package/src/{core → utils}/file-mentions.ts +4 -4
  251. package/src/utils/image-convert.ts +1 -1
  252. package/src/utils/image-resize.ts +1 -1
  253. package/src/utils/shell.ts +1 -1
  254. package/src/{core → utils}/title-generator.ts +4 -4
  255. package/src/utils/tools-manager.ts +1 -1
  256. package/src/{core/tools/web-scrapers → web/scrapers}/choosealicense.ts +1 -1
  257. package/src/{core/tools/web-scrapers → web/scrapers}/twitter.ts +3 -2
  258. package/src/{core/tools/web-scrapers → web/scrapers}/types.ts +4 -2
  259. package/src/{core/tools/web-scrapers → web/scrapers}/utils.ts +1 -1
  260. package/src/{core/tools/web-scrapers → web/scrapers}/youtube.ts +14 -13
  261. package/src/{core/tools/web-search → web/search}/auth.ts +4 -4
  262. package/src/{core/tools/web-search → web/search}/index.ts +22 -71
  263. package/src/{core/tools/web-search → web/search}/providers/anthropic.ts +7 -10
  264. package/src/{core/tools/web-search → web/search}/providers/exa.ts +2 -2
  265. package/src/{core/tools/web-search → web/search}/providers/perplexity.ts +4 -16
  266. package/src/{core/tools/web-search → web/search}/render.ts +3 -3
  267. package/scripts/migrate-sessions.sh +0 -93
  268. package/src/core/index.ts +0 -56
  269. package/src/core/python-prelude.ts +0 -3
  270. package/src/core/ssh-executor.ts +0 -5
  271. package/src/core/streaming-output.ts +0 -115
  272. package/src/core/tools/output.ts +0 -519
  273. package/src/core/tools/read.ts +0 -717
  274. package/src/core/tools/task/template.ts +0 -37
  275. package/src/prompts/tools/output.md +0 -47
  276. package/src/prompts/tools/web-fetch.md +0 -9
  277. /package/src/{core/tools/exa → exa}/types.ts +0 -0
  278. /package/src/{core → exec}/exec.ts +0 -0
  279. /package/src/{core/export-html → export/html}/template.css +0 -0
  280. /package/src/{core/export-html → export/html}/template.generated.ts +0 -0
  281. /package/src/{core/export-html → export/html}/template.html +0 -0
  282. /package/src/{core/export-html → export/html}/template.js +0 -0
  283. /package/src/{core/export-html → export/html}/template.macro.ts +0 -0
  284. /package/src/{core/export-html → export/html}/vendor/highlight.min.js +0 -0
  285. /package/src/{core/export-html → export/html}/vendor/marked.min.js +0 -0
  286. /package/src/{core → extensibility}/custom-commands/index.ts +0 -0
  287. /package/src/{core → extensibility}/custom-tools/index.ts +0 -0
  288. /package/src/{core → extensibility}/extensions/index.ts +0 -0
  289. /package/src/{core → extensibility}/hooks/tool-wrapper.ts +0 -0
  290. /package/src/{core → extensibility}/plugins/index.ts +0 -0
  291. /package/src/{core → extensibility}/plugins/loader.ts +0 -0
  292. /package/src/{core → extensibility}/plugins/manager.ts +0 -0
  293. /package/src/{core → extensibility}/plugins/parser.ts +0 -0
  294. /package/src/{core → extensibility}/plugins/types.ts +0 -0
  295. /package/src/{core/python-modules.ts → ipy/modules.ts} +0 -0
  296. /package/src/{core/python-prelude.py → ipy/prelude.py} +0 -0
  297. /package/src/{core/tools/lsp → lsp}/defaults.json +0 -0
  298. /package/src/{core/tools/lsp → lsp}/edits.ts +0 -0
  299. /package/src/{core/tools/lsp → lsp}/lspmux.ts +0 -0
  300. /package/src/{core/tools/lsp → lsp}/rust-analyzer.ts +0 -0
  301. /package/src/{core/mcp → mcp}/client.ts +0 -0
  302. /package/src/{core/mcp → mcp}/index.ts +0 -0
  303. /package/src/{core/mcp → mcp}/json-rpc.ts +0 -0
  304. /package/src/{core/mcp → mcp}/transports/index.ts +0 -0
  305. /package/src/modes/{interactive/components → components}/countdown-timer.ts +0 -0
  306. /package/src/modes/{interactive/components → components}/custom-editor.ts +0 -0
  307. /package/src/modes/{interactive/components → components}/extensions/index.ts +0 -0
  308. /package/src/modes/{interactive/components → components}/index.ts +0 -0
  309. /package/src/modes/{interactive/components → components}/status-line/index.ts +0 -0
  310. /package/src/modes/{interactive/components → components}/status-line/presets.ts +0 -0
  311. /package/src/modes/{interactive/components → components}/visual-truncate.ts +0 -0
  312. /package/src/modes/{interactive/theme → theme}/dark.json +0 -0
  313. /package/src/modes/{interactive/theme → theme}/defaults/alabaster.json +0 -0
  314. /package/src/modes/{interactive/theme → theme}/defaults/amethyst.json +0 -0
  315. /package/src/modes/{interactive/theme → theme}/defaults/anthracite.json +0 -0
  316. /package/src/modes/{interactive/theme → theme}/defaults/basalt.json +0 -0
  317. /package/src/modes/{interactive/theme → theme}/defaults/birch.json +0 -0
  318. /package/src/modes/{interactive/theme → theme}/defaults/dark-abyss.json +0 -0
  319. /package/src/modes/{interactive/theme → theme}/defaults/dark-arctic.json +0 -0
  320. /package/src/modes/{interactive/theme → theme}/defaults/dark-aurora.json +0 -0
  321. /package/src/modes/{interactive/theme → theme}/defaults/dark-catppuccin.json +0 -0
  322. /package/src/modes/{interactive/theme → theme}/defaults/dark-cavern.json +0 -0
  323. /package/src/modes/{interactive/theme → theme}/defaults/dark-copper.json +0 -0
  324. /package/src/modes/{interactive/theme → theme}/defaults/dark-cosmos.json +0 -0
  325. /package/src/modes/{interactive/theme → theme}/defaults/dark-cyberpunk.json +0 -0
  326. /package/src/modes/{interactive/theme → theme}/defaults/dark-dracula.json +0 -0
  327. /package/src/modes/{interactive/theme → theme}/defaults/dark-eclipse.json +0 -0
  328. /package/src/modes/{interactive/theme → theme}/defaults/dark-ember.json +0 -0
  329. /package/src/modes/{interactive/theme → theme}/defaults/dark-equinox.json +0 -0
  330. /package/src/modes/{interactive/theme → theme}/defaults/dark-forest.json +0 -0
  331. /package/src/modes/{interactive/theme → theme}/defaults/dark-github.json +0 -0
  332. /package/src/modes/{interactive/theme → theme}/defaults/dark-gruvbox.json +0 -0
  333. /package/src/modes/{interactive/theme → theme}/defaults/dark-lavender.json +0 -0
  334. /package/src/modes/{interactive/theme → theme}/defaults/dark-lunar.json +0 -0
  335. /package/src/modes/{interactive/theme → theme}/defaults/dark-midnight.json +0 -0
  336. /package/src/modes/{interactive/theme → theme}/defaults/dark-monochrome.json +0 -0
  337. /package/src/modes/{interactive/theme → theme}/defaults/dark-monokai.json +0 -0
  338. /package/src/modes/{interactive/theme → theme}/defaults/dark-nebula.json +0 -0
  339. /package/src/modes/{interactive/theme → theme}/defaults/dark-nord.json +0 -0
  340. /package/src/modes/{interactive/theme → theme}/defaults/dark-ocean.json +0 -0
  341. /package/src/modes/{interactive/theme → theme}/defaults/dark-one.json +0 -0
  342. /package/src/modes/{interactive/theme → theme}/defaults/dark-rainforest.json +0 -0
  343. /package/src/modes/{interactive/theme → theme}/defaults/dark-reef.json +0 -0
  344. /package/src/modes/{interactive/theme → theme}/defaults/dark-retro.json +0 -0
  345. /package/src/modes/{interactive/theme → theme}/defaults/dark-rose-pine.json +0 -0
  346. /package/src/modes/{interactive/theme → theme}/defaults/dark-sakura.json +0 -0
  347. /package/src/modes/{interactive/theme → theme}/defaults/dark-slate.json +0 -0
  348. /package/src/modes/{interactive/theme → theme}/defaults/dark-solarized.json +0 -0
  349. /package/src/modes/{interactive/theme → theme}/defaults/dark-solstice.json +0 -0
  350. /package/src/modes/{interactive/theme → theme}/defaults/dark-starfall.json +0 -0
  351. /package/src/modes/{interactive/theme → theme}/defaults/dark-sunset.json +0 -0
  352. /package/src/modes/{interactive/theme → theme}/defaults/dark-swamp.json +0 -0
  353. /package/src/modes/{interactive/theme → theme}/defaults/dark-synthwave.json +0 -0
  354. /package/src/modes/{interactive/theme → theme}/defaults/dark-taiga.json +0 -0
  355. /package/src/modes/{interactive/theme → theme}/defaults/dark-terminal.json +0 -0
  356. /package/src/modes/{interactive/theme → theme}/defaults/dark-tokyo-night.json +0 -0
  357. /package/src/modes/{interactive/theme → theme}/defaults/dark-tundra.json +0 -0
  358. /package/src/modes/{interactive/theme → theme}/defaults/dark-twilight.json +0 -0
  359. /package/src/modes/{interactive/theme → theme}/defaults/dark-volcanic.json +0 -0
  360. /package/src/modes/{interactive/theme → theme}/defaults/graphite.json +0 -0
  361. /package/src/modes/{interactive/theme → theme}/defaults/index.ts +0 -0
  362. /package/src/modes/{interactive/theme → theme}/defaults/light-arctic.json +0 -0
  363. /package/src/modes/{interactive/theme → theme}/defaults/light-aurora-day.json +0 -0
  364. /package/src/modes/{interactive/theme → theme}/defaults/light-canyon.json +0 -0
  365. /package/src/modes/{interactive/theme → theme}/defaults/light-catppuccin.json +0 -0
  366. /package/src/modes/{interactive/theme → theme}/defaults/light-cirrus.json +0 -0
  367. /package/src/modes/{interactive/theme → theme}/defaults/light-coral.json +0 -0
  368. /package/src/modes/{interactive/theme → theme}/defaults/light-cyberpunk.json +0 -0
  369. /package/src/modes/{interactive/theme → theme}/defaults/light-dawn.json +0 -0
  370. /package/src/modes/{interactive/theme → theme}/defaults/light-dunes.json +0 -0
  371. /package/src/modes/{interactive/theme → theme}/defaults/light-eucalyptus.json +0 -0
  372. /package/src/modes/{interactive/theme → theme}/defaults/light-forest.json +0 -0
  373. /package/src/modes/{interactive/theme → theme}/defaults/light-frost.json +0 -0
  374. /package/src/modes/{interactive/theme → theme}/defaults/light-github.json +0 -0
  375. /package/src/modes/{interactive/theme → theme}/defaults/light-glacier.json +0 -0
  376. /package/src/modes/{interactive/theme → theme}/defaults/light-gruvbox.json +0 -0
  377. /package/src/modes/{interactive/theme → theme}/defaults/light-haze.json +0 -0
  378. /package/src/modes/{interactive/theme → theme}/defaults/light-honeycomb.json +0 -0
  379. /package/src/modes/{interactive/theme → theme}/defaults/light-lagoon.json +0 -0
  380. /package/src/modes/{interactive/theme → theme}/defaults/light-lavender.json +0 -0
  381. /package/src/modes/{interactive/theme → theme}/defaults/light-meadow.json +0 -0
  382. /package/src/modes/{interactive/theme → theme}/defaults/light-mint.json +0 -0
  383. /package/src/modes/{interactive/theme → theme}/defaults/light-monochrome.json +0 -0
  384. /package/src/modes/{interactive/theme → theme}/defaults/light-ocean.json +0 -0
  385. /package/src/modes/{interactive/theme → theme}/defaults/light-one.json +0 -0
  386. /package/src/modes/{interactive/theme → theme}/defaults/light-opal.json +0 -0
  387. /package/src/modes/{interactive/theme → theme}/defaults/light-orchard.json +0 -0
  388. /package/src/modes/{interactive/theme → theme}/defaults/light-paper.json +0 -0
  389. /package/src/modes/{interactive/theme → theme}/defaults/light-prism.json +0 -0
  390. /package/src/modes/{interactive/theme → theme}/defaults/light-retro.json +0 -0
  391. /package/src/modes/{interactive/theme → theme}/defaults/light-sand.json +0 -0
  392. /package/src/modes/{interactive/theme → theme}/defaults/light-savanna.json +0 -0
  393. /package/src/modes/{interactive/theme → theme}/defaults/light-solarized.json +0 -0
  394. /package/src/modes/{interactive/theme → theme}/defaults/light-soleil.json +0 -0
  395. /package/src/modes/{interactive/theme → theme}/defaults/light-sunset.json +0 -0
  396. /package/src/modes/{interactive/theme → theme}/defaults/light-synthwave.json +0 -0
  397. /package/src/modes/{interactive/theme → theme}/defaults/light-tokyo-night.json +0 -0
  398. /package/src/modes/{interactive/theme → theme}/defaults/light-wetland.json +0 -0
  399. /package/src/modes/{interactive/theme → theme}/defaults/light-zenith.json +0 -0
  400. /package/src/modes/{interactive/theme → theme}/defaults/limestone.json +0 -0
  401. /package/src/modes/{interactive/theme → theme}/defaults/mahogany.json +0 -0
  402. /package/src/modes/{interactive/theme → theme}/defaults/marble.json +0 -0
  403. /package/src/modes/{interactive/theme → theme}/defaults/obsidian.json +0 -0
  404. /package/src/modes/{interactive/theme → theme}/defaults/onyx.json +0 -0
  405. /package/src/modes/{interactive/theme → theme}/defaults/pearl.json +0 -0
  406. /package/src/modes/{interactive/theme → theme}/defaults/porcelain.json +0 -0
  407. /package/src/modes/{interactive/theme → theme}/defaults/quartz.json +0 -0
  408. /package/src/modes/{interactive/theme → theme}/defaults/sandstone.json +0 -0
  409. /package/src/modes/{interactive/theme → theme}/defaults/titanium.json +0 -0
  410. /package/src/modes/{interactive/theme → theme}/light.json +0 -0
  411. /package/src/modes/{interactive/theme → theme}/theme-schema.json +0 -0
  412. /package/src/{core/tools/patch → patch}/fuzzy.ts +0 -0
  413. /package/src/{core/tools/patch → patch}/normalize.ts +0 -0
  414. /package/src/{core/tools/patch → patch}/normative.ts +0 -0
  415. /package/src/{core/tools/patch → patch}/parser.ts +0 -0
  416. /package/src/{core/tools/patch → patch}/types.ts +0 -0
  417. /package/src/{core → session}/compaction/index.ts +0 -0
  418. /package/src/{core → session}/session-storage.ts +0 -0
  419. /package/src/{core/tools/task → task}/name-generator.ts +0 -0
  420. /package/src/{core/tools/task → task}/omp-command.ts +0 -0
  421. /package/src/{core/tools/task → task}/parallel.ts +0 -0
  422. /package/src/{core/tools → tools}/jtd-to-json-schema.ts +0 -0
  423. /package/src/{core/tools → tools}/path-utils.ts +0 -0
  424. /package/src/{core → utils}/event-bus.ts +0 -0
  425. /package/src/{core → utils}/frontmatter.ts +0 -0
  426. /package/src/{core → utils}/terminal-notify.ts +0 -0
  427. /package/src/{core → utils}/timings.ts +0 -0
  428. /package/src/{core → utils}/utils.ts +0 -0
  429. /package/src/{core/tools/web-scrapers → web/scrapers}/artifacthub.ts +0 -0
  430. /package/src/{core/tools/web-scrapers → web/scrapers}/arxiv.ts +0 -0
  431. /package/src/{core/tools/web-scrapers → web/scrapers}/aur.ts +0 -0
  432. /package/src/{core/tools/web-scrapers → web/scrapers}/biorxiv.ts +0 -0
  433. /package/src/{core/tools/web-scrapers → web/scrapers}/bluesky.ts +0 -0
  434. /package/src/{core/tools/web-scrapers → web/scrapers}/brew.ts +0 -0
  435. /package/src/{core/tools/web-scrapers → web/scrapers}/cheatsh.ts +0 -0
  436. /package/src/{core/tools/web-scrapers → web/scrapers}/chocolatey.ts +0 -0
  437. /package/src/{core/tools/web-scrapers → web/scrapers}/cisa-kev.ts +0 -0
  438. /package/src/{core/tools/web-scrapers → web/scrapers}/clojars.ts +0 -0
  439. /package/src/{core/tools/web-scrapers → web/scrapers}/coingecko.ts +0 -0
  440. /package/src/{core/tools/web-scrapers → web/scrapers}/crates-io.ts +0 -0
  441. /package/src/{core/tools/web-scrapers → web/scrapers}/crossref.ts +0 -0
  442. /package/src/{core/tools/web-scrapers → web/scrapers}/devto.ts +0 -0
  443. /package/src/{core/tools/web-scrapers → web/scrapers}/discogs.ts +0 -0
  444. /package/src/{core/tools/web-scrapers → web/scrapers}/discourse.ts +0 -0
  445. /package/src/{core/tools/web-scrapers → web/scrapers}/dockerhub.ts +0 -0
  446. /package/src/{core/tools/web-scrapers → web/scrapers}/fdroid.ts +0 -0
  447. /package/src/{core/tools/web-scrapers → web/scrapers}/firefox-addons.ts +0 -0
  448. /package/src/{core/tools/web-scrapers → web/scrapers}/flathub.ts +0 -0
  449. /package/src/{core/tools/web-scrapers → web/scrapers}/github-gist.ts +0 -0
  450. /package/src/{core/tools/web-scrapers → web/scrapers}/github.ts +0 -0
  451. /package/src/{core/tools/web-scrapers → web/scrapers}/gitlab.ts +0 -0
  452. /package/src/{core/tools/web-scrapers → web/scrapers}/go-pkg.ts +0 -0
  453. /package/src/{core/tools/web-scrapers → web/scrapers}/hackage.ts +0 -0
  454. /package/src/{core/tools/web-scrapers → web/scrapers}/hackernews.ts +0 -0
  455. /package/src/{core/tools/web-scrapers → web/scrapers}/hex.ts +0 -0
  456. /package/src/{core/tools/web-scrapers → web/scrapers}/huggingface.ts +0 -0
  457. /package/src/{core/tools/web-scrapers → web/scrapers}/iacr.ts +0 -0
  458. /package/src/{core/tools/web-scrapers → web/scrapers}/index.ts +0 -0
  459. /package/src/{core/tools/web-scrapers → web/scrapers}/jetbrains-marketplace.ts +0 -0
  460. /package/src/{core/tools/web-scrapers → web/scrapers}/lemmy.ts +0 -0
  461. /package/src/{core/tools/web-scrapers → web/scrapers}/lobsters.ts +0 -0
  462. /package/src/{core/tools/web-scrapers → web/scrapers}/mastodon.ts +0 -0
  463. /package/src/{core/tools/web-scrapers → web/scrapers}/maven.ts +0 -0
  464. /package/src/{core/tools/web-scrapers → web/scrapers}/mdn.ts +0 -0
  465. /package/src/{core/tools/web-scrapers → web/scrapers}/metacpan.ts +0 -0
  466. /package/src/{core/tools/web-scrapers → web/scrapers}/musicbrainz.ts +0 -0
  467. /package/src/{core/tools/web-scrapers → web/scrapers}/npm.ts +0 -0
  468. /package/src/{core/tools/web-scrapers → web/scrapers}/nuget.ts +0 -0
  469. /package/src/{core/tools/web-scrapers → web/scrapers}/nvd.ts +0 -0
  470. /package/src/{core/tools/web-scrapers → web/scrapers}/ollama.ts +0 -0
  471. /package/src/{core/tools/web-scrapers → web/scrapers}/open-vsx.ts +0 -0
  472. /package/src/{core/tools/web-scrapers → web/scrapers}/opencorporates.ts +0 -0
  473. /package/src/{core/tools/web-scrapers → web/scrapers}/openlibrary.ts +0 -0
  474. /package/src/{core/tools/web-scrapers → web/scrapers}/orcid.ts +0 -0
  475. /package/src/{core/tools/web-scrapers → web/scrapers}/osv.ts +0 -0
  476. /package/src/{core/tools/web-scrapers → web/scrapers}/packagist.ts +0 -0
  477. /package/src/{core/tools/web-scrapers → web/scrapers}/pub-dev.ts +0 -0
  478. /package/src/{core/tools/web-scrapers → web/scrapers}/pubmed.ts +0 -0
  479. /package/src/{core/tools/web-scrapers → web/scrapers}/pypi.ts +0 -0
  480. /package/src/{core/tools/web-scrapers → web/scrapers}/rawg.ts +0 -0
  481. /package/src/{core/tools/web-scrapers → web/scrapers}/readthedocs.ts +0 -0
  482. /package/src/{core/tools/web-scrapers → web/scrapers}/reddit.ts +0 -0
  483. /package/src/{core/tools/web-scrapers → web/scrapers}/repology.ts +0 -0
  484. /package/src/{core/tools/web-scrapers → web/scrapers}/rfc.ts +0 -0
  485. /package/src/{core/tools/web-scrapers → web/scrapers}/rubygems.ts +0 -0
  486. /package/src/{core/tools/web-scrapers → web/scrapers}/searchcode.ts +0 -0
  487. /package/src/{core/tools/web-scrapers → web/scrapers}/sec-edgar.ts +0 -0
  488. /package/src/{core/tools/web-scrapers → web/scrapers}/semantic-scholar.ts +0 -0
  489. /package/src/{core/tools/web-scrapers → web/scrapers}/snapcraft.ts +0 -0
  490. /package/src/{core/tools/web-scrapers → web/scrapers}/sourcegraph.ts +0 -0
  491. /package/src/{core/tools/web-scrapers → web/scrapers}/spdx.ts +0 -0
  492. /package/src/{core/tools/web-scrapers → web/scrapers}/spotify.ts +0 -0
  493. /package/src/{core/tools/web-scrapers → web/scrapers}/stackoverflow.ts +0 -0
  494. /package/src/{core/tools/web-scrapers → web/scrapers}/terraform.ts +0 -0
  495. /package/src/{core/tools/web-scrapers → web/scrapers}/tldr.ts +0 -0
  496. /package/src/{core/tools/web-scrapers → web/scrapers}/vimeo.ts +0 -0
  497. /package/src/{core/tools/web-scrapers → web/scrapers}/vscode-marketplace.ts +0 -0
  498. /package/src/{core/tools/web-scrapers → web/scrapers}/w3c.ts +0 -0
  499. /package/src/{core/tools/web-scrapers → web/scrapers}/wikidata.ts +0 -0
  500. /package/src/{core/tools/web-scrapers → web/scrapers}/wikipedia.ts +0 -0
  501. /package/src/{core/tools/web-search → web/search}/types.ts +0 -0
@@ -31,9 +31,6 @@ export const MAX_OUTPUT_BYTES = getEnv("OMP_TASK_MAX_OUTPUT_BYTES", 500_000);
31
31
  /** Maximum output lines per agent */
32
32
  export const MAX_OUTPUT_LINES = getEnv("OMP_TASK_MAX_OUTPUT_LINES", 5000);
33
33
 
34
- /** Maximum agents to show in description */
35
- export const MAX_AGENTS_IN_DESCRIPTION = getEnv("OMP_TASK_MAX_AGENTS_IN_DESCRIPTION", 10);
36
-
37
34
  /** EventBus channel for raw subagent events */
38
35
  export const TASK_SUBAGENT_EVENT_CHANNEL = "task:subagent:event";
39
36
 
@@ -43,35 +40,28 @@ export const TASK_SUBAGENT_PROGRESS_CHANNEL = "task:subagent:progress";
43
40
  /** Single task item for parallel execution */
44
41
  export const taskItemSchema = Type.Object({
45
42
  id: Type.String({
46
- description: "Short task identifier for display (max 32 chars, CamelCase, e.g. 'SessionStore', 'WebFetchFix')",
43
+ description: "Task ID, CamelCase, max 32 chars",
47
44
  maxLength: 32,
48
45
  }),
49
- description: Type.String({ description: "Short description for UI display" }),
50
- vars: Type.Record(Type.String(), Type.String(), {
51
- description: "Template variables to fill {{placeholders}} in context",
52
- }),
46
+ description: Type.String({ description: "Short description for display" }),
47
+ args: Type.Optional(
48
+ Type.Record(Type.String(), Type.String(), {
49
+ description: "Arguments to fill {{placeholders}} in context",
50
+ }),
51
+ ),
53
52
  });
54
53
 
55
54
  export type TaskItem = Static<typeof taskItemSchema>;
56
55
 
57
56
  /** Task tool parameters */
58
57
  export const taskSchema = Type.Object({
59
- agent: Type.String({ description: "Agent type to use for all tasks" }),
60
- context: Type.String({ description: "Template with {{placeholders}} filled by task vars" }),
61
- model: Type.Optional(
62
- Type.String({
63
- description: "Model override for all tasks (fuzzy matching, e.g. 'sonnet', 'opus')",
64
- }),
65
- ),
58
+ agent: Type.String({ description: "Agent type for all tasks" }),
59
+ context: Type.String({ description: "Template with {{placeholders}} for args" }),
60
+ isolated: Type.Optional(Type.Boolean({ description: "Run in isolated git worktree" })),
66
61
  output: Type.Optional(
67
- Type.Record(Type.String(), Type.Unknown(), {
68
- description: "JTD schema for structured subagent output",
69
- }),
62
+ Type.Record(Type.String(), Type.Unknown(), { description: "JTD schema for structured output" }),
70
63
  ),
71
- tasks: Type.Array(taskItemSchema, {
72
- description: "Tasks to run in parallel",
73
- maxItems: MAX_PARALLEL_TASKS,
74
- }),
64
+ tasks: Type.Array(taskItemSchema, { description: "Tasks to run in parallel", maxItems: MAX_PARALLEL_TASKS }),
75
65
  });
76
66
 
77
67
  export type TaskParams = Static<typeof taskSchema>;
@@ -117,12 +107,12 @@ export interface AgentDefinition {
117
107
  /** Progress tracking for a single agent */
118
108
  export interface AgentProgress {
119
109
  index: number;
120
- taskId: string;
110
+ id: string;
121
111
  agent: string;
122
112
  agentSource: AgentSource;
123
113
  status: "pending" | "running" | "completed" | "failed" | "aborted";
124
114
  task: string;
125
- vars?: Record<string, string>;
115
+ args?: Record<string, string>;
126
116
  description?: string;
127
117
  currentTool?: string;
128
118
  currentToolArgs?: string;
@@ -140,11 +130,11 @@ export interface AgentProgress {
140
130
  /** Result from a single agent execution */
141
131
  export interface SingleResult {
142
132
  index: number;
143
- taskId: string;
133
+ id: string;
144
134
  agent: string;
145
135
  agentSource: AgentSource;
146
136
  task: string;
147
- vars?: Record<string, string>;
137
+ args?: Record<string, string>;
148
138
  description?: string;
149
139
  exitCode: number;
150
140
  output: string;
@@ -159,9 +149,11 @@ export interface SingleResult {
159
149
  usage?: Usage;
160
150
  /** Output path for the task result */
161
151
  outputPath?: string;
152
+ /** Patch path for isolated worktree output */
153
+ patchPath?: string;
162
154
  /** Data extracted by registered subprocess tool handlers (keyed by tool name) */
163
155
  extractedToolData?: Record<string, unknown[]>;
164
- /** Output metadata for Output tool integration */
156
+ /** Output metadata for agent:// URL integration */
165
157
  outputMeta?: { lineCount: number; charCount: number };
166
158
  }
167
159
 
@@ -1,7 +1,7 @@
1
1
  import type { AgentEvent, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
2
- import type { SerializedAuthStorage } from "../../auth-storage";
3
- import type { SerializedModelRegistry } from "../../model-registry";
4
- import type { Settings } from "../../settings-manager";
2
+ import type { SerializedModelRegistry } from "$c/config/model-registry";
3
+ import type { Settings } from "$c/config/settings-manager";
4
+ import type { SerializedAuthStorage } from "$c/session/auth-storage";
5
5
 
6
6
  /**
7
7
  * MCP tool metadata passed from parent to worker for proxy tool creation.
@@ -22,7 +22,10 @@ export interface MCPToolMetadata {
22
22
  export interface MCPToolCallRequest {
23
23
  type: "mcp_tool_call";
24
24
  callId: string;
25
- toolName: string;
25
+ /** Server name for routing to correct connection */
26
+ serverName: string;
27
+ /** Original MCP tool name (as expected by the MCP server) */
28
+ mcpToolName: string;
26
29
  params: Record<string, unknown>;
27
30
  timeoutMs?: number;
28
31
  }
@@ -84,6 +87,7 @@ export interface LspToolCallResponse {
84
87
 
85
88
  export interface SubagentWorkerStartPayload {
86
89
  cwd: string;
90
+ worktree?: string;
87
91
  task: string;
88
92
  systemPrompt: string;
89
93
  model?: string;
@@ -17,18 +17,19 @@ import type { AgentEvent, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
17
17
  import type { Api, Model } from "@oh-my-pi/pi-ai";
18
18
  import { logger, postmortem, untilAborted } from "@oh-my-pi/pi-utils";
19
19
  import type { TSchema } from "@sinclair/typebox";
20
- import lspDescription from "../../../prompts/tools/lsp.md" with { type: "text" };
21
- import type { AgentSessionEvent } from "../../agent-session";
22
- import { AuthStorage } from "../../auth-storage";
23
- import type { CustomTool } from "../../custom-tools/types";
24
- import { ModelRegistry } from "../../model-registry";
25
- import { parseModelPattern, parseModelString } from "../../model-resolver";
26
- import { renderPromptTemplate } from "../../prompt-templates";
27
- import { createAgentSession, discoverAuthStorage, discoverModels } from "../../sdk";
28
- import { SessionManager } from "../../session-manager";
29
- import { SettingsManager } from "../../settings-manager";
30
- import { type LspToolDetails, lspSchema } from "../lsp/types";
31
- import { getPythonToolDescription, type PythonToolDetails, type PythonToolParams, pythonSchema } from "../python";
20
+ import { ModelRegistry } from "$c/config/model-registry";
21
+ import { parseModelPattern, parseModelString } from "$c/config/model-resolver";
22
+ import { renderPromptTemplate } from "$c/config/prompt-templates";
23
+ import { SettingsManager } from "$c/config/settings-manager";
24
+ import type { CustomTool } from "$c/extensibility/custom-tools/types";
25
+ import { type LspToolDetails, lspSchema } from "$c/lsp/types";
26
+ import lspDescription from "$c/prompts/tools/lsp.md" with { type: "text" };
27
+ import { createAgentSession, discoverAuthStorage, discoverModels } from "$c/sdk";
28
+ import type { AgentSessionEvent } from "$c/session/agent-session";
29
+ import { AuthStorage } from "$c/session/auth-storage";
30
+ import { SessionManager } from "$c/session/session-manager";
31
+ import { getPythonToolDescription, type PythonToolDetails, type PythonToolParams, pythonSchema } from "$c/tools/python";
32
+ import { ToolAbortError } from "$c/tools/tool-errors";
32
33
  import type {
33
34
  LspToolCallResponse,
34
35
  MCPToolCallResponse,
@@ -88,7 +89,8 @@ function generateLspCallId(): string {
88
89
  }
89
90
 
90
91
  function callMCPToolViaParent(
91
- toolName: string,
92
+ serverName: string,
93
+ mcpToolName: string,
92
94
  params: Record<string, unknown>,
93
95
  signal?: AbortSignal,
94
96
  timeoutMs = MCP_CALL_TIMEOUT_MS,
@@ -99,7 +101,7 @@ function callMCPToolViaParent(
99
101
  }>();
100
102
  const callId = generateMCPCallId();
101
103
  if (signal?.aborted) {
102
- reject(new Error("Aborted"));
104
+ reject(new ToolAbortError());
103
105
  return promise;
104
106
  }
105
107
 
@@ -118,7 +120,7 @@ function callMCPToolViaParent(
118
120
  "abort",
119
121
  () => {
120
122
  cleanup();
121
- reject(new Error("Aborted"));
123
+ reject(new ToolAbortError());
122
124
  },
123
125
  { once: true },
124
126
  );
@@ -139,7 +141,8 @@ function callMCPToolViaParent(
139
141
  postMessageSafe({
140
142
  type: "mcp_tool_call",
141
143
  callId,
142
- toolName,
144
+ serverName,
145
+ mcpToolName,
143
146
  params,
144
147
  timeoutMs,
145
148
  } as SubagentWorkerResponse);
@@ -155,7 +158,7 @@ function callPythonToolViaParent(
155
158
  const { promise, resolve, reject } = Promise.withResolvers<PythonToolCallResponse["result"]>();
156
159
  const callId = generatePythonCallId();
157
160
  if (signal?.aborted) {
158
- reject(new Error("Aborted"));
161
+ reject(new ToolAbortError());
159
162
  return promise;
160
163
  }
161
164
 
@@ -185,7 +188,7 @@ function callPythonToolViaParent(
185
188
  () => {
186
189
  cleanup();
187
190
  sendCancel("Aborted");
188
- reject(new Error("Aborted"));
191
+ reject(new ToolAbortError());
189
192
  },
190
193
  { once: true },
191
194
  );
@@ -221,7 +224,7 @@ function callLspToolViaParent(
221
224
  const { promise, resolve, reject } = Promise.withResolvers<LspToolCallResponse["result"]>();
222
225
  const callId = generateLspCallId();
223
226
  if (signal?.aborted) {
224
- reject(new Error("Aborted"));
227
+ reject(new ToolAbortError());
225
228
  return promise;
226
229
  }
227
230
 
@@ -245,7 +248,7 @@ function callLspToolViaParent(
245
248
  "abort",
246
249
  () => {
247
250
  cleanup();
248
- reject(new Error("Aborted"));
251
+ reject(new ToolAbortError());
249
252
  },
250
253
  { once: true },
251
254
  );
@@ -334,7 +337,8 @@ function createMCPProxyTool(metadata: MCPToolMetadata): CustomTool<TSchema> {
334
337
  execute: async (_toolCallId, params, _onUpdate, _ctx, signal) => {
335
338
  try {
336
339
  const result = await callMCPToolViaParent(
337
- metadata.name,
340
+ metadata.serverName,
341
+ metadata.mcpToolName,
338
342
  params as Record<string, unknown>,
339
343
  signal,
340
344
  metadata.timeoutMs,
@@ -363,7 +367,7 @@ function createMCPProxyTool(metadata: MCPToolMetadata): CustomTool<TSchema> {
363
367
  }
364
368
 
365
369
  function getPythonCallTimeoutMs(params: PythonToolParams): number | undefined {
366
- const timeout = params.timeoutMs;
370
+ const timeout = params.timeout;
367
371
  if (typeof timeout === "number" && Number.isFinite(timeout) && timeout > 0) {
368
372
  return Math.max(1000, Math.round(timeout * 1000) + 1000);
369
373
  }
@@ -530,7 +534,7 @@ async function runTask(runState: RunState, payload: SubagentWorkerStartPayload):
530
534
  if (signal.aborted) {
531
535
  aborted = true;
532
536
  exitCode = 1;
533
- throw new Error("Aborted");
537
+ throw new ToolAbortError();
534
538
  }
535
539
  };
536
540
 
@@ -538,9 +542,6 @@ async function runTask(runState: RunState, payload: SubagentWorkerStartPayload):
538
542
  // Check for pre-start abort
539
543
  checkAbort();
540
544
 
541
- // Set working directory (CLI does this implicitly)
542
- process.chdir(payload.cwd);
543
-
544
545
  // Use serialized auth/models if provided, otherwise discover from disk
545
546
  let authStorage: AuthStorage;
546
547
  let modelRegistry: ModelRegistry;
@@ -574,7 +575,7 @@ async function runTask(runState: RunState, payload: SubagentWorkerStartPayload):
574
575
  // Create session manager (equivalent to CLI's --session or --no-session)
575
576
  const sessionManager = payload.sessionFile
576
577
  ? await SessionManager.open(payload.sessionFile)
577
- : SessionManager.inMemory(payload.cwd);
578
+ : SessionManager.inMemory(payload.worktree ?? payload.cwd);
578
579
  checkAbort();
579
580
 
580
581
  // Use serialized settings if provided, otherwise use empty in-memory settings
@@ -585,9 +586,12 @@ async function runTask(runState: RunState, payload: SubagentWorkerStartPayload):
585
586
  // Note: hasUI: false disables interactive features
586
587
  const completionInstruction =
587
588
  "When finished, call the complete tool exactly once. Do not end with a plain-text final answer.";
589
+ const worktreeNotice = payload.worktree
590
+ ? `You will work under this working tree: ${payload.worktree}. CRITICAL: Do not touch the original repository; only make changes inside this worktree.`
591
+ : "";
588
592
 
589
593
  const { session } = await createAgentSession({
590
- cwd: payload.cwd,
594
+ cwd: payload.worktree ?? payload.cwd,
591
595
  authStorage,
592
596
  modelRegistry,
593
597
  settingsManager,
@@ -597,7 +601,8 @@ async function runTask(runState: RunState, payload: SubagentWorkerStartPayload):
597
601
  outputSchema: payload.outputSchema,
598
602
  requireCompleteTool: true,
599
603
  // Append system prompt (equivalent to CLI's --append-system-prompt)
600
- systemPrompt: (defaultPrompt) => `${defaultPrompt}\n\n${payload.systemPrompt}\n\n${completionInstruction}`,
604
+ systemPrompt: (defaultPrompt) =>
605
+ `${defaultPrompt}\n\n${payload.systemPrompt}\n\n${worktreeNotice}\n\n${completionInstruction}`,
601
606
  sessionManager,
602
607
  hasUI: false,
603
608
  // Pass spawn restrictions to nested tasks
@@ -0,0 +1,166 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { cp, mkdir, rm } from "node:fs/promises";
3
+ import { homedir, tmpdir } from "node:os";
4
+ import path from "node:path";
5
+ import { $ } from "bun";
6
+
7
+ export interface WorktreeBaseline {
8
+ repoRoot: string;
9
+ staged: string;
10
+ unstaged: string;
11
+ untracked: string[];
12
+ }
13
+
14
+ export function getEncodedProjectName(cwd: string): string {
15
+ return `--${cwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
16
+ }
17
+
18
+ export async function getRepoRoot(cwd: string): Promise<string> {
19
+ const result = await $`git rev-parse --show-toplevel`.cwd(cwd).quiet().nothrow();
20
+ if (result.exitCode !== 0) {
21
+ throw new Error("Git repository not found for isolated task execution.");
22
+ }
23
+ const repoRoot = result.text().trim();
24
+ if (!repoRoot) {
25
+ throw new Error("Git repository root could not be resolved for isolated task execution.");
26
+ }
27
+ return repoRoot;
28
+ }
29
+
30
+ export async function ensureWorktree(baseCwd: string, id: string): Promise<string> {
31
+ const repoRoot = await getRepoRoot(baseCwd);
32
+ const encodedProject = getEncodedProjectName(repoRoot);
33
+ const worktreeDir = path.join(homedir(), ".omp", "wt", encodedProject, id);
34
+ await mkdir(path.dirname(worktreeDir), { recursive: true });
35
+ await $`git worktree remove -f ${worktreeDir}`.cwd(repoRoot).quiet().nothrow();
36
+ await rm(worktreeDir, { recursive: true, force: true });
37
+ await $`git worktree add --detach ${worktreeDir} HEAD`.cwd(repoRoot).quiet();
38
+ return worktreeDir;
39
+ }
40
+
41
+ export async function captureBaseline(repoRoot: string): Promise<WorktreeBaseline> {
42
+ const staged = await $`git diff --cached --binary`.cwd(repoRoot).quiet().text();
43
+ const unstaged = await $`git diff --binary`.cwd(repoRoot).quiet().text();
44
+ const untrackedRaw = await $`git ls-files --others --exclude-standard`.cwd(repoRoot).quiet().text();
45
+ const untracked = untrackedRaw
46
+ .split("\n")
47
+ .map((line) => line.trim())
48
+ .filter((line) => line.length > 0);
49
+
50
+ return {
51
+ repoRoot,
52
+ staged,
53
+ unstaged,
54
+ untracked,
55
+ };
56
+ }
57
+
58
+ async function writeTempPatchFile(patch: string): Promise<string> {
59
+ const tempPath = path.join(tmpdir(), `omp-task-patch-${randomUUID()}.patch`);
60
+ await Bun.write(tempPath, patch);
61
+ return tempPath;
62
+ }
63
+
64
+ async function applyPatch(
65
+ cwd: string,
66
+ patch: string,
67
+ options?: { cached?: boolean; env?: Record<string, string> },
68
+ ): Promise<void> {
69
+ if (!patch.trim()) return;
70
+ const tempPath = await writeTempPatchFile(patch);
71
+ try {
72
+ const command = options?.cached ? $`git apply --cached --binary ${tempPath}` : $`git apply --binary ${tempPath}`;
73
+ let runner = command.cwd(cwd).quiet();
74
+ if (options?.env) {
75
+ runner = runner.env(options.env);
76
+ }
77
+ await runner;
78
+ } finally {
79
+ await rm(tempPath, { force: true });
80
+ }
81
+ }
82
+
83
+ export async function applyBaseline(worktreeDir: string, baseline: WorktreeBaseline): Promise<void> {
84
+ await applyPatch(worktreeDir, baseline.staged, { cached: true });
85
+ await applyPatch(worktreeDir, baseline.staged);
86
+ await applyPatch(worktreeDir, baseline.unstaged);
87
+
88
+ for (const entry of baseline.untracked) {
89
+ const source = path.join(baseline.repoRoot, entry);
90
+ const destination = path.join(worktreeDir, entry);
91
+ const exists = await Bun.file(source).exists();
92
+ if (!exists) continue;
93
+ await mkdir(path.dirname(destination), { recursive: true });
94
+ await cp(source, destination, { recursive: true });
95
+ }
96
+ }
97
+
98
+ async function applyPatchToIndex(cwd: string, patch: string, indexFile: string): Promise<void> {
99
+ if (!patch.trim()) return;
100
+ const tempPath = await writeTempPatchFile(patch);
101
+ try {
102
+ await $`git apply --cached --binary ${tempPath}`
103
+ .cwd(cwd)
104
+ .env({
105
+ GIT_INDEX_FILE: indexFile,
106
+ })
107
+ .quiet();
108
+ } finally {
109
+ await rm(tempPath, { force: true });
110
+ }
111
+ }
112
+
113
+ async function listUntracked(cwd: string): Promise<string[]> {
114
+ const raw = await $`git ls-files --others --exclude-standard`.cwd(cwd).quiet().text();
115
+ return raw
116
+ .split("\n")
117
+ .map((line) => line.trim())
118
+ .filter((line) => line.length > 0);
119
+ }
120
+
121
+ export async function captureDeltaPatch(worktreeDir: string, baseline: WorktreeBaseline): Promise<string> {
122
+ const tempIndex = path.join(tmpdir(), `omp-task-index-${randomUUID()}`);
123
+ try {
124
+ await $`git read-tree HEAD`.cwd(worktreeDir).env({
125
+ GIT_INDEX_FILE: tempIndex,
126
+ });
127
+ await applyPatchToIndex(worktreeDir, baseline.staged, tempIndex);
128
+ await applyPatchToIndex(worktreeDir, baseline.unstaged, tempIndex);
129
+ const diff = await $`git diff --binary`
130
+ .cwd(worktreeDir)
131
+ .env({
132
+ GIT_INDEX_FILE: tempIndex,
133
+ })
134
+ .quiet()
135
+ .text();
136
+
137
+ const currentUntracked = await listUntracked(worktreeDir);
138
+ const baselineUntracked = new Set(baseline.untracked);
139
+ const newUntracked = currentUntracked.filter((entry) => !baselineUntracked.has(entry));
140
+
141
+ if (newUntracked.length === 0) return diff;
142
+
143
+ const untrackedDiffs = await Promise.all(
144
+ newUntracked.map((entry) =>
145
+ $`git diff --binary --no-index /dev/null ${entry}`.cwd(worktreeDir).quiet().nothrow().text(),
146
+ ),
147
+ );
148
+ return `${diff}${diff && !diff.endsWith("\n") ? "\n" : ""}${untrackedDiffs.join("\n")}`;
149
+ } finally {
150
+ await rm(tempIndex, { force: true });
151
+ }
152
+ }
153
+
154
+ export async function cleanupWorktree(dir: string): Promise<void> {
155
+ try {
156
+ const commonDirRaw = await $`git rev-parse --git-common-dir`.cwd(dir).quiet().nothrow().text();
157
+ const commonDir = commonDirRaw.trim();
158
+ if (commonDir) {
159
+ const resolvedCommon = path.resolve(dir, commonDir);
160
+ const repoRoot = path.dirname(resolvedCommon);
161
+ await $`git worktree remove -f ${dir}`.cwd(repoRoot).quiet().nothrow();
162
+ }
163
+ } finally {
164
+ await rm(dir, { recursive: true, force: true });
165
+ }
166
+ }
@@ -19,10 +19,10 @@ import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallb
19
19
  import type { Component } from "@oh-my-pi/pi-tui";
20
20
  import { Text } from "@oh-my-pi/pi-tui";
21
21
  import { Type } from "@sinclair/typebox";
22
- import { type Theme, theme } from "../../modes/interactive/theme/theme";
23
- import askDescription from "../../prompts/tools/ask.md" with { type: "text" };
24
- import type { RenderResultOptions } from "../custom-tools/types";
25
- import { renderPromptTemplate } from "../prompt-templates";
22
+ import { renderPromptTemplate } from "$c/config/prompt-templates";
23
+ import type { RenderResultOptions } from "$c/extensibility/custom-tools/types";
24
+ import { type Theme, theme } from "$c/modes/theme/theme";
25
+ import askDescription from "$c/prompts/tools/ask.md" with { type: "text" };
26
26
  import type { ToolSession } from "./index";
27
27
  import { ToolUIKit } from "./render-utils";
28
28
 
@@ -31,29 +31,21 @@ import { ToolUIKit } from "./render-utils";
31
31
  // =============================================================================
32
32
 
33
33
  const OptionItem = Type.Object({
34
- label: Type.String({ description: "Display label for this option" }),
34
+ label: Type.String({ description: "Display label" }),
35
35
  });
36
36
 
37
37
  const QuestionItem = Type.Object({
38
- id: Type.String({ description: "Short identifier for this question (e.g., 'auth', 'cache')" }),
39
- question: Type.String({ description: "The question text" }),
40
- options: Type.Array(OptionItem, { description: "Options for this question" }),
41
- multi: Type.Optional(Type.Boolean({ description: "Allow multiple selections for this question" })),
38
+ id: Type.String({ description: "Question ID, e.g. 'auth', 'cache'" }),
39
+ question: Type.String({ description: "Question text" }),
40
+ options: Type.Array(OptionItem, { description: "Available options" }),
41
+ multi: Type.Optional(Type.Boolean({ description: "Allow multiple selections" })),
42
42
  });
43
43
 
44
44
  const askSchema = Type.Object({
45
- question: Type.Optional(Type.String({ description: "The question to ask the user" })),
46
- options: Type.Optional(Type.Array(OptionItem, { description: "Available options for the user to choose from." })),
47
- multi: Type.Optional(
48
- Type.Boolean({
49
- description: "Allow multiple options to be selected (default: false)",
50
- }),
51
- ),
52
- questions: Type.Optional(
53
- Type.Array(QuestionItem, {
54
- description: "Multiple questions to ask in sequence, each with their own options",
55
- }),
56
- ),
45
+ question: Type.Optional(Type.String({ description: "Question to ask" })),
46
+ options: Type.Optional(Type.Array(OptionItem, { description: "Available options" })),
47
+ multi: Type.Optional(Type.Boolean({ description: "Allow multiple selections (default: false)" })),
48
+ questions: Type.Optional(Type.Array(QuestionItem, { description: "Multiple questions in sequence" })),
57
49
  });
58
50
 
59
51
  /** Result for a single question */
@@ -6,7 +6,7 @@
6
6
  * the specialized tools instead.
7
7
  */
8
8
 
9
- import { type BashInterceptorRule, DEFAULT_BASH_INTERCEPTOR_RULES } from "../settings-manager";
9
+ import { type BashInterceptorRule, DEFAULT_BASH_INTERCEPTOR_RULES } from "$c/config/settings-manager";
10
10
 
11
11
  export interface InterceptionResult {
12
12
  /** If true, the bash command should be blocked */