@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
@@ -1,10 +1,9 @@
1
1
  /**
2
2
  * List available models with optional fuzzy search
3
3
  */
4
-
5
4
  import type { Api, Model } from "@oh-my-pi/pi-ai";
6
- import type { ModelRegistry } from "@oh-my-pi/pi-coding-agent/config/model-registry";
7
- import { fuzzyFilter } from "@oh-my-pi/pi-coding-agent/utils/fuzzy";
5
+ import type { ModelRegistry } from "../config/model-registry";
6
+ import { fuzzyFilter } from "../utils/fuzzy";
8
7
 
9
8
  /**
10
9
  * Format a number as human-readable (e.g., 200000 -> "200K", 1000000 -> "1M")
@@ -35,7 +34,7 @@ export async function listModels(modelRegistry: ModelRegistry, searchPattern?: s
35
34
  // Apply fuzzy filter if search pattern provided
36
35
  let filteredModels: Model<Api>[] = models;
37
36
  if (searchPattern) {
38
- filteredModels = fuzzyFilter(models, searchPattern, (m) => `${m.provider} ${m.id}`);
37
+ filteredModels = fuzzyFilter(models, searchPattern, m => `${m.provider} ${m.id}`);
39
38
  }
40
39
 
41
40
  if (filteredModels.length === 0) {
@@ -51,7 +50,7 @@ export async function listModels(modelRegistry: ModelRegistry, searchPattern?: s
51
50
  });
52
51
 
53
52
  // Calculate column widths
54
- const rows = filteredModels.map((m) => ({
53
+ const rows = filteredModels.map(m => ({
55
54
  provider: m.provider,
56
55
  model: m.id,
57
56
  context: formatTokenCount(m.contextWindow),
@@ -70,12 +69,12 @@ export async function listModels(modelRegistry: ModelRegistry, searchPattern?: s
70
69
  };
71
70
 
72
71
  const widths = {
73
- provider: Math.max(headers.provider.length, ...rows.map((r) => r.provider.length)),
74
- model: Math.max(headers.model.length, ...rows.map((r) => r.model.length)),
75
- context: Math.max(headers.context.length, ...rows.map((r) => r.context.length)),
76
- maxOut: Math.max(headers.maxOut.length, ...rows.map((r) => r.maxOut.length)),
77
- thinking: Math.max(headers.thinking.length, ...rows.map((r) => r.thinking.length)),
78
- images: Math.max(headers.images.length, ...rows.map((r) => r.images.length)),
72
+ provider: Math.max(headers.provider.length, ...rows.map(r => r.provider.length)),
73
+ model: Math.max(headers.model.length, ...rows.map(r => r.model.length)),
74
+ context: Math.max(headers.context.length, ...rows.map(r => r.context.length)),
75
+ maxOut: Math.max(headers.maxOut.length, ...rows.map(r => r.maxOut.length)),
76
+ thinking: Math.max(headers.thinking.length, ...rows.map(r => r.thinking.length)),
77
+ images: Math.max(headers.images.length, ...rows.map(r => r.images.length)),
79
78
  };
80
79
 
81
80
  // Print header
@@ -3,11 +3,10 @@
3
3
  *
4
4
  * Handles `omp plugin <command>` subcommands for plugin lifecycle management.
5
5
  */
