@oh-my-pi/pi-coding-agent 8.0.20 → 8.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (421) hide show
  1. package/CHANGELOG.md +125 -0
  2. package/docs/session.md +111 -46
  3. package/examples/custom-tools/hello/index.ts +1 -1
  4. package/examples/custom-tools/todo/index.ts +3 -4
  5. package/examples/extensions/api-demo.ts +0 -1
  6. package/examples/extensions/chalk-logger.ts +2 -3
  7. package/examples/extensions/hello.ts +0 -1
  8. package/examples/extensions/pirate.ts +0 -1
  9. package/examples/extensions/plan-mode.ts +15 -16
  10. package/examples/extensions/todo.ts +3 -4
  11. package/examples/extensions/tools.ts +1 -2
  12. package/examples/extensions/with-deps/index.ts +0 -1
  13. package/examples/hooks/auto-commit-on-exit.ts +1 -2
  14. package/examples/hooks/confirm-destructive.ts +0 -1
  15. package/examples/hooks/custom-compaction.ts +1 -2
  16. package/examples/hooks/dirty-repo-guard.ts +0 -1
  17. package/examples/hooks/file-trigger.ts +3 -4
  18. package/examples/hooks/git-checkpoint.ts +0 -1
  19. package/examples/hooks/handoff.ts +3 -4
  20. package/examples/hooks/permission-gate.ts +1 -2
  21. package/examples/hooks/protected-paths.ts +1 -2
  22. package/examples/hooks/qna.ts +2 -3
  23. package/examples/hooks/snake.ts +4 -5
  24. package/examples/hooks/status-line.ts +0 -1
  25. package/examples/sdk/01-minimal.ts +2 -3
  26. package/examples/sdk/02-custom-model.ts +2 -3
  27. package/examples/sdk/03-custom-prompt.ts +3 -4
  28. package/examples/sdk/04-skills.ts +2 -3
  29. package/examples/sdk/06-extensions.ts +1 -2
  30. package/examples/sdk/06-hooks.ts +6 -7
  31. package/examples/sdk/07-context-files.ts +0 -1
  32. package/examples/sdk/08-prompt-templates.ts +0 -1
  33. package/examples/sdk/08-slash-commands.ts +0 -1
  34. package/examples/sdk/09-api-keys-and-oauth.ts +0 -1
  35. package/examples/sdk/10-settings.ts +0 -1
  36. package/examples/sdk/11-sessions.ts +0 -1
  37. package/package.json +54 -23
  38. package/scripts/format-prompts.ts +0 -1
  39. package/src/capability/context-file.ts +3 -4
  40. package/src/capability/extension-module.ts +3 -4
  41. package/src/capability/extension.ts +3 -4
  42. package/src/capability/fs.ts +20 -21
  43. package/src/capability/hook.ts +3 -4
  44. package/src/capability/index.ts +15 -16
  45. package/src/capability/instruction.ts +3 -4
  46. package/src/capability/mcp.ts +3 -4
  47. package/src/capability/prompt.ts +3 -4
  48. package/src/capability/rule.ts +3 -4
  49. package/src/capability/settings.ts +2 -3
  50. package/src/capability/skill.ts +3 -4
  51. package/src/capability/slash-command.ts +3 -4
  52. package/src/capability/ssh.ts +3 -4
  53. package/src/capability/system-prompt.ts +3 -4
  54. package/src/capability/tool.ts +3 -4
  55. package/src/cli/args.ts +5 -6
  56. package/src/cli/config-cli.ts +6 -7
  57. package/src/cli/file-processor.ts +19 -17
  58. package/src/cli/jupyter-cli.ts +105 -0
  59. package/src/cli/list-models.ts +10 -11
  60. package/src/cli/plugin-cli.ts +20 -25
  61. package/src/cli/session-picker.ts +2 -3
  62. package/src/cli/setup-cli.ts +2 -3
  63. package/src/cli/stats-cli.ts +2 -3
  64. package/src/cli/update-cli.ts +25 -22
  65. package/src/commit/agentic/agent.ts +307 -0
  66. package/src/commit/agentic/fallback.ts +96 -0
  67. package/src/commit/agentic/index.ts +351 -0
  68. package/src/commit/agentic/prompts/analyze-file.md +22 -0
  69. package/src/commit/agentic/prompts/session-user.md +26 -0
  70. package/src/commit/agentic/prompts/split-confirm.md +1 -0
  71. package/src/commit/agentic/prompts/system.md +40 -0
  72. package/src/commit/agentic/state.ts +69 -0
  73. package/src/commit/agentic/tools/analyze-file.ts +131 -0
  74. package/src/commit/agentic/tools/git-file-diff.ts +194 -0
  75. package/src/commit/agentic/tools/git-hunk.ts +50 -0
  76. package/src/commit/agentic/tools/git-overview.ts +84 -0
  77. package/src/commit/agentic/tools/index.ts +56 -0
  78. package/src/commit/agentic/tools/propose-changelog.ts +128 -0
  79. package/src/commit/agentic/tools/propose-commit.ts +154 -0
  80. package/src/commit/agentic/tools/recent-commits.ts +81 -0
  81. package/src/commit/agentic/tools/split-commit.ts +280 -0
  82. package/src/commit/agentic/topo-sort.ts +44 -0
  83. package/src/commit/agentic/trivial.ts +51 -0
  84. package/src/commit/agentic/validation.ts +200 -0
  85. package/src/commit/analysis/conventional.ts +165 -0
  86. package/src/commit/analysis/index.ts +4 -0
  87. package/src/commit/analysis/scope.ts +242 -0
  88. package/src/commit/analysis/summary.ts +112 -0
  89. package/src/commit/analysis/validation.ts +66 -0
  90. package/src/commit/changelog/detect.ts +36 -0
  91. package/src/commit/changelog/generate.ts +110 -0
  92. package/src/commit/changelog/index.ts +233 -0
  93. package/src/commit/changelog/parse.ts +44 -0
  94. package/src/commit/cli.ts +93 -0
  95. package/src/commit/git/diff.ts +148 -0
  96. package/src/commit/git/errors.ts +11 -0
  97. package/src/commit/git/index.ts +212 -0
  98. package/src/commit/git/operations.ts +53 -0
  99. package/src/commit/index.ts +5 -0
  100. package/src/commit/map-reduce/index.ts +63 -0
  101. package/src/commit/map-reduce/map-phase.ts +178 -0
  102. package/src/commit/map-reduce/reduce-phase.ts +145 -0
  103. package/src/commit/map-reduce/utils.ts +9 -0
  104. package/src/commit/message.ts +11 -0
  105. package/src/commit/model-selection.ts +80 -0
  106. package/src/commit/pipeline.ts +240 -0
  107. package/src/commit/prompts/analysis-system.md +155 -0
  108. package/src/commit/prompts/analysis-user.md +41 -0
  109. package/src/commit/prompts/changelog-system.md +56 -0
  110. package/src/commit/prompts/changelog-user.md +19 -0
  111. package/src/commit/prompts/file-observer-system.md +26 -0
  112. package/src/commit/prompts/file-observer-user.md +9 -0
  113. package/src/commit/prompts/reduce-system.md +60 -0
  114. package/src/commit/prompts/reduce-user.md +17 -0
  115. package/src/commit/prompts/summary-retry.md +4 -0
  116. package/src/commit/prompts/summary-system.md +52 -0
  117. package/src/commit/prompts/summary-user.md +13 -0
  118. package/src/commit/prompts/types-description.md +2 -0
  119. package/src/commit/types.ts +109 -0
  120. package/src/commit/utils/exclusions.ts +42 -0
  121. package/src/config/file-lock.ts +121 -0
  122. package/src/config/keybindings.ts +6 -8
  123. package/src/config/model-registry.ts +65 -38
  124. package/src/config/model-resolver.ts +18 -19
  125. package/src/config/prompt-templates.ts +11 -11
  126. package/src/config/settings-manager.ts +141 -50
  127. package/src/config.ts +64 -66
  128. package/src/cursor.ts +11 -9
  129. package/src/discovery/agents-md.ts +11 -12
  130. package/src/discovery/builtin.ts +68 -73
  131. package/src/discovery/claude.ts +41 -42
  132. package/src/discovery/cline.ts +11 -12
  133. package/src/discovery/codex.ts +52 -53
  134. package/src/discovery/cursor.ts +9 -10
  135. package/src/discovery/gemini.ts +17 -22
  136. package/src/discovery/github.ts +13 -14
  137. package/src/discovery/helpers.ts +35 -34
  138. package/src/discovery/index.ts +22 -24
  139. package/src/discovery/mcp-json.ts +8 -9
  140. package/src/discovery/ssh.ts +8 -9
  141. package/src/discovery/vscode.ts +4 -5
  142. package/src/discovery/windsurf.ts +6 -7
  143. package/src/exa/company.ts +1 -2
  144. package/src/exa/index.ts +2 -3
  145. package/src/exa/linkedin.ts +1 -2
  146. package/src/exa/mcp-client.ts +14 -16
  147. package/src/exa/render.ts +10 -11
  148. package/src/exa/researcher.ts +1 -2
  149. package/src/exa/search.ts +1 -2
  150. package/src/exa/types.ts +0 -1
  151. package/src/exa/websets.ts +1 -2
  152. package/src/exec/bash-executor.ts +3 -4
  153. package/src/exec/exec.ts +0 -1
  154. package/src/export/custom-share.ts +5 -6
  155. package/src/export/html/index.ts +24 -21
  156. package/src/export/ttsr.ts +2 -3
  157. package/src/extensibility/custom-commands/bundled/review/index.ts +7 -8
  158. package/src/extensibility/custom-commands/loader.ts +18 -15
  159. package/src/extensibility/custom-commands/types.ts +2 -3
  160. package/src/extensibility/custom-tools/loader.ts +11 -12
  161. package/src/extensibility/custom-tools/types.ts +7 -8
  162. package/src/extensibility/custom-tools/wrapper.ts +2 -3
  163. package/src/extensibility/extensions/loader.ts +76 -54
  164. package/src/extensibility/extensions/runner.ts +11 -12
  165. package/src/extensibility/extensions/types.ts +20 -27
  166. package/src/extensibility/extensions/wrapper.ts +3 -4
  167. package/src/extensibility/hooks/index.ts +1 -1
  168. package/src/extensibility/hooks/loader.ts +9 -10
  169. package/src/extensibility/hooks/runner.ts +7 -8
  170. package/src/extensibility/hooks/tool-wrapper.ts +0 -1
  171. package/src/extensibility/hooks/types.ts +11 -18
  172. package/src/extensibility/plugins/doctor.ts +3 -3
  173. package/src/extensibility/plugins/installer.ts +27 -27
  174. package/src/extensibility/plugins/loader.ts +59 -56
  175. package/src/extensibility/plugins/manager.ts +211 -171
  176. package/src/extensibility/plugins/parser.ts +1 -1
  177. package/src/extensibility/plugins/paths.ts +8 -8
  178. package/src/extensibility/skills.ts +63 -60
  179. package/src/extensibility/slash-commands.ts +10 -10
  180. package/src/index.ts +54 -54
  181. package/src/internal-urls/agent-protocol.ts +21 -11
  182. package/src/internal-urls/artifact-protocol.ts +17 -13
  183. package/src/internal-urls/router.ts +1 -2
  184. package/src/internal-urls/rule-protocol.ts +3 -4
  185. package/src/internal-urls/skill-protocol.ts +3 -4
  186. package/src/ipy/executor.ts +109 -9
  187. package/src/ipy/gateway-coordinator.ts +79 -90
  188. package/src/ipy/kernel.ts +32 -30
  189. package/src/ipy/modules.ts +13 -13
  190. package/src/lsp/client.ts +21 -10
  191. package/src/lsp/clients/biome-client.ts +1 -2
  192. package/src/lsp/clients/index.ts +3 -3
  193. package/src/lsp/clients/lsp-linter-client.ts +4 -5
  194. package/src/lsp/config.ts +15 -15
  195. package/src/lsp/edits.ts +4 -5
  196. package/src/lsp/index.ts +43 -44
  197. package/src/lsp/lspmux.ts +8 -8
  198. package/src/lsp/render.ts +99 -61
  199. package/src/lsp/utils.ts +3 -3
  200. package/src/main.ts +71 -37
  201. package/src/mcp/client.ts +2 -3
  202. package/src/mcp/config.ts +5 -6
  203. package/src/mcp/json-rpc.ts +0 -1
  204. package/src/mcp/loader.ts +6 -7
  205. package/src/mcp/manager.ts +17 -18
  206. package/src/mcp/tool-bridge.ts +4 -9
  207. package/src/mcp/tool-cache.ts +2 -3
  208. package/src/mcp/transports/http.ts +2 -4
  209. package/src/mcp/transports/stdio.ts +1 -2
  210. package/src/migrations.ts +63 -52
  211. package/src/modes/components/armin.ts +4 -5
  212. package/src/modes/components/assistant-message.ts +33 -5
  213. package/src/modes/components/bash-execution.ts +7 -8
  214. package/src/modes/components/bordered-loader.ts +3 -3
  215. package/src/modes/components/branch-summary-message.ts +3 -3
  216. package/src/modes/components/compaction-summary-message.ts +3 -3
  217. package/src/modes/components/countdown-timer.ts +0 -1
  218. package/src/modes/components/custom-message.ts +5 -5
  219. package/src/modes/components/diff.ts +1 -1
  220. package/src/modes/components/dynamic-border.ts +2 -2
  221. package/src/modes/components/extensions/extension-dashboard.ts +6 -7
  222. package/src/modes/components/extensions/extension-list.ts +2 -3
  223. package/src/modes/components/extensions/inspector-panel.ts +3 -4
  224. package/src/modes/components/extensions/state-manager.ts +25 -26
  225. package/src/modes/components/extensions/types.ts +1 -2
  226. package/src/modes/components/footer.ts +47 -43
  227. package/src/modes/components/history-search.ts +2 -2
  228. package/src/modes/components/hook-editor.ts +3 -4
  229. package/src/modes/components/hook-input.ts +2 -3
  230. package/src/modes/components/hook-message.ts +5 -5
  231. package/src/modes/components/hook-selector.ts +2 -3
  232. package/src/modes/components/keybinding-hints.ts +2 -3
  233. package/src/modes/components/login-dialog.ts +2 -2
  234. package/src/modes/components/model-selector.ts +12 -12
  235. package/src/modes/components/oauth-selector.ts +2 -2
  236. package/src/modes/components/plugin-settings.ts +20 -20
  237. package/src/modes/components/python-execution.ts +7 -8
  238. package/src/modes/components/queue-mode-selector.ts +3 -3
  239. package/src/modes/components/read-tool-group.ts +2 -2
  240. package/src/modes/components/session-selector.ts +4 -4
  241. package/src/modes/components/settings-defs.ts +77 -69
  242. package/src/modes/components/settings-selector.ts +16 -16
  243. package/src/modes/components/show-images-selector.ts +2 -2
  244. package/src/modes/components/status-line/segments.ts +4 -4
  245. package/src/modes/components/status-line/separators.ts +1 -1
  246. package/src/modes/components/status-line/types.ts +2 -2
  247. package/src/modes/components/status-line-segment-editor.ts +7 -8
  248. package/src/modes/components/status-line.ts +12 -12
  249. package/src/modes/components/theme-selector.ts +8 -7
  250. package/src/modes/components/thinking-selector.ts +4 -4
  251. package/src/modes/components/todo-display.ts +2 -2
  252. package/src/modes/components/todo-reminder.ts +4 -4
  253. package/src/modes/components/tool-execution.ts +16 -19
  254. package/src/modes/components/tree-selector.ts +12 -12
  255. package/src/modes/components/ttsr-notification.ts +5 -5
  256. package/src/modes/components/user-message-selector.ts +1 -1
  257. package/src/modes/components/user-message.ts +1 -1
  258. package/src/modes/components/visual-truncate.ts +0 -1
  259. package/src/modes/components/welcome.ts +4 -4
  260. package/src/modes/controllers/command-controller.ts +46 -47
  261. package/src/modes/controllers/event-controller.ts +16 -20
  262. package/src/modes/controllers/extension-ui-controller.ts +40 -46
  263. package/src/modes/controllers/input-controller.ts +17 -18
  264. package/src/modes/controllers/selector-controller.ts +103 -91
  265. package/src/modes/index.ts +3 -3
  266. package/src/modes/interactive-mode.ts +31 -31
  267. package/src/modes/print-mode.ts +12 -13
  268. package/src/modes/rpc/rpc-client.ts +7 -8
  269. package/src/modes/rpc/rpc-mode.ts +24 -28
  270. package/src/modes/rpc/rpc-types.ts +3 -4
  271. package/src/modes/theme/mermaid-cache.ts +89 -0
  272. package/src/modes/theme/theme.ts +130 -53
  273. package/src/modes/types.ts +10 -10
  274. package/src/modes/utils/ui-helpers.ts +17 -17
  275. package/src/patch/applicator.ts +18 -19
  276. package/src/patch/diff.ts +1 -2
  277. package/src/patch/fuzzy.ts +1 -2
  278. package/src/patch/index.ts +11 -18
  279. package/src/patch/normalize.ts +4 -4
  280. package/src/patch/normative.ts +1 -2
  281. package/src/patch/parser.ts +8 -9
  282. package/src/patch/shared.ts +43 -16
  283. package/src/prompts/tools/task.md +2 -0
  284. package/src/sdk.ts +100 -65
  285. package/src/session/agent-session.ts +84 -85
  286. package/src/session/agent-storage.ts +43 -39
  287. package/src/session/artifacts.ts +32 -10
  288. package/src/session/auth-storage.ts +50 -39
  289. package/src/session/compaction/branch-summarization.ts +7 -10
  290. package/src/session/compaction/compaction.ts +8 -19
  291. package/src/session/compaction/utils.ts +6 -9
  292. package/src/session/history-storage.ts +10 -10
  293. package/src/session/messages.ts +4 -5
  294. package/src/session/session-manager.ts +76 -65
  295. package/src/session/session-storage.ts +57 -69
  296. package/src/session/storage-migration.ts +14 -56
  297. package/src/session/streaming-output.ts +2 -2
  298. package/src/ssh/connection-manager.ts +43 -50
  299. package/src/ssh/ssh-executor.ts +2 -2
  300. package/src/ssh/sshfs-mount.ts +11 -18
  301. package/src/system-prompt.ts +28 -35
  302. package/src/task/agents.ts +45 -30
  303. package/src/task/commands.ts +6 -7
  304. package/src/task/discovery.ts +39 -76
  305. package/src/task/executor.ts +14 -15
  306. package/src/task/index.ts +40 -34
  307. package/src/task/output-manager.ts +93 -0
  308. package/src/task/parallel.ts +0 -1
  309. package/src/task/render.ts +24 -30
  310. package/src/task/subprocess-tool-registry.ts +1 -2
  311. package/src/task/worker-protocol.ts +3 -3
  312. package/src/task/worker.ts +33 -39
  313. package/src/task/worktree.ts +19 -19
  314. package/src/tools/ask.ts +41 -20
  315. package/src/tools/bash-interceptor.ts +1 -5
  316. package/src/tools/bash.ts +91 -97
  317. package/src/tools/calculator.ts +49 -47
  318. package/src/tools/complete.ts +4 -5
  319. package/src/tools/context.ts +2 -2
  320. package/src/tools/fetch.ts +84 -124
  321. package/src/tools/find.ts +94 -98
  322. package/src/tools/gemini-image.ts +14 -14
  323. package/src/tools/grep.ts +100 -116
  324. package/src/tools/index.ts +80 -55
  325. package/src/tools/list-limit.ts +1 -1
  326. package/src/tools/ls.ts +44 -70
  327. package/src/tools/notebook.ts +51 -67
  328. package/src/tools/output-meta.ts +3 -4
  329. package/src/tools/output-utils.ts +2 -2
  330. package/src/tools/path-utils.ts +5 -5
  331. package/src/tools/python.ts +104 -217
  332. package/src/tools/read.ts +92 -33
  333. package/src/tools/render-utils.ts +8 -23
  334. package/src/tools/renderers.ts +6 -7
  335. package/src/tools/review.ts +8 -11
  336. package/src/tools/ssh.ts +69 -49
  337. package/src/tools/todo-write.ts +37 -25
  338. package/src/tools/tool-errors.ts +3 -3
  339. package/src/tools/tool-result.ts +3 -8
  340. package/src/tools/write.ts +99 -75
  341. package/src/tui/code-cell.ts +109 -0
  342. package/src/tui/file-list.ts +47 -0
  343. package/src/tui/index.ts +11 -0
  344. package/src/tui/output-block.ts +72 -0
  345. package/src/tui/status-line.ts +39 -0
  346. package/src/tui/tree-list.ts +55 -0
  347. package/src/tui/types.ts +16 -0
  348. package/src/tui/utils.ts +48 -0
  349. package/src/utils/changelog.ts +9 -10
  350. package/src/utils/clipboard.ts +11 -11
  351. package/src/utils/file-mentions.ts +4 -10
  352. package/src/utils/frontmatter.ts +6 -3
  353. package/src/utils/fuzzy.ts +2 -2
  354. package/src/utils/image-convert.ts +1 -1
  355. package/src/utils/image-resize.ts +1 -1
  356. package/src/utils/mime.ts +2 -2
  357. package/src/utils/shell-snapshot.ts +11 -13
  358. package/src/utils/shell.ts +4 -5
  359. package/src/utils/title-generator.ts +8 -9
  360. package/src/utils/tools-manager.ts +23 -23
  361. package/src/vendor/photon/index.js +1099 -1059
  362. package/src/vendor/photon/photon_rs_bg.wasm +0 -0
  363. package/src/web/scrapers/artifacthub.ts +1 -1
  364. package/src/web/scrapers/arxiv.ts +2 -2
  365. package/src/web/scrapers/bluesky.ts +2 -2
  366. package/src/web/scrapers/cheatsh.ts +1 -1
  367. package/src/web/scrapers/chocolatey.ts +2 -2
  368. package/src/web/scrapers/choosealicense.ts +5 -5
  369. package/src/web/scrapers/cisa-kev.ts +1 -1
  370. package/src/web/scrapers/crossref.ts +2 -2
  371. package/src/web/scrapers/devto.ts +3 -3
  372. package/src/web/scrapers/discogs.ts +3 -4
  373. package/src/web/scrapers/discourse.ts +1 -1
  374. package/src/web/scrapers/dockerhub.ts +1 -1
  375. package/src/web/scrapers/fdroid.ts +2 -2
  376. package/src/web/scrapers/firefox-addons.ts +3 -3
  377. package/src/web/scrapers/flathub.ts +1 -1
  378. package/src/web/scrapers/github.ts +3 -3
  379. package/src/web/scrapers/gitlab.ts +4 -4
  380. package/src/web/scrapers/hackernews.ts +2 -2
  381. package/src/web/scrapers/huggingface.ts +1 -1
  382. package/src/web/scrapers/iacr.ts +2 -2
  383. package/src/web/scrapers/index.ts +0 -1
  384. package/src/web/scrapers/jetbrains-marketplace.ts +1 -1
  385. package/src/web/scrapers/lemmy.ts +2 -2
  386. package/src/web/scrapers/maven.ts +2 -2
  387. package/src/web/scrapers/mdn.ts +2 -4
  388. package/src/web/scrapers/metacpan.ts +2 -2
  389. package/src/web/scrapers/musicbrainz.ts +1 -2
  390. package/src/web/scrapers/npm.ts +1 -1
  391. package/src/web/scrapers/nuget.ts +2 -2
  392. package/src/web/scrapers/nvd.ts +3 -3
  393. package/src/web/scrapers/ollama.ts +7 -9
  394. package/src/web/scrapers/opencorporates.ts +2 -2
  395. package/src/web/scrapers/openlibrary.ts +6 -6
  396. package/src/web/scrapers/orcid.ts +0 -1
  397. package/src/web/scrapers/osv.ts +2 -2
  398. package/src/web/scrapers/packagist.ts +1 -1
  399. package/src/web/scrapers/pubmed.ts +1 -2
  400. package/src/web/scrapers/rawg.ts +2 -2
  401. package/src/web/scrapers/readthedocs.ts +1 -2
  402. package/src/web/scrapers/repology.ts +2 -2
  403. package/src/web/scrapers/rfc.ts +1 -1
  404. package/src/web/scrapers/searchcode.ts +2 -2
  405. package/src/web/scrapers/semantic-scholar.ts +1 -1
  406. package/src/web/scrapers/snapcraft.ts +2 -2
  407. package/src/web/scrapers/sourcegraph.ts +1 -1
  408. package/src/web/scrapers/spdx.ts +3 -3
  409. package/src/web/scrapers/spotify.ts +0 -1
  410. package/src/web/scrapers/twitter.ts +1 -1
  411. package/src/web/scrapers/types.ts +1 -2
  412. package/src/web/scrapers/utils.ts +5 -5
  413. package/src/web/scrapers/wikidata.ts +3 -3
  414. package/src/web/scrapers/youtube.ts +9 -14
  415. package/src/web/search/auth.ts +5 -10
  416. package/src/web/search/index.ts +11 -21
  417. package/src/web/search/providers/anthropic.ts +3 -9
  418. package/src/web/search/providers/exa.ts +6 -10
  419. package/src/web/search/providers/perplexity.ts +5 -5
  420. package/src/web/search/render.ts +129 -175
  421. package/tsconfig.json +0 -42
