@oh-my-pi/pi-coding-agent 15.10.10 → 15.10.12

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 (415) hide show
  1. package/CHANGELOG.md +142 -7
  2. package/dist/cli.js +23108 -0
  3. package/dist/tokenizers.linux-x64-gnu-xcjh3jwk.node +0 -0
  4. package/dist/types/async/job-manager.d.ts +18 -0
  5. package/dist/types/cli/args.d.ts +2 -1
  6. package/dist/types/cli/dry-balance-cli.d.ts +1 -1
  7. package/dist/types/cli/gallery-cli.d.ts +1 -1
  8. package/dist/types/cli/gallery-fixtures/types.d.ts +1 -1
  9. package/dist/types/cli/usage-cli.d.ts +72 -0
  10. package/dist/types/cli-commands.d.ts +12 -0
  11. package/dist/types/commands/launch.d.ts +5 -1
  12. package/dist/types/commands/read.d.ts +1 -1
  13. package/dist/types/commands/usage.d.ts +25 -0
  14. package/dist/types/config/api-key-resolver.d.ts +3 -0
  15. package/dist/types/config/append-only-context-mode.d.ts +2 -1
  16. package/dist/types/config/model-discovery.d.ts +55 -0
  17. package/dist/types/config/model-registry.d.ts +8 -219
  18. package/dist/types/config/model-resolver.d.ts +34 -10
  19. package/dist/types/config/model-roles.d.ts +28 -0
  20. package/dist/types/config/models-config-schema.d.ts +523 -42
  21. package/dist/types/config/models-config.d.ts +385 -0
  22. package/dist/types/config/settings-schema.d.ts +41 -8
  23. package/dist/types/config/settings.d.ts +8 -1
  24. package/dist/types/debug/log-viewer.d.ts +1 -1
  25. package/dist/types/debug/raw-sse.d.ts +1 -1
  26. package/dist/types/edit/hashline/noop-loop-guard.d.ts +72 -0
  27. package/dist/types/eval/backend.d.ts +0 -2
  28. package/dist/types/eval/idle-timeout.d.ts +0 -4
  29. package/dist/types/eval/js/shared/rewrite-imports.d.ts +6 -6
  30. package/dist/types/eval/py/executor.d.ts +5 -0
  31. package/dist/types/eval/py/kernel.d.ts +6 -1
  32. package/dist/types/eval/py/runtime.d.ts +9 -0
  33. package/dist/types/exec/bash-executor.d.ts +2 -0
  34. package/dist/types/export/html/template.generated.d.ts +1 -1
  35. package/dist/types/extensibility/extensions/runner.d.ts +3 -2
  36. package/dist/types/extensibility/extensions/types.d.ts +6 -3
  37. package/dist/types/hindsight/mental-models.d.ts +17 -8
  38. package/dist/types/internal-urls/artifact-protocol.d.ts +2 -2
  39. package/dist/types/internal-urls/types.d.ts +1 -1
  40. package/dist/types/lsp/edits.d.ts +9 -0
  41. package/dist/types/lsp/index.d.ts +2 -2
  42. package/dist/types/lsp/types.d.ts +2 -0
  43. package/dist/types/lsp/utils.d.ts +3 -0
  44. package/dist/types/mcp/json-rpc.d.ts +5 -0
  45. package/dist/types/memory-backend/index.d.ts +1 -0
  46. package/dist/types/memory-backend/runtime.d.ts +4 -0
  47. package/dist/types/memory-backend/types.d.ts +66 -1
  48. package/dist/types/mnemopi/state.d.ts +11 -1
  49. package/dist/types/modes/components/agent-dashboard.d.ts +1 -1
  50. package/dist/types/modes/components/assistant-message.d.ts +3 -1
  51. package/dist/types/modes/components/bash-execution.d.ts +1 -1
  52. package/dist/types/modes/components/copy-selector.d.ts +1 -1
  53. package/dist/types/modes/components/dynamic-border.d.ts +1 -1
  54. package/dist/types/modes/components/extensions/extension-dashboard.d.ts +1 -1
  55. package/dist/types/modes/components/extensions/extension-list.d.ts +1 -1
  56. package/dist/types/modes/components/extensions/inspector-panel.d.ts +1 -1
  57. package/dist/types/modes/components/footer.d.ts +1 -1
  58. package/dist/types/modes/components/hook-editor.d.ts +5 -0
  59. package/dist/types/modes/components/hook-input.d.ts +4 -0
  60. package/dist/types/modes/components/hook-selector.d.ts +1 -1
  61. package/dist/types/modes/components/model-selector.d.ts +1 -1
  62. package/dist/types/modes/components/plan-review-overlay.d.ts +1 -1
  63. package/dist/types/modes/components/session-observer-overlay.d.ts +1 -1
  64. package/dist/types/modes/components/session-selector.d.ts +1 -1
  65. package/dist/types/modes/components/status-line/component.d.ts +1 -1
  66. package/dist/types/modes/components/tiny-title-download-progress.d.ts +1 -1
  67. package/dist/types/modes/components/transcript-container.d.ts +25 -6
  68. package/dist/types/modes/components/tree-selector.d.ts +1 -1
  69. package/dist/types/modes/components/user-message-selector.d.ts +1 -1
  70. package/dist/types/modes/components/user-message.d.ts +2 -1
  71. package/dist/types/modes/components/visual-truncate.d.ts +1 -1
  72. package/dist/types/modes/components/welcome.d.ts +19 -3
  73. package/dist/types/modes/controllers/mcp-command-controller.d.ts +1 -1
  74. package/dist/types/modes/controllers/streaming-reveal.d.ts +1 -1
  75. package/dist/types/modes/index.d.ts +3 -3
  76. package/dist/types/modes/interactive-mode.d.ts +8 -3
  77. package/dist/types/modes/oauth-manual-input.d.ts +7 -0
  78. package/dist/types/modes/rpc/rpc-client.d.ts +39 -2
  79. package/dist/types/modes/rpc/rpc-mode.d.ts +31 -2
  80. package/dist/types/modes/rpc/rpc-subagents.d.ts +24 -0
  81. package/dist/types/modes/rpc/rpc-types.d.ts +75 -1
  82. package/dist/types/modes/setup-wizard/index.d.ts +5 -1
  83. package/dist/types/modes/setup-wizard/lazy.d.ts +2 -0
  84. package/dist/types/modes/setup-wizard/scenes/sign-in.d.ts +1 -1
  85. package/dist/types/modes/setup-wizard/scenes/types.d.ts +1 -1
  86. package/dist/types/modes/setup-wizard/scenes/web-search.d.ts +1 -1
  87. package/dist/types/modes/setup-wizard/wizard-overlay.d.ts +1 -1
  88. package/dist/types/modes/types.d.ts +4 -1
  89. package/dist/types/secrets/index.d.ts +1 -1
  90. package/dist/types/secrets/obfuscator.d.ts +8 -2
  91. package/dist/types/session/agent-session.d.ts +15 -3
  92. package/dist/types/session/auth-broker-config.d.ts +4 -0
  93. package/dist/types/session/session-manager.d.ts +1 -1
  94. package/dist/types/session/streaming-output.d.ts +23 -0
  95. package/dist/types/slash-commands/acp-builtins.d.ts +16 -0
  96. package/dist/types/slash-commands/builtin-registry.d.ts +1 -0
  97. package/dist/types/slash-commands/helpers/stats-dashboard.d.ts +13 -0
  98. package/dist/types/slash-commands/types.d.ts +1 -1
  99. package/dist/types/ssh/connection-manager.d.ts +8 -0
  100. package/dist/types/system-prompt.d.ts +2 -0
  101. package/dist/types/task/executor.d.ts +1 -0
  102. package/dist/types/task/index.d.ts +2 -2
  103. package/dist/types/task/parallel.d.ts +2 -2
  104. package/dist/types/task/types.d.ts +8 -0
  105. package/dist/types/task/worktree.d.ts +2 -0
  106. package/dist/types/thinking.d.ts +4 -0
  107. package/dist/types/tiny/title-client.d.ts +11 -0
  108. package/dist/types/tiny/title-protocol.d.ts +1 -0
  109. package/dist/types/tools/ask.d.ts +4 -0
  110. package/dist/types/tools/conflict-detect.d.ts +16 -0
  111. package/dist/types/tools/github-cache.d.ts +7 -0
  112. package/dist/types/tools/index.d.ts +6 -0
  113. package/dist/types/tools/sqlite-reader.d.ts +3 -0
  114. package/dist/types/tui/output-block.d.ts +3 -3
  115. package/dist/types/utils/changelog.d.ts +8 -0
  116. package/dist/types/utils/git.d.ts +15 -2
  117. package/dist/types/utils/title-generator.d.ts +3 -2
  118. package/dist/types/web/scrapers/readthedocs.d.ts +3 -0
  119. package/dist/types/web/scrapers/types.d.ts +12 -0
  120. package/dist/types/web/search/providers/codex.d.ts +1 -1
  121. package/dist/types/web/search/providers/gemini.d.ts +1 -1
  122. package/examples/extensions/tools.ts +5 -4
  123. package/package.json +14 -11
  124. package/scripts/build-binary.ts +18 -23
  125. package/scripts/bundle-dist.ts +81 -0
  126. package/scripts/{dev-launch → omp} +1 -1
  127. package/scripts/{dev-launch-preload.ts → omp.ts} +1 -1
  128. package/src/async/job-manager.ts +57 -3
  129. package/src/auto-thinking/classifier.ts +1 -0
  130. package/src/autoresearch/dashboard.ts +1 -1
  131. package/src/autoresearch/prompt-setup.md +6 -6
  132. package/src/autoresearch/prompt.md +6 -6
  133. package/src/capability/fs.ts +10 -0
  134. package/src/cli/args.ts +4 -1
  135. package/src/cli/auth-gateway-cli.ts +1 -3
  136. package/src/cli/dry-balance-cli.ts +1 -1
  137. package/src/cli/gallery-cli.ts +1 -1
  138. package/src/cli/gallery-fixtures/fs.ts +1 -1
  139. package/src/cli/gallery-fixtures/types.ts +5 -1
  140. package/src/cli/list-models.ts +2 -1
  141. package/src/cli/usage-cli.ts +603 -0
  142. package/src/cli-commands.ts +30 -0
  143. package/src/cli.ts +76 -13
  144. package/src/commands/complete.ts +1 -1
  145. package/src/commands/launch.ts +5 -1
  146. package/src/commands/read.ts +6 -3
  147. package/src/commands/usage.ts +35 -0
  148. package/src/commit/agentic/agent.ts +1 -1
  149. package/src/commit/model-selection.ts +4 -3
  150. package/src/config/api-key-resolver.ts +8 -6
  151. package/src/config/append-only-context-mode.ts +6 -12
  152. package/src/config/model-discovery.ts +554 -0
  153. package/src/config/model-registry.ts +320 -1041
  154. package/src/config/model-resolver.ts +173 -156
  155. package/src/config/model-roles.ts +74 -0
  156. package/src/config/models-config-schema.ts +57 -8
  157. package/src/config/models-config.ts +129 -0
  158. package/src/config/settings-schema.ts +61 -19
  159. package/src/config/settings.ts +98 -4
  160. package/src/dap/client.ts +124 -37
  161. package/src/dap/session.ts +259 -158
  162. package/src/debug/log-viewer.ts +1 -1
  163. package/src/debug/raw-sse.ts +1 -1
  164. package/src/edit/diff.ts +47 -3
  165. package/src/edit/hashline/block-resolver.ts +20 -1
  166. package/src/edit/hashline/diff.ts +36 -1
  167. package/src/edit/hashline/execute.ts +47 -4
  168. package/src/edit/hashline/noop-loop-guard.ts +99 -0
  169. package/src/edit/index.ts +16 -1
  170. package/src/edit/modes/patch.ts +52 -0
  171. package/src/edit/modes/replace.ts +56 -22
  172. package/src/edit/notebook.ts +22 -2
  173. package/src/edit/renderer.ts +36 -10
  174. package/src/eval/__tests__/completion-bridge.test.ts +1 -1
  175. package/src/eval/backend.ts +0 -2
  176. package/src/eval/completion-bridge.ts +3 -1
  177. package/src/eval/idle-timeout.ts +2 -9
  178. package/src/eval/js/context-manager.ts +6 -8
  179. package/src/eval/js/executor.ts +6 -2
  180. package/src/eval/js/index.ts +0 -2
  181. package/src/eval/js/shared/helpers.ts +5 -6
  182. package/src/eval/js/shared/local-module-loader.ts +1 -1
  183. package/src/eval/js/shared/prelude.txt +62 -1
  184. package/src/eval/js/shared/rewrite-imports.ts +40 -22
  185. package/src/eval/js/shared/runtime.ts +1 -1
  186. package/src/eval/py/executor.ts +29 -7
  187. package/src/eval/py/index.ts +6 -3
  188. package/src/eval/py/kernel.ts +43 -4
  189. package/src/eval/py/runner.py +107 -3
  190. package/src/eval/py/runtime.ts +37 -0
  191. package/src/exec/bash-executor.ts +85 -4
  192. package/src/export/html/template.generated.ts +1 -1
  193. package/src/export/html/template.js +3 -1
  194. package/src/extensibility/extensions/get-commands-handler.ts +2 -1
  195. package/src/extensibility/extensions/runner.ts +6 -1
  196. package/src/extensibility/extensions/types.ts +6 -2
  197. package/src/extensibility/plugins/legacy-pi-compat.ts +20 -3
  198. package/src/hindsight/bank.ts +17 -2
  199. package/src/hindsight/mental-models.ts +59 -12
  200. package/src/hindsight/state.ts +6 -1
  201. package/src/internal-urls/artifact-protocol.ts +11 -2
  202. package/src/internal-urls/docs-index.generated.ts +11 -11
  203. package/src/internal-urls/issue-pr-protocol.ts +12 -5
  204. package/src/internal-urls/router.ts +1 -1
  205. package/src/internal-urls/types.ts +1 -1
  206. package/src/lib/xai-http.ts +1 -1
  207. package/src/lsp/client.ts +118 -38
  208. package/src/lsp/clients/biome-client.ts +101 -39
  209. package/src/lsp/edits.ts +143 -95
  210. package/src/lsp/index.ts +31 -22
  211. package/src/lsp/render.ts +1 -1
  212. package/src/lsp/types.ts +2 -0
  213. package/src/lsp/utils.ts +28 -10
  214. package/src/main.ts +183 -23
  215. package/src/mcp/json-rpc.ts +35 -5
  216. package/src/mcp/transports/stdio.ts +7 -1
  217. package/src/memories/index.ts +4 -1
  218. package/src/memory-backend/index.ts +1 -0
  219. package/src/memory-backend/local-backend.ts +9 -0
  220. package/src/memory-backend/off-backend.ts +9 -0
  221. package/src/memory-backend/runtime.ts +66 -0
  222. package/src/memory-backend/types.ts +81 -1
  223. package/src/mnemopi/backend.ts +176 -7
  224. package/src/mnemopi/state.ts +38 -2
  225. package/src/modes/acp/acp-agent.ts +119 -11
  226. package/src/modes/components/agent-dashboard.ts +10 -7
  227. package/src/modes/components/assistant-message.ts +32 -28
  228. package/src/modes/components/bash-execution.ts +1 -1
  229. package/src/modes/components/copy-selector.ts +1 -1
  230. package/src/modes/components/diff.ts +13 -2
  231. package/src/modes/components/dynamic-border.ts +12 -3
  232. package/src/modes/components/extensions/extension-dashboard.ts +8 -5
  233. package/src/modes/components/extensions/extension-list.ts +1 -1
  234. package/src/modes/components/extensions/inspector-panel.ts +1 -1
  235. package/src/modes/components/footer.ts +4 -2
  236. package/src/modes/components/history-search.ts +1 -1
  237. package/src/modes/components/hook-editor.ts +8 -0
  238. package/src/modes/components/hook-input.ts +8 -0
  239. package/src/modes/components/hook-selector.ts +2 -2
  240. package/src/modes/components/model-selector.ts +4 -2
  241. package/src/modes/components/plan-review-overlay.ts +1 -1
  242. package/src/modes/components/session-observer-overlay.ts +2 -2
  243. package/src/modes/components/session-selector.ts +1 -1
  244. package/src/modes/components/settings-selector.ts +5 -1
  245. package/src/modes/components/status-line/component.ts +119 -35
  246. package/src/modes/components/tiny-title-download-progress.ts +1 -1
  247. package/src/modes/components/transcript-container.ts +258 -53
  248. package/src/modes/components/tree-selector.ts +3 -3
  249. package/src/modes/components/user-message-selector.ts +1 -1
  250. package/src/modes/components/user-message.ts +17 -5
  251. package/src/modes/components/visual-truncate.ts +1 -1
  252. package/src/modes/components/welcome.ts +108 -26
  253. package/src/modes/controllers/command-controller.ts +11 -4
  254. package/src/modes/controllers/event-controller.ts +73 -4
  255. package/src/modes/controllers/input-controller.ts +2 -1
  256. package/src/modes/controllers/mcp-command-controller.ts +39 -4
  257. package/src/modes/controllers/selector-controller.ts +1 -1
  258. package/src/modes/controllers/streaming-reveal.ts +85 -18
  259. package/src/modes/index.ts +3 -21
  260. package/src/modes/interactive-mode.ts +42 -18
  261. package/src/modes/oauth-manual-input.ts +30 -3
  262. package/src/modes/rpc/rpc-client.ts +154 -3
  263. package/src/modes/rpc/rpc-mode.ts +97 -12
  264. package/src/modes/rpc/rpc-subagents.ts +265 -0
  265. package/src/modes/rpc/rpc-types.ts +81 -1
  266. package/src/modes/setup-wizard/index.ts +12 -2
  267. package/src/modes/setup-wizard/lazy.ts +16 -0
  268. package/src/modes/setup-wizard/scenes/glyph.ts +1 -1
  269. package/src/modes/setup-wizard/scenes/providers.ts +1 -1
  270. package/src/modes/setup-wizard/scenes/sign-in.ts +1 -1
  271. package/src/modes/setup-wizard/scenes/theme.ts +1 -1
  272. package/src/modes/setup-wizard/scenes/types.ts +1 -1
  273. package/src/modes/setup-wizard/scenes/web-search.ts +1 -1
  274. package/src/modes/setup-wizard/wizard-overlay.ts +1 -1
  275. package/src/modes/types.ts +4 -1
  276. package/src/prompts/agents/explore.md +2 -2
  277. package/src/prompts/agents/librarian.md +1 -2
  278. package/src/prompts/agents/oracle.md +1 -1
  279. package/src/prompts/agents/plan.md +5 -5
  280. package/src/prompts/agents/task.md +5 -5
  281. package/src/prompts/ci-green-request.md +5 -7
  282. package/src/prompts/goals/goal-budget-limit.md +2 -2
  283. package/src/prompts/goals/goal-continuation.md +4 -4
  284. package/src/prompts/goals/goal-mode-active.md +1 -1
  285. package/src/prompts/memories/read-path.md +1 -1
  286. package/src/prompts/memories/stage_one_system.md +2 -2
  287. package/src/prompts/review-custom-request.md +1 -1
  288. package/src/prompts/system/agent-creation-architect.md +2 -2
  289. package/src/prompts/system/auto-continue.md +1 -1
  290. package/src/prompts/system/background-tan-dispatch.md +1 -1
  291. package/src/prompts/system/btw-user.md +2 -2
  292. package/src/prompts/system/commit-message-system.md +13 -1
  293. package/src/prompts/system/custom-system-prompt.md +1 -1
  294. package/src/prompts/system/eager-todo.md +2 -2
  295. package/src/prompts/system/irc-incoming.md +1 -1
  296. package/src/prompts/system/manual-continue.md +1 -1
  297. package/src/prompts/system/omfg-user.md +3 -4
  298. package/src/prompts/system/orchestrate-notice.md +9 -9
  299. package/src/prompts/system/plan-mode-active.md +4 -4
  300. package/src/prompts/system/plan-mode-subagent.md +4 -5
  301. package/src/prompts/system/plan-mode-tool-decision-reminder.md +1 -1
  302. package/src/prompts/system/project-prompt.md +2 -2
  303. package/src/prompts/system/subagent-system-prompt.md +4 -4
  304. package/src/prompts/system/system-prompt.md +13 -24
  305. package/src/prompts/system/title-system.md +2 -2
  306. package/src/prompts/system/ttsr-tool-reminder.md +1 -1
  307. package/src/prompts/system/workflow-notice.md +1 -1
  308. package/src/prompts/tools/ast-edit.md +1 -1
  309. package/src/prompts/tools/ast-grep.md +2 -2
  310. package/src/prompts/tools/bash.md +5 -7
  311. package/src/prompts/tools/browser.md +7 -7
  312. package/src/prompts/tools/debug.md +1 -1
  313. package/src/prompts/tools/eval.md +3 -3
  314. package/src/prompts/tools/find.md +0 -1
  315. package/src/prompts/tools/github.md +8 -7
  316. package/src/prompts/tools/goal.md +1 -1
  317. package/src/prompts/tools/image-gen.md +1 -1
  318. package/src/prompts/tools/inspect-image-system.md +1 -1
  319. package/src/prompts/tools/irc.md +15 -15
  320. package/src/prompts/tools/lsp.md +2 -2
  321. package/src/prompts/tools/patch.md +2 -2
  322. package/src/prompts/tools/read.md +3 -4
  323. package/src/prompts/tools/recall.md +1 -1
  324. package/src/prompts/tools/reflect.md +1 -1
  325. package/src/prompts/tools/render-mermaid.md +2 -2
  326. package/src/prompts/tools/replace.md +4 -10
  327. package/src/prompts/tools/rewind.md +2 -2
  328. package/src/prompts/tools/search-tool-bm25.md +1 -9
  329. package/src/prompts/tools/search.md +0 -1
  330. package/src/prompts/tools/ssh.md +0 -4
  331. package/src/prompts/tools/task.md +2 -3
  332. package/src/prompts/tools/todo.md +1 -1
  333. package/src/sdk.ts +31 -11
  334. package/src/secrets/index.ts +8 -1
  335. package/src/secrets/obfuscator.ts +39 -18
  336. package/src/session/agent-session.ts +223 -64
  337. package/src/session/auth-broker-config.ts +30 -1
  338. package/src/session/session-manager.ts +2 -2
  339. package/src/session/streaming-output.ts +188 -11
  340. package/src/slash-commands/acp-builtins.ts +24 -0
  341. package/src/slash-commands/builtin-registry.ts +40 -0
  342. package/src/slash-commands/helpers/stats-dashboard.ts +85 -0
  343. package/src/slash-commands/types.ts +1 -1
  344. package/src/ssh/connection-manager.ts +27 -0
  345. package/src/system-prompt.ts +14 -0
  346. package/src/task/commands.ts +2 -1
  347. package/src/task/executor.ts +74 -65
  348. package/src/task/index.ts +146 -68
  349. package/src/task/parallel.ts +3 -3
  350. package/src/task/render.ts +20 -5
  351. package/src/task/types.ts +9 -0
  352. package/src/task/worktree.ts +64 -56
  353. package/src/thinking.ts +9 -1
  354. package/src/tiny/title-client.ts +60 -16
  355. package/src/tiny/title-protocol.ts +1 -1
  356. package/src/tiny/worker.ts +6 -4
  357. package/src/tools/archive-reader.ts +30 -2
  358. package/src/tools/ask.ts +104 -21
  359. package/src/tools/ast-edit.ts +25 -5
  360. package/src/tools/auto-generated-guard.ts +20 -3
  361. package/src/tools/bash-interactive.ts +27 -7
  362. package/src/tools/bash.ts +100 -18
  363. package/src/tools/browser/launch.ts +11 -2
  364. package/src/tools/browser/readable.ts +19 -2
  365. package/src/tools/browser/registry.ts +4 -1
  366. package/src/tools/browser/render.ts +2 -2
  367. package/src/tools/browser/tab-supervisor.ts +55 -16
  368. package/src/tools/conflict-detect.ts +50 -4
  369. package/src/tools/debug.ts +1 -1
  370. package/src/tools/eval-render.ts +5 -5
  371. package/src/tools/eval.ts +0 -2
  372. package/src/tools/fetch.ts +33 -10
  373. package/src/tools/gh-cache-invalidation.ts +63 -8
  374. package/src/tools/gh-renderer.ts +1 -1
  375. package/src/tools/gh.ts +172 -29
  376. package/src/tools/github-cache.ts +70 -6
  377. package/src/tools/image-gen.ts +14 -13
  378. package/src/tools/index.ts +13 -1
  379. package/src/tools/inspect-image.ts +1 -0
  380. package/src/tools/irc.ts +5 -1
  381. package/src/tools/job.ts +1 -1
  382. package/src/tools/read.ts +202 -61
  383. package/src/tools/render-utils.ts +3 -3
  384. package/src/tools/resolve.ts +1 -1
  385. package/src/tools/search.ts +92 -29
  386. package/src/tools/sqlite-reader.ts +17 -5
  387. package/src/tools/ssh.ts +8 -8
  388. package/src/tools/todo.ts +38 -8
  389. package/src/tools/write.ts +118 -18
  390. package/src/tui/output-block.ts +4 -4
  391. package/src/utils/changelog.ts +27 -1
  392. package/src/utils/commit-message-generator.ts +1 -0
  393. package/src/utils/file-mentions.ts +2 -1
  394. package/src/utils/git.ts +267 -13
  395. package/src/utils/title-generator.ts +24 -5
  396. package/src/web/scrapers/arxiv.ts +1 -1
  397. package/src/web/scrapers/go-pkg.ts +1 -1
  398. package/src/web/scrapers/iacr.ts +1 -1
  399. package/src/web/scrapers/readthedocs.ts +1 -1
  400. package/src/web/scrapers/twitter.ts +2 -1
  401. package/src/web/scrapers/types.ts +87 -8
  402. package/src/web/scrapers/wikipedia.ts +1 -1
  403. package/src/web/scrapers/youtube.ts +6 -1
  404. package/src/web/search/index.ts +1 -1
  405. package/src/web/search/providers/codex.ts +2 -1
  406. package/src/web/search/providers/gemini.ts +2 -3
  407. package/src/web/search/render.ts +8 -6
  408. package/dist/types/config/model-equivalence.d.ts +0 -24
  409. package/dist/types/config/model-id-affixes.d.ts +0 -12
  410. package/dist/types/config/model-provider-priority.d.ts +0 -1
  411. package/dist/types/exec/idle-timeout-watchdog.d.ts +0 -18
  412. package/src/config/model-equivalence.ts +0 -875
  413. package/src/config/model-id-affixes.ts +0 -81
  414. package/src/config/model-provider-priority.ts +0 -56
  415. package/src/exec/idle-timeout-watchdog.ts +0 -126
