@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
@@ -1,14 +1,6 @@
1
- export { AskTool, type AskToolDetails } from "./ask";
2
- export { BashTool, type BashToolDetails, type BashToolOptions } from "./bash";
3
- export { CalculatorTool, type CalculatorToolDetails } from "./calculator";
4
- export { CompleteTool } from "./complete";
5
1
  // Exa MCP tools (22 tools)
6
- export { exaTools } from "./exa/index";
7
- export type { ExaRenderDetails, ExaSearchResponse, ExaSearchResult } from "./exa/types";
8
- export { type FindOperations, FindTool, type FindToolDetails, type FindToolOptions } from "./find";
9
- export { setPreferredImageProvider } from "./gemini-image";
10
- export { type GrepOperations, GrepTool, type GrepToolDetails, type GrepToolOptions } from "./grep";
11
- export { type LsOperations, LsTool, type LsToolDetails, type LsToolOptions } from "./ls";
2
+ export { exaTools } from "$c/exa/index";
3
+ export type { ExaRenderDetails, ExaSearchResponse, ExaSearchResult } from "$c/exa/types";
12
4
  export {
13
5
  type FileDiagnosticsResult,
14
6
  type FileFormatResult,
@@ -19,27 +11,9 @@ export {
19
11
  type LspWarmupOptions,
20
12
  type LspWarmupResult,
21
13
  warmupLspServers,
22
- } from "./lsp/index";
23
- export { NotebookTool, type NotebookToolDetails } from "./notebook";
24
- export { OutputTool, type OutputToolDetails } from "./output";
25
- export { EditTool, type EditToolDetails } from "./patch";
26
- export { PythonTool, type PythonToolDetails, type PythonToolOptions } from "./python";
27
- export { ReadTool, type ReadToolDetails } from "./read";
28
- export { reportFindingTool, type SubmitReviewDetails } from "./review";
29
- export { loadSshTool, type SSHToolDetails, SshTool } from "./ssh";
30
- export { BUNDLED_AGENTS, TaskTool } from "./task/index";
31
- export { type TodoItem, TodoWriteTool, type TodoWriteToolDetails } from "./todo-write";
32
- export {
33
- DEFAULT_MAX_BYTES,
34
- DEFAULT_MAX_LINES,
35
- formatSize,
36
- type TruncationOptions,
37
- type TruncationResult,
38
- truncateHead,
39
- truncateLine,
40
- truncateTail,
41
- } from "./truncate";
42
- export { WebFetchTool, type WebFetchToolDetails } from "./web-fetch";
14
+ } from "$c/lsp/index";
15
+ export { EditTool, type EditToolDetails } from "$c/patch";
16
+ export { BUNDLED_AGENTS, TaskTool } from "$c/task/index";
43
17
  export {
44
18
  companyWebSearchTools,
45
19
  exaWebSearchTools,
@@ -57,34 +31,61 @@ export {
57
31
  webSearchCustomTool,
58
32
  webSearchDeepTool,
59
33
  webSearchLinkedinTool,
60
- } from "./web-search/index";
34
+ } from "$c/web/search/index";
35
+ export { AskTool, type AskToolDetails } from "./ask";
36
+ export { BashTool, type BashToolDetails, type BashToolOptions } from "./bash";
37
+ export { CalculatorTool, type CalculatorToolDetails } from "./calculator";
38
+ export { CompleteTool } from "./complete";
39
+ export { FetchTool, type FetchToolDetails } from "./fetch";
40
+ export { type FindOperations, FindTool, type FindToolDetails, type FindToolOptions } from "./find";
41
+ export { setPreferredImageProvider } from "./gemini-image";
42
+ export { type GrepOperations, GrepTool, type GrepToolDetails, type GrepToolOptions } from "./grep";
43
+ export { type LsOperations, LsTool, type LsToolDetails, type LsToolOptions } from "./ls";
44
+ export { NotebookTool, type NotebookToolDetails } from "./notebook";
45
+ export { PythonTool, type PythonToolDetails, type PythonToolOptions } from "./python";
46
+ export { ReadTool, type ReadToolDetails } from "./read";
47
+ export { reportFindingTool, type SubmitReviewDetails } from "./review";
48
+ export { loadSshTool, type SSHToolDetails, SshTool } from "./ssh";
49
+ export { type TodoItem, TodoWriteTool, type TodoWriteToolDetails } from "./todo-write";
50
+ export {
51
+ DEFAULT_MAX_BYTES,
52
+ DEFAULT_MAX_LINES,
53
+ formatSize,
54
+ type TruncationOptions,
55
+ type TruncationResult,
56
+ truncateHead,
57
+ truncateLine,
58
+ truncateTail,
59
+ } from "./truncate";
61
60
  export { WriteTool, type WriteToolDetails } from "./write";
