@prometheus-ai/agent 0.5.4 → 0.5.8

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 (1145) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/cli.js +25110 -0
  3. package/dist/types/async/index.d.ts +0 -1
  4. package/dist/types/async/job-manager.d.ts +33 -0
  5. package/dist/types/autolearn/controller.d.ts +25 -0
  6. package/dist/types/autolearn/managed-skills.d.ts +45 -0
  7. package/dist/types/autoresearch/state.d.ts +1 -1
  8. package/dist/types/autoresearch/tools/init-experiment.d.ts +1 -1
  9. package/dist/types/autoresearch/tools/log-experiment.d.ts +1 -1
  10. package/dist/types/autoresearch/tools/run-experiment.d.ts +1 -1
  11. package/dist/types/autoresearch/tools/update-notes.d.ts +1 -1
  12. package/dist/types/autoresearch/types.d.ts +1 -1
  13. package/dist/types/capability/context-file.d.ts +0 -13
  14. package/dist/types/capability/mcp.d.ts +1 -0
  15. package/dist/types/capability/rule-buckets.d.ts +1 -1
  16. package/dist/types/capability/rule.d.ts +6 -1
  17. package/dist/types/capability/types.d.ts +0 -4
  18. package/dist/types/cli/args.d.ts +23 -3
  19. package/dist/types/cli/bench-cli.d.ts +78 -0
  20. package/dist/types/cli/claude-trace-cli.d.ts +7 -0
  21. package/dist/types/cli/dry-balance-cli.d.ts +16 -2
  22. package/dist/types/cli/gallery-cli.d.ts +43 -0
  23. package/dist/types/cli/gallery-fixtures/agentic.d.ts +2 -0
  24. package/dist/types/cli/gallery-fixtures/codeintel.d.ts +3 -0
  25. package/dist/types/cli/gallery-fixtures/edit.d.ts +3 -0
  26. package/dist/types/cli/gallery-fixtures/fs.d.ts +2 -0
  27. package/dist/types/cli/gallery-fixtures/index.d.ts +4 -0
  28. package/dist/types/cli/gallery-fixtures/interaction.d.ts +3 -0
  29. package/dist/types/cli/gallery-fixtures/memory.d.ts +2 -0
  30. package/dist/types/cli/gallery-fixtures/misc.d.ts +3 -0
  31. package/dist/types/cli/gallery-fixtures/search.d.ts +3 -0
  32. package/dist/types/cli/gallery-fixtures/shell.d.ts +3 -0
  33. package/dist/types/cli/gallery-fixtures/types.d.ts +55 -0
  34. package/dist/types/cli/gallery-fixtures/web.d.ts +2 -0
  35. package/dist/types/cli/gallery-screenshot.d.ts +35 -0
  36. package/dist/types/cli/grievances-cli.d.ts +1 -1
  37. package/dist/types/cli/list-models.d.ts +6 -14
  38. package/dist/types/cli/models-cli.d.ts +49 -0
  39. package/dist/types/cli/session-picker.d.ts +1 -1
  40. package/dist/types/cli/setup-cli.d.ts +1 -1
  41. package/dist/types/cli/setup-model-picker.d.ts +14 -0
  42. package/dist/types/cli/startup-cwd.d.ts +2 -0
  43. package/dist/types/cli/update-cli.d.ts +13 -40
  44. package/dist/types/cli/usage-cli.d.ts +81 -0
  45. package/dist/types/cli-commands.d.ts +12 -0
  46. package/dist/types/collab/crypto.d.ts +7 -0
  47. package/dist/types/collab/guest.d.ts +37 -0
  48. package/dist/types/collab/host.d.ts +29 -0
  49. package/dist/types/collab/protocol.d.ts +119 -0
  50. package/dist/types/collab/relay-client.d.ts +22 -0
  51. package/dist/types/commands/bench.d.ts +29 -0
  52. package/dist/types/commands/gallery.d.ts +47 -0
  53. package/dist/types/commands/install.d.ts +1 -1
  54. package/dist/types/commands/join.d.ts +12 -0
  55. package/dist/types/commands/launch.d.ts +8 -4
  56. package/dist/types/commands/models.d.ts +33 -0
  57. package/dist/types/commands/read.d.ts +1 -1
  58. package/dist/types/commands/say.d.ts +24 -0
  59. package/dist/types/commands/token.d.ts +25 -0
  60. package/dist/types/commands/usage.d.ts +34 -0
  61. package/dist/types/commit/agentic/tools/analyze-file.d.ts +1 -1
  62. package/dist/types/commit/agentic/tools/git-file-diff.d.ts +1 -1
  63. package/dist/types/commit/agentic/tools/git-hunk.d.ts +1 -1
  64. package/dist/types/commit/agentic/tools/git-overview.d.ts +1 -1
  65. package/dist/types/commit/agentic/tools/propose-changelog.d.ts +1 -1
  66. package/dist/types/commit/agentic/tools/propose-commit.d.ts +1 -1
  67. package/dist/types/commit/agentic/tools/recent-commits.d.ts +1 -1
  68. package/dist/types/commit/agentic/tools/schemas.d.ts +1 -1
  69. package/dist/types/commit/agentic/tools/split-commit.d.ts +1 -1
  70. package/dist/types/commit/analysis/conventional.d.ts +2 -2
  71. package/dist/types/commit/analysis/summary.d.ts +2 -2
  72. package/dist/types/commit/changelog/generate.d.ts +3 -3
  73. package/dist/types/commit/changelog/index.d.ts +2 -2
  74. package/dist/types/commit/map-reduce/index.d.ts +3 -3
  75. package/dist/types/commit/map-reduce/map-phase.d.ts +2 -2
  76. package/dist/types/commit/map-reduce/reduce-phase.d.ts +2 -2
  77. package/dist/types/commit/model-selection.d.ts +10 -4
  78. package/dist/types/commit/shared-llm.d.ts +1 -1
  79. package/dist/types/config/api-key-resolver.d.ts +43 -0
  80. package/dist/types/config/append-only-context-mode.d.ts +2 -1
  81. package/dist/types/config/keybindings.d.ts +12 -7
  82. package/dist/types/config/model-discovery.d.ts +57 -0
  83. package/dist/types/config/model-equivalence.d.ts +1 -1
  84. package/dist/types/config/model-registry.d.ts +86 -222
  85. package/dist/types/config/model-resolver.d.ts +43 -12
  86. package/dist/types/config/model-roles.d.ts +29 -0
  87. package/dist/types/config/models-config-schema.d.ts +536 -43
  88. package/dist/types/config/models-config.d.ts +391 -0
  89. package/dist/types/config/settings-schema.d.ts +1202 -324
  90. package/dist/types/config/settings.d.ts +15 -3
  91. package/dist/types/dap/config.d.ts +14 -1
  92. package/dist/types/dap/types.d.ts +10 -0
  93. package/dist/types/debug/log-viewer.d.ts +1 -1
  94. package/dist/types/debug/raw-sse.d.ts +1 -1
  95. package/dist/types/debug/report-bundle.d.ts +3 -0
  96. package/dist/types/debug/terminal-info.d.ts +0 -1
  97. package/dist/types/discovery/at-imports.d.ts +15 -0
  98. package/dist/types/discovery/prometheus-extension-roots.d.ts +7 -7
  99. package/dist/types/edit/diff.d.ts +3 -2
  100. package/dist/types/edit/file-snapshot-store.d.ts +18 -0
  101. package/dist/types/edit/hashline/noop-loop-guard.d.ts +72 -0
  102. package/dist/types/edit/hashline/params.d.ts +1 -1
  103. package/dist/types/edit/index.d.ts +0 -1
  104. package/dist/types/edit/modes/apply-patch.d.ts +1 -1
  105. package/dist/types/edit/modes/patch.d.ts +1 -1
  106. package/dist/types/edit/modes/replace.d.ts +1 -1
  107. package/dist/types/edit/renderer.d.ts +1 -0
  108. package/dist/types/eval/__tests__/completion-bridge.test.d.ts +1 -0
  109. package/dist/types/eval/__tests__/helpers-local-roots.test.d.ts +1 -0
  110. package/dist/types/eval/__tests__/js-context-manager.test.d.ts +1 -0
  111. package/dist/types/eval/backend.d.ts +7 -2
  112. package/dist/types/eval/bridge-timeout.d.ts +1 -1
  113. package/dist/types/eval/completion-bridge.d.ts +25 -0
  114. package/dist/types/eval/idle-timeout.d.ts +1 -5
  115. package/dist/types/eval/js/context-manager.d.ts +1 -0
  116. package/dist/types/eval/js/executor.d.ts +2 -0
  117. package/dist/types/eval/js/index.d.ts +1 -1
  118. package/dist/types/eval/js/shared/helpers.d.ts +7 -1
  119. package/dist/types/eval/js/shared/rewrite-imports.d.ts +6 -6
  120. package/dist/types/eval/js/shared/runtime.d.ts +6 -1
  121. package/dist/types/eval/js/worker-protocol.d.ts +6 -0
  122. package/dist/types/eval/py/__tests__/prelude.test.d.ts +1 -0
  123. package/dist/types/eval/py/executor.d.ts +12 -0
  124. package/dist/types/eval/py/index.d.ts +1 -1
  125. package/dist/types/eval/py/kernel.d.ts +6 -1
  126. package/dist/types/eval/py/runtime.d.ts +9 -0
  127. package/dist/types/exa/index.d.ts +1 -19
  128. package/dist/types/exa/mcp-client.d.ts +10 -3
  129. package/dist/types/exa/types.d.ts +0 -83
  130. package/dist/types/exec/bash-executor.d.ts +7 -0
  131. package/dist/types/export/custom-share.d.ts +1 -2
  132. package/dist/types/export/html/index.d.ts +39 -0
  133. package/dist/types/export/html/template-js.d.ts +2 -0
  134. package/dist/types/export/share.d.ts +61 -0
  135. package/dist/types/export/ttsr.d.ts +14 -0
  136. package/dist/types/extensibility/custom-commands/types.d.ts +9 -4
  137. package/dist/types/extensibility/custom-tools/loader.d.ts +30 -4
  138. package/dist/types/extensibility/custom-tools/types.d.ts +16 -8
  139. package/dist/types/extensibility/extensions/index.d.ts +1 -1
  140. package/dist/types/extensibility/extensions/loader.d.ts +20 -1
  141. package/dist/types/extensibility/extensions/model-api.d.ts +17 -0
  142. package/dist/types/extensibility/extensions/runner.d.ts +5 -2
  143. package/dist/types/extensibility/extensions/types.d.ts +72 -11
  144. package/dist/types/extensibility/hooks/index.d.ts +2 -1
  145. package/dist/types/extensibility/hooks/loader.d.ts +1 -1
  146. package/dist/types/extensibility/hooks/types.d.ts +11 -5
  147. package/dist/types/extensibility/{legacy-pi-ai-shim.d.ts → legacy-package-ai-shim.d.ts} +2 -2
  148. package/dist/types/extensibility/plugins/{legacy-pi-compat.d.ts → legacy-package-compat.d.ts} +20 -3
  149. package/dist/types/extensibility/plugins/loader.d.ts +11 -0
  150. package/dist/types/extensibility/plugins/marketplace-auto-update.d.ts +8 -0
  151. package/dist/types/extensibility/plugins/types.d.ts +2 -2
  152. package/dist/types/extensibility/shared-events.d.ts +3 -3
  153. package/dist/types/extensibility/skills.d.ts +10 -0
  154. package/dist/types/extensibility/slash-commands.d.ts +1 -11
  155. package/dist/types/goals/guided-setup.d.ts +18 -0
  156. package/dist/types/goals/state.d.ts +1 -1
  157. package/dist/types/goals/tools/goal-tool.d.ts +1 -1
  158. package/dist/types/hindsight/mental-models.d.ts +17 -8
  159. package/dist/types/hindsight/transcript.d.ts +1 -1
  160. package/dist/types/index.d.ts +5 -0
  161. package/dist/types/internal-urls/artifact-protocol.d.ts +2 -2
  162. package/dist/types/internal-urls/history-protocol.d.ts +14 -0
  163. package/dist/types/internal-urls/index.d.ts +1 -0
  164. package/dist/types/internal-urls/local-protocol.d.ts +14 -2
  165. package/dist/types/internal-urls/types.d.ts +1 -1
  166. package/dist/types/irc/bus.d.ts +79 -0
  167. package/dist/types/lib/xai-http.d.ts +1 -1
  168. package/dist/types/lsp/client.d.ts +10 -0
  169. package/dist/types/lsp/config.d.ts +2 -2
  170. package/dist/types/lsp/edits.d.ts +9 -0
  171. package/dist/types/lsp/format-options.d.ts +32 -0
  172. package/dist/types/lsp/index.d.ts +2 -7
  173. package/dist/types/lsp/types.d.ts +13 -1
  174. package/dist/types/lsp/utils.d.ts +6 -2
  175. package/dist/types/main.d.ts +23 -8
  176. package/dist/types/mcp/json-rpc.d.ts +5 -0
  177. package/dist/types/mcp/manager.d.ts +8 -0
  178. package/dist/types/mcp/oauth-discovery.d.ts +6 -1
  179. package/dist/types/mcp/oauth-flow.d.ts +13 -3
  180. package/dist/types/mcp/startup-events.d.ts +11 -0
  181. package/dist/types/mcp/tool-bridge.d.ts +2 -0
  182. package/dist/types/mcp/transports/stdio.d.ts +13 -0
  183. package/dist/types/mcp/types.d.ts +2 -0
  184. package/dist/types/memories/index.d.ts +7 -15
  185. package/dist/types/memories/storage.d.ts +0 -10
  186. package/dist/types/memory-backend/index.d.ts +3 -1
  187. package/dist/types/memory-backend/local-backend.d.ts +4 -3
  188. package/dist/types/memory-backend/resolve.d.ts +2 -2
  189. package/dist/types/memory-backend/runtime.d.ts +4 -0
  190. package/dist/types/memory-backend/types.d.ts +67 -2
  191. package/dist/types/mnemopi/config.d.ts +31 -1
  192. package/dist/types/mnemopi/state.d.ts +40 -2
  193. package/dist/types/modes/acp/acp-agent.d.ts +1 -2
  194. package/dist/types/modes/components/agent-dashboard.d.ts +17 -1
  195. package/dist/types/modes/components/agent-hub.d.ts +82 -0
  196. package/dist/types/modes/components/assistant-message.d.ts +5 -12
  197. package/dist/types/modes/components/bash-execution.d.ts +1 -1
  198. package/dist/types/modes/components/chat-block.d.ts +64 -0
  199. package/dist/types/modes/components/collab-prompt-message.d.ts +10 -0
  200. package/dist/types/modes/components/compaction-summary-message.d.ts +25 -5
  201. package/dist/types/modes/components/copy-selector.d.ts +1 -1
  202. package/dist/types/modes/components/custom-editor.d.ts +49 -2
  203. package/dist/types/modes/components/custom-editor.test.d.ts +1 -0
  204. package/dist/types/modes/components/dynamic-border.d.ts +1 -1
  205. package/dist/types/modes/components/extensions/extension-dashboard.d.ts +1 -1
  206. package/dist/types/modes/components/extensions/extension-list.d.ts +1 -1
  207. package/dist/types/modes/components/extensions/inspector-panel.d.ts +1 -1
  208. package/dist/types/modes/components/footer.d.ts +1 -1
  209. package/dist/types/modes/components/hook-editor.d.ts +5 -0
  210. package/dist/types/modes/components/hook-input.d.ts +4 -0
  211. package/dist/types/modes/components/hook-selector.d.ts +5 -7
  212. package/dist/types/modes/components/index.d.ts +1 -0
  213. package/dist/types/modes/components/late-diagnostics-message.d.ts +20 -0
  214. package/dist/types/modes/components/logout-account-selector.d.ts +8 -0
  215. package/dist/types/modes/components/mcp-add-wizard.d.ts +2 -1
  216. package/dist/types/modes/components/model-selector.d.ts +1 -1
  217. package/dist/types/modes/components/oauth-selector.d.ts +10 -1
  218. package/dist/types/modes/components/overlay-box.d.ts +17 -0
  219. package/dist/types/modes/components/plan-review-overlay.d.ts +61 -0
  220. package/dist/types/modes/components/plan-toc.d.ts +41 -0
  221. package/dist/types/modes/components/read-tool-group.d.ts +8 -0
  222. package/dist/types/modes/components/reset-usage-selector.d.ts +12 -0
  223. package/dist/types/modes/components/segment-track.d.ts +11 -6
  224. package/dist/types/modes/components/session-selector.d.ts +18 -9
  225. package/dist/types/modes/components/settings-defs.d.ts +9 -2
  226. package/dist/types/modes/components/settings-selector.d.ts +17 -4
  227. package/dist/types/modes/components/snapcompact-shape-preview.d.ts +31 -0
  228. package/dist/types/modes/components/status-line/component.d.ts +61 -0
  229. package/dist/types/modes/components/status-line/index.d.ts +1 -0
  230. package/dist/types/modes/components/status-line/types.d.ts +47 -3
  231. package/dist/types/modes/components/tiny-title-download-progress.d.ts +1 -1
  232. package/dist/types/modes/components/tool-execution.d.ts +49 -2
  233. package/dist/types/modes/components/transcript-container.d.ts +76 -26
  234. package/dist/types/modes/components/tree-selector.d.ts +2 -2
  235. package/dist/types/modes/components/ttsr-notification.d.ts +5 -1
  236. package/dist/types/modes/components/usage-row.d.ts +3 -0
  237. package/dist/types/modes/components/user-message-selector.d.ts +1 -1
  238. package/dist/types/modes/components/user-message.d.ts +2 -1
  239. package/dist/types/modes/components/visual-truncate.d.ts +1 -1
  240. package/dist/types/modes/components/welcome.d.ts +12 -2
  241. package/dist/types/modes/controllers/command-controller.d.ts +3 -2
  242. package/dist/types/modes/controllers/event-controller.d.ts +7 -1
  243. package/dist/types/modes/controllers/extension-ui-controller.d.ts +0 -1
  244. package/dist/types/modes/controllers/input-controller.d.ts +25 -3
  245. package/dist/types/modes/controllers/mcp-command-controller.d.ts +8 -0
  246. package/dist/types/modes/controllers/selector-controller.d.ts +5 -2
  247. package/dist/types/modes/controllers/session-focus-controller.d.ts +31 -0
  248. package/dist/types/modes/controllers/streaming-reveal.d.ts +22 -0
  249. package/dist/types/modes/controllers/tan-command-controller.d.ts +6 -0
  250. package/dist/types/modes/controllers/tool-args-reveal.d.ts +43 -0
  251. package/dist/types/modes/gradient-highlight.d.ts +9 -4
  252. package/dist/types/modes/image-references.d.ts +14 -3
  253. package/dist/types/modes/index.d.ts +8 -7
  254. package/dist/types/modes/interactive-mode.d.ts +92 -16
  255. package/dist/types/modes/magic-keywords.d.ts +14 -2
  256. package/dist/types/modes/markdown-prose.d.ts +1 -1
  257. package/dist/types/modes/oauth-manual-input.d.ts +7 -0
  258. package/dist/types/modes/rpc/rpc-client.d.ts +48 -2
  259. package/dist/types/modes/rpc/rpc-mode.d.ts +67 -2
  260. package/dist/types/modes/rpc/rpc-subagents.d.ts +24 -0
  261. package/dist/types/modes/rpc/rpc-types.d.ts +113 -1
  262. package/dist/types/modes/runtime-init.d.ts +4 -0
  263. package/dist/types/modes/session-observer-registry.d.ts +9 -0
  264. package/dist/types/modes/setup-version.d.ts +11 -0
  265. package/dist/types/modes/setup-wizard/index.d.ts +7 -2
  266. package/dist/types/modes/setup-wizard/lazy.d.ts +2 -0
  267. package/dist/types/modes/setup-wizard/scenes/sign-in.d.ts +4 -1
  268. package/dist/types/modes/setup-wizard/scenes/types.d.ts +11 -2
  269. package/dist/types/modes/setup-wizard/scenes/web-search.d.ts +6 -2
  270. package/dist/types/modes/setup-wizard/wizard-overlay.d.ts +1 -1
  271. package/dist/types/modes/theme/theme.d.ts +42 -7
  272. package/dist/types/modes/types.d.ts +62 -13
  273. package/dist/types/modes/utils/context-usage.d.ts +6 -1
  274. package/dist/types/modes/utils/copy-targets.d.ts +21 -1
  275. package/dist/types/modes/utils/ui-helpers.d.ts +4 -4
  276. package/dist/types/modes/workflow.d.ts +3 -3
  277. package/dist/types/plan-mode/approved-plan.d.ts +27 -8
  278. package/dist/types/plan-mode/plan-protection.d.ts +4 -4
  279. package/dist/types/registry/agent-lifecycle.d.ts +51 -0
  280. package/dist/types/registry/agent-registry.d.ts +33 -5
  281. package/dist/types/sdk.d.ts +46 -4
  282. package/dist/types/secrets/index.d.ts +1 -1
  283. package/dist/types/secrets/obfuscator.d.ts +9 -3
  284. package/dist/types/session/agent-session.d.ts +136 -66
  285. package/dist/types/session/agent-storage.d.ts +2 -1
  286. package/dist/types/session/auth-broker-config.d.ts +4 -0
  287. package/dist/types/session/auth-storage.d.ts +1 -1
  288. package/dist/types/session/codex-auto-reset.d.ts +111 -0
  289. package/dist/types/session/indexed-session-storage.d.ts +3 -3
  290. package/dist/types/session/messages.d.ts +26 -15
  291. package/dist/types/session/session-context.d.ts +39 -0
  292. package/dist/types/session/session-entries.d.ts +159 -0
  293. package/dist/types/session/session-history-format.d.ts +12 -0
  294. package/dist/types/session/session-listing.d.ts +69 -0
  295. package/dist/types/session/session-loader.d.ts +16 -0
  296. package/dist/types/session/session-manager.d.ts +107 -440
  297. package/dist/types/session/session-migrations.d.ts +12 -0
  298. package/dist/types/session/session-paths.d.ts +25 -0
  299. package/dist/types/session/session-persistence.d.ts +8 -0
  300. package/dist/types/session/session-storage.d.ts +11 -7
  301. package/dist/types/session/snapcompact-inline.d.ts +145 -0
  302. package/dist/types/session/snapcompact-savings-journal.d.ts +46 -0
  303. package/dist/types/session/streaming-output.d.ts +46 -0
  304. package/dist/types/session/tool-choice-queue.d.ts +6 -6
  305. package/dist/types/session/yield-queue.d.ts +10 -1
  306. package/dist/types/slash-commands/acp-builtins.d.ts +16 -0
  307. package/dist/types/slash-commands/available-commands.d.ts +34 -0
  308. package/dist/types/slash-commands/builtin-registry.d.ts +10 -0
  309. package/dist/types/slash-commands/helpers/active-oauth-account.d.ts +14 -0
  310. package/dist/types/slash-commands/helpers/logout.d.ts +15 -0
  311. package/dist/types/slash-commands/helpers/reset-usage.d.ts +27 -0
  312. package/dist/types/slash-commands/helpers/stats-dashboard.d.ts +13 -0
  313. package/dist/types/slash-commands/types.d.ts +5 -9
  314. package/dist/types/ssh/connection-manager.d.ts +8 -0
  315. package/dist/types/stt/asr-client.d.ts +90 -0
  316. package/dist/types/stt/asr-protocol.d.ts +97 -0
  317. package/dist/types/stt/asr-worker.d.ts +2 -0
  318. package/dist/types/stt/downloader.d.ts +38 -0
  319. package/dist/types/stt/endpointer.d.ts +59 -0
  320. package/dist/types/stt/index.d.ts +5 -1
  321. package/dist/types/stt/models.d.ts +120 -0
  322. package/dist/types/stt/recorder.d.ts +17 -0
  323. package/dist/types/stt/stt-controller.d.ts +6 -0
  324. package/dist/types/stt/transcriber.d.ts +5 -7
  325. package/dist/types/stt/wav.d.ts +29 -0
  326. package/dist/types/system-prompt.d.ts +9 -1
  327. package/dist/types/task/commands.d.ts +1 -1
  328. package/dist/types/task/discovery.d.ts +1 -2
  329. package/dist/types/task/executor.d.ts +61 -2
  330. package/dist/types/task/index.d.ts +37 -6
  331. package/dist/types/task/output-manager.d.ts +0 -7
  332. package/dist/types/task/parallel.d.ts +2 -2
  333. package/dist/types/task/prometheus-command.d.ts +2 -2
  334. package/dist/types/task/render.d.ts +20 -7
  335. package/dist/types/task/repair-args.d.ts +8 -7
  336. package/dist/types/task/types.d.ts +109 -52
  337. package/dist/types/task/worktree.d.ts +2 -0
  338. package/dist/types/telemetry-export.d.ts +2 -2
  339. package/dist/types/thinking.d.ts +4 -0
  340. package/dist/types/tiny/models.d.ts +1 -1
  341. package/dist/types/tiny/title-client.d.ts +12 -1
  342. package/dist/types/tiny/title-protocol.d.ts +1 -0
  343. package/dist/types/tools/archive-reader.d.ts +5 -0
  344. package/dist/types/tools/ask.d.ts +6 -1
  345. package/dist/types/tools/ast-edit.d.ts +4 -1
  346. package/dist/types/tools/ast-grep.d.ts +4 -1
  347. package/dist/types/tools/bash.d.ts +5 -2
  348. package/dist/types/tools/browser/attach.d.ts +4 -4
  349. package/dist/types/tools/browser/cmux/cmux-tab.d.ts +202 -0
  350. package/dist/types/tools/browser/cmux/rpc.d.ts +70 -0
  351. package/dist/types/tools/browser/cmux/socket-client.d.ts +19 -0
  352. package/dist/types/tools/browser/registry.d.ts +17 -3
  353. package/dist/types/tools/browser/render.d.ts +2 -0
  354. package/dist/types/tools/browser/tab-protocol.d.ts +2 -0
  355. package/dist/types/tools/browser/tab-supervisor.d.ts +16 -4
  356. package/dist/types/tools/browser/tab-worker.d.ts +18 -1
  357. package/dist/types/tools/browser.d.ts +3 -1
  358. package/dist/types/tools/checkpoint.d.ts +1 -1
  359. package/dist/types/tools/conflict-detect.d.ts +16 -0
  360. package/dist/types/tools/debug.d.ts +1 -1
  361. package/dist/types/tools/eval-render.d.ts +1 -8
  362. package/dist/types/tools/eval.d.ts +9 -1
  363. package/dist/types/tools/fetch.d.ts +17 -8
  364. package/dist/types/tools/find.d.ts +1 -8
  365. package/dist/types/tools/gh-cache-invalidation.d.ts +6 -0
  366. package/dist/types/tools/gh.d.ts +4 -1
  367. package/dist/types/tools/github-cache.d.ts +19 -0
  368. package/dist/types/tools/grouped-file-output.d.ts +46 -12
  369. package/dist/types/tools/image-gen.d.ts +1 -1
  370. package/dist/types/tools/index.d.ts +89 -8
  371. package/dist/types/tools/inspect-image.d.ts +1 -1
  372. package/dist/types/tools/irc.d.ts +79 -39
  373. package/dist/types/tools/job.d.ts +8 -2
  374. package/dist/types/tools/learn.d.ts +51 -0
  375. package/dist/types/tools/manage-skill.d.ts +40 -0
  376. package/dist/types/tools/memory-edit.d.ts +2 -2
  377. package/dist/types/tools/memory-recall.d.ts +1 -1
  378. package/dist/types/tools/memory-reflect.d.ts +1 -1
  379. package/dist/types/tools/memory-render.d.ts +4 -1
  380. package/dist/types/tools/memory-retain.d.ts +1 -1
  381. package/dist/types/tools/path-utils.d.ts +17 -5
  382. package/dist/types/tools/plan-mode-guard.d.ts +18 -9
  383. package/dist/types/tools/read.d.ts +3 -2
  384. package/dist/types/tools/render-mermaid.d.ts +1 -1
  385. package/dist/types/tools/render-utils.d.ts +47 -27
  386. package/dist/types/tools/renderers.d.ts +10 -2
  387. package/dist/types/tools/report-tool-issue.d.ts +6 -1
  388. package/dist/types/tools/resolve.d.ts +1 -1
  389. package/dist/types/tools/review.d.ts +1 -1
  390. package/dist/types/tools/search-tool-bm25.d.ts +1 -1
  391. package/dist/types/tools/search.d.ts +7 -3
  392. package/dist/types/tools/sqlite-reader.d.ts +4 -0
  393. package/dist/types/tools/ssh.d.ts +2 -1
  394. package/dist/types/tools/todo.d.ts +7 -15
  395. package/dist/types/tools/tool-result.d.ts +2 -0
  396. package/dist/types/tools/tool-timeouts.d.ts +1 -1
  397. package/dist/types/tools/tts.d.ts +26 -1
  398. package/dist/types/tools/write.d.ts +6 -3
  399. package/dist/types/tools/yield.d.ts +8 -0
  400. package/dist/types/tts/downloader.d.ts +20 -0
  401. package/dist/types/tts/index.d.ts +8 -0
  402. package/dist/types/tts/models.d.ts +82 -0
  403. package/dist/types/tts/player.d.ts +32 -0
  404. package/dist/types/tts/runtime.d.ts +6 -0
  405. package/dist/types/tts/streaming-player.d.ts +41 -0
  406. package/dist/types/tts/tts-client.d.ts +93 -0
  407. package/dist/types/tts/tts-protocol.d.ts +95 -0
  408. package/dist/types/tts/tts-worker.d.ts +2 -0
  409. package/dist/types/tts/vocalizer.d.ts +41 -0
  410. package/dist/types/tts/wav.d.ts +8 -0
  411. package/dist/types/tui/code-cell.d.ts +0 -2
  412. package/dist/types/tui/hyperlink.d.ts +13 -7
  413. package/dist/types/tui/output-block.d.ts +16 -22
  414. package/dist/types/tui/status-line.d.ts +3 -0
  415. package/dist/types/utils/block-context.d.ts +35 -0
  416. package/dist/types/utils/changelog.d.ts +8 -0
  417. package/dist/types/utils/clipboard.d.ts +4 -3
  418. package/dist/types/utils/enhanced-paste.d.ts +20 -0
  419. package/dist/types/utils/file-mentions.d.ts +7 -0
  420. package/dist/types/utils/git.d.ts +22 -3
  421. package/dist/types/utils/image-loading.d.ts +30 -1
  422. package/dist/types/utils/session-color.d.ts +15 -3
  423. package/dist/types/utils/thinking-display.d.ts +17 -0
  424. package/dist/types/utils/title-generator.d.ts +3 -2
  425. package/dist/types/utils/tool-choice.d.ts +8 -0
  426. package/dist/types/utils/tools-manager.d.ts +2 -1
  427. package/dist/types/web/kagi.d.ts +2 -2
  428. package/dist/types/web/parallel.d.ts +3 -0
  429. package/dist/types/web/scrapers/github.d.ts +22 -0
  430. package/dist/types/web/scrapers/readthedocs.d.ts +3 -0
  431. package/dist/types/web/scrapers/types.d.ts +12 -0
  432. package/dist/types/web/search/index.d.ts +1 -1
  433. package/dist/types/web/search/providers/anthropic.d.ts +2 -1
  434. package/dist/types/web/search/providers/base.d.ts +2 -1
  435. package/dist/types/web/search/providers/brave.d.ts +2 -1
  436. package/dist/types/web/search/providers/codex.d.ts +2 -1
  437. package/dist/types/web/search/providers/exa.d.ts +2 -1
  438. package/dist/types/web/search/providers/gemini.d.ts +10 -6
  439. package/dist/types/web/search/providers/jina.d.ts +7 -2
  440. package/dist/types/web/search/providers/kagi.d.ts +7 -2
  441. package/dist/types/web/search/providers/kimi.d.ts +7 -2
  442. package/dist/types/web/search/providers/parallel.d.ts +2 -1
  443. package/dist/types/web/search/providers/perplexity.d.ts +10 -2
  444. package/dist/types/web/search/providers/searxng.d.ts +2 -1
  445. package/dist/types/web/search/providers/synthetic.d.ts +7 -3
  446. package/dist/types/web/search/providers/tavily.d.ts +2 -1
  447. package/dist/types/web/search/providers/zai.d.ts +2 -1
  448. package/dist/types/web/search/types.d.ts +1 -1
  449. package/examples/extensions/api-demo.ts +2 -2
  450. package/package.json +41 -15
  451. package/scripts/bench-guard.ts +71 -0
  452. package/scripts/build-binary.ts +24 -25
  453. package/scripts/bundle-dist.ts +97 -0
  454. package/scripts/generate-share-viewer.ts +34 -0
  455. package/scripts/prometheus +42 -0
  456. package/scripts/prometheus.ts +20 -0
  457. package/src/async/index.ts +0 -1
  458. package/src/async/job-manager.ts +106 -3
  459. package/src/auto-thinking/classifier.ts +2 -1
  460. package/src/autolearn/controller.ts +139 -0
  461. package/src/autolearn/managed-skills.ts +257 -0
  462. package/src/autoresearch/dashboard.ts +1 -1
  463. package/src/autoresearch/prompt-setup.md +6 -6
  464. package/src/autoresearch/prompt.md +6 -6
  465. package/src/autoresearch/state.ts +1 -1
  466. package/src/autoresearch/storage.ts +2 -1
  467. package/src/autoresearch/tools/init-experiment.ts +1 -1
  468. package/src/autoresearch/tools/log-experiment.ts +1 -1
  469. package/src/autoresearch/tools/run-experiment.ts +1 -1
  470. package/src/autoresearch/tools/update-notes.ts +1 -1
  471. package/src/autoresearch/types.ts +1 -1
  472. package/src/capability/context-file.ts +0 -14
  473. package/src/capability/fs.ts +10 -0
  474. package/src/capability/index.ts +1 -6
  475. package/src/capability/mcp.ts +1 -0
  476. package/src/capability/rule-buckets.ts +4 -2
  477. package/src/capability/rule.ts +10 -1
  478. package/src/capability/types.ts +0 -4
  479. package/src/cli/args.ts +66 -13
  480. package/src/cli/auth-broker-cli.ts +6 -7
  481. package/src/cli/auth-gateway-cli.ts +8 -9
  482. package/src/cli/bench-cli.ts +437 -0
  483. package/src/cli/claude-trace-cli.ts +28 -50
  484. package/src/cli/completion-gen.ts +28 -28
  485. package/src/cli/dry-balance-cli.ts +56 -23
  486. package/src/cli/gallery-cli.ts +231 -0
  487. package/src/cli/gallery-fixtures/agentic.ts +407 -0
  488. package/src/cli/gallery-fixtures/codeintel.ts +187 -0
  489. package/src/cli/gallery-fixtures/edit.ts +194 -0
  490. package/src/cli/gallery-fixtures/fs.ts +220 -0
  491. package/src/cli/gallery-fixtures/index.ts +40 -0
  492. package/src/cli/gallery-fixtures/interaction.ts +49 -0
  493. package/src/cli/gallery-fixtures/memory.ts +81 -0
  494. package/src/cli/gallery-fixtures/misc.ts +250 -0
  495. package/src/cli/gallery-fixtures/search.ts +213 -0
  496. package/src/cli/gallery-fixtures/shell.ts +167 -0
  497. package/src/cli/gallery-fixtures/types.ts +57 -0
  498. package/src/cli/gallery-fixtures/web.ts +158 -0
  499. package/src/cli/gallery-screenshot.ts +279 -0
  500. package/src/cli/grievances-cli.ts +1 -1
  501. package/src/cli/list-models.ts +16 -174
  502. package/src/cli/models-cli.ts +429 -0
  503. package/src/cli/session-picker.ts +2 -1
  504. package/src/cli/setup-cli.ts +148 -47
  505. package/src/cli/setup-model-picker.ts +43 -0
  506. package/src/cli/startup-cwd.ts +68 -0
  507. package/src/cli/update-cli.ts +144 -272
  508. package/src/cli/usage-cli.ts +774 -0
  509. package/src/cli-commands.ts +36 -0
  510. package/src/cli.ts +141 -32
  511. package/src/collab/crypto.ts +63 -0
  512. package/src/collab/guest.ts +451 -0
  513. package/src/collab/host.ts +565 -0
  514. package/src/collab/protocol.ts +241 -0
  515. package/src/collab/relay-client.ts +216 -0
  516. package/src/commands/bench.ts +42 -0
  517. package/src/commands/complete.ts +1 -1
  518. package/src/commands/gallery.ts +52 -0
  519. package/src/commands/install.ts +1 -1
  520. package/src/commands/join.ts +39 -0
  521. package/src/commands/launch.ts +8 -4
  522. package/src/commands/models.ts +61 -0
  523. package/src/commands/read.ts +6 -3
  524. package/src/commands/say.ts +102 -0
  525. package/src/commands/setup.ts +1 -1
  526. package/src/commands/token.ts +89 -0
  527. package/src/commands/usage.ts +43 -0
  528. package/src/commit/agentic/agent.ts +2 -1
  529. package/src/commit/agentic/tools/analyze-file.ts +42 -20
  530. package/src/commit/agentic/tools/git-file-diff.ts +1 -1
  531. package/src/commit/agentic/tools/git-hunk.ts +1 -1
  532. package/src/commit/agentic/tools/git-overview.ts +1 -1
  533. package/src/commit/agentic/tools/propose-changelog.ts +1 -1
  534. package/src/commit/agentic/tools/propose-commit.ts +1 -1
  535. package/src/commit/agentic/tools/recent-commits.ts +1 -1
  536. package/src/commit/agentic/tools/schemas.ts +1 -1
  537. package/src/commit/agentic/tools/split-commit.ts +9 -2
  538. package/src/commit/analysis/conventional.ts +2 -2
  539. package/src/commit/analysis/summary.ts +3 -3
  540. package/src/commit/changelog/generate.ts +3 -3
  541. package/src/commit/changelog/index.ts +2 -2
  542. package/src/commit/map-reduce/index.ts +3 -3
  543. package/src/commit/map-reduce/map-phase.ts +2 -2
  544. package/src/commit/map-reduce/reduce-phase.ts +2 -2
  545. package/src/commit/model-selection.ts +35 -12
  546. package/src/commit/pipeline.ts +4 -4
  547. package/src/commit/shared-llm.ts +1 -1
  548. package/src/config/api-key-resolver.ts +67 -0
  549. package/src/config/append-only-context-mode.ts +6 -12
  550. package/src/config/keybindings.ts +9 -4
  551. package/src/config/mcp-schema.json +4 -0
  552. package/src/config/model-discovery.ts +574 -0
  553. package/src/config/model-equivalence.ts +5 -4
  554. package/src/config/model-registry.ts +659 -1093
  555. package/src/config/model-resolver.ts +374 -174
  556. package/src/config/model-roles.ts +88 -0
  557. package/src/config/models-config-schema.ts +61 -9
  558. package/src/config/models-config.ts +130 -0
  559. package/src/config/settings-schema.ts +1441 -387
  560. package/src/config/settings.ts +261 -69
  561. package/src/dap/client.ts +138 -53
  562. package/src/dap/config.ts +41 -2
  563. package/src/dap/defaults.json +1 -0
  564. package/src/dap/session.ts +263 -161
  565. package/src/dap/types.ts +10 -0
  566. package/src/debug/index.ts +50 -60
  567. package/src/debug/log-viewer.ts +1 -1
  568. package/src/debug/protocol-probe.ts +1 -1
  569. package/src/debug/raw-sse-buffer.ts +7 -4
  570. package/src/debug/raw-sse.ts +1 -1
  571. package/src/debug/report-bundle.ts +9 -0
  572. package/src/debug/terminal-info.ts +0 -3
  573. package/src/discovery/agents-md.ts +25 -21
  574. package/src/discovery/agents.ts +9 -15
  575. package/src/discovery/at-imports.ts +273 -0
  576. package/src/discovery/builtin-rules/index.ts +4 -0
  577. package/src/discovery/builtin-rules/ts-no-test-timers.md +55 -0
  578. package/src/discovery/builtin-rules/ts-redundant-clear-guard.md +75 -0
  579. package/src/discovery/builtin.ts +45 -23
  580. package/src/discovery/claude-plugins.ts +44 -5
  581. package/src/discovery/helpers.ts +50 -9
  582. package/src/discovery/prometheus-extension-roots.ts +10 -10
  583. package/src/discovery/prometheus-plugins.ts +10 -10
  584. package/src/edit/diff.ts +191 -4
  585. package/src/edit/file-snapshot-store.ts +34 -1
  586. package/src/edit/hashline/block-resolver.ts +20 -1
  587. package/src/edit/hashline/diff.ts +123 -2
  588. package/src/edit/hashline/execute.ts +60 -4
  589. package/src/edit/hashline/filesystem.ts +2 -1
  590. package/src/edit/hashline/noop-loop-guard.ts +99 -0
  591. package/src/edit/hashline/params.ts +1 -1
  592. package/src/edit/index.ts +47 -18
  593. package/src/edit/modes/apply-patch.ts +1 -1
  594. package/src/edit/modes/patch.ts +59 -3
  595. package/src/edit/modes/replace.ts +58 -24
  596. package/src/edit/notebook.ts +22 -2
  597. package/src/edit/renderer.ts +315 -151
  598. package/src/eval/__tests__/agent-bridge.test.ts +105 -39
  599. package/src/eval/__tests__/budget-bridge.test.ts +1 -1
  600. package/src/eval/__tests__/completion-bridge.test.ts +412 -0
  601. package/src/eval/__tests__/helpers-local-roots.test.ts +58 -0
  602. package/src/eval/__tests__/js-context-manager.test.ts +241 -0
  603. package/src/eval/__tests__/llm-bridge.test.ts +6 -4
  604. package/src/eval/__tests__/shared-executors.test.ts +34 -92
  605. package/src/eval/agent-bridge.ts +39 -23
  606. package/src/eval/backend.ts +15 -2
  607. package/src/eval/bridge-timeout.ts +1 -1
  608. package/src/eval/completion-bridge.ts +203 -0
  609. package/src/eval/idle-timeout.ts +3 -10
  610. package/src/eval/js/context-manager.ts +108 -31
  611. package/src/eval/js/executor.ts +9 -2
  612. package/src/eval/js/index.ts +7 -3
  613. package/src/eval/js/shared/helpers.ts +59 -13
  614. package/src/eval/js/shared/local-module-loader.ts +2 -2
  615. package/src/eval/js/shared/prelude.txt +167 -30
  616. package/src/eval/js/shared/rewrite-imports.ts +58 -34
  617. package/src/eval/js/shared/runtime.ts +24 -16
  618. package/src/eval/js/tool-bridge.ts +4 -0
  619. package/src/eval/js/worker-core.ts +1 -0
  620. package/src/eval/js/worker-entry.ts +6 -0
  621. package/src/eval/js/worker-protocol.ts +6 -0
  622. package/src/eval/llm-bridge.ts +2 -1
  623. package/src/eval/py/__tests__/prelude.test.ts +19 -0
  624. package/src/eval/py/executor.ts +70 -26
  625. package/src/eval/py/index.ts +13 -4
  626. package/src/eval/py/kernel.ts +48 -9
  627. package/src/eval/py/prelude.py +73 -24
  628. package/src/eval/py/runner.py +133 -28
  629. package/src/eval/py/runtime.ts +38 -1
  630. package/src/exa/index.ts +1 -26
  631. package/src/exa/mcp-client.ts +10 -10
  632. package/src/exa/types.ts +0 -97
  633. package/src/exec/bash-executor.ts +104 -7
  634. package/src/export/custom-share.ts +1 -1
  635. package/src/export/html/index.ts +119 -17
  636. package/src/export/html/share-loader.js +102 -0
  637. package/src/export/html/template-js.ts +6 -0
  638. package/src/export/html/template.css +745 -459
  639. package/src/export/html/template.css.d.ts +2 -0
  640. package/src/export/html/template.html +6 -3
  641. package/src/export/html/template.js +277 -891
  642. package/src/export/html/tool-views.generated.d.ts +2 -0
  643. package/src/export/html/tool-views.generated.js +38 -0
  644. package/src/export/share.ts +269 -0
  645. package/src/export/ttsr.ts +122 -1
  646. package/src/extensibility/custom-commands/loader.ts +7 -4
  647. package/src/extensibility/custom-commands/types.ts +9 -4
  648. package/src/extensibility/custom-tools/loader.ts +51 -23
  649. package/src/extensibility/custom-tools/types.ts +16 -8
  650. package/src/extensibility/extensions/get-commands-handler.ts +2 -1
  651. package/src/extensibility/extensions/index.ts +1 -0
  652. package/src/extensibility/extensions/loader.ts +70 -20
  653. package/src/extensibility/extensions/model-api.ts +41 -0
  654. package/src/extensibility/extensions/runner.ts +12 -2
  655. package/src/extensibility/extensions/types.ts +83 -11
  656. package/src/extensibility/extensions/wrapper.ts +41 -5
  657. package/src/extensibility/hooks/index.ts +2 -1
  658. package/src/extensibility/hooks/loader.ts +6 -3
  659. package/src/extensibility/hooks/types.ts +11 -5
  660. package/src/extensibility/{legacy-pi-ai-shim.ts → legacy-package-ai-shim.ts} +2 -2
  661. package/src/extensibility/plugins/doctor.ts +1 -2
  662. package/src/extensibility/plugins/installer.ts +2 -2
  663. package/src/extensibility/plugins/{legacy-pi-compat.ts → legacy-package-compat.ts} +165 -77
  664. package/src/extensibility/plugins/loader.ts +34 -23
  665. package/src/extensibility/plugins/manager.ts +226 -95
  666. package/src/extensibility/plugins/marketplace-auto-update.ts +49 -0
  667. package/src/extensibility/plugins/types.ts +3 -3
  668. package/src/extensibility/shared-events.ts +3 -3
  669. package/src/extensibility/skills.ts +113 -9
  670. package/src/extensibility/slash-commands.ts +1 -97
  671. package/src/goals/guided-setup.ts +133 -0
  672. package/src/goals/state.ts +1 -1
  673. package/src/goals/tools/goal-tool.ts +38 -28
  674. package/src/hindsight/bank.ts +17 -2
  675. package/src/hindsight/client.ts +27 -2
  676. package/src/hindsight/mental-models.ts +59 -12
  677. package/src/hindsight/state.ts +12 -3
  678. package/src/hindsight/transcript.ts +1 -1
  679. package/src/index.ts +5 -0
  680. package/src/internal-urls/artifact-protocol.ts +11 -2
  681. package/src/internal-urls/docs-index.generated.ts +9 -7
  682. package/src/internal-urls/history-protocol.ts +113 -0
  683. package/src/internal-urls/index.ts +1 -0
  684. package/src/internal-urls/issue-pr-protocol.ts +22 -9
  685. package/src/internal-urls/local-protocol.ts +42 -7
  686. package/src/internal-urls/memory-protocol.ts +4 -31
  687. package/src/internal-urls/router.ts +3 -1
  688. package/src/internal-urls/types.ts +1 -1
  689. package/src/irc/bus.ts +303 -0
  690. package/src/lib/xai-http.ts +3 -3
  691. package/src/lsp/client.ts +245 -104
  692. package/src/lsp/clients/biome-client.ts +101 -39
  693. package/src/lsp/clients/lsp-linter-client.ts +2 -10
  694. package/src/lsp/config.ts +15 -5
  695. package/src/lsp/defaults.json +6 -0
  696. package/src/lsp/edits.ts +143 -95
  697. package/src/lsp/format-options.ts +119 -0
  698. package/src/lsp/index.ts +233 -93
  699. package/src/lsp/render.ts +11 -35
  700. package/src/lsp/types.ts +13 -1
  701. package/src/lsp/utils.ts +31 -12
  702. package/src/main.ts +396 -216
  703. package/src/mcp/config-writer.ts +7 -3
  704. package/src/mcp/json-rpc.ts +35 -5
  705. package/src/mcp/manager.ts +31 -16
  706. package/src/mcp/oauth-discovery.ts +34 -4
  707. package/src/mcp/oauth-flow.ts +61 -8
  708. package/src/mcp/render.ts +7 -1
  709. package/src/mcp/startup-events.ts +21 -0
  710. package/src/mcp/tool-bridge.ts +2 -0
  711. package/src/mcp/transports/stdio.ts +224 -4
  712. package/src/mcp/types.ts +2 -0
  713. package/src/memories/index.ts +174 -1128
  714. package/src/memories/storage.ts +2 -41
  715. package/src/memory-backend/index.ts +14 -1
  716. package/src/memory-backend/local-backend.ts +18 -3
  717. package/src/memory-backend/off-backend.ts +9 -0
  718. package/src/memory-backend/resolve.ts +4 -6
  719. package/src/memory-backend/runtime.ts +66 -0
  720. package/src/memory-backend/types.ts +82 -2
  721. package/src/mnemopi/backend.ts +220 -28
  722. package/src/mnemopi/config.ts +138 -33
  723. package/src/mnemopi/state.ts +91 -11
  724. package/src/modes/acp/acp-agent.ts +149 -142
  725. package/src/modes/acp/acp-event-mapper.ts +5 -1
  726. package/src/modes/components/agent-dashboard.ts +17 -11
  727. package/src/modes/components/agent-hub.ts +1346 -0
  728. package/src/modes/components/assistant-message.ts +190 -80
  729. package/src/modes/components/bash-execution.ts +1 -1
  730. package/src/modes/components/btw-panel.ts +5 -1
  731. package/src/modes/components/chat-block.ts +111 -0
  732. package/src/modes/components/collab-prompt-message.ts +30 -0
  733. package/src/modes/components/compaction-summary-message.ts +168 -33
  734. package/src/modes/components/copy-selector.ts +2 -45
  735. package/src/modes/components/custom-editor.test.ts +96 -0
  736. package/src/modes/components/custom-editor.ts +405 -118
  737. package/src/modes/components/custom-message.ts +1 -3
  738. package/src/modes/components/diff.ts +13 -2
  739. package/src/modes/components/dynamic-border.ts +12 -3
  740. package/src/modes/components/execution-shared.ts +1 -2
  741. package/src/modes/components/extensions/extension-dashboard.ts +8 -5
  742. package/src/modes/components/extensions/extension-list.ts +1 -1
  743. package/src/modes/components/extensions/inspector-panel.ts +7 -3
  744. package/src/modes/components/extensions/state-manager.ts +36 -41
  745. package/src/modes/components/footer.ts +4 -2
  746. package/src/modes/components/history-search.ts +1 -1
  747. package/src/modes/components/hook-editor.ts +8 -0
  748. package/src/modes/components/hook-input.ts +8 -0
  749. package/src/modes/components/hook-message.ts +1 -3
  750. package/src/modes/components/hook-selector.ts +6 -7
  751. package/src/modes/components/index.ts +1 -0
  752. package/src/modes/components/late-diagnostics-message.ts +60 -0
  753. package/src/modes/components/login-dialog.ts +1 -1
  754. package/src/modes/components/logout-account-selector.ts +130 -0
  755. package/src/modes/components/mcp-add-wizard.ts +14 -1
  756. package/src/modes/components/model-selector.ts +177 -75
  757. package/src/modes/components/oauth-selector.ts +102 -16
  758. package/src/modes/components/overlay-box.ts +108 -0
  759. package/src/modes/components/plan-review-overlay.ts +845 -0
  760. package/src/modes/components/plan-toc.ts +138 -0
  761. package/src/modes/components/plugin-settings.ts +22 -5
  762. package/src/modes/components/read-tool-group.ts +442 -39
  763. package/src/modes/components/reset-usage-selector.ts +161 -0
  764. package/src/modes/components/segment-track.ts +44 -7
  765. package/src/modes/components/session-selector.ts +97 -37
  766. package/src/modes/components/settings-defs.ts +28 -6
  767. package/src/modes/components/settings-selector.ts +541 -93
  768. package/src/modes/components/skill-message.ts +0 -1
  769. package/src/modes/components/snapcompact-shape-preview-doc.md +11 -0
  770. package/src/modes/components/snapcompact-shape-preview.ts +193 -0
  771. package/src/modes/components/{status-line.ts → status-line/component.ts} +205 -168
  772. package/src/modes/components/status-line/index.ts +1 -0
  773. package/src/modes/components/status-line/presets.ts +3 -3
  774. package/src/modes/components/status-line/segments.ts +26 -7
  775. package/src/modes/components/status-line/types.ts +40 -9
  776. package/src/modes/components/tiny-title-download-progress.ts +1 -1
  777. package/src/modes/components/tips.txt +7 -3
  778. package/src/modes/components/todo-reminder.ts +0 -2
  779. package/src/modes/components/tool-execution.ts +236 -103
  780. package/src/modes/components/transcript-container.ts +724 -99
  781. package/src/modes/components/tree-selector.ts +19 -4
  782. package/src/modes/components/ttsr-notification.ts +72 -30
  783. package/src/modes/components/usage-row.ts +18 -0
  784. package/src/modes/components/user-message-selector.ts +1 -1
  785. package/src/modes/components/user-message.ts +28 -12
  786. package/src/modes/components/visual-truncate.ts +1 -1
  787. package/src/modes/components/welcome.ts +80 -22
  788. package/src/modes/controllers/command-controller-shared.ts +7 -6
  789. package/src/modes/controllers/command-controller.ts +210 -180
  790. package/src/modes/controllers/event-controller.ts +352 -142
  791. package/src/modes/controllers/extension-ui-controller.ts +167 -208
  792. package/src/modes/controllers/input-controller.ts +778 -162
  793. package/src/modes/controllers/mcp-command-controller.ts +232 -80
  794. package/src/modes/controllers/selector-controller.ts +284 -145
  795. package/src/modes/controllers/session-focus-controller.ts +112 -0
  796. package/src/modes/controllers/ssh-command-controller.ts +2 -2
  797. package/src/modes/controllers/streaming-reveal.ts +295 -0
  798. package/src/modes/controllers/tan-command-controller.ts +173 -0
  799. package/src/modes/controllers/tool-args-reveal.ts +174 -0
  800. package/src/modes/gradient-highlight.ts +21 -9
  801. package/src/modes/image-references.ts +33 -7
  802. package/src/modes/index.ts +8 -25
  803. package/src/modes/interactive-mode.ts +840 -186
  804. package/src/modes/magic-keywords.ts +28 -6
  805. package/src/modes/markdown-prose.ts +1 -1
  806. package/src/modes/oauth-manual-input.ts +30 -3
  807. package/src/modes/rpc/rpc-client.ts +186 -3
  808. package/src/modes/rpc/rpc-mode.ts +318 -24
  809. package/src/modes/rpc/rpc-subagents.ts +265 -0
  810. package/src/modes/rpc/rpc-types.ts +111 -2
  811. package/src/modes/runtime-init.ts +28 -3
  812. package/src/modes/session-observer-registry.ts +72 -3
  813. package/src/modes/setup-version.ts +11 -0
  814. package/src/modes/setup-wizard/index.ts +16 -4
  815. package/src/modes/setup-wizard/lazy.ts +16 -0
  816. package/src/modes/setup-wizard/scenes/glyph.ts +25 -7
  817. package/src/modes/setup-wizard/scenes/providers.ts +45 -12
  818. package/src/modes/setup-wizard/scenes/sign-in.ts +14 -13
  819. package/src/modes/setup-wizard/scenes/splash.ts +1 -1
  820. package/src/modes/setup-wizard/scenes/theme.ts +29 -2
  821. package/src/modes/setup-wizard/scenes/types.ts +11 -2
  822. package/src/modes/setup-wizard/scenes/web-search.ts +26 -9
  823. package/src/modes/setup-wizard/wizard-overlay.ts +40 -3
  824. package/src/modes/shared.ts +2 -0
  825. package/src/modes/theme/defaults/dark-poimandres.json +1 -1
  826. package/src/modes/theme/defaults/light-poimandres.json +1 -1
  827. package/src/modes/theme/shimmer.ts +20 -9
  828. package/src/modes/theme/theme-schema.json +1 -1
  829. package/src/modes/theme/theme.ts +342 -82
  830. package/src/modes/types.ts +60 -18
  831. package/src/modes/utils/context-usage.ts +88 -8
  832. package/src/modes/utils/copy-targets.ts +133 -27
  833. package/src/modes/utils/hotkeys-markdown.ts +3 -2
  834. package/src/modes/utils/ui-helpers.ts +191 -110
  835. package/src/modes/workflow.ts +10 -10
  836. package/src/plan-mode/approved-plan.ts +66 -43
  837. package/src/plan-mode/plan-protection.ts +4 -4
  838. package/src/priority.json +5 -1
  839. package/src/prompts/agents/designer.md +1 -1
  840. package/src/prompts/agents/explore.md +3 -3
  841. package/src/prompts/agents/librarian.md +2 -3
  842. package/src/prompts/agents/oracle.md +2 -2
  843. package/src/prompts/agents/plan.md +6 -6
  844. package/src/prompts/agents/reviewer.md +1 -1
  845. package/src/prompts/agents/task.md +6 -5
  846. package/src/prompts/bench.md +12 -0
  847. package/src/prompts/ci-green-request.md +5 -7
  848. package/src/prompts/goals/goal-budget-limit.md +2 -2
  849. package/src/prompts/goals/goal-continuation.md +4 -4
  850. package/src/prompts/goals/goal-mode-active.md +1 -1
  851. package/src/prompts/goals/guided-goal-interview.md +8 -0
  852. package/src/prompts/goals/guided-goal-system.md +12 -0
  853. package/src/prompts/memories/consolidation.md +2 -7
  854. package/src/prompts/memories/consolidation_system.md +4 -0
  855. package/src/prompts/memories/identity_review.md +2 -2
  856. package/src/prompts/memories/read-path.md +11 -10
  857. package/src/prompts/memories/stage_one_system.md +2 -2
  858. package/src/prompts/review-custom-request.md +1 -1
  859. package/src/prompts/system/agent-creation-architect.md +2 -2
  860. package/src/prompts/system/auto-continue.md +1 -1
  861. package/src/prompts/system/autolearn-guidance-learn.md +1 -0
  862. package/src/prompts/system/autolearn-guidance.md +7 -0
  863. package/src/prompts/system/autolearn-nudge.md +3 -0
  864. package/src/prompts/system/background-tan-dispatch.md +8 -0
  865. package/src/prompts/system/btw-user.md +2 -2
  866. package/src/prompts/system/commit-message-system.md +13 -1
  867. package/src/prompts/system/custom-system-prompt.md +1 -1
  868. package/src/prompts/system/eager-task.md +7 -0
  869. package/src/prompts/system/eager-todo.md +11 -6
  870. package/src/prompts/system/empty-stop-retry.md +4 -6
  871. package/src/prompts/system/irc-autoreply.md +6 -0
  872. package/src/prompts/system/irc-incoming.md +3 -4
  873. package/src/prompts/system/manual-continue.md +7 -0
  874. package/src/prompts/system/omfg-user.md +3 -4
  875. package/src/prompts/system/orchestrate-notice.md +10 -10
  876. package/src/prompts/system/personalities/default.md +26 -0
  877. package/src/prompts/system/personalities/friendly.md +17 -0
  878. package/src/prompts/system/personalities/pragmatic.md +15 -0
  879. package/src/prompts/system/plan-mode-active.md +70 -77
  880. package/src/prompts/system/plan-mode-approved.md +1 -1
  881. package/src/prompts/system/plan-mode-subagent.md +4 -5
  882. package/src/prompts/system/plan-mode-tool-decision-reminder.md +1 -1
  883. package/src/prompts/system/project-prompt.md +2 -2
  884. package/src/prompts/system/snapcompact-context-frames-note.md +1 -0
  885. package/src/prompts/system/snapcompact-context-stub.md +1 -0
  886. package/src/prompts/system/snapcompact-system-frames-note.md +1 -0
  887. package/src/prompts/system/snapcompact-system-stub.md +1 -0
  888. package/src/prompts/system/snapcompact-toolresult-note.md +1 -0
  889. package/src/prompts/system/subagent-system-prompt.md +7 -8
  890. package/src/prompts/system/system-prompt.md +28 -57
  891. package/src/prompts/system/tiny-title-system.md +1 -1
  892. package/src/prompts/system/title-marker-instruction.md +1 -0
  893. package/src/prompts/system/title-system-marker.md +16 -0
  894. package/src/prompts/system/title-system.md +16 -3
  895. package/src/prompts/system/ttsr-tool-reminder.md +1 -1
  896. package/src/prompts/system/workflow-notice.md +4 -4
  897. package/src/prompts/tools/ast-edit.md +1 -1
  898. package/src/prompts/tools/ast-grep.md +2 -2
  899. package/src/prompts/tools/bash.md +16 -8
  900. package/src/prompts/tools/browser.md +33 -43
  901. package/src/prompts/tools/debug.md +1 -1
  902. package/src/prompts/tools/eval.md +31 -51
  903. package/src/prompts/tools/find.md +0 -1
  904. package/src/prompts/tools/github.md +8 -7
  905. package/src/prompts/tools/goal.md +1 -1
  906. package/src/prompts/tools/image-gen.md +1 -1
  907. package/src/prompts/tools/inspect-image-system.md +1 -1
  908. package/src/prompts/tools/irc.md +39 -31
  909. package/src/prompts/tools/job.md +2 -1
  910. package/src/prompts/tools/learn.md +7 -0
  911. package/src/prompts/tools/lsp-late-diagnostic.md +8 -0
  912. package/src/prompts/tools/lsp.md +2 -2
  913. package/src/prompts/tools/manage-skill.md +9 -0
  914. package/src/prompts/tools/memory-edit.md +1 -1
  915. package/src/prompts/tools/patch.md +2 -2
  916. package/src/prompts/tools/read.md +31 -39
  917. package/src/prompts/tools/recall.md +1 -1
  918. package/src/prompts/tools/reflect.md +1 -1
  919. package/src/prompts/tools/render-mermaid.md +2 -2
  920. package/src/prompts/tools/replace.md +4 -10
  921. package/src/prompts/tools/rewind.md +2 -2
  922. package/src/prompts/tools/search-tool-bm25.md +1 -9
  923. package/src/prompts/tools/search.md +0 -1
  924. package/src/prompts/tools/ssh.md +0 -4
  925. package/src/prompts/tools/task-summary.md +5 -16
  926. package/src/prompts/tools/task.md +47 -31
  927. package/src/prompts/tools/todo.md +6 -3
  928. package/src/registry/agent-lifecycle.ts +218 -0
  929. package/src/registry/agent-registry.ts +46 -5
  930. package/src/sdk.ts +692 -219
  931. package/src/secrets/index.ts +8 -1
  932. package/src/secrets/obfuscator.ts +40 -19
  933. package/src/session/agent-session.ts +1577 -806
  934. package/src/session/agent-storage.ts +18 -9
  935. package/src/session/auth-broker-config.ts +30 -1
  936. package/src/session/auth-storage.ts +6 -0
  937. package/src/session/codex-auto-reset.ts +202 -0
  938. package/src/session/history-storage.ts +3 -2
  939. package/src/session/indexed-session-storage.ts +7 -10
  940. package/src/session/messages.ts +59 -95
  941. package/src/session/session-context.ts +352 -0
  942. package/src/session/session-dump-format.ts +12 -3
  943. package/src/session/session-entries.ts +194 -0
  944. package/src/session/session-history-format.ts +246 -0
  945. package/src/session/session-listing.ts +588 -0
  946. package/src/session/session-loader.ts +106 -0
  947. package/src/session/session-manager.ts +1003 -2920
  948. package/src/session/session-migrations.ts +78 -0
  949. package/src/session/session-paths.ts +193 -0
  950. package/src/session/session-persistence.ts +131 -0
  951. package/src/session/session-storage.ts +91 -30
  952. package/src/session/snapcompact-inline.ts +542 -0
  953. package/src/session/snapcompact-savings-journal.ts +113 -0
  954. package/src/session/streaming-output.ts +248 -11
  955. package/src/session/tool-choice-queue.ts +23 -11
  956. package/src/session/yield-queue.ts +20 -2
  957. package/src/slash-commands/acp-builtins.ts +25 -1
  958. package/src/slash-commands/available-commands.ts +105 -0
  959. package/src/slash-commands/builtin-registry.ts +575 -49
  960. package/src/slash-commands/helpers/active-oauth-account.ts +44 -0
  961. package/src/slash-commands/helpers/context-report.ts +28 -1
  962. package/src/slash-commands/helpers/logout.ts +88 -0
  963. package/src/slash-commands/helpers/reset-usage.ts +66 -0
  964. package/src/slash-commands/helpers/stats-dashboard.ts +85 -0
  965. package/src/slash-commands/helpers/usage-report.ts +38 -3
  966. package/src/slash-commands/types.ts +5 -9
  967. package/src/ssh/connection-manager.ts +27 -0
  968. package/src/ssh/ssh-executor.ts +60 -4
  969. package/src/stt/asr-client.ts +520 -0
  970. package/src/stt/asr-protocol.ts +65 -0
  971. package/src/stt/asr-worker.ts +790 -0
  972. package/src/stt/downloader.ts +107 -47
  973. package/src/stt/endpointer.ts +259 -0
  974. package/src/stt/index.ts +5 -1
  975. package/src/stt/models.ts +150 -0
  976. package/src/stt/recorder.ts +254 -67
  977. package/src/stt/stt-controller.ts +201 -22
  978. package/src/stt/transcriber.ts +37 -68
  979. package/src/stt/wav.ts +173 -0
  980. package/src/system-prompt.ts +52 -10
  981. package/src/task/agents.ts +3 -4
  982. package/src/task/commands.ts +3 -2
  983. package/src/task/discovery.ts +17 -24
  984. package/src/task/executor.ts +1054 -529
  985. package/src/task/index.ts +862 -757
  986. package/src/task/output-manager.ts +0 -11
  987. package/src/task/parallel.ts +3 -3
  988. package/src/task/prometheus-command.ts +2 -2
  989. package/src/task/render.ts +529 -182
  990. package/src/task/repair-args.ts +21 -9
  991. package/src/task/types.ts +144 -66
  992. package/src/task/worktree.ts +64 -56
  993. package/src/telemetry-export.ts +27 -9
  994. package/src/thinking.ts +9 -7
  995. package/src/tiny/models.ts +2 -2
  996. package/src/tiny/text.ts +5 -1
  997. package/src/tiny/title-client.ts +72 -20
  998. package/src/tiny/title-protocol.ts +1 -1
  999. package/src/tiny/worker.ts +23 -99
  1000. package/src/tool-discovery/tool-index.ts +2 -0
  1001. package/src/tools/archive-reader.ts +94 -2
  1002. package/src/tools/ask.ts +234 -177
  1003. package/src/tools/ast-edit.ts +136 -80
  1004. package/src/tools/ast-grep.ts +41 -45
  1005. package/src/tools/auto-generated-guard.ts +20 -3
  1006. package/src/tools/bash-interactive.ts +28 -8
  1007. package/src/tools/bash.ts +198 -35
  1008. package/src/tools/browser/attach.ts +26 -7
  1009. package/src/tools/browser/cmux/cmux-tab.ts +1264 -0
  1010. package/src/tools/browser/cmux/rpc.ts +156 -0
  1011. package/src/tools/browser/cmux/socket-client.ts +309 -0
  1012. package/src/tools/browser/launch.ts +11 -2
  1013. package/src/tools/browser/readable.ts +19 -2
  1014. package/src/tools/browser/registry.ts +52 -5
  1015. package/src/tools/browser/render.ts +13 -5
  1016. package/src/tools/browser/tab-protocol.ts +2 -0
  1017. package/src/tools/browser/tab-supervisor.ts +256 -34
  1018. package/src/tools/browser/tab-worker.ts +259 -91
  1019. package/src/tools/browser.ts +44 -2
  1020. package/src/tools/checkpoint.ts +1 -1
  1021. package/src/tools/conflict-detect.ts +50 -4
  1022. package/src/tools/debug.ts +27 -12
  1023. package/src/tools/eval-render.ts +32 -35
  1024. package/src/tools/eval.ts +26 -12
  1025. package/src/tools/fetch.ts +450 -99
  1026. package/src/tools/find.ts +182 -142
  1027. package/src/tools/gh-cache-invalidation.ts +255 -0
  1028. package/src/tools/gh-renderer.ts +104 -51
  1029. package/src/tools/gh.ts +232 -37
  1030. package/src/tools/github-cache.ts +97 -7
  1031. package/src/tools/grouped-file-output.ts +159 -52
  1032. package/src/tools/image-gen.ts +237 -132
  1033. package/src/tools/index.ts +147 -26
  1034. package/src/tools/inspect-image-renderer.ts +74 -45
  1035. package/src/tools/inspect-image.ts +12 -6
  1036. package/src/tools/irc.ts +626 -173
  1037. package/src/tools/job.ts +106 -29
  1038. package/src/tools/learn.ts +144 -0
  1039. package/src/tools/manage-skill.ts +104 -0
  1040. package/src/tools/memory-edit.ts +4 -4
  1041. package/src/tools/memory-recall.ts +7 -9
  1042. package/src/tools/memory-reflect.ts +5 -9
  1043. package/src/tools/memory-render.ts +23 -6
  1044. package/src/tools/memory-retain.ts +4 -4
  1045. package/src/tools/path-utils.ts +102 -48
  1046. package/src/tools/plan-mode-guard.ts +101 -40
  1047. package/src/tools/read.ts +475 -120
  1048. package/src/tools/render-mermaid.ts +1 -1
  1049. package/src/tools/render-utils.ts +132 -76
  1050. package/src/tools/renderers.ts +12 -1
  1051. package/src/tools/report-tool-issue.ts +14 -6
  1052. package/src/tools/resolve.ts +20 -3
  1053. package/src/tools/review.ts +2 -2
  1054. package/src/tools/search-tool-bm25.ts +37 -24
  1055. package/src/tools/search.ts +233 -115
  1056. package/src/tools/sqlite-reader.ts +26 -17
  1057. package/src/tools/ssh.ts +20 -14
  1058. package/src/tools/todo.ts +197 -191
  1059. package/src/tools/tool-result.ts +8 -0
  1060. package/src/tools/tool-timeouts.ts +1 -1
  1061. package/src/tools/tts.ts +205 -74
  1062. package/src/tools/write.ts +291 -155
  1063. package/src/tools/yield.ts +10 -1
  1064. package/src/tts/downloader.ts +64 -0
  1065. package/src/tts/index.ts +8 -0
  1066. package/src/tts/models.ts +137 -0
  1067. package/src/tts/player.ts +137 -0
  1068. package/src/tts/runtime.ts +21 -0
  1069. package/src/tts/streaming-player.ts +266 -0
  1070. package/src/tts/tts-client.ts +647 -0
  1071. package/src/tts/tts-protocol.ts +60 -0
  1072. package/src/tts/tts-worker.ts +505 -0
  1073. package/src/tts/vocalizer.ts +162 -0
  1074. package/src/tts/wav.ts +58 -0
  1075. package/src/tui/code-cell.ts +2 -7
  1076. package/src/tui/hyperlink.ts +40 -26
  1077. package/src/tui/output-block.ts +60 -108
  1078. package/src/tui/status-line.ts +5 -1
  1079. package/src/utils/block-context.ts +312 -0
  1080. package/src/utils/changelog.ts +27 -1
  1081. package/src/utils/clipboard.ts +91 -22
  1082. package/src/utils/commit-message-generator.ts +8 -3
  1083. package/src/utils/enhanced-paste.ts +230 -0
  1084. package/src/utils/file-mentions.ts +3 -1
  1085. package/src/utils/git.ts +315 -15
  1086. package/src/utils/image-loading.ts +65 -4
  1087. package/src/utils/session-color.ts +83 -9
  1088. package/src/utils/thinking-display.ts +37 -0
  1089. package/src/utils/title-generator.ts +73 -10
  1090. package/src/utils/tool-choice.ts +16 -0
  1091. package/src/utils/tools-manager.ts +19 -1
  1092. package/src/web/kagi.ts +28 -26
  1093. package/src/web/parallel.ts +7 -3
  1094. package/src/web/scrapers/arxiv.ts +1 -1
  1095. package/src/web/scrapers/github.ts +351 -3
  1096. package/src/web/scrapers/go-pkg.ts +1 -1
  1097. package/src/web/scrapers/iacr.ts +1 -1
  1098. package/src/web/scrapers/readthedocs.ts +1 -1
  1099. package/src/web/scrapers/twitter.ts +2 -1
  1100. package/src/web/scrapers/types.ts +87 -8
  1101. package/src/web/scrapers/wikipedia.ts +1 -1
  1102. package/src/web/scrapers/youtube.ts +9 -3
  1103. package/src/web/search/index.ts +15 -2
  1104. package/src/web/search/providers/anthropic.ts +62 -21
  1105. package/src/web/search/providers/base.ts +2 -1
  1106. package/src/web/search/providers/brave.ts +5 -2
  1107. package/src/web/search/providers/codex.ts +87 -51
  1108. package/src/web/search/providers/exa.ts +101 -10
  1109. package/src/web/search/providers/gemini.ts +49 -24
  1110. package/src/web/search/providers/jina.ts +15 -5
  1111. package/src/web/search/providers/kagi.ts +9 -2
  1112. package/src/web/search/providers/kimi.ts +45 -20
  1113. package/src/web/search/providers/parallel.ts +39 -24
  1114. package/src/web/search/providers/perplexity.ts +226 -63
  1115. package/src/web/search/providers/searxng.ts +19 -3
  1116. package/src/web/search/providers/synthetic.ts +16 -11
  1117. package/src/web/search/providers/tavily.ts +12 -9
  1118. package/src/web/search/providers/zai.ts +22 -9
  1119. package/src/web/search/render.ts +59 -64
  1120. package/src/web/search/types.ts +5 -1
  1121. package/dist/types/discovery/context-files.d.ts +0 -17
  1122. package/dist/types/exa/factory.d.ts +0 -13
  1123. package/dist/types/exa/render.d.ts +0 -19
  1124. package/dist/types/exa/researcher.d.ts +0 -9
  1125. package/dist/types/exa/search.d.ts +0 -9
  1126. package/dist/types/exa/websets.d.ts +0 -9
  1127. package/dist/types/export/html/template.generated.d.ts +0 -1
  1128. package/dist/types/modes/components/session-observer-overlay.d.ts +0 -11
  1129. package/dist/types/modes/components/status-line.d.ts +0 -77
  1130. package/dist/types/slash-commands/headless-plan.d.ts +0 -3
  1131. package/dist/types/stt/setup.d.ts +0 -18
  1132. package/scripts/generate-template.ts +0 -33
  1133. package/src/discovery/context-files.ts +0 -49
  1134. package/src/exa/factory.ts +0 -60
  1135. package/src/exa/render.ts +0 -244
  1136. package/src/exa/researcher.ts +0 -36
  1137. package/src/exa/search.ts +0 -47
  1138. package/src/exa/websets.ts +0 -248
  1139. package/src/export/html/template.generated.ts +0 -2
  1140. package/src/modes/components/session-observer-overlay.ts +0 -852
  1141. package/src/slash-commands/headless-plan.ts +0 -142
  1142. package/src/stt/setup.ts +0 -52
  1143. package/src/stt/transcribe.py +0 -70
  1144. /package/dist/types/extensibility/{legacy-pi-coding-agent-shim.d.ts → legacy-package-agent-shim.d.ts} +0 -0
  1145. /package/src/extensibility/{legacy-pi-coding-agent-shim.ts → legacy-package-agent-shim.ts} +0 -0