@@ -1,6 +1,6 @@
1
- import { APP_NAME } from "@oh-my-pi/pi-coding-agent/config";
2
- import { theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
3
1
  import { type Component, truncateToWidth, visibleWidth } from "@oh-my-pi/pi-tui";
2
+ import { APP_NAME } from "../../config";
3
+ import { theme } from "../../modes/theme/theme";
4
4
 
5
5
  export interface RecentSession {
6
6
  name: string;
@@ -65,14 +65,14 @@ export class WelcomeComponent implements Component {
65
65
  const piLogo = ["▀████████████▀", " ╘███ ███ ", " ███ ███ ", " ███ ███ ", " ▄███▄ ▄███▄ "];
66
66
 
67
67
  // Apply gradient to logo
68
- const logoColored = piLogo.map((line) => this.gradientLine(line));
68
+ const logoColored = piLogo.map(line => this.gradientLine(line));
69
69
 
70
70
  // Left column - centered content
71
71
  const leftLines = [
72
72
  "",
73
73
  this.centerText(theme.bold("Welcome back!"), leftCol),
74
74
  "",
75
- ...logoColored.map((l) => this.centerText(l, leftCol)),
75
+ ...logoColored.map(l => this.centerText(l, leftCol)),
76
76
  "",
77
77
  this.centerText(theme.fg("muted", this.modelName), leftCol),
78
78
  this.centerText(theme.fg("borderMuted", this.providerName), leftCol),
@@ -1,25 +1,25 @@
1
- import { mkdir, rm } from "node:fs/promises";
1
+ import * as fs from "node:fs/promises";
2
2
  import * as os from "node:os";
3
3
  import * as path from "node:path";
4
4
  import type { UsageLimit, UsageReport } from "@oh-my-pi/pi-ai";
5
- import { getDebugLogPath } from "@oh-my-pi/pi-coding-agent/config";
6
- import { loadCustomShare } from "@oh-my-pi/pi-coding-agent/export/custom-share";
7
- import type { CompactOptions } from "@oh-my-pi/pi-coding-agent/extensibility/extensions/types";
8
- import { getGatewayStatus } from "@oh-my-pi/pi-coding-agent/ipy/gateway-coordinator";
9
- import { ArminComponent } from "@oh-my-pi/pi-coding-agent/modes/components/armin";
10
- import { BashExecutionComponent } from "@oh-my-pi/pi-coding-agent/modes/components/bash-execution";
11
- import { BorderedLoader } from "@oh-my-pi/pi-coding-agent/modes/components/bordered-loader";
12
- import { DynamicBorder } from "@oh-my-pi/pi-coding-agent/modes/components/dynamic-border";
13
- import { PythonExecutionComponent } from "@oh-my-pi/pi-coding-agent/modes/components/python-execution";
14
- import { getMarkdownTheme, getSymbolTheme, theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
15
- import type { InteractiveModeContext } from "@oh-my-pi/pi-coding-agent/modes/types";
16
- import { createCompactionSummaryMessage } from "@oh-my-pi/pi-coding-agent/session/messages";
17
- import { outputMeta } from "@oh-my-pi/pi-coding-agent/tools/output-meta";
18
- import { getChangelogPath, parseChangelog } from "@oh-my-pi/pi-coding-agent/utils/changelog";
19
- import { copyToClipboard } from "@oh-my-pi/pi-coding-agent/utils/clipboard";
20
5
  import { Loader, Markdown, Spacer, Text, visibleWidth } from "@oh-my-pi/pi-tui";
21
6
  import { $ } from "bun";
22
7
  import { nanoid } from "nanoid";
8
+ import { getDebugLogPath } from "../../config";
9
+ import { loadCustomShare } from "../../export/custom-share";
10
+ import type { CompactOptions } from "../../extensibility/extensions/types";
11
+ import { getGatewayStatus } from "../../ipy/gateway-coordinator";
12
+ import { ArminComponent } from "../../modes/components/armin";
13
+ import { BashExecutionComponent } from "../../modes/components/bash-execution";
14
+ import { BorderedLoader } from "../../modes/components/bordered-loader";
15
+ import { DynamicBorder } from "../../modes/components/dynamic-border";
16
+ import { PythonExecutionComponent } from "../../modes/components/python-execution";
17
+ import { getMarkdownTheme, getSymbolTheme, theme } from "../../modes/theme/theme";
18
+ import type { InteractiveModeContext } from "../../modes/types";
19
+ import { createCompactionSummaryMessage } from "../../session/messages";
20
+ import { outputMeta } from "../../tools/output-meta";
21
+ import { getChangelogPath, parseChangelog } from "../../utils/changelog";
22
+ import { copyToClipboard } from "../../utils/clipboard";
23
23
 
24
24
  export class CommandController {
25
25
  constructor(private readonly ctx: InteractiveModeContext) {}
@@ -77,7 +77,7 @@ export class CommandController {
77
77
  const tmpFile = path.join(os.tmpdir(), `${nanoid()}.html`);
78
78
  const cleanupTempFile = async () => {
79
79
  try {
80
- await rm(tmpFile, { force: true });
80
+ await fs.rm(tmpFile, { force: true });
81
81
  } catch {
82
82
  // Ignore cleanup errors
83
83
  }
@@ -212,7 +212,7 @@ export class CommandController {
212
212
  }
213
213
  }
214
214
 
215
- handleSessionCommand(): void {
215
+ async handleSessionCommand(): Promise<void> {
216
216
  const stats = this.ctx.session.getSessionStats();
217
217
 
218
218
  let info = `${theme.bold("Session Info")}\n\n`;
@@ -240,7 +240,7 @@ export class CommandController {
240
240
  info += `${theme.fg("dim", "Total:")} ${stats.cost.toFixed(4)}\n`;
241
241
  }
242
242
 
243
- const gateway = getGatewayStatus();
243
+ const gateway = await getGatewayStatus();
244
244
  info += `\n${theme.bold("Python Gateway")}\n`;
245
245
  if (gateway.active) {
246
246
  info += `${theme.fg("dim", "Status:")} ${theme.fg("success", "Active (Global)")}\n`;
@@ -316,15 +316,15 @@ export class CommandController {
316
316
  this.ctx.ui.requestRender();
317
317
  }
318
318
 
319
- handleChangelogCommand(): void {
319
+ async handleChangelogCommand(): Promise<void> {
320
320
  const changelogPath = getChangelogPath();
321
- const allEntries = parseChangelog(changelogPath);
321
+ const allEntries = await parseChangelog(changelogPath);
322
322
 
323
323
  const changelogMarkdown =
324
324
  allEntries.length > 0
325
325
  ? allEntries
326
326
  .reverse()
327
- .map((e) => e.content)
327
+ .map(e => e.content)
328
328
  .join("\n\n")
329
329
  : "No changelog entries found.";
330
330
 
@@ -434,12 +434,11 @@ export class CommandController {
434
434
  }),
435
435
  "",
436
436
  "=== Agent messages (JSONL) ===",
437
- ...this.ctx.session.messages.map((msg) => JSON.stringify(msg)),
437
+ ...this.ctx.session.messages.map(msg => JSON.stringify(msg)),
438
438
  "",
439
439
  ].join("\n");
440
440
 
441
441
  try {
442
- await mkdir(path.dirname(debugLogPath), { recursive: true });
443
442
  await Bun.write(debugLogPath, debugData);
444
443
  } catch (error) {
445
444
  this.ctx.showError(`Failed to write debug log: ${error instanceof Error ? error.message : String(error)}`);
@@ -478,7 +477,7 @@ export class CommandController {
478
477
  try {
479
478
  const result = await this.ctx.session.executeBash(
480
479
  command,
481
- (chunk) => {
480
+ chunk => {
482
481
  if (this.ctx.bashComponent) {
483
482
  this.ctx.bashComponent.appendOutput(chunk);
484
483
  this.ctx.ui.requestRender();
@@ -520,7 +519,7 @@ export class CommandController {
520
519
  try {
521
520
  const result = await this.ctx.session.executePython(
522
521
  code,
523
- (chunk) => {
522
+ chunk => {
524
523
  if (this.ctx.pythonComponent) {
525
524
  this.ctx.pythonComponent.appendOutput(chunk);
526
525
  this.ctx.ui.requestRender();
@@ -549,7 +548,7 @@ export class CommandController {
549
548
 
550
549
  async handleCompactCommand(customInstructions?: string): Promise<void> {
551
550
  const entries = this.ctx.sessionManager.getEntries();
552
- const messageCount = entries.filter((e) => e.type === "message").length;
551
+ const messageCount = entries.filter(e => e.type === "message").length;
553
552
 
554
553
  if (messageCount < 2) {
555
554
  this.ctx.showWarning("Nothing to compact (no messages yet)");
@@ -590,8 +589,8 @@ export class CommandController {
590
589
  const label = isAuto ? "Auto-compacting context... (esc to cancel)" : "Compacting context... (esc to cancel)";
591
590
  const compactingLoader = new Loader(
592
591
  this.ctx.ui,
593
- (spinner) => theme.fg("accent", spinner),
594
- (text) => theme.fg("muted", text),
592
+ spinner => theme.fg("accent", spinner),
593
+ text => theme.fg("muted", text),
595
594
  label,
596
595
  getSymbolTheme().spinnerFrames,
597
596
  );
@@ -635,7 +634,7 @@ const COLUMN_WIDTH = BAR_WIDTH + 2;
635
634
  function formatProviderName(provider: string): string {
636
635
  return provider
637
636
  .split(/[-_]/g)
638
- .map((part) => (part ? part[0].toUpperCase() + part.slice(1) : ""))
637
+ .map(part => (part ? part[0].toUpperCase() + part.slice(1) : ""))
639
638
  .join(" ");
640
639
  }
641
640
 
@@ -688,8 +687,8 @@ function resolveFraction(limit: UsageLimit): number | undefined {
688
687
 
689
688
  function resolveProviderUsageTotal(reports: UsageReport[]): number {
690
689
  return reports
691
- .flatMap((report) => report.limits)
692
- .map((limit) => resolveFraction(limit) ?? 0)
690
+ .flatMap(report => report.limits)
691
+ .map(limit => resolveFraction(limit) ?? 0)
693
692
  .reduce((sum, value) => sum + value, 0);
694
693
  }
695
694
 
@@ -741,9 +740,9 @@ function padColumn(text: string, width: number): string {
741
740
  }
742
741
 
743
742
  function resolveAggregateStatus(limits: UsageLimit[]): UsageLimit["status"] {
744
- const hasOk = limits.some((limit) => limit.status === "ok");
745
- const hasWarning = limits.some((limit) => limit.status === "warning");
746
- const hasExhausted = limits.some((limit) => limit.status === "exhausted");
743
+ const hasOk = limits.some(limit => limit.status === "ok");
744
+ const hasWarning = limits.some(limit => limit.status === "warning");
745
+ const hasExhausted = limits.some(limit => limit.status === "exhausted");
747
746
  if (!hasOk && !hasWarning && !hasExhausted) return "unknown";
748
747
  if (hasOk) {
749
748
  return hasWarning || hasExhausted ? "warning" : "ok";
@@ -762,12 +761,12 @@ function isZeroUsage(limit: UsageLimit): boolean {
762
761
  }
763
762
 
764
763
  function isZeroUsageGroup(limits: UsageLimit[]): boolean {
765
- return limits.length > 0 && limits.every((limit) => isZeroUsage(limit));
764
+ return limits.length > 0 && limits.every(limit => isZeroUsage(limit));
766
765
  }
767
766
 
768
767
  function formatAggregateAmount(limits: UsageLimit[]): string {
769
768
  const fractions = limits
770
- .map((limit) => resolveFraction(limit))
769
+ .map(limit => resolveFraction(limit))
771
770
  .filter((value): value is number => value !== undefined);
772
771
  if (fractions.length === limits.length && fractions.length > 0) {
773
772
  const sum = fractions.reduce((total, value) => total + value, 0);
@@ -778,8 +777,8 @@ function formatAggregateAmount(limits: UsageLimit[]): string {
778
777
  }
779
778
 
780
779
  const amounts = limits
781
- .map((limit) => limit.amount)
782
- .filter((amount) => amount.used !== undefined && amount.limit !== undefined && amount.limit > 0);
780
+ .map(limit => limit.amount)
781
+ .filter(amount => amount.used !== undefined && amount.limit !== undefined && amount.limit > 0);
783
782
  if (amounts.length === limits.length && amounts.length > 0) {
784
783
  const totalUsed = amounts.reduce((sum, amount) => sum + (amount.used ?? 0), 0);
785
784
  const totalLimit = amounts.reduce((sum, amount) => sum + (amount.limit ?? 0), 0);
@@ -794,11 +793,11 @@ function formatAggregateAmount(limits: UsageLimit[]): string {
794
793
 
795
794
  function resolveResetRange(limits: UsageLimit[], nowMs: number): string | null {
796
795
  const resets = limits
797
- .map((limit) => limit.window?.resetInMs ?? undefined)
796
+ .map(limit => limit.window?.resetInMs ?? undefined)
798
797
  .filter((value): value is number => value !== undefined && Number.isFinite(value) && value > 0);
799
798
  if (resets.length === 0) {
800
799
  const absolute = limits
801
- .map((limit) => limit.window?.resetsAt)
800
+ .map(limit => limit.window?.resetsAt)
802
801
  .filter((value): value is number => value !== undefined && Number.isFinite(value) && value > nowMs);
803
802
  if (absolute.length === 0) return null;
804
803
  const earliest = Math.min(...absolute);
@@ -841,7 +840,7 @@ function renderUsageBar(limit: UsageLimit, uiTheme: typeof theme): string {
841
840
 
842
841
  function renderUsageReports(reports: UsageReport[], uiTheme: typeof theme, nowMs: number): string {
843
842
  const lines: string[] = [];
844
- const latestFetchedAt = Math.max(...reports.map((report) => report.fetchedAt ?? 0));
843
+ const latestFetchedAt = Math.max(...reports.map(report => report.fetchedAt ?? 0));
845
844
  const headerSuffix = latestFetchedAt ? ` (${formatDuration(nowMs - latestFetchedAt)} ago)` : "";
846
845
  lines.push(uiTheme.bold(uiTheme.fg("accent", `Usage${headerSuffix}`)));
847
846
  const grouped = new Map<string, UsageReport[]>();
@@ -886,7 +885,7 @@ function renderUsageReports(reports: UsageReport[], uiTheme: typeof theme, nowMs
886
885
  }
887
886
  }
888
887
 
889
- const providerAllZero = isZeroUsageGroup(Array.from(limitGroups.values()).flatMap((group) => group.limits));
888
+ const providerAllZero = isZeroUsageGroup(Array.from(limitGroups.values()).flatMap(group => group.limits));
890
889
  if (providerAllZero) {
891
890
  const providerTitle = `${resolveStatusIcon("ok", uiTheme)} ${uiTheme.fg("accent", `${providerName} (0%)`)}`;
892
891
  lines.push(uiTheme.bold(providerTitle));
@@ -908,8 +907,8 @@ function renderUsageReports(reports: UsageReport[], uiTheme: typeof theme, nowMs
908
907
  if (aFraction !== bFraction) return bFraction - aFraction;
909
908
  return a.index - b.index;
910
909
  });
911
- const sortedLimits = entries.map((entry) => entry.limit);
912
- const sortedReports = entries.map((entry) => entry.report);
910
+ const sortedLimits = entries.map(entry => entry.limit);
911
+ const sortedReports = entries.map(entry => entry.report);
913
912
 
914
913
  const status = resolveAggregateStatus(sortedLimits);
915
914
  const statusIcon = resolveStatusIcon(status, uiTheme);
@@ -932,13 +931,13 @@ function renderUsageReports(reports: UsageReport[], uiTheme: typeof theme, nowMs
932
931
  padColumn(formatAccountHeader(limit, sortedReports[index], index, nowMs), COLUMN_WIDTH),
933
932
  );
934
933
  lines.push(` ${accountLabels.join(" ")}`.trimEnd());
935
- const bars = sortedLimits.map((limit) => padColumn(renderUsageBar(limit, uiTheme), COLUMN_WIDTH));
934
+ const bars = sortedLimits.map(limit => padColumn(renderUsageBar(limit, uiTheme), COLUMN_WIDTH));
936
935
  lines.push(` ${bars.join(" ")} ${formatAggregateAmount(sortedLimits)}`.trimEnd());
937
936
  const resetText = sortedLimits.length <= 1 ? resolveResetRange(sortedLimits, nowMs) : null;
938
937
  if (resetText) {
939
938
  lines.push(` ${uiTheme.fg("dim", resetText)}`.trimEnd());
940
939
  }
941
- const notes = sortedLimits.flatMap((limit) => limit.notes ?? []);
940
+ const notes = sortedLimits.flatMap(limit => limit.notes ?? []);
942
941
  if (notes.length > 0) {
943
942
  lines.push(` ${uiTheme.fg("dim", notes.join(" • "))}`.trimEnd());
944
943
  }
@@ -1,17 +1,13 @@
1
- import { AssistantMessageComponent } from "@oh-my-pi/pi-coding-agent/modes/components/assistant-message";
2
- import { ReadToolGroupComponent } from "@oh-my-pi/pi-coding-agent/modes/components/read-tool-group";
3
- import { TodoReminderComponent } from "@oh-my-pi/pi-coding-agent/modes/components/todo-reminder";
4
- import { ToolExecutionComponent } from "@oh-my-pi/pi-coding-agent/modes/components/tool-execution";
5
- import { TtsrNotificationComponent } from "@oh-my-pi/pi-coding-agent/modes/components/ttsr-notification";
6
- import { getSymbolTheme, theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
7
- import type { InteractiveModeContext, TodoItem } from "@oh-my-pi/pi-coding-agent/modes/types";
8
- import type { AgentSessionEvent } from "@oh-my-pi/pi-coding-agent/session/agent-session";
9
- import {
10
- detectNotificationProtocol,
11
- isNotificationSuppressed,
12
- sendNotification,
13
- } from "@oh-my-pi/pi-coding-agent/utils/terminal-notify";
14
1
  import { Loader, Text } from "@oh-my-pi/pi-tui";
2
+ import { AssistantMessageComponent } from "../../modes/components/assistant-message";
3
+ import { ReadToolGroupComponent } from "../../modes/components/read-tool-group";
4
+ import { TodoReminderComponent } from "../../modes/components/todo-reminder";
5
+ import { ToolExecutionComponent } from "../../modes/components/tool-execution";
6
+ import { TtsrNotificationComponent } from "../../modes/components/ttsr-notification";
7
+ import { getSymbolTheme, theme } from "../../modes/theme/theme";
8
+ import type { InteractiveModeContext, TodoItem } from "../../modes/types";
9
+ import type { AgentSessionEvent } from "../../session/agent-session";
10
+ import { detectNotificationProtocol, isNotificationSuppressed, sendNotification } from "../../utils/terminal-notify";
15
11
 
16
12
  export class EventController {
17
13
  private lastReadGroup: ReadToolGroupComponent | undefined = undefined;
@@ -66,8 +62,8 @@ export class EventController {
66
62
  this.ctx.statusContainer.clear();
67
63
  this.ctx.loadingAnimation = new Loader(
68
64
  this.ctx.ui,
69
- (spinner) => theme.fg("accent", spinner),
70
- (text) => theme.fg("muted", text),
65
+ spinner => theme.fg("accent", spinner),
66
+ text => theme.fg("muted", text),
71
67
  `Working${theme.format.ellipsis} (esc to interrupt)`,
72
68
  getSymbolTheme().spinnerFrames,
73
69
  );
@@ -111,7 +107,7 @@ export class EventController {
111
107
  this.ctx.streamingComponent.updateContent(this.ctx.streamingMessage);
112
108
 
113
109
  const thinkingCount = this.ctx.streamingMessage.content.filter(
114
- (content) => content.type === "thinking" && content.thinking.trim(),
110
+ content => content.type === "thinking" && content.thinking.trim(),
115
111
  ).length;
116
112
  if (thinkingCount > this.lastThinkingCount) {
117
113
  this.resetReadGroup();
@@ -277,8 +273,8 @@ export class EventController {
277
273
  const reasonText = event.reason === "overflow" ? "Context overflow detected, " : "";
278
274
  this.ctx.autoCompactionLoader = new Loader(
279
275
  this.ctx.ui,
280
- (spinner) => theme.fg("accent", spinner),
281
- (text) => theme.fg("muted", text),
276
+ spinner => theme.fg("accent", spinner),
277
+ text => theme.fg("muted", text),
282
278
  `${reasonText}Auto-compacting${theme.format.ellipsis} (esc to cancel)`,
283
279
  getSymbolTheme().spinnerFrames,
284
280
  );
@@ -327,8 +323,8 @@ export class EventController {
327
323
  const delaySeconds = Math.round(event.delayMs / 1000);
328
324
  this.ctx.retryLoader = new Loader(
329
325
  this.ctx.ui,
330
- (spinner) => theme.fg("warning", spinner),
331
- (text) => theme.fg("muted", text),
326
+ spinner => theme.fg("warning", spinner),
327
+ text => theme.fg("muted", text),
332
328
  `Retrying (${event.attempt}/${event.maxAttempts}) in ${delaySeconds}s${theme.format.ellipsis} (esc to cancel)`,
333
329
  getSymbolTheme().spinnerFrames,
334
330
  );
@@ -1,26 +1,20 @@
1
- import { KeybindingsManager } from "@oh-my-pi/pi-coding-agent/config/keybindings";
1
+ import type { Component, TUI } from "@oh-my-pi/pi-tui";
2
+ import { Spacer, Text } from "@oh-my-pi/pi-tui";
3
+ import { logger } from "@oh-my-pi/pi-utils";
4
+ import { KeybindingsManager } from "../../config/keybindings";
2
5
  import type {
3
6
  ExtensionActions,
4
7
  ExtensionCommandContextActions,
5
8
  ExtensionContextActions,
6
9
  ExtensionError,
7
10
  ExtensionUIContext,
8
- } from "@oh-my-pi/pi-coding-agent/extensibility/extensions/index";
9
- import { HookEditorComponent } from "@oh-my-pi/pi-coding-agent/modes/components/hook-editor";
10
- import { HookInputComponent } from "@oh-my-pi/pi-coding-agent/modes/components/hook-input";
11
- import { HookSelectorComponent } from "@oh-my-pi/pi-coding-agent/modes/components/hook-selector";
12
- import {
13
- getAvailableThemesWithPaths,
14
- getThemeByName,
15
- setTheme,
16
- type Theme,
17
- theme,
18
- } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
19
- import type { InteractiveModeContext } from "@oh-my-pi/pi-coding-agent/modes/types";
20
- import { setTerminalTitle } from "@oh-my-pi/pi-coding-agent/utils/title-generator";
21
- import type { Component, TUI } from "@oh-my-pi/pi-tui";
22
- import { Spacer, Text } from "@oh-my-pi/pi-tui";
23
- import { logger } from "@oh-my-pi/pi-utils";
11
+ } from "../../extensibility/extensions";
12
+ import { HookEditorComponent } from "../../modes/components/hook-editor";
13
+ import { HookInputComponent } from "../../modes/components/hook-input";
14
+ import { HookSelectorComponent } from "../../modes/components/hook-selector";
15
+ import { getAvailableThemesWithPaths, getThemeByName, setTheme, type Theme, theme } from "../../modes/theme/theme";
16
+ import type { InteractiveModeContext } from "../../modes/types";
17
+ import { setTerminalTitle } from "../../utils/title-generator";
24
18
 
25
19
  export class ExtensionUiController {
26
20
  constructor(private ctx: InteractiveModeContext) {}
@@ -37,22 +31,22 @@ export class ExtensionUiController {
37
31
  notify: (message, type) => this.showHookNotify(message, type),
38
32
  setStatus: (key, text) => this.setHookStatus(key, text),
39
33
  setWidget: (key, content) => this.setHookWidget(key, content),
40
- setTitle: (title) => setTerminalTitle(title),
34
+ setTitle: title => setTerminalTitle(title),
41
35
  custom: (factory, _options) => this.showHookCustom(factory),
42
- setEditorText: (text) => this.ctx.editor.setText(text),
36
+ setEditorText: text => this.ctx.editor.setText(text),
43
37
  getEditorText: () => this.ctx.editor.getText(),
44
38
  editor: (title, prefill) => this.showHookEditor(title, prefill),
45
39
  get theme() {
46
40
  return theme;
47
41
  },
48
- getAllThemes: () => getAvailableThemesWithPaths().map((t) => ({ name: t.name, path: t.path })),
49
- getTheme: (name) => getThemeByName(name),
50
- setTheme: (themeArg) => {
42
+ getAllThemes: async () => (await getAvailableThemesWithPaths()).map(t => ({ name: t.name, path: t.path })),
43
+ getTheme: name => getThemeByName(name),
44
+ setTheme: async themeArg => {
51
45
  if (typeof themeArg === "string") {
52
- return setTheme(themeArg, true);
46
+ return await setTheme(themeArg, true);
53
47
  }
54
48
  // Theme object passed directly - not supported in current implementation
55
- return { success: false, error: "Direct theme object not supported" };
49
+ return Promise.resolve({ success: false, error: "Direct theme object not supported" });
56
50
  },
57
51
  setFooter: () => {},
58
52
  setHeader: () => {},
@@ -98,15 +92,15 @@ export class ExtensionUiController {
98
92
  },
99
93
  getActiveTools: () => this.ctx.session.getActiveToolNames(),
100
94
  getAllTools: () => this.ctx.session.getAllToolNames(),
101
- setActiveTools: (toolNames) => this.ctx.session.setActiveToolsByName(toolNames),
102
- setModel: async (model) => {
95
+ setActiveTools: toolNames => this.ctx.session.setActiveToolsByName(toolNames),
96
+ setModel: async model => {
103
97
  const key = await this.ctx.session.modelRegistry.getApiKey(model);
104
98
  if (!key) return false;
105
99
  await this.ctx.session.setModel(model);
106
100
  return true;
107
101
  },
108
102
  getThinkingLevel: () => this.ctx.session.thinkingLevel,
109
- setThinkingLevel: (level) => this.ctx.session.setThinkingLevel(level),
103
+ setThinkingLevel: level => this.ctx.session.setThinkingLevel(level),
110
104
  };
111
105
  const contextActions: ExtensionContextActions = {
112
106
  getModel: () => this.ctx.session.model,
@@ -117,7 +111,7 @@ export class ExtensionUiController {
117
111
  // Signal shutdown request (will be handled by main loop)
118
112
  },
119
113
  getContextUsage: () => this.ctx.session.getContextUsage(),
120
- compact: async (instructionsOrOptions) => {
114
+ compact: async instructionsOrOptions => {
121
115
  const instructions = typeof instructionsOrOptions === "string" ? instructionsOrOptions : undefined;
122
116
  const options =
123
117
  instructionsOrOptions && typeof instructionsOrOptions === "object" ? instructionsOrOptions : undefined;
@@ -127,7 +121,7 @@ export class ExtensionUiController {
127
121
  const commandActions: ExtensionCommandContextActions = {
128
122
  getContextUsage: () => this.ctx.session.getContextUsage(),
129
123
  waitForIdle: () => this.ctx.session.agent.waitForIdle(),
130
- newSession: async (options) => {
124
+ newSession: async options => {
131
125
  // Stop any loading animation
132
126
  if (this.ctx.loadingAnimation) {
133
127
  this.ctx.loadingAnimation.stop();
@@ -163,7 +157,7 @@ export class ExtensionUiController {
163
157
 
164
158
  return { cancelled: false };
165
159
  },
166
- branch: async (entryId) => {
160
+ branch: async entryId => {
167
161
  const result = await this.ctx.session.branch(entryId);
168
162
  if (result.cancelled) {
169
163
  return { cancelled: true };
@@ -195,7 +189,7 @@ export class ExtensionUiController {
195
189
 
196
190
  return { cancelled: false };
197
191
  },
198
- compact: async (instructionsOrOptions) => {
192
+ compact: async instructionsOrOptions => {
199
193
  const instructions = typeof instructionsOrOptions === "string" ? instructionsOrOptions : undefined;
200
194
  const options =
201
195
  instructionsOrOptions && typeof instructionsOrOptions === "object" ? instructionsOrOptions : undefined;
@@ -267,15 +261,15 @@ export class ExtensionUiController {
267
261
  },
268
262
  getActiveTools: () => this.ctx.session.getActiveToolNames(),
269
263
  getAllTools: () => this.ctx.session.getAllToolNames(),
270
- setActiveTools: (toolNames) => this.ctx.session.setActiveToolsByName(toolNames),
271
- setModel: async (model) => {
264
+ setActiveTools: toolNames => this.ctx.session.setActiveToolsByName(toolNames),
265
+ setModel: async model => {
272
266
  const key = await this.ctx.session.modelRegistry.getApiKey(model);
273
267
  if (!key) return false;
274
268
  await this.ctx.session.setModel(model);
275
269
  return true;
276
270
  },
277
271
  getThinkingLevel: () => this.ctx.session.thinkingLevel,
278
- setThinkingLevel: (level) => this.ctx.session.setThinkingLevel(level),
272
+ setThinkingLevel: level => this.ctx.session.setThinkingLevel(level),
279
273
  };
280
274
  const contextActions: ExtensionContextActions = {
281
275
  getModel: () => this.ctx.session.model,
@@ -286,7 +280,7 @@ export class ExtensionUiController {
286
280
  // Signal shutdown request (will be handled by main loop)
287
281
  },
288
282
  getContextUsage: () => this.ctx.session.getContextUsage(),
289
- compact: async (instructionsOrOptions) => {
283
+ compact: async instructionsOrOptions => {
290
284
  const instructions = typeof instructionsOrOptions === "string" ? instructionsOrOptions : undefined;
291
285
  const options =
292
286
  instructionsOrOptions && typeof instructionsOrOptions === "object" ? instructionsOrOptions : undefined;
@@ -296,7 +290,7 @@ export class ExtensionUiController {
296
290
  const commandActions: ExtensionCommandContextActions = {
297
291
  getContextUsage: () => this.ctx.session.getContextUsage(),
298
292
  waitForIdle: () => this.ctx.session.agent.waitForIdle(),
299
- newSession: async (options) => {
293
+ newSession: async options => {
300
294
  if (this.ctx.isBackgrounded) {
301
295
  return { cancelled: true };
302
296
  }
@@ -335,7 +329,7 @@ export class ExtensionUiController {
335
329
 
336
330
  return { cancelled: false };
337
331
  },
338
- branch: async (entryId) => {
332
+ branch: async entryId => {
339
333
  if (this.ctx.isBackgrounded) {
340
334
  return { cancelled: true };
341
335
  }
@@ -373,7 +367,7 @@ export class ExtensionUiController {
373
367
 
374
368
  return { cancelled: false };
375
369
  },
376
- compact: async (instructionsOrOptions) => {
370
+ compact: async instructionsOrOptions => {
377
371
  const instructions = typeof instructionsOrOptions === "string" ? instructionsOrOptions : undefined;
378
372
  const options =
379
373
  instructionsOrOptions && typeof instructionsOrOptions === "object" ? instructionsOrOptions : undefined;
@@ -404,9 +398,9 @@ export class ExtensionUiController {
404
398
  get theme() {
405
399
  return theme;
406
400
  },
407
- getAllThemes: () => [],
408
- getTheme: () => undefined,
409
- setTheme: () => ({ success: false, error: "Background mode" }),
401
+ getAllThemes: () => Promise.resolve([]),
402
+ getTheme: () => Promise.resolve(undefined),
403
+ setTheme: () => Promise.resolve({ success: false, error: "Background mode" }),
410
404
  setFooter: () => {},
411
405
  setHeader: () => {},
412
406
  setEditorComponent: () => {},
@@ -431,7 +425,7 @@ export class ExtensionUiController {
431
425
  await registeredTool.definition.onSession(event, {
432
426
  ui: uiContext,
433
427
  getContextUsage: () => this.ctx.session.getContextUsage(),
434
- compact: async (instructionsOrOptions) => {
428
+ compact: async instructionsOrOptions => {
435
429
  const instructions = typeof instructionsOrOptions === "string" ? instructionsOrOptions : undefined;
436
430
  const options =
437
431
  instructionsOrOptions && typeof instructionsOrOptions === "object"
@@ -493,7 +487,7 @@ export class ExtensionUiController {
493
487
  this.ctx.hookSelector = new HookSelectorComponent(
494
488
  title,
495
489
  options,
496
- (option) => {
490
+ option => {
497
491
  this.hideHookSelector();
498
492
  resolve(option);
499
493
  },
@@ -538,7 +532,7 @@ export class ExtensionUiController {
538
532
  this.ctx.hookInput = new HookInputComponent(
539
533
  title,
540
534
  placeholder,
541
- (value) => {
535
+ value => {
542
536
  this.hideHookInput();
543
537
  resolve(value);
544
538
  },
@@ -575,7 +569,7 @@ export class ExtensionUiController {
575
569
  this.ctx.ui,
576
570
  title,
577
571
  prefill,
578
- (value) => {
572
+ value => {
579
573
  this.hideHookEditor();
580
574
  resolve(value);
581
575
  },
@@ -643,7 +637,7 @@ export class ExtensionUiController {
643
637
  resolve(result);
644
638
  };
645
639
 
646
- Promise.try(() => factory(this.ctx.ui, theme, keybindings, close)).then((c) => {
640
+ Promise.try(() => factory(this.ctx.ui, theme, keybindings, close)).then(c => {
647
641
  component = c;
648
642
  this.ctx.editorContainer.clear();
649
643
  this.ctx.editorContainer.addChild(component);