@@ -194,7 +194,7 @@ class AgentListPane implements Component {
194
194
  private readonly maxVisible: number,
195
195
  ) {}
196
196
 
197
- render(width: number): string[] {
197
+ render(width: number): readonly string[] {
198
198
  const lines: string[] = [];
199
199
  const searchPrefix = theme.fg("muted", "Search: ");
200
200
  const searchText = this.searchQuery || theme.fg("dim", "type to filter");
@@ -255,7 +255,7 @@ class AgentInspectorPane implements Component {
255
255
  private readonly effectiveResolution: ModelResolution | undefined,
256
256
  ) {}
257
257
 
258
- render(width: number): string[] {
258
+ render(width: number): readonly string[] {
259
259
  if (!this.agent) {
260
260
  return [theme.fg("muted", "Select an agent"), theme.fg("dim", "to inspect settings")];
261
261
  }
@@ -314,7 +314,7 @@ class TwoColumnBody implements Component {
314
314
  private readonly maxHeight: number,
315
315
  ) {}
316
316
 
317
- render(width: number): string[] {
317
+ render(width: number): readonly string[] {
318
318
  const leftWidth = Math.floor(width * 0.5);
319
319
  const rightWidth = width - leftWidth - 3;
320
320
  const leftLines = this.leftPane.render(leftWidth);
@@ -507,7 +507,7 @@ export class AgentDashboard extends Container {
507
507
  return Math.max(3, this.#computeBodyHeight() - 3);
508
508
  }
509
509
 
510
- override render(width: number): string[] {
510
+ override render(width: number): readonly string[] {
511
511
  // Rebuild when terminal geometry changes so the full-screen overlay
512
512
  // re-fits on resize.
513
513
  if (this.#terminalRows() !== this.#builtRows || this.#uiWidth() !== this.#builtCols) {
@@ -516,10 +516,13 @@ export class AgentDashboard extends Container {
516
516
  const lines = super.render(width);
517
517
  // Pad to the full viewport so every state (list, edit, create) covers the
518
518
  // screen as a true full-screen view instead of letting the transcript peek
519
- // through below it.
519
+ // through below it. Copy before padding — the container's render result is
520
+ // component-owned and must not be mutated.
520
521
  const rows = this.#terminalRows();
521
- while (lines.length < rows) lines.push("");
522
- return lines;
522
+ if (lines.length >= rows) return lines;
523
+ const padded = lines.slice();
524
+ while (padded.length < rows) padded.push("");
525
+ return padded;
523
526
  }
524
527
 
525
528
  #clampSelection(): void {
@@ -36,6 +36,9 @@ export class AssistantMessageComponent extends Container {
36
36
  * transcript keeps the error in history.
37
37
  */
38
38
  #errorPinned = false;
39
+ /** Whether the last updateContent carried an in-flight streaming partial; such
40
+ * renders bypass the markdown module LRU (see Markdown.transientRenderCache). */
41
+ #lastUpdateTransient = false;
39
42
 
40
43
  constructor(
41
44
  message?: AssistantMessage,
@@ -59,7 +62,7 @@ export class AssistantMessageComponent extends Container {
59
62
  override invalidate(): void {
60
63
  super.invalidate();
61
64
  if (this.#lastMessage) {
62
- this.updateContent(this.#lastMessage);
65
+ this.updateContent(this.#lastMessage, { transient: this.#lastUpdateTransient });
63
66
  }
64
67
  }
65
68
 
@@ -75,7 +78,7 @@ export class AssistantMessageComponent extends Container {
75
78
  if (this.#errorPinned === pinned) return;
76
79
  this.#errorPinned = pinned;
77
80
  if (this.#lastMessage) {
78
- this.updateContent(this.#lastMessage);
81
+ this.updateContent(this.#lastMessage, { transient: this.#lastUpdateTransient });
79
82
  }
80
83
  }
81
84
 
@@ -123,7 +126,7 @@ export class AssistantMessageComponent extends Container {
123
126
  this.#convertToolImagesForKitty(toolCallId, validImages);
124
127
  }
125
128
  if (this.#lastMessage) {
126
- this.updateContent(this.#lastMessage);
129
+ this.updateContent(this.#lastMessage, { transient: this.#lastUpdateTransient });
127
130
  }
128
131
  }
129
132
 
@@ -146,7 +149,7 @@ export class AssistantMessageComponent extends Container {
146
149
  mimeType: "image/png",
147
150
  });
148
151
  if (this.#lastMessage) {
149
- this.updateContent(this.#lastMessage);
152
+ this.updateContent(this.#lastMessage, { transient: this.#lastUpdateTransient });
150
153
  }
151
154
  this.onImageUpdate?.();
152
155
  })
@@ -159,7 +162,7 @@ export class AssistantMessageComponent extends Container {
159
162
  setUsageInfo(usage: Usage): void {
160
163
  this.#usageInfo = usage;
161
164
  if (this.#lastMessage) {
162
- this.updateContent(this.#lastMessage);
165
+ this.updateContent(this.#lastMessage, { transient: this.#lastUpdateTransient });
163
166
  }
164
167
  }
165
168
 
@@ -211,14 +214,17 @@ export class AssistantMessageComponent extends Container {
211
214
  }
212
215
  }
213
216
 
214
- updateContent(message: AssistantMessage): void {
217
+ updateContent(message: AssistantMessage, opts?: { transient?: boolean }): void {
215
218
  this.#lastMessage = message;
219
+ this.#lastUpdateTransient = opts?.transient === true;
216
220
 
217
221
  // Clear content container
218
222
  this.#contentContainer.clear();
219
223
 
220
224
  const hasVisibleContent = message.content.some(
221
- c => (c.type === "text" && c.text.trim()) || (c.type === "thinking" && c.thinking.trim()),
225
+ c =>
226
+ (c.type === "text" && c.text.trim()) ||
227
+ (!this.hideThinkingBlock && c.type === "thinking" && c.thinking.trim()),
222
228
  );
223
229
 
224
230
  // Render content in order
@@ -228,34 +234,32 @@ export class AssistantMessageComponent extends Container {
228
234
  if (content.type === "text" && content.text.trim()) {
229
235
  // Assistant text messages with no background - trim the text
230
236
  // Set paddingY=0 to avoid extra spacing before tool executions
231
- this.#contentContainer.addChild(new Markdown(content.text.trim(), 1, 0, getMarkdownTheme()));
237
+ const markdown = new Markdown(content.text.trim(), 1, 0, getMarkdownTheme());
238
+ markdown.transientRenderCache = this.#lastUpdateTransient;
239
+ this.#contentContainer.addChild(markdown);
232
240
  } else if (content.type === "thinking" && content.thinking.trim()) {
241
+ if (this.hideThinkingBlock) {
242
+ thinkingIndex += 1;
243
+ continue;
244
+ }
233
245
  // Add spacing only when another visible assistant content block follows.
234
246
  // This avoids a superfluous blank line before separately-rendered tool execution blocks.
235
247
  const hasVisibleContentAfter = message.content
236
248
  .slice(i + 1)
237
249
  .some(c => (c.type === "text" && c.text.trim()) || (c.type === "thinking" && c.thinking.trim()));
238
250
 
239
- if (this.hideThinkingBlock) {
240
- // Show static "Thinking..." label when hidden
241
- this.#contentContainer.addChild(new Text(theme.italic(theme.fg("thinkingText", "Thinking...")), 1, 0));
242
- if (hasVisibleContentAfter) {
243
- this.#contentContainer.addChild(new Spacer(1));
244
- }
245
- } else {
246
- const thinkingText = content.thinking.trim();
247
- // Thinking traces in thinkingText color, italic
248
- this.#contentContainer.addChild(
249
- new Markdown(thinkingText, 1, 0, getMarkdownTheme(), {
250
- color: (text: string) => theme.fg("thinkingText", text),
251
- italic: true,
252
- }),
253
- );
254
- this.#appendThinkingExtensions(i, thinkingIndex, thinkingText);
255
- thinkingIndex += 1;
256
- if (hasVisibleContentAfter) {
257
- this.#contentContainer.addChild(new Spacer(1));
258
- }
251
+ const thinkingText = content.thinking.trim();
252
+ // Thinking traces in thinkingText color, italic
253
+ const thinkingMarkdown = new Markdown(thinkingText, 1, 0, getMarkdownTheme(), {
254
+ color: (text: string) => theme.fg("thinkingText", text),
255
+ italic: true,
256
+ });
257
+ thinkingMarkdown.transientRenderCache = this.#lastUpdateTransient;
258
+ this.#contentContainer.addChild(thinkingMarkdown);
259
+ this.#appendThinkingExtensions(i, thinkingIndex, thinkingText);
260
+ thinkingIndex += 1;
261
+ if (hasVisibleContentAfter) {
262
+ this.#contentContainer.addChild(new Spacer(1));
259
263
  }
260
264
  }
261
265
  }
@@ -126,7 +126,7 @@ export class BashExecutionComponent extends Container {
126
126
  this.#updateDisplay();
127
127
  }
128
128
 
129
- override render(width: number): string[] {
129
+ override render(width: number): readonly string[] {
130
130
  if (this.#displayDirty) {
131
131
  this.#displayDirty = false;
132
132
  this.#updateDisplay();
@@ -173,7 +173,7 @@ export class CopySelectorComponent implements Component {
173
173
  return out;
174
174
  }
175
175
 
176
- render(width: number): string[] {
176
+ render(width: number): readonly string[] {
177
177
  const height = process.stdout.rows || 40;
178
178
  const flat = this.#flatten();
179
179
  const cursorIdx = Math.max(
@@ -109,10 +109,16 @@ export function renderDiff(diffText: string, options: RenderDiffOptions = {}): s
109
109
  const lines = sanitizeText(diffText).split("\n");
110
110
  const result: string[] = [];
111
111
  const parsedLines = lines.map(parseDiffLine);
112
+ // Reserve 3 gutter digits: a streaming preview re-renders this diff as it
113
+ // grows, and a width derived purely from the current max line number widens
114
+ // at the 100-line crossing — re-padding every already-rendered row, which
115
+ // breaks the transcript's append-only commit detection and forces a full
116
+ // recommit of the block into native scrollback. A constant gutter through
117
+ // 999 lines keeps streamed rows byte-identical to the final result render.
112
118
  const lineNumberWidth = parsedLines.reduce((width, parsed) => {
113
119
  const lineNumber = parsed?.lineNum.trim() ?? "";
114
120
  return Math.max(width, lineNumber.length);
115
- }, 0);
121
+ }, 3);
116
122
 
117
123
  // Batch-highlight context (unedited) lines so consecutive lines tokenize
118
124
  // with full multi-line context. Highlighting is a no-op when no language
@@ -142,7 +148,12 @@ export function renderDiff(diffText: string, options: RenderDiffOptions = {}): s
142
148
 
143
149
  if (!parsed) {
144
150
  prevLineNum = "";
145
- result.push(theme.fg("toolDiffContext", replaceTabs(line, options.filePath)));
151
+ // Blank gap rows (and legacy "..." markers from older transcripts)
152
+ // mark non-contiguous diff regions; display them as a single dim
153
+ // unicode ellipsis.
154
+ const trimmed = line.trim();
155
+ const isGapRow = trimmed.length === 0 || trimmed === "..." || trimmed === "…";
156
+ result.push(theme.fg("toolDiffContext", isGapRow ? "…" : replaceTabs(line, options.filePath)));
146
157
  i++;
147
158
  continue;
148
159
  }
@@ -10,16 +10,25 @@ import { theme } from "../../modes/theme/theme";
10
10
  */
11
11
  export class DynamicBorder implements Component {
12
12
  #color: (str: string) => string;
13
+ #cachedWidth = -1;
14
+ #cachedLines: string[] | undefined;
13
15
 
14
16
  constructor(color: (str: string) => string = str => theme.fg("border", str)) {
15
17
  this.#color = color;
16
18
  }
17
19
 
18
20
  invalidate(): void {
19
- // No cached state to invalidate currently
21
+ this.#cachedWidth = -1;
22
+ this.#cachedLines = undefined;
20
23
  }
21
24
 
22
- render(width: number): string[] {
23
- return [this.#color(theme.boxSharp.horizontal.repeat(Math.max(1, width)))];
25
+ render(width: number): readonly string[] {
26
+ if (this.#cachedLines && this.#cachedWidth === width) {
27
+ return this.#cachedLines;
28
+ }
29
+ const lines = [this.#color(theme.boxSharp.horizontal.repeat(Math.max(1, width)))];
30
+ this.#cachedWidth = width;
31
+ this.#cachedLines = lines;
32
+ return lines;
24
33
  }
25
34
  }
@@ -137,7 +137,7 @@ export class ExtensionDashboard extends Container {
137
137
  return Math.max(3, this.#computeBodyHeight() - 3);
138
138
  }
139
139
 
140
- override render(width: number): string[] {
140
+ override render(width: number): readonly string[] {
141
141
  // Rebuild when terminal geometry changes so the full-screen overlay
142
142
  // re-fits on resize.
143
143
  if (this.#terminalRows() !== this.#builtRows || this.#uiWidth() !== this.#builtCols) {
@@ -145,10 +145,13 @@ export class ExtensionDashboard extends Container {
145
145
  }
146
146
  const lines = super.render(width);
147
147
  // Pad to the full viewport so the dashboard covers the screen instead of
148
- // letting the transcript peek through below it.
148
+ // letting the transcript peek through below it. Copy before padding — the
149
+ // container's render result is component-owned and must not be mutated.
149
150
  const rows = this.#terminalRows();
150
- while (lines.length < rows) lines.push("");
151
- return lines;
151
+ if (lines.length >= rows) return lines;
152
+ const padded = lines.slice();
153
+ while (padded.length < rows) padded.push("");
154
+ return padded;
152
155
  }
153
156
 
154
157
  #buildLayout(): void {
@@ -367,7 +370,7 @@ class TwoColumnBody implements Component {
367
370
  private readonly maxHeight: number,
368
371
  ) {}
369
372
 
370
- render(width: number): string[] {
373
+ render(width: number): readonly string[] {
371
374
  const leftWidth = Math.floor(width * 0.5);
372
375
  const rightWidth = Math.max(0, width - leftWidth - 3);
373
376
 
@@ -113,7 +113,7 @@ export class ExtensionList implements Component {
113
113
 
114
114
  invalidate(): void {}
115
115
 
116
- render(width: number): string[] {
116
+ render(width: number): readonly string[] {
117
117
  const lines: string[] = [];
118
118
 
119
119
  // Search bar
@@ -18,7 +18,7 @@ export class InspectorPanel implements Component {
18
18
 
19
19
  invalidate(): void {}
20
20
 
21
- render(width: number): string[] {
21
+ render(width: number): readonly string[] {
22
22
  if (!this.#extension) {
23
23
  return [theme.fg("muted", "Select an extension"), theme.fg("dim", "to view details")];
24
24
  }
@@ -1,4 +1,5 @@
1
1
  import * as fs from "node:fs";
2
+ import * as path from "node:path";
2
3
  import { stripVTControlCharacters } from "node:util";
3
4
  import { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
4
5
  import { type Component, padding, truncateToWidth, visibleWidth } from "@oh-my-pi/pi-tui";
@@ -65,7 +66,8 @@ export class FooterComponent implements Component {
65
66
  }
66
67
 
67
68
  try {
68
- this.#gitWatcher = fs.watch(head.headPath, () => {
69
+ const watchPath = head.isReftable ? path.join(head.gitDir, "reftable") : head.headPath;
70
+ this.#gitWatcher = fs.watch(watchPath, () => {
69
71
  this.#cachedBranch = undefined; // Invalidate cache
70
72
  if (this.#onBranchChange) {
71
73
  this.#onBranchChange();
@@ -110,7 +112,7 @@ export class FooterComponent implements Component {
110
112
  return this.#cachedBranch;
111
113
  }
112
114
 
113
- render(width: number): string[] {
115
+ render(width: number): readonly string[] {
114
116
  const state = this.session.state;
115
117
 
116
118
  // Calculate cumulative usage from ALL session entries (not just post-compaction messages)
@@ -98,7 +98,7 @@ class HistoryResultsList implements Component {
98
98
  // No cached state to invalidate currently
99
99
  }
100
100
 
101
- render(width: number): string[] {
101
+ render(width: number): readonly string[] {
102
102
  const lines: string[] = [];
103
103
 
104
104
  if (this.#results.length === 0) {
@@ -86,6 +86,14 @@ export class HookEditorComponent extends Container {
86
86
  this.#onSubmitCallback(this.#editor.getExpandedText());
87
87
  }
88
88
 
89
+ /** Route non-bracketed paste transports (e.g. kitty's OSC 5522 enhanced clipboard)
90
+ * into the inner editor, mirroring bracketed-paste semantics. Without this hook,
91
+ * enhanced-paste routing falls back to the main prompt editor hidden behind the
92
+ * dialog (#2127 routing contract). */
93
+ pasteText(text: string): void {
94
+ this.#editor.pasteText(text);
95
+ }
96
+
89
97
  /** Prompt-style: raw Enter submits; Editor owns newline-producing sequences. */
90
98
  #handlePromptStyleInput(keyData: string): void {
91
99
  // Prompt-style keeps Escape as an explicit cancel key and also honors app.interrupt remaps.
@@ -73,6 +73,14 @@ export class HookInputComponent extends Container {
73
73
  }
74
74
  }
75
75
 
76
+ /** Route non-bracketed paste transports (e.g. kitty's OSC 5522 enhanced clipboard)
77
+ * into the inner input, mirroring bracketed-paste semantics. Pasting counts as
78
+ * interaction, so the timeout countdown resets like any keystroke. */
79
+ pasteText(text: string): void {
80
+ this.#countdown?.reset();
81
+ this.#input.pasteText(text);
82
+ }
83
+
76
84
  dispose(): void {
77
85
  this.#countdown?.dispose();
78
86
  }
@@ -122,7 +122,7 @@ class OutlinedList extends Container {
122
122
  this.invalidate();
123
123
  }
124
124
 
125
- render(width: number): string[] {
125
+ render(width: number): readonly string[] {
126
126
  const borderColor = (text: string) => theme.fg("border", text);
127
127
  const horizontal = borderColor(theme.boxSharp.horizontal.repeat(Math.max(1, width)));
128
128
  const innerWidth = Math.max(1, width - 2);
@@ -645,7 +645,7 @@ export class HookSelectorComponent extends Container {
645
645
  }
646
646
  }
647
647
 
648
- override render(width: number): string[] {
648
+ override render(width: number): readonly string[] {
649
649
  const renderWidth = Math.max(1, width);
650
650
  if (this.#lastRenderWidth !== renderWidth) {
651
651
  this.#lastRenderWidth = renderWidth;
@@ -1,5 +1,7 @@
1
1
  import { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
2
- import { getSupportedEfforts, type Model, modelsAreEqual } from "@oh-my-pi/pi-ai";
2
+ import type { Model } from "@oh-my-pi/pi-ai";
3
+ import { getSupportedEfforts } from "@oh-my-pi/pi-catalog/model-thinking";
4
+ import { modelsAreEqual } from "@oh-my-pi/pi-catalog/models";
3
5
  import {
4
6
  Container,
5
7
  fuzzyFilter,
@@ -16,8 +18,8 @@ import {
16
18
  } from "@oh-my-pi/pi-tui";
17
19
  import { formatNumber } from "@oh-my-pi/pi-utils";
18
20
  import type { ModelRegistry } from "../../config/model-registry";
19
- import { getKnownRoleIds, getRoleInfo, MODEL_ROLE_IDS, MODEL_ROLES } from "../../config/model-registry";
20
21
  import { getModelMatchPreferences, resolveModelRoleValue } from "../../config/model-resolver";
22
+ import { getKnownRoleIds, getRoleInfo, MODEL_ROLE_IDS, MODEL_ROLES } from "../../config/model-roles";
21
23
  import type { Settings } from "../../config/settings";
22
24
  import { type ThemeColor, theme } from "../../modes/theme/theme";
23
25
  import { matchesSelectDown, matchesSelectUp } from "../../modes/utils/keybinding-matchers";
@@ -754,7 +754,7 @@ export class PlanReviewOverlay implements Component {
754
754
  return [theme.fg("dim", this.#buildHelp())];
755
755
  }
756
756
 
757
- render(width: number): string[] {
757
+ render(width: number): readonly string[] {
758
758
  const termHeight = process.stdout.rows || 40;
759
759
  const sidebarShown = this.#sidebarVisible(width);
760
760
  this.#sidebarShown = sidebarShown;
@@ -118,12 +118,12 @@ export class SessionObserverOverlayComponent extends Container {
118
118
  return pool.sort((a, b) => b.lastUpdate - a.lastUpdate)[0];
119
119
  }
120
120
 
121
- override render(width: number): string[] {
121
+ override render(width: number): readonly string[] {
122
122
  return this.#renderViewer(width);
123
123
  }
124
124
 
125
125
  #setupViewer(): void {
126
- this.children = [];
126
+ this.clear();
127
127
  this.#scrollOffset = 0;
128
128
  this.#selectedEntryIndex = 0;
129
129
  this.#expandedEntries.clear();
@@ -255,7 +255,7 @@ class SessionList implements Component {
255
255
  // No cached state to invalidate currently
256
256
  }
257
257
 
258
- render(width: number): string[] {
258
+ render(width: number): readonly string[] {
259
259
  const lines: string[] = [];
260
260
 
261
261
  // Render search input
@@ -631,8 +631,12 @@ export class SettingsSelectorComponent extends Container {
631
631
  return;
632
632
  }
633
633
 
634
- // Escape at top level cancels
634
+ // Escape clears an active settings search before closing the panel.
635
635
  if (matchesAppInterrupt(data) && !this.#currentSubmenu) {
636
+ if (this.#currentList?.hasSearchQuery()) {
637
+ this.#currentList.clearSearch();
638
+ return;
639
+ }
636
640
  this.callbacks.onCancel();
637
641
  return;
638
642
  }