6
-
7
- import { APP_NAME } from "@oh-my-pi/pi-coding-agent/config";
8
- import { PluginManager, parseSettingValue, validateSetting } from "@oh-my-pi/pi-coding-agent/extensibility/plugins";
9
- import { theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
10
6
  import chalk from "chalk";
7
+ import { APP_NAME } from "../config";
8
+ import { PluginManager, parseSettingValue, validateSetting } from "../extensibility/plugins";
9
+ import { theme } from "../modes/theme/theme";
11
10
 
12
11
  // =============================================================================
13
12
  // Types
@@ -247,7 +246,7 @@ async function handleList(manager: PluginManager, flags: { json?: boolean }): Pr
247
246
  if (availableFeatures.length > 0) {
248
247
  const enabledSet = new Set(plugin.enabledFeatures ?? []);
249
248
  const featureDisplay = availableFeatures
250
- .map((f) => (enabledSet.has(f) ? chalk.green(f) : chalk.dim(f)))
249
+ .map(f => (enabledSet.has(f) ? chalk.green(f) : chalk.dim(f)))
251
250
  .join(", ");
252
251
  console.log(chalk.dim(` Available: [${featureDisplay}]`));
253
252
  }
@@ -298,10 +297,10 @@ async function handleDoctor(manager: PluginManager, flags: { json?: boolean; fix
298
297
  }
299
298
  }
300
299
 
301
- const errors = checks.filter((c) => c.status === "error" && !c.fixed).length;
302
- const warnings = checks.filter((c) => c.status === "warning" && !c.fixed).length;
303
- const ok = checks.filter((c) => c.status === "ok").length;
304
- const fixed = checks.filter((c) => c.fixed).length;
300
+ const errors = checks.filter(c => c.status === "error" && !c.fixed).length;
301
+ const warnings = checks.filter(c => c.status === "warning" && !c.fixed).length;
302
+ const ok = checks.filter(c => c.status === "ok").length;
303
+ const fixed = checks.filter(c => c.fixed).length;
305
304
 
306
305
  console.log("");
307
306
  console.log(`Summary: ${ok} ok, ${warnings} warnings, ${errors} errors${fixed > 0 ? `, ${fixed} fixed` : ""}`);
@@ -328,7 +327,7 @@ async function handleFeatures(
328
327
 
329
328
  const pluginName = args[0];
330
329
  const plugins = await manager.list();
331
- const plugin = plugins.find((p) => p.name === pluginName);
330
+ const plugin = plugins.find(p => p.name === pluginName);
332
331
 
333
332
  if (!plugin) {
334
333
  console.error(chalk.red(`Plugin "${pluginName}" not found`));
@@ -337,21 +336,21 @@ async function handleFeatures(
337
336
 
338
337
  // Handle modifications
339
338
  if (flags.enable || flags.disable || flags.set) {
340
- let currentFeatures = new Set(manager.getEnabledFeatures(pluginName) ?? []);
339
+ let currentFeatures = new Set((await manager.getEnabledFeatures(pluginName)) ?? []);
341
340
 
342
341
  if (flags.set) {
343
342
  // --set replaces all features
344
343
  currentFeatures = new Set(
345
344
  flags.set
346
345
  .split(",")
347
- .map((f) => f.trim())
346
+ .map(f => f.trim())
348
347
  .filter(Boolean),
349
348
  );
350
349
  } else {
351
350
  if (flags.enable) {
352
351
  for (const f of flags.enable
353
352
  .split(",")
354
- .map((f) => f.trim())
353
+ .map(f => f.trim())
355
354
  .filter(Boolean)) {
356
355
  currentFeatures.add(f);
357
356
  }
@@ -359,7 +358,7 @@ async function handleFeatures(
359
358
  if (flags.disable) {
360
359
  for (const f of flags.disable
361
360
  .split(",")
362
- .map((f) => f.trim())
361
+ .map(f => f.trim())
363
362
  .filter(Boolean)) {
364
363
  currentFeatures.delete(f);
365
364
  }
@@ -371,7 +370,7 @@ async function handleFeatures(
371
370
  }
372
371
 
373
372
  // Display current state
374
- const updatedFeatures = manager.getEnabledFeatures(pluginName);
373
+ const updatedFeatures = await manager.getEnabledFeatures(pluginName);
375
374
 
376
375
  if (flags.json) {
377
376
  console.log(
@@ -433,7 +432,7 @@ async function handleConfig(
433
432
  }
434
433
 
435
434
  const plugins = await manager.list();
436
- const plugin = plugins.find((p) => p.name === pluginName);
435
+ const plugin = plugins.find(p => p.name === pluginName);
437
436
 
438
437
  if (!plugin) {
439
438
  console.error(chalk.red(`Plugin "${pluginName}" not found`));
@@ -442,7 +441,7 @@ async function handleConfig(
442
441
 
443
442
  switch (subcommand) {
444
443
  case "list": {
445
- const settings = manager.getPluginSettings(pluginName);
444
+ const settings = await manager.getPluginSettings(pluginName);
446
445
  const schema = plugin.manifest.settings || {};
447
446
 
448
447
  if (flags.json) {
@@ -477,7 +476,7 @@ async function handleConfig(
477
476
  process.exit(1);
478
477
  }
479
478
 
480
- const settings = manager.getPluginSettings(pluginName);
479
+ const settings = await manager.getPluginSettings(pluginName);
481
480
  const schema = plugin.manifest.settings?.[key];
482
481
  const value = settings[key] ?? schema?.default;
483
482
 
@@ -512,7 +511,7 @@ async function handleConfig(
512
511
  }
513
512
  }
514
513
 
515
- manager.setPluginSetting(pluginName, key, value);
514
+ await manager.setPluginSetting(pluginName, key, value);
516
515
  console.log(chalk.green(`${theme.status.success} Set ${key}`));
517
516
  break;
518
517
  }
@@ -523,7 +522,7 @@ async function handleConfig(
523
522
  process.exit(1);
524
523
  }
525
524
 
526
- manager.deletePluginSetting(pluginName, key);
525
+ await manager.deletePluginSetting(pluginName, key);
527
526
  console.log(chalk.green(`${theme.status.success} Deleted ${key}`));
528
527
  break;
529
528
  }
@@ -540,7 +539,7 @@ async function handleConfigValidate(manager: PluginManager, flags: { json?: bool
540
539
  const results: Array<{ plugin: string; key: string; error: string }> = [];
541
540
 
542
541
  for (const plugin of plugins) {
543
- const settings = manager.getPluginSettings(plugin.name);
542
+ const settings = await manager.getPluginSettings(plugin.name);
544
543
  const schema = plugin.manifest.settings || {};
545
544
 
546
545
  for (const [key, s] of Object.entries(schema)) {
@@ -1,10 +1,9 @@
1
1
  /**
2
2
  * TUI session selector for --resume flag
3
3
  */
4
-
5
- import { SessionSelectorComponent } from "@oh-my-pi/pi-coding-agent/modes/components/session-selector";
6
- import type { SessionInfo } from "@oh-my-pi/pi-coding-agent/session/session-manager";
7
4
  import { ProcessTerminal, TUI } from "@oh-my-pi/pi-tui";
5
+ import { SessionSelectorComponent } from "../modes/components/session-selector";
6
+ import type { SessionInfo } from "../session/session-manager";
8
7
 
9
8
  /** Show TUI session selector and return selected session path or null if cancelled */
10
9
  export async function selectSession(sessions: SessionInfo[]): Promise<string | null> {
@@ -3,11 +3,10 @@
3
3
  *
4
4
  * Handles `omp setup <component>` to install dependencies for optional features.
5
5
  */
6
-
7
- import { APP_NAME } from "@oh-my-pi/pi-coding-agent/config";
8
- import { theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
9
6
  import { $ } from "bun";
10
7
  import chalk from "chalk";
8
+ import { APP_NAME } from "../config";
9
+ import { theme } from "../modes/theme/theme";
11
10
 
12
11
  export type SetupComponent = "python";
13
12
 
@@ -3,9 +3,8 @@
3
3
  *
4
4
  * Handles `omp stats` subcommand for viewing AI usage statistics.
5
5
  */
6
-
7
- import { APP_NAME } from "@oh-my-pi/pi-coding-agent/config";
8
6
  import chalk from "chalk";
7
+ import { APP_NAME } from "../config";
9
8
 
10
9
  // =============================================================================
11
10
  // Types
@@ -106,7 +105,7 @@ export async function runStatsCommand(cmd: StatsCommandArgs): Promise<void> {
106
105
  }
107
106
 
108
107
  // Start the dashboard server
109
- const { port } = startServer(cmd.port);
108
+ const { port } = await startServer(cmd.port);
110
109
  console.log(chalk.green(`Dashboard available at: http://localhost:${port}`));
111
110
  console.log("Press Ctrl+C to stop\n");
112
111
 
@@ -4,15 +4,15 @@
4
4
  * Handles `omp update` to check for and install updates.
5
5
  * Uses bun if available, otherwise downloads binary from GitHub releases.
6
6
  */
7
-
8
7
  import { execSync, spawnSync } from "node:child_process";
9
- import { createWriteStream, existsSync, renameSync, unlinkSync } from "node:fs";
10
- import { dirname } from "node:path";
8
+ import * as fs from "node:fs";
9
+ import * as path from "node:path";
11
10
  import { Readable } from "node:stream";
12
11
  import { pipeline } from "node:stream/promises";
13
- import { APP_NAME, VERSION } from "@oh-my-pi/pi-coding-agent/config";
14
- import { theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
12
+ import { isEnoent } from "@oh-my-pi/pi-utils";
15
13
  import chalk from "chalk";
14
+ import { APP_NAME, VERSION } from "../config";
15
+ import { theme } from "../modes/theme/theme";
16
16
 
17
17
  /**
18
18
  * Detect if we're running as a Bun compiled binary.
@@ -73,7 +73,7 @@ async function getLatestRelease(): Promise<ReleaseInfo> {
73
73
  return {
74
74
  tag: data.tag_name,
75
75
  version: data.tag_name.replace(/^v/, ""),
76
- assets: data.assets.map((a) => ({ name: a.name, url: a.browser_download_url })),
76
+ assets: data.assets.map(a => ({ name: a.name, url: a.browser_download_url })),
77
77
  };
78
78
  }
79
79
 
@@ -154,14 +154,14 @@ async function updateViaBun(): Promise<void> {
154
154
  */
155
155
  async function updateViaBinary(release: ReleaseInfo): Promise<void> {
156
156
  const binaryName = getBinaryName();
157
- const asset = release.assets.find((a) => a.name === binaryName);
157
+ const asset = release.assets.find(a => a.name === binaryName);
158
158
 
159
159
  if (!asset) {
160
160
  throw new Error(`No binary found for ${binaryName}`);
161
161
  }
162
162
 
163
163
  const execPath = process.execPath;
164
- const _execDir = dirname(execPath);
164
+ const _execDir = path.dirname(execPath);
165
165
  const tempPath = `${execPath}.new`;
166
166
  const backupPath = `${execPath}.bak`;
167
167
 
@@ -173,7 +173,7 @@ async function updateViaBinary(release: ReleaseInfo): Promise<void> {
173
173
  throw new Error(`Download failed: ${response.statusText}`);
174
174
  }
175
175
 
176
- const fileStream = createWriteStream(tempPath, { mode: 0o755 });
176
+ const fileStream = fs.createWriteStream(tempPath, { mode: 0o755 });
177
177
  const nodeStream = Readable.fromWeb(response.body as import("stream/web").ReadableStream);
178
178
  await pipeline(nodeStream, fileStream);
179
179
 
@@ -181,27 +181,30 @@ async function updateViaBinary(release: ReleaseInfo): Promise<void> {
181
181
  console.log(chalk.dim("Installing update..."));
182
182
 
183
183
  try {
184
- // Backup current binary
185
- if (existsSync(backupPath)) {
186
- unlinkSync(backupPath);
184
+ try {
185
+ await fs.promises.unlink(backupPath);
186
+ } catch (err) {
187
+ if (!isEnoent(err)) throw err;
187
188
  }
188
- renameSync(execPath, backupPath);
189
+ await fs.promises.rename(execPath, backupPath);
189
190
 
190
- // Move new binary into place
191
- renameSync(tempPath, execPath);
191
+ await fs.promises.rename(tempPath, execPath);
192
192
 
193
- // Clean up backup
194
- unlinkSync(backupPath);
193
+ await fs.promises.unlink(backupPath);
195
194
 
196
195
  console.log(chalk.green(`\n${theme.status.success} Updated to ${release.version}`));
197
196
  console.log(chalk.dim(`Restart ${APP_NAME} to use the new version`));
198
197
  } catch (err) {
199
- // Restore from backup if possible
200
- if (existsSync(backupPath) && !existsSync(execPath)) {
201
- renameSync(backupPath, execPath);
198
+ const [backupExists, execExists, tempExists] = await Promise.all([
199
+ Bun.file(backupPath).exists(),
200
+ Bun.file(execPath).exists(),
201
+ Bun.file(tempPath).exists(),
202
+ ]);
203
+ if (backupExists && !execExists) {
204
+ await fs.promises.rename(backupPath, execPath);
202
205
  }
203
- if (existsSync(tempPath)) {
204
- unlinkSync(tempPath);
206
+ if (tempExists) {
207
+ await fs.promises.unlink(tempPath);
205
208
  }
206
209
  throw err;
207
210
  }
@@ -1,21 +1,19 @@
1
1
  import type { Api, Model } from "@oh-my-pi/pi-ai";
2
- import agentUserPrompt from "@oh-my-pi/pi-coding-agent/commit/agentic/prompts/session-user.md" with { type: "text" };
3
- import agentSystemPrompt from "@oh-my-pi/pi-coding-agent/commit/agentic/prompts/system.md" with { type: "text" };
4
- import type { CommitAgentState } from "@oh-my-pi/pi-coding-agent/commit/agentic/state";
5
- import { createCommitTools } from "@oh-my-pi/pi-coding-agent/commit/agentic/tools";
6
- import type { ControlledGit } from "@oh-my-pi/pi-coding-agent/commit/git";
7
- import typesDescriptionPrompt from "@oh-my-pi/pi-coding-agent/commit/prompts/types-description.md" with {
8
- type: "text",
9
- };
10
- import type { ModelRegistry } from "@oh-my-pi/pi-coding-agent/config/model-registry";
11
- import { renderPromptTemplate } from "@oh-my-pi/pi-coding-agent/config/prompt-templates";
12
- import type { SettingsManager } from "@oh-my-pi/pi-coding-agent/config/settings-manager";
13
- import { getMarkdownTheme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
14
- import { createAgentSession } from "@oh-my-pi/pi-coding-agent/sdk";
15
- import type { AgentSessionEvent } from "@oh-my-pi/pi-coding-agent/session/agent-session";
16
- import type { AuthStorage } from "@oh-my-pi/pi-coding-agent/session/auth-storage";
17
2
  import { Markdown } from "@oh-my-pi/pi-tui";
18
3
  import chalk from "chalk";
4
+ import type { ControlledGit } from "../../commit/git";
5
+ import typesDescriptionPrompt from "../../commit/prompts/types-description.md" with { type: "text" };
6
+ import type { ModelRegistry } from "../../config/model-registry";
7
+ import { renderPromptTemplate } from "../../config/prompt-templates";
8
+ import type { SettingsManager } from "../../config/settings-manager";
9
+ import { getMarkdownTheme } from "../../modes/theme/theme";
10
+ import { createAgentSession } from "../../sdk";
11
+ import type { AgentSessionEvent } from "../../session/agent-session";
12
+ import type { AuthStorage } from "../../session/auth-storage";
13
+ import agentUserPrompt from "./prompts/session-user.md" with { type: "text" };
14
+ import agentSystemPrompt from "./prompts/system.md" with { type: "text" };
15
+ import type { CommitAgentState } from "./state";
16
+ import { createCommitTools } from "./tools";
19
17
 
20
18
  export interface CommitAgentInput {
21
19
  cwd: string;
@@ -176,8 +174,8 @@ function writeStdout(message: string): void {
176
174
 
177
175
  function extractMessagePreview(content: Array<{ type: string; text?: string }>): string | null {
178
176
  const textBlocks = content
179
- .filter((block) => block.type === "text" && typeof block.text === "string")
180
- .map((block) => block.text?.trim())
177
+ .filter(block => block.type === "text" && typeof block.text === "string")
178
+ .map(block => block.text?.trim())
181
179
  .filter((value): value is string => Boolean(value));
182
180
  if (textBlocks.length === 0) return null;
183
181
  const combined = textBlocks.join(" ").replace(/\s+/g, " ").trim();
@@ -186,9 +184,9 @@ function extractMessagePreview(content: Array<{ type: string; text?: string }>):
186
184
 
187
185
  function extractMessageText(content: Array<{ type: string; text?: string }>): string | null {
188
186
  const textBlocks = content
189
- .filter((block) => block.type === "text" && typeof block.text === "string")
190
- .map((block) => block.text ?? "")
191
- .filter((value) => value.trim().length > 0);
187
+ .filter(block => block.type === "text" && typeof block.text === "string")
188
+ .map(block => block.text ?? "")
189
+ .filter(value => value.trim().length > 0);
192
190
  if (textBlocks.length === 0) return null;
193
191
  return textBlocks.join("\n").trim();
194
192
  }
@@ -196,7 +194,7 @@ function extractMessageText(content: Array<{ type: string; text?: string }>): st
196
194
  function writeAssistantMessage(message: string): void {
197
195
  const lines = renderMarkdownLines(message);
198
196
  if (lines.length === 0) return;
199
- let firstContentIndex = lines.findIndex((line) => line.trim().length > 0);
197
+ let firstContentIndex = lines.findIndex(line => line.trim().length > 0);
200
198
  if (firstContentIndex === -1) {
201
199
  firstContentIndex = 0;
202
200
  }
@@ -215,7 +213,7 @@ function renderMarkdownLines(message: string): string[] {
215
213
  function formatToolLabel(toolName: string): string {
216
214
  const displayName = toolName
217
215
  .split(/[_-]/)
218
- .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
216
+ .map(segment => segment.charAt(0).toUpperCase() + segment.slice(1))
219
217
  .join("");
220
218
  return displayName;
221
219
  }
@@ -227,7 +225,7 @@ function formatToolArgs(args?: Record<string, unknown>): string[] {
227
225
  if (value === null || value === undefined) return;
228
226
  if (Array.isArray(value)) {
229
227
  if (value.length === 0) return;
230
- const rendered = value.map((item) => renderPrimitive(item)).filter(Boolean);
228
+ const rendered = value.map(item => renderPrimitive(item)).filter(Boolean);
231
229
  if (rendered.length > 0) {
232
230
  lines.push(`${keyPath}: ${rendered.join(", ")}`);
233
231
  }
@@ -1,6 +1,6 @@
1
- import { basename } from "node:path";
2
- import type { CommitProposal } from "@oh-my-pi/pi-coding-agent/commit/agentic/state";
3
- import type { CommitType, ConventionalAnalysis, NumstatEntry } from "@oh-my-pi/pi-coding-agent/commit/types";
1
+ import * as path from "node:path";
2
+ import type { CommitType, ConventionalAnalysis, NumstatEntry } from "../../commit/types";
3
+ import type { CommitProposal } from "./state";
4
4
 
5
5
  const TEST_PATTERNS = ["/test/", "/tests/", "/__tests__/", "_test.", ".test.", ".spec.", "_spec."];
6
6
  const DOC_EXTENSIONS = new Set([".md", ".txt", ".rst", ".adoc"]);
@@ -20,7 +20,7 @@ function inferTypeFromFiles(numstat: NumstatEntry[]): CommitType {
20
20
  const lowerPath = entry.path.toLowerCase();
21
21
  const ext = getExtension(entry.path);
22
22
 
23
- if (TEST_PATTERNS.some((pattern) => lowerPath.includes(pattern))) {
23
+ if (TEST_PATTERNS.some(pattern => lowerPath.includes(pattern))) {
24
24
  hasTests = true;
25
25
  } else if (DOC_EXTENSIONS.has(ext)) {
26
26
  hasDocs = true;
@@ -40,16 +40,16 @@ function inferTypeFromFiles(numstat: NumstatEntry[]): CommitType {
40
40
  return "refactor";
41
41
  }
42
42
 
43
- function getExtension(path: string): string {
44
- const name = basename(path);
43
+ function getExtension(filePath: string): string {
44
+ const name = path.basename(filePath);
45
45
  const dotIndex = name.lastIndexOf(".");
46
46
  return dotIndex >= 0 ? name.slice(dotIndex).toLowerCase() : "";
47
47
  }
48
48
 
49
49
  export function generateFallbackAnalysis(numstat: NumstatEntry[]): ConventionalAnalysis {
50
50
  const type = inferTypeFromFiles(numstat);
51
- const details = numstat.slice(0, 3).map((e) => ({
52
- text: `Updated ${basename(e.path)}`,
51
+ const details = numstat.slice(0, 3).map(e => ({
52
+ text: `Updated ${path.basename(e.path)}`,
53
53
  userVisible: false,
54
54
  }));
55
55
 
@@ -76,7 +76,7 @@ export function generateFallbackSummary(type: CommitType, numstat: NumstatEntry[
76
76
  revert: "reverted changes in",
77
77
  };
78
78
  const verb = verbMap[type] ?? "updated";
79
- const file = basename(numstat[0]?.path ?? "files");
79
+ const file = path.basename(numstat[0]?.path ?? "files");
80
80
 
81
81
  if (numstat.length === 1) {
82
82
  return `${verb} ${file}`;
@@ -1,28 +1,21 @@
1
- import { relative } from "node:path";
1
+ import * as path from "node:path";
2
2
  import { createInterface } from "node:readline/promises";
3
- import { type ExistingChangelogEntries, runCommitAgentSession } from "@oh-my-pi/pi-coding-agent/commit/agentic/agent";
4
- import { generateFallbackProposal } from "@oh-my-pi/pi-coding-agent/commit/agentic/fallback";
5
- import splitConfirmPrompt from "@oh-my-pi/pi-coding-agent/commit/agentic/prompts/split-confirm.md" with {
6
- type: "text",
7
- };
8
- import type {
9
- CommitAgentState,
10
- CommitProposal,
11
- HunkSelector,
12
- SplitCommitPlan,
13
- } from "@oh-my-pi/pi-coding-agent/commit/agentic/state";
14
- import { computeDependencyOrder } from "@oh-my-pi/pi-coding-agent/commit/agentic/topo-sort";
15
- import { detectTrivialChange } from "@oh-my-pi/pi-coding-agent/commit/agentic/trivial";
16
- import { applyChangelogProposals } from "@oh-my-pi/pi-coding-agent/commit/changelog";
17
- import { detectChangelogBoundaries } from "@oh-my-pi/pi-coding-agent/commit/changelog/detect";
18
- import { parseUnreleasedSection } from "@oh-my-pi/pi-coding-agent/commit/changelog/parse";
19
- import { ControlledGit } from "@oh-my-pi/pi-coding-agent/commit/git";
20
- import { formatCommitMessage } from "@oh-my-pi/pi-coding-agent/commit/message";
21
- import { resolvePrimaryModel, resolveSmolModel } from "@oh-my-pi/pi-coding-agent/commit/model-selection";
22
- import type { CommitCommandArgs, ConventionalAnalysis } from "@oh-my-pi/pi-coding-agent/commit/types";
23
- import { renderPromptTemplate } from "@oh-my-pi/pi-coding-agent/config/prompt-templates";
24
- import { SettingsManager } from "@oh-my-pi/pi-coding-agent/config/settings-manager";
25
- import { discoverAuthStorage, discoverContextFiles, discoverModels } from "@oh-my-pi/pi-coding-agent/sdk";
3
+ import { applyChangelogProposals } from "../../commit/changelog";
4
+ import { detectChangelogBoundaries } from "../../commit/changelog/detect";
5
+ import { parseUnreleasedSection } from "../../commit/changelog/parse";
6
+ import { ControlledGit } from "../../commit/git";
7
+ import { formatCommitMessage } from "../../commit/message";
8
+ import { resolvePrimaryModel, resolveSmolModel } from "../../commit/model-selection";
9
+ import type { CommitCommandArgs, ConventionalAnalysis } from "../../commit/types";
10
+ import { renderPromptTemplate } from "../../config/prompt-templates";
11
+ import { SettingsManager } from "../../config/settings-manager";
12
+ import { discoverAuthStorage, discoverContextFiles, discoverModels } from "../../sdk";
13
+ import { type ExistingChangelogEntries, runCommitAgentSession } from "./agent";
14
+ import { generateFallbackProposal } from "./fallback";
15
+ import splitConfirmPrompt from "./prompts/split-confirm.md" with { type: "text" };
16
+ import type { CommitAgentState, CommitProposal, HunkSelector, SplitCommitPlan } from "./state";
17
+ import { computeDependencyOrder } from "./topo-sort";
18
+ import { detectTrivialChange } from "./trivial";
26
19
 
27
20
  interface CommitExecutionContext {
28
21
  git: ControlledGit;
@@ -34,9 +27,9 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
34
27
  const cwd = process.cwd();
35
28
  const git = new ControlledGit(cwd);
36
29
  const [settingsManager, authStorage] = await Promise.all([SettingsManager.create(cwd), discoverAuthStorage()]);
37
- const modelRegistryPromise = discoverModels(authStorage);
38
30
 
39
31
  writeStdout("● Resolving model...");
32
+ const modelRegistry = discoverModels(authStorage);
40
33
  const stagedFilesPromise = (async () => {
41
34
  let stagedFiles = await git.getStagedFiles();
42
35
  if (stagedFiles.length === 0) {
@@ -47,7 +40,6 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
47
40
  return stagedFiles;
48
41
  })();
49
42
 
50
- const modelRegistry = await modelRegistryPromise;
51
43
  const primaryModelPromise = resolvePrimaryModel(args.model, settingsManager, modelRegistry);
52
44
  const [primaryModelResult, stagedFiles] = await Promise.all([primaryModelPromise, stagedFilesPromise]);
53
45
  const { model: primaryModel, apiKey: primaryApiKey } = primaryModelResult;
@@ -69,7 +61,7 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
69
61
  git.getNumstat(true),
70
62
  git.getDiff(true),
71
63
  ]);
72
- const changelogTargets = changelogBoundaries.map((boundary) => boundary.changelogPath);
64
+ const changelogTargets = changelogBoundaries.map(boundary => boundary.changelogPath);
73
65
  if (!args.noChangelog) {
74
66
  if (changelogTargets.length > 0) {
75
67
  for (const path of changelogTargets) {
@@ -81,7 +73,7 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
81
73
  }
82
74
 
83
75
  writeStdout("● Discovering context files...");
84
- const agentsMdFiles = contextFiles.filter((file) => file.path.endsWith("AGENTS.md"));
76
+ const agentsMdFiles = contextFiles.filter(file => file.path.endsWith("AGENTS.md"));
85
77
  if (agentsMdFiles.length > 0) {
86
78
  for (const file of agentsMdFiles) {
87
79
  writeStdout(` └─ ${file.path}`);
@@ -168,14 +160,14 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
168
160
  cwd,
169
161
  proposals: commitState.changelogProposal.entries,
170
162
  dryRun: args.dryRun,
171
- onProgress: (message) => {
163
+ onProgress: message => {
172
164
  writeStdout(` ├─ ${message}`);
173
165
  },
174
166
  });
175
- updatedChangelogFiles = updated.map((path) => relative(cwd, path));
167
+ updatedChangelogFiles = updated.map(filePath => path.relative(cwd, filePath));
176
168
  if (updated.length > 0) {
177
- for (const path of updated) {
178
- writeStdout(` └─ ${path}`);
169
+ for (const filePath of updated) {
170
+ writeStdout(` └─ ${filePath}`);
179
171
  }
180
172
  } else {
181
173
  writeStdout(" └─ (no changes)");
@@ -229,8 +221,8 @@ async function runSplitCommit(
229
221
  appendFilesToLastCommit(plan, ctx.additionalFiles);
230
222
  }
231
223
  const stagedFiles = await ctx.git.getStagedFiles();
232
- const plannedFiles = new Set(plan.commits.flatMap((commit) => commit.changes.map((change) => change.path)));
233
- const missingFiles = stagedFiles.filter((file) => !plannedFiles.has(file));
224
+ const plannedFiles = new Set(plan.commits.flatMap(commit => commit.changes.map(change => change.path)));
225
+ const missingFiles = stagedFiles.filter(file => !plannedFiles.has(file));
234
226
  if (missingFiles.length > 0) {
235
227
  writeStderr(`Split commit plan missing staged files: ${missingFiles.join(", ")}`);
236
228
  return;
@@ -248,7 +240,7 @@ async function runSplitCommit(
248
240
  const message = formatCommitMessage(analysis, commit.summary);
249
241
  writeStdout(`Commit ${index + 1}:\n${message}\n`);
250
242
  const changeSummary = commit.changes
251
- .map((change) => formatFileChangeSummary(change.path, change.hunks))
243
+ .map(change => formatFileChangeSummary(change.path, change.hunks))
252
244
  .join(", ");
253
245
  writeStdout(`Changes: ${changeSummary}\n`);
254
246
  }
@@ -288,7 +280,7 @@ async function runSplitCommit(
288
280
 
289
281
  function appendFilesToLastCommit(plan: SplitCommitPlan, files: string[]): void {
290
282
  if (plan.commits.length === 0) return;
291
- const planned = new Set(plan.commits.flatMap((commit) => commit.changes.map((change) => change.path)));
283
+ const planned = new Set(plan.commits.flatMap(commit => commit.changes.map(change => change.path)));
292
284
  const targetCommit = plan.commits[plan.commits.length - 1];
293
285
  for (const file of files) {
294
286
  if (planned.has(file)) continue;
@@ -312,7 +304,7 @@ async function confirmSplitCommitPlan(plan: SplitCommitPlan): Promise<boolean> {
312
304
  }
313
305
 
314
306
  function formatWarnings(warnings: string[]): string {
315
- return `Warnings:\n${warnings.map((warning) => `- ${warning}`).join("\n")}`;
307
+ return `Warnings:\n${warnings.map(warning => `- ${warning}`).join("\n")}`;
316
308
  }
317
309
 
318
310
  function writeStdout(message: string): void {
@@ -335,7 +327,7 @@ function formatFileChangeSummary(path: string, hunks: HunkSelector): string {
335
327
 
336
328
  async function loadExistingChangelogEntries(paths: string[]): Promise<ExistingChangelogEntries[]> {
337
329
  const entries = await Promise.all(
338
- paths.map(async (path) => {
330
+ paths.map(async path => {
339
331
  const file = Bun.file(path);
340
332
  if (!(await file.exists())) {
341
333
  return null;
@@ -1,9 +1,4 @@
1
- import type {
2
- CommitType,
3
- ConventionalAnalysis,
4
- ConventionalDetail,
5
- NumstatEntry,
6
- } from "@oh-my-pi/pi-coding-agent/commit/types";
1
+ import type { CommitType, ConventionalAnalysis, ConventionalDetail, NumstatEntry } from "../../commit/types";
7
2
 
8
3
  export interface GitOverviewSnapshot {
9
4
  files: string[];