62
61
 
63
62
  import type { AgentTool } from "@oh-my-pi/pi-agent-core";
64
63
  import { logger } from "@oh-my-pi/pi-utils";
65
- import type { EventBus } from "../event-bus";
66
- import { getPreludeDocs, warmPythonEnvironment } from "../python-executor";
67
- import { checkPythonKernelAvailability } from "../python-kernel";
68
- import type { BashInterceptorRule } from "../settings-manager";
64
+ import type { BashInterceptorRule } from "$c/config/settings-manager";
65
+ import type { InternalUrlRouter } from "$c/internal-urls";
66
+ import { getPreludeDocs, warmPythonEnvironment } from "$c/ipy/executor";
67
+ import { checkPythonKernelAvailability } from "$c/ipy/kernel";
68
+ import { LspTool } from "$c/lsp/index";
69
+ import { EditTool } from "$c/patch";
70
+ import type { ArtifactManager } from "$c/session/artifacts";
71
+ import { TaskTool } from "$c/task/index";
72
+ import type { EventBus } from "$c/utils/event-bus";
73
+ import { WebSearchTool } from "$c/web/search/index";
69
74
  import { AskTool } from "./ask";
70
75
  import { BashTool } from "./bash";
71
76
  import { CalculatorTool } from "./calculator";
72
77
  import { CompleteTool } from "./complete";
78
+ import { FetchTool } from "./fetch";
73
79
  import { FindTool } from "./find";
74
80
  import { GrepTool } from "./grep";
75
81
  import { LsTool } from "./ls";
76
- import { LspTool } from "./lsp/index";
77
82
  import { NotebookTool } from "./notebook";
78
- import { OutputTool } from "./output";
79
- import { EditTool } from "./patch";
83
+ import { wrapToolsWithMetaNotice } from "./output-meta";
80
84
  import { PythonTool } from "./python";
81
85
  import { ReadTool } from "./read";
82
86
  import { reportFindingTool } from "./review";
83
87
  import { loadSshTool } from "./ssh";
84
- import { TaskTool } from "./task/index";
85
88
  import { TodoWriteTool } from "./todo-write";
86
- import { WebFetchTool } from "./web-fetch";
87
- import { WebSearchTool } from "./web-search/index";
88
89
  import { WriteTool } from "./write";
89
90
 
90
91
  /** Tool type (AgentTool from pi-ai) */
