@oh-my-pi/pi-coding-agent 8.0.20 → 8.2.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 (421) hide show
  1. package/CHANGELOG.md +125 -0
  2. package/docs/session.md +111 -46
  3. package/examples/custom-tools/hello/index.ts +1 -1
  4. package/examples/custom-tools/todo/index.ts +3 -4
  5. package/examples/extensions/api-demo.ts +0 -1
  6. package/examples/extensions/chalk-logger.ts +2 -3
  7. package/examples/extensions/hello.ts +0 -1
  8. package/examples/extensions/pirate.ts +0 -1
  9. package/examples/extensions/plan-mode.ts +15 -16
  10. package/examples/extensions/todo.ts +3 -4
  11. package/examples/extensions/tools.ts +1 -2
  12. package/examples/extensions/with-deps/index.ts +0 -1
  13. package/examples/hooks/auto-commit-on-exit.ts +1 -2
  14. package/examples/hooks/confirm-destructive.ts +0 -1
  15. package/examples/hooks/custom-compaction.ts +1 -2
  16. package/examples/hooks/dirty-repo-guard.ts +0 -1
  17. package/examples/hooks/file-trigger.ts +3 -4
  18. package/examples/hooks/git-checkpoint.ts +0 -1
  19. package/examples/hooks/handoff.ts +3 -4
  20. package/examples/hooks/permission-gate.ts +1 -2
  21. package/examples/hooks/protected-paths.ts +1 -2
  22. package/examples/hooks/qna.ts +2 -3
  23. package/examples/hooks/snake.ts +4 -5
  24. package/examples/hooks/status-line.ts +0 -1
  25. package/examples/sdk/01-minimal.ts +2 -3
  26. package/examples/sdk/02-custom-model.ts +2 -3
  27. package/examples/sdk/03-custom-prompt.ts +3 -4
  28. package/examples/sdk/04-skills.ts +2 -3
  29. package/examples/sdk/06-extensions.ts +1 -2
  30. package/examples/sdk/06-hooks.ts +6 -7
  31. package/examples/sdk/07-context-files.ts +0 -1
  32. package/examples/sdk/08-prompt-templates.ts +0 -1
  33. package/examples/sdk/08-slash-commands.ts +0 -1
  34. package/examples/sdk/09-api-keys-and-oauth.ts +0 -1
  35. package/examples/sdk/10-settings.ts +0 -1
  36. package/examples/sdk/11-sessions.ts +0 -1
  37. package/package.json +54 -23
  38. package/scripts/format-prompts.ts +0 -1
  39. package/src/capability/context-file.ts +3 -4
  40. package/src/capability/extension-module.ts +3 -4
  41. package/src/capability/extension.ts +3 -4
  42. package/src/capability/fs.ts +20 -21
  43. package/src/capability/hook.ts +3 -4
  44. package/src/capability/index.ts +15 -16
  45. package/src/capability/instruction.ts +3 -4
  46. package/src/capability/mcp.ts +3 -4
  47. package/src/capability/prompt.ts +3 -4
  48. package/src/capability/rule.ts +3 -4
  49. package/src/capability/settings.ts +2 -3
  50. package/src/capability/skill.ts +3 -4
  51. package/src/capability/slash-command.ts +3 -4
  52. package/src/capability/ssh.ts +3 -4
  53. package/src/capability/system-prompt.ts +3 -4
  54. package/src/capability/tool.ts +3 -4
  55. package/src/cli/args.ts +5 -6
  56. package/src/cli/config-cli.ts +6 -7
  57. package/src/cli/file-processor.ts +19 -17
  58. package/src/cli/jupyter-cli.ts +105 -0
  59. package/src/cli/list-models.ts +10 -11
  60. package/src/cli/plugin-cli.ts +20 -25
  61. package/src/cli/session-picker.ts +2 -3
  62. package/src/cli/setup-cli.ts +2 -3
  63. package/src/cli/stats-cli.ts +2 -3
  64. package/src/cli/update-cli.ts +25 -22
  65. package/src/commit/agentic/agent.ts +307 -0
  66. package/src/commit/agentic/fallback.ts +96 -0
  67. package/src/commit/agentic/index.ts +351 -0
  68. package/src/commit/agentic/prompts/analyze-file.md +22 -0
  69. package/src/commit/agentic/prompts/session-user.md +26 -0
  70. package/src/commit/agentic/prompts/split-confirm.md +1 -0
  71. package/src/commit/agentic/prompts/system.md +40 -0
  72. package/src/commit/agentic/state.ts +69 -0
  73. package/src/commit/agentic/tools/analyze-file.ts +131 -0
  74. package/src/commit/agentic/tools/git-file-diff.ts +194 -0
  75. package/src/commit/agentic/tools/git-hunk.ts +50 -0
  76. package/src/commit/agentic/tools/git-overview.ts +84 -0
  77. package/src/commit/agentic/tools/index.ts +56 -0
  78. package/src/commit/agentic/tools/propose-changelog.ts +128 -0
  79. package/src/commit/agentic/tools/propose-commit.ts +154 -0
  80. package/src/commit/agentic/tools/recent-commits.ts +81 -0
  81. package/src/commit/agentic/tools/split-commit.ts +280 -0
  82. package/src/commit/agentic/topo-sort.ts +44 -0
  83. package/src/commit/agentic/trivial.ts +51 -0
  84. package/src/commit/agentic/validation.ts +200 -0
  85. package/src/commit/analysis/conventional.ts +165 -0
  86. package/src/commit/analysis/index.ts +4 -0
  87. package/src/commit/analysis/scope.ts +242 -0
  88. package/src/commit/analysis/summary.ts +112 -0
  89. package/src/commit/analysis/validation.ts +66 -0
  90. package/src/commit/changelog/detect.ts +36 -0
  91. package/src/commit/changelog/generate.ts +110 -0
  92. package/src/commit/changelog/index.ts +233 -0
  93. package/src/commit/changelog/parse.ts +44 -0
  94. package/src/commit/cli.ts +93 -0
  95. package/src/commit/git/diff.ts +148 -0
  96. package/src/commit/git/errors.ts +11 -0
  97. package/src/commit/git/index.ts +212 -0
  98. package/src/commit/git/operations.ts +53 -0
  99. package/src/commit/index.ts +5 -0
  100. package/src/commit/map-reduce/index.ts +63 -0
  101. package/src/commit/map-reduce/map-phase.ts +178 -0
  102. package/src/commit/map-reduce/reduce-phase.ts +145 -0
  103. package/src/commit/map-reduce/utils.ts +9 -0
  104. package/src/commit/message.ts +11 -0
  105. package/src/commit/model-selection.ts +80 -0
  106. package/src/commit/pipeline.ts +240 -0
  107. package/src/commit/prompts/analysis-system.md +155 -0
  108. package/src/commit/prompts/analysis-user.md +41 -0
  109. package/src/commit/prompts/changelog-system.md +56 -0
  110. package/src/commit/prompts/changelog-user.md +19 -0
  111. package/src/commit/prompts/file-observer-system.md +26 -0
  112. package/src/commit/prompts/file-observer-user.md +9 -0
  113. package/src/commit/prompts/reduce-system.md +60 -0
  114. package/src/commit/prompts/reduce-user.md +17 -0
  115. package/src/commit/prompts/summary-retry.md +4 -0
  116. package/src/commit/prompts/summary-system.md +52 -0
  117. package/src/commit/prompts/summary-user.md +13 -0
  118. package/src/commit/prompts/types-description.md +2 -0
  119. package/src/commit/types.ts +109 -0
  120. package/src/commit/utils/exclusions.ts +42 -0
  121. package/src/config/file-lock.ts +121 -0
  122. package/src/config/keybindings.ts +6 -8
  123. package/src/config/model-registry.ts +65 -38
  124. package/src/config/model-resolver.ts +18 -19
  125. package/src/config/prompt-templates.ts +11 -11
  126. package/src/config/settings-manager.ts +141 -50
  127. package/src/config.ts +64 -66
  128. package/src/cursor.ts +11 -9
  129. package/src/discovery/agents-md.ts +11 -12
  130. package/src/discovery/builtin.ts +68 -73
  131. package/src/discovery/claude.ts +41 -42
  132. package/src/discovery/cline.ts +11 -12
  133. package/src/discovery/codex.ts +52 -53
  134. package/src/discovery/cursor.ts +9 -10
  135. package/src/discovery/gemini.ts +17 -22
  136. package/src/discovery/github.ts +13 -14
  137. package/src/discovery/helpers.ts +35 -34
  138. package/src/discovery/index.ts +22 -24
  139. package/src/discovery/mcp-json.ts +8 -9
  140. package/src/discovery/ssh.ts +8 -9
  141. package/src/discovery/vscode.ts +4 -5
  142. package/src/discovery/windsurf.ts +6 -7
  143. package/src/exa/company.ts +1 -2
  144. package/src/exa/index.ts +2 -3
  145. package/src/exa/linkedin.ts +1 -2
  146. package/src/exa/mcp-client.ts +14 -16
  147. package/src/exa/render.ts +10 -11
  148. package/src/exa/researcher.ts +1 -2
  149. package/src/exa/search.ts +1 -2
  150. package/src/exa/types.ts +0 -1
  151. package/src/exa/websets.ts +1 -2
  152. package/src/exec/bash-executor.ts +3 -4
  153. package/src/exec/exec.ts +0 -1
  154. package/src/export/custom-share.ts +5 -6
  155. package/src/export/html/index.ts +24 -21
  156. package/src/export/ttsr.ts +2 -3
  157. package/src/extensibility/custom-commands/bundled/review/index.ts +7 -8
  158. package/src/extensibility/custom-commands/loader.ts +18 -15
  159. package/src/extensibility/custom-commands/types.ts +2 -3
  160. package/src/extensibility/custom-tools/loader.ts +11 -12
  161. package/src/extensibility/custom-tools/types.ts +7 -8
  162. package/src/extensibility/custom-tools/wrapper.ts +2 -3
  163. package/src/extensibility/extensions/loader.ts +76 -54
  164. package/src/extensibility/extensions/runner.ts +11 -12
  165. package/src/extensibility/extensions/types.ts +20 -27
  166. package/src/extensibility/extensions/wrapper.ts +3 -4
  167. package/src/extensibility/hooks/index.ts +1 -1
  168. package/src/extensibility/hooks/loader.ts +9 -10
  169. package/src/extensibility/hooks/runner.ts +7 -8
  170. package/src/extensibility/hooks/tool-wrapper.ts +0 -1
  171. package/src/extensibility/hooks/types.ts +11 -18
  172. package/src/extensibility/plugins/doctor.ts +3 -3
  173. package/src/extensibility/plugins/installer.ts +27 -27
  174. package/src/extensibility/plugins/loader.ts +59 -56
  175. package/src/extensibility/plugins/manager.ts +211 -171
  176. package/src/extensibility/plugins/parser.ts +1 -1
  177. package/src/extensibility/plugins/paths.ts +8 -8
  178. package/src/extensibility/skills.ts +63 -60
  179. package/src/extensibility/slash-commands.ts +10 -10
  180. package/src/index.ts +54 -54
  181. package/src/internal-urls/agent-protocol.ts +21 -11
  182. package/src/internal-urls/artifact-protocol.ts +17 -13
  183. package/src/internal-urls/router.ts +1 -2
  184. package/src/internal-urls/rule-protocol.ts +3 -4
  185. package/src/internal-urls/skill-protocol.ts +3 -4
  186. package/src/ipy/executor.ts +109 -9
  187. package/src/ipy/gateway-coordinator.ts +79 -90
  188. package/src/ipy/kernel.ts +32 -30
  189. package/src/ipy/modules.ts +13 -13
  190. package/src/lsp/client.ts +21 -10
  191. package/src/lsp/clients/biome-client.ts +1 -2
  192. package/src/lsp/clients/index.ts +3 -3
  193. package/src/lsp/clients/lsp-linter-client.ts +4 -5
  194. package/src/lsp/config.ts +15 -15
  195. package/src/lsp/edits.ts +4 -5
  196. package/src/lsp/index.ts +43 -44
  197. package/src/lsp/lspmux.ts +8 -8
  198. package/src/lsp/render.ts +99 -61
  199. package/src/lsp/utils.ts +3 -3
  200. package/src/main.ts +71 -37
  201. package/src/mcp/client.ts +2 -3
  202. package/src/mcp/config.ts +5 -6
  203. package/src/mcp/json-rpc.ts +0 -1
  204. package/src/mcp/loader.ts +6 -7
  205. package/src/mcp/manager.ts +17 -18
  206. package/src/mcp/tool-bridge.ts +4 -9
  207. package/src/mcp/tool-cache.ts +2 -3
  208. package/src/mcp/transports/http.ts +2 -4
  209. package/src/mcp/transports/stdio.ts +1 -2
  210. package/src/migrations.ts +63 -52
  211. package/src/modes/components/armin.ts +4 -5
  212. package/src/modes/components/assistant-message.ts +33 -5
  213. package/src/modes/components/bash-execution.ts +7 -8
  214. package/src/modes/components/bordered-loader.ts +3 -3
  215. package/src/modes/components/branch-summary-message.ts +3 -3
  216. package/src/modes/components/compaction-summary-message.ts +3 -3
  217. package/src/modes/components/countdown-timer.ts +0 -1
  218. package/src/modes/components/custom-message.ts +5 -5
  219. package/src/modes/components/diff.ts +1 -1
  220. package/src/modes/components/dynamic-border.ts +2 -2
  221. package/src/modes/components/extensions/extension-dashboard.ts +6 -7
  222. package/src/modes/components/extensions/extension-list.ts +2 -3
  223. package/src/modes/components/extensions/inspector-panel.ts +3 -4
  224. package/src/modes/components/extensions/state-manager.ts +25 -26
  225. package/src/modes/components/extensions/types.ts +1 -2
  226. package/src/modes/components/footer.ts +47 -43
  227. package/src/modes/components/history-search.ts +2 -2
  228. package/src/modes/components/hook-editor.ts +3 -4
  229. package/src/modes/components/hook-input.ts +2 -3
  230. package/src/modes/components/hook-message.ts +5 -5
  231. package/src/modes/components/hook-selector.ts +2 -3
  232. package/src/modes/components/keybinding-hints.ts +2 -3
  233. package/src/modes/components/login-dialog.ts +2 -2
  234. package/src/modes/components/model-selector.ts +12 -12
  235. package/src/modes/components/oauth-selector.ts +2 -2
  236. package/src/modes/components/plugin-settings.ts +20 -20
  237. package/src/modes/components/python-execution.ts +7 -8
  238. package/src/modes/components/queue-mode-selector.ts +3 -3
  239. package/src/modes/components/read-tool-group.ts +2 -2
  240. package/src/modes/components/session-selector.ts +4 -4
  241. package/src/modes/components/settings-defs.ts +77 -69
  242. package/src/modes/components/settings-selector.ts +16 -16
  243. package/src/modes/components/show-images-selector.ts +2 -2
  244. package/src/modes/components/status-line/segments.ts +4 -4
  245. package/src/modes/components/status-line/separators.ts +1 -1
  246. package/src/modes/components/status-line/types.ts +2 -2
  247. package/src/modes/components/status-line-segment-editor.ts +7 -8
  248. package/src/modes/components/status-line.ts +12 -12
  249. package/src/modes/components/theme-selector.ts +8 -7
  250. package/src/modes/components/thinking-selector.ts +4 -4
  251. package/src/modes/components/todo-display.ts +2 -2
  252. package/src/modes/components/todo-reminder.ts +4 -4
  253. package/src/modes/components/tool-execution.ts +16 -19
  254. package/src/modes/components/tree-selector.ts +12 -12
  255. package/src/modes/components/ttsr-notification.ts +5 -5
  256. package/src/modes/components/user-message-selector.ts +1 -1
  257. package/src/modes/components/user-message.ts +1 -1
  258. package/src/modes/components/visual-truncate.ts +0 -1
  259. package/src/modes/components/welcome.ts +4 -4
  260. package/src/modes/controllers/command-controller.ts +46 -47
  261. package/src/modes/controllers/event-controller.ts +16 -20
  262. package/src/modes/controllers/extension-ui-controller.ts +40 -46
  263. package/src/modes/controllers/input-controller.ts +17 -18
  264. package/src/modes/controllers/selector-controller.ts +103 -91
  265. package/src/modes/index.ts +3 -3
  266. package/src/modes/interactive-mode.ts +31 -31
  267. package/src/modes/print-mode.ts +12 -13
  268. package/src/modes/rpc/rpc-client.ts +7 -8
  269. package/src/modes/rpc/rpc-mode.ts +24 -28
  270. package/src/modes/rpc/rpc-types.ts +3 -4
  271. package/src/modes/theme/mermaid-cache.ts +89 -0
  272. package/src/modes/theme/theme.ts +130 -53
  273. package/src/modes/types.ts +10 -10
  274. package/src/modes/utils/ui-helpers.ts +17 -17
  275. package/src/patch/applicator.ts +18 -19
  276. package/src/patch/diff.ts +1 -2
  277. package/src/patch/fuzzy.ts +1 -2
  278. package/src/patch/index.ts +11 -18
  279. package/src/patch/normalize.ts +4 -4
  280. package/src/patch/normative.ts +1 -2
  281. package/src/patch/parser.ts +8 -9
  282. package/src/patch/shared.ts +43 -16
  283. package/src/prompts/tools/task.md +2 -0
  284. package/src/sdk.ts +100 -65
  285. package/src/session/agent-session.ts +84 -85
  286. package/src/session/agent-storage.ts +43 -39
  287. package/src/session/artifacts.ts +32 -10
  288. package/src/session/auth-storage.ts +50 -39
  289. package/src/session/compaction/branch-summarization.ts +7 -10
  290. package/src/session/compaction/compaction.ts +8 -19
  291. package/src/session/compaction/utils.ts +6 -9
  292. package/src/session/history-storage.ts +10 -10
  293. package/src/session/messages.ts +4 -5
  294. package/src/session/session-manager.ts +76 -65
  295. package/src/session/session-storage.ts +57 -69
  296. package/src/session/storage-migration.ts +14 -56
  297. package/src/session/streaming-output.ts +2 -2
  298. package/src/ssh/connection-manager.ts +43 -50
  299. package/src/ssh/ssh-executor.ts +2 -2
  300. package/src/ssh/sshfs-mount.ts +11 -18
  301. package/src/system-prompt.ts +28 -35
  302. package/src/task/agents.ts +45 -30
  303. package/src/task/commands.ts +6 -7
  304. package/src/task/discovery.ts +39 -76
  305. package/src/task/executor.ts +14 -15
  306. package/src/task/index.ts +40 -34
  307. package/src/task/output-manager.ts +93 -0
  308. package/src/task/parallel.ts +0 -1
  309. package/src/task/render.ts +24 -30
  310. package/src/task/subprocess-tool-registry.ts +1 -2
  311. package/src/task/worker-protocol.ts +3 -3
  312. package/src/task/worker.ts +33 -39
  313. package/src/task/worktree.ts +19 -19
  314. package/src/tools/ask.ts +41 -20
  315. package/src/tools/bash-interceptor.ts +1 -5
  316. package/src/tools/bash.ts +91 -97
  317. package/src/tools/calculator.ts +49 -47
  318. package/src/tools/complete.ts +4 -5
  319. package/src/tools/context.ts +2 -2
  320. package/src/tools/fetch.ts +84 -124
  321. package/src/tools/find.ts +94 -98
  322. package/src/tools/gemini-image.ts +14 -14
  323. package/src/tools/grep.ts +100 -116
  324. package/src/tools/index.ts +80 -55
  325. package/src/tools/list-limit.ts +1 -1
  326. package/src/tools/ls.ts +44 -70
  327. package/src/tools/notebook.ts +51 -67
  328. package/src/tools/output-meta.ts +3 -4
  329. package/src/tools/output-utils.ts +2 -2
  330. package/src/tools/path-utils.ts +5 -5
  331. package/src/tools/python.ts +104 -217
  332. package/src/tools/read.ts +92 -33
  333. package/src/tools/render-utils.ts +8 -23
  334. package/src/tools/renderers.ts +6 -7
  335. package/src/tools/review.ts +8 -11
  336. package/src/tools/ssh.ts +69 -49
  337. package/src/tools/todo-write.ts +37 -25
  338. package/src/tools/tool-errors.ts +3 -3
  339. package/src/tools/tool-result.ts +3 -8
  340. package/src/tools/write.ts +99 -75
  341. package/src/tui/code-cell.ts +109 -0
  342. package/src/tui/file-list.ts +47 -0
  343. package/src/tui/index.ts +11 -0
  344. package/src/tui/output-block.ts +72 -0
  345. package/src/tui/status-line.ts +39 -0
  346. package/src/tui/tree-list.ts +55 -0
  347. package/src/tui/types.ts +16 -0
  348. package/src/tui/utils.ts +48 -0
  349. package/src/utils/changelog.ts +9 -10
  350. package/src/utils/clipboard.ts +11 -11
  351. package/src/utils/file-mentions.ts +4 -10
  352. package/src/utils/frontmatter.ts +6 -3
  353. package/src/utils/fuzzy.ts +2 -2
  354. package/src/utils/image-convert.ts +1 -1
  355. package/src/utils/image-resize.ts +1 -1
  356. package/src/utils/mime.ts +2 -2
  357. package/src/utils/shell-snapshot.ts +11 -13
  358. package/src/utils/shell.ts +4 -5
  359. package/src/utils/title-generator.ts +8 -9
  360. package/src/utils/tools-manager.ts +23 -23
  361. package/src/vendor/photon/index.js +1099 -1059
  362. package/src/vendor/photon/photon_rs_bg.wasm +0 -0
  363. package/src/web/scrapers/artifacthub.ts +1 -1
  364. package/src/web/scrapers/arxiv.ts +2 -2
  365. package/src/web/scrapers/bluesky.ts +2 -2
  366. package/src/web/scrapers/cheatsh.ts +1 -1
  367. package/src/web/scrapers/chocolatey.ts +2 -2
  368. package/src/web/scrapers/choosealicense.ts +5 -5
  369. package/src/web/scrapers/cisa-kev.ts +1 -1
  370. package/src/web/scrapers/crossref.ts +2 -2
  371. package/src/web/scrapers/devto.ts +3 -3
  372. package/src/web/scrapers/discogs.ts +3 -4
  373. package/src/web/scrapers/discourse.ts +1 -1
  374. package/src/web/scrapers/dockerhub.ts +1 -1
  375. package/src/web/scrapers/fdroid.ts +2 -2
  376. package/src/web/scrapers/firefox-addons.ts +3 -3
  377. package/src/web/scrapers/flathub.ts +1 -1
  378. package/src/web/scrapers/github.ts +3 -3
  379. package/src/web/scrapers/gitlab.ts +4 -4
  380. package/src/web/scrapers/hackernews.ts +2 -2
  381. package/src/web/scrapers/huggingface.ts +1 -1
  382. package/src/web/scrapers/iacr.ts +2 -2
  383. package/src/web/scrapers/index.ts +0 -1
  384. package/src/web/scrapers/jetbrains-marketplace.ts +1 -1
  385. package/src/web/scrapers/lemmy.ts +2 -2
  386. package/src/web/scrapers/maven.ts +2 -2
  387. package/src/web/scrapers/mdn.ts +2 -4
  388. package/src/web/scrapers/metacpan.ts +2 -2
  389. package/src/web/scrapers/musicbrainz.ts +1 -2
  390. package/src/web/scrapers/npm.ts +1 -1
  391. package/src/web/scrapers/nuget.ts +2 -2
  392. package/src/web/scrapers/nvd.ts +3 -3
  393. package/src/web/scrapers/ollama.ts +7 -9
  394. package/src/web/scrapers/opencorporates.ts +2 -2
  395. package/src/web/scrapers/openlibrary.ts +6 -6
  396. package/src/web/scrapers/orcid.ts +0 -1
  397. package/src/web/scrapers/osv.ts +2 -2
  398. package/src/web/scrapers/packagist.ts +1 -1
  399. package/src/web/scrapers/pubmed.ts +1 -2
  400. package/src/web/scrapers/rawg.ts +2 -2
  401. package/src/web/scrapers/readthedocs.ts +1 -2
  402. package/src/web/scrapers/repology.ts +2 -2
  403. package/src/web/scrapers/rfc.ts +1 -1
  404. package/src/web/scrapers/searchcode.ts +2 -2
  405. package/src/web/scrapers/semantic-scholar.ts +1 -1
  406. package/src/web/scrapers/snapcraft.ts +2 -2
  407. package/src/web/scrapers/sourcegraph.ts +1 -1
  408. package/src/web/scrapers/spdx.ts +3 -3
  409. package/src/web/scrapers/spotify.ts +0 -1
  410. package/src/web/scrapers/twitter.ts +1 -1
  411. package/src/web/scrapers/types.ts +1 -2
  412. package/src/web/scrapers/utils.ts +5 -5
  413. package/src/web/scrapers/wikidata.ts +3 -3
  414. package/src/web/scrapers/youtube.ts +9 -14
  415. package/src/web/search/auth.ts +5 -10
  416. package/src/web/search/index.ts +11 -21
  417. package/src/web/search/providers/anthropic.ts +3 -9
  418. package/src/web/search/providers/exa.ts +6 -10
  419. package/src/web/search/providers/perplexity.ts +5 -5
  420. package/src/web/search/render.ts +129 -175
  421. package/tsconfig.json +0 -42
