@oh-my-pi/pi-coding-agent 8.1.0 → 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 (402) hide show
  1. package/CHANGELOG.md +21 -1
  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 +51 -23
  38. package/scripts/format-prompts.ts +0 -1
  39. package/src/capability/context-file.ts +2 -3
  40. package/src/capability/extension-module.ts +2 -3
  41. package/src/capability/extension.ts +2 -3
  42. package/src/capability/fs.ts +20 -21
  43. package/src/capability/hook.ts +2 -3
  44. package/src/capability/index.ts +15 -16
  45. package/src/capability/instruction.ts +2 -3
  46. package/src/capability/mcp.ts +2 -3
  47. package/src/capability/prompt.ts +2 -3
  48. package/src/capability/rule.ts +2 -3
  49. package/src/capability/settings.ts +1 -2
  50. package/src/capability/skill.ts +2 -3
  51. package/src/capability/slash-command.ts +2 -3
  52. package/src/capability/ssh.ts +2 -3
  53. package/src/capability/system-prompt.ts +2 -3
  54. package/src/capability/tool.ts +2 -3
  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 -21
  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 +21 -23
  66. package/src/commit/agentic/fallback.ts +9 -9
  67. package/src/commit/agentic/index.ts +30 -38
  68. package/src/commit/agentic/state.ts +1 -6
  69. package/src/commit/agentic/tools/analyze-file.ts +15 -15
  70. package/src/commit/agentic/tools/git-file-diff.ts +3 -3
  71. package/src/commit/agentic/tools/git-hunk.ts +7 -7
  72. package/src/commit/agentic/tools/git-overview.ts +5 -5
  73. package/src/commit/agentic/tools/index.ts +14 -14
  74. package/src/commit/agentic/tools/propose-changelog.ts +6 -6
  75. package/src/commit/agentic/tools/propose-commit.ts +8 -8
  76. package/src/commit/agentic/tools/recent-commits.ts +2 -2
  77. package/src/commit/agentic/tools/split-commit.ts +19 -23
  78. package/src/commit/agentic/topo-sort.ts +1 -1
  79. package/src/commit/agentic/trivial.ts +3 -3
  80. package/src/commit/agentic/validation.ts +12 -12
  81. package/src/commit/analysis/conventional.ts +7 -11
  82. package/src/commit/analysis/index.ts +4 -4
  83. package/src/commit/analysis/scope.ts +4 -4
  84. package/src/commit/analysis/summary.ts +7 -9
  85. package/src/commit/analysis/validation.ts +1 -1
  86. package/src/commit/changelog/detect.ts +6 -6
  87. package/src/commit/changelog/generate.ts +7 -9
  88. package/src/commit/changelog/index.ts +13 -13
  89. package/src/commit/changelog/parse.ts +2 -2
  90. package/src/commit/cli.ts +1 -1
  91. package/src/commit/git/diff.ts +3 -3
  92. package/src/commit/git/index.ts +19 -24
  93. package/src/commit/index.ts +1 -1
  94. package/src/commit/map-reduce/index.ts +9 -9
  95. package/src/commit/map-reduce/map-phase.ts +19 -34
  96. package/src/commit/map-reduce/reduce-phase.ts +9 -11
  97. package/src/commit/message.ts +2 -2
  98. package/src/commit/model-selection.ts +3 -7
  99. package/src/commit/pipeline.ts +20 -22
  100. package/src/commit/utils/exclusions.ts +3 -3
  101. package/src/config/file-lock.ts +17 -7
  102. package/src/config/keybindings.ts +6 -8
  103. package/src/config/model-registry.ts +55 -37
  104. package/src/config/model-resolver.ts +18 -19
  105. package/src/config/prompt-templates.ts +11 -11
  106. package/src/config/settings-manager.ts +50 -34
  107. package/src/config.ts +60 -62
  108. package/src/cursor.ts +11 -9
  109. package/src/discovery/agents-md.ts +11 -12
  110. package/src/discovery/builtin.ts +68 -73
  111. package/src/discovery/claude.ts +41 -42
  112. package/src/discovery/cline.ts +11 -12
  113. package/src/discovery/codex.ts +52 -53
  114. package/src/discovery/cursor.ts +9 -10
  115. package/src/discovery/gemini.ts +17 -22
  116. package/src/discovery/github.ts +13 -14
  117. package/src/discovery/helpers.ts +35 -34
  118. package/src/discovery/index.ts +16 -18
  119. package/src/discovery/mcp-json.ts +8 -9
  120. package/src/discovery/ssh.ts +8 -9
  121. package/src/discovery/vscode.ts +4 -5
  122. package/src/discovery/windsurf.ts +6 -7
  123. package/src/exa/company.ts +1 -2
  124. package/src/exa/index.ts +2 -3
  125. package/src/exa/linkedin.ts +1 -2
  126. package/src/exa/mcp-client.ts +14 -16
  127. package/src/exa/render.ts +10 -11
  128. package/src/exa/researcher.ts +1 -2
  129. package/src/exa/search.ts +1 -2
  130. package/src/exa/types.ts +0 -1
  131. package/src/exa/websets.ts +1 -2
  132. package/src/exec/bash-executor.ts +3 -4
  133. package/src/exec/exec.ts +0 -1
  134. package/src/export/custom-share.ts +5 -6
  135. package/src/export/html/index.ts +24 -21
  136. package/src/export/ttsr.ts +2 -3
  137. package/src/extensibility/custom-commands/bundled/review/index.ts +7 -8
  138. package/src/extensibility/custom-commands/loader.ts +17 -14
  139. package/src/extensibility/custom-commands/types.ts +1 -2
  140. package/src/extensibility/custom-tools/loader.ts +10 -11
  141. package/src/extensibility/custom-tools/types.ts +6 -7
  142. package/src/extensibility/custom-tools/wrapper.ts +2 -3
  143. package/src/extensibility/extensions/loader.ts +75 -53
  144. package/src/extensibility/extensions/runner.ts +11 -12
  145. package/src/extensibility/extensions/types.ts +19 -26
  146. package/src/extensibility/extensions/wrapper.ts +3 -4
  147. package/src/extensibility/hooks/index.ts +1 -1
  148. package/src/extensibility/hooks/loader.ts +8 -9
  149. package/src/extensibility/hooks/runner.ts +7 -8
  150. package/src/extensibility/hooks/tool-wrapper.ts +0 -1
  151. package/src/extensibility/hooks/types.ts +10 -17
  152. package/src/extensibility/plugins/doctor.ts +3 -3
  153. package/src/extensibility/plugins/installer.ts +27 -27
  154. package/src/extensibility/plugins/loader.ts +59 -56
  155. package/src/extensibility/plugins/manager.ts +211 -171
  156. package/src/extensibility/plugins/parser.ts +1 -1
  157. package/src/extensibility/plugins/paths.ts +8 -8
  158. package/src/extensibility/skills.ts +63 -60
  159. package/src/extensibility/slash-commands.ts +10 -10
  160. package/src/index.ts +46 -46
  161. package/src/internal-urls/agent-protocol.ts +21 -11
  162. package/src/internal-urls/artifact-protocol.ts +17 -13
  163. package/src/internal-urls/router.ts +1 -2
  164. package/src/internal-urls/rule-protocol.ts +3 -4
  165. package/src/internal-urls/skill-protocol.ts +3 -4
  166. package/src/ipy/executor.ts +14 -10
  167. package/src/ipy/gateway-coordinator.ts +79 -90
  168. package/src/ipy/kernel.ts +32 -30
  169. package/src/ipy/modules.ts +13 -13
  170. package/src/lsp/client.ts +21 -10
  171. package/src/lsp/clients/biome-client.ts +1 -2
  172. package/src/lsp/clients/index.ts +3 -3
  173. package/src/lsp/clients/lsp-linter-client.ts +4 -5
  174. package/src/lsp/config.ts +15 -15
  175. package/src/lsp/edits.ts +4 -5
  176. package/src/lsp/index.ts +43 -44
  177. package/src/lsp/lspmux.ts +8 -8
  178. package/src/lsp/render.ts +10 -16
  179. package/src/lsp/utils.ts +3 -3
  180. package/src/main.ts +55 -34
  181. package/src/mcp/client.ts +2 -3
  182. package/src/mcp/config.ts +5 -6
  183. package/src/mcp/json-rpc.ts +0 -1
  184. package/src/mcp/loader.ts +3 -4
  185. package/src/mcp/manager.ts +17 -18
  186. package/src/mcp/tool-bridge.ts +4 -9
  187. package/src/mcp/tool-cache.ts +2 -3
  188. package/src/mcp/transports/http.ts +2 -4
  189. package/src/mcp/transports/stdio.ts +1 -2
  190. package/src/migrations.ts +60 -49
  191. package/src/modes/components/armin.ts +4 -5
  192. package/src/modes/components/assistant-message.ts +6 -6
  193. package/src/modes/components/bash-execution.ts +7 -8
  194. package/src/modes/components/bordered-loader.ts +3 -3
  195. package/src/modes/components/branch-summary-message.ts +3 -3
  196. package/src/modes/components/compaction-summary-message.ts +3 -3
  197. package/src/modes/components/countdown-timer.ts +0 -1
  198. package/src/modes/components/custom-message.ts +5 -5
  199. package/src/modes/components/diff.ts +1 -1
  200. package/src/modes/components/dynamic-border.ts +2 -2
  201. package/src/modes/components/extensions/extension-dashboard.ts +6 -7
  202. package/src/modes/components/extensions/extension-list.ts +2 -3
  203. package/src/modes/components/extensions/inspector-panel.ts +3 -4
  204. package/src/modes/components/extensions/state-manager.ts +25 -26
  205. package/src/modes/components/extensions/types.ts +1 -2
  206. package/src/modes/components/footer.ts +47 -43
  207. package/src/modes/components/history-search.ts +2 -2
  208. package/src/modes/components/hook-editor.ts +3 -4
  209. package/src/modes/components/hook-input.ts +2 -3
  210. package/src/modes/components/hook-message.ts +5 -5
  211. package/src/modes/components/hook-selector.ts +2 -3
  212. package/src/modes/components/keybinding-hints.ts +2 -3
  213. package/src/modes/components/login-dialog.ts +2 -2
  214. package/src/modes/components/model-selector.ts +12 -12
  215. package/src/modes/components/oauth-selector.ts +2 -2
  216. package/src/modes/components/plugin-settings.ts +20 -20
  217. package/src/modes/components/python-execution.ts +7 -8
  218. package/src/modes/components/queue-mode-selector.ts +3 -3
  219. package/src/modes/components/read-tool-group.ts +2 -2
  220. package/src/modes/components/session-selector.ts +4 -4
  221. package/src/modes/components/settings-defs.ts +77 -69
  222. package/src/modes/components/settings-selector.ts +16 -16
  223. package/src/modes/components/show-images-selector.ts +2 -2
  224. package/src/modes/components/status-line/segments.ts +4 -4
  225. package/src/modes/components/status-line/separators.ts +1 -1
  226. package/src/modes/components/status-line/types.ts +2 -2
  227. package/src/modes/components/status-line-segment-editor.ts +7 -8
  228. package/src/modes/components/status-line.ts +12 -12
  229. package/src/modes/components/theme-selector.ts +8 -7
  230. package/src/modes/components/thinking-selector.ts +4 -4
  231. package/src/modes/components/todo-display.ts +2 -2
  232. package/src/modes/components/todo-reminder.ts +4 -4
  233. package/src/modes/components/tool-execution.ts +11 -16
  234. package/src/modes/components/tree-selector.ts +11 -11
  235. package/src/modes/components/ttsr-notification.ts +5 -5
  236. package/src/modes/components/user-message-selector.ts +1 -1
  237. package/src/modes/components/user-message.ts +1 -1
  238. package/src/modes/components/visual-truncate.ts +0 -1
  239. package/src/modes/components/welcome.ts +4 -4
  240. package/src/modes/controllers/command-controller.ts +46 -47
  241. package/src/modes/controllers/event-controller.ts +16 -20
  242. package/src/modes/controllers/extension-ui-controller.ts +40 -46
  243. package/src/modes/controllers/input-controller.ts +17 -18
  244. package/src/modes/controllers/selector-controller.ts +103 -91
  245. package/src/modes/index.ts +3 -3
  246. package/src/modes/interactive-mode.ts +27 -29
  247. package/src/modes/print-mode.ts +12 -13
  248. package/src/modes/rpc/rpc-client.ts +7 -8
  249. package/src/modes/rpc/rpc-mode.ts +24 -25
  250. package/src/modes/rpc/rpc-types.ts +3 -4
  251. package/src/modes/theme/mermaid-cache.ts +2 -2
  252. package/src/modes/theme/theme.ts +128 -53
  253. package/src/modes/types.ts +10 -10
  254. package/src/modes/utils/ui-helpers.ts +17 -17
  255. package/src/patch/applicator.ts +18 -19
  256. package/src/patch/diff.ts +1 -2
  257. package/src/patch/fuzzy.ts +1 -2
  258. package/src/patch/index.ts +10 -11
  259. package/src/patch/normalize.ts +4 -4
  260. package/src/patch/normative.ts +1 -2
  261. package/src/patch/parser.ts +8 -9
  262. package/src/patch/shared.ts +12 -13
  263. package/src/sdk.ts +60 -63
  264. package/src/session/agent-session.ts +83 -84
  265. package/src/session/agent-storage.ts +11 -11
  266. package/src/session/artifacts.ts +8 -9
  267. package/src/session/auth-storage.ts +25 -29
  268. package/src/session/compaction/branch-summarization.ts +7 -10
  269. package/src/session/compaction/compaction.ts +8 -19
  270. package/src/session/compaction/utils.ts +6 -9
  271. package/src/session/history-storage.ts +10 -10
  272. package/src/session/messages.ts +4 -5
  273. package/src/session/session-manager.ts +76 -65
  274. package/src/session/session-storage.ts +57 -69
  275. package/src/session/storage-migration.ts +2 -3
  276. package/src/session/streaming-output.ts +2 -2
  277. package/src/ssh/connection-manager.ts +43 -50
  278. package/src/ssh/ssh-executor.ts +2 -2
  279. package/src/ssh/sshfs-mount.ts +11 -18
  280. package/src/system-prompt.ts +27 -34
  281. package/src/task/agents.ts +45 -30
  282. package/src/task/commands.ts +6 -7
  283. package/src/task/discovery.ts +39 -76
  284. package/src/task/executor.ts +14 -15
  285. package/src/task/index.ts +33 -36
  286. package/src/task/output-manager.ts +3 -4
  287. package/src/task/parallel.ts +0 -1
  288. package/src/task/render.ts +19 -20
  289. package/src/task/subprocess-tool-registry.ts +1 -2
  290. package/src/task/worker-protocol.ts +3 -3
  291. package/src/task/worker.ts +32 -38
  292. package/src/task/worktree.ts +19 -19
  293. package/src/tools/ask.ts +8 -9
  294. package/src/tools/bash-interceptor.ts +1 -5
  295. package/src/tools/bash.ts +19 -18
  296. package/src/tools/calculator.ts +12 -12
  297. package/src/tools/complete.ts +3 -4
  298. package/src/tools/context.ts +2 -2
  299. package/src/tools/fetch.ts +23 -26
  300. package/src/tools/find.ts +15 -16
  301. package/src/tools/gemini-image.ts +14 -14
  302. package/src/tools/grep.ts +27 -27
  303. package/src/tools/index.ts +78 -56
  304. package/src/tools/list-limit.ts +1 -1
  305. package/src/tools/ls.ts +7 -7
  306. package/src/tools/notebook.ts +5 -5
  307. package/src/tools/output-meta.ts +3 -4
  308. package/src/tools/output-utils.ts +1 -1
  309. package/src/tools/path-utils.ts +5 -5
  310. package/src/tools/python.ts +36 -37
  311. package/src/tools/read.ts +23 -23
  312. package/src/tools/render-utils.ts +8 -9
  313. package/src/tools/renderers.ts +6 -7
  314. package/src/tools/review.ts +8 -11
  315. package/src/tools/ssh.ts +31 -30
  316. package/src/tools/todo-write.ts +13 -13
  317. package/src/tools/tool-errors.ts +3 -3
  318. package/src/tools/tool-result.ts +3 -8
  319. package/src/tools/write.ts +11 -16
  320. package/src/tui/code-cell.ts +3 -9
  321. package/src/tui/file-list.ts +3 -4
  322. package/src/tui/output-block.ts +1 -2
  323. package/src/tui/status-line.ts +2 -3
  324. package/src/tui/tree-list.ts +2 -3
  325. package/src/tui/types.ts +1 -2
  326. package/src/tui/utils.ts +2 -3
  327. package/src/utils/changelog.ts +9 -10
  328. package/src/utils/clipboard.ts +11 -11
  329. package/src/utils/file-mentions.ts +4 -10
  330. package/src/utils/frontmatter.ts +6 -3
  331. package/src/utils/fuzzy.ts +2 -2
  332. package/src/utils/image-convert.ts +1 -1
  333. package/src/utils/image-resize.ts +1 -1
  334. package/src/utils/mime.ts +2 -2
  335. package/src/utils/shell-snapshot.ts +11 -13
  336. package/src/utils/shell.ts +4 -5
  337. package/src/utils/title-generator.ts +8 -9
  338. package/src/utils/tools-manager.ts +23 -23
  339. package/src/vendor/photon/index.js +1099 -1059
  340. package/src/vendor/photon/photon_rs_bg.wasm +0 -0
  341. package/src/web/scrapers/artifacthub.ts +1 -1
  342. package/src/web/scrapers/arxiv.ts +2 -2
  343. package/src/web/scrapers/bluesky.ts +2 -2
  344. package/src/web/scrapers/cheatsh.ts +1 -1
  345. package/src/web/scrapers/chocolatey.ts +2 -2
  346. package/src/web/scrapers/choosealicense.ts +5 -5
  347. package/src/web/scrapers/cisa-kev.ts +1 -1
  348. package/src/web/scrapers/crossref.ts +2 -2
  349. package/src/web/scrapers/devto.ts +3 -3
  350. package/src/web/scrapers/discogs.ts +3 -4
  351. package/src/web/scrapers/discourse.ts +1 -1
  352. package/src/web/scrapers/dockerhub.ts +1 -1
  353. package/src/web/scrapers/fdroid.ts +2 -2
  354. package/src/web/scrapers/firefox-addons.ts +3 -3
  355. package/src/web/scrapers/flathub.ts +1 -1
  356. package/src/web/scrapers/github.ts +3 -3
  357. package/src/web/scrapers/gitlab.ts +4 -4
  358. package/src/web/scrapers/hackernews.ts +2 -2
  359. package/src/web/scrapers/huggingface.ts +1 -1
  360. package/src/web/scrapers/iacr.ts +2 -2
  361. package/src/web/scrapers/index.ts +0 -1
  362. package/src/web/scrapers/jetbrains-marketplace.ts +1 -1
  363. package/src/web/scrapers/lemmy.ts +2 -2
  364. package/src/web/scrapers/maven.ts +2 -2
  365. package/src/web/scrapers/mdn.ts +2 -4
  366. package/src/web/scrapers/metacpan.ts +2 -2
  367. package/src/web/scrapers/musicbrainz.ts +1 -2
  368. package/src/web/scrapers/npm.ts +1 -1
  369. package/src/web/scrapers/nuget.ts +2 -2
  370. package/src/web/scrapers/nvd.ts +3 -3
  371. package/src/web/scrapers/ollama.ts +7 -9
  372. package/src/web/scrapers/opencorporates.ts +2 -2
  373. package/src/web/scrapers/openlibrary.ts +6 -6
  374. package/src/web/scrapers/orcid.ts +0 -1
  375. package/src/web/scrapers/osv.ts +2 -2
  376. package/src/web/scrapers/packagist.ts +1 -1
  377. package/src/web/scrapers/pubmed.ts +1 -2
  378. package/src/web/scrapers/rawg.ts +2 -2
  379. package/src/web/scrapers/readthedocs.ts +1 -2
  380. package/src/web/scrapers/repology.ts +2 -2
  381. package/src/web/scrapers/rfc.ts +1 -1
  382. package/src/web/scrapers/searchcode.ts +2 -2
  383. package/src/web/scrapers/semantic-scholar.ts +1 -1
  384. package/src/web/scrapers/snapcraft.ts +2 -2
  385. package/src/web/scrapers/sourcegraph.ts +1 -1
  386. package/src/web/scrapers/spdx.ts +3 -3
  387. package/src/web/scrapers/spotify.ts +0 -1
  388. package/src/web/scrapers/twitter.ts +1 -1
  389. package/src/web/scrapers/types.ts +1 -2
  390. package/src/web/scrapers/utils.ts +5 -5
  391. package/src/web/scrapers/wikidata.ts +3 -3
  392. package/src/web/scrapers/youtube.ts +9 -14
  393. package/src/web/search/auth.ts +4 -9
  394. package/src/web/search/index.ts +11 -21
  395. package/src/web/search/providers/anthropic.ts +3 -9
  396. package/src/web/search/providers/exa.ts +6 -10
  397. package/src/web/search/providers/perplexity.ts +5 -5
  398. package/src/web/search/render.ts +16 -18
  399. package/scripts/generate-wasm-b64.ts +0 -24
  400. package/src/commit/map-reduce/.map-phase.ts.kate-swp +0 -0
  401. package/src/task/.executor.ts.kate-swp +0 -0
  402. package/src/vendor/photon/photon_rs_bg.wasm.b64.js +0 -1