@@ -106,6 +107,10 @@ export interface ToolSession {
106
107
  requireCompleteTool?: boolean;
107
108
  /** Get session file */
108
109
  getSessionFile: () => string | null;
110
+ /** Cached artifact manager (allocated per ToolSession) */
111
+ artifactManager?: ArtifactManager;
112
+ /** Get artifacts directory for artifact:// URLs and $ARTIFACTS env var */
113
+ getArtifactsDir?: () => string | null;
109
114
  /** Get session spawns */
110
115
  getSessionSpawns: () => string | null;
111
116
  /** Get resolved model string if explicitly set for this session */
@@ -113,13 +118,15 @@ export interface ToolSession {
113
118
  /** Get the current session model string, regardless of how it was chosen */
114
119
  getActiveModelString?: () => string | undefined;
115
120
  /** Auth storage for passing to subagents (avoids re-discovery) */
116
- authStorage?: import("../auth-storage").AuthStorage;
121
+ authStorage?: import("$c/session/auth-storage").AuthStorage;
117
122
  /** Model registry for passing to subagents (avoids re-discovery) */
118
- modelRegistry?: import("../model-registry").ModelRegistry;
123
+ modelRegistry?: import("$c/config/model-registry").ModelRegistry;
119
124
  /** MCP manager for proxying MCP calls through parent */
120
125
  mcpManager?: import("../mcp/manager").MCPManager;
126
+ /** Internal URL router for agent:// and skill:// URLs */
127
+ internalRouter?: InternalUrlRouter;
121
128
  /** Settings manager for passing to subagents (avoids SQLite access in workers) */
122
- settingsManager?: { serialize: () => import("../settings-manager").Settings };
129
+ settingsManager?: { serialize: () => import("$c/config/settings-manager").Settings };
123
130
  /** Settings manager (optional) */
124
131
  settings?: {
125
132
  getImageAutoResize(): boolean;
@@ -153,11 +160,10 @@ export const BUILTIN_TOOLS: Record<string, ToolFactory> = {
153
160
  ls: (s) => new LsTool(s),
154
161
  lsp: LspTool.createIf,
155
162
  notebook: (s) => new NotebookTool(s),
156
- output: (s) => new OutputTool(s),
157
163
  read: (s) => new ReadTool(s),
158
164
  task: TaskTool.create,
159
165
  todo_write: (s) => new TodoWriteTool(s),
160
- web_fetch: (s) => new WebFetchTool(s),
166
+ fetch: (s) => new FetchTool(s),
161
167
  web_search: (s) => new WebSearchTool(s),
162
168
  write: (s) => new WriteTool(s),
163
169
  };
@@ -222,13 +228,13 @@ export async function createTools(session: ToolSession, toolNames?: string[]): P
222
228
  } else if (!isTestEnv && getPreludeDocs().length === 0) {
223
229
  const sessionFile = session.getSessionFile?.() ?? undefined;
224
230
  const warmSessionId = sessionFile ? `session:${sessionFile}:cwd:${session.cwd}` : `cwd:${session.cwd}`;
225
- void warmPythonEnvironment(session.cwd, warmSessionId, session.settings?.getPythonSharedGateway?.()).catch(
226
- (err) => {
227
- logger.warn("Failed to warm Python environment", {
228
- error: err instanceof Error ? err.message : String(err),
229
- });
230
- },
231
- );
231
+ try {
232
+ await warmPythonEnvironment(session.cwd, warmSessionId, session.settings?.getPythonSharedGateway?.());
233
+ } catch (err) {
234
+ logger.warn("Failed to warm Python environment", {
235
+ error: err instanceof Error ? err.message : String(err),
236
+ });
237
+ }
232
238
  }
233
239
  }
234
240
 
@@ -266,11 +272,12 @@ export async function createTools(session: ToolSession, toolNames?: string[]): P
266
272
  ];
267
273
  const results = await Promise.all(entries.map(([, factory]) => factory(session)));
268
274
  const tools = results.filter((t): t is Tool => t !== null);
275
+ const wrappedTools = wrapToolsWithMetaNotice(tools);
269
276
 
270
277
  if (filteredRequestedTools !== undefined) {
271
278
  const allowed = new Set(filteredRequestedTools);
272
- return tools.filter((tool) => allowed.has(tool.name));
279
+ return wrappedTools.filter((tool) => allowed.has(tool.name));
273
280
  }
274
281
 
275
- return tools;
282
+ return wrappedTools;
276
283
  }
