@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
@@ -861,7 +861,9 @@
861
861
  html += '<div class="tool-diff">';
862
862
  for (const line of diffLines) {
863
863
  const cls = line.match(/^\+/) ? 'diff-added' : line.match(/^-/) ? 'diff-removed' : 'diff-context';
864
- html += '<div class="' + cls + '">' + escapeHtml(replaceTabs(line)) + '</div>';
864
+ // Blank gap rows mark non-contiguous regions; show a unicode ellipsis.
865
+ const display = line.trim().length === 0 ? '\u2026' : replaceTabs(line);
866
+ html += '<div class="' + cls + '">' + escapeHtml(display) + '</div>';
865
867
  }
866
868
  html += '</div>';
867
869
  } else if (result) {
@@ -15,6 +15,7 @@
15
15
  * themselves. Each frontend (interactive-mode, ACP) prepends its own builtins.
16
16
  */
17
17
  import type { SkillsSettings } from "../../config/settings";
18
+ import { BUILTIN_SLASH_COMMAND_RESERVED_NAMES } from "../../slash-commands/builtin-registry";
18
19
  import type { CustomCommandSource, LoadedCustomCommand } from "../custom-commands";
19
20
  import { getSkillSlashCommandName, type Skill } from "../skills";
20
21
  import type { SlashCommandInfo, SlashCommandLocation } from "../slash-commands";
@@ -32,7 +33,7 @@ export function getSessionSlashCommands(session: CommandsCapableSession): SlashC
32
33
 
33
34
  const runner = session.extensionRunner;
34
35
  if (runner) {
35
- for (const cmd of runner.getRegisteredCommands()) {
36
+ for (const cmd of runner.getRegisteredCommands(BUILTIN_SLASH_COMMAND_RESERVED_NAMES)) {
36
37
  out.push({
37
38
  name: cmd.name,
38
39
  description: cmd.description,
@@ -6,6 +6,7 @@ import type { CredentialDisabledEvent, ImageContent, Model, ProviderResponseMeta
6
6
  import type { KeyId } from "@oh-my-pi/pi-tui";
7
7
  import { logger } from "@oh-my-pi/pi-utils";
8
8
  import type { ModelRegistry } from "../../config/model-registry";
9
+ import type { MemoryRuntimeContext } from "../../memory-backend";
9
10
  import { type Theme, theme } from "../../modes/theme/theme";
10
11
  import type { SessionManager } from "../../session/session-manager";
11
12
  import type {
@@ -187,6 +188,7 @@ export class ExtensionRunner {
187
188
  #switchSessionHandler: SwitchSessionHandler = async () => ({ cancelled: false });
188
189
  #reloadHandler: () => Promise<void> = async () => {};
189
190
  #shutdownHandler: ShutdownHandler = () => {};
191
+ #getMemoryFn?: () => MemoryRuntimeContext | undefined;
190
192
  #commandDiagnostics: Array<{ type: string; message: string; path: string }> = [];
191
193
  #initialized = false;
192
194
  /**
@@ -204,8 +206,10 @@ export class ExtensionRunner {
204
206
  private readonly cwd: string,
205
207
  private readonly sessionManager: SessionManager,
206
208
  private readonly modelRegistry: ModelRegistry,
209
+ getMemory?: () => MemoryRuntimeContext | undefined,
207
210
  ) {
208
211
  this.#uiContext = noOpUIContext;
212
+ this.#getMemoryFn = getMemory;
209
213
  }
210
214
 
211
215
  initialize(
@@ -427,7 +431,7 @@ export class ExtensionRunner {
427
431
  return this.extensions.flatMap(ext => ext.assistantThinkingRenderers);
428
432
  }
429
433
 
430
- getRegisteredCommands(reserved?: Set<string>): RegisteredCommand[] {
434
+ getRegisteredCommands(reserved?: ReadonlySet<string>): RegisteredCommand[] {
431
435
  this.#commandDiagnostics = [];
432
436
 
433
437
  const commands = new Map<string, RegisteredCommand>();
@@ -480,6 +484,7 @@ export class ExtensionRunner {
480
484
  hasPendingMessages: () => this.#hasPendingMessagesFn(),
481
485
  shutdown: () => this.#shutdownHandler(),
482
486
  getSystemPrompt: () => this.#getSystemPromptFn(),
487
+ memory: this.#getMemoryFn?.(),
483
488
  };
484
489
  }
485
490
 
@@ -22,6 +22,7 @@ import type {
22
22
  Context,
23
23
  ImageContent,
24
24
  Model,
25
+ ModelSpec,
25
26
  ProviderResponseMetadata,
26
27
  SimpleStreamOptions,
27
28
  Static,
@@ -39,6 +40,7 @@ import type { EditToolDetails } from "../../edit";
39
40
  import type { PythonResult } from "../../eval/py/executor";
40
41
  import type { BashResult } from "../../exec/bash-executor";
41
42
  import type { ExecOptions, ExecResult } from "../../exec/exec";
43
+ import type { MemoryRuntimeContext } from "../../memory-backend";
42
44
  import type { CustomEditor } from "../../modes/components/custom-editor";
43
45
  import type { Theme } from "../../modes/theme/theme";
44
46
  import type { CustomMessage } from "../../session/messages";
@@ -318,6 +320,8 @@ export interface ExtensionContext {
318
320
  shutdown(): void;
319
321
  /** Get the current effective system prompt. */
320
322
  getSystemPrompt(): string[];
323
+ /** Structured memory runtime for status/search/save across the configured backend. */
324
+ memory?: MemoryRuntimeContext;
321
325
  }
322
326
 
323
327
  /**
@@ -1081,7 +1085,7 @@ export interface ExtensionAPI {
1081
1085
  * id: "claude-sonnet-4@20250514",
1082
1086
  * name: "Claude Sonnet 4 (Vertex)",
1083
1087
  * reasoning: true,
1084
- * thinking: { mode: "anthropic-adaptive", minLevel: "minimal", maxLevel: "high" },
1088
+ * thinking: { mode: "anthropic-adaptive", efforts: ["minimal", "low", "medium", "high"] },
1085
1089
  * input: ["text", "image"],
1086
1090
  * cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
1087
1091
  * contextWindow: 200000,
@@ -1168,7 +1172,7 @@ export interface ProviderModelConfig {
1168
1172
  /** Custom headers for this model. */
1169
1173
  headers?: Record<string, string>;
1170
1174
  /** OpenAI compatibility settings. */
1171
- compat?: Model<Api>["compat"];
1175
+ compat?: ModelSpec<Api>["compat"];
1172
1176
  }
1173
1177
 
1174
1178
  /** Extension factory function type. Supports both sync and async initialization. */
@@ -110,9 +110,26 @@ function bunfsPath(...segments: string[]): string {
110
110
  return path.join(BUNFS_PACKAGE_ROOT, ...segments);
111
111
  }
112
112
 
113
+ function resolveBundledSelfPackageRoot(): string | undefined {
114
+ if (!process.env.PI_BUNDLED) return undefined;
115
+ try {
116
+ return path.dirname(Bun.resolveSync("@oh-my-pi/pi-coding-agent/package.json", import.meta.dir));
117
+ } catch {
118
+ return undefined;
119
+ }
120
+ }
121
+
122
+ const BUNDLED_SELF_PACKAGE_ROOT = resolveBundledSelfPackageRoot();
123
+
124
+ function sourceShimPath(file: string): string {
125
+ return BUNDLED_SELF_PACKAGE_ROOT
126
+ ? path.join(BUNDLED_SELF_PACKAGE_ROOT, "src", "extensibility", file)
127
+ : path.resolve(import.meta.dir, "..", file);
128
+ }
129
+
113
130
  const TYPEBOX_SHIM_PATH = BUNFS_PACKAGE_ROOT
114
131
  ? bunfsPath("coding-agent", "src", "extensibility", "typebox.js")
115
- : path.resolve(import.meta.dir, "../typebox.ts");
132
+ : sourceShimPath("typebox.ts");
116
133
 
117
134
  // Legacy extensions historically imported `Type` (and `Static`/`TSchema`) from
118
135
  // the package root of `@(scope)/pi-ai`. pi-ai 15.1.0 removed the runtime `Type`
@@ -124,7 +141,7 @@ const TYPEBOX_SHIM_PATH = BUNFS_PACKAGE_ROOT
124
141
  // against the bundled pi-ai package.
125
142
  const LEGACY_PI_AI_SHIM_PATH = BUNFS_PACKAGE_ROOT
126
143
  ? bunfsPath("coding-agent", "src", "extensibility", "legacy-pi-ai-shim.js")
127
- : path.resolve(import.meta.dir, "../legacy-pi-ai-shim.ts");
144
+ : sourceShimPath("legacy-pi-ai-shim.ts");
128
145
 
129
146
  // The coding-agent's own `./src/index.ts` cannot be listed as an extra
130
147
  // `bun --compile` entrypoint alongside the CLI entry without breaking binary
@@ -133,7 +150,7 @@ const LEGACY_PI_AI_SHIM_PATH = BUNFS_PACKAGE_ROOT
133
150
  // avoids that collision while re-exporting the canonical package surface.
134
151
  const LEGACY_PI_CODING_AGENT_SHIM_PATH = BUNFS_PACKAGE_ROOT
135
152
  ? bunfsPath("coding-agent", "src", "extensibility", "legacy-pi-coding-agent-shim.js")
136
- : path.resolve(import.meta.dir, "../legacy-pi-coding-agent-shim.ts");
153
+ : sourceShimPath("legacy-pi-coding-agent-shim.ts");
137
154
 
138
155
  // Package-root overrides. Shim entries are always applied because they replace
139
156
  // (or augment) the canonical surface even in non-compiled installs. The bunfs
@@ -22,6 +22,7 @@
22
22
 
23
23
  import * as path from "node:path";
24
24
  import { logger } from "@oh-my-pi/pi-utils";
25
+ import * as git from "../utils/git";
25
26
  import type { HindsightApi } from "./client";
26
27
  import type { HindsightConfig } from "./config";
27
28
 
@@ -53,10 +54,24 @@ function baseBankId(config: HindsightConfig): string {
53
54
  return prefix ? `${prefix}-${base}` : base;
54
55
  }
55
56
 
56
- /** Best-effort project label from a working-directory path. */
57
+ /**
58
+ * Best-effort project label from a working-directory path.
59
+ *
60
+ * When `directory` lives inside a git repository we resolve the primary
61
+ * checkout root (or the shared common dir for bare-repo worktrees) via
62
+ * {@link git.repo.primaryRootSync} and basename that, so every linked
63
+ * worktree of one repo shares the same `project:<name>` tag.
64
+ * Outside a repo (or when resolution fails), fall back to the cwd basename.
65
+ *
66
+ * Sync only: this runs on the hot path of `computeBankScope`, which is
67
+ * exposed as a sync API to callers like `backend.ts` and must stay sync.
68
+ * `git.repo.primaryRootSync` walks `.git`/`commondir` with sync file reads —
69
+ * no subprocess — so the cost is one or two `stat`s and a small `readFile`.
70
+ */
57
71
  function projectLabel(directory: string): string {
58
72
  if (!directory) return UNKNOWN_PROJECT;
59
- return path.basename(directory) || UNKNOWN_PROJECT;
73
+ const primary = git.repo.primaryRootSync(directory);
74
+ return path.basename(primary ?? directory) || UNKNOWN_PROJECT;
60
75
  }
61
76
 
62
77
  /**
@@ -26,8 +26,10 @@
26
26
  * retain side to emit them.
27
27
  *
28
28
  * Seed tags are baked from `seeds.json` plus, for `projectTagged: true`
29
- * entries, the active scope's `retainTags` (i.e. `project:<cwd>`). Untagged
30
- * seeds (e.g. `user-preferences`) read every memory in the bank the
29
+ * entries, the active scope's `retainTags` (i.e. `project:<cwd>`). In
30
+ * `per-project-tagged`, those project seeds also get project-suffixed ids so
31
+ * each tag can own its conventions/decisions models in the shared bank.
32
+ * Untagged seeds (e.g. `user-preferences`) read every memory in the bank — the
31
33
  * reflect call applies no tag filter when `tags` is empty.
32
34
  *
33
35
  * Seed lifecycle is **create-only**: changes to `source_query`, `tags`,
@@ -72,31 +74,52 @@ export interface MentalModelSeed {
72
74
  sourceQuery: string;
73
75
  tags: string[];
74
76
  maxTokens?: number;
77
+ /** Legacy unqualified seed ids accepted as already-present when tags match. */
78
+ legacyIds?: string[];
75
79
  trigger?: MentalModelTrigger;
76
80
  }
77
81
 
78
82
  /**
79
83
  * Resolve the seed list that applies to the active bank scope. Per-project
80
84
  * seeds are skipped in `global` mode (where there is no project axis) and
81
- * `projectTagged` seeds inherit the scope's `retainTags`.
85
+ * `projectTagged` seeds inherit the scope's `retainTags`. In shared tagged
86
+ * banks, project seeds use project-suffixed ids and accept matching legacy
87
+ * bare ids as already present.
82
88
  */
83
89
  export function resolveSeedsForScope(scope: BankScope, scoping: HindsightScoping): MentalModelSeed[] {
84
90
  const out: MentalModelSeed[] = [];
85
91
  for (const seed of BUILTIN_SEEDS) {
86
92
  if (!seed.scopes.includes(scoping)) continue;
87
93
  const tags = collectSeedTags(seed, scope);
94
+ const id = resolveSeedId(seed, tags, scoping);
88
95
  out.push({
89
- id: seed.id,
96
+ id,
90
97
  name: seed.name,
91
98
  sourceQuery: seed.source_query,
92
99
  tags,
93
100
  maxTokens: seed.max_tokens,
94
101
  trigger: seed.trigger,
102
+ legacyIds: id === seed.id ? undefined : [seed.id],
95
103
  });
96
104
  }
97
105
  return out;
98
106
  }
99
107
 
108
+ const PROJECT_TAG_PREFIX = "project:";
109
+
110
+ function resolveSeedId(seed: RawSeed, tags: string[], scoping: HindsightScoping): string {
111
+ if (scoping !== "per-project-tagged" || !seed.projectTagged || tags.length === 0) return seed.id;
112
+ return `${seed.id}-${seedIdSuffixFromProjectTag(tags[0])}`;
113
+ }
114
+
115
+ function seedIdSuffixFromProjectTag(tag: string): string {
116
+ const raw = tag.startsWith(PROJECT_TAG_PREFIX) ? tag.slice(PROJECT_TAG_PREFIX.length) : tag;
117
+ const sanitized = raw
118
+ .trim()
119
+ .replace(/[^A-Za-z0-9._-]+/g, "-")
120
+ .replace(/^-+|-+$/g, "");
121
+ return sanitized || "project";
122
+ }
100
123
  function collectSeedTags(seed: RawSeed, scope: BankScope): string[] {
101
124
  const collected: string[] = [];
102
125
  if (seed.projectTagged && scope.retainTags) collected.push(...scope.retainTags);
@@ -124,17 +147,17 @@ export async function ensureMentalModels(
124
147
  ): Promise<void> {
125
148
  if (seeds.length === 0) return;
126
149
 
127
- let existing: Set<string>;
150
+ let existing: MentalModelSummary[];
128
151
  try {
129
152
  const list = await client.listMentalModels(bankId, { detail: "metadata" });
130
- existing = new Set((list.items ?? []).map(m => m.id));
153
+ existing = list.items ?? [];
131
154
  } catch (err) {
132
155
  logger.debug("Hindsight: ensureMentalModels list failed", { bankId, error: String(err) });
133
156
  return;
134
157
  }
135
158
 
136
159
  for (const seed of seeds) {
137
- if (existing.has(seed.id)) continue;
160
+ if (seedAlreadyExists(seed, existing)) continue;
138
161
  try {
139
162
  await client.createMentalModel(bankId, seed.name, seed.sourceQuery, {
140
163
  id: seed.id,
@@ -151,6 +174,19 @@ export async function ensureMentalModels(
151
174
  }
152
175
  }
153
176
 
177
+ /** Return whether a seed is already represented by current bank metadata. */
178
+ export function seedAlreadyExists(seed: MentalModelSeed, models: readonly MentalModelSummary[]): boolean {
179
+ for (const model of models) {
180
+ if (model.id === seed.id) return true;
181
+ if (seed.legacyIds?.includes(model.id) && sameStringSet(model.tags ?? [], seed.tags)) return true;
182
+ }
183
+ return false;
184
+ }
185
+
186
+ function sameStringSet(left: readonly string[], right: readonly string[]): boolean {
187
+ return left.length === right.length && left.every(item => right.includes(item));
188
+ }
189
+
154
190
  /**
155
191
  * Default character budget for the rendered `<mental_models>` block. Mental
156
192
  * models are injected on every prompt rebuild; an unbounded block can crowd
@@ -170,15 +206,17 @@ export const MENTAL_MODEL_RENDER_BUDGET_CHARS_DEFAULT = 16_000;
170
206
  * reflect for a freshly-seeded model hasn't completed yet).
171
207
  *
172
208
  * The rendered block is bounded by `budgetChars` (default
173
- * MENTAL_MODEL_RENDER_BUDGET_CHARS_DEFAULT). Per-model content is truncated
174
- * before assembly; if assembly still exceeds the budget, trailing models are
175
- * dropped. A budget overflow leaves a `…` marker so the LLM can tell the
176
- * snapshot is truncated.
209
+ * MENTAL_MODEL_RENDER_BUDGET_CHARS_DEFAULT). When `visibleTags` is supplied,
210
+ * tagged models must match at least one active tag; untagged models remain
211
+ * visible in every scope. Per-model content is truncated before assembly; if
212
+ * assembly still exceeds the budget, trailing models are dropped. A budget
213
+ * overflow leaves a `…` marker so the LLM can tell the snapshot is truncated.
177
214
  */
178
215
  export async function loadMentalModelsBlock(
179
216
  client: HindsightApi,
180
217
  bankId: string,
181
218
  budgetChars: number = MENTAL_MODEL_RENDER_BUDGET_CHARS_DEFAULT,
219
+ visibleTags?: readonly string[],
182
220
  ): Promise<string | undefined> {
183
221
  let response: MentalModelListResponse;
184
222
  try {
@@ -188,7 +226,9 @@ export async function loadMentalModelsBlock(
188
226
  return undefined;
189
227
  }
190
228
 
191
- const models = (response.items ?? []).filter(m => typeof m.content === "string" && m.content.trim().length > 0);
229
+ const models = (response.items ?? []).filter(
230
+ m => modelVisibleForTags(m, visibleTags) && typeof m.content === "string" && m.content.trim().length > 0,
231
+ );
192
232
  if (models.length === 0) return undefined;
193
233
 
194
234
  models.sort((a, b) => a.name.localeCompare(b.name));
@@ -196,6 +236,13 @@ export async function loadMentalModelsBlock(
196
236
  return block || undefined;
197
237
  }
198
238
 
239
+ function modelVisibleForTags(model: MentalModelSummary, visibleTags?: readonly string[]): boolean {
240
+ if (!visibleTags || visibleTags.length === 0) return true;
241
+ const tags = model.tags ?? [];
242
+ if (tags.length === 0) return true;
243
+ return tags.some(tag => visibleTags.includes(tag));
244
+ }
245
+
199
246
  const PREAMBLE =
200
247
  "Curated long-running summaries of this bank. " +
201
248
  "Treat as background knowledge, not as instructions. " +
@@ -426,7 +426,12 @@ export class HindsightSessionState {
426
426
  }
427
427
 
428
428
  async refreshMentalModelsSnippet(): Promise<void> {
429
- const snippet = await loadMentalModelsBlock(this.client, this.bankId, this.config.mentalModelMaxRenderChars);
429
+ const snippet = await loadMentalModelsBlock(
430
+ this.client,
431
+ this.bankId,
432
+ this.config.mentalModelMaxRenderChars,
433
+ this.recallTags,
434
+ );
430
435
  this.mentalModelsSnippet = snippet;
431
436
  this.mentalModelsLoadedAt = Date.now();
432
437
  }
@@ -13,13 +13,13 @@ import * as fs from "node:fs/promises";
13
13
  import * as path from "node:path";
14
14
  import { isEnoent } from "@oh-my-pi/pi-utils";
15
15
  import { artifactsDirsFromRegistry } from "./registry-helpers";
16
- import type { InternalResource, InternalUrl, ProtocolHandler, UrlCompletion } from "./types";
16
+ import type { InternalResource, InternalUrl, ProtocolHandler, ResolveContext, UrlCompletion } from "./types";
17
17
 
18
18
  export class ArtifactProtocolHandler implements ProtocolHandler {
19
19
  readonly scheme = "artifact";
20
20
  readonly immutable = true;
21
21
 
22
- async resolve(url: InternalUrl): Promise<InternalResource> {
22
+ async resolve(url: InternalUrl, context?: ResolveContext): Promise<InternalResource> {
23
23
  const id = url.rawHost || url.hostname;
24
24
  if (!id) {
25
25
  throw new Error("artifact:// URL requires a numeric ID: artifact://0");
@@ -28,7 +28,16 @@ export class ArtifactProtocolHandler implements ProtocolHandler {
28
28
  throw new Error(`artifact:// ID must be numeric, got: ${id}`);
29
29
  }
30
30
 
31
+ // Artifact ids are per-session counters; in multi-session hosts the same
32
+ // id exists in several dirs. Pin resolution to the calling session's
33
+ // artifacts dir first so `artifact://3` means *this* session's #3.
31
34
  const dirs = artifactsDirsFromRegistry();
35
+ const pinnedDir = context?.localProtocolOptions?.getArtifactsDir?.() ?? null;
36
+ if (pinnedDir) {
37
+ const pinnedIndex = dirs.indexOf(pinnedDir);
38
+ if (pinnedIndex >= 0) dirs.splice(pinnedIndex, 1);
39
+ dirs.unshift(pinnedDir);
40
+ }
32
41
 
33
42
  if (dirs.length === 0) {
34
43
  throw new Error("No session - artifacts unavailable");