@oh-my-pi/pi-coding-agent 7.0.0 → 8.0.1

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 (503) 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 +12 -11
  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/tsconfig.json +25 -0
  268. package/scripts/migrate-sessions.sh +0 -93
  269. package/src/core/index.ts +0 -56
  270. package/src/core/python-prelude.ts +0 -3
  271. package/src/core/ssh-executor.ts +0 -5
  272. package/src/core/streaming-output.ts +0 -115
  273. package/src/core/tools/output.ts +0 -519
  274. package/src/core/tools/read.ts +0 -717
  275. package/src/core/tools/task/template.ts +0 -37
  276. package/src/prompts/tools/output.md +0 -47
  277. package/src/prompts/tools/web-fetch.md +0 -9
  278. package/src/vendor/photon/photon_rs_bg.wasm.b64.js +0 -1
  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/python-prelude.py → ipy/prelude.py} +0 -0
  299. /package/src/{core/tools/lsp → lsp}/defaults.json +0 -0
  300. /package/src/{core/tools/lsp → lsp}/edits.ts +0 -0
  301. /package/src/{core/tools/lsp → lsp}/lspmux.ts +0 -0
  302. /package/src/{core/tools/lsp → lsp}/rust-analyzer.ts +0 -0
  303. /package/src/{core/mcp → mcp}/client.ts +0 -0
  304. /package/src/{core/mcp → mcp}/index.ts +0 -0
  305. /package/src/{core/mcp → mcp}/json-rpc.ts +0 -0
  306. /package/src/{core/mcp → mcp}/transports/index.ts +0 -0
  307. /package/src/modes/{interactive/components → components}/countdown-timer.ts +0 -0
  308. /package/src/modes/{interactive/components → components}/custom-editor.ts +0 -0
  309. /package/src/modes/{interactive/components → components}/extensions/index.ts +0 -0
  310. /package/src/modes/{interactive/components → components}/index.ts +0 -0
  311. /package/src/modes/{interactive/components → components}/status-line/index.ts +0 -0
  312. /package/src/modes/{interactive/components → components}/status-line/presets.ts +0 -0
  313. /package/src/modes/{interactive/components → components}/visual-truncate.ts +0 -0
  314. /package/src/modes/{interactive/theme → theme}/dark.json +0 -0
  315. /package/src/modes/{interactive/theme → theme}/defaults/alabaster.json +0 -0
  316. /package/src/modes/{interactive/theme → theme}/defaults/amethyst.json +0 -0
  317. /package/src/modes/{interactive/theme → theme}/defaults/anthracite.json +0 -0
  318. /package/src/modes/{interactive/theme → theme}/defaults/basalt.json +0 -0
  319. /package/src/modes/{interactive/theme → theme}/defaults/birch.json +0 -0
  320. /package/src/modes/{interactive/theme → theme}/defaults/dark-abyss.json +0 -0
  321. /package/src/modes/{interactive/theme → theme}/defaults/dark-arctic.json +0 -0
  322. /package/src/modes/{interactive/theme → theme}/defaults/dark-aurora.json +0 -0
  323. /package/src/modes/{interactive/theme → theme}/defaults/dark-catppuccin.json +0 -0
  324. /package/src/modes/{interactive/theme → theme}/defaults/dark-cavern.json +0 -0
  325. /package/src/modes/{interactive/theme → theme}/defaults/dark-copper.json +0 -0
  326. /package/src/modes/{interactive/theme → theme}/defaults/dark-cosmos.json +0 -0
  327. /package/src/modes/{interactive/theme → theme}/defaults/dark-cyberpunk.json +0 -0
  328. /package/src/modes/{interactive/theme → theme}/defaults/dark-dracula.json +0 -0
  329. /package/src/modes/{interactive/theme → theme}/defaults/dark-eclipse.json +0 -0
  330. /package/src/modes/{interactive/theme → theme}/defaults/dark-ember.json +0 -0
  331. /package/src/modes/{interactive/theme → theme}/defaults/dark-equinox.json +0 -0
  332. /package/src/modes/{interactive/theme → theme}/defaults/dark-forest.json +0 -0
  333. /package/src/modes/{interactive/theme → theme}/defaults/dark-github.json +0 -0
  334. /package/src/modes/{interactive/theme → theme}/defaults/dark-gruvbox.json +0 -0
  335. /package/src/modes/{interactive/theme → theme}/defaults/dark-lavender.json +0 -0
  336. /package/src/modes/{interactive/theme → theme}/defaults/dark-lunar.json +0 -0
  337. /package/src/modes/{interactive/theme → theme}/defaults/dark-midnight.json +0 -0
  338. /package/src/modes/{interactive/theme → theme}/defaults/dark-monochrome.json +0 -0
  339. /package/src/modes/{interactive/theme → theme}/defaults/dark-monokai.json +0 -0
  340. /package/src/modes/{interactive/theme → theme}/defaults/dark-nebula.json +0 -0
  341. /package/src/modes/{interactive/theme → theme}/defaults/dark-nord.json +0 -0
  342. /package/src/modes/{interactive/theme → theme}/defaults/dark-ocean.json +0 -0
  343. /package/src/modes/{interactive/theme → theme}/defaults/dark-one.json +0 -0
  344. /package/src/modes/{interactive/theme → theme}/defaults/dark-rainforest.json +0 -0
  345. /package/src/modes/{interactive/theme → theme}/defaults/dark-reef.json +0 -0
  346. /package/src/modes/{interactive/theme → theme}/defaults/dark-retro.json +0 -0
  347. /package/src/modes/{interactive/theme → theme}/defaults/dark-rose-pine.json +0 -0
  348. /package/src/modes/{interactive/theme → theme}/defaults/dark-sakura.json +0 -0
  349. /package/src/modes/{interactive/theme → theme}/defaults/dark-slate.json +0 -0
  350. /package/src/modes/{interactive/theme → theme}/defaults/dark-solarized.json +0 -0
  351. /package/src/modes/{interactive/theme → theme}/defaults/dark-solstice.json +0 -0
  352. /package/src/modes/{interactive/theme → theme}/defaults/dark-starfall.json +0 -0
  353. /package/src/modes/{interactive/theme → theme}/defaults/dark-sunset.json +0 -0
  354. /package/src/modes/{interactive/theme → theme}/defaults/dark-swamp.json +0 -0
  355. /package/src/modes/{interactive/theme → theme}/defaults/dark-synthwave.json +0 -0
  356. /package/src/modes/{interactive/theme → theme}/defaults/dark-taiga.json +0 -0
  357. /package/src/modes/{interactive/theme → theme}/defaults/dark-terminal.json +0 -0
  358. /package/src/modes/{interactive/theme → theme}/defaults/dark-tokyo-night.json +0 -0
  359. /package/src/modes/{interactive/theme → theme}/defaults/dark-tundra.json +0 -0
  360. /package/src/modes/{interactive/theme → theme}/defaults/dark-twilight.json +0 -0
  361. /package/src/modes/{interactive/theme → theme}/defaults/dark-volcanic.json +0 -0
  362. /package/src/modes/{interactive/theme → theme}/defaults/graphite.json +0 -0
  363. /package/src/modes/{interactive/theme → theme}/defaults/index.ts +0 -0
  364. /package/src/modes/{interactive/theme → theme}/defaults/light-arctic.json +0 -0
  365. /package/src/modes/{interactive/theme → theme}/defaults/light-aurora-day.json +0 -0
  366. /package/src/modes/{interactive/theme → theme}/defaults/light-canyon.json +0 -0
  367. /package/src/modes/{interactive/theme → theme}/defaults/light-catppuccin.json +0 -0
  368. /package/src/modes/{interactive/theme → theme}/defaults/light-cirrus.json +0 -0
  369. /package/src/modes/{interactive/theme → theme}/defaults/light-coral.json +0 -0
  370. /package/src/modes/{interactive/theme → theme}/defaults/light-cyberpunk.json +0 -0
  371. /package/src/modes/{interactive/theme → theme}/defaults/light-dawn.json +0 -0
  372. /package/src/modes/{interactive/theme → theme}/defaults/light-dunes.json +0 -0
  373. /package/src/modes/{interactive/theme → theme}/defaults/light-eucalyptus.json +0 -0
  374. /package/src/modes/{interactive/theme → theme}/defaults/light-forest.json +0 -0
  375. /package/src/modes/{interactive/theme → theme}/defaults/light-frost.json +0 -0
  376. /package/src/modes/{interactive/theme → theme}/defaults/light-github.json +0 -0
  377. /package/src/modes/{interactive/theme → theme}/defaults/light-glacier.json +0 -0
  378. /package/src/modes/{interactive/theme → theme}/defaults/light-gruvbox.json +0 -0
  379. /package/src/modes/{interactive/theme → theme}/defaults/light-haze.json +0 -0
  380. /package/src/modes/{interactive/theme → theme}/defaults/light-honeycomb.json +0 -0
  381. /package/src/modes/{interactive/theme → theme}/defaults/light-lagoon.json +0 -0
  382. /package/src/modes/{interactive/theme → theme}/defaults/light-lavender.json +0 -0
  383. /package/src/modes/{interactive/theme → theme}/defaults/light-meadow.json +0 -0
  384. /package/src/modes/{interactive/theme → theme}/defaults/light-mint.json +0 -0
  385. /package/src/modes/{interactive/theme → theme}/defaults/light-monochrome.json +0 -0
  386. /package/src/modes/{interactive/theme → theme}/defaults/light-ocean.json +0 -0
  387. /package/src/modes/{interactive/theme → theme}/defaults/light-one.json +0 -0
  388. /package/src/modes/{interactive/theme → theme}/defaults/light-opal.json +0 -0
  389. /package/src/modes/{interactive/theme → theme}/defaults/light-orchard.json +0 -0
  390. /package/src/modes/{interactive/theme → theme}/defaults/light-paper.json +0 -0
  391. /package/src/modes/{interactive/theme → theme}/defaults/light-prism.json +0 -0
  392. /package/src/modes/{interactive/theme → theme}/defaults/light-retro.json +0 -0
  393. /package/src/modes/{interactive/theme → theme}/defaults/light-sand.json +0 -0
  394. /package/src/modes/{interactive/theme → theme}/defaults/light-savanna.json +0 -0
  395. /package/src/modes/{interactive/theme → theme}/defaults/light-solarized.json +0 -0
  396. /package/src/modes/{interactive/theme → theme}/defaults/light-soleil.json +0 -0
  397. /package/src/modes/{interactive/theme → theme}/defaults/light-sunset.json +0 -0
  398. /package/src/modes/{interactive/theme → theme}/defaults/light-synthwave.json +0 -0
  399. /package/src/modes/{interactive/theme → theme}/defaults/light-tokyo-night.json +0 -0
  400. /package/src/modes/{interactive/theme → theme}/defaults/light-wetland.json +0 -0
  401. /package/src/modes/{interactive/theme → theme}/defaults/light-zenith.json +0 -0
  402. /package/src/modes/{interactive/theme → theme}/defaults/limestone.json +0 -0
  403. /package/src/modes/{interactive/theme → theme}/defaults/mahogany.json +0 -0
  404. /package/src/modes/{interactive/theme → theme}/defaults/marble.json +0 -0
  405. /package/src/modes/{interactive/theme → theme}/defaults/obsidian.json +0 -0
  406. /package/src/modes/{interactive/theme → theme}/defaults/onyx.json +0 -0
  407. /package/src/modes/{interactive/theme → theme}/defaults/pearl.json +0 -0
  408. /package/src/modes/{interactive/theme → theme}/defaults/porcelain.json +0 -0
  409. /package/src/modes/{interactive/theme → theme}/defaults/quartz.json +0 -0
  410. /package/src/modes/{interactive/theme → theme}/defaults/sandstone.json +0 -0
  411. /package/src/modes/{interactive/theme → theme}/defaults/titanium.json +0 -0
  412. /package/src/modes/{interactive/theme → theme}/light.json +0 -0
  413. /package/src/modes/{interactive/theme → theme}/theme-schema.json +0 -0
  414. /package/src/{core/tools/patch → patch}/fuzzy.ts +0 -0
  415. /package/src/{core/tools/patch → patch}/normalize.ts +0 -0
  416. /package/src/{core/tools/patch → patch}/normative.ts +0 -0
  417. /package/src/{core/tools/patch → patch}/parser.ts +0 -0
  418. /package/src/{core/tools/patch → patch}/types.ts +0 -0
  419. /package/src/{core → session}/compaction/index.ts +0 -0
  420. /package/src/{core → session}/session-storage.ts +0 -0
  421. /package/src/{core/tools/task → task}/name-generator.ts +0 -0
  422. /package/src/{core/tools/task → task}/omp-command.ts +0 -0
  423. /package/src/{core/tools/task → task}/parallel.ts +0 -0
  424. /package/src/{core/tools → tools}/jtd-to-json-schema.ts +0 -0
  425. /package/src/{core/tools → tools}/path-utils.ts +0 -0
  426. /package/src/{core → utils}/event-bus.ts +0 -0
  427. /package/src/{core → utils}/frontmatter.ts +0 -0
  428. /package/src/{core → utils}/terminal-notify.ts +0 -0
  429. /package/src/{core → utils}/timings.ts +0 -0
  430. /package/src/{core → utils}/utils.ts +0 -0
  431. /package/src/{core/tools/web-scrapers → web/scrapers}/artifacthub.ts +0 -0
  432. /package/src/{core/tools/web-scrapers → web/scrapers}/arxiv.ts +0 -0
  433. /package/src/{core/tools/web-scrapers → web/scrapers}/aur.ts +0 -0
  434. /package/src/{core/tools/web-scrapers → web/scrapers}/biorxiv.ts +0 -0
  435. /package/src/{core/tools/web-scrapers → web/scrapers}/bluesky.ts +0 -0
  436. /package/src/{core/tools/web-scrapers → web/scrapers}/brew.ts +0 -0
  437. /package/src/{core/tools/web-scrapers → web/scrapers}/cheatsh.ts +0 -0
  438. /package/src/{core/tools/web-scrapers → web/scrapers}/chocolatey.ts +0 -0
  439. /package/src/{core/tools/web-scrapers → web/scrapers}/cisa-kev.ts +0 -0
  440. /package/src/{core/tools/web-scrapers → web/scrapers}/clojars.ts +0 -0
  441. /package/src/{core/tools/web-scrapers → web/scrapers}/coingecko.ts +0 -0
  442. /package/src/{core/tools/web-scrapers → web/scrapers}/crates-io.ts +0 -0
  443. /package/src/{core/tools/web-scrapers → web/scrapers}/crossref.ts +0 -0
  444. /package/src/{core/tools/web-scrapers → web/scrapers}/devto.ts +0 -0
  445. /package/src/{core/tools/web-scrapers → web/scrapers}/discogs.ts +0 -0
  446. /package/src/{core/tools/web-scrapers → web/scrapers}/discourse.ts +0 -0
  447. /package/src/{core/tools/web-scrapers → web/scrapers}/dockerhub.ts +0 -0
  448. /package/src/{core/tools/web-scrapers → web/scrapers}/fdroid.ts +0 -0
  449. /package/src/{core/tools/web-scrapers → web/scrapers}/firefox-addons.ts +0 -0
  450. /package/src/{core/tools/web-scrapers → web/scrapers}/flathub.ts +0 -0
  451. /package/src/{core/tools/web-scrapers → web/scrapers}/github-gist.ts +0 -0
  452. /package/src/{core/tools/web-scrapers → web/scrapers}/github.ts +0 -0
  453. /package/src/{core/tools/web-scrapers → web/scrapers}/gitlab.ts +0 -0
  454. /package/src/{core/tools/web-scrapers → web/scrapers}/go-pkg.ts +0 -0
  455. /package/src/{core/tools/web-scrapers → web/scrapers}/hackage.ts +0 -0
  456. /package/src/{core/tools/web-scrapers → web/scrapers}/hackernews.ts +0 -0
  457. /package/src/{core/tools/web-scrapers → web/scrapers}/hex.ts +0 -0
  458. /package/src/{core/tools/web-scrapers → web/scrapers}/huggingface.ts +0 -0
  459. /package/src/{core/tools/web-scrapers → web/scrapers}/iacr.ts +0 -0
  460. /package/src/{core/tools/web-scrapers → web/scrapers}/index.ts +0 -0
  461. /package/src/{core/tools/web-scrapers → web/scrapers}/jetbrains-marketplace.ts +0 -0
  462. /package/src/{core/tools/web-scrapers → web/scrapers}/lemmy.ts +0 -0
  463. /package/src/{core/tools/web-scrapers → web/scrapers}/lobsters.ts +0 -0
  464. /package/src/{core/tools/web-scrapers → web/scrapers}/mastodon.ts +0 -0
  465. /package/src/{core/tools/web-scrapers → web/scrapers}/maven.ts +0 -0
  466. /package/src/{core/tools/web-scrapers → web/scrapers}/mdn.ts +0 -0
  467. /package/src/{core/tools/web-scrapers → web/scrapers}/metacpan.ts +0 -0
  468. /package/src/{core/tools/web-scrapers → web/scrapers}/musicbrainz.ts +0 -0
  469. /package/src/{core/tools/web-scrapers → web/scrapers}/npm.ts +0 -0
  470. /package/src/{core/tools/web-scrapers → web/scrapers}/nuget.ts +0 -0
  471. /package/src/{core/tools/web-scrapers → web/scrapers}/nvd.ts +0 -0
  472. /package/src/{core/tools/web-scrapers → web/scrapers}/ollama.ts +0 -0
  473. /package/src/{core/tools/web-scrapers → web/scrapers}/open-vsx.ts +0 -0
  474. /package/src/{core/tools/web-scrapers → web/scrapers}/opencorporates.ts +0 -0
  475. /package/src/{core/tools/web-scrapers → web/scrapers}/openlibrary.ts +0 -0
  476. /package/src/{core/tools/web-scrapers → web/scrapers}/orcid.ts +0 -0
  477. /package/src/{core/tools/web-scrapers → web/scrapers}/osv.ts +0 -0
  478. /package/src/{core/tools/web-scrapers → web/scrapers}/packagist.ts +0 -0
  479. /package/src/{core/tools/web-scrapers → web/scrapers}/pub-dev.ts +0 -0
  480. /package/src/{core/tools/web-scrapers → web/scrapers}/pubmed.ts +0 -0
  481. /package/src/{core/tools/web-scrapers → web/scrapers}/pypi.ts +0 -0
  482. /package/src/{core/tools/web-scrapers → web/scrapers}/rawg.ts +0 -0
  483. /package/src/{core/tools/web-scrapers → web/scrapers}/readthedocs.ts +0 -0
  484. /package/src/{core/tools/web-scrapers → web/scrapers}/reddit.ts +0 -0
  485. /package/src/{core/tools/web-scrapers → web/scrapers}/repology.ts +0 -0
  486. /package/src/{core/tools/web-scrapers → web/scrapers}/rfc.ts +0 -0
  487. /package/src/{core/tools/web-scrapers → web/scrapers}/rubygems.ts +0 -0
  488. /package/src/{core/tools/web-scrapers → web/scrapers}/searchcode.ts +0 -0
  489. /package/src/{core/tools/web-scrapers → web/scrapers}/sec-edgar.ts +0 -0
  490. /package/src/{core/tools/web-scrapers → web/scrapers}/semantic-scholar.ts +0 -0
  491. /package/src/{core/tools/web-scrapers → web/scrapers}/snapcraft.ts +0 -0
  492. /package/src/{core/tools/web-scrapers → web/scrapers}/sourcegraph.ts +0 -0
  493. /package/src/{core/tools/web-scrapers → web/scrapers}/spdx.ts +0 -0
  494. /package/src/{core/tools/web-scrapers → web/scrapers}/spotify.ts +0 -0
  495. /package/src/{core/tools/web-scrapers → web/scrapers}/stackoverflow.ts +0 -0
  496. /package/src/{core/tools/web-scrapers → web/scrapers}/terraform.ts +0 -0
  497. /package/src/{core/tools/web-scrapers → web/scrapers}/tldr.ts +0 -0
  498. /package/src/{core/tools/web-scrapers → web/scrapers}/vimeo.ts +0 -0
  499. /package/src/{core/tools/web-scrapers → web/scrapers}/vscode-marketplace.ts +0 -0
  500. /package/src/{core/tools/web-scrapers → web/scrapers}/w3c.ts +0 -0
  501. /package/src/{core/tools/web-scrapers → web/scrapers}/wikidata.ts +0 -0
  502. /package/src/{core/tools/web-scrapers → web/scrapers}/wikipedia.ts +0 -0
  503. /package/src/{core/tools/web-search → web/search}/types.ts +0 -0
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Internal URL router for resolving agent:// and skill:// URLs.
3
+ */
4
+
5
+ import type { InternalResource, InternalUrl, ProtocolHandler } from "./types";
6
+
7
+ /**
8
+ * Router for internal URL schemes.
9
+ *
10
+ * Dispatches URLs like `agent://output_id` or `skill://skill-name` to
11
+ * registered protocol handlers.
12
+ */
13
+ export class InternalUrlRouter {
14
+ private handlers = new Map<string, ProtocolHandler>();
15
+
16
+ /**
17
+ * Register a protocol handler.
18
+ * @param handler Handler to register (uses handler.scheme as key)
19
+ */
20
+ register(handler: ProtocolHandler): void {
21
+ this.handlers.set(handler.scheme, handler);
22
+ }
23
+
24
+ /**
25
+ * Check if the router can handle a URL.
26
+ * @param input URL string to check
27
+ */
28
+ canHandle(input: string): boolean {
29
+ const match = input.match(/^([a-z][a-z0-9+.-]*):\/\//i);
30
+ if (!match) return false;
31
+ const scheme = match[1].toLowerCase();
32
+ return this.handlers.has(scheme);
33
+ }
34
+
35
+ /**
36
+ * Resolve an internal URL to its content.
37
+ * @param input URL string (e.g., "agent://reviewer_0", "skill://notion-pages")
38
+ * @throws Error if scheme is not registered or resolution fails
39
+ */
40
+ async resolve(input: string): Promise<InternalResource> {
41
+ let parsed: URL;
42
+ try {
43
+ parsed = new URL(input);
44
+ } catch {
45
+ throw new Error(`Invalid URL: ${input}`);
46
+ }
47
+
48
+ const hostMatch = input.match(/^([a-z][a-z0-9+.-]*):\/\/([^/?#]*)/i);
49
+ let rawHost = hostMatch ? hostMatch[2] : parsed.hostname;
50
+ try {
51
+ rawHost = decodeURIComponent(rawHost);
52
+ } catch {
53
+ // Leave rawHost as-is if decoding fails.
54
+ }
55
+ (parsed as InternalUrl).rawHost = rawHost;
56
+
57
+ const scheme = parsed.protocol.replace(/:$/, "").toLowerCase();
58
+ const handler = this.handlers.get(scheme);
59
+
60
+ if (!handler) {
61
+ const available = Array.from(this.handlers.keys())
62
+ .map((s) => `${s}://`)
63
+ .join(", ");
64
+ throw new Error(`Unknown protocol: ${scheme}://\nSupported: ${available || "none"}`);
65
+ }
66
+
67
+ return handler.resolve(parsed as InternalUrl);
68
+ }
69
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Protocol handler for rule:// URLs.
3
+ *
4
+ * Resolves rule names to their content files.
5
+ *
6
+ * URL forms:
7
+ * - rule://<name> - Reads rule content
8
+ */
9
+
10
+ import type { Rule } from "$c/capability/rule";
11
+ import type { InternalResource, InternalUrl, ProtocolHandler } from "./types";
12
+
13
+ export interface RuleProtocolOptions {
14
+ /**
15
+ * Returns the currently loaded rules.
16
+ */
17
+ getRules: () => readonly Rule[];
18
+ }
19
+
20
+ /**
21
+ * Handler for rule:// URLs.
22
+ *
23
+ * Resolves rule names to their content.
24
+ */
25
+ export class RuleProtocolHandler implements ProtocolHandler {
26
+ readonly scheme = "rule";
27
+
28
+ constructor(private readonly options: RuleProtocolOptions) {}
29
+
30
+ async resolve(url: InternalUrl): Promise<InternalResource> {
31
+ const rules = this.options.getRules();
32
+
33
+ // Extract rule name from host
34
+ const ruleName = url.rawHost || url.hostname;
35
+ if (!ruleName) {
36
+ throw new Error("rule:// URL requires a rule name: rule://<name>");
37
+ }
38
+
39
+ // Find the rule
40
+ const rule = rules.find((r) => r.name === ruleName);
41
+ if (!rule) {
42
+ const available = rules.map((r) => r.name);
43
+ const availableStr = available.length > 0 ? available.join(", ") : "none";
44
+ throw new Error(`Unknown rule: ${ruleName}\nAvailable: ${availableStr}`);
45
+ }
46
+
47
+ return {
48
+ url: url.href,
49
+ content: rule.content,
50
+ contentType: "text/markdown",
51
+ size: Buffer.byteLength(rule.content, "utf-8"),
52
+ sourcePath: rule.path,
53
+ notes: [],
54
+ };
55
+ }
56
+ }
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Protocol handler for skill:// URLs.
3
+ *
4
+ * Resolves skill names to their SKILL.md files or relative paths within skill directories.
5
+ *
6
+ * URL forms:
7
+ * - skill://<name> - Reads SKILL.md
8
+ * - skill://<name>/<path> - Reads relative path within skill's baseDir
9
+ */
10
+
11
+ import * as path from "node:path";
12
+ import type { Skill } from "$c/extensibility/skills";
13
+ import type { InternalResource, InternalUrl, ProtocolHandler } from "./types";
14
+
15
+ export interface SkillProtocolOptions {
16
+ /**
17
+ * Returns the currently loaded skills.
18
+ */
19
+ getSkills: () => readonly Skill[];
20
+ }
21
+
22
+ /**
23
+ * Get content type based on file extension.
24
+ */
25
+ function getContentType(filePath: string): InternalResource["contentType"] {
26
+ const ext = path.extname(filePath).toLowerCase();
27
+ if (ext === ".md") return "text/markdown";
28
+ return "text/plain";
29
+ }
30
+
31
+ /**
32
+ * Validate that a path is safe (no traversal, no absolute paths).
33
+ */
34
+ function validateRelativePath(relativePath: string): void {
35
+ if (path.isAbsolute(relativePath)) {
36
+ throw new Error("Absolute paths are not allowed in skill:// URLs");
37
+ }
38
+
39
+ const normalized = path.normalize(relativePath);
40
+ if (normalized.startsWith("..") || normalized.includes("/../") || normalized.includes("/..")) {
41
+ throw new Error("Path traversal (..) is not allowed in skill:// URLs");
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Handler for skill:// URLs.
47
+ *
48
+ * Resolves skill names to their content files.
49
+ */
50
+ export class SkillProtocolHandler implements ProtocolHandler {
51
+ readonly scheme = "skill";
52
+
53
+ constructor(private readonly options: SkillProtocolOptions) {}
54
+
55
+ async resolve(url: InternalUrl): Promise<InternalResource> {
56
+ const skills = this.options.getSkills();
57
+
58
+ // Extract skill name from host
59
+ const skillName = url.rawHost || url.hostname;
60
+ if (!skillName) {
61
+ throw new Error("skill:// URL requires a skill name: skill://<name>");
62
+ }
63
+
64
+ // Find the skill
65
+ const skill = skills.find((s) => s.name === skillName);
66
+ if (!skill) {
67
+ const available = skills.map((s) => s.name);
68
+ const availableStr = available.length > 0 ? available.join(", ") : "none";
69
+ throw new Error(`Unknown skill: ${skillName}\nAvailable: ${availableStr}`);
70
+ }
71
+
72
+ // Determine the file to read
73
+ let targetPath: string;
74
+ const urlPath = url.pathname;
75
+ const hasRelativePath = urlPath && urlPath !== "/" && urlPath !== "";
76
+
77
+ if (hasRelativePath) {
78
+ // Read relative path within skill's baseDir
79
+ const relativePath = decodeURIComponent(urlPath.slice(1)); // Remove leading /
80
+ validateRelativePath(relativePath);
81
+ targetPath = path.join(skill.baseDir, relativePath);
82
+
83
+ // Verify the resolved path is still within baseDir
84
+ const resolvedPath = path.resolve(targetPath);
85
+ const resolvedBaseDir = path.resolve(skill.baseDir);
86
+ if (!resolvedPath.startsWith(resolvedBaseDir + path.sep) && resolvedPath !== resolvedBaseDir) {
87
+ throw new Error("Path traversal is not allowed");
88
+ }
89
+ } else {
90
+ // Read SKILL.md
91
+ targetPath = skill.filePath;
92
+ }
93
+
94
+ // Read the file
95
+ const file = Bun.file(targetPath);
96
+ if (!(await file.exists())) {
97
+ throw new Error(`File not found: ${targetPath}`);
98
+ }
99
+
100
+ const content = await file.text();
101
+ const contentType = getContentType(targetPath);
102
+
103
+ return {
104
+ url: url.href,
105
+ content,
106
+ contentType,
107
+ size: Buffer.byteLength(content, "utf-8"),
108
+ sourcePath: targetPath,
109
+ notes: [],
110
+ };
111
+ }
112
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Types for the internal URL routing system.
3
+ *
4
+ * Internal URLs (agent://, skill://) are resolved by tools like fetch and read,
5
+ * providing access to agent outputs and skill files without exposing filesystem paths.
6
+ */
7
+
8
+ /**
9
+ * Resolved internal resource returned by protocol handlers.
10
+ */
11
+ export interface InternalResource {
12
+ /** Canonical URL that was resolved */
13
+ url: string;
14
+ /** Resolved text content */
15
+ content: string;
16
+ /** MIME type: text/markdown, application/json, or text/plain */
17
+ contentType: "text/markdown" | "application/json" | "text/plain";
18
+ /** Content size in bytes */
19
+ size?: number;
20
+ /** Underlying filesystem path (for debugging, not exposed to agent) */
21
+ sourcePath?: string;
22
+ /** Additional notes about resolution */
23
+ notes?: string[];
24
+ }
25
+
26
+ /**
27
+ * Parsed internal URL with preserved host casing.
28
+ */
29
+ export interface InternalUrl extends URL {
30
+ /**
31
+ * Raw host segment extracted from input, preserving case.
32
+ */
33
+ rawHost: string;
34
+ }
35
+
36
+ /**
37
+ * Handler for a specific internal URL scheme (e.g., agent://, skill://).
38
+ */
39
+ export interface ProtocolHandler {
40
+ /** The scheme this handler processes (without trailing ://) */
41
+ readonly scheme: string;
42
+ /**
43
+ * Resolve an internal URL to its content.
44
+ * @param url Parsed URL object
45
+ * @throws Error with user-friendly message if resolution fails
46
+ */
47
+ resolve(url: InternalUrl): Promise<InternalResource>;
48
+ }
@@ -6,8 +6,8 @@ import {
6
6
  type KernelExecuteResult,
7
7
  type PreludeHelper,
8
8
  PythonKernel,
9
- } from "./python-kernel";
10
- import { OutputSink } from "./streaming-output";
9
+ } from "$c/ipy/kernel";
10
+ import { OutputSink } from "$c/session/streaming-output";
11
11
  export type PythonKernelMode = "session" | "per-call";
12
12
 
13
13
  export interface PythonExecutorOptions {
@@ -29,6 +29,11 @@ export interface PythonExecutorOptions {
29
29
  useSharedGateway?: boolean;
30
30
  /** Session file path for accessing task outputs */
31
31
  sessionFile?: string;
32
+ /** Artifacts directory for $ARTIFACTS env var and artifact storage */
33
+ artifactsDir?: string;
34
+ /** Artifact path/id for full output storage */
35
+ artifactPath?: string;
36
+ artifactId?: string;
32
37
  }
33
38
 
34
39
  export interface PythonKernelExecutor {
@@ -44,8 +49,16 @@ export interface PythonResult {
44
49
  cancelled: boolean;
45
50
  /** Whether the output was truncated */
46
51
  truncated: boolean;
47
- /** Path to temp file containing full output (if output exceeded truncation threshold) */
48
- fullOutputPath?: string;
52
+ /** Artifact ID if full output was saved to artifact storage */
53
+ artifactId?: string;
54
+ /** Total number of lines in the output stream */
55
+ totalLines: number;
56
+ /** Total number of bytes in the output stream */
57
+ totalBytes: number;
58
+ /** Number of lines included in the output text */
59
+ outputLines: number;
60
+ /** Number of bytes included in the output text */
61
+ outputBytes: number;
49
62
  /** Rich display outputs captured from display_data/execute_result */
50
63
  displayOutputs: KernelDisplayOutput[];
51
64
  /** Whether stdin was requested */
@@ -124,8 +137,15 @@ async function createKernelSession(
124
137
  cwd: string,
125
138
  useSharedGateway?: boolean,
126
139
  sessionFile?: string,
140
+ artifactsDir?: string,
127
141
  ): Promise<KernelSession> {
128
- const env = sessionFile ? { OMP_SESSION_FILE: sessionFile } : undefined;
142
+ const env: Record<string, string> | undefined =
143
+ sessionFile || artifactsDir
144
+ ? {
145
+ ...(sessionFile ? { OMP_SESSION_FILE: sessionFile } : {}),
146
+ ...(artifactsDir ? { ARTIFACTS: artifactsDir } : {}),
147
+ }
148
+ : undefined;
129
149
  const kernel = await PythonKernel.start({ cwd, useSharedGateway, env });
130
150
  const session: KernelSession = {
131
151
  id: sessionId,
@@ -152,6 +172,7 @@ async function restartKernelSession(
152
172
  cwd: string,
153
173
  useSharedGateway?: boolean,
154
174
  sessionFile?: string,
175
+ artifactsDir?: string,
155
176
  ): Promise<void> {
156
177
  session.restartCount += 1;
157
178
  if (session.restartCount > 1) {
@@ -162,7 +183,13 @@ async function restartKernelSession(
162
183
  } catch (err) {
163
184
  logger.warn("Failed to shutdown crashed kernel", { error: err instanceof Error ? err.message : String(err) });
164
185
  }
165
- const env = sessionFile ? { OMP_SESSION_FILE: sessionFile } : undefined;
186
+ const env: Record<string, string> | undefined =
187
+ sessionFile || artifactsDir
188
+ ? {
189
+ ...(sessionFile ? { OMP_SESSION_FILE: sessionFile } : {}),
190
+ ...(artifactsDir ? { ARTIFACTS: artifactsDir } : {}),
191
+ }
192
+ : undefined;
166
193
  const kernel = await PythonKernel.start({ cwd, useSharedGateway, env });
167
194
  session.kernel = kernel;
168
195
  session.dead = false;
@@ -187,17 +214,18 @@ async function withKernelSession<T>(
187
214
  handler: (kernel: PythonKernel) => Promise<T>,
188
215
  useSharedGateway?: boolean,
189
216
  sessionFile?: string,
217
+ artifactsDir?: string,
190
218
  ): Promise<T> {
191
219
  let session = kernelSessions.get(sessionId);
192
220
  if (!session) {
193
- session = await createKernelSession(sessionId, cwd, useSharedGateway, sessionFile);
221
+ session = await createKernelSession(sessionId, cwd, useSharedGateway, sessionFile, artifactsDir);
194
222
  kernelSessions.set(sessionId, session);
195
223
  }
196
224
 
197
225
  const run = async (): Promise<T> => {
198
226
  session!.lastUsedAt = Date.now();
199
227
  if (session!.dead || !session!.kernel.isAlive()) {
200
- await restartKernelSession(session!, cwd, useSharedGateway, sessionFile);
228
+ await restartKernelSession(session!, cwd, useSharedGateway, sessionFile, artifactsDir);
201
229
  }
202
230
  try {
203
231
  const result = await handler(session!.kernel);
@@ -207,7 +235,7 @@ async function withKernelSession<T>(
207
235
  if (!session!.dead && session!.kernel.isAlive()) {
208
236
  throw err;
209
237
  }
210
- await restartKernelSession(session!, cwd, useSharedGateway, sessionFile);
238
+ await restartKernelSession(session!, cwd, useSharedGateway, sessionFile, artifactsDir);
211
239
  const result = await handler(session!.kernel);
212
240
  session!.restartCount = 0;
213
241
  return result;
@@ -227,7 +255,11 @@ async function executeWithKernel(
227
255
  code: string,
228
256
  options: PythonExecutorOptions | undefined,
229
257
  ): Promise<PythonResult> {
230
- const sink = new OutputSink({ onChunk: options?.onChunk });
258
+ const sink = new OutputSink({
259
+ onChunk: options?.onChunk,
260
+ artifactPath: options?.artifactPath,
261
+ artifactId: options?.artifactId,
262
+ });
231
263
  const displayOutputs: KernelDisplayOutput[] = [];
232
264
 
233
265
  try {
@@ -291,9 +323,16 @@ export async function executePython(code: string, options?: PythonExecutorOption
291
323
  const kernelMode = options?.kernelMode ?? "session";
292
324
  const useSharedGateway = options?.useSharedGateway;
293
325
  const sessionFile = options?.sessionFile;
326
+ const artifactsDir = options?.artifactsDir;
294
327
 
295
328
  if (kernelMode === "per-call") {
296
- const env = sessionFile ? { OMP_SESSION_FILE: sessionFile } : undefined;
329
+ const env: Record<string, string> | undefined =
330
+ sessionFile || artifactsDir
331
+ ? {
332
+ ...(sessionFile ? { OMP_SESSION_FILE: sessionFile } : {}),
333
+ ...(artifactsDir ? { ARTIFACTS: artifactsDir } : {}),
334
+ }
335
+ : undefined;
297
336
  const kernel = await PythonKernel.start({ cwd, useSharedGateway, env });
298
337
  try {
299
338
  return await executeWithKernel(kernel, code, options);
@@ -315,5 +354,6 @@ export async function executePython(code: string, options?: PythonExecutorOption
315
354
  async (kernel) => executeWithKernel(kernel, code, options),
316
355
  useSharedGateway,
317
356
  sessionFile,
357
+ artifactsDir,
318
358
  );
319
359
  }