@@ -0,0 +1,40 @@
1
+ import type { LimitsMeta } from "$c/tools/output-meta";
2
+
3
+ export interface ListLimitResult<T> {
4
+ items: T[];
5
+ limitReached?: number;
6
+ meta: Partial<LimitsMeta>;
7
+ }
8
+
9
+ export interface ListLimitOptions {
10
+ limit?: number;
11
+ headLimit?: number;
12
+ limitType?: "match" | "result";
13
+ }
14
+
15
+ export function applyListLimit<T>(items: T[], options: ListLimitOptions): ListLimitResult<T> {
16
+ const meta: Partial<LimitsMeta> = {};
17
+ const limitType = options.limitType ?? "result";
18
+ const effectiveLimit = options.limit !== undefined && options.limit > 0 ? options.limit : undefined;
19
+ const effectiveHeadLimit = options.headLimit !== undefined && options.headLimit > 0 ? options.headLimit : undefined;
20
+ let limited = items;
21
+ let limitReached: number | undefined;
22
+
23
+ if (effectiveLimit !== undefined && items.length >= effectiveLimit) {
24
+ limited = items.slice(0, effectiveLimit);
25
+ limitReached = effectiveLimit;
26
+ const suggestion = effectiveLimit * 2;
27
+ if (limitType === "match") {
28
+ meta.matchLimit = { reached: effectiveLimit, suggestion };
29
+ } else {
30
+ meta.resultLimit = { reached: effectiveLimit, suggestion };
31
+ }
32
+ }
33
+
34
+ if (effectiveHeadLimit !== undefined && limited.length > effectiveHeadLimit) {
35
+ limited = limited.slice(0, effectiveHeadLimit);
36
+ meta.headLimit = { reached: effectiveHeadLimit, suggestion: effectiveHeadLimit * 2 };
37
+ }
38
+
39
+ return { items: limited, limitReached, meta };
40
+ }
@@ -3,9 +3,12 @@ import type { AgentTool, AgentToolResult } from "@oh-my-pi/pi-agent-core";
3
3
  import { type Component, Text } from "@oh-my-pi/pi-tui";
4
4
  import { untilAborted } from "@oh-my-pi/pi-utils";
5
5
  import { Type } from "@sinclair/typebox";
6
- import { getLanguageFromPath, type Theme } from "../../modes/interactive/theme/theme";
7
- import type { RenderResultOptions } from "../custom-tools/types";
6
+ import type { RenderResultOptions } from "$c/extensibility/custom-tools/types";
7
+ import { getLanguageFromPath, type Theme } from "$c/modes/theme/theme";
8
+ import type { OutputMeta } from "$c/tools/output-meta";
9
+ import { ToolError, throwIfAborted } from "$c/tools/tool-errors";
8
10
  import type { ToolSession } from "./index";
11
+ import { applyListLimit } from "./list-limit";
9
12
  import { resolveToCwd } from "./path-utils";