package/src/tools/read.ts CHANGED
@@ -8,8 +8,14 @@ import { glob, type SummaryResult, summarizeCode } from "@prometheus-ai/natives"
8
8
  import type { Component } from "@prometheus-ai/tui";
9
9
  import { Text } from "@prometheus-ai/tui";
10
10
  import { getRemoteDir, logger, prompt, readImageMetadata, untilAborted } from "@prometheus-ai/utils";
11
- import * as z from "zod/v4";
12
- import { getFileSnapshotStore, recordFileSnapshot } from "../edit/file-snapshot-store";
11
+ import { LRUCache } from "lru-cache/raw";
12
+ import { z } from "zod/v4";
13
+ import {
14
+ canonicalSnapshotKey,
15
+ getFileSnapshotStore,
16
+ recordFileSnapshot,
17
+ SNAPSHOT_MAX_BYTES,
18
+ } from "../edit/file-snapshot-store";
13
19
  import { normalizeToLF } from "../edit/normalize";
14
20
  import { isNotebookPath, readEditableNotebookText } from "../edit/notebook";
15
21
  import type { RenderResultOptions } from "../extensibility/custom-tools/types";
@@ -30,11 +36,17 @@ import {
30
36
  } from "../session/streaming-output";
31
37
  import { fileHyperlink, renderCodeCell, renderMarkdownCell, renderStatusLine, tryResolveInternalUrlSync } from "../tui";