package/src/tools/ls.ts CHANGED
@@ -1,14 +1,14 @@
1
1
  import nodePath from "node:path";
2
2
  import type { AgentTool, AgentToolResult } from "@oh-my-pi/pi-agent-core";
3
- import type { RenderResultOptions } from "@oh-my-pi/pi-coding-agent/extensibility/custom-tools/types";
4
- import { getLanguageFromPath, type Theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
5
- import type { OutputMeta } from "@oh-my-pi/pi-coding-agent/tools/output-meta";
6
- import { ToolError, throwIfAborted } from "@oh-my-pi/pi-coding-agent/tools/tool-errors";
7
3
  import { type Component, Text } from "@oh-my-pi/pi-tui";
8
4
  import { untilAborted } from "@oh-my-pi/pi-utils";
9
5
  import { Type } from "@sinclair/typebox";
10
- import type { ToolSession } from "./index";
6
+ import type { RenderResultOptions } from "../extensibility/custom-tools/types";
7
+ import type { Theme } from "../modes/theme/theme";
8
+ import { renderFileList, renderStatusLine } from "../tui";
9
+ import type { ToolSession } from ".";
11
10
  import { applyListLimit } from "./list-limit";
11
+ import type { OutputMeta } from "./output-meta";
12
12
  import { resolveToCwd } from "./path-utils";
13
13
  import {
14
14
  formatAge,
@@ -16,12 +16,9 @@ import {
16
16
  formatCount,
17
17
  formatEmptyMessage,
18
18
  formatErrorMessage,
19
- formatExpandHint,
20
- formatMeta,
21
- formatMoreItems,
22
- formatTruncationSuffix,
23
19
  PREVIEW_LIMITS,
24
20
  } from "./render-utils";
21
+ import { ToolError, throwIfAborted } from "./tool-errors";
25
22
  import { toolResult } from "./tool-result";
26
23
  import { type TruncationResult, truncateHead } from "./truncate";
27
24
 
@@ -214,13 +211,9 @@ const COLLAPSED_LIST_LIMIT = PREVIEW_LIMITS.COLLAPSED_ITEMS;
214
211
  export const lsToolRenderer = {
215
212
  inline: true,
216
213
  renderCall(args: LsRenderArgs, uiTheme: Theme): Component {
217
- const label = uiTheme.fg("toolTitle", uiTheme.bold("Ls"));
218
- let text = `${uiTheme.format.bullet} ${label} ${uiTheme.fg("accent", args.path || ".")}`;
219
-
220
214
  const meta: string[] = [];
221
215
  if (args.limit !== undefined) meta.push(`limit:${args.limit}`);
222
- text += formatMeta(meta, uiTheme);
223
-
216
+ const text = renderStatusLine({ icon: "pending", title: "Ls", description: args.path || ".", meta }, uiTheme);
224
217
  return new Text(text, 0, 0);
225
218
  },
226
219
 
@@ -228,31 +221,35 @@ export const lsToolRenderer = {
228
221
  result: { content: Array<{ type: string; text?: string }>; details?: LsToolDetails; isError?: boolean },
229
222
  { expanded }: RenderResultOptions,
230
223
  uiTheme: Theme,
224
+ args?: LsRenderArgs,
231
225
  ): Component {
232
226
  const details = result.details;
233
- const textContent = result.content?.find((c) => c.type === "text")?.text ?? "";
227
+ const textContent = result.content?.find(c => c.type === "text")?.text ?? "";
234
228
 
235
229
  if (result.isError) {
236
- return new Text(` ${formatErrorMessage(textContent, uiTheme)}`, 0, 0);
230
+ const header = renderStatusLine({ icon: "error", title: "Ls", description: args?.path || "." }, uiTheme);
231
+ return new Text([header, formatErrorMessage(textContent, uiTheme)].join("\n"), 0, 0);
237
232
  }
238
233
 
239
234
  if (
240
235
  (!textContent || textContent.trim() === "" || textContent.trim() === "(empty directory)") &&
241
236
  (!details?.entries || details.entries.length === 0)
242
237
  ) {
243
- return new Text(` ${formatEmptyMessage("Empty directory", uiTheme)}`, 0, 0);
238
+ const header = renderStatusLine({ icon: "warning", title: "Ls", description: args?.path || "." }, uiTheme);
239
+ return new Text([header, formatEmptyMessage("Empty directory", uiTheme)].join("\n"), 0, 0);
244
240
  }
245
241
 
246
242
  let entries: string[] = details?.entries ? [...details.entries] : [];
247
243
  let rawEntries: string[] | undefined = details?.rawEntries;
248
244
  if (entries.length === 0) {
249
245
  const rawLines = textContent.split("\n").filter((l: string) => l.trim());
250
- entries = rawLines.filter((line) => !/^\[.*\]$/.test(line.trim()));
246
+ entries = rawLines.filter(line => !/^\[.*\]$/.test(line.trim()));
251
247
  rawEntries = undefined; // Can't reliably extract raw paths from text
252
248
  }
253
249
 
254
250
  if (entries.length === 0) {
255
- return new Text(` ${formatEmptyMessage("Empty directory", uiTheme)}`, 0, 0);
251
+ const header = renderStatusLine({ icon: "warning", title: "Ls", description: args?.path || "." }, uiTheme);
252
+ return new Text([header, formatEmptyMessage("Empty directory", uiTheme)].join("\n"), 0, 0);
256
253
  }
257
254
 
258
255
  let dirCount = details?.dirCount;
@@ -260,8 +257,11 @@ export const lsToolRenderer = {
260
257
  if (dirCount === undefined || fileCount === undefined) {
261
258
  dirCount = 0;
262
259
  fileCount = 0;
263
- for (const entry of entries) {
264
- if (entry.endsWith("/")) {
260
+ for (let i = 0; i < entries.length; i++) {
261
+ const entry = entries[i];
262
+ const raw = rawEntries?.[i] ?? entry;
263
+ const name = raw.split(" (")[0];
264
+ if (name.endsWith("/")) {
265
265
  dirCount += 1;
266
266
  } else {
267
267
  fileCount += 1;
@@ -272,62 +272,36 @@ export const lsToolRenderer = {
272
272
  const truncation = details?.meta?.truncation;
273
273
  const limits = details?.meta?.limits;
274
274
  const truncated = Boolean(details?.entryLimitReached || truncation || limits?.resultLimit || limits?.headLimit);
275
- const icon = truncated
276
- ? uiTheme.styledSymbol("status.warning", "warning")
277
- : uiTheme.styledSymbol("status.success", "success");
278
-
279
275
  const summaryText = [formatCount("dir", dirCount ?? 0), formatCount("file", fileCount ?? 0)].join(
280
276
  uiTheme.sep.dot,
281
277
  );
282
- const maxEntries = expanded ? entries.length : Math.min(entries.length, COLLAPSED_LIST_LIMIT);
283
- const hasMoreEntries = entries.length > maxEntries;
284
- const expandHint = formatExpandHint(uiTheme, expanded, hasMoreEntries);
278
+ const meta = truncated ? [summaryText, uiTheme.fg("warning", "truncated")] : [summaryText];
279
+ const header = renderStatusLine(
280
+ { icon: truncated ? "warning" : "success", title: "Ls", description: args?.path || ".", meta },
281
+ uiTheme,
282
+ );
285
283
 
286
- let text = ` ${icon} ${uiTheme.fg("dim", summaryText)}${formatTruncationSuffix(truncated, uiTheme)}${expandHint}`;
284
+ const fileLines = renderFileList(
285
+ {
286
+ files: entries.map((entry, index) => ({
287
+ path: entry,
288
+ isDirectory: (rawEntries?.[index] ?? entry).endsWith("/"),
289
+ })),
290
+ expanded,
291
+ maxCollapsed: COLLAPSED_LIST_LIMIT,
292
+ },
293
+ uiTheme,
294
+ );
287
295
 
288
296
  const truncationReasons: string[] = [];
289
- if (limits?.resultLimit) {
290
- truncationReasons.push(`entry limit ${limits.resultLimit.reached}`);
291
- }
292
- if (truncation) {
293
- truncationReasons.push(`output cap ${formatBytes(truncation.outputBytes)}`);
294
- }
295
- if (truncation?.artifactId) {
296
- truncationReasons.push(`full output: artifact://${truncation.artifactId}`);
297
- }
298
-
299
- const hasTruncation = truncationReasons.length > 0;
300
-
301
- for (let i = 0; i < maxEntries; i++) {
302
- const entry = entries[i];
303
- const rawEntry = rawEntries?.[i] ?? entry;
304
- const isLast = i === maxEntries - 1 && !hasMoreEntries && !hasTruncation;
305
- const branch = isLast ? uiTheme.tree.last : uiTheme.tree.branch;
306
- const isDir = rawEntry.endsWith("/");
307
- const entryPath = isDir ? rawEntry.slice(0, -1) : rawEntry;
308
- const lang = isDir ? undefined : getLanguageFromPath(entryPath);
309
- const entryIcon = isDir
310
- ? uiTheme.fg("accent", uiTheme.icon.folder)
311
- : uiTheme.fg("muted", uiTheme.getLangIcon(lang));
312
- const entryColor = isDir ? "accent" : "toolOutput";
313
- text += `\n ${uiTheme.fg("dim", branch)} ${entryIcon} ${uiTheme.fg(entryColor, entry)}`;
314
- }
297
+ if (limits?.resultLimit) truncationReasons.push(`entry limit ${limits.resultLimit.reached}`);
298
+ if (truncation) truncationReasons.push(`output cap ${formatBytes(truncation.outputBytes)}`);
299
+ if (truncation?.artifactId) truncationReasons.push(`full output: artifact://${truncation.artifactId}`);
315
300
 
316
- if (hasMoreEntries) {
317
- const moreEntriesBranch = hasTruncation ? uiTheme.tree.branch : uiTheme.tree.last;
318
- text += `\n ${uiTheme.fg("dim", moreEntriesBranch)} ${uiTheme.fg(
319
- "muted",
320
- formatMoreItems(entries.length - maxEntries, "entry", uiTheme),
321
- )}`;
322
- }
301
+ const extraLines =
302
+ truncationReasons.length > 0 ? [uiTheme.fg("warning", `truncated: ${truncationReasons.join(", ")}`)] : [];
323
303
 
324
- if (hasTruncation) {
325
- text += `\n ${uiTheme.fg("dim", uiTheme.tree.last)} ${uiTheme.fg(
326
- "warning",
327
- `truncated: ${truncationReasons.join(", ")}`,
328
- )}`;
329
- }
330
-
331
- return new Text(text, 0, 0);
304
+ return new Text([header, ...fileLines, ...extraLines].join("\n"), 0, 0);
332
305
  },
306
+ mergeCallAndResult: true,
333
307
  };
@@ -1,21 +1,15 @@
1
1
  import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
2
2
  import { StringEnum } from "@oh-my-pi/pi-ai";
3
- import type { RenderResultOptions } from "@oh-my-pi/pi-coding-agent/extensibility/custom-tools/types";
4
- import type { Theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
5
- import type { ToolSession } from "@oh-my-pi/pi-coding-agent/sdk";
6
3
  import type { Component } from "@oh-my-pi/pi-tui";
7
4
  import { Text } from "@oh-my-pi/pi-tui";
8
5
  import { untilAborted } from "@oh-my-pi/pi-utils";
9
6
  import { type Static, Type } from "@sinclair/typebox";
7
+ import type { RenderResultOptions } from "../extensibility/custom-tools/types";
8
+ import type { Theme } from "../modes/theme/theme";
9
+ import type { ToolSession } from "../sdk";
10
+ import { renderCodeCell, renderStatusLine } from "../tui";
10
11
  import { resolveToCwd } from "./path-utils";
11
- import {
12
- formatCount,
13
- formatErrorMessage,
14
- formatExpandHint,
15
- formatMeta,
16
- formatMoreItems,
17
- PREVIEW_LIMITS,
18
- } from "./render-utils";
12
+ import { formatCount, formatErrorMessage, PREVIEW_LIMITS } from "./render-utils";
19
13
 
20
14
  const notebookSchema = Type.Object({
21
15
  action: StringEnum(["edit", "insert", "delete"], {
@@ -200,57 +194,31 @@ export class NotebookTool implements AgentTool<typeof notebookSchema, NotebookTo
200
194
 
201
195
  interface NotebookRenderArgs {
202
196
  action: string;
203
- notebookPath: string;
197
+ notebookPath?: string;
198
+ notebook_path?: string;
204
199
  cellNumber?: number;
200
+ cell_index?: number;
205
201
  cellType?: string;
202
+ cell_type?: string;
206
203
  content?: string;
207
204
  }
208
205
 
209
206
  const COLLAPSED_TEXT_LIMIT = PREVIEW_LIMITS.COLLAPSED_LINES * 2;
210
207
 
211
- function normalizeCellLines(lines: string[]): string[] {
212
- return lines.map((line) => (line.endsWith("\n") ? line.slice(0, -1) : line));
213
- }
214
-
215
- function renderCellPreview(lines: string[], expanded: boolean, uiTheme: Theme): string {
216
- const normalized = normalizeCellLines(lines);
217
- if (normalized.length === 0) {
218
- return `\n ${uiTheme.fg("dim", uiTheme.tree.last)} ${uiTheme.fg("muted", "(empty cell)")}`;
219
- }
220
-
221
- const maxLines = expanded ? normalized.length : Math.min(normalized.length, COLLAPSED_TEXT_LIMIT);
222
- let text = "";
223
-
224
- for (let i = 0; i < maxLines; i++) {
225
- const isLast = i === maxLines - 1 && (expanded || normalized.length <= maxLines);
226
- const branch = isLast ? uiTheme.tree.last : uiTheme.tree.branch;
227
- const line = normalized[i];
228
- text += `\n ${uiTheme.fg("dim", branch)} ${uiTheme.fg("toolOutput", line)}`;
229
- }
230
-
231
- const remaining = normalized.length - maxLines;
232
- if (remaining > 0) {
233
- text += `\n ${uiTheme.fg("dim", uiTheme.tree.last)} ${uiTheme.fg(
234
- "muted",
235
- formatMoreItems(remaining, "line", uiTheme),
236
- )}`;
237
- }
238
-
239
- return text;
240
- }
241
-
242
208
  export const notebookToolRenderer = {
243
209
  renderCall(args: NotebookRenderArgs, uiTheme: Theme): Component {
244
- const label = uiTheme.fg("toolTitle", uiTheme.bold("Notebook"));
245
- let text = `${label} ${uiTheme.fg("accent", args.action || "?")}`;
246
-
247
210
  const meta: string[] = [];
248
- meta.push(`in ${args.notebookPath || "?"}`);
249
- if (args.cellNumber !== undefined) meta.push(`cell:${args.cellNumber}`);
250
- if (args.cellType) meta.push(`type:${args.cellType}`);
251
-
252
- text += formatMeta(meta, uiTheme);
253
-
211
+ const notebookPath = args.notebookPath ?? args.notebook_path;
212
+ const cellNumber = args.cellNumber ?? args.cell_index;
213
+ const cellType = args.cellType ?? args.cell_type;
214
+ meta.push(`in ${notebookPath || "?"}`);
215
+ if (cellNumber !== undefined) meta.push(`cell:${cellNumber}`);
216
+ if (cellType) meta.push(`type:${cellType}`);
217
+
218
+ const text = renderStatusLine(
219
+ { icon: "pending", title: "Notebook", description: args.action || "?", meta },
220
+ uiTheme,
221
+ );
254
222
  return new Text(text, 0, 0);
255
223
  },
256
224
 
@@ -258,10 +226,13 @@ export const notebookToolRenderer = {
258
226
  result: { content: Array<{ type: string; text?: string }>; details?: NotebookToolDetails },
259
227
  { expanded }: RenderResultOptions,
260
228
  uiTheme: Theme,
229
+ args?: NotebookRenderArgs,
261
230
  ): Component {
262
231
  const content = result.content?.[0];
263
232
  if (content?.type === "text" && content.text?.startsWith("Error:")) {
264
- return new Text(formatErrorMessage(content.text, uiTheme), 0, 0);
233
+ const notebookPath = args?.notebookPath ?? args?.notebook_path ?? "?";
234
+ const header = renderStatusLine({ icon: "error", title: "Notebook", description: notebookPath }, uiTheme);
235
+ return new Text([header, formatErrorMessage(content.text, uiTheme)].join("\n"), 0, 0);
265
236
  }
266
237
 
267
238
  const details = result.details;
@@ -269,25 +240,38 @@ export const notebookToolRenderer = {
269
240
  const cellIndex = details?.cellIndex;
270
241
  const cellType = details?.cellType;
271
242
  const totalCells = details?.totalCells;
272
- const cellSource = details?.cellSource;
273
- const lineCount = cellSource?.length;
274
- const canExpand = cellSource !== undefined && cellSource.length > COLLAPSED_TEXT_LIMIT;
243
+ const cellSource = details?.cellSource ?? [];
244
+ const lineCount = cellSource.length;
275
245
 
276
- const icon = uiTheme.styledSymbol("status.success", "success");
277
246
  const actionLabel = action === "insert" ? "Inserted" : action === "delete" ? "Deleted" : "Edited";
278
247
  const cellLabel = cellType || "cell";
279
- const summaryParts = [`${actionLabel} ${cellLabel} at index ${cellIndex ?? "?"}`];
280
- if (lineCount !== undefined) summaryParts.push(formatCount("line", lineCount));
248
+ const summaryParts = [`${actionLabel} ${cellLabel} ${cellIndex ?? "?"}`];
249
+ if (lineCount > 0) summaryParts.push(formatCount("line", lineCount));
281
250
  if (totalCells !== undefined) summaryParts.push(`${totalCells} total`);
282
- const summaryText = summaryParts.join(uiTheme.sep.dot);
283
251
 
284
- const expandHint = expanded || !canExpand ? "" : formatExpandHint(uiTheme);
285
- let text = `${icon} ${uiTheme.fg("dim", summaryText)}${expandHint}`;
252
+ const outputLines = summaryParts.map(part => uiTheme.fg("dim", part));
253
+ const codeText = cellSource.join("");
254
+ const language = cellType === "markdown" ? "markdown" : undefined;
286
255
 
287
- if (cellSource) {
288
- text += renderCellPreview(cellSource, expanded, uiTheme);
289
- }
290
-
291
- return new Text(text, 0, 0);
256
+ const notebookPath = args?.notebookPath ?? args?.notebook_path;
257
+ const notebookLabel = notebookPath ? `${actionLabel} ${notebookPath}` : "Notebook";
258
+ return {
259
+ render: (width: number) =>
260
+ renderCodeCell(
261
+ {
262
+ code: codeText,
263
+ language,
264
+ title: notebookLabel,
265
+ status: "complete",
266
+ output: outputLines.join("\n"),
267
+ codeMaxLines: expanded ? Number.POSITIVE_INFINITY : COLLAPSED_TEXT_LIMIT,
268
+ expanded,
269
+ width,
270
+ },
271
+ uiTheme,
272
+ ),
273
+ invalidate: () => {},
274
+ };
292
275
  },
276
+ mergeCallAndResult: true,
293
277
  };
@@ -4,13 +4,12 @@
4
4
  * Tools populate details.meta using the fluent OutputMetaBuilder.
5
5
  * The tool wrapper automatically formats and appends notices at message boundary.
6
6
  */
7
-
8
7
  import type { AgentTool, AgentToolResult } from "@oh-my-pi/pi-agent-core";
9
8
  import type { ImageContent, TextContent } from "@oh-my-pi/pi-ai";
10
- import type { OutputSummary } from "@oh-my-pi/pi-coding-agent/session/streaming-output";
11
- import type { TruncationResult } from "@oh-my-pi/pi-coding-agent/tools/truncate";
12
- import { formatSize } from "@oh-my-pi/pi-coding-agent/tools/truncate";
9
+ import type { OutputSummary } from "../session/streaming-output";
13
10
  import { renderError } from "./tool-errors";
11
+ import type { TruncationResult } from "./truncate";
12
+ import { formatSize } from "./truncate";
14
13
 
15
14
  /**
16
15
  * Truncation metadata for the output notice.
@@ -1,5 +1,5 @@
1
- import { ArtifactManager } from "@oh-my-pi/pi-coding-agent/session/artifacts";
2
- import type { ToolSession } from "./index";
1
+ import { ArtifactManager } from "../session/artifacts";
2
+ import type { ToolSession } from ".";
3
3
 
4
4
  export interface TailBuffer {
5
5
  append(chunk: string): void;
@@ -1,6 +1,6 @@
1
- import { accessSync, constants } from "node:fs";
1
+ import * as fs from "node:fs";
2
2
  import * as os from "node:os";
3
- import { isAbsolute, resolve as resolvePath } from "node:path";
3
+ import * as path from "node:path";
4
4
 
5
5
  const UNICODE_SPACES = /[\u00A0\u2000-\u200A\u202F\u205F\u3000]/g;
6
6
  const NARROW_NO_BREAK_SPACE = "\u202F";
@@ -15,7 +15,7 @@ function tryMacOSScreenshotPath(filePath: string): string {
15
15
 
16
16
  function fileExists(filePath: string): boolean {
17
17
  try {
18
- accessSync(filePath, constants.F_OK);
18
+ fs.accessSync(filePath, fs.constants.F_OK);
19
19
  return true;
20
20
  } catch {
21
21
  return false;
@@ -39,10 +39,10 @@ export function expandPath(filePath: string): string {
39
39
  */
40
40
  export function resolveToCwd(filePath: string, cwd: string): string {
41
41
  const expanded = expandPath(filePath);
42
- if (isAbsolute(expanded)) {
42
+ if (path.isAbsolute(expanded)) {
43
43
  return expanded;
44
44
  }
45
- return resolvePath(cwd, expanded);
45
+ return path.resolve(cwd, expanded);
46
46
  }
47
47
 
48
48
  export function resolveReadPath(filePath: string, cwd: string): string {