package/src/config.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { existsSync, readFileSync, statSync } from "node:fs";
2
- import { homedir } from "node:os";
3
- import { dirname, join, resolve } from "node:path";
4
- import { logger } from "@oh-my-pi/pi-utils";
1
+ import * as fs from "node:fs";
2
+ import * as os from "node:os";
3
+ import * as path from "node:path";
4
+ import { isEnoent, logger } from "@oh-my-pi/pi-utils";
5
5
  // Embed package.json at build time for config
6
6
  import packageJson from "../package.json" with { type: "json" };
7
7
 
@@ -35,11 +35,11 @@ export const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;
35
35
  */
36
36
  export function getPackageDir(): string {
37
37
  let dir = import.meta.dir;
38
- while (dir !== dirname(dir)) {
39
- if (existsSync(join(dir, "package.json"))) {
38
+ while (dir !== path.dirname(dir)) {
39
+ if (fs.existsSync(path.join(dir, "package.json"))) {
40
40
  return dir;
41
41
  }
42
- dir = dirname(dir);
42
+ dir = path.dirname(dir);
43
43
  }
44
44
  // Fallback to cwd (docs/examples won't be found, but that's fine)
45
45
  return process.cwd();
@@ -47,7 +47,7 @@ export function getPackageDir(): string {
47
47
 
48
48
  /** Get path to CHANGELOG.md (optional, may not exist in binary) */
49
49
  export function getChangelogPath(): string {
50
- return resolve(join(getPackageDir(), "CHANGELOG.md"));
50
+ return path.resolve(path.join(getPackageDir(), "CHANGELOG.md"));
51
51
  }
52
52
 
53
53
  // =============================================================================
@@ -56,27 +56,27 @@ export function getChangelogPath(): string {
56
56
 
57
57
  /** Get the agent config directory (e.g., ~/.omp/agent/) */
58
58
  export function getAgentDir(): string {
59
- return process.env[ENV_AGENT_DIR] || join(homedir(), CONFIG_DIR_NAME, "agent");
59
+ return process.env[ENV_AGENT_DIR] || path.join(os.homedir(), CONFIG_DIR_NAME, "agent");
60
60
  }
61
61
 
62
62
  /** Get path to user's custom themes directory */
63
63
  export function getCustomThemesDir(): string {
64
- return join(getAgentDir(), "themes");
64
+ return path.join(getAgentDir(), "themes");
65
65
  }
66
66
 
67
67
  /** Get path to models.json */
68
68
  export function getModelsPath(): string {
69
- return join(getAgentDir(), "models.json");
69
+ return path.join(getAgentDir(), "models.json");
70
70
  }
71
71
 
72
72
  /** Get path to models.yml (preferred over models.json) */
73
73
  export function getModelsYamlPath(): string {
74
- return join(getAgentDir(), "models.yml");
74
+ return path.join(getAgentDir(), "models.yml");
75
75
  }
76
76
 
77
77
  /** Get path to auth.json */
78
78
  export function getAuthPath(): string {
79
- return join(getAgentDir(), "auth.json");
79
+ return path.join(getAgentDir(), "auth.json");
80
80
  }
81
81
 
82
82
  /**
@@ -85,37 +85,37 @@ export function getAuthPath(): string {
85
85
  * @returns Absolute path to the agent.db file
86
86
  */
87
87
  export function getAgentDbPath(agentDir: string = getAgentDir()): string {
88
- return join(agentDir, "agent.db");
88
+ return path.join(agentDir, "agent.db");
89
89
  }
90
90
 
91
91
  /** Get path to tools directory */
92
92
  export function getToolsDir(): string {
93
- return join(getAgentDir(), "tools");
93
+ return path.join(getAgentDir(), "tools");
94
94
  }
95
95
 
96
96
  /** Get path to managed binaries directory (fd, rg) */
97
97
  export function getBinDir(): string {
98
- return join(getAgentDir(), "bin");
98
+ return path.join(getAgentDir(), "bin");
99
99
  }
100
100
 
101
101
  /** Get path to slash commands directory */
102
102
  export function getCommandsDir(): string {
103
- return join(getAgentDir(), "commands");
103
+ return path.join(getAgentDir(), "commands");
104
104
  }
105
105
 
106
106
  /** Get path to prompts directory */
107
107
  export function getPromptsDir(): string {
108
- return join(getAgentDir(), "prompts");
108
+ return path.join(getAgentDir(), "prompts");
109
109
  }
110
110
 
111
111
  /** Get path to sessions directory */
112
112
  export function getSessionsDir(): string {
113
- return join(getAgentDir(), "sessions");
113
+ return path.join(getAgentDir(), "sessions");
114
114
  }
115
115
 
116
116
  /** Get path to debug log file */
117
117
  export function getDebugLogPath(): string {
118
- return join(getAgentDir(), `${APP_NAME}-debug.log`);
118
+ return path.join(getAgentDir(), `${APP_NAME}-debug.log`);
119
119
  }
120
120
 
121
121
  // =============================================================================
@@ -128,7 +128,7 @@ export function getDebugLogPath(): string {
128
128
  * Project-level: .omp, .pi, .claude, .codex, .gemini
129
129
  */
130
130
  const USER_CONFIG_BASES = priorityList.map(({ dir, globalAgentDir }) => ({
131
- base: () => join(homedir(), globalAgentDir ?? dir),
131
+ base: () => path.join(os.homedir(), globalAgentDir ?? dir),
132
132
  name: dir,
133
133
  }));
134
134
 
@@ -177,9 +177,9 @@ export function getConfigDirs(subpath: string, options: GetConfigDirsOptions = {
177
177
  // User-level directories (highest priority)
178
178
  if (user) {
179
179
  for (const { base, name } of USER_CONFIG_BASES) {
180
- const path = join(base(), subpath);
181
- if (!existingOnly || existsSync(path)) {
182
- results.push({ path, source: name, level: "user" });
180
+ const resolvedPath = path.resolve(base(), subpath);
181
+ if (!existingOnly || fs.existsSync(resolvedPath)) {
182
+ results.push({ path: resolvedPath, source: name, level: "user" });
183
183
  }
184
184
  }
185
185
  }
@@ -187,9 +187,9 @@ export function getConfigDirs(subpath: string, options: GetConfigDirsOptions = {
187
187
  // Project-level directories
188
188
  if (project) {
189
189
  for (const { base, name } of PROJECT_CONFIG_BASES) {
190
- const path = resolve(cwd, base, subpath);
191
- if (!existingOnly || existsSync(path)) {
192
- results.push({ path, source: name, level: "project" });
190
+ const resolvedPath = path.resolve(cwd, base, subpath);
191
+ if (!existingOnly || fs.existsSync(resolvedPath)) {
192
+ results.push({ path: resolvedPath, source: name, level: "project" });
193
193
  }
194
194
  }
195
195
  }
@@ -202,7 +202,7 @@ export function getConfigDirs(subpath: string, options: GetConfigDirsOptions = {
202
202
  * Returns just the paths, highest priority first.
203
203
  */
204
204
  export function getConfigDirPaths(subpath: string, options: GetConfigDirsOptions = {}): string[] {
205
- return getConfigDirs(subpath, options).map((e) => e.path);
205
+ return getConfigDirs(subpath, options).map(e => e.path);
206
206
  }
207
207
 
208
208
  export interface ConfigFileResult<T> {
@@ -226,25 +226,24 @@ export interface ConfigFileResult<T> {
226
226
  * console.log(result.content);
227
227
  * }
228
228
  */
229
- export function readConfigFile<T = unknown>(
229
+ export async function readConfigFile<T = unknown>(
230
230
  subpath: string,
231
231
  options: GetConfigDirsOptions = {},
232
- ): ConfigFileResult<T> | undefined {
232
+ ): Promise<ConfigFileResult<T> | undefined> {
233
233
  const dirs = getConfigDirs("", { ...options, existingOnly: false });
234
234
 
235
235
  for (const { path: base, source, level } of dirs) {
236
- const filePath = join(base, subpath);
236
+ const filePath = path.join(base, subpath);
237
237
  try {
238
- if (existsSync(filePath)) {
239
- const content = readFileSync(filePath, "utf-8");
240
- return {
241
- path: filePath,
242
- source,
243
- level,
244
- content: JSON.parse(content) as T,
245
- };
246
- }
238
+ const content = await Bun.file(filePath).text();
239
+ return {
240
+ path: filePath,
241
+ source,
242
+ level,
243
+ content: JSON.parse(content) as T,
244
+ };
247
245
  } catch (error) {
246
+ if (isEnoent(error)) continue;
248
247
  logger.warn("Failed to parse config file", { path: filePath, error: String(error) });
249
248
  }
250
249
  }
@@ -256,26 +255,25 @@ export function readConfigFile<T = unknown>(
256
255
  * Get all existing config files for a subpath (for merging scenarios).
257
256
  * Returns in priority order (highest first).
258
257
  */
259
- export function readAllConfigFiles<T = unknown>(
258
+ export async function readAllConfigFiles<T = unknown>(
260
259
  subpath: string,
261
260
  options: GetConfigDirsOptions = {},
262
- ): ConfigFileResult<T>[] {
261
+ ): Promise<ConfigFileResult<T>[]> {
263
262
  const dirs = getConfigDirs("", { ...options, existingOnly: false });
264
263
  const results: ConfigFileResult<T>[] = [];
265
264
 
266
265
  for (const { path: base, source, level } of dirs) {
267
- const filePath = join(base, subpath);
266
+ const filePath = path.join(base, subpath);
268
267
  try {
269
- if (existsSync(filePath)) {
270
- const content = readFileSync(filePath, "utf-8");
271
- results.push({
272
- path: filePath,
273
- source,
274
- level,
275
- content: JSON.parse(content) as T,
276
- });
277
- }
268
+ const content = await Bun.file(filePath).text();
269
+ results.push({
270
+ path: filePath,
271
+ source,
272
+ level,
273
+ content: JSON.parse(content) as T,
274
+ });
278
275
  } catch (error) {
276
+ if (isEnoent(error)) continue;
279
277
  logger.warn("Failed to parse config file", { path: filePath, error: String(error) });
280
278
  }
281
279
  }
@@ -291,8 +289,8 @@ export function findConfigFile(subpath: string, options: GetConfigDirsOptions =
291
289
  const dirs = getConfigDirs("", { ...options, existingOnly: false });
292
290
 
293
291
  for (const { path: base } of dirs) {
294
- const filePath = join(base, subpath);
295
- if (existsSync(filePath)) {
292
+ const filePath = path.join(base, subpath);
293
+ if (fs.existsSync(filePath)) {
296
294
  return filePath;
297
295
  }
298
296
  }
@@ -310,8 +308,8 @@ export function findConfigFileWithMeta(
310
308
  const dirs = getConfigDirs("", { ...options, existingOnly: false });
311
309
 
312
310
  for (const { path: base, source, level } of dirs) {
313
- const filePath = join(base, subpath);
314
- if (existsSync(filePath)) {
311
+ const filePath = path.join(base, subpath);
312
+ if (fs.existsSync(filePath)) {
315
313
  return { path: filePath, source, level };
316
314
  }
317
315
  }
@@ -325,7 +323,7 @@ export function findConfigFileWithMeta(
325
323
 
326
324
  async function isDirectory(p: string): Promise<boolean> {
327
325
  try {
328
- return existsSync(p) && statSync(p).isDirectory();
326
+ return (await fs.promises.stat(p)).isDirectory();
329
327
  } catch {
330
328
  return false;
331
329
  }
@@ -348,14 +346,14 @@ export async function findNearestProjectConfigDir(
348
346
  while (true) {
349
347
  // Check all config bases at this level, in priority order
350
348
  for (const { base, name } of PROJECT_CONFIG_BASES) {
351
- const candidate = join(currentDir, base, subpath);
349
+ const candidate = path.join(currentDir, base, subpath);
352
350
  if (await isDirectory(candidate)) {
353
351
  return { path: candidate, source: name, level: "project" };
354
352
  }
355
353
  }
356
354
 
357
355
  // Move up one directory
358
- const parentDir = dirname(currentDir);
356
+ const parentDir = path.dirname(currentDir);
359
357
  if (parentDir === currentDir) break; // Reached root
360
358
  currentDir = parentDir;
361
359
  }
@@ -381,20 +379,20 @@ export async function findAllNearestProjectConfigDirs(
381
379
  for (const { base, name } of PROJECT_CONFIG_BASES) {
382
380
  if (foundBases.has(name)) continue;
383
381
 
384
- const candidate = join(currentDir, base, subpath);
382
+ const candidate = path.join(currentDir, base, subpath);
385
383
  if (await isDirectory(candidate)) {
386
384
  results.push({ path: candidate, source: name, level: "project" });
387
385
  foundBases.add(name);
388
386
  }
389
387
  }
390
388
 
391
- const parentDir = dirname(currentDir);
389
+ const parentDir = path.dirname(currentDir);
392
390
  if (parentDir === currentDir) break;
393
391
  currentDir = parentDir;
394
392
  }
395
393
 
396
394
  // Sort by priority order
397
- const order = PROJECT_CONFIG_BASES.map((b) => b.name);
395
+ const order = PROJECT_CONFIG_BASES.map(b => b.name);
398
396
  results.sort((a, b) => order.indexOf(a.source) - order.indexOf(b.source));
399
397
 
400
398
  return results;
package/src/cursor.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { randomUUID } from "node:crypto";
2
- import { rmSync, statSync } from "node:fs";
2
+ import * as fs from "node:fs/promises";
3
3
  import type {
4
4
  AgentEvent,
5
5
  AgentTool,
@@ -8,7 +8,7 @@ import type {
8
8
  AgentToolUpdateCallback,
9
9
  } from "@oh-my-pi/pi-agent-core";
10
10
  import type { CursorMcpCall, CursorExecHandlers as ICursorExecHandlers, ToolResultMessage } from "@oh-my-pi/pi-ai";
11
- import { resolveToCwd } from "@oh-my-pi/pi-coding-agent/tools/path-utils";
11
+ import { resolveToCwd } from "./tools/path-utils";
12
12
 
13
13
  interface CursorExecBridgeOptions {
14
14
  cwd: string;
@@ -59,7 +59,7 @@ async function executeTool(
59
59
  let isError = false;
60
60
 
61
61
  const onUpdate: AgentToolUpdateCallback<unknown> | undefined = options.emitEvent
62
- ? (partialResult) => {
62
+ ? partialResult => {
63
63
  options.emitEvent?.({
64
64
  type: "tool_execution_update",
65
65
  toolCallId,
@@ -98,17 +98,19 @@ async function executeDelete(options: CursorExecBridgeOptions, pathArg: string,
98
98
  let result: AgentToolResult<unknown>;
99
99
 
100
100
  try {
101
- const stat = statSync(absolutePath, { throwIfNoEntry: false });
102
- if (!stat) {
101
+ let fileStat: Awaited<ReturnType<typeof fs.stat>> | undefined;
102
+ try {
103
+ fileStat = await fs.stat(absolutePath);
104
+ } catch {
103
105
  throw new Error(`File not found: ${pathArg}`);
104
106
  }
105
- if (!stat.isFile()) {
107
+ if (!fileStat.isFile()) {
106
108
  throw new Error(`Path is not a file: ${pathArg}`);
107
109
  }
108
110
 
109
- rmSync(absolutePath);
111
+ await fs.rm(absolutePath);
110
112
 
111
- const sizeText = stat.size ? ` (${stat.size} bytes)` : "";
113
+ const sizeText = fileStat.size ? ` (${fileStat.size} bytes)` : "";
112
114
  const message = `Deleted ${pathArg}${sizeText}`;
113
115
  result = { content: [{ type: "text", text: message }], details: {} };
114
116
  } catch (error) {
@@ -220,7 +222,7 @@ export class CursorExecHandlers implements ICursorExecHandlers {
220
222
  const toolCallId = decodeToolCallId(call.toolCallId);
221
223
  const tool = this.options.tools.get(toolName);
222
224
  if (!tool) {
223
- const availableTools = Array.from(this.options.tools.keys()).filter((name) => name.startsWith("mcp_"));
225
+ const availableTools = Array.from(this.options.tools.keys()).filter(name => name.startsWith("mcp_"));
224
226
  const message = formatMcpToolErrorMessage(toolName, availableTools);
225
227
  const toolResult: ToolResultMessage = {
226
228
  role: "toolResult",
@@ -5,12 +5,11 @@
5
5
  * This handles AGENTS.md files that live in project root (not in config directories
6
6
  * like .codex/ or .gemini/, which are handled by their respective providers).
7
7
  */
8
-
9
- import { dirname, join, sep } from "node:path";
10
- import { registerProvider } from "@oh-my-pi/pi-coding-agent/capability";
11
- import { type ContextFile, contextFileCapability } from "@oh-my-pi/pi-coding-agent/capability/context-file";
12
- import { readFile } from "@oh-my-pi/pi-coding-agent/capability/fs";
13
- import type { LoadContext, LoadResult } from "@oh-my-pi/pi-coding-agent/capability/types";
8
+ import * as path from "node:path";
9
+ import { registerProvider } from "../capability";
10
+ import { type ContextFile, contextFileCapability } from "../capability/context-file";
11
+ import { readFile } from "../capability/fs";
12
+ import type { LoadContext, LoadResult } from "../capability/types";
14
13
  import { calculateDepth, createSourceMeta } from "./helpers";
15
14
 
16
15
  const PROVIDER_ID = "agents-md";
@@ -29,16 +28,16 @@ async function loadAgentsMd(ctx: LoadContext): Promise<LoadResult<ContextFile>>
29
28
  let depth = 0;
30
29
 
31
30
  while (depth < MAX_DEPTH) {
32
- const candidate = join(current, "AGENTS.md");
31
+ const candidate = path.join(current, "AGENTS.md");
33
32
  const content = await readFile(candidate);
34
33
 
35
34
  if (content !== null) {
36
- const parent = dirname(candidate);
37
- const baseName = parent.split(sep).pop() ?? "";
35
+ const parent = path.dirname(candidate);
36
+ const baseName = parent.split(path.sep).pop() ?? "";
38
37
 
39
38
  if (!baseName.startsWith(".")) {
40
- const fileDir = dirname(candidate);
41
- const calculatedDepth = calculateDepth(ctx.cwd, fileDir, sep);
39
+ const fileDir = path.dirname(candidate);
40
+ const calculatedDepth = calculateDepth(ctx.cwd, fileDir, path.sep);
42
41
 
43
42
  items.push({
44
43
  path: candidate,
@@ -51,7 +50,7 @@ async function loadAgentsMd(ctx: LoadContext): Promise<LoadResult<ContextFile>>
51
50
  }
52
51
 
53
52
  // Move to parent directory
54
- const parent = dirname(current);
53
+ const parent = path.dirname(current);
55
54
  if (parent === current) break; // Reached filesystem root
56
55
  current = parent;
57
56
  depth++;