10
13
  import {
11
14
  formatAge,
@@ -19,7 +22,8 @@ import {
19
22
  formatTruncationSuffix,
20
23
  PREVIEW_LIMITS,
21
24
  } from "./render-utils";
22
- import { DEFAULT_MAX_BYTES, formatSize, type TruncationResult, truncateHead } from "./truncate";
25
+ import { toolResult } from "./tool-result";
26
+ import { type TruncationResult, truncateHead } from "./truncate";
23
27
 
24
28
  const lsSchema = Type.Object({
25
29
  path: Type.Optional(Type.String({ description: "Directory to list (default: current directory)" })),
@@ -46,11 +50,14 @@ export interface LsToolOptions {
46
50
 
47
51
  export interface LsToolDetails {
48
52
  entries?: string[];
53
+ /** Raw entry names (with / suffix for dirs) without age suffix, for icon detection */
54
+ rawEntries?: string[];
49
55
  dirCount?: number;
50
56
  fileCount?: number;
51
57
  truncation?: TruncationResult;
52
58
  truncationReasons?: Array<"entryLimit" | "byteLimit">;
53
59
  entryLimitReached?: number;
60
+ meta?: OutputMeta;
54
61
  }
55
62
 
56
63
  /** Default operations using Bun APIs */
@@ -95,11 +102,11 @@ export class LsTool implements AgentTool<typeof lsSchema, LsToolDetails> {
95
102
  // Check if path exists and is a directory
96
103
  const dirStat = await this.ops.stat(dirPath);
97
104
  if (!dirStat) {
98
- throw new Error(`Path not found: ${dirPath}`);
105
+ throw new ToolError(`Path not found: ${dirPath}`);
99
106
  }
100
107
 
101
108
  if (!dirStat.isDirectory()) {
102
- throw new Error(`Not a directory: ${dirPath}`);
109
+ throw new ToolError(`Not a directory: ${dirPath}`);
103
110
  }
104
111
 
105
112
  // Read directory entries
@@ -108,25 +115,24 @@ export class LsTool implements AgentTool<typeof lsSchema, LsToolDetails> {
108
115
  entries = await this.ops.readdir(dirPath);
109
116
  } catch (error) {
110
117
  const message = error instanceof Error ? error.message : String(error);
111
- throw new Error(`Cannot read directory: ${message}`);
118
+ throw new ToolError(`Cannot read directory: ${message}`);
112
119
  }
113
120
 
114
121
  // Sort alphabetically (case-insensitive)
115
122
  entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
116
123
 
124
+ const listLimit = applyListLimit(entries, { limit: effectiveLimit });
125
+ const limitedEntries = listLimit.items;
126
+ const limitMeta = listLimit.meta;
127
+
117
128
  // Format entries with directory indicators
118
129
  const results: string[] = [];
119
- let entryLimitReached = false;
130
+ const rawResults: string[] = [];
120
131
  let dirCount = 0;
121
132
  let fileCount = 0;
122
133
 
123
- for (const entry of entries) {
124
- signal?.throwIfAborted();
125
- if (results.length >= effectiveLimit) {
126
- entryLimitReached = true;
127
- break;
128
- }
129
-
134
+ for (const entry of limitedEntries) {
135
+ throwIfAborted(signal);
130
136
  const fullPath = nodePath.join(dirPath, entry);
131
137
  let suffix = "";
132
138
  let age = "";
@@ -150,6 +156,7 @@ export class LsTool implements AgentTool<typeof lsSchema, LsToolDetails> {
150
156
  // Format: "name/ (2d ago)" or "name (just now)"
151
157
  const line = age ? `${entry}${suffix} (${age})` : entry + suffix;
152
158
  results.push(line);
159
+ rawResults.push(entry + suffix);
153
160
  }
154
161
 
155
162
  if (results.length === 0) {
@@ -160,25 +167,21 @@ export class LsTool implements AgentTool<typeof lsSchema, LsToolDetails> {
160
167
  const rawOutput = results.join("\n");
161
168
  const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });
162
169
 
163
- let output = truncation.content;
170
+ const output = truncation.content;
164
171
  const details: LsToolDetails = {
165
172
  entries: results,
173
+ rawEntries: rawResults,
166
174
  dirCount,
167
175
  fileCount,
168
176
  };
169
177
  const truncationReasons: Array<"entryLimit" | "byteLimit"> = [];
170
178
 
171
- // Build notices
172
- const notices: string[] = [];
173
-
174
- if (entryLimitReached) {
175
- notices.push(`${effectiveLimit} entries limit reached. Use limit=${effectiveLimit * 2} for more`);
176
- details.entryLimitReached = effectiveLimit;
179
+ if (limitMeta.resultLimit) {
180
+ details.entryLimitReached = limitMeta.resultLimit.reached;
177
181
  truncationReasons.push("entryLimit");
178
182
  }
179
183
 
180
184
  if (truncation.truncated) {
181
- notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);
182
185
  details.truncation = truncation;
183
186
  truncationReasons.push("byteLimit");
184
187
  }
@@ -187,14 +190,12 @@ export class LsTool implements AgentTool<typeof lsSchema, LsToolDetails> {
187
190
  details.truncationReasons = truncationReasons;
188
191
  }
189
192
 
190
- if (notices.length > 0) {
191
- output += `\n\n[${notices.join(". ")}]`;
193
+ const resultBuilder = toolResult(details).text(output).limits({ resultLimit: limitMeta.resultLimit?.reached });
194
+ if (truncation.truncated) {
195
+ resultBuilder.truncation(truncation, { direction: "head" });
192
196
  }
193
197
 
194
- return {
195
- content: [{ type: "text", text: output }],
196
- details,
197
- };
198
+ return resultBuilder.done();
198
199
  });
199
200
  }
200
201
  }
@@ -243,9 +244,11 @@ export const lsToolRenderer = {
243
244
  }
244
245
 
245
246
  let entries: string[] = details?.entries ? [...details.entries] : [];
247
+ let rawEntries: string[] | undefined = details?.rawEntries;
246
248
  if (entries.length === 0) {
247
249
  const rawLines = textContent.split("\n").filter((l: string) => l.trim());
248
250
  entries = rawLines.filter((line) => !/^\[.*\]$/.test(line.trim()));
251
+ rawEntries = undefined; // Can't reliably extract raw paths from text
249
252
  }
250
253
 
251
254
  if (entries.length === 0) {
@@ -266,7 +269,9 @@ export const lsToolRenderer = {
266
269
  }
267
270
  }
268
271
 
269
- const truncated = Boolean(details?.truncation?.truncated || details?.entryLimitReached);
272
+ const truncation = details?.meta?.truncation;
273
+ const limits = details?.meta?.limits;
274
+ const truncated = Boolean(details?.entryLimitReached || truncation || limits?.resultLimit || limits?.headLimit);
270
275
  const icon = truncated
271
276
  ? uiTheme.styledSymbol("status.warning", "warning")
272
277
  : uiTheme.styledSymbol("status.success", "success");
@@ -281,21 +286,25 @@ export const lsToolRenderer = {
281
286
  let text = ` ${icon} ${uiTheme.fg("dim", summaryText)}${formatTruncationSuffix(truncated, uiTheme)}${expandHint}`;
282
287
 
283
288
  const truncationReasons: string[] = [];
284
- if (details?.entryLimitReached) {
285
- truncationReasons.push(`entry limit ${details.entryLimitReached}`);
289
+ if (limits?.resultLimit) {
290
+ truncationReasons.push(`entry limit ${limits.resultLimit.reached}`);
291
+ }
292
+ if (truncation) {
293
+ truncationReasons.push(`output cap ${formatBytes(truncation.outputBytes)}`);
286
294
  }
287
- if (details?.truncation?.truncated) {
288
- truncationReasons.push(`output cap ${formatBytes(details.truncation.maxBytes)}`);
295
+ if (truncation?.artifactId) {
296
+ truncationReasons.push(`full output: artifact://${truncation.artifactId}`);
289
297
  }
290
298
 
291
299
  const hasTruncation = truncationReasons.length > 0;
292
300
 
293
301
  for (let i = 0; i < maxEntries; i++) {
294
302
  const entry = entries[i];
303
+ const rawEntry = rawEntries?.[i] ?? entry;
295
304
  const isLast = i === maxEntries - 1 && !hasMoreEntries && !hasTruncation;
296
305
  const branch = isLast ? uiTheme.tree.last : uiTheme.tree.branch;
297
- const isDir = entry.endsWith("/");
298
- const entryPath = isDir ? entry.slice(0, -1) : entry;
306
+ const isDir = rawEntry.endsWith("/");
307
+ const entryPath = isDir ? rawEntry.slice(0, -1) : rawEntry;
299
308
  const lang = isDir ? undefined : getLanguageFromPath(entryPath);
300
309
  const entryIcon = isDir
301
310
  ? uiTheme.fg("accent", uiTheme.icon.folder)
@@ -4,9 +4,9 @@ import type { Component } from "@oh-my-pi/pi-tui";
4
4
  import { Text } from "@oh-my-pi/pi-tui";
5
5
  import { untilAborted } from "@oh-my-pi/pi-utils";
6
6
  import { type Static, Type } from "@sinclair/typebox";
7
- import type { Theme } from "../../modes/interactive/theme/theme";
8
- import type { RenderResultOptions } from "../custom-tools/types";
9
- import type { ToolSession } from "../sdk";
7
+ import type { RenderResultOptions } from "$c/extensibility/custom-tools/types";
8
+ import type { Theme } from "$c/modes/theme/theme";
9
+ import type { ToolSession } from "$c/sdk";
10
10
  import { resolveToCwd } from "./path-utils";
11
11
  import {
12
12
  formatCount,