@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
@@ -4,29 +4,24 @@
4
4
  * Primary provider for OMP native configs. Supports all capabilities.
5
5
  * .pi is an alias for backwards compatibility.
6
6
  */
7
-
8
- import { type ContextFile, contextFileCapability } from "@oh-my-pi/pi-coding-agent/capability/context-file";
9
- import {
10
- type Extension,
11
- type ExtensionManifest,
12
- extensionCapability,
13
- } from "@oh-my-pi/pi-coding-agent/capability/extension";
14
- import { type ExtensionModule, extensionModuleCapability } from "@oh-my-pi/pi-coding-agent/capability/extension-module";
15
- import { readDirEntries, readFile } from "@oh-my-pi/pi-coding-agent/capability/fs";
16
- import { type Hook, hookCapability } from "@oh-my-pi/pi-coding-agent/capability/hook";
17
- import { registerProvider } from "@oh-my-pi/pi-coding-agent/capability/index";
18
- import { type Instruction, instructionCapability } from "@oh-my-pi/pi-coding-agent/capability/instruction";
19
- import { type MCPServer, mcpCapability } from "@oh-my-pi/pi-coding-agent/capability/mcp";
20
- import { type Prompt, promptCapability } from "@oh-my-pi/pi-coding-agent/capability/prompt";
21
- import { type Rule, ruleCapability } from "@oh-my-pi/pi-coding-agent/capability/rule";
22
- import { type Settings, settingsCapability } from "@oh-my-pi/pi-coding-agent/capability/settings";
23
- import { type Skill, skillCapability } from "@oh-my-pi/pi-coding-agent/capability/skill";
24
- import { type SlashCommand, slashCommandCapability } from "@oh-my-pi/pi-coding-agent/capability/slash-command";
25
- import { type SystemPrompt, systemPromptCapability } from "@oh-my-pi/pi-coding-agent/capability/system-prompt";
26
- import { type CustomTool, toolCapability } from "@oh-my-pi/pi-coding-agent/capability/tool";
27
- import type { LoadContext, LoadResult } from "@oh-my-pi/pi-coding-agent/capability/types";
28
- import { parseFrontmatter } from "@oh-my-pi/pi-coding-agent/utils/frontmatter";
29
- import { dirname, isAbsolute, join, resolve } from "path";
7
+ import * as path from "node:path";
8
+ import { registerProvider } from "../capability";
9
+ import { type ContextFile, contextFileCapability } from "../capability/context-file";
10
+ import { type Extension, type ExtensionManifest, extensionCapability } from "../capability/extension";
11
+ import { type ExtensionModule, extensionModuleCapability } from "../capability/extension-module";
12
+ import { readDirEntries, readFile } from "../capability/fs";
13
+ import { type Hook, hookCapability } from "../capability/hook";
14
+ import { type Instruction, instructionCapability } from "../capability/instruction";
15
+ import { type MCPServer, mcpCapability } from "../capability/mcp";
16
+ import { type Prompt, promptCapability } from "../capability/prompt";
17
+ import { type Rule, ruleCapability } from "../capability/rule";
18
+ import { type Settings, settingsCapability } from "../capability/settings";
19
+ import { type Skill, skillCapability } from "../capability/skill";
20
+ import { type SlashCommand, slashCommandCapability } from "../capability/slash-command";
21
+ import { type SystemPrompt, systemPromptCapability } from "../capability/system-prompt";
22
+ import { type CustomTool, toolCapability } from "../capability/tool";
23
+ import type { LoadContext, LoadResult } from "../capability/types";
24
+ import { parseFrontmatter } from "../utils/frontmatter";
30
25
  import {
31
26
  createSourceMeta,
32
27
  discoverExtensionModulePaths,
@@ -51,7 +46,7 @@ async function getConfigDirs(ctx: LoadContext): Promise<Array<{ dir: string; lev
51
46
  const result: Array<{ dir: string; level: "user" | "project" }> = [];
52
47
 
53
48
  for (const name of PROJECT_DIRS) {
54
- const projectDir = join(ctx.cwd, name);
49
+ const projectDir = path.join(ctx.cwd, name);
55
50
  const entries = await readDirEntries(projectDir);
56
51
  if (entries.length > 0) {
57
52
  result.push({ dir: projectDir, level: "project" });
@@ -60,7 +55,7 @@ async function getConfigDirs(ctx: LoadContext): Promise<Array<{ dir: string; lev
60
55
  }
61
56
 
62
57
  for (const name of USER_DIRS) {
63
- const userDir = join(ctx.home, name, PATHS.userAgent.replace(`${PATHS.userBase}/`, ""));
58
+ const userDir = path.join(ctx.home, name, PATHS.userAgent.replace(`${PATHS.userBase}/`, ""));
64
59
  const entries = await readDirEntries(userDir);
65
60
  if (entries.length > 0) {
66
61
  result.push({ dir: userDir, level: "user" });
@@ -99,18 +94,18 @@ async function loadMCPServers(ctx: LoadContext): Promise<LoadResult<MCPServer>>
99
94
  };
100
95
 
101
96
  const projectDirs = await Promise.all(
102
- PROJECT_DIRS.map(async (name) => {
103
- const dir = join(ctx.cwd, name);
97
+ PROJECT_DIRS.map(async name => {
98
+ const dir = path.join(ctx.cwd, name);
104
99
  const entries = await readDirEntries(dir);
105
100
  return entries.length > 0 ? dir : null;
106
101
  }),
107
102
  );
108
- const userPaths = USER_DIRS.map((name) => join(ctx.home, name, "mcp.json"));
103
+ const userPaths = USER_DIRS.map(name => path.join(ctx.home, name, "mcp.json"));
109
104
 
110
- const projectDir = projectDirs.find((dir) => dir !== null);
105
+ const projectDir = projectDirs.find(dir => dir !== null);
111
106
  if (projectDir) {
112
- const projectCandidates = ["mcp.json", ".mcp.json"].map((filename) => join(projectDir, filename));
113
- const projectContents = await Promise.all(projectCandidates.map((path) => readFile(path)));
107
+ const projectCandidates = ["mcp.json", ".mcp.json"].map(filename => path.join(projectDir, filename));
108
+ const projectContents = await Promise.all(projectCandidates.map(path => readFile(path)));
114
109
  for (let i = 0; i < projectCandidates.length; i++) {
115
110
  const content = projectContents[i];
116
111
  if (content) {
@@ -120,7 +115,7 @@ async function loadMCPServers(ctx: LoadContext): Promise<LoadResult<MCPServer>>
120
115
  }
121
116
  }
122
117
 
123
- const userContents = await Promise.all(userPaths.map((path) => readFile(path)));
118
+ const userContents = await Promise.all(userPaths.map(path => readFile(path)));
124
119
  for (let i = 0; i < userPaths.length; i++) {
125
120
  const content = userContents[i];
126
121
  if (content) {
@@ -144,10 +139,10 @@ registerProvider<MCPServer>(mcpCapability.id, {
144
139
  async function loadSystemPrompt(ctx: LoadContext): Promise<LoadResult<SystemPrompt>> {
145
140
  const items: SystemPrompt[] = [];
146
141
 
147
- const userPaths = USER_DIRS.map((name) =>
148
- join(ctx.home, name, PATHS.userAgent.replace(`${PATHS.userBase}/`, ""), "SYSTEM.md"),
142
+ const userPaths = USER_DIRS.map(name =>
143
+ path.join(ctx.home, name, PATHS.userAgent.replace(`${PATHS.userBase}/`, ""), "SYSTEM.md"),
149
144
  );
150
- const userContents = await Promise.all(userPaths.map((p) => readFile(p)));
145
+ const userContents = await Promise.all(userPaths.map(p => readFile(p)));
151
146
  for (let i = 0; i < userPaths.length; i++) {
152
147
  const content = userContents[i];
153
148
  if (content) {
@@ -165,18 +160,18 @@ async function loadSystemPrompt(ctx: LoadContext): Promise<LoadResult<SystemProm
165
160
  let current = ctx.cwd;
166
161
  while (true) {
167
162
  ancestors.push(current);
168
- const parent = dirname(current);
163
+ const parent = path.dirname(current);
169
164
  if (parent === current) break;
170
165
  current = parent;
171
166
  }
172
167
 
173
168
  for (const dir of ancestors) {
174
- const configDirs = PROJECT_DIRS.map((name) => join(dir, name));
175
- const entriesResults = await Promise.all(configDirs.map((d) => readDirEntries(d)));
169
+ const configDirs = PROJECT_DIRS.map(name => path.join(dir, name));
170
+ const entriesResults = await Promise.all(configDirs.map(d => readDirEntries(d)));
176
171
  const validConfigDir = configDirs.find((_, i) => entriesResults[i].length > 0);
177
172
  if (!validConfigDir) continue;
178
173
 
179
- const projectPath = join(validConfigDir, "SYSTEM.md");
174
+ const projectPath = path.join(validConfigDir, "SYSTEM.md");
180
175
  const content = await readFile(projectPath);
181
176
  if (content) {
182
177
  items.push({
@@ -206,7 +201,7 @@ async function loadSkills(ctx: LoadContext): Promise<LoadResult<Skill>> {
206
201
  const results = await Promise.all(
207
202
  configDirs.map(({ dir, level }) =>
208
203
  loadSkillsFromDir(ctx, {
209
- dir: join(dir, "skills"),
204
+ dir: path.join(dir, "skills"),
210
205
  providerId: PROVIDER_ID,
211
206
  level,
212
207
  requireDescription: true,
@@ -215,8 +210,8 @@ async function loadSkills(ctx: LoadContext): Promise<LoadResult<Skill>> {
215
210
  );
216
211
 
217
212
  return {
218
- items: results.flatMap((r) => r.items),
219
- warnings: results.flatMap((r) => r.warnings ?? []),
213
+ items: results.flatMap(r => r.items),
214
+ warnings: results.flatMap(r => r.warnings ?? []),
220
215
  };
221
216
  }
222
217
 
@@ -234,7 +229,7 @@ async function loadSlashCommands(ctx: LoadContext): Promise<LoadResult<SlashComm
234
229
  const warnings: string[] = [];
235
230
 
236
231
  for (const { dir, level } of await getConfigDirs(ctx)) {
237
- const commandsDir = join(dir, "commands");
232
+ const commandsDir = path.join(dir, "commands");
238
233
  const result = await loadFilesFromDir<SlashCommand>(ctx, commandsDir, PROVIDER_ID, level, {
239
234
  extensions: ["md"],
240
235
  transform: (name, content, path, source) => ({
@@ -266,7 +261,7 @@ async function loadRules(ctx: LoadContext): Promise<LoadResult<Rule>> {
266
261
  const warnings: string[] = [];
267
262
 
268
263
  for (const { dir, level } of await getConfigDirs(ctx)) {
269
- const rulesDir = join(dir, "rules");
264
+ const rulesDir = path.join(dir, "rules");
270
265
  const result = await loadFilesFromDir<Rule>(ctx, rulesDir, PROVIDER_ID, level, {
271
266
  extensions: ["md", "mdc"],
272
267
  transform: (name, content, path, source) => {
@@ -304,7 +299,7 @@ async function loadPrompts(ctx: LoadContext): Promise<LoadResult<Prompt>> {
304
299
  const warnings: string[] = [];
305
300
 
306
301
  for (const { dir, level } of await getConfigDirs(ctx)) {
307
- const promptsDir = join(dir, "prompts");
302
+ const promptsDir = path.join(dir, "prompts");
308
303
  const result = await loadFilesFromDir<Prompt>(ctx, promptsDir, PROVIDER_ID, level, {
309
304
  extensions: ["md"],
310
305
  transform: (name, content, path, source) => ({
@@ -336,15 +331,15 @@ async function loadExtensionModules(ctx: LoadContext): Promise<LoadResult<Extens
336
331
 
337
332
  const resolveExtensionPath = (rawPath: string): string => {
338
333
  if (rawPath.startsWith("~/")) {
339
- return join(ctx.home, rawPath.slice(2));
334
+ return path.join(ctx.home, rawPath.slice(2));
340
335
  }
341
336
  if (rawPath.startsWith("~")) {
342
- return join(ctx.home, rawPath.slice(1));
337
+ return path.join(ctx.home, rawPath.slice(1));
343
338
  }
344
- if (isAbsolute(rawPath)) {
339
+ if (path.isAbsolute(rawPath)) {
345
340
  return rawPath;
346
341
  }
347
- return resolve(ctx.cwd, rawPath);
342
+ return path.resolve(ctx.cwd, rawPath);
348
343
  };
349
344
 
350
345
  const createExtensionModule = (extPath: string, level: "user" | "project"): ExtensionModule => ({
@@ -357,8 +352,8 @@ async function loadExtensionModules(ctx: LoadContext): Promise<LoadResult<Extens
357
352
  const configDirs = await getConfigDirs(ctx);
358
353
 
359
354
  const [discoveredResults, settingsResults] = await Promise.all([
360
- Promise.all(configDirs.map(({ dir }) => discoverExtensionModulePaths(ctx, join(dir, "extensions")))),
361
- Promise.all(configDirs.map(({ dir }) => readFile(join(dir, "settings.json")))),
355
+ Promise.all(configDirs.map(({ dir }) => discoverExtensionModulePaths(ctx, path.join(dir, "extensions")))),
356
+ Promise.all(configDirs.map(({ dir }) => readFile(path.join(dir, "settings.json")))),
362
357
  ]);
363
358
 
364
359
  for (let i = 0; i < configDirs.length; i++) {
@@ -379,7 +374,7 @@ async function loadExtensionModules(ctx: LoadContext): Promise<LoadResult<Extens
379
374
  const settingsContent = settingsResults[i];
380
375
  if (!settingsContent) continue;
381
376
 
382
- const settingsPath = join(dir, "settings.json");
377
+ const settingsPath = path.join(dir, "settings.json");
383
378
  const settingsData = parseJSON<{ extensions?: unknown }>(settingsContent);
384
379
  const extensions = settingsData?.extensions;
385
380
  if (!Array.isArray(extensions)) continue;
@@ -424,7 +419,7 @@ async function loadExtensionModules(ctx: LoadContext): Promise<LoadResult<Extens
424
419
  }
425
420
  }
426
421
 
427
- const dirDiscoveryResults = await Promise.all(dirDiscoveryPromises.map((d) => d.promise));
422
+ const dirDiscoveryResults = await Promise.all(dirDiscoveryPromises.map(d => d.promise));
428
423
  for (let i = 0; i < dirDiscoveryPromises.length; i++) {
429
424
  const { level } = dirDiscoveryPromises[i];
430
425
  for (const extPath of dirDiscoveryResults[i]) {
@@ -449,7 +444,7 @@ async function loadExtensions(ctx: LoadContext): Promise<LoadResult<Extension>>
449
444
  const warnings: string[] = [];
450
445
 
451
446
  const configDirs = await getConfigDirs(ctx);
452
- const entriesResults = await Promise.all(configDirs.map(({ dir }) => readDirEntries(join(dir, "extensions"))));
447
+ const entriesResults = await Promise.all(configDirs.map(({ dir }) => readDirEntries(path.join(dir, "extensions"))));
453
448
 
454
449
  const manifestCandidates: Array<{
455
450
  extDir: string;
@@ -461,16 +456,16 @@ async function loadExtensions(ctx: LoadContext): Promise<LoadResult<Extension>>
461
456
  for (let i = 0; i < configDirs.length; i++) {
462
457
  const { dir, level } = configDirs[i];
463
458
  const entries = entriesResults[i];
464
- const extensionsDir = join(dir, "extensions");
459
+ const extensionsDir = path.join(dir, "extensions");
465
460
 
466
461
  for (const entry of entries) {
467
462
  if (entry.name.startsWith(".")) continue;
468
463
  if (!entry.isDirectory()) continue;
469
464
 
470
- const extDir = join(extensionsDir, entry.name);
465
+ const extDir = path.join(extensionsDir, entry.name);
471
466
  manifestCandidates.push({
472
467
  extDir,
473
- manifestPath: join(extDir, "gemini-extension.json"),
468
+ manifestPath: path.join(extDir, "gemini-extension.json"),
474
469
  entryName: entry.name,
475
470
  level,
476
471
  });
@@ -516,7 +511,7 @@ async function loadInstructions(ctx: LoadContext): Promise<LoadResult<Instructio
516
511
  const warnings: string[] = [];
517
512
 
518
513
  for (const { dir, level } of await getConfigDirs(ctx)) {
519
- const instructionsDir = join(dir, "instructions");
514
+ const instructionsDir = path.join(dir, "instructions");
520
515
  const result = await loadFilesFromDir<Instruction>(ctx, instructionsDir, PROVIDER_ID, level, {
521
516
  extensions: ["md"],
522
517
  transform: (name, content, path, source) => {
@@ -561,7 +556,7 @@ async function loadHooks(ctx: LoadContext): Promise<LoadResult<Hook>> {
561
556
  for (const { dir, level } of configDirs) {
562
557
  for (const hookType of hookTypes) {
563
558
  typeDirRequests.push({
564
- typeDir: join(dir, "hooks", hookType),
559
+ typeDir: path.join(dir, "hooks", hookType),
565
560
  hookType,
566
561
  level,
567
562
  });
@@ -578,17 +573,17 @@ async function loadHooks(ctx: LoadContext): Promise<LoadResult<Hook>> {
578
573
  if (entry.name.startsWith(".")) continue;
579
574
  if (!entry.isFile()) continue;
580
575
 
581
- const path = join(typeDir, entry.name);
576
+ const hookPath = path.join(typeDir, entry.name);
582
577
  const baseName = entry.name.includes(".") ? entry.name.slice(0, entry.name.lastIndexOf(".")) : entry.name;
583
578
  const tool = baseName === "*" ? "*" : baseName;
584
579
 
585
580
  items.push({
586
581
  name: entry.name,
587
- path,
582
+ path: hookPath,
588
583
  type: hookType,
589
584
  tool,
590
585
  level,
591
- _source: createSourceMeta(PROVIDER_ID, path, level),
586
+ _source: createSourceMeta(PROVIDER_ID, hookPath, level),
592
587
  });
593
588
  }
594
589
  }
@@ -610,7 +605,7 @@ async function loadTools(ctx: LoadContext): Promise<LoadResult<CustomTool>> {
610
605
  const warnings: string[] = [];
611
606
 
612
607
  const configDirs = await getConfigDirs(ctx);
613
- const entriesResults = await Promise.all(configDirs.map(({ dir }) => readDirEntries(join(dir, "tools"))));
608
+ const entriesResults = await Promise.all(configDirs.map(({ dir }) => readDirEntries(path.join(dir, "tools"))));
614
609
 
615
610
  const fileLoadPromises: Array<Promise<{ items: CustomTool[]; warnings?: string[] }>> = [];
616
611
  const subDirCandidates: Array<{
@@ -624,7 +619,7 @@ async function loadTools(ctx: LoadContext): Promise<LoadResult<CustomTool>> {
624
619
  const toolEntries = entriesResults[i];
625
620
  if (toolEntries.length === 0) continue;
626
621
 
627
- const toolsDir = join(dir, "tools");
622
+ const toolsDir = path.join(dir, "tools");
628
623
 
629
624
  fileLoadPromises.push(
630
625
  loadFilesFromDir<CustomTool>(ctx, toolsDir, PROVIDER_ID, level, {
@@ -657,7 +652,7 @@ async function loadTools(ctx: LoadContext): Promise<LoadResult<CustomTool>> {
657
652
  if (!entry.isDirectory()) continue;
658
653
 
659
654
  subDirCandidates.push({
660
- indexPath: join(toolsDir, entry.name, "index.ts"),
655
+ indexPath: path.join(toolsDir, entry.name, "index.ts"),
661
656
  entryName: entry.name,
662
657
  level,
663
658
  });
@@ -705,7 +700,7 @@ async function loadSettings(ctx: LoadContext): Promise<LoadResult<Settings>> {
705
700
  const warnings: string[] = [];
706
701
 
707
702
  for (const { dir, level } of await getConfigDirs(ctx)) {
708
- const settingsPath = join(dir, "settings.json");
703
+ const settingsPath = path.join(dir, "settings.json");
709
704
  const content = await readFile(settingsPath);
710
705
  if (!content) continue;
711
706
 
@@ -739,10 +734,10 @@ async function loadContextFiles(ctx: LoadContext): Promise<LoadResult<ContextFil
739
734
  const items: ContextFile[] = [];
740
735
  const warnings: string[] = [];
741
736
 
742
- const userPaths = USER_DIRS.map((name) =>
743
- join(ctx.home, name, PATHS.userAgent.replace(`${PATHS.userBase}/`, ""), "AGENTS.md"),
737
+ const userPaths = USER_DIRS.map(name =>
738
+ path.join(ctx.home, name, PATHS.userAgent.replace(`${PATHS.userBase}/`, ""), "AGENTS.md"),
744
739
  );
745
- const userContents = await Promise.all(userPaths.map((p) => readFile(p)));
740
+ const userContents = await Promise.all(userPaths.map(p => readFile(p)));
746
741
  for (let i = 0; i < userPaths.length; i++) {
747
742
  const content = userContents[i];
748
743
  if (content) {
@@ -761,19 +756,19 @@ async function loadContextFiles(ctx: LoadContext): Promise<LoadResult<ContextFil
761
756
  let depth = 0;
762
757
  while (true) {
763
758
  ancestors.push({ dir: current, depth });
764
- const parent = dirname(current);
759
+ const parent = path.dirname(current);
765
760
  if (parent === current) break;
766
761
  current = parent;
767
762
  depth++;
768
763
  }
769
764
 
770
765
  for (const { dir, depth: ancestorDepth } of ancestors) {
771
- const configDirs = PROJECT_DIRS.map((name) => join(dir, name));
772
- const entriesResults = await Promise.all(configDirs.map((d) => readDirEntries(d)));
766
+ const configDirs = PROJECT_DIRS.map(name => path.join(dir, name));
767
+ const entriesResults = await Promise.all(configDirs.map(d => readDirEntries(d)));
773
768
  const validConfigDir = configDirs.find((_, i) => entriesResults[i].length > 0);
774
769
  if (!validConfigDir) continue;
775
770
 
776
- const projectPath = join(validConfigDir, "AGENTS.md");
771
+ const projectPath = path.join(validConfigDir, "AGENTS.md");
777
772
  const content = await readFile(projectPath);
778
773
  if (content) {
779
774
  items.push({
@@ -4,20 +4,19 @@
4
4
  * Loads configuration from .claude directories.
5
5
  * Priority: 80 (tool-specific, below builtin but above shared standards)
6
6
  */
7
-
8
- import { join, sep } from "node:path";
9
- import { type ContextFile, contextFileCapability } from "@oh-my-pi/pi-coding-agent/capability/context-file";
10
- import { type ExtensionModule, extensionModuleCapability } from "@oh-my-pi/pi-coding-agent/capability/extension-module";
11
- import { readFile } from "@oh-my-pi/pi-coding-agent/capability/fs";
12
- import { type Hook, hookCapability } from "@oh-my-pi/pi-coding-agent/capability/hook";
13
- import { registerProvider } from "@oh-my-pi/pi-coding-agent/capability/index";
14
- import { type MCPServer, mcpCapability } from "@oh-my-pi/pi-coding-agent/capability/mcp";
15
- import { type Settings, settingsCapability } from "@oh-my-pi/pi-coding-agent/capability/settings";
16
- import { type Skill, skillCapability } from "@oh-my-pi/pi-coding-agent/capability/skill";
17
- import { type SlashCommand, slashCommandCapability } from "@oh-my-pi/pi-coding-agent/capability/slash-command";
18
- import { type SystemPrompt, systemPromptCapability } from "@oh-my-pi/pi-coding-agent/capability/system-prompt";
19
- import { type CustomTool, toolCapability } from "@oh-my-pi/pi-coding-agent/capability/tool";
20
- import type { LoadContext, LoadResult } from "@oh-my-pi/pi-coding-agent/capability/types";
7
+ import * as path from "node:path";
8
+ import { registerProvider } from "../capability";
9
+ import { type ContextFile, contextFileCapability } from "../capability/context-file";
10
+ import { type ExtensionModule, extensionModuleCapability } from "../capability/extension-module";
11
+ import { readFile } from "../capability/fs";
12
+ import { type Hook, hookCapability } from "../capability/hook";
13
+ import { type MCPServer, mcpCapability } from "../capability/mcp";
14
+ import { type Settings, settingsCapability } from "../capability/settings";
15
+ import { type Skill, skillCapability } from "../capability/skill";
16
+ import { type SlashCommand, slashCommandCapability } from "../capability/slash-command";
17
+ import { type SystemPrompt, systemPromptCapability } from "../capability/system-prompt";
18
+ import { type CustomTool, toolCapability } from "../capability/tool";
19
+ import type { LoadContext, LoadResult } from "../capability/types";
21
20
  import {
22
21
  calculateDepth,
23
22
  createSourceMeta,
@@ -38,14 +37,14 @@ const CONFIG_DIR = ".claude";
38
37
  * Get user-level .claude path.
39
38
  */
40
39
  function getUserClaude(ctx: LoadContext): string {
41
- return join(ctx.home, CONFIG_DIR);
40
+ return path.join(ctx.home, CONFIG_DIR);
42
41
  }
43
42
 
44
43
  /**
45
44
  * Get project-level .claude path (cwd only).
46
45
  */
47
46
  function getProjectClaude(ctx: LoadContext): string {
48
- return join(ctx.cwd, CONFIG_DIR);
47
+ return path.join(ctx.cwd, CONFIG_DIR);
49
48
  }
50
49
 
51
50
  // =============================================================================
@@ -57,12 +56,12 @@ async function loadMCPServers(ctx: LoadContext): Promise<LoadResult<MCPServer>>
57
56
  const warnings: string[] = [];
58
57
 
59
58
  const userBase = getUserClaude(ctx);
60
- const userClaudeJson = join(ctx.home, ".claude.json");
61
- const userMcpJson = join(userBase, "mcp.json");
59
+ const userClaudeJson = path.join(ctx.home, ".claude.json");
60
+ const userMcpJson = path.join(userBase, "mcp.json");
62
61
 
63
- const projectBase = join(ctx.cwd, CONFIG_DIR);
64
- const projectMcpJson = join(projectBase, ".mcp.json");
65
- const projectMcpJsonAlt = join(projectBase, "mcp.json");
62
+ const projectBase = path.join(ctx.cwd, CONFIG_DIR);
63
+ const projectMcpJson = path.join(projectBase, ".mcp.json");
64
+ const projectMcpJsonAlt = path.join(projectBase, "mcp.json");
66
65
 
67
66
  const userPaths = [
68
67
  { path: userClaudeJson, level: "user" as const },
@@ -126,7 +125,7 @@ async function loadContextFiles(ctx: LoadContext): Promise<LoadResult<ContextFil
126
125
  const warnings: string[] = [];
127
126
 
128
127
  const userBase = getUserClaude(ctx);
129
- const userClaudeMd = join(userBase, "CLAUDE.md");
128
+ const userClaudeMd = path.join(userBase, "CLAUDE.md");
130
129
 
131
130
  const userContent = await readFile(userClaudeMd);
132
131
  if (userContent !== null) {
@@ -139,10 +138,10 @@ async function loadContextFiles(ctx: LoadContext): Promise<LoadResult<ContextFil
139
138
  }
140
139
 
141
140
  const projectBase = getProjectClaude(ctx);
142
- const projectClaudeMd = join(projectBase, "CLAUDE.md");
141
+ const projectClaudeMd = path.join(projectBase, "CLAUDE.md");
143
142
  const projectContent = await readFile(projectClaudeMd);
144
143
  if (projectContent !== null) {
145
- const depth = calculateDepth(ctx.cwd, projectBase, sep);
144
+ const depth = calculateDepth(ctx.cwd, projectBase, path.sep);
146
145
  items.push({
147
146
  path: projectClaudeMd,
148
147
  content: projectContent,
@@ -160,8 +159,8 @@ async function loadContextFiles(ctx: LoadContext): Promise<LoadResult<ContextFil
160
159
  // =============================================================================
161
160
 
162
161
  async function loadSkills(ctx: LoadContext): Promise<LoadResult<Skill>> {
163
- const userSkillsDir = join(getUserClaude(ctx), "skills");
164
- const projectSkillsDir = join(getProjectClaude(ctx), "skills");
162
+ const userSkillsDir = path.join(getUserClaude(ctx), "skills");
163
+ const projectSkillsDir = path.join(getProjectClaude(ctx), "skills");
165
164
 
166
165
  const results = await Promise.all([
167
166
  loadSkillsFromDir(ctx, { dir: userSkillsDir, providerId: PROVIDER_ID, level: "user" }),
@@ -169,8 +168,8 @@ async function loadSkills(ctx: LoadContext): Promise<LoadResult<Skill>> {
169
168
  ]);
170
169
 
171
170
  return {
172
- items: results.flatMap((r) => r.items),
173
- warnings: results.flatMap((r) => r.warnings ?? []),
171
+ items: results.flatMap(r => r.items),
172
+ warnings: results.flatMap(r => r.warnings ?? []),
174
173
  };
175
174
  }
176
175
 
@@ -183,8 +182,8 @@ async function loadExtensionModules(ctx: LoadContext): Promise<LoadResult<Extens
183
182
  const warnings: string[] = [];
184
183
 
185
184
  const userBase = getUserClaude(ctx);
186
- const userExtensionsDir = join(userBase, "extensions");
187
- const projectExtensionsDir = join(ctx.cwd, CONFIG_DIR, "extensions");
185
+ const userExtensionsDir = path.join(userBase, "extensions");
186
+ const projectExtensionsDir = path.join(ctx.cwd, CONFIG_DIR, "extensions");
188
187
 
189
188
  const dirsToDiscover: { dir: string; level: "user" | "project" }[] = [
190
189
  { dir: userExtensionsDir, level: "user" },
@@ -194,7 +193,7 @@ async function loadExtensionModules(ctx: LoadContext): Promise<LoadResult<Extens
194
193
  const pathsByLevel = await Promise.all(
195
194
  dirsToDiscover.map(async ({ dir, level }) => {
196
195
  const paths = await discoverExtensionModulePaths(ctx, dir);
197
- return paths.map((extPath) => ({ extPath, level }));
196
+ return paths.map(extPath => ({ extPath, level }));
198
197
  }),
199
198
  );
200
199
 
@@ -221,7 +220,7 @@ async function loadSlashCommands(ctx: LoadContext): Promise<LoadResult<SlashComm
221
220
  const warnings: string[] = [];
222
221
 
223
222
  const userBase = getUserClaude(ctx);
224
- const userCommandsDir = join(userBase, "commands");
223
+ const userCommandsDir = path.join(userBase, "commands");
225
224
 
226
225
  const userResult = await loadFilesFromDir<SlashCommand>(ctx, userCommandsDir, PROVIDER_ID, "user", {
227
226
  extensions: ["md"],
@@ -240,7 +239,7 @@ async function loadSlashCommands(ctx: LoadContext): Promise<LoadResult<SlashComm
240
239
  items.push(...userResult.items);
241
240
  if (userResult.warnings) warnings.push(...userResult.warnings);
242
241
 
243
- const projectCommandsDir = join(ctx.cwd, CONFIG_DIR, "commands");
242
+ const projectCommandsDir = path.join(ctx.cwd, CONFIG_DIR, "commands");
244
243
 
245
244
  const projectResult = await loadFilesFromDir<SlashCommand>(ctx, projectCommandsDir, PROVIDER_ID, "project", {
246
245
  extensions: ["md"],
@@ -271,18 +270,18 @@ async function loadHooks(ctx: LoadContext): Promise<LoadResult<Hook>> {
271
270
  const warnings: string[] = [];
272
271
 
273
272
  const userBase = getUserClaude(ctx);
274
- const userHooksDir = join(userBase, "hooks");
273
+ const userHooksDir = path.join(userBase, "hooks");
275
274
  const projectBase = getProjectClaude(ctx);
276
- const projectHooksDir = join(projectBase, "hooks");
275
+ const projectHooksDir = path.join(projectBase, "hooks");
277
276
 
278
277
  const hookTypes = ["pre", "post"] as const;
279
278
 
280
279
  const loadTasks: { dir: string; hookType: "pre" | "post"; level: "user" | "project" }[] = [];
281
280
  for (const hookType of hookTypes) {
282
- loadTasks.push({ dir: join(userHooksDir, hookType), hookType, level: "user" });
281
+ loadTasks.push({ dir: path.join(userHooksDir, hookType), hookType, level: "user" });
283
282
  }
284
283
  for (const hookType of hookTypes) {
285
- loadTasks.push({ dir: join(projectHooksDir, hookType), hookType, level: "project" });
284
+ loadTasks.push({ dir: path.join(projectHooksDir, hookType), hookType, level: "project" });
286
285
  }
287
286
 
288
287
  const results = await Promise.all(
@@ -320,7 +319,7 @@ async function loadTools(ctx: LoadContext): Promise<LoadResult<CustomTool>> {
320
319
  const warnings: string[] = [];
321
320
 
322
321
  const userBase = getUserClaude(ctx);
323
- const userToolsDir = join(userBase, "tools");
322
+ const userToolsDir = path.join(userBase, "tools");
324
323
 
325
324
  const userResult = await loadFilesFromDir<CustomTool>(ctx, userToolsDir, PROVIDER_ID, "user", {
326
325
  transform: (name, _content, path, source) => {
@@ -339,7 +338,7 @@ async function loadTools(ctx: LoadContext): Promise<LoadResult<CustomTool>> {
339
338
  if (userResult.warnings) warnings.push(...userResult.warnings);
340
339
 
341
340
  const projectBase = getProjectClaude(ctx);
342
- const projectToolsDir = join(projectBase, "tools");
341
+ const projectToolsDir = path.join(projectBase, "tools");
343
342
 
344
343
  const projectResult = await loadFilesFromDir<CustomTool>(ctx, projectToolsDir, PROVIDER_ID, "project", {
345
344
  transform: (name, _content, path, source) => {
@@ -369,7 +368,7 @@ async function loadSystemPrompts(ctx: LoadContext): Promise<LoadResult<SystemPro
369
368
  const warnings: string[] = [];
370
369
 
371
370
  const userBase = getUserClaude(ctx);
372
- const userSystemMd = join(userBase, "SYSTEM.md");
371
+ const userSystemMd = path.join(userBase, "SYSTEM.md");
373
372
 
374
373
  const content = await readFile(userSystemMd);
375
374
  if (content !== null) {
@@ -393,7 +392,7 @@ async function loadSettings(ctx: LoadContext): Promise<LoadResult<Settings>> {
393
392
  const warnings: string[] = [];
394
393
 
395
394
  const userBase = getUserClaude(ctx);
396
- const userSettingsJson = join(userBase, "settings.json");
395
+ const userSettingsJson = path.join(userBase, "settings.json");
397
396
 
398
397
  const userContent = await readFile(userSettingsJson);
399
398
  if (userContent) {
@@ -411,7 +410,7 @@ async function loadSettings(ctx: LoadContext): Promise<LoadResult<Settings>> {
411
410
  }
412
411
 
413
412
  const projectBase = getProjectClaude(ctx);
414
- const projectSettingsJson = join(projectBase, "settings.json");
413
+ const projectSettingsJson = path.join(projectBase, "settings.json");
415
414
  const projectContent = await readFile(projectSettingsJson);
416
415
  if (projectContent) {
417
416
  const data = parseJSON<Record<string, unknown>>(projectContent);
@@ -4,14 +4,13 @@
4
4
  * Loads rules from .clinerules (can be single file or directory with *.md files).
5
5
  * Project-only (no user-level config).
6
6
  */
7
-
8
- import { dirname, resolve } from "node:path";
9
- import { readDirEntries, readFile } from "@oh-my-pi/pi-coding-agent/capability/fs";
10
- import { registerProvider } from "@oh-my-pi/pi-coding-agent/capability/index";
11
- import type { Rule } from "@oh-my-pi/pi-coding-agent/capability/rule";
12
- import { ruleCapability } from "@oh-my-pi/pi-coding-agent/capability/rule";
13
- import type { LoadContext, LoadResult } from "@oh-my-pi/pi-coding-agent/capability/types";
14
- import { parseFrontmatter } from "@oh-my-pi/pi-coding-agent/utils/frontmatter";
7
+ import * as path from "node:path";
8
+ import { registerProvider } from "../capability";
9
+ import { readDirEntries, readFile } from "../capability/fs";
10
+ import type { Rule } from "../capability/rule";
11
+ import { ruleCapability } from "../capability/rule";
12
+ import type { LoadContext, LoadResult } from "../capability/types";
13
+ import { parseFrontmatter } from "../utils/frontmatter";
15
14
  import { createSourceMeta, loadFilesFromDir } from "./helpers";
16
15
 
17
16
  const PROVIDER_ID = "cline";
@@ -19,18 +18,18 @@ const DISPLAY_NAME = "Cline";
19
18
  const PRIORITY = 40;
20
19
 
21
20
  async function findClinerules(startDir: string): Promise<{ path: string; isDir: boolean } | null> {
22
- let current = resolve(startDir);
21
+ let current = path.resolve(startDir);
23
22
 
24
23
  while (true) {
25
24
  const entries = await readDirEntries(current);
26
- const entry = entries.find((e) => e.name === ".clinerules");
25
+ const entry = entries.find(e => e.name === ".clinerules");
27
26
  if (entry) {
28
27
  return {
29
- path: resolve(current, ".clinerules"),
28
+ path: path.resolve(current, ".clinerules"),
30
29
  isDir: entry.isDirectory(),
31
30
  };
32
31
  }
33
- const parent = dirname(current);
32
+ const parent = path.dirname(current);
34
33
  if (parent === current) return null;
35
34
  current = parent;
36
35
  }