@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/lsp/render.ts CHANGED
@@ -7,18 +7,12 @@
7
7
  * - Grouped references and symbols
8
8
  * - Collapsible/expandable views
9
9
  */
10
-
11
10
  import type { AgentToolResult, RenderResultOptions } from "@oh-my-pi/pi-agent-core";
12
- import { getLanguageFromPath, type Theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
13
- import {
14
- formatExpandHint,
15
- formatMoreItems,
16
- TRUNCATE_LENGTHS,
17
- truncate,
18
- } from "@oh-my-pi/pi-coding-agent/tools/render-utils";
19
- import { renderOutputBlock, renderStatusLine } from "@oh-my-pi/pi-coding-agent/tui";
20
11
  import { type Component, Text } from "@oh-my-pi/pi-tui";
21
12
  import { highlight, supportsLanguage } from "cli-highlight";
13
+ import { getLanguageFromPath, type Theme } from "../modes/theme/theme";
14
+ import { formatExpandHint, formatMoreItems, TRUNCATE_LENGTHS, truncate } from "../tools/render-utils";
15
+ import { renderOutputBlock, renderStatusLine } from "../tui";
22
16
  import type { LspParams, LspToolDetails } from "./types";
23
17
 
24
18
  // =============================================================================
@@ -265,11 +259,11 @@ function renderDiagnostics(
265
259
  if (warnCount > 0) meta.push(`${warnCount} warning${warnCount !== 1 ? "s" : ""}`);
266
260
  if (meta.length === 0) meta.push("No issues");
267
261
 
268
- const diagLines = lines.filter((l) => l.includes(theme.status.error) || /:\d+:\d+/.test(l));
262
+ const diagLines = lines.filter(l => l.includes(theme.status.error) || /:\d+:\d+/.test(l));
269
263
  const parsedDiagnostics = diagLines
270
- .map((line) => parseDiagnosticLine(line))
264
+ .map(line => parseDiagnosticLine(line))
271
265
  .filter((diag): diag is ParsedDiagnostic => diag !== null);
272
- const fallbackDiagnostics: RawDiagnostic[] = diagLines.map((line) => ({ raw: line.trim() }));
266
+ const fallbackDiagnostics: RawDiagnostic[] = diagLines.map(line => ({ raw: line.trim() }));
273
267
 
274
268
  if (expanded) {
275
269
  let output = `${icon} ${theme.fg("dim", meta.join(theme.sep.dot))}`;
@@ -343,7 +337,7 @@ function renderReferences(refMatch: RegExpMatchArray, lines: string[], expanded:
343
337
  const icon =
344
338
  refCount > 0 ? theme.styledSymbol("status.success", "success") : theme.styledSymbol("status.warning", "warning");
345
339
 
346
- const locLines = lines.filter((l) => /^\s*\S+:\d+:\d+/.test(l));
340
+ const locLines = lines.filter(l => /^\s*\S+:\d+:\d+/.test(l));
347
341
 
348
342
  // Group by file
349
343
  const byFile = new Map<string, Array<[string, string]>>();
@@ -436,7 +430,7 @@ function renderSymbols(symbolsMatch: RegExpMatchArray, lines: string[], expanded
436
430
  icon: string;
437
431
  }
438
432
 
439
- const symbolLines = lines.filter((l) => l.includes("@") && l.includes("line"));
433
+ const symbolLines = lines.filter(l => l.includes("@") && l.includes("line"));
440
434
  const symbols: SymbolInfo[] = [];
441
435
 
442
436
  for (const line of symbolLines) {
@@ -479,7 +473,7 @@ function renderSymbols(symbolsMatch: RegExpMatchArray, lines: string[], expanded
479
473
  return prefix;
480
474
  };
481
475
 
482
- const topLevelCount = symbols.filter((s) => s.indent === 0).length;
476
+ const topLevelCount = symbols.filter(s => s.indent === 0).length;
483
477
 
484
478
  if (expanded) {
485
479
  let output = `${icon} ${theme.fg("dim", `in ${fileName}`)}`;
@@ -497,7 +491,7 @@ function renderSymbols(symbolsMatch: RegExpMatchArray, lines: string[], expanded
497
491
  }
498
492
 
499
493
  // Collapsed: show first 3 top-level symbols
500
- const topLevel = symbols.filter((s) => s.indent === 0).slice(0, 3);
494
+ const topLevel = symbols.filter(s => s.indent === 0).slice(0, 3);
501
495
  const hasMoreSymbols = symbols.length > topLevel.length;
502
496
  const expandHint = formatExpandHint(theme, expanded, hasMoreSymbols);
503
497
  let output = `${icon} ${theme.fg("dim", `in ${fileName}`)}${expandHint}`;
package/src/lsp/utils.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import path from "node:path";
2
- import { type Theme, theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
2
+ import { type Theme, theme } from "../modes/theme/theme";
3
3
  import type {
4
4
  Diagnostic,
5
5
  DiagnosticSeverity,
@@ -232,7 +232,7 @@ export function severityToIcon(severity?: DiagnosticSeverity): string {
232
232
  function stripDiagnosticNoise(message: string): string {
233
233
  return message
234
234
  .split("\n")
235
- .filter((line) => {
235
+ .filter(line => {
236
236
  const trimmed = line.trim();
237
237
  // Skip "for further information visit <url>" lines
238
238
  if (trimmed.startsWith("for further information visit")) return false;
@@ -491,7 +491,7 @@ export function extractHoverText(
491
491
  }
492
492
 
493
493
  if (Array.isArray(contents)) {
494
- return contents.map((c) => extractHoverText(c as string | { kind: string; value: string })).join("\n\n");
494
+ return contents.map(c => extractHoverText(c as string | { kind: string; value: string })).join("\n\n");
495
495
  }
496
496
 
497
497
  if (typeof contents === "object" && contents !== null) {
package/src/main.ts CHANGED
@@ -4,17 +4,17 @@
4
4
  * This file handles CLI argument parsing and translates them into
5
5
  * createAgentSession() options. The SDK does the heavy lifting.
6
6
  */
7
-
8
- import { homedir, tmpdir } from "node:os";
9
- import { join, resolve } from "node:path";
7
+ import * as fs from "node:fs/promises";
8
+ import * as os from "node:os";
9
+ import * as path from "node:path";
10
10
  import { createInterface } from "node:readline/promises";
11
11
  import { type ImageContent, supportsXhigh } from "@oh-my-pi/pi-ai";
12
- import { initTheme, stopThemeWatcher } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
13
12
  import { postmortem } from "@oh-my-pi/pi-utils";
14
13
  import chalk from "chalk";
15
14
  import { type Args, parseArgs, printHelp } from "./cli/args";
16
15
  import { parseConfigArgs, printConfigHelp, runConfigCommand } from "./cli/config-cli";
17
16
  import { processFileArguments } from "./cli/file-processor";
17
+ import { parseJupyterArgs, printJupyterHelp, runJupyterCommand } from "./cli/jupyter-cli";
18
18
  import { listModels } from "./cli/list-models";
19
19
  import { parsePluginArgs, printPluginHelp, runPluginCommand } from "./cli/plugin-cli";
20
20
  import { selectSession } from "./cli/session-picker";
@@ -32,6 +32,7 @@ import { exportFromFile } from "./export/html";
32
32
  import type { ExtensionUIContext } from "./extensibility/extensions/types";
33
33
  import { runMigrations, showDeprecationWarnings } from "./migrations";
34
34
  import { InteractiveMode, runPrintMode, runRpcMode } from "./modes";
35
+ import { initTheme, stopThemeWatcher } from "./modes/theme/theme";
35
36
  import { type CreateAgentSessionOptions, createAgentSession, discoverAuthStorage, discoverModels } from "./sdk";
36
37
  import type { AgentSession } from "./session/agent-session";
37
38
  import { type SessionInfo, SessionManager } from "./session/session-manager";
@@ -96,7 +97,7 @@ async function runInteractiveMode(
96
97
  await mode.init();
97
98
 
98
99
  versionCheckPromise
99
- .then((newVersion) => {
100
+ .then(newVersion => {
100
101
  if (newVersion) {
101
102
  mode.showNewVersionNotification(newVersion);
102
103
  }
@@ -176,13 +177,17 @@ async function prepareInitialMessage(
176
177
  /**
177
178
  * Resolve a session argument to a local or global session match.
178
179
  */
179
- function resolveSessionMatch(sessionArg: string, cwd: string, sessionDir?: string): SessionInfo | undefined {
180
- const sessions = SessionManager.list(cwd, sessionDir);
181
- let matches = sessions.filter((session) => session.id.startsWith(sessionArg));
180
+ async function resolveSessionMatch(
181
+ sessionArg: string,
182
+ cwd: string,
183
+ sessionDir?: string,
184
+ ): Promise<SessionInfo | undefined> {
185
+ const sessions = await SessionManager.list(cwd, sessionDir);
186
+ let matches = sessions.filter(session => session.id.startsWith(sessionArg));
182
187
 
183
188
  if (matches.length === 0 && !sessionDir) {
184
- const globalSessions = SessionManager.listAll();
185
- matches = globalSessions.filter((session) => session.id.startsWith(sessionArg));
189
+ const globalSessions = await SessionManager.listAll();
190
+ matches = globalSessions.filter(session => session.id.startsWith(sessionArg));
186
191
  }
187
192
 
188
193
  return matches[0];
@@ -202,25 +207,25 @@ async function promptForkSession(session: SessionInfo): Promise<boolean> {
202
207
  }
203
208
  }
204
209
 
205
- function getChangelogForDisplay(parsed: Args, settingsManager: SettingsManager): string | undefined {
210
+ async function getChangelogForDisplay(parsed: Args, settingsManager: SettingsManager): Promise<string | undefined> {
206
211
  if (parsed.continue || parsed.resume) {
207
212
  return undefined;
208
213
  }
209
214
 
210
215
  const lastVersion = settingsManager.getLastChangelogVersion();
211
216
  const changelogPath = getChangelogPath();
212
- const entries = parseChangelog(changelogPath);
217
+ const entries = await parseChangelog(changelogPath);
213
218
 
214
219
  if (!lastVersion) {
215
220
  if (entries.length > 0) {
216
221
  settingsManager.setLastChangelogVersion(VERSION);
217
- return entries.map((e) => e.content).join("\n\n");
222
+ return entries.map(e => e.content).join("\n\n");
218
223
  }
219
224
  } else {
220
225
  const newEntries = getNewEntries(entries, lastVersion);
221
226
  if (newEntries.length > 0) {
222
227
  settingsManager.setLastChangelogVersion(VERSION);
223
- return newEntries.map((e) => e.content).join("\n\n");
228
+ return newEntries.map(e => e.content).join("\n\n");
224
229
  }
225
230
  }
226
231
 
@@ -236,12 +241,12 @@ async function createSessionManager(parsed: Args, cwd: string): Promise<SessionM
236
241
  if (sessionArg.includes("/") || sessionArg.includes("\\") || sessionArg.endsWith(".jsonl")) {
237
242
  return await SessionManager.open(sessionArg, parsed.sessionDir);
238
243
  }
239
- const match = resolveSessionMatch(sessionArg, cwd, parsed.sessionDir);
244
+ const match = await resolveSessionMatch(sessionArg, cwd, parsed.sessionDir);
240
245
  if (!match) {
241
246
  throw new Error(`Session "${sessionArg}" not found.`);
242
247
  }
243
- const normalizedCwd = resolve(cwd);
244
- const normalizedMatchCwd = resolve(match.cwd || cwd);
248
+ const normalizedCwd = path.resolve(cwd);
249
+ const normalizedMatchCwd = path.resolve(match.cwd || cwd);
245
250
  if (normalizedCwd !== normalizedMatchCwd) {
246
251
  const shouldFork = await promptForkSession(match);
247
252
  if (!shouldFork) {
@@ -268,13 +273,13 @@ async function maybeAutoChdir(parsed: Args): Promise<void> {
268
273
  return;
269
274
  }
270
275
 
271
- const home = homedir();
276
+ const home = os.homedir();
272
277
  if (!home) {
273
278
  return;
274
279
  }
275
280
 
276
281
  const normalizePath = (value: string) => {
277
- const resolved = resolve(value);
282
+ const resolved = path.resolve(value);
278
283
  return process.platform === "win32" ? resolved.toLowerCase() : resolved;
279
284
  };
280
285
 
@@ -284,16 +289,16 @@ async function maybeAutoChdir(parsed: Args): Promise<void> {
284
289
  return;
285
290
  }
286
291
 
287
- const isDirectory = async (path: string) => {
292
+ const isDirectory = async (p: string) => {
288
293
  try {
289
- const stat = await Bun.file(path).stat();
290
- return stat.isDirectory();
294
+ const s = await fs.stat(p);
295
+ return s.isDirectory();
291
296
  } catch {
292
297
  return false;
293
298
  }
294
299
  };
295
300
 
296
- const candidates = [join(home, "tmp"), "/tmp", "/var/tmp"];
301
+ const candidates = [path.join(home, "tmp"), "/tmp", "/var/tmp"];
297
302
  for (const candidate of candidates) {
298
303
  try {
299
304
  if (!(await isDirectory(candidate))) {
@@ -307,7 +312,7 @@ async function maybeAutoChdir(parsed: Args): Promise<void> {
307
312
  }
308
313
 
309
314
  try {
310
- const fallback = tmpdir();
315
+ const fallback = os.tmpdir();
311
316
  if (fallback && normalizePath(fallback) !== cwd && (await isDirectory(fallback))) {
312
317
  process.chdir(fallback);
313
318
  }
@@ -386,10 +391,10 @@ async function buildSessionOptions(
386
391
  const parsedModel = parseModelString(remembered);
387
392
  const rememberedModel = parsedModel
388
393
  ? scopedModels.find(
389
- (scopedModel) =>
394
+ scopedModel =>
390
395
  scopedModel.model.provider === parsedModel.provider && scopedModel.model.id === parsedModel.id,
391
396
  )
392
- : scopedModels.find((scopedModel) => scopedModel.model.id.toLowerCase() === remembered.toLowerCase());
397
+ : scopedModels.find(scopedModel => scopedModel.model.id.toLowerCase() === remembered.toLowerCase());
393
398
  if (rememberedModel) {
394
399
  options.model = rememberedModel.model;
395
400
  }
@@ -414,7 +419,7 @@ async function buildSessionOptions(
414
419
  // Scoped models for Ctrl+P cycling - fill in default thinking levels when not explicit
415
420
  if (scopedModels.length > 0) {
416
421
  const defaultThinkingLevel = settingsManager.getDefaultThinkingLevel() ?? "off";
417
- options.scopedModels = scopedModels.map((scopedModel) => ({
422
+ options.scopedModels = scopedModels.map(scopedModel => ({
418
423
  model: scopedModel.model,
419
424
  thinkingLevel: scopedModel.explicitThinkingLevel
420
425
  ? (scopedModel.thinkingLevel ?? defaultThinkingLevel)
@@ -431,7 +436,7 @@ async function buildSessionOptions(
431
436
  } else if (resolvedSystemPrompt) {
432
437
  options.systemPrompt = resolvedSystemPrompt;
433
438
  } else if (resolvedAppendPrompt) {
434
- options.systemPrompt = (defaultPrompt) => `${defaultPrompt}\n\n${resolvedAppendPrompt}`;
439
+ options.systemPrompt = defaultPrompt => `${defaultPrompt}\n\n${resolvedAppendPrompt}`;
435
440
  }
436
441
 
437
442
  // Tools
@@ -477,7 +482,7 @@ export async function main(args: string[]) {
477
482
 
478
483
  // Initialize theme early with defaults (CLI commands need symbols)
479
484
  // Will be re-initialized with user preferences later
480
- initTheme();
485
+ await initTheme();
481
486
 
482
487
  // Handle plugin subcommand before regular parsing
483
488
  const pluginCmd = parsePluginArgs(args);
@@ -523,6 +528,17 @@ export async function main(args: string[]) {
523
528
  return;
524
529
  }
525
530
 
531
+ // Handle jupyter subcommand
532
+ const jupyterCmd = parseJupyterArgs(args);
533
+ if (jupyterCmd) {
534
+ if (args.includes("--help") || args.includes("-h")) {
535
+ printJupyterHelp();
536
+ return;
537
+ }
538
+ await runJupyterCommand(jupyterCmd);
539
+ return;
540
+ }
541
+
526
542
  // Handle stats subcommand
527
543
  const statsCmd = parseStatsArgs(args);
528
544
  if (statsCmd) {
@@ -554,7 +570,7 @@ export async function main(args: string[]) {
554
570
 
555
571
  // Create AuthStorage and ModelRegistry upfront
556
572
  const authStorage = await discoverAuthStorage();
557
- const modelRegistry = await discoverModels(authStorage);
573
+ const modelRegistry = discoverModels(authStorage);
558
574
  time("discoverModels");
559
575
 
560
576
  if (parsed.version) {
@@ -619,7 +635,12 @@ export async function main(args: string[]) {
619
635
  settingsManager.applyOverrides({ modelRoles: roleOverrides });
620
636
  }
621
637
 
622
- initTheme(settingsManager.getTheme(), isInteractive, settingsManager.getSymbolPreset());
638
+ await initTheme(
639
+ settingsManager.getTheme(),
640
+ isInteractive,
641
+ settingsManager.getSymbolPreset(),
642
+ settingsManager.getColorBlindMode(),
643
+ );
623
644
  time("initTheme");
624
645
 
625
646
  // Show deprecation warnings in interactive mode
@@ -640,7 +661,7 @@ export async function main(args: string[]) {
640
661
 
641
662
  // Handle --resume: show session picker
642
663
  if (parsed.resume) {
643
- const sessions = SessionManager.list(cwd, parsed.sessionDir);
664
+ const sessions = await SessionManager.list(cwd, parsed.sessionDir);
644
665
  time("SessionManager.list");
645
666
  if (sessions.length === 0) {
646
667
  writeStdout(chalk.dim("No sessions found"));
@@ -722,12 +743,12 @@ export async function main(args: string[]) {
722
743
  await runRpcMode(session);
723
744
  } else if (isInteractive) {
724
745
  const versionCheckPromise = checkForNewVersion(VERSION).catch(() => undefined);
725
- const changelogMarkdown = getChangelogForDisplay(parsed, settingsManager);
746
+ const changelogMarkdown = await getChangelogForDisplay(parsed, settingsManager);
726
747
 
727
748
  const scopedModelsForDisplay = sessionOptions.scopedModels ?? scopedModels;
728
749
  if (scopedModelsForDisplay.length > 0) {
729
750
  const modelList = scopedModelsForDisplay
730
- .map((scopedModel) => {
751
+ .map(scopedModel => {
731
752
  const thinkingStr = scopedModel.thinkingLevel !== "off" ? `:${scopedModel.thinkingLevel}` : "";
732
753
  return `${scopedModel.model.id}${thinkingStr}`;
733
754
  })
package/src/mcp/client.ts CHANGED
@@ -3,7 +3,6 @@
3
3
  *
4
4
  * Handles connection initialization, tool listing, and tool calling.
5
5
  */
6
-
7
6
  import { createHttpTransport } from "./transports/http";
8
7
  import { createStdioTransport } from "./transports/stdio";
9
8
  import type {
@@ -39,11 +38,11 @@ function withTimeout<T>(promise: Promise<T>, ms: number, message: string): Promi
39
38
  const { promise: wrapped, resolve, reject } = Promise.withResolvers<T>();
40
39
  const timer = setTimeout(() => reject(new Error(message)), ms);
41
40
  promise.then(
42
- (value) => {
41
+ value => {
43
42
  clearTimeout(timer);
44
43
  resolve(value);
45
44
  },
46
- (error) => {
45
+ error => {
47
46
  clearTimeout(timer);
48
47
  reject(error);
49
48
  },
package/src/mcp/config.ts CHANGED
@@ -3,10 +3,9 @@
3
3
  *
4
4
  * Uses the capability system to load MCP servers from multiple sources.
5
5
  */
6
-
7
- import { mcpCapability } from "@oh-my-pi/pi-coding-agent/capability/mcp";
8
- import type { MCPServer } from "@oh-my-pi/pi-coding-agent/discovery";
9
- import { loadCapability } from "@oh-my-pi/pi-coding-agent/discovery";
6
+ import { mcpCapability } from "../capability/mcp";
7
+ import type { MCPServer } from "../discovery";
8
+ import { loadCapability } from "../discovery";
10
9
  import type { MCPServerConfig } from "./types";
11
10
 
12
11
  /** Options for loading MCP configs */
@@ -86,7 +85,7 @@ export async function loadAllMCPConfigs(cwd: string, options?: LoadMCPConfigsOpt
86
85
  // Filter out project-level configs if disabled
87
86
  const servers = enableProjectConfig
88
87
  ? result.items
89
- : result.items.filter((server) => server._source.level !== "project");
88
+ : result.items.filter(server => server._source.level !== "project");
90
89
 
91
90
  // Convert to legacy format and preserve source metadata
92
91
  const configs: Record<string, MCPServerConfig> = {};
@@ -130,7 +129,7 @@ export function isExaMCPServer(name: string, config: MCPServerConfig): boolean {
130
129
  // Check by args for stdio servers (e.g., mcp-remote to exa)
131
130
  if (!config.type || config.type === "stdio") {
132
131
  const stdioConfig = config as { args?: string[] };
133
- if (stdioConfig.args?.some((arg) => EXA_MCP_URL_PATTERN.test(arg))) {
132
+ if (stdioConfig.args?.some(arg => EXA_MCP_URL_PATTERN.test(arg))) {
134
133
  return true;
135
134
  }
136
135
  }
@@ -4,7 +4,6 @@
4
4
  * Lightweight utilities for calling MCP servers directly via HTTP
5
5
  * without maintaining persistent connections.
6
6
  */
7
-
8
7
  import { logger } from "@oh-my-pi/pi-utils";
9
8
 
10
9
  /** Parse SSE response format (lines starting with "data: ") */
package/src/mcp/loader.ts CHANGED
@@ -3,10 +3,9 @@
3
3
  *
4
4
  * Integrates MCP tool discovery with the custom tools system.
5
5
  */
6
-
7
- import type { LoadedCustomTool } from "@oh-my-pi/pi-coding-agent/extensibility/custom-tools/types";
8
- import { AgentStorage } from "@oh-my-pi/pi-coding-agent/session/agent-storage";
9
6
  import { logger } from "@oh-my-pi/pi-utils";
7
+ import type { LoadedCustomTool } from "../extensibility/custom-tools/types";
8
+ import { AgentStorage } from "../session/agent-storage";
10
9
  import { type MCPLoadResult, MCPManager } from "./manager";
11
10
  import { MCPToolCache } from "./tool-cache";
12
11
 
@@ -78,7 +77,7 @@ export async function discoverAndLoadMCPTools(cwd: string, options?: MCPToolsLoa
78
77
  }
79
78
 
80
79
  // Convert MCP tools to LoadedCustomTool format
81
- const loadedTools: LoadedCustomTool[] = result.tools.map((tool) => {
80
+ const loadedTools: LoadedCustomTool[] = result.tools.map(tool => {
82
81
  // MCPTool and DeferredMCPTool have these properties
83
82
  const mcpTool = tool as { mcpServerName?: string };
84
83
  const serverName = mcpTool.mcpServerName;
@@ -4,10 +4,9 @@
4
4
  * Discovers, connects to, and manages MCP servers.
5
5
  * Handles tool loading and lifecycle.
6
6
  */
7
-
8
- import type { CustomTool } from "@oh-my-pi/pi-coding-agent/extensibility/custom-tools/types";
9
7
  import { logger } from "@oh-my-pi/pi-utils";
10
8
  import type { TSchema } from "@sinclair/typebox";
9
+ import type { CustomTool } from "../extensibility/custom-tools/types";
11
10
  import { connectToServer, disconnectServer, listTools } from "./client";
12
11
  import { loadAllMCPConfigs, validateServerConfig } from "./config";
13
12
  import type { MCPToolDetails } from "./tool-bridge";
@@ -34,11 +33,11 @@ const STARTUP_TIMEOUT_MS = 250;
34
33
  function trackPromise<T>(promise: Promise<T>): TrackedPromise<T> {
35
34
  const tracked: TrackedPromise<T> = { promise, status: "pending" };
36
35
  promise.then(
37
- (value) => {
36
+ value => {
38
37
  tracked.status = "fulfilled";
39
38
  tracked.value = value;
40
39
  },
41
- (reason) => {
40
+ reason => {
42
41
  tracked.status = "rejected";
43
42
  tracked.reason = reason;
44
43
  },
@@ -156,7 +155,7 @@ export class MCPManager {
156
155
  }
157
156
 
158
157
  const connectionPromise = connectToServer(name, config).then(
159
- (connection) => {
158
+ connection => {
160
159
  if (sources[name]) {
161
160
  connection._source = sources[name];
162
161
  }
@@ -166,7 +165,7 @@ export class MCPManager {
166
165
  }
167
166
  return connection;
168
167
  },
169
- (error) => {
168
+ error => {
170
169
  if (this.pendingConnections.get(name) === connectionPromise) {
171
170
  this.pendingConnections.delete(name);
172
171
  }
@@ -175,7 +174,7 @@ export class MCPManager {
175
174
  );
176
175
  this.pendingConnections.set(name, connectionPromise);
177
176
 
178
- const toolsPromise = connectionPromise.then(async (connection) => {
177
+ const toolsPromise = connectionPromise.then(async connection => {
179
178
  const serverTools = await listTools(connection);
180
179
  return { connection, serverTools };
181
180
  });
@@ -192,7 +191,7 @@ export class MCPManager {
192
191
  this.replaceServerTools(name, customTools);
193
192
  void this.toolCache?.set(name, config, serverTools);
194
193
  })
195
- .catch((error) => {
194
+ .catch(error => {
196
195
  if (this.pendingToolLoads.get(name) !== toolsPromise) return;
197
196
  this.pendingToolLoads.delete(name);
198
197
  if (!allowBackgroundLogging || reportedErrors.has(name)) return;
@@ -203,22 +202,22 @@ export class MCPManager {
203
202
 
204
203
  // Notify about servers we're connecting to
205
204
  if (connectionTasks.length > 0 && onConnecting) {
206
- onConnecting(connectionTasks.map((task) => task.name));
205
+ onConnecting(connectionTasks.map(task => task.name));
207
206
  }
208
207
 
209
208
  if (connectionTasks.length > 0) {
210
209
  await Promise.race([
211
- Promise.allSettled(connectionTasks.map((task) => task.tracked.promise)),
210
+ Promise.allSettled(connectionTasks.map(task => task.tracked.promise)),
212
211
  delay(STARTUP_TIMEOUT_MS),
213
212
  ]);
214
213
 
215
214
  const cachedTools = new Map<string, MCPToolDefinition[]>();
216
- const pendingTasks = connectionTasks.filter((task) => task.tracked.status === "pending");
215
+ const pendingTasks = connectionTasks.filter(task => task.tracked.status === "pending");
217
216
 
218
217
  if (pendingTasks.length > 0) {
219
218
  if (this.toolCache) {
220
219
  await Promise.all(
221
- pendingTasks.map(async (task) => {
220
+ pendingTasks.map(async task => {
222
221
  const cached = await this.toolCache?.get(task.name, task.config);
223
222
  if (cached) {
224
223
  cachedTools.set(task.name, cached);
@@ -227,9 +226,9 @@ export class MCPManager {
227
226
  );
228
227
  }
229
228
 
230
- const pendingWithoutCache = pendingTasks.filter((task) => !cachedTools.has(task.name));
229
+ const pendingWithoutCache = pendingTasks.filter(task => !cachedTools.has(task.name));
231
230
  if (pendingWithoutCache.length > 0) {
232
- await Promise.allSettled(pendingWithoutCache.map((task) => task.tracked.promise));
231
+ await Promise.allSettled(pendingWithoutCache.map(task => task.tracked.promise));
233
232
  }
234
233
  }
235
234
 
@@ -269,7 +268,7 @@ export class MCPManager {
269
268
  }
270
269
 
271
270
  private replaceServerTools(name: string, tools: CustomTool<TSchema, MCPToolDetails>[]): void {
272
- this.tools = this.tools.filter((t) => !t.name.startsWith(`mcp_${name}_`));
271
+ this.tools = this.tools.filter(t => !t.name.startsWith(`mcp_${name}_`));
273
272
  this.tools.push(...tools);
274
273
  }
275
274
 
@@ -327,14 +326,14 @@ export class MCPManager {
327
326
  }
328
327
 
329
328
  // Remove tools from this server
330
- this.tools = this.tools.filter((t) => !t.name.startsWith(`mcp_${name}_`));
329
+ this.tools = this.tools.filter(t => !t.name.startsWith(`mcp_${name}_`));
331
330
  }
332
331
 
333
332
  /**
334
333
  * Disconnect from all servers.
335
334
  */
336
335
  async disconnectAll(): Promise<void> {
337
- const promises = Array.from(this.connections.values()).map((conn) => disconnectServer(conn));
336
+ const promises = Array.from(this.connections.values()).map(conn => disconnectServer(conn));
338
337
  await Promise.allSettled(promises);
339
338
 
340
339
  this.pendingConnections.clear();
@@ -367,7 +366,7 @@ export class MCPManager {
367
366
  * Refresh tools from all servers.
368
367
  */
369
368
  async refreshAllTools(): Promise<void> {
370
- const promises = Array.from(this.connections.keys()).map((name) => this.refreshServerTools(name));
369
+ const promises = Array.from(this.connections.keys()).map(name => this.refreshServerTools(name));
371
370
  await Promise.allSettled(promises);
372
371
  }
373
372
  }
@@ -3,15 +3,10 @@
3
3
  *
4
4
  * Converts MCP tool definitions to CustomTool format for the agent.
5
5
  */
6
-
7
6
  import type { AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
8
- import type { SourceMeta } from "@oh-my-pi/pi-coding-agent/capability/types";
9
- import type {
10
- CustomTool,
11
- CustomToolContext,
12
- CustomToolResult,
13
- } from "@oh-my-pi/pi-coding-agent/extensibility/custom-tools/types";
14
7
  import type { TSchema } from "@sinclair/typebox";
8
+ import type { SourceMeta } from "../capability/types";
9
+ import type { CustomTool, CustomToolContext, CustomToolResult } from "../extensibility/custom-tools/types";
15
10
  import { callTool } from "./client";
16
11
  import type { MCPContent, MCPServerConnection, MCPToolDefinition } from "./types";
17
12
 
@@ -125,7 +120,7 @@ export class MCPTool implements CustomTool<TSchema, MCPToolDetails> {
125
120
 
126
121
  /** Create MCPTool instances for all tools from an MCP server connection */
127
122
  static fromTools(connection: MCPServerConnection, tools: MCPToolDefinition[]): MCPTool[] {
128
- return tools.map((tool) => new MCPTool(connection, tool));
123
+ return tools.map(tool => new MCPTool(connection, tool));
129
124
  }
130
125
 
131
126
  constructor(
@@ -209,7 +204,7 @@ export class DeferredMCPTool implements CustomTool<TSchema, MCPToolDetails> {
209
204
  getConnection: () => Promise<MCPServerConnection>,
210
205
  source?: SourceMeta,
211
206
  ): DeferredMCPTool[] {
212
- return tools.map((tool) => new DeferredMCPTool(serverName, tool, getConnection, source));
207
+ return tools.map(tool => new DeferredMCPTool(serverName, tool, getConnection, source));
213
208
  }
214
209
 
215
210
  constructor(
@@ -3,9 +3,8 @@
3
3
  *
4
4
  * Stores tool definitions per server in agent.db for fast startup.
5
5
  */
6
-
7
- import type { AgentStorage } from "@oh-my-pi/pi-coding-agent/session/agent-storage";
8
6
  import { logger } from "@oh-my-pi/pi-utils";
7
+ import type { AgentStorage } from "../session/agent-storage";
9
8
  import type { MCPServerConfig, MCPToolDefinition } from "./types";
10
9
 
11
10
  const CACHE_VERSION = 1;
@@ -24,7 +23,7 @@ function isRecord(value: unknown): value is Record<string, unknown> {
24
23
 
25
24
  function stableClone(value: unknown): unknown {
26
25
  if (Array.isArray(value)) {
27
- return value.map((item) => stableClone(item));
26
+ return value.map(item => stableClone(item));
28
27
  }
29
28
  if (isRecord(value)) {
30
29
  const sorted: Record<string, unknown> = {};
@@ -4,22 +4,20 @@
4
4
  * Implements JSON-RPC 2.0 over HTTP POST with optional SSE streaming.
5
5
  * Based on MCP spec 2025-03-26.
6
6
  */
7
-
7
+ import { readSseEvents } from "@oh-my-pi/pi-utils";
8
8
  import type {
9
9
  JsonRpcMessage,
10
10
  JsonRpcResponse,
11
11
  MCPHttpServerConfig,
12
12
  MCPSseServerConfig,
13
13
  MCPTransport,
14
- } from "@oh-my-pi/pi-coding-agent/mcp/types";
14
+ } from "../../mcp/types";
15
15
 
16
16
  /** Generate unique request ID */
17
17
  function generateId(): string {
18
18
  return Math.random().toString(36).slice(2) + Date.now().toString(36);
19
19
  }
20
20
 
21
- import { readSseEvents } from "@oh-my-pi/pi-utils";
22
-
23
21
  /**
24
22
  * HTTP transport for MCP servers.
25
23
  * Uses POST for requests, supports SSE responses.
@@ -4,9 +4,8 @@
4
4
  * Implements JSON-RPC 2.0 over subprocess stdin/stdout.
5
5
  * Messages are newline-delimited JSON.
6
6
  */
7
-
8
- import type { JsonRpcResponse, MCPStdioServerConfig, MCPTransport } from "@oh-my-pi/pi-coding-agent/mcp/types";
9
7
  import { type Subprocess, spawn } from "bun";
8
+ import type { JsonRpcResponse, MCPStdioServerConfig, MCPTransport } from "../../mcp/types";
10
9
 
11
10
  /** Generate unique request ID */
12
11
  function generateId(): string {