32
38
  import { CachedOutputBlock, markFramedBlockComponent } from "../tui/output-block";
39
+ import { buildLineEntriesWithBlockContext, type LineEntry, lineEntriesToPlainText } from "../utils/block-context";
33
40
  import { resolveFileDisplayMode } from "../utils/file-display-mode";
34
- import { ImageInputTooLargeError, loadImageInput, MAX_IMAGE_INPUT_BYTES } from "../utils/image-loading";
41
+ import {
42
+ ImageInputTooLargeError,
43
+ loadImageInput,
44
+ MAX_IMAGE_INPUT_BYTES,
45
+ webpExclusionForModel,
46
+ } from "../utils/image-loading";
35
47
  import { convertFileWithMarkit } from "../utils/markit";
36
48
  import { buildDirectoryTree, type DirectoryTree } from "../workspace-tree";
37
- import { type ArchiveReader, openArchive, parseArchivePathCandidates } from "./archive-reader";
49
+ import { type ArchiveReader, formatArchiveEntryLines, openArchive, parseArchivePathCandidates } from "./archive-reader";
38
50
  import {
39
51
  type ConflictEntry,
40
52
  type ConflictScope,
@@ -81,6 +93,7 @@ import {
81
93
  getTableSchema,
82
94
  isSqliteFile,
83
95
  listTables,
96
+ MAX_RAW_QUERY_ROWS,
84
97
  parseSqlitePathCandidates,
85
98
  parseSqliteSelector,
86
99
  queryRows,
@@ -93,6 +106,28 @@ import {
93
106
  import { ToolAbortError, ToolError, throwIfAborted } from "./tool-errors";
94
107
  import { toolResult } from "./tool-result";
95
108
 
109
+ // Per-session memo for tree-sitter summaries. `summarizeCode` is a pure function
110
+ // of (code, path, fold settings) but costs ~12-18ms for a ~1500-line file, and a
111
+ // repeat summary read of the same unchanged file re-parses from scratch. Key on
112
+ // the content hash of the freshly-read bytes (+ path + fold settings): the file
113
+ // is still read fresh on every call, so a hit only reuses the deterministic
114
+ // parse — there is no staleness window and no stat guard is needed. Bounded LRU,
115
+ // aged out with the session via WeakMap.
116
+ // Unusable results (not parsed, or nothing elided) are memoized as `false`: the
117
+ // full SummaryResult embeds the whole source in kept segments, and the caller
118
+ // only ever renders `parsed && elided` summaries — caching the segments would
119
+ // retain up to 48 near-2MiB sources just to remember "no summary".
120
+ const SUMMARY_CACHE_MAX = 48;
121
+ const summaryParseCaches = new WeakMap<object, LRUCache<string, SummaryResult | false>>();
122
+ function getSummaryParseCache(session: object): LRUCache<string, SummaryResult | false> {
123
+ let cache = summaryParseCaches.get(session);
124
+ if (!cache) {
125
+ cache = new LRUCache<string, SummaryResult | false>({ max: SUMMARY_CACHE_MAX });
126
+ summaryParseCaches.set(session, cache);
127
+ }
128
+ return cache;
129
+ }
130
+
96
131
  // Document types converted to markdown via markit.
97
132
  const CONVERTIBLE_EXTENSIONS = new Set([".pdf", ".doc", ".docx", ".ppt", ".pptx", ".xls", ".xlsx", ".rtf", ".epub"]);
98
133
 
@@ -108,6 +143,15 @@ const PROSE_SUMMARY_EXTENSIONS = new Set([".md", ".txt"]);
108
143
  // Remote mount path prefix (sshfs mounts) - skip fuzzy matching to avoid hangs
109
144
  const REMOTE_MOUNT_PREFIX = getRemoteDir() + path.sep;
110
145
 
146
+ async function readBracketContextFullLines(absolutePath: string, fileSize: number): Promise<string[] | undefined> {
147
+ if (fileSize > SNAPSHOT_MAX_BYTES) return undefined;
148
+ try {
149
+ return normalizeToLF(await Bun.file(absolutePath).text()).split("\n");
150
+ } catch {
151
+ return undefined;
152
+ }
153
+ }
154
+
111
155
  function isRemoteMountPath(absolutePath: string): boolean {
112
156
  return absolutePath.startsWith(REMOTE_MOUNT_PREFIX);
113
157
  }
@@ -131,7 +175,7 @@ function recordFullHashlineContext(
131
175
  ): HashlineHeaderContext | undefined {
132
176
  if (!absolutePath || !path.isAbsolute(absolutePath)) return undefined;
133
177
  const normalized = normalizeToLF(fullText);
134
- const tag = getFileSnapshotStore(session).record(absolutePath, normalized);
178
+ const tag = getFileSnapshotStore(session).record(canonicalSnapshotKey(absolutePath), normalized);
135
179
  return {
136
180
  header: formatHashlineHeader(displayPath, tag),
137
181
  tag,
@@ -174,6 +218,21 @@ function formatTextWithMode(
174
218
  return text;
175
219
  }
176
220
 
221
+ const BRACKET_CONTEXT_ELLIPSIS = "…";
222
+
223
+ function formatLineEntryWithMode(entry: LineEntry, shouldAddHashLines: boolean, shouldAddLineNumbers: boolean): string {
224
+ if (entry.kind === "ellipsis") return BRACKET_CONTEXT_ELLIPSIS;
225
+ return formatSingleLine(entry.lineNumber, entry.text, shouldAddHashLines, shouldAddLineNumbers);
226
+ }
227
+
228
+ function formatLineEntriesWithMode(
229
+ entries: readonly LineEntry[],
230
+ shouldAddHashLines: boolean,
231
+ shouldAddLineNumbers: boolean,
232
+ ): string {
233
+ return entries.map(entry => formatLineEntryWithMode(entry, shouldAddHashLines, shouldAddLineNumbers)).join("\n");
234
+ }
235
+
177
236
  const BRACE_PAIRS: Record<string, string> = { "{": "}", "(": ")", "[": "]" };
178
237
  const BRACE_TAIL_TRAILING_RE = /^[;,)\]}]*$/;
179
238
 
@@ -304,6 +363,7 @@ async function streamLinesFromFile(
304
363
  maxBytes: number,
305
364
  selectedLineLimit: number | null,
306
365
  signal?: AbortSignal,
366
+ stopScanAfterCollect = false,
307
367
  ): Promise<{
308
368
  lines: string[];
309
369
  totalFileLines: number;
@@ -312,6 +372,8 @@ async function streamLinesFromFile(
312
372
  firstLinePreview?: { text: string; bytes: number };
313
373
  firstLineByteLength?: number;
314
374
  selectedBytesTotal: number;
375
+ /** False when `stopScanAfterCollect` cut the scan short — `totalFileLines` is then a lower bound. */
376
+ reachedEof: boolean;
315
377
  }> {
316
378
  const bufferChunk = Buffer.allocUnsafe(READ_CHUNK_SIZE);
317
379
  const collectedLines: string[] = [];
@@ -319,6 +381,7 @@ async function streamLinesFromFile(
319
381
  let collectedBytes = 0;
320
382
  let stoppedByByteLimit = false;
321
383
  let doneCollecting = false;
384
+ let reachedEof = true;
322
385
  let fileHandle: fs.FileHandle | null = null;
323
386
  let currentLineLength = 0;
324
387
  let currentLineChunks: Buffer[] = [];
@@ -433,6 +496,30 @@ async function streamLinesFromFile(
433
496
  const chunk = bufferChunk.subarray(0, bytesRead);
434
497
  endedWithNewline = chunk[bytesRead - 1] === 0x0a;
435
498
 
499
+ // Once collection and selected-line accounting are both finished, the
500
+ // remaining scan only computes `totalFileLines` — count newlines with
501
+ // native indexOf instead of the per-byte JS loop (a multi-GB tail
502
+ // otherwise stalls the read for seconds to minutes).
503
+ if (doneCollecting && selectedLineLimit !== null && selectedLinesSeen >= selectedLineLimit) {
504
+ if (stopScanAfterCollect) {
505
+ reachedEof = false;
506
+ break;
507
+ }
508
+ let searchFrom = 0;
509
+ let newlineAt = chunk.indexOf(0x0a);
510
+ while (newlineAt !== -1) {
511
+ lineIndex++;
512
+ searchFrom = newlineAt + 1;
513
+ newlineAt = chunk.indexOf(0x0a, searchFrom);
514
+ }
515
+ if (searchFrom === 0) {
516
+ currentLineLength += chunk.length;
517
+ } else {
518
+ currentLineLength = chunk.length - searchFrom;
519
+ }
520
+ continue;
521
+ }
522
+
436
523
  let start = 0;
437
524
  for (let i = 0; i < chunk.length; i++) {
438
525
  if (chunk[i] === 0x0a) {
@@ -455,7 +542,7 @@ async function streamLinesFromFile(
455
542
  }
456
543
  }
457
544
 
458
- if (endedWithNewline || currentLineLength > 0 || !sawAnyByte) {
545
+ if (reachedEof && (endedWithNewline || currentLineLength > 0 || !sawAnyByte)) {
459
546
  finalizeLine();
460
547
  }
461
548
 
@@ -473,6 +560,7 @@ async function streamLinesFromFile(
473
560
  firstLinePreview,
474
561
  firstLineByteLength,
475
562
  selectedBytesTotal,
563
+ reachedEof,
476
564
  };
477
565
  }
478
566
 
@@ -486,6 +574,17 @@ function isNotFoundError(error: unknown): boolean {
486
574
  return code === "ENOENT" || code === "ENOTDIR";
487
575
  }
488
576
 
577
+ /**
578
+ * Escape glob metacharacters so a literal path (e.g. `foo[1].ts`) interpolated
579
+ * into a suffix-glob pattern matches itself. Each metachar is wrapped in a
580
+ * character class (the native glob engine rewrites `\` to `/`, so backslash
581
+ * escaping is unavailable). `]`/`}` need no escaping once their openers are
582
+ * neutralized — unmatched closers are literal.
583
+ */
584
+ function escapeGlobMetachars(value: string): string {
585
+ return value.replace(/[*?[{]/g, "[$&]");
586
+ }
587
+
489
588
  /**
490
589
  * Attempt to resolve a non-existent path by finding a unique suffix match within the workspace.
491
590
  * Uses a glob suffix pattern so the native engine handles matching directly.
@@ -498,6 +597,7 @@ async function findUniqueSuffixMatch(
498
597
  ): Promise<{ absolutePath: string; displayPath: string } | null> {
499
598
  const normalized = rawPath.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/+$/, "");
500
599
  if (!normalized) return null;
600
+ const pattern = `**/${escapeGlobMetachars(normalized)}`;
501
601
 
502
602
  const timeoutSignal = AbortSignal.timeout(GLOB_TIMEOUT_MS);
503
603
  const combinedSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;
@@ -506,7 +606,7 @@ async function findUniqueSuffixMatch(
506
606
  try {
507
607
  const result = await untilAborted(combinedSignal, () =>
508
608
  glob({
509
- pattern: `**/${normalized}`,
609
+ pattern,
510
610
  path: cwd,
511
611
  // No fileType filter: matches both files and directories
512
612
  hidden: true,
@@ -530,9 +630,7 @@ async function findUniqueSuffixMatch(
530
630
  }
531
631
 
532
632
  function decodeUtf8Text(bytes: Uint8Array): string | null {
533
- for (const byte of bytes) {
534
- if (byte === 0) return null;
535
- }
633
+ if (bytes.indexOf(0) !== -1) return null;
536
634
 
537
635
  try {
538
636
  return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
@@ -550,7 +648,11 @@ function prependSuffixResolutionNotice(text: string, suffixResolution?: { from:
550
648
 
551
649
  const readSchema = z
552
650
  .object({
553
- path: z.string().describe('path or url; append :<sel> for line ranges or raw mode (e.g. "src/foo.ts:50-100")'),
651
+ path: z
652
+ .string()
653
+ .describe(
654
+ 'Local path, internal URI (e.g. "prometheus://", "issue://123", "pr://123"), or URL; append :<sel> for line ranges or raw mode (e.g. "src/foo.ts:50-100")',
655
+ ),
554
656
  })
555
657
  .strict();
556
658
 
@@ -575,6 +677,8 @@ export interface ReadToolDetails {
575
677
  summary?: { lines: number; elidedSpans: number; elidedLines: number };
576
678
  /** Number of unresolved git conflicts surfaced by this read (TUI uses for inline `⚠ N` badge). */
577
679
  conflictCount?: number;
680
+ /** Paths recovered from a delimited read argument; used only by the TUI to render one call as multiple read rows. */
681
+ displayReadTargets?: string[];
578
682
  }
579
683
 
580
684
  type ReadParams = ReadToolInput;
@@ -657,6 +761,9 @@ interface ResolvedSqliteReadPath {
657
761
  suffixResolution?: { from: string; to: string };
658
762
  }
659
763
 
764
+ /** Per-execute memo of suffix-glob lookups; `null` records a confirmed miss. */
765
+ type SuffixMatchCache = Map<string, { absolutePath: string; displayPath: string } | null>;
766
+
660
767
  /**
661
768
  * Read tool implementation.
662
769
  *
@@ -670,7 +777,6 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
670
777
  readonly loadMode = "essential";
671
778
  readonly description: string;
672
779
  readonly parameters = readSchema;
673
- readonly nonAbortable = true;
674
780
  readonly strict = true;
675
781
 
676
782
  readonly #autoResizeImages: boolean;
@@ -704,6 +810,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
704
810
  const notice = `Note: interpreted as ${parts.length} paths: ${parts.join(", ")}`;
705
811
  const notes = [notice];
706
812
  const content: Array<TextContent | ImageContent> = [];
813
+ const displayReadTargets: string[] = [];
707
814
  let pendingText = notice;
708
815
  const flushText = () => {
709
816
  if (pendingText.length === 0) return;
@@ -717,6 +824,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
717
824
  for (const part of parts) {
718
825
  try {
719
826
  const result = await this.execute("read-delimited-part", { path: part }, signal);
827
+ displayReadTargets.push(result.details?.suffixResolution?.to ?? part);
720
828
  for (const block of result.content) {
721
829
  if (block.type === "text") {
722
830
  appendText(block.text);
@@ -730,15 +838,39 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
730
838
  const message = error instanceof Error ? error.message : String(error);
731
839
  const errorNote = `Could not read ${part}: ${message}`;
732
840
  notes.push(errorNote);
841
+ displayReadTargets.push(part);
733
842
  appendText(`[${errorNote}]`);
734
843
  }
735
844
  }
736
845
  flushText();
737
846
 
738
- return toolResult<ReadToolDetails>({ notes }).content(content).done();
847
+ return toolResult<ReadToolDetails>({ notes, displayReadTargets }).content(content).done();
739
848
  }
740
849
 
741
- async #resolveArchiveReadPath(readPath: string, signal?: AbortSignal): Promise<ResolvedArchiveReadPath | null> {
850
+ /**
851
+ * Memoized {@link findUniqueSuffixMatch} for a single read call. A missing
852
+ * path with archive/sqlite extensions probes the workspace once per stage
853
+ * (archive candidates, sqlite candidates, plain path) — each glob carries a
854
+ * 5s timeout, so repeated lookups of the same string stack into a long
855
+ * stall before erroring. The cache collapses repeats within one execute().
856
+ */
857
+ async #findSuffixMatchCached(
858
+ cache: SuffixMatchCache,
859
+ rawPath: string,
860
+ signal?: AbortSignal,
861
+ ): Promise<{ absolutePath: string; displayPath: string } | null> {
862
+ const hit = cache.get(rawPath);
863
+ if (hit !== undefined) return hit;
864
+ const result = await findUniqueSuffixMatch(rawPath, this.session.cwd, signal);
865
+ cache.set(rawPath, result);
866
+ return result;
867
+ }
868
+
869
+ async #resolveArchiveReadPath(
870
+ readPath: string,
871
+ suffixCache: SuffixMatchCache,
872
+ signal?: AbortSignal,
873
+ ): Promise<ResolvedArchiveReadPath | null> {
742
874
  const candidates = parseArchivePathCandidates(readPath);
743
875
  for (const candidate of candidates) {
744
876
  let absolutePath = resolveReadPath(candidate.archivePath, this.session.cwd);
@@ -755,7 +887,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
755
887
  } catch (error) {
756
888
  if (!isNotFoundError(error) || isRemoteMountPath(absolutePath)) continue;
757
889
 
758
- const suffixMatch = await findUniqueSuffixMatch(candidate.archivePath, this.session.cwd, signal);
890
+ const suffixMatch = await this.#findSuffixMatchCached(suffixCache, candidate.archivePath, signal);
759
891
  if (!suffixMatch) continue;
760
892
 
761
893
  try {
@@ -780,7 +912,11 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
780
912
  return null;
781
913
  }
782
914
 
783
- async #resolveSqliteReadPath(readPath: string, signal?: AbortSignal): Promise<ResolvedSqliteReadPath | null> {
915
+ async #resolveSqliteReadPath(
916
+ readPath: string,
917
+ suffixCache: SuffixMatchCache,
918
+ signal?: AbortSignal,
919
+ ): Promise<ResolvedSqliteReadPath | null> {
784
920
  const candidates = parseSqlitePathCandidates(readPath);
785
921
  for (const candidate of candidates) {
786
922
  let absolutePath = resolveReadPath(candidate.sqlitePath, this.session.cwd);
@@ -800,7 +936,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
800
936
  } catch (error) {
801
937
  if (!isNotFoundError(error) || isRemoteMountPath(absolutePath)) continue;
802
938
 
803
- const suffixMatch = await findUniqueSuffixMatch(candidate.sqlitePath, this.session.cwd, signal);
939
+ const suffixMatch = await this.#findSuffixMatchCached(suffixCache, candidate.sqlitePath, signal);
804
940
  if (!suffixMatch) continue;
805
941
 
806
942
  try {
@@ -911,6 +1047,21 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
911
1047
  emittedHashlineHeader = true;
912
1048
  return prependHashlineHeader(formatted, hashContext);
913
1049
  };
1050
+ const formatLineEntries = (entries: readonly LineEntry[], startNum: number): string => {
1051
+ const firstLine = entries.find(entry => entry.kind === "line");
1052
+ details.displayContent = {
1053
+ text: lineEntriesToPlainText(entries, BRACKET_CONTEXT_ELLIPSIS),
1054
+ startLine: firstLine?.kind === "line" ? firstLine.lineNumber : startNum,
1055
+ };
1056
+ const formatted = formatLineEntriesWithMode(entries, shouldAddHashLines, shouldAddLineNumbers);
1057
+ if (!hashContext || emittedHashlineHeader) return formatted;
1058
+ emittedHashlineHeader = true;
1059
+ return prependHashlineHeader(formatted, hashContext);
1060
+ };
1061
+ const buildLineEntries = (endLineDisplay: number): LineEntry[] =>
1062
+ buildLineEntriesWithBlockContext(allLines, [{ startLine: startLineDisplay, endLine: endLineDisplay }], {
1063
+ path: options.sourcePath,
1064
+ });
914
1065
 
915
1066
  let outputText: string;
916
1067
  let truncationInfo:
@@ -942,7 +1093,12 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
942
1093
  options: { direction: "head", startLine: startLineDisplay, totalFileLines: totalLines },
943
1094
  };
944
1095
  } else if (truncation.truncated) {
945
- outputText = formatText(truncation.content, startLineDisplay);
1096
+ const outputLines = truncation.outputLines ?? countTextLines(truncation.content);
1097
+ const endLineDisplay = startLineDisplay + Math.max(0, outputLines - 1);
1098
+ outputText =
1099
+ options.raw === true
1100
+ ? formatText(truncation.content, startLineDisplay)
1101
+ : formatLineEntries(buildLineEntries(endLineDisplay), startLineDisplay);
946
1102
  details.truncation = truncation;
947
1103
  truncationInfo = {
948
1104
  result: truncation,
@@ -952,10 +1108,16 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
952
1108
  const remaining = allLines.length - (startLine + userLimitedLines);
953
1109
  const nextOffset = startLine + userLimitedLines + 1;
954
1110
 
955
- outputText = formatText(selectedContent, startLineDisplay);
1111
+ outputText =
1112
+ options.raw === true
1113
+ ? formatText(selectedContent, startLineDisplay)
1114
+ : formatLineEntries(buildLineEntries(endLine), startLineDisplay);
956
1115
  outputText += `\n\n[${remaining} more lines in ${options.entityLabel}. Use :${nextOffset} to continue]`;
957
1116
  } else {
958
- outputText = formatText(truncation.content, startLineDisplay);
1117
+ outputText =
1118
+ options.raw === true
1119
+ ? formatText(truncation.content, startLineDisplay)
1120
+ : formatLineEntries(buildLineEntries(endLine), startLineDisplay);
959
1121
  }
960
1122
 
961
1123
  resultBuilder.text(outputText);
@@ -1007,21 +1169,37 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1007
1169
  if (options.sourceUrl) resultBuilder.sourceUrl(options.sourceUrl);
1008
1170
  if (options.sourceInternal) resultBuilder.sourceInternal(options.sourceInternal);
1009
1171
 
1010
- const parts: string[] = [];
1011
1172
  const outOfBounds: LineRange[] = [];
1173
+ const visibleSpans: Array<{ startLine: number; endLine: number }> = [];
1174
+ const rawParts: string[] = [];
1012
1175
  for (const range of ranges) {
1013
1176
  if (range.startLine > totalLines) {
1014
1177
  outOfBounds.push(range);
1015
1178
  continue;
1016
1179
  }
1017
1180
  const effectiveEnd = Math.min(range.endLine ?? totalLines, totalLines);
1018
- const sliced = allLines.slice(range.startLine - 1, effectiveEnd).join("\n");
1019
- const formatted = formatTextWithMode(sliced, range.startLine, shouldAddHashLines, shouldAddLineNumbers);
1020
- parts.push(hashContext && !emittedHashlineHeader ? prependHashlineHeader(formatted, hashContext) : formatted);
1021
- if (hashContext) emittedHashlineHeader = true;
1181
+ visibleSpans.push({ startLine: range.startLine, endLine: effectiveEnd });
1182
+ if (options.raw === true) {
1183
+ rawParts.push(allLines.slice(range.startLine - 1, effectiveEnd).join("\n"));
1184
+ }
1022
1185
  }
1023
1186
 
1024
- const outputText = parts.length > 0 ? parts.join("\n\n…\n\n") : "";
1187
+ let outputText = "";
1188
+ if (options.raw === true) {
1189
+ outputText = rawParts.length > 0 ? rawParts.join("\n\n…\n\n") : "";
1190
+ } else if (visibleSpans.length > 0) {
1191
+ const entries = buildLineEntriesWithBlockContext(allLines, visibleSpans, { path: options.sourcePath });
1192
+ const firstLine = entries.find(entry => entry.kind === "line");
1193
+ if (firstLine?.kind === "line") {
1194
+ details.displayContent = {
1195
+ text: lineEntriesToPlainText(entries, BRACKET_CONTEXT_ELLIPSIS),
1196
+ startLine: firstLine.lineNumber,
1197
+ };
1198
+ }
1199
+ const formatted = formatLineEntriesWithMode(entries, shouldAddHashLines, shouldAddLineNumbers);
1200
+ outputText = hashContext && !emittedHashlineHeader ? prependHashlineHeader(formatted, hashContext) : formatted;
1201
+ if (hashContext) emittedHashlineHeader = true;
1202
+ }
1025
1203
  const notices: string[] = [];
1026
1204
  for (const range of outOfBounds) {
1027
1205
  const bound = range.endLine !== undefined ? `${range.startLine}-${range.endLine}` : `${range.startLine}`;
@@ -1042,6 +1220,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1042
1220
  async #readLocalFileMultiRange(
1043
1221
  absolutePath: string,
1044
1222
  ranges: readonly LineRange[],
1223
+ fileSize: number,
1045
1224
  parsed: ParsedSelector,
1046
1225
  displayMode: { hashLines: boolean; lineNumbers: boolean },
1047
1226
  suffixResolution: { from: string; to: string } | undefined,
@@ -1049,6 +1228,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1049
1228
  ): Promise<{
1050
1229
  outputText: string;
1051
1230
  columnTruncated: number;
1231
+ displayContent?: { text: string; startLine: number };
1052
1232
  bridgeResult?: AgentToolResult<ReadToolDetails>;
1053
1233
  }> {
1054
1234
  const rawSelector = isRawSelector(parsed);
@@ -1081,23 +1261,39 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1081
1261
 
1082
1262
  const blocks: string[] = [];
1083
1263
  const notices: string[] = [];
1264
+ const visibleSpans: Array<{ startLine: number; endLine: number }> = [];
1265
+ const displayLineByNumber = new Map<number, string>();
1266
+ const fullLines = rawSelector ? undefined : await readBracketContextFullLines(absolutePath, fileSize);
1084
1267
  let columnTruncated = 0;
1268
+ let displayContent: { text: string; startLine: number } | undefined;
1085
1269
 
1086
1270
  for (const range of ranges) {
1087
1271
  const rangeStart = range.startLine - 1; // 0-indexed
1088
1272
  const requestedLength = range.endLine !== undefined ? range.endLine - range.startLine + 1 : this.#defaultLimit;
1089
1273
  const maxLines = Math.min(requestedLength, DEFAULT_MAX_LINES);
1090
- const maxBytesForRead = Math.max(DEFAULT_MAX_BYTES, maxLines * 512);
1091
1274
 
1092
- const streamResult = await streamLinesFromFile(
1093
- absolutePath,
1094
- rangeStart,
1095
- maxLines,
1096
- maxBytesForRead,
1097
- maxLines,
1098
- signal,
1099
- );
1100
- const totalFileLines = streamResult.totalFileLines;
1275
+ // When the full file is already in memory (the common case for files
1276
+ // within the snapshot byte cap), slice ranges from it instead of
1277
+ // re-streaming the file once per range.
1278
+ let collectedLines: string[];
1279
+ let totalFileLines: number;
1280
+ if (fullLines) {
1281
+ totalFileLines = fullLines.length;
1282
+ collectedLines = fullLines.slice(rangeStart, rangeStart + maxLines);
1283
+ } else {
1284
+ const maxBytesForRead = Math.max(DEFAULT_MAX_BYTES, maxLines * 512);
1285
+ const streamResult = await streamLinesFromFile(
1286
+ absolutePath,
1287
+ rangeStart,
1288
+ maxLines,
1289
+ maxBytesForRead,
1290
+ maxLines,
1291
+ signal,
1292
+ fileSize > SNAPSHOT_MAX_BYTES, // giant file: collected ranges don't need an exact EOF line count
1293
+ );
1294
+ totalFileLines = streamResult.totalFileLines;
1295
+ collectedLines = streamResult.lines;
1296
+ }
1101
1297
 
1102
1298
  if (rangeStart >= totalFileLines) {
1103
1299
  const bound = range.endLine !== undefined ? `${range.startLine}-${range.endLine}` : `${range.startLine}`;
@@ -1105,7 +1301,6 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1105
1301
  continue;
1106
1302
  }
1107
1303
 
1108
- const collectedLines = streamResult.lines;
1109
1304
  // Column truncation is display-only; clone before stamping ellipsis so
1110
1305
  // the original on-disk lines stay intact for display reconstruction.
1111
1306
  let displayLines: string[] = collectedLines;
@@ -1121,11 +1316,43 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1121
1316
  }
1122
1317
  if (cloned) displayLines = cloned;
1123
1318
  }
1124
- const blockText = displayLines.join("\n");
1125
- blocks.push(formatTextWithMode(blockText, range.startLine, shouldAddHashLines, shouldAddLineNumbers));
1319
+ const endLine = range.startLine + Math.max(0, displayLines.length - 1);
1320
+ visibleSpans.push({ startLine: range.startLine, endLine });
1321
+ for (let i = 0; i < displayLines.length; i++) {
1322
+ displayLineByNumber.set(range.startLine + i, displayLines[i] ?? "");
1323
+ }
1324
+ if (!fullLines || rawSelector) {
1325
+ const blockText = displayLines.join("\n");
1326
+ blocks.push(formatTextWithMode(blockText, range.startLine, shouldAddHashLines, shouldAddLineNumbers));
1327
+ }
1126
1328
  }
1127
1329
 
1128
- let outputText = blocks.join("\n\n…\n\n");
1330
+ let outputText: string;
1331
+ if (!rawSelector && fullLines && visibleSpans.length > 0) {
1332
+ const entries = buildLineEntriesWithBlockContext(
1333
+ fullLines,
1334
+ visibleSpans,
1335
+ { path: absolutePath },
1336
+ {
1337
+ lineText: (lineNumber, sourceText) => {
1338
+ const visibleText = displayLineByNumber.get(lineNumber);
1339
+ if (visibleText !== undefined) return visibleText;
1340
+ if (maxColumns <= 0) return sourceText;
1341
+ const truncated = truncateLine(sourceText, maxColumns);
1342
+ if (truncated.wasTruncated) columnTruncated = maxColumns;
1343
+ return truncated.text;
1344
+ },
1345
+ },
1346
+ );
1347
+ const firstLine = entries.find(entry => entry.kind === "line");
1348
+ displayContent = {
1349
+ text: lineEntriesToPlainText(entries, BRACKET_CONTEXT_ELLIPSIS),
1350
+ startLine: firstLine?.kind === "line" ? firstLine.lineNumber : (visibleSpans[0]?.startLine ?? 1),
1351
+ };
1352
+ outputText = formatLineEntriesWithMode(entries, shouldAddHashLines, shouldAddLineNumbers);
1353
+ } else {
1354
+ outputText = blocks.join("\n\n…\n\n");
1355
+ }
1129
1356
  if (shouldAddHashLines && outputText) {
1130
1357
  const tag = await recordFileSnapshot(this.session, absolutePath);
1131
1358
  if (tag) {
@@ -1135,36 +1362,33 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1135
1362
  if (notices.length > 0) {
1136
1363
  outputText = outputText ? `${outputText}\n${notices.join("\n")}` : notices.join("\n");
1137
1364
  }
1138
- return { outputText, columnTruncated };
1365
+ return { outputText, columnTruncated, displayContent };
1139
1366
  }
1140
1367
 
1141
1368
  async #readArchiveDirectory(
1142
1369
  archive: ArchiveReader,
1143
1370
  archivePath: string,
1144
1371
  subPath: string,
1372
+ offset: number | undefined,
1145
1373
  limit: number | undefined,
1146
1374
  details: ReadToolDetails,
1147
1375
  signal?: AbortSignal,
1148
1376
  ): Promise<AgentToolResult<ReadToolDetails>> {
1149
1377
  const DEFAULT_LIMIT = 500;
1150
1378
  const effectiveLimit = limit ?? DEFAULT_LIMIT;
1151
- const entries = archive.listDirectory(subPath);
1379
+ const allEntries = archive.listDirectory(subPath);
1380
+ // `offset` is 1-indexed (line-selector semantics): `a.zip:dir:50` starts
1381
+ // the listing at the 50th entry instead of being silently ignored.
1382
+ const entries = offset !== undefined && offset > 1 ? allEntries.slice(offset - 1) : allEntries;
1152
1383
 
1153
1384
  const listLimit = applyListLimit(entries, { limit: effectiveLimit });
1154
1385
  const limitedEntries = listLimit.items;
1155
1386
  const limitMeta = listLimit.meta;
1156
1387
 
1157
- const results: string[] = [];
1158
- for (const entry of limitedEntries) {
1388
+ for (let index = 0; index < limitedEntries.length; index++) {
1159
1389
  throwIfAborted(signal);
1160
- if (entry.isDirectory) {
1161
- results.push(`${entry.name}/`);
1162
- continue;
1163
- }
1164
-
1165
- const sizeSuffix = entry.size > 0 ? ` (${formatBytes(entry.size)})` : "";
1166
- results.push(`${entry.name}${sizeSuffix}`);
1167
1390
  }
1391
+ const results = formatArchiveEntryLines(limitedEntries);
1168
1392
 
1169
1393
  const output = results.length > 0 ? results.join("\n") : "(empty archive directory)";
1170
1394
  const text = prependSuffixResolutionNotice(output, details.suffixResolution);
@@ -1194,27 +1418,41 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1194
1418
  suffixResolution: resolvedArchivePath.suffixResolution,
1195
1419
  };
1196
1420
 
1197
- const node = archive.getNode(resolvedArchivePath.archiveSubPath);
1421
+ let archiveSubPath = resolvedArchivePath.archiveSubPath;
1422
+ let sel = parsedSel;
1423
+ let node = archive.getNode(archiveSubPath);
1424
+ if (!node && archiveSubPath) {
1425
+ // `archive.zip:500` / `archive.zip:raw`: the whole subPath is a
1426
+ // selector on the archive root, not a member name. Member names take
1427
+ // precedence (getNode above); fall back to root + selector.
1428
+ const wholeSel = parseSel(archiveSubPath);
1429
+ if (wholeSel.kind !== "none") {
1430
+ node = archive.getNode("");
1431
+ archiveSubPath = "";
1432
+ sel = wholeSel;
1433
+ }
1434
+ }
1198
1435
  if (!node) {
1199
1436
  throw new ToolError(`Path '${readPath}' not found inside archive`);
1200
1437
  }
1201
1438
 
1202
1439
  if (node.isDirectory) {
1203
- if (isMultiRange(parsedSel)) {
1440
+ if (isMultiRange(sel)) {
1204
1441
  throw new ToolError("Multi-range line selectors are not supported for archive directory listings.");
1205
1442
  }
1206
- const { limit } = selToOffsetLimit(parsedSel);
1443
+ const { offset, limit } = selToOffsetLimit(sel);
1207
1444
  return this.#readArchiveDirectory(
1208
1445
  archive,
1209
1446
  resolvedArchivePath.absolutePath,
1210
- resolvedArchivePath.archiveSubPath,
1447
+ archiveSubPath,
1448
+ offset,
1211
1449
  limit,
1212
1450
  details,
1213
1451
  signal,
1214
1452
  );
1215
1453
  }
1216
1454
 
1217
- const entry = await archive.readFile(resolvedArchivePath.archiveSubPath);
1455
+ const entry = await archive.readFile(archiveSubPath);
1218
1456
  const text = decodeUtf8Text(entry.bytes);
1219
1457
  if (text === null) {
1220
1458
  return toolResult<ReadToolDetails>(details)
@@ -1228,26 +1466,26 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1228
1466
  .done();
1229
1467
  }
1230
1468
 
1231
- const raw = isRawSelector(parsedSel);
1469
+ // Archive members are immutable: there is no edit path for bytes inside
1470
+ // an archive, and a hashline tag keyed to the archive file would invite
1471
+ // (and fail) edits while clobbering sibling members' snapshots.
1472
+ const raw = isRawSelector(sel);
1232
1473
  const result =
1233
- isMultiRange(parsedSel) && parsedSel.kind === "lines"
1234
- ? this.#buildInMemoryMultiRangeResult(text, parsedSel.ranges, {
1474
+ isMultiRange(sel) && sel.kind === "lines"
1475
+ ? this.#buildInMemoryMultiRangeResult(text, sel.ranges, {
1235
1476
  details,
1236
1477
  sourcePath: resolvedArchivePath.absolutePath,
1237
1478
  entityLabel: "archive entry",
1238
1479
  raw,
1480
+ immutable: true,
1239
1481
  })
1240
- : this.#buildInMemoryTextResult(
1241
- text,
1242
- selToOffsetLimit(parsedSel).offset,
1243
- selToOffsetLimit(parsedSel).limit,
1244
- {
1245
- details,
1246
- sourcePath: resolvedArchivePath.absolutePath,
1247
- entityLabel: "archive entry",
1248
- raw,
1249
- },
1250
- );
1482
+ : this.#buildInMemoryTextResult(text, selToOffsetLimit(sel).offset, selToOffsetLimit(sel).limit, {
1483
+ details,
1484
+ sourcePath: resolvedArchivePath.absolutePath,
1485
+ entityLabel: "archive entry",
1486
+ raw,
1487
+ immutable: true,
1488
+ });
1251
1489
  const firstText = result.content.find((content): content is TextContent => content.type === "text");
1252
1490
  if (firstText) {
1253
1491
  firstText.text = prependSuffixResolutionNotice(firstText.text, resolvedArchivePath.suffixResolution);
@@ -1352,19 +1590,18 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1352
1590
  }
1353
1591
  case "raw": {
1354
1592
  const result = executeReadQuery(db, selector.sql);
1593
+ let output = renderTable(result.columns, result.rows, {
1594
+ totalCount: result.rows.length,
1595
+ offset: 0,
1596
+ limit: result.rows.length || DEFAULT_MAX_LINES,
1597
+ table: "query",
1598
+ dbPath: resolvedSqlitePath.absolutePath,
1599
+ });
1600
+ if (result.truncated) {
1601
+ output += `\n[Output capped at ${MAX_RAW_QUERY_ROWS} rows; add a LIMIT/OFFSET clause to the query to page through more]`;
1602
+ }
1355
1603
  return toolResult<ReadToolDetails>(details)
1356
- .text(
1357
- prependSuffixResolutionNotice(
1358
- renderTable(result.columns, result.rows, {
1359
- totalCount: result.rows.length,
1360
- offset: 0,
1361
- limit: result.rows.length || DEFAULT_MAX_LINES,
1362
- table: "query",
1363
- dbPath: resolvedSqlitePath.absolutePath,
1364
- }),
1365
- resolvedSqlitePath.suffixResolution,
1366
- ),
1367
- )
1604
+ .text(prependSuffixResolutionNotice(output, resolvedSqlitePath.suffixResolution))
1368
1605
  .sourcePath(resolvedSqlitePath.absolutePath)
1369
1606
  .done();
1370
1607
  }
@@ -1405,15 +1642,25 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1405
1642
  if (lineCount > MAX_SUMMARY_LINES) return null;
1406
1643
  if (lineCount < this.session.settings.get("read.summarize.minTotalLines")) return null;
1407
1644
 
1645
+ const minBodyLines = this.session.settings.get("read.summarize.minBodyLines");
1646
+ const minCommentLines = this.session.settings.get("read.summarize.minCommentLines");
1647
+ const unfoldUntilLines = this.session.settings.get("read.summarize.unfoldUntil");
1648
+ const unfoldLimitLines = this.session.settings.get("read.summarize.unfoldLimit");
1649
+ const cache = getSummaryParseCache(this.session);
1650
+ const cacheKey = `${absolutePath}\0${Bun.hash(code)}\0${minBodyLines},${minCommentLines},${unfoldUntilLines},${unfoldLimitLines}`;
1651
+ const memoized = cache.get(cacheKey);
1652
+ if (memoized !== undefined) return memoized || null;
1408
1653
  const result = summarizeCode({
1409
1654
  code,
1410
1655
  path: absolutePath,
1411
- minBodyLines: this.session.settings.get("read.summarize.minBodyLines"),
1412
- minCommentLines: this.session.settings.get("read.summarize.minCommentLines"),
1413
- unfoldUntilLines: this.session.settings.get("read.summarize.unfoldUntil"),
1414
- unfoldLimitLines: this.session.settings.get("read.summarize.unfoldLimit"),
1656
+ minBodyLines,
1657
+ minCommentLines,
1658
+ unfoldUntilLines,
1659
+ unfoldLimitLines,
1415
1660
  });
1416
- return result;
1661
+ const usable = result.parsed && result.elided ? result : false;
1662
+ cache.set(cacheKey, usable);
1663
+ return usable || null;
1417
1664
  } catch {
1418
1665
  return null;
1419
1666
  }
@@ -1589,10 +1836,19 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1589
1836
  if (internalRouter.canHandle(readPath)) {
1590
1837
  const internalTarget = splitInternalUrlSel(readPath);
1591
1838
  const parsed = parseSel(internalTarget.sel);
1839
+ if (internalTarget.sel !== undefined && parsed.kind === "none") {
1840
+ throw new ToolError(
1841
+ `Invalid selector ':${internalTarget.sel}' on '${internalTarget.path}'. Use :N, :N-M, :N+K, :N- (open-ended), a comma-separated list of ranges, :raw, or a range combined with raw (e.g. :raw:50-100).`,
1842
+ );
1843
+ }
1592
1844
  return this.#handleInternalUrl(internalTarget.path, parsed, signal);
1593
1845
  }
1594
1846
 
1595
- const archivePath = await this.#resolveArchiveReadPath(readPath, signal);
1847
+ // One suffix-glob memo per read call — archive, sqlite, and plain-path
1848
+ // resolution share misses instead of re-globbing the workspace.
1849
+ const suffixCache: SuffixMatchCache = new Map();
1850
+
1851
+ const archivePath = await this.#resolveArchiveReadPath(readPath, suffixCache, signal);
1596
1852
  if (archivePath) {
1597
1853
  const archiveSubPath = splitPathAndSel(archivePath.archiveSubPath);
1598
1854
  const archiveParsed = parseSel(archiveSubPath.sel);
@@ -1604,7 +1860,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1604
1860
  );
1605
1861
  }
1606
1862
 
1607
- const sqlitePath = await this.#resolveSqliteReadPath(readPath, signal);
1863
+ const sqlitePath = await this.#resolveSqliteReadPath(readPath, suffixCache, signal);
1608
1864
  if (sqlitePath) {
1609
1865
  return this.#readSqlite(sqlitePath, signal);
1610
1866
  }
@@ -1626,7 +1882,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1626
1882
  if (isNotFoundError(error)) {
1627
1883
  // Attempt unique suffix resolution before falling back to fuzzy suggestions
1628
1884
  if (!isRemoteMountPath(absolutePath)) {
1629
- const suffixMatch = await findUniqueSuffixMatch(localReadPath, this.session.cwd, signal);
1885
+ const suffixMatch = await this.#findSuffixMatchCached(suffixCache, localReadPath, signal);
1630
1886
  if (suffixMatch) {
1631
1887
  try {
1632
1888
  const retryStat = await Bun.file(suffixMatch.absolutePath).stat();
@@ -1655,7 +1911,9 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1655
1911
  throw new ToolError("Multi-range line selectors are not supported for directory listings.");
1656
1912
  }
1657
1913
  const { offset, limit } = selToOffsetLimit(parsed);
1658
- const dirResult = await this.#readDirectory(absolutePath, offset, limit, signal);
1914
+ // Directory listings are deterministic and fast; never abort them mid-scan
1915
+ // (an interrupt would otherwise surface a misleading "Operation aborted").
1916
+ const dirResult = await this.#readDirectory(absolutePath, offset, limit, undefined);
1659
1917
  if (suffixResolution) {
1660
1918
  dirResult.details ??= {};
1661
1919
  dirResult.details.suffixResolution = suffixResolution;
@@ -1721,6 +1979,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1721
1979
  maxBytes: MAX_IMAGE_SIZE,
1722
1980
  resolvedPath: absolutePath,
1723
1981
  detectedMimeType: mimeType,
1982
+ excludeWebP: webpExclusionForModel(this.session.getActiveModel?.()),
1724
1983
  });
1725
1984
  if (!imageInput) {
1726
1985
  throw new ToolError(`Read image file [${mimeType}] failed: unsupported image format.`);
@@ -1757,15 +2016,25 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1757
2016
  // Convert document via markit.
1758
2017
  const result = await convertFileWithMarkit(absolutePath, signal);
1759
2018
  if (result.ok) {
1760
- // Apply truncation to converted content
1761
- const truncation = truncateHead(result.content);
1762
- const outputText = truncation.content;
1763
-
1764
- details = { truncation };
1765
- sourcePath = absolutePath;
1766
- truncationInfo = { result: truncation, options: { direction: "head", startLine: 1 } };
1767
-
1768
- content = [{ type: "text", text: outputText }];
2019
+ // Route the converted markdown through the in-memory text builder
2020
+ // so line-range selectors (`file.pdf:50-100`, `:5-16,40-80`) and
2021
+ // raw mode apply against the converted output. Without this,
2022
+ // `file.pdf:50-100` silently returned the head of the document
2023
+ // because only `truncateHead` was being applied.
2024
+ if (isMultiRange(parsed) && parsed.kind === "lines") {
2025
+ return this.#buildInMemoryMultiRangeResult(result.content, parsed.ranges, {
2026
+ details: { resolvedPath: absolutePath },
2027
+ sourcePath: absolutePath,
2028
+ entityLabel: "document",
2029
+ });
2030
+ }
2031
+ const { offset, limit } = selToOffsetLimit(parsed);
2032
+ return this.#buildInMemoryTextResult(result.content, offset, limit, {
2033
+ details: { resolvedPath: absolutePath },
2034
+ sourcePath: absolutePath,
2035
+ entityLabel: "document",
2036
+ raw: isRawSelector(parsed),
2037
+ });
1769
2038
  } else if (result.error) {
1770
2039
  content = [{ type: "text", text: `[Cannot read ${ext} file: ${result.error || "conversion failed"}]` }];
1771
2040
  } else {
@@ -1809,15 +2078,16 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1809
2078
  const multiResult = await this.#readLocalFileMultiRange(
1810
2079
  absolutePath,
1811
2080
  parsed.ranges,
2081
+ fileSize,
1812
2082
  parsed,
1813
2083
  displayMode,
1814
2084
  suffixResolution,
1815
- signal,
2085
+ undefined, // plain-file read: deterministic and fast, never abort mid-read
1816
2086
  );
1817
2087
  if (multiResult.bridgeResult) return multiResult.bridgeResult;
1818
2088
  content = [{ type: "text", text: multiResult.outputText }];
1819
2089
  sourcePath = absolutePath;
1820
- details = {};
2090
+ details = multiResult.displayContent ? { displayContent: multiResult.displayContent } : {};
1821
2091
  if (multiResult.columnTruncated > 0) {
1822
2092
  columnTruncated = multiResult.columnTruncated;
1823
2093
  }
@@ -1871,7 +2141,8 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1871
2141
  maxLinesToCollect,
1872
2142
  maxBytesForRead,
1873
2143
  selectedLineLimit,
1874
- signal,
2144
+ undefined, // plain-file read: deterministic and fast, never abort mid-read
2145
+ fileSize > SNAPSHOT_MAX_BYTES, // giant file: don't scan to EOF just for an exact line count
1875
2146
  );
1876
2147
 
1877
2148
  const {
@@ -1881,6 +2152,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1881
2152
  stoppedByByteLimit,
1882
2153
  firstLinePreview,
1883
2154
  firstLineByteLength,
2155
+ reachedEof,
1884
2156
  } = streamResult;
1885
2157
 
1886
2158
  // Check if offset is out of bounds - return graceful message instead of throwing
@@ -1901,6 +2173,25 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1901
2173
  // counts in `truncation` keep reflecting the source, not the trimmed
1902
2174
  // view — column truncation surfaces separately via `.limits()`.
1903
2175
  const rawSelector = isRawSelector(parsed);
2176
+ // Binary sniff: NUL bytes in the collected window mean the file is
2177
+ // not displayable text (binary, or UTF-16 which has NULs in the
2178
+ // ASCII range) — emit a notice instead of mojibake filling the
2179
+ // line budget. `:raw` stays an explicit escape hatch.
2180
+ if (!rawSelector) {
2181
+ for (const line of collectedLines) {
2182
+ if (line.includes("\u0000")) {
2183
+ return toolResult<ReadToolDetails>({ resolvedPath: absolutePath, suffixResolution })
2184
+ .text(
2185
+ prependSuffixResolutionNotice(
2186
+ `[Cannot read binary file '${formatPathRelativeToCwd(absolutePath, this.session.cwd)}' (${formatBytes(fileSize)}); content contains NUL bytes (binary or UTF-16 encoded)]`,
2187
+ suffixResolution,
2188
+ ),
2189
+ )
2190
+ .sourcePath(absolutePath)
2191
+ .done();
2192
+ }
2193
+ }
2194
+ }
1904
2195
  const maxColumns = resolveOutputMaxColumns(this.session.settings);
1905
2196
  // Column truncation is display-only. `collectedLines` MUST stay
1906
2197
  // byte-for-byte with the on-disk content so the snapshot recorded
@@ -1921,6 +2212,15 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1921
2212
  if (cloned) displayLines = cloned;
1922
2213
  }
1923
2214
 
2215
+ const displayLineByNumber = new Map<number, string>();
2216
+ for (let i = 0; i < displayLines.length; i++) {
2217
+ displayLineByNumber.set(startLineDisplay + i, displayLines[i] ?? "");
2218
+ }
2219
+ const bracketContextFullLines = rawSelector
2220
+ ? undefined
2221
+ : await readBracketContextFullLines(absolutePath, fileSize);
2222
+ const displayedEndLine = startLineDisplay + Math.max(0, displayLines.length - 1);
2223
+
1924
2224
  const selectedContent = displayLines.join("\n");
1925
2225
  const userLimitedLines = collectedLines.length;
1926
2226
 
@@ -1951,7 +2251,10 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1951
2251
  // full file and any anchor validates while the file is unchanged.
1952
2252
  const isWholeFile = offset === undefined && limit === undefined && !wasTruncated;
1953
2253
  const tag = isWholeFile
1954
- ? getFileSnapshotStore(this.session).record(absolutePath, normalizeToLF(collectedLines.join("\n")))
2254
+ ? getFileSnapshotStore(this.session).record(
2255
+ canonicalSnapshotKey(absolutePath),
2256
+ normalizeToLF(collectedLines.join("\n")),
2257
+ )
1955
2258
  : await recordFileSnapshot(this.session, absolutePath);
1956
2259
  if (tag) {
1957
2260
  hashContext = hashlineHeaderContext(formatPathRelativeToCwd(absolutePath, this.session.cwd), tag);
@@ -1967,6 +2270,33 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1967
2270
  emittedHashlineHeader = true;
1968
2271
  return prependHashlineHeader(formatted, hashContext);
1969
2272
  };
2273
+ const formatBracketAwareText = (): string | undefined => {
2274
+ if (!bracketContextFullLines) return undefined;
2275
+ const entries = buildLineEntriesWithBlockContext(
2276
+ bracketContextFullLines,
2277
+ [{ startLine: startLineDisplay, endLine: displayedEndLine }],
2278
+ { path: absolutePath },
2279
+ {
2280
+ lineText: (lineNumber, sourceText) => {
2281
+ const visibleText = displayLineByNumber.get(lineNumber);
2282
+ if (visibleText !== undefined) return visibleText;
2283
+ if (maxColumns <= 0) return sourceText;
2284
+ const truncated = truncateLine(sourceText, maxColumns);
2285
+ if (truncated.wasTruncated) columnTruncated = maxColumns;
2286
+ return truncated.text;
2287
+ },
2288
+ },
2289
+ );
2290
+ const firstLine = entries.find(entry => entry.kind === "line");
2291
+ capturedDisplayContent = {
2292
+ text: lineEntriesToPlainText(entries, BRACKET_CONTEXT_ELLIPSIS),
2293
+ startLine: firstLine?.kind === "line" ? firstLine.lineNumber : startLineDisplay,
2294
+ };
2295
+ const formatted = formatLineEntriesWithMode(entries, shouldAddHashLines, shouldAddLineNumbers);
2296
+ if (!hashContext || emittedHashlineHeader) return formatted;
2297
+ emittedHashlineHeader = true;
2298
+ return prependHashlineHeader(formatted, hashContext);
2299
+ };
1970
2300
 
1971
2301
  let outputText: string;
1972
2302
 
@@ -1990,27 +2320,36 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
1990
2320
  sourcePath = absolutePath;
1991
2321
  truncationInfo = {
1992
2322
  result: truncation,
1993
- options: { direction: "head", startLine: startLineDisplay, totalFileLines },
2323
+ options: {
2324
+ direction: "head",
2325
+ startLine: startLineDisplay,
2326
+ totalFileLines: reachedEof ? totalFileLines : undefined,
2327
+ },
1994
2328
  };
1995
2329
  } else if (truncation.truncated) {
1996
- outputText = formatText(truncation.content, startLineDisplay);
2330
+ outputText = formatBracketAwareText() ?? formatText(truncation.content, startLineDisplay);
1997
2331
  details = { truncation };
1998
2332
  sourcePath = absolutePath;
1999
2333
  truncationInfo = {
2000
2334
  result: truncation,
2001
- options: { direction: "head", startLine: startLineDisplay, totalFileLines },
2335
+ options: {
2336
+ direction: "head",
2337
+ startLine: startLineDisplay,
2338
+ totalFileLines: reachedEof ? totalFileLines : undefined,
2339
+ },
2002
2340
  };
2003
- } else if (startLine + userLimitedLines < totalFileLines) {
2004
- const remaining = totalFileLines - (startLine + userLimitedLines);
2341
+ } else if (startLine + userLimitedLines < totalFileLines || !reachedEof) {
2005
2342
  const nextOffset = startLine + userLimitedLines + 1;
2006
2343
 
2007
- outputText = formatText(truncation.content, startLineDisplay);
2008
- outputText += `\n\n[${remaining} more lines in file. Use :${nextOffset} to continue]`;
2344
+ outputText = formatBracketAwareText() ?? formatText(truncation.content, startLineDisplay);
2345
+ outputText += reachedEof
2346
+ ? `\n\n[${totalFileLines - (startLine + userLimitedLines)} more lines in file. Use :${nextOffset} to continue]`
2347
+ : `\n\n[More lines in file (${formatBytes(fileSize)} total; not scanned to EOF). Use :${nextOffset} to continue]`;
2009
2348
  details = {};
2010
2349
  sourcePath = absolutePath;
2011
2350
  } else {
2012
2351
  // No truncation, no user limit exceeded
2013
- outputText = formatText(truncation.content, startLineDisplay);
2352
+ outputText = formatBracketAwareText() ?? formatText(truncation.content, startLineDisplay);
2014
2353
  details = {};
2015
2354
  sourcePath = absolutePath;
2016
2355
  }
@@ -2337,10 +2676,20 @@ function firstReadSelectorLine(sel: string | undefined): number | undefined {
2337
2676
  }
2338
2677
  }
2339
2678
 
2679
+ /** Absolute fs path the read result actually resolved to, used as the OSC 8 link
2680
+ * target when the structured `resolvedPath` isn't set (the common plain-file and
2681
+ * image reads only record the path in `meta.source`). URL/internal sources are
2682
+ * not fs paths, so only `type: "path"` qualifies. */
2683
+ function readSourceFsPath(details: ReadToolDetails | undefined): string | undefined {
2684
+ const source = details?.meta?.source;
2685
+ return source?.type === "path" ? source.value : undefined;
2686
+ }
2687
+
2340
2688
  function formatReadPathLink(
2341
2689
  rawPath: string,
2342
2690
  options: {
2343
2691
  resolvedPath?: string;
2692
+ sourcePath?: string;
2344
2693
  suffixResolution?: { from: string; to: string };
2345
2694
  offset?: number;
2346
2695
  fallbackLabel?: string;
@@ -2352,11 +2701,13 @@ function formatReadPathLink(
2352
2701
  const plainDisplayPath = options.suffixResolution
2353
2702
  ? shortenPath(options.suffixResolution.to)
2354
2703
  : shortenPath(basePath || options.resolvedPath || options.fallbackLabel || rawPath);
2355
- const target = options.resolvedPath ?? tryResolveInternalUrlSync(basePath);
2704
+ const absoluteInputPath = path.isAbsolute(basePath) ? basePath : undefined;
2705
+ const target =
2706
+ options.resolvedPath ?? options.sourcePath ?? tryResolveInternalUrlSync(basePath) ?? absoluteInputPath;
2356
2707
  const line = firstReadSelectorLine(split.sel) ?? options.offset;
2357
2708
  const linkOptions = line !== undefined ? { line } : undefined;
2358
- const displayPath = target ? fileHyperlink(target, plainDisplayPath, linkOptions) : plainDisplayPath;
2359
- return `${displayPath}${selectorSuffix}`;
2709
+ const linkedPath = target ? fileHyperlink(target, plainDisplayPath, linkOptions) : plainDisplayPath;
2710
+ return `${linkedPath}${selectorSuffix}`;
2360
2711
  }
2361
2712
 
2362
2713
  export const readToolRenderer = {
@@ -2403,7 +2754,9 @@ export const readToolRenderer = {
2403
2754
  const rawErrorText = result.content?.find(c => c.type === "text")?.text ?? "";
2404
2755
  const errorText = (rawErrorText || "Unknown error").replace(/^Error:\s*/, "");
2405
2756
  const rawPath = args?.file_path || args?.path || "";
2406
- const filePath = formatReadPathLink(rawPath, { offset: args?.offset }) || shortenPath(rawPath);
2757
+ const filePath =
2758
+ formatReadPathLink(rawPath, { offset: args?.offset, sourcePath: readSourceFsPath(result.details) }) ||
2759
+ shortenPath(rawPath);
2407
2760
  let title = filePath ? `Read ${filePath}` : "Read";
2408
2761
  if (args?.offset !== undefined || args?.limit !== undefined) {
2409
2762
  const startLine = args.offset ?? 1;
@@ -2454,6 +2807,7 @@ export const readToolRenderer = {
2454
2807
  const suffix = details?.suffixResolution;
2455
2808
  const displayPath = formatReadPathLink(rawPath, {
2456
2809
  resolvedPath: details?.resolvedPath,
2810
+ sourcePath: readSourceFsPath(details),
2457
2811
  suffixResolution: suffix,
2458
2812
  fallbackLabel: "image",
2459
2813
  });
@@ -2486,12 +2840,13 @@ export const readToolRenderer = {
2486
2840
  }
2487
2841
 
2488
2842
  const suffix = details?.suffixResolution;
2489
- // resolvedPath is the absolute fs path for fs-backed reads (regular files plus
2490
- // local:// / memory:// / skill:// / artifact:// resources). Fall back to a sync
2491
- // resolver for fs-backed internal URLs so the title is clickable even before the
2492
- // result lands or if the handler didn't populate resolvedPath.
2843
+ // resolvedPath is the absolute fs path when a read resolved/corrected the
2844
+ // input (suffix match, internal URL, archive/sqlite/notebook); plain file
2845
+ // reads only record the absolute path in meta.source, so fall back to that
2846
+ // (and then to a sync internal-URL resolver) to keep the title clickable.
2493
2847
  const displayPath = formatReadPathLink(rawPath, {
2494
2848
  resolvedPath: details?.resolvedPath,
2849
+ sourcePath: readSourceFsPath(details),
2495
2850
  suffixResolution: suffix,
2496
2851
  offset: args?.offset,
2497
2852
  });