oma-coding-agent 1.1.4

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 (1298) hide show
  1. package/CHANGELOG.md +12164 -0
  2. package/README.md +35 -0
  3. package/dist/cli.js +18266 -0
  4. package/examples/README.md +21 -0
  5. package/examples/custom-tools/README.md +104 -0
  6. package/examples/custom-tools/hello/index.ts +20 -0
  7. package/examples/extensions/README.md +142 -0
  8. package/examples/extensions/api-demo.ts +79 -0
  9. package/examples/extensions/chalk-logger.ts +25 -0
  10. package/examples/extensions/hello.ts +31 -0
  11. package/examples/extensions/pirate.ts +43 -0
  12. package/examples/extensions/plan-mode.ts +549 -0
  13. package/examples/extensions/reload-runtime.ts +38 -0
  14. package/examples/extensions/thinking-note.ts +13 -0
  15. package/examples/extensions/tools.ts +145 -0
  16. package/examples/extensions/with-deps/index.ts +36 -0
  17. package/examples/extensions/with-deps/package-lock.json +31 -0
  18. package/examples/extensions/with-deps/package.json +17 -0
  19. package/examples/hooks/README.md +56 -0
  20. package/examples/hooks/auto-commit-on-exit.ts +48 -0
  21. package/examples/hooks/confirm-destructive.ts +58 -0
  22. package/examples/hooks/custom-compaction.ts +115 -0
  23. package/examples/hooks/dirty-repo-guard.ts +51 -0
  24. package/examples/hooks/file-trigger.ts +40 -0
  25. package/examples/hooks/git-checkpoint.ts +52 -0
  26. package/examples/hooks/handoff.ts +149 -0
  27. package/examples/hooks/permission-gate.ts +33 -0
  28. package/examples/hooks/protected-paths.ts +29 -0
  29. package/examples/hooks/qna.ts +118 -0
  30. package/examples/hooks/status-line.ts +39 -0
  31. package/examples/sdk/01-minimal.ts +21 -0
  32. package/examples/sdk/02-custom-model.ts +49 -0
  33. package/examples/sdk/03-custom-prompt.ts +46 -0
  34. package/examples/sdk/04-skills.ts +43 -0
  35. package/examples/sdk/06-extensions.ts +82 -0
  36. package/examples/sdk/06-hooks.ts +61 -0
  37. package/examples/sdk/07-context-files.ts +35 -0
  38. package/examples/sdk/08-prompt-templates.ts +41 -0
  39. package/examples/sdk/08-slash-commands.ts +46 -0
  40. package/examples/sdk/09-api-keys-and-oauth.ts +54 -0
  41. package/examples/sdk/11-sessions.ts +47 -0
  42. package/examples/sdk/12-redis-sessions.ts +54 -0
  43. package/examples/sdk/13-sql-sessions.ts +61 -0
  44. package/examples/sdk/README.md +172 -0
  45. package/package.json +573 -0
  46. package/scripts/bench-guard.ts +71 -0
  47. package/scripts/build-binary.ts +108 -0
  48. package/scripts/bundle-dist.ts +110 -0
  49. package/scripts/embed-mupdf-wasm.ts +67 -0
  50. package/scripts/format-prompts.ts +68 -0
  51. package/scripts/generate-docs-index.ts +56 -0
  52. package/scripts/generate-share-viewer.ts +34 -0
  53. package/scripts/measure-prompt-tokens.ts +63 -0
  54. package/scripts/omp +42 -0
  55. package/scripts/omp.ts +19 -0
  56. package/src/advisor/__tests__/advisor.test.ts +915 -0
  57. package/src/advisor/advise-tool.ts +165 -0
  58. package/src/advisor/index.ts +4 -0
  59. package/src/advisor/runtime.ts +270 -0
  60. package/src/advisor/transcript-recorder.ts +136 -0
  61. package/src/advisor/watchdog.ts +83 -0
  62. package/src/async/index.ts +1 -0
  63. package/src/async/job-manager.ts +674 -0
  64. package/src/auto-thinking/classifier.ts +190 -0
  65. package/src/autolearn/controller.ts +139 -0
  66. package/src/autolearn/managed-skills.ts +255 -0
  67. package/src/autoresearch/command-resume.md +14 -0
  68. package/src/autoresearch/dashboard.ts +436 -0
  69. package/src/autoresearch/git.ts +319 -0
  70. package/src/autoresearch/helpers.ts +218 -0
  71. package/src/autoresearch/index.ts +536 -0
  72. package/src/autoresearch/prompt-setup.md +43 -0
  73. package/src/autoresearch/prompt.md +103 -0
  74. package/src/autoresearch/resume-message.md +10 -0
  75. package/src/autoresearch/state.ts +273 -0
  76. package/src/autoresearch/storage.ts +700 -0
  77. package/src/autoresearch/tools/init-experiment.ts +269 -0
  78. package/src/autoresearch/tools/log-experiment.ts +521 -0
  79. package/src/autoresearch/tools/run-experiment.ts +407 -0
  80. package/src/autoresearch/tools/update-notes.ts +109 -0
  81. package/src/autoresearch/types.ts +168 -0
  82. package/src/capability/context-file.ts +44 -0
  83. package/src/capability/extension-module.ts +34 -0
  84. package/src/capability/extension.ts +47 -0
  85. package/src/capability/fs.ts +117 -0
  86. package/src/capability/hook.ts +40 -0
  87. package/src/capability/index.ts +436 -0
  88. package/src/capability/instruction.ts +37 -0
  89. package/src/capability/mcp.ts +76 -0
  90. package/src/capability/prompt.ts +35 -0
  91. package/src/capability/rule-buckets.ts +66 -0
  92. package/src/capability/rule.ts +261 -0
  93. package/src/capability/settings.ts +34 -0
  94. package/src/capability/skill.ts +63 -0
  95. package/src/capability/slash-command.ts +40 -0
  96. package/src/capability/ssh.ts +41 -0
  97. package/src/capability/system-prompt.ts +34 -0
  98. package/src/capability/tool.ts +38 -0
  99. package/src/capability/types.ts +168 -0
  100. package/src/cli/agents-cli.ts +138 -0
  101. package/src/cli/args.ts +361 -0
  102. package/src/cli/auth-broker-cli.ts +893 -0
  103. package/src/cli/auth-gateway-cli.ts +608 -0
  104. package/src/cli/bench-cli.ts +552 -0
  105. package/src/cli/classify-install-target.ts +76 -0
  106. package/src/cli/claude-trace-cli.ts +795 -0
  107. package/src/cli/commands/init-xdg.ts +27 -0
  108. package/src/cli/completion-gen.ts +550 -0
  109. package/src/cli/config-cli.ts +418 -0
  110. package/src/cli/dry-balance-cli.ts +858 -0
  111. package/src/cli/extension-flags.ts +48 -0
  112. package/src/cli/file-processor.ts +133 -0
  113. package/src/cli/flag-tables.ts +280 -0
  114. package/src/cli/gallery-cli.ts +231 -0
  115. package/src/cli/gallery-fixtures/agentic.ts +407 -0
  116. package/src/cli/gallery-fixtures/codeintel.ts +187 -0
  117. package/src/cli/gallery-fixtures/edit.ts +194 -0
  118. package/src/cli/gallery-fixtures/fs.ts +220 -0
  119. package/src/cli/gallery-fixtures/index.ts +40 -0
  120. package/src/cli/gallery-fixtures/interaction.ts +49 -0
  121. package/src/cli/gallery-fixtures/memory.ts +81 -0
  122. package/src/cli/gallery-fixtures/misc.ts +250 -0
  123. package/src/cli/gallery-fixtures/search.ts +213 -0
  124. package/src/cli/gallery-fixtures/shell.ts +167 -0
  125. package/src/cli/gallery-fixtures/types.ts +57 -0
  126. package/src/cli/gallery-fixtures/web.ts +158 -0
  127. package/src/cli/gallery-screenshot.ts +279 -0
  128. package/src/cli/grep-cli.ts +160 -0
  129. package/src/cli/grievances-cli.ts +256 -0
  130. package/src/cli/initial-message.ts +58 -0
  131. package/src/cli/models-cli.ts +427 -0
  132. package/src/cli/plugin-cli.ts +996 -0
  133. package/src/cli/profile-alias.ts +338 -0
  134. package/src/cli/profile-bootstrap.ts +243 -0
  135. package/src/cli/read-cli.ts +57 -0
  136. package/src/cli/session-picker.ts +80 -0
  137. package/src/cli/setup-cli.ts +332 -0
  138. package/src/cli/setup-model-picker.ts +43 -0
  139. package/src/cli/shell-cli.ts +176 -0
  140. package/src/cli/ssh-cli.ts +179 -0
  141. package/src/cli/startup-cwd.ts +58 -0
  142. package/src/cli/stats-cli.ts +229 -0
  143. package/src/cli/tiny-models-cli.ts +127 -0
  144. package/src/cli/ttsr-cli.ts +995 -0
  145. package/src/cli/update-cli.ts +671 -0
  146. package/src/cli/usage-cli.ts +774 -0
  147. package/src/cli/web-search-cli.ts +132 -0
  148. package/src/cli/worktree-cli.ts +291 -0
  149. package/src/cli-commands.ts +85 -0
  150. package/src/cli.ts +326 -0
  151. package/src/collab/crypto.ts +63 -0
  152. package/src/collab/guest.ts +450 -0
  153. package/src/collab/host.ts +577 -0
  154. package/src/collab/protocol.ts +274 -0
  155. package/src/collab/relay-client.ts +216 -0
  156. package/src/commands/acp.ts +24 -0
  157. package/src/commands/agents.ts +57 -0
  158. package/src/commands/auth-broker.ts +99 -0
  159. package/src/commands/auth-gateway.ts +69 -0
  160. package/src/commands/bench.ts +42 -0
  161. package/src/commands/commit.ts +46 -0
  162. package/src/commands/complete.ts +66 -0
  163. package/src/commands/completions.ts +60 -0
  164. package/src/commands/config.ts +51 -0
  165. package/src/commands/dry-balance.ts +43 -0
  166. package/src/commands/gallery.ts +52 -0
  167. package/src/commands/grep.ts +48 -0
  168. package/src/commands/grievances.ts +51 -0
  169. package/src/commands/install.ts +107 -0
  170. package/src/commands/join.ts +39 -0
  171. package/src/commands/launch.ts +182 -0
  172. package/src/commands/models.ts +61 -0
  173. package/src/commands/plugin.ts +78 -0
  174. package/src/commands/read.ts +38 -0
  175. package/src/commands/say.ts +102 -0
  176. package/src/commands/setup.ts +67 -0
  177. package/src/commands/shell.ts +29 -0
  178. package/src/commands/ssh.ts +60 -0
  179. package/src/commands/stats.ts +29 -0
  180. package/src/commands/tiny-models.ts +36 -0
  181. package/src/commands/token.ts +108 -0
  182. package/src/commands/ttsr.ts +125 -0
  183. package/src/commands/update.ts +21 -0
  184. package/src/commands/usage.ts +43 -0
  185. package/src/commands/web-search.ts +42 -0
  186. package/src/commands/worktree.ts +56 -0
  187. package/src/commit/agentic/agent.ts +318 -0
  188. package/src/commit/agentic/fallback.ts +96 -0
  189. package/src/commit/agentic/index.ts +355 -0
  190. package/src/commit/agentic/prompts/analyze-file.md +22 -0
  191. package/src/commit/agentic/prompts/session-user.md +25 -0
  192. package/src/commit/agentic/prompts/split-confirm.md +1 -0
  193. package/src/commit/agentic/prompts/system.md +38 -0
  194. package/src/commit/agentic/state.ts +60 -0
  195. package/src/commit/agentic/tools/analyze-file.ts +149 -0
  196. package/src/commit/agentic/tools/git-file-diff.ts +191 -0
  197. package/src/commit/agentic/tools/git-hunk.ts +52 -0
  198. package/src/commit/agentic/tools/git-overview.ts +81 -0
  199. package/src/commit/agentic/tools/index.ts +54 -0
  200. package/src/commit/agentic/tools/propose-changelog.ts +147 -0
  201. package/src/commit/agentic/tools/propose-commit.ts +109 -0
  202. package/src/commit/agentic/tools/recent-commits.ts +81 -0
  203. package/src/commit/agentic/tools/schemas.ts +11 -0
  204. package/src/commit/agentic/tools/split-commit.ts +241 -0
  205. package/src/commit/agentic/topo-sort.ts +44 -0
  206. package/src/commit/agentic/trivial.ts +51 -0
  207. package/src/commit/agentic/validation.ts +183 -0
  208. package/src/commit/analysis/conventional.ts +64 -0
  209. package/src/commit/analysis/index.ts +4 -0
  210. package/src/commit/analysis/scope.ts +242 -0
  211. package/src/commit/analysis/summary.ts +107 -0
  212. package/src/commit/analysis/validation.ts +66 -0
  213. package/src/commit/changelog/detect.ts +40 -0
  214. package/src/commit/changelog/generate.ts +101 -0
  215. package/src/commit/changelog/index.ts +234 -0
  216. package/src/commit/changelog/parse.ts +44 -0
  217. package/src/commit/cli.ts +85 -0
  218. package/src/commit/git/diff.ts +148 -0
  219. package/src/commit/index.ts +5 -0
  220. package/src/commit/map-reduce/index.ts +69 -0
  221. package/src/commit/map-reduce/map-phase.ts +193 -0
  222. package/src/commit/map-reduce/reduce-phase.ts +49 -0
  223. package/src/commit/map-reduce/utils.ts +9 -0
  224. package/src/commit/message.ts +11 -0
  225. package/src/commit/model-selection.ts +89 -0
  226. package/src/commit/pipeline.ts +243 -0
  227. package/src/commit/prompts/analysis-system.md +148 -0
  228. package/src/commit/prompts/analysis-user.md +38 -0
  229. package/src/commit/prompts/changelog-system.md +50 -0
  230. package/src/commit/prompts/changelog-user.md +18 -0
  231. package/src/commit/prompts/file-observer-system.md +24 -0
  232. package/src/commit/prompts/file-observer-user.md +8 -0
  233. package/src/commit/prompts/reduce-system.md +50 -0
  234. package/src/commit/prompts/reduce-user.md +17 -0
  235. package/src/commit/prompts/summary-retry.md +3 -0
  236. package/src/commit/prompts/summary-system.md +38 -0
  237. package/src/commit/prompts/summary-user.md +13 -0
  238. package/src/commit/prompts/types-description.md +2 -0
  239. package/src/commit/shared-llm.ts +70 -0
  240. package/src/commit/types.ts +118 -0
  241. package/src/commit/utils/exclusions.ts +42 -0
  242. package/src/commit/utils.ts +58 -0
  243. package/src/config/api-key-resolver.ts +67 -0
  244. package/src/config/append-only-context-mode.ts +76 -0
  245. package/src/config/config-file.ts +315 -0
  246. package/src/config/file-lock.ts +164 -0
  247. package/src/config/keybindings.ts +634 -0
  248. package/src/config/mcp-schema.json +238 -0
  249. package/src/config/model-discovery.ts +589 -0
  250. package/src/config/model-registry.ts +2260 -0
  251. package/src/config/model-resolver.ts +1819 -0
  252. package/src/config/model-roles.ts +99 -0
  253. package/src/config/models-config-schema.ts +266 -0
  254. package/src/config/models-config.ts +131 -0
  255. package/src/config/prompt-templates.ts +185 -0
  256. package/src/config/resolve-config-value.ts +94 -0
  257. package/src/config/settings-schema.ts +4740 -0
  258. package/src/config/settings.ts +1243 -0
  259. package/src/config.ts +242 -0
  260. package/src/cursor.ts +340 -0
  261. package/src/dap/client.ts +760 -0
  262. package/src/dap/config.ts +189 -0
  263. package/src/dap/defaults.json +212 -0
  264. package/src/dap/index.ts +4 -0
  265. package/src/dap/session.ts +1441 -0
  266. package/src/dap/types.ts +610 -0
  267. package/src/debug/index.ts +559 -0
  268. package/src/debug/log-formatting.ts +58 -0
  269. package/src/debug/log-viewer.ts +908 -0
  270. package/src/debug/profiler.ts +162 -0
  271. package/src/debug/protocol-probe.ts +267 -0
  272. package/src/debug/raw-sse-buffer.ts +294 -0
  273. package/src/debug/raw-sse.ts +292 -0
  274. package/src/debug/remote-debugger.ts +151 -0
  275. package/src/debug/report-bundle.ts +375 -0
  276. package/src/debug/system-info.ts +111 -0
  277. package/src/debug/terminal-info.ts +124 -0
  278. package/src/discovery/agents-md.ts +67 -0
  279. package/src/discovery/agents.ts +230 -0
  280. package/src/discovery/at-imports.ts +273 -0
  281. package/src/discovery/builtin-defaults.ts +39 -0
  282. package/src/discovery/builtin-rules/index.ts +63 -0
  283. package/src/discovery/builtin-rules/low-end/no-hallucinated-apis.md +14 -0
  284. package/src/discovery/builtin-rules/low-end/no-hallucinated-paths.md +14 -0
  285. package/src/discovery/builtin-rules/low-end/no-premature-completion.md +14 -0
  286. package/src/discovery/builtin-rules/rs-box-leak.md +48 -0
  287. package/src/discovery/builtin-rules/rs-future-prelude.md +23 -0
  288. package/src/discovery/builtin-rules/rs-lazylock.md +51 -0
  289. package/src/discovery/builtin-rules/rs-match-ergonomics.md +67 -0
  290. package/src/discovery/builtin-rules/rs-parking-lot.md +44 -0
  291. package/src/discovery/builtin-rules/rs-result-type.md +19 -0
  292. package/src/discovery/builtin-rules/ts-bare-catch.md +38 -0
  293. package/src/discovery/builtin-rules/ts-import-type.md +42 -0
  294. package/src/discovery/builtin-rules/ts-no-any.md +65 -0
  295. package/src/discovery/builtin-rules/ts-no-deprecated-leftovers.md +44 -0
  296. package/src/discovery/builtin-rules/ts-no-dynamic-import.md +39 -0
  297. package/src/discovery/builtin-rules/ts-no-inline-cast-access.md +55 -0
  298. package/src/discovery/builtin-rules/ts-no-return-type.md +44 -0
  299. package/src/discovery/builtin-rules/ts-no-test-timers.md +55 -0
  300. package/src/discovery/builtin-rules/ts-no-tiny-functions.md +51 -0
  301. package/src/discovery/builtin-rules/ts-promise-with-resolvers.md +65 -0
  302. package/src/discovery/builtin-rules/ts-redundant-clear-guard.md +75 -0
  303. package/src/discovery/builtin-rules/ts-set-map.md +28 -0
  304. package/src/discovery/builtin.ts +934 -0
  305. package/src/discovery/claude-plugins.ts +386 -0
  306. package/src/discovery/claude.ts +584 -0
  307. package/src/discovery/cline.ts +83 -0
  308. package/src/discovery/codex.ts +522 -0
  309. package/src/discovery/cursor.ts +220 -0
  310. package/src/discovery/gemini.ts +383 -0
  311. package/src/discovery/github.ts +337 -0
  312. package/src/discovery/helpers.ts +1092 -0
  313. package/src/discovery/index.ts +81 -0
  314. package/src/discovery/mcp-json.ts +172 -0
  315. package/src/discovery/omp-extension-roots.ts +190 -0
  316. package/src/discovery/omp-plugins.ts +383 -0
  317. package/src/discovery/opencode.ts +398 -0
  318. package/src/discovery/plugin-dir-roots.ts +28 -0
  319. package/src/discovery/ssh.ts +153 -0
  320. package/src/discovery/substitute-plugin-root.ts +29 -0
  321. package/src/discovery/vscode.ts +105 -0
  322. package/src/discovery/windsurf.ts +147 -0
  323. package/src/edit/apply-patch/index.ts +87 -0
  324. package/src/edit/apply-patch/parser.ts +174 -0
  325. package/src/edit/diff.ts +999 -0
  326. package/src/edit/file-snapshot-store.ts +143 -0
  327. package/src/edit/hashline/block-resolver.ts +33 -0
  328. package/src/edit/hashline/diff.ts +290 -0
  329. package/src/edit/hashline/execute.ts +237 -0
  330. package/src/edit/hashline/filesystem.ts +130 -0
  331. package/src/edit/hashline/index.ts +5 -0
  332. package/src/edit/hashline/noop-loop-guard.ts +99 -0
  333. package/src/edit/hashline/params.ts +19 -0
  334. package/src/edit/index.ts +620 -0
  335. package/src/edit/modes/apply-patch.lark +19 -0
  336. package/src/edit/modes/apply-patch.ts +53 -0
  337. package/src/edit/modes/patch.ts +1888 -0
  338. package/src/edit/modes/replace.ts +1133 -0
  339. package/src/edit/normalize.ts +345 -0
  340. package/src/edit/notebook.ts +242 -0
  341. package/src/edit/read-file.ts +25 -0
  342. package/src/edit/renderer.ts +823 -0
  343. package/src/edit/streaming.ts +517 -0
  344. package/src/eval/__tests__/agent-bridge.test.ts +769 -0
  345. package/src/eval/__tests__/bridge-timeout.test.ts +64 -0
  346. package/src/eval/__tests__/budget-bridge.test.ts +69 -0
  347. package/src/eval/__tests__/completion-bridge.test.ts +412 -0
  348. package/src/eval/__tests__/helpers-local-roots.test.ts +58 -0
  349. package/src/eval/__tests__/idle-timeout.test.ts +80 -0
  350. package/src/eval/__tests__/js-context-manager.test.ts +291 -0
  351. package/src/eval/__tests__/kernel-spawn.test.ts +103 -0
  352. package/src/eval/__tests__/prelude-agent.test.ts +73 -0
  353. package/src/eval/agent-bridge.ts +319 -0
  354. package/src/eval/backend.ts +71 -0
  355. package/src/eval/bridge-timeout.ts +44 -0
  356. package/src/eval/budget-bridge.ts +48 -0
  357. package/src/eval/completion-bridge.ts +211 -0
  358. package/src/eval/concurrency-bridge.ts +34 -0
  359. package/src/eval/idle-timeout.ts +91 -0
  360. package/src/eval/index.ts +4 -0
  361. package/src/eval/js/context-manager.ts +621 -0
  362. package/src/eval/js/executor.ts +173 -0
  363. package/src/eval/js/index.ts +51 -0
  364. package/src/eval/js/shared/helpers.ts +283 -0
  365. package/src/eval/js/shared/indirect-eval.ts +30 -0
  366. package/src/eval/js/shared/local-module-loader.ts +342 -0
  367. package/src/eval/js/shared/prelude.ts +2 -0
  368. package/src/eval/js/shared/prelude.txt +307 -0
  369. package/src/eval/js/shared/rewrite-imports.ts +532 -0
  370. package/src/eval/js/shared/runtime.ts +580 -0
  371. package/src/eval/js/shared/types.ts +18 -0
  372. package/src/eval/js/tool-bridge.ts +163 -0
  373. package/src/eval/js/worker-core.ts +151 -0
  374. package/src/eval/js/worker-entry.ts +37 -0
  375. package/src/eval/js/worker-protocol.ts +47 -0
  376. package/src/eval/py/__tests__/prelude.test.ts +19 -0
  377. package/src/eval/py/display.ts +71 -0
  378. package/src/eval/py/executor.ts +742 -0
  379. package/src/eval/py/index.ts +68 -0
  380. package/src/eval/py/kernel.ts +748 -0
  381. package/src/eval/py/prelude.py +683 -0
  382. package/src/eval/py/prelude.ts +3 -0
  383. package/src/eval/py/runner.py +1177 -0
  384. package/src/eval/py/runtime.ts +276 -0
  385. package/src/eval/py/spawn-options.ts +126 -0
  386. package/src/eval/py/tool-bridge.ts +182 -0
  387. package/src/eval/session-id.ts +8 -0
  388. package/src/eval/types.ts +48 -0
  389. package/src/exa/index.ts +2 -0
  390. package/src/exa/mcp-client.ts +370 -0
  391. package/src/exa/types.ts +69 -0
  392. package/src/exec/bash-executor.ts +434 -0
  393. package/src/exec/exec.ts +53 -0
  394. package/src/exec/non-interactive-env.ts +119 -0
  395. package/src/export/custom-share.ts +65 -0
  396. package/src/export/html/index.ts +266 -0
  397. package/src/export/html/share-loader.js +102 -0
  398. package/src/export/html/template.css +1337 -0
  399. package/src/export/html/template.html +49 -0
  400. package/src/export/html/template.js +1626 -0
  401. package/src/export/html/tool-views.generated.js +37 -0
  402. package/src/export/html/vendor/highlight.min.js +1213 -0
  403. package/src/export/html/vendor/marked.min.js +6 -0
  404. package/src/export/share.ts +268 -0
  405. package/src/export/ttsr.ts +583 -0
  406. package/src/extensibility/custom-commands/bundled/ci-green/index.ts +54 -0
  407. package/src/extensibility/custom-commands/bundled/review/index.ts +698 -0
  408. package/src/extensibility/custom-commands/index.ts +2 -0
  409. package/src/extensibility/custom-commands/loader.ts +242 -0
  410. package/src/extensibility/custom-commands/types.ts +119 -0
  411. package/src/extensibility/custom-tools/index.ts +7 -0
  412. package/src/extensibility/custom-tools/loader.ts +268 -0
  413. package/src/extensibility/custom-tools/types.ts +277 -0
  414. package/src/extensibility/custom-tools/wrapper.ts +47 -0
  415. package/src/extensibility/extensions/compact-handler.ts +40 -0
  416. package/src/extensibility/extensions/get-commands-handler.ts +78 -0
  417. package/src/extensibility/extensions/index.ts +16 -0
  418. package/src/extensibility/extensions/loader.ts +587 -0
  419. package/src/extensibility/extensions/model-api.ts +41 -0
  420. package/src/extensibility/extensions/runner.ts +989 -0
  421. package/src/extensibility/extensions/types.ts +1394 -0
  422. package/src/extensibility/extensions/wrapper.ts +259 -0
  423. package/src/extensibility/hooks/index.ts +6 -0
  424. package/src/extensibility/hooks/loader.ts +262 -0
  425. package/src/extensibility/hooks/runner.ts +425 -0
  426. package/src/extensibility/hooks/tool-wrapper.ts +107 -0
  427. package/src/extensibility/hooks/types.ts +613 -0
  428. package/src/extensibility/legacy-pi-ai-shim.ts +61 -0
  429. package/src/extensibility/legacy-pi-coding-agent-shim.ts +128 -0
  430. package/src/extensibility/plugins/doctor.ts +65 -0
  431. package/src/extensibility/plugins/git-url.ts +367 -0
  432. package/src/extensibility/plugins/index.ts +9 -0
  433. package/src/extensibility/plugins/installer.ts +192 -0
  434. package/src/extensibility/plugins/legacy-pi-compat.ts +712 -0
  435. package/src/extensibility/plugins/loader.ts +458 -0
  436. package/src/extensibility/plugins/manager.ts +1026 -0
  437. package/src/extensibility/plugins/marketplace/cache.ts +136 -0
  438. package/src/extensibility/plugins/marketplace/fetcher.ts +315 -0
  439. package/src/extensibility/plugins/marketplace/index.ts +6 -0
  440. package/src/extensibility/plugins/marketplace/manager.ts +770 -0
  441. package/src/extensibility/plugins/marketplace/registry.ts +196 -0
  442. package/src/extensibility/plugins/marketplace/source-resolver.ts +147 -0
  443. package/src/extensibility/plugins/marketplace/types.ts +191 -0
  444. package/src/extensibility/plugins/marketplace-auto-update.ts +49 -0
  445. package/src/extensibility/plugins/parser.ts +105 -0
  446. package/src/extensibility/plugins/runtime-config.ts +9 -0
  447. package/src/extensibility/plugins/types.ts +194 -0
  448. package/src/extensibility/shared-events.ts +367 -0
  449. package/src/extensibility/skills.ts +408 -0
  450. package/src/extensibility/slash-commands.ts +131 -0
  451. package/src/extensibility/tool-proxy.ts +28 -0
  452. package/src/extensibility/typebox.ts +945 -0
  453. package/src/extensibility/utils.ts +44 -0
  454. package/src/goals/guided-setup.ts +142 -0
  455. package/src/goals/index.ts +3 -0
  456. package/src/goals/runtime.ts +521 -0
  457. package/src/goals/state.ts +37 -0
  458. package/src/goals/tools/goal-tool.ts +251 -0
  459. package/src/hindsight/backend.ts +354 -0
  460. package/src/hindsight/bank.ts +156 -0
  461. package/src/hindsight/client.ts +623 -0
  462. package/src/hindsight/config.ts +175 -0
  463. package/src/hindsight/content.ts +210 -0
  464. package/src/hindsight/index.ts +8 -0
  465. package/src/hindsight/mental-models.ts +429 -0
  466. package/src/hindsight/seeds.json +32 -0
  467. package/src/hindsight/state.ts +492 -0
  468. package/src/hindsight/transcript.ts +71 -0
  469. package/src/index.ts +66 -0
  470. package/src/internal-urls/agent-protocol.ts +146 -0
  471. package/src/internal-urls/artifact-protocol.ts +107 -0
  472. package/src/internal-urls/docs-index.generated.txt +2 -0
  473. package/src/internal-urls/docs-index.ts +102 -0
  474. package/src/internal-urls/history-protocol.ts +118 -0
  475. package/src/internal-urls/index.ts +25 -0
  476. package/src/internal-urls/issue-pr-protocol.ts +594 -0
  477. package/src/internal-urls/json-query.ts +126 -0
  478. package/src/internal-urls/local-protocol.ts +309 -0
  479. package/src/internal-urls/mcp-protocol.ts +151 -0
  480. package/src/internal-urls/memory-protocol.ts +169 -0
  481. package/src/internal-urls/omp-protocol.ts +94 -0
  482. package/src/internal-urls/parse.ts +72 -0
  483. package/src/internal-urls/registry-helpers.ts +25 -0
  484. package/src/internal-urls/router.ts +105 -0
  485. package/src/internal-urls/rule-protocol.ts +45 -0
  486. package/src/internal-urls/skill-protocol.ts +96 -0
  487. package/src/internal-urls/types.ts +152 -0
  488. package/src/internal-urls/vault-protocol.ts +936 -0
  489. package/src/irc/bus.ts +311 -0
  490. package/src/lib/xai-http.ts +124 -0
  491. package/src/lsp/client.ts +1217 -0
  492. package/src/lsp/clients/biome-client.ts +264 -0
  493. package/src/lsp/clients/index.ts +50 -0
  494. package/src/lsp/clients/lsp-linter-client.ts +85 -0
  495. package/src/lsp/clients/swiftlint-client.ts +120 -0
  496. package/src/lsp/config.ts +502 -0
  497. package/src/lsp/defaults.json +499 -0
  498. package/src/lsp/diagnostics-ledger.ts +51 -0
  499. package/src/lsp/edits.ts +267 -0
  500. package/src/lsp/format-options.ts +119 -0
  501. package/src/lsp/index.ts +2480 -0
  502. package/src/lsp/lspmux.ts +233 -0
  503. package/src/lsp/render.ts +668 -0
  504. package/src/lsp/startup-events.ts +13 -0
  505. package/src/lsp/types.ts +444 -0
  506. package/src/lsp/utils.ts +718 -0
  507. package/src/main.ts +1421 -0
  508. package/src/markit/NOTICE +32 -0
  509. package/src/markit/converters/docx.ts +56 -0
  510. package/src/markit/converters/epub.ts +136 -0
  511. package/src/markit/converters/mammoth.d.ts +24 -0
  512. package/src/markit/converters/pdf/columns.ts +103 -0
  513. package/src/markit/converters/pdf/extract.ts +574 -0
  514. package/src/markit/converters/pdf/grid.ts +780 -0
  515. package/src/markit/converters/pdf/headers.ts +106 -0
  516. package/src/markit/converters/pdf/index.ts +146 -0
  517. package/src/markit/converters/pdf/render.ts +501 -0
  518. package/src/markit/converters/pdf/types.ts +84 -0
  519. package/src/markit/converters/pptx.ts +325 -0
  520. package/src/markit/converters/xlsx.ts +173 -0
  521. package/src/markit/index.ts +2 -0
  522. package/src/markit/registry.ts +59 -0
  523. package/src/markit/types.ts +35 -0
  524. package/src/mcp/client.ts +509 -0
  525. package/src/mcp/config-writer.ts +229 -0
  526. package/src/mcp/config.ts +365 -0
  527. package/src/mcp/index.ts +29 -0
  528. package/src/mcp/json-rpc.ts +122 -0
  529. package/src/mcp/loader.ts +124 -0
  530. package/src/mcp/manager.ts +1326 -0
  531. package/src/mcp/oauth-credentials.ts +104 -0
  532. package/src/mcp/oauth-discovery.ts +467 -0
  533. package/src/mcp/oauth-flow.ts +555 -0
  534. package/src/mcp/render.ts +155 -0
  535. package/src/mcp/smithery-auth.ts +104 -0
  536. package/src/mcp/smithery-connect.ts +145 -0
  537. package/src/mcp/smithery-registry.ts +477 -0
  538. package/src/mcp/startup-events.ts +21 -0
  539. package/src/mcp/timeout.ts +59 -0
  540. package/src/mcp/tool-bridge.ts +429 -0
  541. package/src/mcp/tool-cache.ts +117 -0
  542. package/src/mcp/transports/http.ts +519 -0
  543. package/src/mcp/transports/index.ts +6 -0
  544. package/src/mcp/transports/stdio.ts +606 -0
  545. package/src/mcp/types.ts +427 -0
  546. package/src/memories/index.ts +1281 -0
  547. package/src/memories/storage.ts +578 -0
  548. package/src/memory-backend/index.ts +18 -0
  549. package/src/memory-backend/local-backend.ts +45 -0
  550. package/src/memory-backend/off-backend.ts +25 -0
  551. package/src/memory-backend/resolve.ts +25 -0
  552. package/src/memory-backend/runtime.ts +66 -0
  553. package/src/memory-backend/types.ts +166 -0
  554. package/src/mnemopi/backend.ts +612 -0
  555. package/src/mnemopi/config.ts +265 -0
  556. package/src/mnemopi/embed-client.ts +401 -0
  557. package/src/mnemopi/embed-protocol.ts +35 -0
  558. package/src/mnemopi/embed-worker.ts +113 -0
  559. package/src/mnemopi/index.ts +3 -0
  560. package/src/mnemopi/state.ts +657 -0
  561. package/src/modes/acp/acp-agent.ts +2362 -0
  562. package/src/modes/acp/acp-client-bridge.ts +154 -0
  563. package/src/modes/acp/acp-event-mapper.ts +933 -0
  564. package/src/modes/acp/acp-mode.ts +23 -0
  565. package/src/modes/acp/index.ts +2 -0
  566. package/src/modes/acp/terminal-auth.ts +37 -0
  567. package/src/modes/components/__tests__/skill-message.test.ts +92 -0
  568. package/src/modes/components/advisor-message.ts +99 -0
  569. package/src/modes/components/agent-dashboard.ts +1206 -0
  570. package/src/modes/components/agent-hub.ts +566 -0
  571. package/src/modes/components/agent-transcript-viewer.ts +461 -0
  572. package/src/modes/components/assistant-message.ts +612 -0
  573. package/src/modes/components/background-tan-message.ts +36 -0
  574. package/src/modes/components/bash-execution.ts +220 -0
  575. package/src/modes/components/bordered-loader.ts +41 -0
  576. package/src/modes/components/btw-panel.ts +112 -0
  577. package/src/modes/components/cache-invalidation-marker.ts +110 -0
  578. package/src/modes/components/chat-block.ts +111 -0
  579. package/src/modes/components/chat-transcript-builder.ts +476 -0
  580. package/src/modes/components/collab-prompt-message.ts +32 -0
  581. package/src/modes/components/compaction-summary-message.ts +215 -0
  582. package/src/modes/components/copy-selector.ts +206 -0
  583. package/src/modes/components/countdown-timer.ts +75 -0
  584. package/src/modes/components/custom-editor.test.ts +142 -0
  585. package/src/modes/components/custom-editor.ts +620 -0
  586. package/src/modes/components/custom-message.ts +67 -0
  587. package/src/modes/components/diff.ts +254 -0
  588. package/src/modes/components/dynamic-border.ts +34 -0
  589. package/src/modes/components/error-banner.ts +33 -0
  590. package/src/modes/components/eval-execution.ts +158 -0
  591. package/src/modes/components/execution-shared.ts +101 -0
  592. package/src/modes/components/extensions/extension-dashboard.ts +399 -0
  593. package/src/modes/components/extensions/extension-list.ts +502 -0
  594. package/src/modes/components/extensions/index.ts +9 -0
  595. package/src/modes/components/extensions/inspector-panel.ts +321 -0
  596. package/src/modes/components/extensions/state-manager.ts +627 -0
  597. package/src/modes/components/extensions/types.ts +186 -0
  598. package/src/modes/components/footer.ts +275 -0
  599. package/src/modes/components/history-search.ts +280 -0
  600. package/src/modes/components/hook-editor.ts +167 -0
  601. package/src/modes/components/hook-input.ts +87 -0
  602. package/src/modes/components/hook-message.ts +67 -0
  603. package/src/modes/components/hook-selector.ts +659 -0
  604. package/src/modes/components/index.ts +38 -0
  605. package/src/modes/components/keybinding-hints.ts +65 -0
  606. package/src/modes/components/late-diagnostics-message.ts +60 -0
  607. package/src/modes/components/login-dialog.ts +164 -0
  608. package/src/modes/components/logout-account-selector.ts +130 -0
  609. package/src/modes/components/mcp-add-wizard.ts +1360 -0
  610. package/src/modes/components/message-frame.ts +92 -0
  611. package/src/modes/components/model-selector.ts +1315 -0
  612. package/src/modes/components/oauth-selector.ts +457 -0
  613. package/src/modes/components/omfg-panel.ts +141 -0
  614. package/src/modes/components/overlay-box.ts +109 -0
  615. package/src/modes/components/plan-review-overlay.ts +847 -0
  616. package/src/modes/components/plan-toc.ts +138 -0
  617. package/src/modes/components/plugin-selector.ts +95 -0
  618. package/src/modes/components/plugin-settings.ts +739 -0
  619. package/src/modes/components/queue-mode-selector.ts +56 -0
  620. package/src/modes/components/read-tool-group.ts +676 -0
  621. package/src/modes/components/reset-usage-selector.ts +161 -0
  622. package/src/modes/components/segment-track.ts +89 -0
  623. package/src/modes/components/session-selector.ts +631 -0
  624. package/src/modes/components/settings-defs.ts +225 -0
  625. package/src/modes/components/settings-selector.ts +1095 -0
  626. package/src/modes/components/show-images-selector.ts +45 -0
  627. package/src/modes/components/skill-message.ts +110 -0
  628. package/src/modes/components/snapcompact-shape-preview-doc.md +18 -0
  629. package/src/modes/components/snapcompact-shape-preview.ts +192 -0
  630. package/src/modes/components/status-line/component.ts +1001 -0
  631. package/src/modes/components/status-line/context-thresholds.ts +78 -0
  632. package/src/modes/components/status-line/git-utils.ts +42 -0
  633. package/src/modes/components/status-line/index.ts +5 -0
  634. package/src/modes/components/status-line/presets.ts +106 -0
  635. package/src/modes/components/status-line/segments.ts +616 -0
  636. package/src/modes/components/status-line/separators.ts +55 -0
  637. package/src/modes/components/status-line/token-rate.ts +66 -0
  638. package/src/modes/components/status-line/types.ts +124 -0
  639. package/src/modes/components/theme-selector.ts +63 -0
  640. package/src/modes/components/thinking-selector.ts +52 -0
  641. package/src/modes/components/tiny-title-download-progress.ts +90 -0
  642. package/src/modes/components/tips.txt +24 -0
  643. package/src/modes/components/todo-reminder.ts +39 -0
  644. package/src/modes/components/tool-execution.ts +1165 -0
  645. package/src/modes/components/transcript-container.ts +806 -0
  646. package/src/modes/components/tree-selector.ts +994 -0
  647. package/src/modes/components/ttsr-notification.ts +123 -0
  648. package/src/modes/components/usage-row.ts +18 -0
  649. package/src/modes/components/user-message-selector.ts +227 -0
  650. package/src/modes/components/user-message.ts +68 -0
  651. package/src/modes/components/visual-truncate.ts +63 -0
  652. package/src/modes/components/welcome.ts +581 -0
  653. package/src/modes/controllers/btw-controller.ts +173 -0
  654. package/src/modes/controllers/command-controller-shared.ts +109 -0
  655. package/src/modes/controllers/command-controller.ts +1653 -0
  656. package/src/modes/controllers/event-controller.ts +1153 -0
  657. package/src/modes/controllers/extension-ui-controller.ts +893 -0
  658. package/src/modes/controllers/input-controller.ts +1627 -0
  659. package/src/modes/controllers/mcp-command-controller.ts +2162 -0
  660. package/src/modes/controllers/omfg-controller.ts +283 -0
  661. package/src/modes/controllers/omfg-rule.ts +647 -0
  662. package/src/modes/controllers/selector-controller.ts +1285 -0
  663. package/src/modes/controllers/session-focus-controller.ts +112 -0
  664. package/src/modes/controllers/ssh-command-controller.ts +384 -0
  665. package/src/modes/controllers/streaming-reveal.ts +295 -0
  666. package/src/modes/controllers/tan-command-controller.ts +190 -0
  667. package/src/modes/controllers/todo-command-controller.ts +485 -0
  668. package/src/modes/controllers/tool-args-reveal.ts +174 -0
  669. package/src/modes/data/emojis.json +1 -0
  670. package/src/modes/emoji-autocomplete.ts +285 -0
  671. package/src/modes/gradient-highlight.ts +99 -0
  672. package/src/modes/image-references.ts +137 -0
  673. package/src/modes/index.ts +17 -0
  674. package/src/modes/interactive-mode.ts +3940 -0
  675. package/src/modes/internal-url-autocomplete.ts +143 -0
  676. package/src/modes/loop-limit.ts +192 -0
  677. package/src/modes/magic-keywords.ts +42 -0
  678. package/src/modes/markdown-prose.ts +247 -0
  679. package/src/modes/oauth-manual-input.ts +69 -0
  680. package/src/modes/orchestrate.ts +42 -0
  681. package/src/modes/print-mode.ts +130 -0
  682. package/src/modes/prompt-action-autocomplete.ts +260 -0
  683. package/src/modes/rpc/host-tools.ts +186 -0
  684. package/src/modes/rpc/host-uris.ts +235 -0
  685. package/src/modes/rpc/rpc-client.ts +995 -0
  686. package/src/modes/rpc/rpc-mode.ts +1156 -0
  687. package/src/modes/rpc/rpc-subagents.ts +265 -0
  688. package/src/modes/rpc/rpc-types.ts +487 -0
  689. package/src/modes/runtime-init.ts +142 -0
  690. package/src/modes/session-observer-registry.ts +215 -0
  691. package/src/modes/setup-version.ts +11 -0
  692. package/src/modes/setup-wizard/index.ts +101 -0
  693. package/src/modes/setup-wizard/lazy.ts +16 -0
  694. package/src/modes/setup-wizard/scenes/glyph.ts +114 -0
  695. package/src/modes/setup-wizard/scenes/outro.ts +35 -0
  696. package/src/modes/setup-wizard/scenes/providers.ts +103 -0
  697. package/src/modes/setup-wizard/scenes/sign-in.ts +286 -0
  698. package/src/modes/setup-wizard/scenes/splash.ts +201 -0
  699. package/src/modes/setup-wizard/scenes/theme.ts +326 -0
  700. package/src/modes/setup-wizard/scenes/types.ts +57 -0
  701. package/src/modes/setup-wizard/scenes/web-search.ts +145 -0
  702. package/src/modes/setup-wizard/startup-splash.ts +107 -0
  703. package/src/modes/setup-wizard/wizard-overlay.ts +334 -0
  704. package/src/modes/shared.ts +49 -0
  705. package/src/modes/theme/dark.json +95 -0
  706. package/src/modes/theme/defaults/alabaster.json +93 -0
  707. package/src/modes/theme/defaults/amethyst.json +96 -0
  708. package/src/modes/theme/defaults/anthracite.json +93 -0
  709. package/src/modes/theme/defaults/basalt.json +91 -0
  710. package/src/modes/theme/defaults/birch.json +95 -0
  711. package/src/modes/theme/defaults/dark-abyss.json +91 -0
  712. package/src/modes/theme/defaults/dark-arctic.json +104 -0
  713. package/src/modes/theme/defaults/dark-aurora.json +95 -0
  714. package/src/modes/theme/defaults/dark-catppuccin.json +107 -0
  715. package/src/modes/theme/defaults/dark-cavern.json +91 -0
  716. package/src/modes/theme/defaults/dark-copper.json +95 -0
  717. package/src/modes/theme/defaults/dark-cosmos.json +90 -0
  718. package/src/modes/theme/defaults/dark-cyberpunk.json +102 -0
  719. package/src/modes/theme/defaults/dark-dracula.json +98 -0
  720. package/src/modes/theme/defaults/dark-eclipse.json +91 -0
  721. package/src/modes/theme/defaults/dark-ember.json +95 -0
  722. package/src/modes/theme/defaults/dark-equinox.json +90 -0
  723. package/src/modes/theme/defaults/dark-forest.json +96 -0
  724. package/src/modes/theme/defaults/dark-github.json +105 -0
  725. package/src/modes/theme/defaults/dark-gruvbox.json +112 -0
  726. package/src/modes/theme/defaults/dark-lavender.json +95 -0
  727. package/src/modes/theme/defaults/dark-lunar.json +89 -0
  728. package/src/modes/theme/defaults/dark-midnight.json +95 -0
  729. package/src/modes/theme/defaults/dark-monochrome.json +94 -0
  730. package/src/modes/theme/defaults/dark-monokai.json +98 -0
  731. package/src/modes/theme/defaults/dark-nebula.json +90 -0
  732. package/src/modes/theme/defaults/dark-nord.json +97 -0
  733. package/src/modes/theme/defaults/dark-ocean.json +101 -0
  734. package/src/modes/theme/defaults/dark-one.json +100 -0
  735. package/src/modes/theme/defaults/dark-poimandres.json +142 -0
  736. package/src/modes/theme/defaults/dark-rainforest.json +91 -0
  737. package/src/modes/theme/defaults/dark-reef.json +91 -0
  738. package/src/modes/theme/defaults/dark-retro.json +92 -0
  739. package/src/modes/theme/defaults/dark-rose-pine.json +96 -0
  740. package/src/modes/theme/defaults/dark-sakura.json +95 -0
  741. package/src/modes/theme/defaults/dark-slate.json +95 -0
  742. package/src/modes/theme/defaults/dark-solarized.json +97 -0
  743. package/src/modes/theme/defaults/dark-solstice.json +90 -0
  744. package/src/modes/theme/defaults/dark-starfall.json +91 -0
  745. package/src/modes/theme/defaults/dark-sunset.json +99 -0
  746. package/src/modes/theme/defaults/dark-swamp.json +90 -0
  747. package/src/modes/theme/defaults/dark-synthwave.json +103 -0
  748. package/src/modes/theme/defaults/dark-taiga.json +91 -0
  749. package/src/modes/theme/defaults/dark-terminal.json +95 -0
  750. package/src/modes/theme/defaults/dark-tokyo-night.json +101 -0
  751. package/src/modes/theme/defaults/dark-tundra.json +91 -0
  752. package/src/modes/theme/defaults/dark-twilight.json +91 -0
  753. package/src/modes/theme/defaults/dark-volcanic.json +91 -0
  754. package/src/modes/theme/defaults/graphite.json +92 -0
  755. package/src/modes/theme/defaults/index.ts +199 -0
  756. package/src/modes/theme/defaults/light-arctic.json +107 -0
  757. package/src/modes/theme/defaults/light-aurora-day.json +91 -0
  758. package/src/modes/theme/defaults/light-canyon.json +91 -0
  759. package/src/modes/theme/defaults/light-catppuccin.json +106 -0
  760. package/src/modes/theme/defaults/light-cirrus.json +90 -0
  761. package/src/modes/theme/defaults/light-coral.json +95 -0
  762. package/src/modes/theme/defaults/light-cyberpunk.json +96 -0
  763. package/src/modes/theme/defaults/light-dawn.json +90 -0
  764. package/src/modes/theme/defaults/light-dunes.json +91 -0
  765. package/src/modes/theme/defaults/light-eucalyptus.json +95 -0
  766. package/src/modes/theme/defaults/light-forest.json +100 -0
  767. package/src/modes/theme/defaults/light-frost.json +95 -0
  768. package/src/modes/theme/defaults/light-github.json +115 -0
  769. package/src/modes/theme/defaults/light-glacier.json +91 -0
  770. package/src/modes/theme/defaults/light-gruvbox.json +108 -0
  771. package/src/modes/theme/defaults/light-haze.json +90 -0
  772. package/src/modes/theme/defaults/light-honeycomb.json +95 -0
  773. package/src/modes/theme/defaults/light-lagoon.json +91 -0
  774. package/src/modes/theme/defaults/light-lavender.json +95 -0
  775. package/src/modes/theme/defaults/light-meadow.json +91 -0
  776. package/src/modes/theme/defaults/light-mint.json +95 -0
  777. package/src/modes/theme/defaults/light-monochrome.json +101 -0
  778. package/src/modes/theme/defaults/light-ocean.json +99 -0
  779. package/src/modes/theme/defaults/light-one.json +99 -0
  780. package/src/modes/theme/defaults/light-opal.json +91 -0
  781. package/src/modes/theme/defaults/light-orchard.json +91 -0
  782. package/src/modes/theme/defaults/light-paper.json +95 -0
  783. package/src/modes/theme/defaults/light-poimandres.json +142 -0
  784. package/src/modes/theme/defaults/light-prism.json +90 -0
  785. package/src/modes/theme/defaults/light-retro.json +98 -0
  786. package/src/modes/theme/defaults/light-sand.json +95 -0
  787. package/src/modes/theme/defaults/light-savanna.json +91 -0
  788. package/src/modes/theme/defaults/light-solarized.json +102 -0
  789. package/src/modes/theme/defaults/light-soleil.json +90 -0
  790. package/src/modes/theme/defaults/light-sunset.json +99 -0
  791. package/src/modes/theme/defaults/light-synthwave.json +98 -0
  792. package/src/modes/theme/defaults/light-tokyo-night.json +111 -0
  793. package/src/modes/theme/defaults/light-wetland.json +91 -0
  794. package/src/modes/theme/defaults/light-zenith.json +89 -0
  795. package/src/modes/theme/defaults/limestone.json +94 -0
  796. package/src/modes/theme/defaults/mahogany.json +97 -0
  797. package/src/modes/theme/defaults/marble.json +93 -0
  798. package/src/modes/theme/defaults/obsidian.json +91 -0
  799. package/src/modes/theme/defaults/onyx.json +91 -0
  800. package/src/modes/theme/defaults/pearl.json +93 -0
  801. package/src/modes/theme/defaults/porcelain.json +91 -0
  802. package/src/modes/theme/defaults/quartz.json +96 -0
  803. package/src/modes/theme/defaults/sandstone.json +95 -0
  804. package/src/modes/theme/defaults/titanium.json +90 -0
  805. package/src/modes/theme/light.json +93 -0
  806. package/src/modes/theme/mermaid-cache.ts +92 -0
  807. package/src/modes/theme/shimmer.ts +235 -0
  808. package/src/modes/theme/theme-schema.json +459 -0
  809. package/src/modes/theme/theme.ts +2915 -0
  810. package/src/modes/turn-budget.ts +31 -0
  811. package/src/modes/types.ts +406 -0
  812. package/src/modes/ultrathink.ts +41 -0
  813. package/src/modes/utils/context-usage.ts +432 -0
  814. package/src/modes/utils/copy-targets.ts +360 -0
  815. package/src/modes/utils/hotkeys-markdown.ts +62 -0
  816. package/src/modes/utils/keybinding-matchers.ts +51 -0
  817. package/src/modes/utils/tools-markdown.ts +27 -0
  818. package/src/modes/utils/ui-helpers.ts +886 -0
  819. package/src/modes/workflow.ts +42 -0
  820. package/src/plan-mode/approved-plan.ts +186 -0
  821. package/src/plan-mode/plan-handoff.ts +37 -0
  822. package/src/plan-mode/plan-protection.ts +31 -0
  823. package/src/plan-mode/state.ts +6 -0
  824. package/src/priority.json +45 -0
  825. package/src/prompts/advisor/advise-tool.md +3 -0
  826. package/src/prompts/advisor/system.md +113 -0
  827. package/src/prompts/agents/designer.md +74 -0
  828. package/src/prompts/agents/explore.md +58 -0
  829. package/src/prompts/agents/frontmatter.md +11 -0
  830. package/src/prompts/agents/init.md +33 -0
  831. package/src/prompts/agents/librarian.md +119 -0
  832. package/src/prompts/agents/oracle.md +54 -0
  833. package/src/prompts/agents/plan.md +48 -0
  834. package/src/prompts/agents/reviewer.md +139 -0
  835. package/src/prompts/agents/task.md +17 -0
  836. package/src/prompts/bench.md +12 -0
  837. package/src/prompts/ci-green-request.md +36 -0
  838. package/src/prompts/dry-balance-bench.md +8 -0
  839. package/src/prompts/goals/goal-budget-limit.md +16 -0
  840. package/src/prompts/goals/goal-continuation.md +28 -0
  841. package/src/prompts/goals/goal-mode-active.md +23 -0
  842. package/src/prompts/goals/guided-goal-interview.md +8 -0
  843. package/src/prompts/goals/guided-goal-system.md +12 -0
  844. package/src/prompts/low-end/system.md +47 -0
  845. package/src/prompts/memories/consolidation.md +30 -0
  846. package/src/prompts/memories/consolidation_system.md +4 -0
  847. package/src/prompts/memories/read-path.md +17 -0
  848. package/src/prompts/memories/stage_one_input.md +6 -0
  849. package/src/prompts/memories/stage_one_system.md +21 -0
  850. package/src/prompts/review-custom-request.md +22 -0
  851. package/src/prompts/review-headless-request.md +16 -0
  852. package/src/prompts/review-request.md +69 -0
  853. package/src/prompts/steering/user-interjection.md +9 -0
  854. package/src/prompts/system/agent-creation-architect.md +50 -0
  855. package/src/prompts/system/agent-creation-user.md +6 -0
  856. package/src/prompts/system/auto-continue.md +1 -0
  857. package/src/prompts/system/auto-thinking-difficulty-local.md +14 -0
  858. package/src/prompts/system/auto-thinking-difficulty.md +12 -0
  859. package/src/prompts/system/autolearn-guidance-learn.md +1 -0
  860. package/src/prompts/system/autolearn-guidance.md +7 -0
  861. package/src/prompts/system/autolearn-nudge.md +3 -0
  862. package/src/prompts/system/background-tan-dispatch.md +8 -0
  863. package/src/prompts/system/btw-user.md +8 -0
  864. package/src/prompts/system/commit-message-system.md +14 -0
  865. package/src/prompts/system/custom-system-prompt.md +64 -0
  866. package/src/prompts/system/eager-task.md +7 -0
  867. package/src/prompts/system/eager-todo.md +18 -0
  868. package/src/prompts/system/empty-stop-retry.md +4 -0
  869. package/src/prompts/system/irc-autoreply.md +6 -0
  870. package/src/prompts/system/irc-incoming.md +7 -0
  871. package/src/prompts/system/manual-continue.md +7 -0
  872. package/src/prompts/system/memory-consolidation-system.md +8 -0
  873. package/src/prompts/system/memory-extraction-system.md +26 -0
  874. package/src/prompts/system/omfg-user.md +50 -0
  875. package/src/prompts/system/orchestrate-notice.md +40 -0
  876. package/src/prompts/system/personalities/default.md +18 -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 +109 -0
  880. package/src/prompts/system/plan-mode-approved.md +25 -0
  881. package/src/prompts/system/plan-mode-compact-instructions.md +16 -0
  882. package/src/prompts/system/plan-mode-reference.md +11 -0
  883. package/src/prompts/system/plan-mode-subagent.md +33 -0
  884. package/src/prompts/system/plan-mode-tool-decision-reminder.md +9 -0
  885. package/src/prompts/system/project-prompt.md +52 -0
  886. package/src/prompts/system/snapcompact-context-frames-note.md +1 -0
  887. package/src/prompts/system/snapcompact-context-stub.md +1 -0
  888. package/src/prompts/system/snapcompact-system-frames-note.md +1 -0
  889. package/src/prompts/system/snapcompact-system-stub.md +1 -0
  890. package/src/prompts/system/snapcompact-toolresult-note.md +1 -0
  891. package/src/prompts/system/subagent-system-prompt.md +71 -0
  892. package/src/prompts/system/subagent-user-prompt.md +3 -0
  893. package/src/prompts/system/subagent-yield-reminder.md +12 -0
  894. package/src/prompts/system/system-prompt.md +251 -0
  895. package/src/prompts/system/tiny-title-system.md +8 -0
  896. package/src/prompts/system/title-marker-instruction.md +1 -0
  897. package/src/prompts/system/title-system-marker.md +16 -0
  898. package/src/prompts/system/title-system.md +16 -0
  899. package/src/prompts/system/ttsr-interrupt.md +7 -0
  900. package/src/prompts/system/ttsr-tool-reminder.md +5 -0
  901. package/src/prompts/system/ultrathink-notice.md +3 -0
  902. package/src/prompts/system/unexpected-stop-classifier.md +17 -0
  903. package/src/prompts/system/unexpected-stop-retry.md +4 -0
  904. package/src/prompts/system/web-search.md +25 -0
  905. package/src/prompts/system/workflow-notice.md +70 -0
  906. package/src/prompts/tools/apply-patch.md +65 -0
  907. package/src/prompts/tools/ask.md +22 -0
  908. package/src/prompts/tools/ast-edit.md +22 -0
  909. package/src/prompts/tools/ast-grep.md +25 -0
  910. package/src/prompts/tools/async-result.md +8 -0
  911. package/src/prompts/tools/bash.md +45 -0
  912. package/src/prompts/tools/browser.md +42 -0
  913. package/src/prompts/tools/checkpoint.md +15 -0
  914. package/src/prompts/tools/debug.md +17 -0
  915. package/src/prompts/tools/eval.md +70 -0
  916. package/src/prompts/tools/find.md +19 -0
  917. package/src/prompts/tools/github.md +17 -0
  918. package/src/prompts/tools/goal.md +11 -0
  919. package/src/prompts/tools/image-attachment-describe-system.md +8 -0
  920. package/src/prompts/tools/image-attachment-describe.md +10 -0
  921. package/src/prompts/tools/image-gen.md +7 -0
  922. package/src/prompts/tools/inspect-image-system.md +20 -0
  923. package/src/prompts/tools/inspect-image.md +22 -0
  924. package/src/prompts/tools/irc.md +33 -0
  925. package/src/prompts/tools/job.md +17 -0
  926. package/src/prompts/tools/learn.md +7 -0
  927. package/src/prompts/tools/lsp-late-diagnostic.md +8 -0
  928. package/src/prompts/tools/lsp.md +39 -0
  929. package/src/prompts/tools/manage-skill.md +9 -0
  930. package/src/prompts/tools/memory-edit.md +8 -0
  931. package/src/prompts/tools/patch.md +57 -0
  932. package/src/prompts/tools/read.md +76 -0
  933. package/src/prompts/tools/recall.md +5 -0
  934. package/src/prompts/tools/reflect.md +5 -0
  935. package/src/prompts/tools/replace.md +29 -0
  936. package/src/prompts/tools/resolve.md +4 -0
  937. package/src/prompts/tools/retain.md +6 -0
  938. package/src/prompts/tools/rewind.md +13 -0
  939. package/src/prompts/tools/search-tool-bm25.md +32 -0
  940. package/src/prompts/tools/search.md +22 -0
  941. package/src/prompts/tools/ssh.md +22 -0
  942. package/src/prompts/tools/task-summary.md +17 -0
  943. package/src/prompts/tools/task.md +91 -0
  944. package/src/prompts/tools/todo.md +39 -0
  945. package/src/prompts/tools/web-search.md +6 -0
  946. package/src/prompts/tools/write.md +14 -0
  947. package/src/registry/agent-lifecycle.ts +270 -0
  948. package/src/registry/agent-registry.ts +190 -0
  949. package/src/sdk.ts +2919 -0
  950. package/src/secrets/index.ts +123 -0
  951. package/src/secrets/obfuscator.ts +298 -0
  952. package/src/secrets/regex.ts +21 -0
  953. package/src/session/agent-session.ts +12539 -0
  954. package/src/session/agent-storage.ts +478 -0
  955. package/src/session/artifacts.ts +153 -0
  956. package/src/session/auth-broker-config.ts +92 -0
  957. package/src/session/auth-storage.ts +24 -0
  958. package/src/session/blob-store.ts +255 -0
  959. package/src/session/client-bridge.ts +85 -0
  960. package/src/session/codex-auto-reset.ts +202 -0
  961. package/src/session/compact-modes.ts +105 -0
  962. package/src/session/history-storage.ts +361 -0
  963. package/src/session/indexed-session-storage.ts +427 -0
  964. package/src/session/messages.ts +546 -0
  965. package/src/session/redis-session-storage.ts +170 -0
  966. package/src/session/session-context.ts +399 -0
  967. package/src/session/session-dump-format.ts +216 -0
  968. package/src/session/session-entries.ts +198 -0
  969. package/src/session/session-history-format.ts +308 -0
  970. package/src/session/session-listing.ts +588 -0
  971. package/src/session/session-loader.ts +93 -0
  972. package/src/session/session-manager.ts +1748 -0
  973. package/src/session/session-migrations.ts +78 -0
  974. package/src/session/session-paths.ts +193 -0
  975. package/src/session/session-persistence.ts +147 -0
  976. package/src/session/session-storage.ts +590 -0
  977. package/src/session/shake-types.ts +43 -0
  978. package/src/session/snapcompact-inline.ts +542 -0
  979. package/src/session/snapcompact-savings-journal.ts +113 -0
  980. package/src/session/sql-session-storage.ts +314 -0
  981. package/src/session/streaming-output.ts +1330 -0
  982. package/src/session/tool-choice-queue.ts +290 -0
  983. package/src/session/unexpected-stop-classifier.ts +129 -0
  984. package/src/session/yield-queue.ts +183 -0
  985. package/src/slash-commands/acp-builtins.ts +70 -0
  986. package/src/slash-commands/available-commands.ts +105 -0
  987. package/src/slash-commands/builtin-registry.ts +2332 -0
  988. package/src/slash-commands/helpers/active-oauth-account.ts +44 -0
  989. package/src/slash-commands/helpers/collab-qrcode.ts +28 -0
  990. package/src/slash-commands/helpers/context-report.ts +66 -0
  991. package/src/slash-commands/helpers/format.ts +46 -0
  992. package/src/slash-commands/helpers/logout.ts +88 -0
  993. package/src/slash-commands/helpers/marketplace-manager.ts +25 -0
  994. package/src/slash-commands/helpers/mcp.ts +532 -0
  995. package/src/slash-commands/helpers/parse.ts +85 -0
  996. package/src/slash-commands/helpers/reset-usage.ts +66 -0
  997. package/src/slash-commands/helpers/ssh.ts +195 -0
  998. package/src/slash-commands/helpers/stats-dashboard.ts +85 -0
  999. package/src/slash-commands/helpers/todo.ts +279 -0
  1000. package/src/slash-commands/helpers/usage-report.ts +128 -0
  1001. package/src/slash-commands/marketplace-install-parser.ts +99 -0
  1002. package/src/slash-commands/types.ts +135 -0
  1003. package/src/ssh/config-writer.ts +183 -0
  1004. package/src/ssh/connection-manager.ts +510 -0
  1005. package/src/ssh/ssh-executor.ts +189 -0
  1006. package/src/ssh/sshfs-mount.ts +140 -0
  1007. package/src/ssh/utils.ts +8 -0
  1008. package/src/startup-splash.ts +19 -0
  1009. package/src/stt/asr-client.ts +521 -0
  1010. package/src/stt/asr-protocol.ts +65 -0
  1011. package/src/stt/asr-worker.ts +790 -0
  1012. package/src/stt/downloader.ts +138 -0
  1013. package/src/stt/endpointer.ts +259 -0
  1014. package/src/stt/index.ts +7 -0
  1015. package/src/stt/models.ts +150 -0
  1016. package/src/stt/recorder.ts +538 -0
  1017. package/src/stt/stt-controller.ts +380 -0
  1018. package/src/stt/transcriber.ts +60 -0
  1019. package/src/stt/wav.ts +173 -0
  1020. package/src/system-prompt.ts +709 -0
  1021. package/src/task/agents.ts +166 -0
  1022. package/src/task/commands.ts +132 -0
  1023. package/src/task/discovery.ts +122 -0
  1024. package/src/task/executor.ts +2356 -0
  1025. package/src/task/index.ts +1580 -0
  1026. package/src/task/name-generator.ts +1577 -0
  1027. package/src/task/omp-command.ts +26 -0
  1028. package/src/task/output-manager.ts +93 -0
  1029. package/src/task/parallel.ts +116 -0
  1030. package/src/task/persisted-revive.ts +128 -0
  1031. package/src/task/render.ts +1558 -0
  1032. package/src/task/repair-args.ts +129 -0
  1033. package/src/task/subprocess-tool-registry.ts +88 -0
  1034. package/src/task/types.ts +401 -0
  1035. package/src/task/worktree.ts +514 -0
  1036. package/src/telemetry-export.ts +144 -0
  1037. package/src/thinking.ts +187 -0
  1038. package/src/tiny/device.ts +111 -0
  1039. package/src/tiny/dtype.ts +101 -0
  1040. package/src/tiny/models.ts +252 -0
  1041. package/src/tiny/text.ts +169 -0
  1042. package/src/tiny/title-client.ts +538 -0
  1043. package/src/tiny/title-protocol.ts +56 -0
  1044. package/src/tiny/worker.ts +491 -0
  1045. package/src/tool-discovery/mode.ts +24 -0
  1046. package/src/tool-discovery/tool-index.ts +271 -0
  1047. package/src/tools/__tests__/json-tree.test.ts +35 -0
  1048. package/src/tools/approval.ts +189 -0
  1049. package/src/tools/ask.ts +977 -0
  1050. package/src/tools/ast-edit.ts +700 -0
  1051. package/src/tools/ast-grep.ts +483 -0
  1052. package/src/tools/auto-generated-guard.ts +322 -0
  1053. package/src/tools/bash-command-fixup.ts +37 -0
  1054. package/src/tools/bash-interactive.ts +408 -0
  1055. package/src/tools/bash-interceptor.ts +67 -0
  1056. package/src/tools/bash-pty-selection.ts +14 -0
  1057. package/src/tools/bash-skill-urls.ts +248 -0
  1058. package/src/tools/bash.ts +1405 -0
  1059. package/src/tools/browser/attach.ts +194 -0
  1060. package/src/tools/browser/cmux/cmux-tab.ts +1264 -0
  1061. package/src/tools/browser/cmux/rpc.ts +156 -0
  1062. package/src/tools/browser/cmux/socket-client.ts +309 -0
  1063. package/src/tools/browser/launch.ts +673 -0
  1064. package/src/tools/browser/readable.ts +112 -0
  1065. package/src/tools/browser/registry.ts +241 -0
  1066. package/src/tools/browser/render.ts +221 -0
  1067. package/src/tools/browser/tab-protocol.ts +107 -0
  1068. package/src/tools/browser/tab-supervisor.ts +799 -0
  1069. package/src/tools/browser/tab-worker-entry.ts +29 -0
  1070. package/src/tools/browser/tab-worker.ts +1226 -0
  1071. package/src/tools/browser.ts +403 -0
  1072. package/src/tools/builtin-names.ts +34 -0
  1073. package/src/tools/checkpoint.ts +136 -0
  1074. package/src/tools/conflict-detect.ts +718 -0
  1075. package/src/tools/context.ts +39 -0
  1076. package/src/tools/debug.ts +1087 -0
  1077. package/src/tools/eval-backends.ts +27 -0
  1078. package/src/tools/eval-render.ts +762 -0
  1079. package/src/tools/eval.ts +600 -0
  1080. package/src/tools/fetch.ts +1902 -0
  1081. package/src/tools/file-recorder.ts +35 -0
  1082. package/src/tools/find.ts +629 -0
  1083. package/src/tools/fs-cache-invalidation.ts +28 -0
  1084. package/src/tools/gh-cache-invalidation.ts +255 -0
  1085. package/src/tools/gh-format.ts +12 -0
  1086. package/src/tools/gh-renderer.ts +481 -0
  1087. package/src/tools/gh.ts +3752 -0
  1088. package/src/tools/github-cache.ts +663 -0
  1089. package/src/tools/grouped-file-output.ts +210 -0
  1090. package/src/tools/image-gen.ts +1586 -0
  1091. package/src/tools/index.ts +649 -0
  1092. package/src/tools/inspect-image-renderer.ts +132 -0
  1093. package/src/tools/inspect-image.ts +260 -0
  1094. package/src/tools/irc.ts +788 -0
  1095. package/src/tools/job.ts +612 -0
  1096. package/src/tools/json-tree.ts +260 -0
  1097. package/src/tools/jtd-to-json-schema.ts +219 -0
  1098. package/src/tools/jtd-to-typescript.ts +136 -0
  1099. package/src/tools/jtd-utils.ts +102 -0
  1100. package/src/tools/learn.ts +141 -0
  1101. package/src/tools/list-limit.ts +40 -0
  1102. package/src/tools/manage-skill.ts +100 -0
  1103. package/src/tools/match-line-format.ts +20 -0
  1104. package/src/tools/memory-edit.ts +59 -0
  1105. package/src/tools/memory-recall.ts +102 -0
  1106. package/src/tools/memory-reflect.ts +88 -0
  1107. package/src/tools/memory-render.ts +202 -0
  1108. package/src/tools/memory-retain.ts +89 -0
  1109. package/src/tools/output-meta.ts +768 -0
  1110. package/src/tools/output-schema-validator.ts +132 -0
  1111. package/src/tools/path-utils.ts +1116 -0
  1112. package/src/tools/plan-mode-guard.ts +142 -0
  1113. package/src/tools/puppeteer/00_stealth_tampering.txt +63 -0
  1114. package/src/tools/puppeteer/01_stealth_activity.txt +20 -0
  1115. package/src/tools/puppeteer/02_stealth_hairline.txt +11 -0
  1116. package/src/tools/puppeteer/03_stealth_botd.txt +384 -0
  1117. package/src/tools/puppeteer/04_stealth_iframe.txt +81 -0
  1118. package/src/tools/puppeteer/05_stealth_webgl.txt +75 -0
  1119. package/src/tools/puppeteer/06_stealth_screen.txt +72 -0
  1120. package/src/tools/puppeteer/07_stealth_fonts.txt +97 -0
  1121. package/src/tools/puppeteer/08_stealth_audio.txt +51 -0
  1122. package/src/tools/puppeteer/09_stealth_locale.txt +46 -0
  1123. package/src/tools/puppeteer/10_stealth_plugins.txt +208 -0
  1124. package/src/tools/puppeteer/11_stealth_hardware.txt +8 -0
  1125. package/src/tools/puppeteer/12_stealth_codecs.txt +40 -0
  1126. package/src/tools/puppeteer/13_stealth_worker.txt +74 -0
  1127. package/src/tools/read.ts +3124 -0
  1128. package/src/tools/render-utils.ts +895 -0
  1129. package/src/tools/renderers.ts +86 -0
  1130. package/src/tools/report-tool-issue.ts +530 -0
  1131. package/src/tools/resolve.ts +302 -0
  1132. package/src/tools/review.ts +251 -0
  1133. package/src/tools/search-tool-bm25.ts +351 -0
  1134. package/src/tools/search.ts +1583 -0
  1135. package/src/tools/sqlite-reader.ts +828 -0
  1136. package/src/tools/ssh.ts +369 -0
  1137. package/src/tools/todo.ts +938 -0
  1138. package/src/tools/tool-errors.ts +62 -0
  1139. package/src/tools/tool-result.ts +102 -0
  1140. package/src/tools/tool-timeouts.ts +30 -0
  1141. package/src/tools/tts.ts +265 -0
  1142. package/src/tools/write.ts +1182 -0
  1143. package/src/tools/yield.ts +269 -0
  1144. package/src/tts/downloader.ts +64 -0
  1145. package/src/tts/index.ts +8 -0
  1146. package/src/tts/models.ts +137 -0
  1147. package/src/tts/player.ts +137 -0
  1148. package/src/tts/runtime.ts +21 -0
  1149. package/src/tts/streaming-player.ts +266 -0
  1150. package/src/tts/tts-client.ts +642 -0
  1151. package/src/tts/tts-protocol.ts +60 -0
  1152. package/src/tts/tts-worker.ts +505 -0
  1153. package/src/tts/vocalizer.ts +162 -0
  1154. package/src/tts/wav.ts +58 -0
  1155. package/src/tui/code-cell.ts +257 -0
  1156. package/src/tui/file-list.ts +55 -0
  1157. package/src/tui/hyperlink.ts +178 -0
  1158. package/src/tui/index.ts +13 -0
  1159. package/src/tui/output-block.ts +240 -0
  1160. package/src/tui/status-line.ts +54 -0
  1161. package/src/tui/tree-list.ts +133 -0
  1162. package/src/tui/types.ts +15 -0
  1163. package/src/tui/utils.ts +103 -0
  1164. package/src/tui/width-aware-text.ts +58 -0
  1165. package/src/utils/block-context.ts +312 -0
  1166. package/src/utils/changelog.ts +132 -0
  1167. package/src/utils/clipboard.ts +262 -0
  1168. package/src/utils/command-args.ts +76 -0
  1169. package/src/utils/commit-message-generator.ts +147 -0
  1170. package/src/utils/edit-mode.ts +41 -0
  1171. package/src/utils/enhanced-paste.ts +230 -0
  1172. package/src/utils/event-bus.ts +33 -0
  1173. package/src/utils/external-editor.ts +78 -0
  1174. package/src/utils/file-display-mode.ts +45 -0
  1175. package/src/utils/file-mentions.ts +284 -0
  1176. package/src/utils/git.ts +1838 -0
  1177. package/src/utils/image-loading.ts +231 -0
  1178. package/src/utils/image-resize.ts +309 -0
  1179. package/src/utils/image-vision-fallback.ts +197 -0
  1180. package/src/utils/ipc.ts +38 -0
  1181. package/src/utils/jj.ts +248 -0
  1182. package/src/utils/lang-from-path.ts +244 -0
  1183. package/src/utils/markit.ts +143 -0
  1184. package/src/utils/mupdf-wasm-embed.ts +12 -0
  1185. package/src/utils/open.ts +55 -0
  1186. package/src/utils/qrcode.ts +535 -0
  1187. package/src/utils/session-color.ts +142 -0
  1188. package/src/utils/shell-snapshot.ts +187 -0
  1189. package/src/utils/sixel.ts +69 -0
  1190. package/src/utils/thinking-display.ts +11 -0
  1191. package/src/utils/title-generator.ts +416 -0
  1192. package/src/utils/tool-choice.ts +49 -0
  1193. package/src/utils/tools-manager.ts +372 -0
  1194. package/src/utils/turndown.ts +83 -0
  1195. package/src/utils/zip.ts +1091 -0
  1196. package/src/web/kagi.ts +304 -0
  1197. package/src/web/parallel.ts +353 -0
  1198. package/src/web/scrapers/artifacthub.ts +207 -0
  1199. package/src/web/scrapers/arxiv.ts +83 -0
  1200. package/src/web/scrapers/aur.ts +162 -0
  1201. package/src/web/scrapers/biorxiv.ts +133 -0
  1202. package/src/web/scrapers/bluesky.ts +262 -0
  1203. package/src/web/scrapers/brew.ts +172 -0
  1204. package/src/web/scrapers/cheatsh.ts +68 -0
  1205. package/src/web/scrapers/chocolatey.ts +196 -0
  1206. package/src/web/scrapers/choosealicense.ts +95 -0
  1207. package/src/web/scrapers/cisa-kev.ts +87 -0
  1208. package/src/web/scrapers/clojars.ts +154 -0
  1209. package/src/web/scrapers/coingecko.ts +177 -0
  1210. package/src/web/scrapers/crates-io.ts +97 -0
  1211. package/src/web/scrapers/crossref.ts +136 -0
  1212. package/src/web/scrapers/devto.ts +147 -0
  1213. package/src/web/scrapers/discogs.ts +306 -0
  1214. package/src/web/scrapers/discourse.ts +197 -0
  1215. package/src/web/scrapers/dockerhub.ts +138 -0
  1216. package/src/web/scrapers/docs-rs.ts +652 -0
  1217. package/src/web/scrapers/fdroid.ts +134 -0
  1218. package/src/web/scrapers/firefox-addons.ts +191 -0
  1219. package/src/web/scrapers/flathub.ts +223 -0
  1220. package/src/web/scrapers/github-gist.ts +58 -0
  1221. package/src/web/scrapers/github.ts +800 -0
  1222. package/src/web/scrapers/gitlab.ts +401 -0
  1223. package/src/web/scrapers/go-pkg.ts +266 -0
  1224. package/src/web/scrapers/hackage.ts +140 -0
  1225. package/src/web/scrapers/hackernews.ts +189 -0
  1226. package/src/web/scrapers/hex.ts +105 -0
  1227. package/src/web/scrapers/huggingface.ts +321 -0
  1228. package/src/web/scrapers/iacr.ts +89 -0
  1229. package/src/web/scrapers/index.ts +252 -0
  1230. package/src/web/scrapers/jetbrains-marketplace.ts +159 -0
  1231. package/src/web/scrapers/lemmy.ts +203 -0
  1232. package/src/web/scrapers/lobsters.ts +175 -0
  1233. package/src/web/scrapers/mastodon.ts +292 -0
  1234. package/src/web/scrapers/maven.ts +138 -0
  1235. package/src/web/scrapers/mdn.ts +173 -0
  1236. package/src/web/scrapers/metacpan.ts +222 -0
  1237. package/src/web/scrapers/musicbrainz.ts +250 -0
  1238. package/src/web/scrapers/npm.ts +98 -0
  1239. package/src/web/scrapers/nuget.ts +183 -0
  1240. package/src/web/scrapers/nvd.ts +222 -0
  1241. package/src/web/scrapers/ollama.ts +239 -0
  1242. package/src/web/scrapers/open-vsx.ts +106 -0
  1243. package/src/web/scrapers/opencorporates.ts +292 -0
  1244. package/src/web/scrapers/openlibrary.ts +336 -0
  1245. package/src/web/scrapers/orcid.ts +286 -0
  1246. package/src/web/scrapers/osv.ts +176 -0
  1247. package/src/web/scrapers/packagist.ts +160 -0
  1248. package/src/web/scrapers/pub-dev.ts +143 -0
  1249. package/src/web/scrapers/pubmed.ts +211 -0
  1250. package/src/web/scrapers/pypi.ts +112 -0
  1251. package/src/web/scrapers/rawg.ts +110 -0
  1252. package/src/web/scrapers/readthedocs.ts +120 -0
  1253. package/src/web/scrapers/reddit.ts +95 -0
  1254. package/src/web/scrapers/repology.ts +251 -0
  1255. package/src/web/scrapers/rfc.ts +201 -0
  1256. package/src/web/scrapers/rubygems.ts +103 -0
  1257. package/src/web/scrapers/searchcode.ts +189 -0
  1258. package/src/web/scrapers/sec-edgar.ts +261 -0
  1259. package/src/web/scrapers/semantic-scholar.ts +171 -0
  1260. package/src/web/scrapers/snapcraft.ts +187 -0
  1261. package/src/web/scrapers/sourcegraph.ts +336 -0
  1262. package/src/web/scrapers/spdx.ts +108 -0
  1263. package/src/web/scrapers/spotify.ts +198 -0
  1264. package/src/web/scrapers/stackoverflow.ts +120 -0
  1265. package/src/web/scrapers/terraform.ts +277 -0
  1266. package/src/web/scrapers/tldr.ts +47 -0
  1267. package/src/web/scrapers/twitter.ts +94 -0
  1268. package/src/web/scrapers/types.ts +354 -0
  1269. package/src/web/scrapers/utils.ts +109 -0
  1270. package/src/web/scrapers/vimeo.ts +133 -0
  1271. package/src/web/scrapers/vscode-marketplace.ts +187 -0
  1272. package/src/web/scrapers/w3c.ts +156 -0
  1273. package/src/web/scrapers/wikidata.ts +344 -0
  1274. package/src/web/scrapers/wikipedia.ts +84 -0
  1275. package/src/web/scrapers/youtube.ts +325 -0
  1276. package/src/web/search/index.ts +317 -0
  1277. package/src/web/search/provider.ts +169 -0
  1278. package/src/web/search/providers/anthropic.ts +343 -0
  1279. package/src/web/search/providers/base.ts +90 -0
  1280. package/src/web/search/providers/brave.ts +152 -0
  1281. package/src/web/search/providers/codex.ts +593 -0
  1282. package/src/web/search/providers/exa.ts +400 -0
  1283. package/src/web/search/providers/gemini.ts +518 -0
  1284. package/src/web/search/providers/jina.ts +111 -0
  1285. package/src/web/search/providers/kagi.ts +86 -0
  1286. package/src/web/search/providers/kimi.ts +196 -0
  1287. package/src/web/search/providers/parallel.ts +225 -0
  1288. package/src/web/search/providers/perplexity-auth.ts +133 -0
  1289. package/src/web/search/providers/perplexity.ts +866 -0
  1290. package/src/web/search/providers/searxng.ts +325 -0
  1291. package/src/web/search/providers/synthetic.ts +114 -0
  1292. package/src/web/search/providers/tavily.ts +176 -0
  1293. package/src/web/search/providers/utils.ts +128 -0
  1294. package/src/web/search/providers/zai.ts +333 -0
  1295. package/src/web/search/render.ts +262 -0
  1296. package/src/web/search/types.ts +462 -0
  1297. package/src/web/search/utils.ts +17 -0
  1298. package/src/workspace-tree.ts +326 -0
@@ -0,0 +1,1165 @@
1
+ import type { SnapshotStore } from "@oh-my-pi/hashline";
2
+ import type { AgentTool } from "@oh-my-pi/pi-agent-core";
3
+ import {
4
+ Box,
5
+ type Component,
6
+ Container,
7
+ getImageDimensions,
8
+ Image,
9
+ ImageProtocol,
10
+ imageFallback,
11
+ type NativeScrollbackLiveRegion,
12
+ Spacer,
13
+ TERMINAL,
14
+ Text,
15
+ type TUI,
16
+ } from "@oh-my-pi/pi-tui";
17
+ import { getProjectDir, logger, sanitizeText } from "@oh-my-pi/pi-utils";
18
+ import { EDIT_MODE_STRATEGIES, type EditMode, type PerFileDiffPreview } from "../../edit";
19
+ import type { Theme } from "../../modes/theme/theme";
20
+ import { getThemeEpoch, theme } from "../../modes/theme/theme";
21
+ import { BASH_DEFAULT_PREVIEW_LINES } from "../../tools/bash";
22
+ import { EVAL_DEFAULT_PREVIEW_LINES } from "../../tools/eval";
23
+ import { isWaitingPollDetails } from "../../tools/job";
24
+ import {
25
+ formatArgsInline,
26
+ JSON_TREE_MAX_DEPTH_COLLAPSED,
27
+ JSON_TREE_MAX_DEPTH_EXPANDED,
28
+ JSON_TREE_MAX_LINES_COLLAPSED,
29
+ JSON_TREE_MAX_LINES_EXPANDED,
30
+ JSON_TREE_SCALAR_LEN_COLLAPSED,
31
+ JSON_TREE_SCALAR_LEN_EXPANDED,
32
+ renderJsonTreeLines,
33
+ } from "../../tools/json-tree";
34
+ import { formatExpandHint, replaceTabs, resolveImageOptions, truncateToWidth } from "../../tools/render-utils";
35
+ import { toolRenderers } from "../../tools/renderers";
36
+ import { TODO_STRIKE_TOTAL_FRAMES } from "../../tools/todo";
37
+ import { isFramedBlockComponent, renderStatusLine, WidthAwareText } from "../../tui";
38
+ import { sanitizeWithOptionalSixelPassthrough } from "../../utils/sixel";
39
+ import { renderDiff } from "./diff";
40
+
41
+ /**
42
+ * Drop trailing removal/hunk-header lines that appear in a streaming diff
43
+ * before the matching `+added` lines have arrived. Without this, a partial
44
+ * apply_patch / hashline preview shows `-old` first and then visibly grows
45
+ * the `+new` block beneath it — the "removals first, additions catching up"
46
+ * jitter. Once the next streaming tick brings the additions in, the trailing
47
+ * block reappears alongside them.
48
+ */
49
+ function stripTrailingUnbalancedRemoval(diff: string | undefined): string | undefined {
50
+ if (!diff) return diff;
51
+ const lines = diff.split("\n");
52
+ let lastAddIdx = -1;
53
+ for (let i = lines.length - 1; i >= 0; i--) {
54
+ if (lines[i].startsWith("+")) {
55
+ lastAddIdx = i;
56
+ break;
57
+ }
58
+ }
59
+ let hasTrailingUnbalanced = false;
60
+ for (let i = lastAddIdx + 1; i < lines.length; i++) {
61
+ const line = lines[i];
62
+ if (line.startsWith("-") || line.startsWith("@@")) {
63
+ hasTrailingUnbalanced = true;
64
+ break;
65
+ }
66
+ }
67
+ if (!hasTrailingUnbalanced) return diff;
68
+ if (lastAddIdx === -1) return "";
69
+ return lines.slice(0, lastAddIdx + 1).join("\n");
70
+ }
71
+
72
+ function stabilizeStreamingPreviews(previews: PerFileDiffPreview[]): PerFileDiffPreview[] {
73
+ let changed = false;
74
+ const next = previews.map(preview => {
75
+ if (!preview.diff) return preview;
76
+ const trimmed = stripTrailingUnbalancedRemoval(preview.diff);
77
+ if (trimmed === preview.diff) return preview;
78
+ changed = true;
79
+ return { ...preview, diff: trimmed ?? "" };
80
+ });
81
+ return changed ? next : previews;
82
+ }
83
+
84
+ function isEditLikeToolName(toolName: string): boolean {
85
+ return toolName === "edit" || toolName === "apply_patch";
86
+ }
87
+
88
+ function resolveEditModeForTool(toolName: string, tool: AgentTool | undefined): EditMode | undefined {
89
+ if (toolName === "apply_patch") return "apply_patch";
90
+ if (toolName !== "edit") return undefined;
91
+ return (tool as { mode?: EditMode } | undefined)?.mode;
92
+ }
93
+
94
+ function rawTextInputFromPartialJson(partialJson: unknown): string | undefined {
95
+ if (typeof partialJson !== "string") return undefined;
96
+ if (partialJson.length === 0) return undefined;
97
+ const trimmed = partialJson.trimStart();
98
+ if (trimmed.length === 0) return undefined;
99
+ const first = trimmed[0];
100
+ // Function-tool arguments stream as JSON. Custom/free-form tools stream raw
101
+ // text in the same transport field; only the raw form is a valid fallback for
102
+ // the conventional `input` parameter.
103
+ if (first === "{" || first === '"') return undefined;
104
+ return partialJson;
105
+ }
106
+
107
+ function getArgsWithStreamedTextInput(args: unknown): unknown {
108
+ if (args == null || typeof args !== "object") return args;
109
+ const record = args as Record<string, unknown>;
110
+ if (typeof record.input === "string") return args;
111
+ const input = rawTextInputFromPartialJson(record.__partialJson);
112
+ return input === undefined ? args : { ...record, input };
113
+ }
114
+
115
+ /**
116
+ * Transcript-side probe telling a block whether it is still inside the live
117
+ * (repaintable) region. Implemented by `TranscriptContainer`; injected rather
118
+ * than imported so the component stays decoupled from the transcript.
119
+ */
120
+ export interface TranscriptLiveRegionProbe {
121
+ isBlockInLiveRegion(component: Component): boolean;
122
+ }
123
+
124
+ export interface ToolExecutionOptions {
125
+ snapshots?: SnapshotStore;
126
+ showImages?: boolean; // default: true (only used if terminal supports images)
127
+ editFuzzyThreshold?: number;
128
+ editAllowFuzzy?: boolean;
129
+ /** Live-region probe used to settle detached task progress once the block
130
+ * leaves the repaintable transcript region. */
131
+ liveRegion?: TranscriptLiveRegionProbe;
132
+ }
133
+
134
+ export interface ToolExecutionHandle {
135
+ updateArgs(args: any, toolCallId?: string): void;
136
+ updateResult(
137
+ result: {
138
+ content: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;
139
+ details?: any;
140
+ isError?: boolean;
141
+ },
142
+ isPartial?: boolean,
143
+ toolCallId?: string,
144
+ ): void;
145
+ setArgsComplete(toolCallId?: string): void;
146
+ setExpanded(expanded: boolean): void;
147
+ }
148
+
149
+ /** Drive pending-tool redraws at 30fps for live tool headers and displaceable
150
+ * poll blocks. The TUI throttles at the same cadence, and static frames diff to
151
+ * a no-op redraw at ~zero cost. */
152
+ export const SPINNER_RENDER_INTERVAL_MS = 1000 / 30;
153
+ /** Advance the spinner glyph at its classic ~12.5fps step, decoupled from the
154
+ * render cadence (mirrors `Loader`). */
155
+ export const SPINNER_GLYPH_ADVANCE_MS = 80;
156
+
157
+ /** Phase-locked spinner glyph index shared by every live tool block so parallel
158
+ * spinners advance in lockstep instead of each tracking its own start time. */
159
+ export function sharedSpinnerFrame(frameCount: number, now: number = performance.now()): number {
160
+ return frameCount > 0 ? Math.floor(now / SPINNER_GLYPH_ADVANCE_MS) % frameCount : 0;
161
+ }
162
+
163
+ // Stable per-instance counter so each tool execution's inline images get a
164
+ // graphics id that survives child re-creation (the image budget keys off it).
165
+ let toolExecutionInstanceSeq = 0;
166
+
167
+ /**
168
+ * Component that renders a tool call with its result (updateable)
169
+ */
170
+ export class ToolExecutionComponent extends Container implements NativeScrollbackLiveRegion {
171
+ #contentBox: Box; // Used for custom tools and bash visual truncation
172
+ #contentText: WidthAwareText; // Generic fallback (no custom/built-in renderer)
173
+ #multiFileBoxes: (Box | Spacer)[] = []; // Extra boxes for multi-file edit results
174
+ #imageComponents: Image[] = [];
175
+ #imageSpacers: Spacer[] = [];
176
+ readonly #instanceId = ++toolExecutionInstanceSeq;
177
+ #toolName: string;
178
+ #toolLabel: string;
179
+ #args: any;
180
+ #expanded = false;
181
+ #showImages: boolean;
182
+ #editFuzzyThreshold: number | undefined;
183
+ #editAllowFuzzy: boolean | undefined;
184
+ #snapshots?: SnapshotStore;
185
+ #isPartial = true;
186
+ #resultVersion = 0;
187
+ #lastDisplayKey: string | undefined;
188
+ // Bumped whenever a render input that #rebuildDisplay consumes but the memo
189
+ // key cannot cheaply hash changes: streamed call args, the async edit-diff
190
+ // preview, and Kitty PNG conversions. Folded into the dirty key so those
191
+ // updates are not swallowed by the memo (see #updateDisplay).
192
+ #displayInputVersion = 0;
193
+ // Set once #rebuildDisplay has populated the display. Replaces a
194
+ // #contentBox.children.length probe so the memo fast-path also covers the
195
+ // #contentText fallback path (which leaves #contentBox empty).
196
+ #displayBuilt = false;
197
+ // Number of Image children the last rebuild emitted. Only when this is > 0 does
198
+ // the memo key fold in viewport-dependent image sizing (resolveImageOptions),
199
+ // so a terminal resize re-shapes image-bearing results to rescale them without
200
+ // forcing the common image-free result to re-shape on every resize tick.
201
+ #renderedImageCount = 0;
202
+ #tool?: AgentTool;
203
+ #ui: TUI;
204
+ #cwd: string;
205
+ #result?: {
206
+ content: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;
207
+ isError?: boolean;
208
+ details?: any;
209
+ };
210
+ // Edit preview state
211
+ #editMode?: EditMode;
212
+ #editDiffPreview?: PerFileDiffPreview[];
213
+ #editDiffAbort?: AbortController;
214
+ #editDiffLastArgsKey?: string;
215
+ // Latest in-flight streaming diff recompute, captured so it can be awaited.
216
+ #editDiffInFlight?: Promise<void>;
217
+ // Cached converted images for Kitty protocol (which requires PNG), keyed by index
218
+ #convertedImages: Map<number, { data: string; mimeType: string }> = new Map();
219
+ // Spinner animation for partial task results
220
+ #spinnerFrame?: number;
221
+ #spinnerInterval?: NodeJS.Timeout;
222
+ // Todo write completion strikethrough reveal animation
223
+ #todoStrikeInterval?: NodeJS.Timeout;
224
+ // Track if args are still being streamed (for edit/write spinner)
225
+ #argsComplete = false;
226
+ // Sealed once the tool reaches a terminal state (result delivered, or the
227
+ // turn abandoned it without one). Drives `isTranscriptBlockFinalized`: until
228
+ // sealed the block stays in the transcript's repaintable live region so a
229
+ // late result still repaints instead of stranding the streaming preview.
230
+ #sealed = false;
231
+ // A `job` poll result whose watched jobs are all still running. Such a
232
+ // block never finalizes (stays in the transcript live region) so a
233
+ // follow-up `job` call can displace it instead of stacking another
234
+ // "waiting on N jobs" frame. Cleared by `seal()`.
235
+ #displaceable = false;
236
+ // Probe into the owning transcript (absent outside the interactive
237
+ // transcript, e.g. in tests): whether this block is still repaintable.
238
+ #liveRegion?: TranscriptLiveRegionProbe;
239
+ // One-way latch for a detached (`async.state === "running"`) task block
240
+ // that left the transcript live region: its rows are commit-eligible
241
+ // history, so progress renders static gray and further partial snapshots are
242
+ // dropped (see #maybeFreezeBackgroundTask).
243
+ #backgroundTaskFrozen = false;
244
+ #renderState: {
245
+ spinnerFrame?: number;
246
+ expanded: boolean;
247
+ isPartial: boolean;
248
+ renderContext?: Record<string, unknown>;
249
+ } = {
250
+ expanded: false,
251
+ isPartial: true,
252
+ };
253
+
254
+ constructor(
255
+ toolName: string,
256
+ args: any,
257
+ options: ToolExecutionOptions = {},
258
+ tool: AgentTool | undefined,
259
+ ui: TUI,
260
+ cwd: string = getProjectDir(),
261
+ _toolCallId?: string,
262
+ ) {
263
+ super();
264
+ this.#toolName = toolName;
265
+ this.#toolLabel = tool?.label ?? toolName;
266
+ this.#showImages = options.showImages ?? true;
267
+ this.#editFuzzyThreshold = options.editFuzzyThreshold;
268
+ this.#editAllowFuzzy = options.editAllowFuzzy;
269
+ this.#snapshots = options.snapshots;
270
+ this.#liveRegion = options.liveRegion;
271
+ this.#tool = tool;
272
+ this.#ui = ui;
273
+ this.#cwd = cwd;
274
+ this.#args = args;
275
+ this.#editMode = resolveEditModeForTool(toolName, tool);
276
+
277
+ // Always create both - contentBox for custom tools/bash/tools with renderers, contentText for other built-ins.
278
+ // paddingY is 1 so background-tinted blocks (custom/extension tools and the
279
+ // generic fallback) get top/bottom breathing room. TranscriptContainer
280
+ // strips PLAIN-blank edges, so framed/minimal blocks (no bg set) drop these
281
+ // lines and keep their tight spacing — only tinted lines survive.
282
+ this.#contentBox = new Box(0, 1);
283
+ this.#contentText = new WidthAwareText(contentWidth => this.#formatToolExecution(contentWidth), 1, 1);
284
+
285
+ // Use Box for custom tools or built-in tools that have renderers
286
+ const hasRenderer = toolName in toolRenderers;
287
+ const hasCustomRenderer = !!(tool?.renderCall || tool?.renderResult);
288
+ if (hasCustomRenderer || hasRenderer) {
289
+ this.addChild(this.#contentBox);
290
+ } else {
291
+ this.addChild(this.#contentText);
292
+ }
293
+ // Tool blocks are visually distinct cards (background-tinted or framed),
294
+ // so keep their horizontal padding even when the user enables tight layout.
295
+ this.setIgnoreTight(true);
296
+
297
+ this.#updateDisplay();
298
+ this.#editDiffInFlight = this.#runPreviewDiff();
299
+ }
300
+
301
+ updateArgs(args: any, _toolCallId?: string): void {
302
+ // Reference-equality short-circuit before any further work. Callers
303
+ // always allocate a new arg object on each streamed delta (see
304
+ // event-controller.ts and ui-helpers.ts), so a same-reference assignment
305
+ // signals "nothing meaningful changed" and the renderer can skip.
306
+ if (args === this.#args) return;
307
+ this.#args = args;
308
+ this.#displayInputVersion++;
309
+ this.#updateSpinnerAnimation();
310
+ this.#editDiffInFlight = this.#runPreviewDiff();
311
+ this.#updateDisplay();
312
+ }
313
+
314
+ /**
315
+ * Signal that args are complete (tool is about to execute).
316
+ * This triggers an immediate final diff computation for edit-like tools.
317
+ */
318
+ setArgsComplete(_toolCallId?: string): void {
319
+ this.#argsComplete = true;
320
+ this.#updateSpinnerAnimation();
321
+ this.#editDiffInFlight = this.#runPreviewDiff();
322
+ }
323
+
324
+ /**
325
+ * Await the streaming diff recompute kicked off by the most recent
326
+ * `updateArgs`/`setArgsComplete`. The recompute reads the file and re-runs the
327
+ * whole-file Myers diff off the render path, signalling completion only via a
328
+ * throttled `requestRender`. Tests await this to sample a *settled* preview
329
+ * deterministically instead of racing the spinner's render ticks.
330
+ */
331
+ async whenPreviewSettled(): Promise<void> {
332
+ await this.#editDiffInFlight;
333
+ }
334
+
335
+ async #runPreviewDiff(): Promise<void> {
336
+ const editMode = this.#editMode;
337
+ if (!editMode) return;
338
+ const strategy = EDIT_MODE_STRATEGIES[editMode];
339
+ if (!strategy) return;
340
+
341
+ const args = this.#args;
342
+ if (args == null || typeof args !== "object") return;
343
+
344
+ const previewArgs = getArgsWithStreamedTextInput(args);
345
+ const partialJson = (previewArgs as { __partialJson?: string }).__partialJson;
346
+ let effectiveArgs: unknown;
347
+ try {
348
+ effectiveArgs = strategy.extractCompleteEdits(previewArgs, partialJson);
349
+ } catch {
350
+ effectiveArgs = previewArgs;
351
+ }
352
+
353
+ // Coalesce duplicate computes for identical args. The key pairs the
354
+ // streaming flag with a content hash: the final (args-complete) pass
355
+ // computes an untrimmed diff and must run even when the payload is
356
+ // byte-identical to the last streamed chunk — only `isStreaming` differs,
357
+ // and it flips the trailing-line trim. Without the flag a single-line edit
358
+ // whose trailing payload line never gets a newline stays stuck on the
359
+ // trimmed "no changes" streaming preview and renders no diff. Hashing keeps
360
+ // the retained key tiny instead of holding the whole serialized blob.
361
+ const streamingState = this.#argsComplete ? "final" : "stream";
362
+ let argsKey: string;
363
+ try {
364
+ argsKey = `${streamingState}:${Bun.hash(JSON.stringify(effectiveArgs))}`;
365
+ } catch {
366
+ // effectiveArgs isn't JSON-serializable (exotic value in tool args).
367
+ // The raw streamed JSON is a plain string, so hash that instead of a
368
+ // timestamp — a deterministic key keeps the dedup cache working
369
+ // instead of recomputing (and re-reading the file) on every render.
370
+ argsKey = `${streamingState}:partial:${Bun.hash(partialJson ?? "")}`;
371
+ }
372
+ if (argsKey === this.#editDiffLastArgsKey) return;
373
+ this.#editDiffLastArgsKey = argsKey;
374
+
375
+ this.#editDiffAbort?.abort();
376
+ const controller = new AbortController();
377
+ this.#editDiffAbort = controller;
378
+
379
+ try {
380
+ const isStreaming = !this.#argsComplete;
381
+ if (editMode === "hashline" && !this.#snapshots) return;
382
+ const previews = await strategy.computeDiffPreview(effectiveArgs, {
383
+ cwd: this.#cwd,
384
+ signal: controller.signal,
385
+ snapshots: this.#snapshots!,
386
+ fuzzyThreshold: this.#editFuzzyThreshold,
387
+ allowFuzzy: this.#editAllowFuzzy,
388
+ isStreaming,
389
+ });
390
+ if (controller.signal.aborted) return;
391
+ if (previews) {
392
+ this.#editDiffPreview = isStreaming ? stabilizeStreamingPreviews(previews) : previews;
393
+ this.#displayInputVersion++;
394
+ this.#updateDisplay();
395
+ this.#ui.requestRender();
396
+ }
397
+ } catch (err) {
398
+ if (controller.signal.aborted) return;
399
+ logger.warn("Edit preview diff failed", { tool: this.#toolName, error: String(err) });
400
+ }
401
+ }
402
+
403
+ updateResult(
404
+ result: {
405
+ content: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;
406
+ details?: any;
407
+ isError?: boolean;
408
+ },
409
+ isPartial = false,
410
+ _toolCallId?: string,
411
+ ): void {
412
+ // A detached task spawn keeps streaming progress snapshots after the
413
+ // block froze (left the transcript live region). Drop them: the rows are
414
+ // static gray history now, and repainting would rewrite rows the engine
415
+ // may already have committed to native scrollback. The terminal snapshot
416
+ // (async completed/failed → isPartial=false) still applies so a block
417
+ // that is still on screen settles on real results.
418
+ if (isPartial && this.#toolName === "task" && this.#maybeFreezeBackgroundTask()) {
419
+ return;
420
+ }
421
+ this.#result = result;
422
+ this.#resultVersion++;
423
+ this.#isPartial = isPartial;
424
+ // A `job` poll that found every watched job still running is transient
425
+ // "still waiting" chrome; keep the block displaceable so the next `job`
426
+ // call replaces it instead of stacking another waiting frame (see the
427
+ // event controller's displaceable-poll bookkeeping).
428
+ this.#displaceable = this.#toolName === "job" && result.isError !== true && isWaitingPollDetails(result.details);
429
+ // When tool is complete, ensure args are marked complete so spinner stops
430
+ if (!isPartial) {
431
+ this.#argsComplete = true;
432
+ }
433
+ this.#updateSpinnerAnimation();
434
+ this.#updateTodoStrikeAnimation();
435
+ this.#updateDisplay();
436
+ // Convert non-PNG images to PNG for Kitty protocol (async)
437
+ this.#maybeConvertImagesForKitty();
438
+ }
439
+
440
+ /**
441
+ * Get all image blocks from result content and details.images.
442
+ * Some tools (like generate_image) store images in details to avoid bloating model context.
443
+ */
444
+ #getAllImageBlocks(): Array<{ data?: string; mimeType?: string }> {
445
+ if (!this.#result) return [];
446
+ const contentImages = this.#result.content?.filter((c: any) => c.type === "image") || [];
447
+ const detailImages = this.#result.details?.images || [];
448
+ return [...contentImages, ...detailImages];
449
+ }
450
+
451
+ /**
452
+ * Convert non-PNG images to PNG for Kitty graphics protocol.
453
+ * Kitty requires PNG format (f=100), so JPEG/GIF/WebP won't display.
454
+ */
455
+ #maybeConvertImagesForKitty(): void {
456
+ // Only needed for Kitty protocol
457
+ if (TERMINAL.imageProtocol !== ImageProtocol.Kitty) return;
458
+ if (!this.#result) return;
459
+
460
+ const imageBlocks = this.#getAllImageBlocks();
461
+
462
+ for (let i = 0; i < imageBlocks.length; i++) {
463
+ const img = imageBlocks[i];
464
+ if (!img.data || !img.mimeType) continue;
465
+ // Skip if already PNG or already converted
466
+ if (img.mimeType === "image/png") continue;
467
+ if (this.#convertedImages.has(i)) continue;
468
+
469
+ // Convert async - catch errors from processing
470
+ const index = i;
471
+ new Bun.Image(Buffer.from(img.data, "base64"))
472
+ .png()
473
+ .toBase64()
474
+ .then(data => {
475
+ this.#convertedImages.set(index, { data, mimeType: "image/png" });
476
+ this.#displayInputVersion++;
477
+ this.#updateDisplay();
478
+ this.#ui.requestRender();
479
+ })
480
+ .catch(() => {
481
+ // Ignore conversion failures - display will use original image format
482
+ });
483
+ }
484
+ }
485
+
486
+ /**
487
+ * Start or stop spinner animation based on whether this is a partial task result.
488
+ */
489
+ #updateSpinnerAnimation(): void {
490
+ // Spinner for: task tool with partial result, or edit/write while args streaming
491
+ const isStreamingArgs = !this.#argsComplete && (isEditLikeToolName(this.#toolName) || this.#toolName === "write");
492
+ const isBackgroundAsyncRunning =
493
+ (this.#result?.details as { async?: { state?: string } } | undefined)?.async?.state === "running";
494
+ const isBackgroundAsyncTask = this.#toolName === "task" && isBackgroundAsyncRunning;
495
+ const isPartialTask = this.#isPartial && this.#toolName === "task" && !isBackgroundAsyncTask;
496
+ // Detached async task progress rows are static now; progress snapshots
497
+ // still call #maybeFreezeBackgroundTask before applying so rows settle
498
+ // once the block leaves the live region.
499
+ const needsSpinner = isStreamingArgs || isPartialTask || this.isDisplaceableBlock();
500
+ if (needsSpinner && !this.#spinnerInterval) {
501
+ const frameCount = theme.spinnerFrames.length;
502
+ const frame = sharedSpinnerFrame(frameCount);
503
+ this.#spinnerFrame = frame;
504
+ this.#renderState.spinnerFrame = frame;
505
+ this.#spinnerInterval = setInterval(() => {
506
+ // If a detached task interval from an older render path is still live,
507
+ // stop it the instant the block leaves the repaintable region.
508
+ if (this.#maybeFreezeBackgroundTask()) return;
509
+ const now = performance.now();
510
+ const frameCount = theme.spinnerFrames.length;
511
+ this.#spinnerFrame = sharedSpinnerFrame(frameCount, now);
512
+ this.#renderState.spinnerFrame = this.#spinnerFrame;
513
+ this.#ui.requestRender();
514
+ }, SPINNER_RENDER_INTERVAL_MS);
515
+ } else if (!needsSpinner && this.#spinnerInterval) {
516
+ clearInterval(this.#spinnerInterval);
517
+ this.#spinnerInterval = undefined;
518
+ // Clear the last drawn frame so a non-live renderCall (e.g. a write whose
519
+ // args just completed) stops showing a frozen spinner glyph. Skip when a
520
+ // todo strike owns the frame — it sets its own value right after this.
521
+ if (!this.#todoStrikeInterval) {
522
+ this.#spinnerFrame = undefined;
523
+ this.#renderState.spinnerFrame = undefined;
524
+ }
525
+ }
526
+ }
527
+
528
+ /**
529
+ * Freeze a detached (`async.state === "running"`) task block once it leaves
530
+ * the transcript's live region. Past that seam its rows are commit-eligible
531
+ * native-scrollback history: repaint the progress rows static gray and drop
532
+ * further partial snapshots. One-way — blocks never re-enter the live
533
+ * region. Returns whether the block is frozen.
534
+ */
535
+ #maybeFreezeBackgroundTask(): boolean {
536
+ if (this.#backgroundTaskFrozen) return true;
537
+ if (this.#toolName !== "task" || this.#liveRegion === undefined) return false;
538
+ const asyncState = (this.#result?.details as { async?: { state?: string } } | undefined)?.async?.state;
539
+ if (asyncState !== "running") return false;
540
+ if (this.#liveRegion.isBlockInLiveRegion(this)) return false;
541
+ this.#backgroundTaskFrozen = true;
542
+ this.#updateSpinnerAnimation();
543
+ this.#updateDisplay();
544
+ this.#ui.requestRender();
545
+ return true;
546
+ }
547
+
548
+ #updateTodoStrikeAnimation(): void {
549
+ if (this.#toolName !== "todo" || this.#isPartial || this.#result?.isError) {
550
+ this.#stopTodoStrikeAnimation();
551
+ return;
552
+ }
553
+ const completedTasks = (this.#result?.details as { completedTasks?: unknown[] } | undefined)?.completedTasks;
554
+ if (!completedTasks || completedTasks.length === 0) {
555
+ this.#stopTodoStrikeAnimation();
556
+ return;
557
+ }
558
+ if (this.#todoStrikeInterval) return;
559
+
560
+ this.#spinnerFrame = 0;
561
+ this.#renderState.spinnerFrame = 0;
562
+ this.#todoStrikeInterval = setInterval(() => {
563
+ const nextFrame = (this.#spinnerFrame ?? 0) + 1;
564
+ if (nextFrame > TODO_STRIKE_TOTAL_FRAMES) {
565
+ this.#stopTodoStrikeAnimation();
566
+ } else {
567
+ this.#spinnerFrame = nextFrame;
568
+ this.#renderState.spinnerFrame = nextFrame;
569
+ }
570
+ this.#ui.requestRender();
571
+ }, 65);
572
+ }
573
+
574
+ #stopTodoStrikeAnimation(): void {
575
+ if (this.#todoStrikeInterval) {
576
+ clearInterval(this.#todoStrikeInterval);
577
+ this.#todoStrikeInterval = undefined;
578
+ }
579
+ if (!this.#spinnerInterval) {
580
+ this.#spinnerFrame = undefined;
581
+ this.#renderState.spinnerFrame = undefined;
582
+ }
583
+ }
584
+
585
+ /**
586
+ * Standalone harnesses may mount a tool component directly under `TUI`
587
+ * instead of inside `TranscriptContainer`. In that shape the component must
588
+ * report its own live-region seam for provisional previews, or the core
589
+ * renderer treats it like shell output and commits tail-window edit/eval/bash
590
+ * previews to immutable native scrollback before the result replaces them.
591
+ */
592
+ getNativeScrollbackLiveRegionStart(): number | undefined {
593
+ return !this.isTranscriptBlockFinalized() && !this.isTranscriptBlockCommitStable() ? 0 : undefined;
594
+ }
595
+
596
+ /**
597
+ * Whether this block has reached a terminal state for transcript freezing.
598
+ * Reports `false` while it can still visually change so the
599
+ * {@link TranscriptContainer} keeps it inside the repaintable live region:
600
+ * a foreground tool awaiting its result, or one streaming partial output.
601
+ * A final (non-partial) result, a background-async tool the agent has moved
602
+ * past, or an explicit {@link seal} flips it to `true`.
603
+ */
604
+ isTranscriptBlockFinalized(): boolean {
605
+ if (this.#sealed) return true;
606
+ if (this.#result === undefined) return false;
607
+ // A displaceable waiting poll stays live: its rows are kept out of
608
+ // native scrollback so a follow-up `job` call can remove the block.
609
+ if (this.#displaceable) return false;
610
+ if (!this.#isPartial) return true;
611
+ // Partial result: a background async tool is accepted to freeze (the agent
612
+ // continues while it runs and would otherwise pin an unbounded live region);
613
+ // a foreground tool streaming partial output stays live until it finishes.
614
+ return (this.#result.details as { async?: { state?: string } } | undefined)?.async?.state === "running";
615
+ }
616
+
617
+ /**
618
+ * Whether this still-live block's settled rows may enter native scrollback
619
+ * (see `FinalizableBlock.isTranscriptBlockCommitStable`). Renderers classify
620
+ * pending views by durability instead of by tool name: a provisional view is
621
+ * allowed to be useful on screen, but finalization may replace or re-anchor
622
+ * it wholesale, so committing any of its rows would strand stale preview
623
+ * bytes in immutable scrollback. Non-provisional views stream rows whose
624
+ * committed prefix survives the remaining transitions.
625
+ */
626
+ isTranscriptBlockCommitStable(): boolean {
627
+ if (this.#displaceable) return false;
628
+ if (this.isTranscriptBlockFinalized()) return true;
629
+ // `provisionalPendingPreview` describes only the PENDING call preview
630
+ // (`renderCall`, before any result): the result render may re-anchor it
631
+ // wholesale, so its rows must never commit. Once a (streaming partial)
632
+ // result exists the result renderer is the live shape — its body is
633
+ // top-anchored and grows append-only, and `deriveLiveCommitState` gates
634
+ // per-row durability — so the block is commit-stable like any settled
635
+ // stream. Gating the flag on the pending phase is what keeps a collapsed
636
+ // streaming eval/bash/ssh whose box outgrows the viewport from stranding
637
+ // its head: while commit-unstable its scrolled-off top committed nowhere
638
+ // and repainted nowhere, so it read as truncated until ctrl+o (expanded)
639
+ // flipped it stable.
640
+ if (this.#result !== undefined) return true;
641
+ const tool = this.#tool as { provisionalPendingPreview?: boolean | "collapsed" } | undefined;
642
+ const provisionalPendingPreview =
643
+ tool?.provisionalPendingPreview ?? toolRenderers[this.#toolName]?.provisionalPendingPreview;
644
+ return provisionalPendingPreview !== true && (provisionalPendingPreview !== "collapsed" || this.#expanded);
645
+ }
646
+
647
+ /**
648
+ * Mark the tool terminal even though no result arrived (the turn aborted or
649
+ * abandoned it) and stop animating, so it can freeze and stops pinning the
650
+ * transcript live region.
651
+ */
652
+ seal(): void {
653
+ if (this.#sealed) return;
654
+ this.#sealed = true;
655
+ this.#displaceable = false;
656
+ // A sealed detached task is abandoned history: settle its progress rows
657
+ // on static gray.
658
+ this.#backgroundTaskFrozen = true;
659
+ this.stopAnimation();
660
+ this.#updateDisplay();
661
+ this.#ui.requestRender();
662
+ }
663
+
664
+ /**
665
+ * Whether this block is a waiting `job` poll (every watched job still
666
+ * running) that has not been sealed. Such a block never finalized, so none
667
+ * of its rows entered native scrollback (the ticking spinner keeps the
668
+ * stable-prefix ratchet at zero) and the whole block can be removed when a
669
+ * follow-up `job` call supersedes it.
670
+ */
671
+ isDisplaceableBlock(): boolean {
672
+ return this.#displaceable && !this.#sealed;
673
+ }
674
+
675
+ /**
676
+ * Stop spinner animation and cleanup resources.
677
+ */
678
+ stopAnimation(): void {
679
+ if (this.#spinnerInterval) {
680
+ clearInterval(this.#spinnerInterval);
681
+ this.#spinnerInterval = undefined;
682
+ this.#spinnerFrame = undefined;
683
+ this.#renderState.spinnerFrame = undefined;
684
+ }
685
+ this.#stopTodoStrikeAnimation();
686
+ this.#editDiffAbort?.abort();
687
+ this.#editDiffAbort = undefined;
688
+ }
689
+
690
+ setExpanded(expanded: boolean): void {
691
+ this.#expanded = expanded;
692
+ this.#updateDisplay();
693
+ }
694
+
695
+ setShowImages(show: boolean): void {
696
+ this.#showImages = show;
697
+ this.#updateDisplay();
698
+ }
699
+
700
+ override invalidate(): void {
701
+ super.invalidate();
702
+ this.#updateDisplay();
703
+ }
704
+
705
+ #updateDisplay(): void {
706
+ // `TERMINAL.imageProtocol` is resolved by an async capability probe during
707
+ // TUI startup, so a result rendered before it lands must re-shape once it
708
+ // does (it gates Image children vs text fallback in #rebuildDisplay); keyed
709
+ // here for the same reason markdown.ts keys its render cache on it.
710
+ const key = `${this.#resultVersion}|${this.#expanded}|${this.#isPartial}|${this.#spinnerFrame ?? "-"}|${this.#showImages}|${getThemeEpoch()}|${this.#displayInputVersion}|${this.#backgroundTaskFrozen}|${TERMINAL.imageProtocol ?? "-"}|${this.#imageSizeKey()}`;
711
+ if (key === this.#lastDisplayKey && this.#displayBuilt) return;
712
+ this.#lastDisplayKey = key;
713
+
714
+ this.#rebuildDisplay();
715
+ this.#displayBuilt = true;
716
+ }
717
+
718
+ // Viewport-/settings-dependent image sizing folded into the memo key only when
719
+ // the last rebuild actually emitted images, so a terminal resize re-shapes an
720
+ // image-bearing result (to rescale it) without re-shaping every image-free
721
+ // result on each resize tick.
722
+ #imageSizeKey(): string {
723
+ if (this.#renderedImageCount === 0) return "-";
724
+ const o = resolveImageOptions();
725
+ return `${o.maxWidthCells}:${o.maxHeightCells ?? "-"}`;
726
+ }
727
+
728
+ #rebuildDisplay(): void {
729
+ // Sync shared mutable render state for component closures
730
+ this.#renderState.expanded = this.#expanded;
731
+ this.#renderState.isPartial = this.#isPartial;
732
+ this.#renderState.spinnerFrame = this.#spinnerFrame;
733
+
734
+ // Non-self-framing tools (custom/extension renderers and the generic
735
+ // fallback) get a padded, state-tinted block — built-ins that draw their
736
+ // own frame opt out below via the framed-component mark.
737
+ const stateBgKey = this.#isPartial ? "toolPendingBg" : this.#result?.isError ? "toolErrorBg" : "toolSuccessBg";
738
+ const stateBgFn = (t: string) => theme.bg(stateBgKey, t);
739
+
740
+ // Check for custom tool rendering
741
+ if (this.#tool && (this.#tool.renderCall || this.#tool.renderResult)) {
742
+ const tool = this.#tool;
743
+ const mergeCallAndResult = Boolean((tool as { mergeCallAndResult?: boolean }).mergeCallAndResult);
744
+ // Custom tools use Box for flexible component rendering
745
+ this.#contentBox.setBgFn(undefined);
746
+ this.#contentBox.clear();
747
+ // Mirror the built-in renderer branch so custom renderers (notably the
748
+ // task tool, whose live instance routes through here) receive the same
749
+ // render context — e.g. the `hasResult` flag that suppresses the task
750
+ // call preview once result lines exist.
751
+ this.#renderState.renderContext = this.#buildRenderContext();
752
+
753
+ // Render call component. The fallback label only stands in for a
754
+ // missing `renderCall`; when the call is intentionally suppressed
755
+ // (mergeCallAndResult once a result exists) we render nothing here so
756
+ // the result component isn't preceded by a redundant tool-name line.
757
+ const shouldRenderCall = !this.#result || !mergeCallAndResult;
758
+ if (shouldRenderCall) {
759
+ if (tool.renderCall) {
760
+ try {
761
+ const callComponent = tool.renderCall(this.#getCallArgsForRender(), this.#renderState, theme);
762
+ if (callComponent) this.#contentBox.addChild(callComponent as Component);
763
+ } catch (err) {
764
+ logger.warn("Tool renderer failed", { tool: this.#toolName, error: String(err) });
765
+ // Fall back to default on error
766
+ this.#contentBox.addChild(new Text(theme.fg("toolTitle", theme.bold(this.#toolLabel)), 0, 0));
767
+ }
768
+ } else {
769
+ // No custom renderCall, show tool name
770
+ this.#contentBox.addChild(new Text(theme.fg("toolTitle", theme.bold(this.#toolLabel)), 0, 0));
771
+ }
772
+ }
773
+
774
+ // Render result component if we have a result
775
+ if (this.#result && tool.renderResult) {
776
+ try {
777
+ const renderResult = tool.renderResult as (
778
+ result: { content: Array<{ type: string; text?: string }>; details?: unknown; isError?: boolean },
779
+ options: { expanded: boolean; isPartial: boolean; spinnerFrame?: number },
780
+ theme: Theme,
781
+ args?: unknown,
782
+ ) => Component;
783
+ const resultComponent = renderResult(
784
+ {
785
+ content: this.#result.content as any,
786
+ details: this.#result.details,
787
+ isError: this.#result.isError,
788
+ },
789
+ this.#renderState,
790
+ theme,
791
+ this.#args,
792
+ );
793
+ if (resultComponent) this.#contentBox.addChild(resultComponent);
794
+ } catch (err) {
795
+ logger.warn("Tool renderer failed", { tool: this.#toolName, error: String(err) });
796
+ // Fall back to showing raw output on error
797
+ const output = this.#getTextOutput();
798
+ if (output) {
799
+ this.#contentBox.addChild(new Text(theme.fg("toolOutput", replaceTabs(output)), 0, 0));
800
+ }
801
+ }
802
+ } else if (this.#result) {
803
+ // Has result but no custom renderResult
804
+ const output = this.#getTextOutput();
805
+ if (output) {
806
+ this.#contentBox.addChild(new Text(theme.fg("toolOutput", replaceTabs(output)), 0, 0));
807
+ }
808
+ }
809
+ // Custom tools that draw their own frame (task) render flush; plain
810
+ // extension renderers get the padded, state-tinted block back.
811
+ const customFramed = this.#contentBox.children.some(isFramedBlockComponent);
812
+ this.#contentBox.setPaddingX(customFramed ? 0 : 1);
813
+ this.#contentBox.setBgFn(customFramed ? undefined : stateBgFn);
814
+ } else if (this.#toolName in toolRenderers) {
815
+ // Built-in tools with renderers
816
+ const renderer = toolRenderers[this.#toolName];
817
+
818
+ // Clean up previous multi-file boxes
819
+ for (const box of this.#multiFileBoxes) {
820
+ this.removeChild(box);
821
+ }
822
+ this.#multiFileBoxes = [];
823
+
824
+ // Check for multi-file edit results
825
+ const perFileResults = this.#result?.details?.perFileResults as
826
+ | Array<{ path: string; isError?: boolean }>
827
+ | undefined;
828
+ if (perFileResults && perFileResults.length > 1) {
829
+ // Multi-file: render each file as its own Box (identical to separate tool calls)
830
+ this.#contentBox.setBgFn(undefined);
831
+ this.#contentBox.clear();
832
+
833
+ const renderContext = this.#buildRenderContext();
834
+ this.#renderState.renderContext = renderContext;
835
+
836
+ for (let i = 0; i < perFileResults.length; i++) {
837
+ const fileResult = perFileResults[i];
838
+ if (i > 0) {
839
+ const spacer = new Spacer(1);
840
+ this.#multiFileBoxes.push(spacer);
841
+ this.addChild(spacer);
842
+ }
843
+ const fileBox = new Box(0, 0);
844
+ try {
845
+ const resultComponent = renderer.renderResult(
846
+ { content: [], details: fileResult, isError: fileResult.isError },
847
+ this.#renderState,
848
+ theme,
849
+ );
850
+ if (resultComponent) fileBox.addChild(resultComponent);
851
+ } catch (err) {
852
+ logger.warn("Tool renderer failed", { tool: this.#toolName, error: String(err) });
853
+ }
854
+ this.#multiFileBoxes.push(fileBox);
855
+ this.addChild(fileBox);
856
+ }
857
+
858
+ // Show pending indicator for remaining files
859
+ const totalFiles = this.#args?.edits
860
+ ? new Set((this.#args.edits as any[]).map((e: any) => e?.path).filter(Boolean)).size
861
+ : 0;
862
+ const remaining = Math.max(0, totalFiles - perFileResults.length);
863
+ if (remaining > 0 && this.#isPartial) {
864
+ const pendingSpacer = new Spacer(1);
865
+ this.#multiFileBoxes.push(pendingSpacer);
866
+ this.addChild(pendingSpacer);
867
+ const pendingBox = new Box(0, 0);
868
+ const pendingText = renderStatusLine(
869
+ {
870
+ icon: "pending",
871
+ title: "Edit",
872
+ description: theme.fg("dim", `${remaining} more file${remaining > 1 ? "s" : ""} pending…`),
873
+ },
874
+ theme,
875
+ );
876
+ pendingBox.addChild(new Text(pendingText, 0, 0));
877
+ this.#multiFileBoxes.push(pendingBox);
878
+ this.addChild(pendingBox);
879
+ }
880
+ } else {
881
+ // Single-file or no result: standard rendering
882
+ // Inline renderers skip background styling
883
+ this.#contentBox.setBgFn(undefined);
884
+ this.#contentBox.clear();
885
+
886
+ const renderContext = this.#buildRenderContext();
887
+ this.#renderState.renderContext = renderContext;
888
+
889
+ const shouldRenderCall = !this.#result || !renderer.mergeCallAndResult;
890
+ if (shouldRenderCall) {
891
+ // Render call component
892
+ try {
893
+ const callComponent = renderer.renderCall(this.#getCallArgsForRender(), this.#renderState, theme);
894
+ if (callComponent) this.#contentBox.addChild(callComponent);
895
+ } catch (err) {
896
+ logger.warn("Tool renderer failed", { tool: this.#toolName, error: String(err) });
897
+ // Fall back to default on error
898
+ this.#contentBox.addChild(new Text(theme.fg("toolTitle", theme.bold(this.#toolLabel)), 0, 0));
899
+ }
900
+ }
901
+
902
+ // Render result component if we have a result
903
+ if (this.#result) {
904
+ try {
905
+ const resultComponent = renderer.renderResult(
906
+ {
907
+ content: this.#result.content as any,
908
+ details: this.#result.details,
909
+ isError: this.#result.isError,
910
+ },
911
+ this.#renderState,
912
+ theme,
913
+ this.#getCallArgsForRender(),
914
+ );
915
+ if (resultComponent) this.#contentBox.addChild(resultComponent);
916
+ } catch (err) {
917
+ logger.warn("Tool renderer failed", { tool: this.#toolName, error: String(err) });
918
+ // Fall back to showing raw output on error
919
+ const output = this.#getTextOutput();
920
+ if (output) {
921
+ this.#contentBox.addChild(new Text(theme.fg("toolOutput", replaceTabs(output)), 0, 0));
922
+ }
923
+ }
924
+ }
925
+ }
926
+ } else {
927
+ // Generic fallback (no custom/built-in renderer). WidthAwareText
928
+ // reformats at render time so output fills the actual terminal width
929
+ // instead of a fixed column cap.
930
+ this.#contentText.setCustomBgFn(stateBgFn);
931
+ this.#contentText.invalidate();
932
+ }
933
+
934
+ // Handle images (same for both custom and built-in)
935
+ for (const img of this.#imageComponents) {
936
+ this.removeChild(img);
937
+ }
938
+ this.#imageComponents = [];
939
+ for (const spacer of this.#imageSpacers) {
940
+ this.removeChild(spacer);
941
+ }
942
+ this.#imageSpacers = [];
943
+
944
+ if (this.#result) {
945
+ const imageBlocks = this.#getAllImageBlocks();
946
+
947
+ for (let i = 0; i < imageBlocks.length; i++) {
948
+ const img = imageBlocks[i];
949
+ if (TERMINAL.imageProtocol && this.#showImages && img.data && img.mimeType) {
950
+ // Use converted PNG for Kitty protocol if available
951
+ const converted = this.#convertedImages.get(i);
952
+ const imageData = converted?.data ?? img.data;
953
+ const imageMimeType = converted?.mimeType ?? img.mimeType;
954
+
955
+ // For Kitty, skip non-PNG images that haven't been converted yet
956
+ if (TERMINAL.imageProtocol === ImageProtocol.Kitty && imageMimeType !== "image/png") {
957
+ continue;
958
+ }
959
+
960
+ const spacer = new Spacer(1);
961
+ this.addChild(spacer);
962
+ this.#imageSpacers.push(spacer);
963
+ const imageComponent = new Image(
964
+ imageData,
965
+ imageMimeType,
966
+ { fallbackColor: (s: string) => theme.fg("toolOutput", s) },
967
+ { ...resolveImageOptions(), budget: this.#ui.imageBudget, imageKey: `te${this.#instanceId}:${i}` },
968
+ );
969
+ this.#imageComponents.push(imageComponent);
970
+ this.addChild(imageComponent);
971
+ }
972
+ }
973
+ }
974
+ this.#renderedImageCount = this.#imageComponents.length;
975
+ }
976
+
977
+ #getCallArgsForRender(): any {
978
+ const renderArgs = getArgsWithStreamedTextInput(this.#args);
979
+ if (!isEditLikeToolName(this.#toolName)) {
980
+ return renderArgs;
981
+ }
982
+ const previews = this.#editDiffPreview;
983
+ if (!previews || previews.length === 0) {
984
+ return renderArgs;
985
+ }
986
+ // Single-file previews feed the existing `previewDiff` channel consumed
987
+ // by `formatStreamingDiff` in the renderer.
988
+ const first = previews[0];
989
+ if (!first?.diff) {
990
+ return renderArgs;
991
+ }
992
+ return { ...(renderArgs as Record<string, unknown>), previewDiff: first.diff };
993
+ }
994
+
995
+ /**
996
+ * Build render context for tools that need extra state (bash, python, edit)
997
+ */
998
+ #buildRenderContext(): Record<string, unknown> {
999
+ const context: Record<string, unknown> = {};
1000
+ const normalizeTimeoutSeconds = (value: unknown, maxSeconds: number): number | undefined => {
1001
+ if (typeof value !== "number" || !Number.isFinite(value)) return undefined;
1002
+ return Math.max(1, Math.min(maxSeconds, value));
1003
+ };
1004
+
1005
+ if (this.#toolName === "bash") {
1006
+ // Bash needs render context even before a result exists. The renderer uses the pending-call args
1007
+ // plus this context to keep the inline command preview visible while tool-call JSON is still streaming.
1008
+ if (this.#result) {
1009
+ // Pass raw output and expanded state - renderer handles width-aware truncation
1010
+ const output = this.#getTextOutput().trimEnd();
1011
+ context.output = output;
1012
+ }
1013
+ context.expanded = this.#expanded;
1014
+ context.previewLines = BASH_DEFAULT_PREVIEW_LINES;
1015
+ context.timeout = normalizeTimeoutSeconds(this.#args?.timeout, 3600);
1016
+ } else if (this.#toolName === "eval" && this.#result) {
1017
+ const output = this.#getTextOutput().trimEnd();
1018
+ context.output = output;
1019
+ context.expanded = this.#expanded;
1020
+ context.previewLines = EVAL_DEFAULT_PREVIEW_LINES;
1021
+ } else if (this.#toolName === "task") {
1022
+ // Once a result snapshot exists the task renderer's `renderResult`
1023
+ // draws every dispatched agent as a progress/result line, so tell
1024
+ // `renderCall` to drop its duplicate streaming preview list.
1025
+ context.hasResult = Boolean(this.#result);
1026
+ // Out of the transcript live region: progress rows render static gray
1027
+ // (see task/render.ts).
1028
+ context.frozen = this.#backgroundTaskFrozen;
1029
+ } else if (isEditLikeToolName(this.#toolName)) {
1030
+ context.editMode = this.#editMode;
1031
+ const previews = this.#editDiffPreview;
1032
+ if (previews && previews.length > 0) {
1033
+ const first = previews[0];
1034
+ if (first?.diff || first?.error) {
1035
+ context.editDiffPreview = first.error
1036
+ ? { error: first.error }
1037
+ : { diff: first.diff ?? "", firstChangedLine: first.firstChangedLine };
1038
+ }
1039
+ if (previews.length > 1) {
1040
+ context.perFileDiffPreview = previews;
1041
+ }
1042
+ }
1043
+ if (!previews?.some(preview => preview.diff)) {
1044
+ const editMode = this.#editMode;
1045
+ const strategy = editMode ? EDIT_MODE_STRATEGIES[editMode] : undefined;
1046
+ const fallback = strategy?.renderStreamingFallback(getArgsWithStreamedTextInput(this.#args), theme);
1047
+ if (fallback) context.editStreamingFallback = fallback;
1048
+ }
1049
+ context.renderDiff = renderDiff;
1050
+ }
1051
+
1052
+ return context;
1053
+ }
1054
+
1055
+ #getTextOutput(): string {
1056
+ if (!this.#result) return "";
1057
+
1058
+ const textBlocks = this.#result.content?.filter((c: any) => c.type === "text") || [];
1059
+ const imageBlocks = this.#getAllImageBlocks();
1060
+
1061
+ let output = textBlocks
1062
+ .map((c: any) => {
1063
+ return sanitizeWithOptionalSixelPassthrough(c.text || "", sanitizeText);
1064
+ })
1065
+ .join("\n");
1066
+
1067
+ if (imageBlocks.length > 0 && (!TERMINAL.imageProtocol || !this.#showImages)) {
1068
+ const imageIndicators = imageBlocks
1069
+ .map((img: any) => {
1070
+ const dims = img.data ? (getImageDimensions(img.data, img.mimeType) ?? undefined) : undefined;
1071
+ return imageFallback(img.mimeType, dims);
1072
+ })
1073
+ .join("\n");
1074
+ output = output ? `${output}\n${imageIndicators}` : imageIndicators;
1075
+ }
1076
+
1077
+ return output;
1078
+ }
1079
+
1080
+ /**
1081
+ * Format a generic tool execution (fallback for tools without custom renderers)
1082
+ */
1083
+ #formatToolExecution(contentWidth: number): string {
1084
+ const lines: string[] = [];
1085
+ const icon = this.#isPartial ? "pending" : this.#result?.isError ? "error" : "done";
1086
+ lines.push(renderStatusLine({ icon, title: this.#toolLabel }, theme));
1087
+
1088
+ const argsObject = this.#args && typeof this.#args === "object" ? (this.#args as Record<string, unknown>) : null;
1089
+ if (!this.#expanded && argsObject && Object.keys(argsObject).length > 0) {
1090
+ // Budget the inline preview against the render width, leaving room for
1091
+ // the ` └─ ` connector prefix instead of a fixed cap.
1092
+ const inlineBudget = Math.max(20, contentWidth - Bun.stringWidth(theme.tree.last) - 2);
1093
+ const preview = formatArgsInline(argsObject, inlineBudget);
1094
+ if (preview) {
1095
+ lines.push(` ${theme.fg("dim", theme.tree.last)} ${theme.fg("dim", preview)}`);
1096
+ }
1097
+ }
1098
+
1099
+ if (this.#expanded && this.#args !== undefined) {
1100
+ lines.push("");
1101
+ lines.push(theme.fg("dim", "Args"));
1102
+ const tree = renderJsonTreeLines(
1103
+ this.#args,
1104
+ theme,
1105
+ JSON_TREE_MAX_DEPTH_EXPANDED,
1106
+ JSON_TREE_MAX_LINES_EXPANDED,
1107
+ JSON_TREE_SCALAR_LEN_EXPANDED,
1108
+ );
1109
+ lines.push(...tree.lines);
1110
+ if (tree.truncated) {
1111
+ lines.push(theme.fg("dim", "…"));
1112
+ }
1113
+ lines.push("");
1114
+ }
1115
+
1116
+ if (!this.#result) {
1117
+ return lines.join("\n");
1118
+ }
1119
+
1120
+ const textContent = this.#getTextOutput().trimEnd();
1121
+ if (!textContent) {
1122
+ lines.push(theme.fg("dim", "(no output)"));
1123
+ return lines.join("\n");
1124
+ }
1125
+
1126
+ if (textContent.startsWith("{") || textContent.startsWith("[")) {
1127
+ try {
1128
+ const parsed = JSON.parse(textContent);
1129
+ const maxDepth = this.#expanded ? JSON_TREE_MAX_DEPTH_EXPANDED : JSON_TREE_MAX_DEPTH_COLLAPSED;
1130
+ const maxLines = this.#expanded ? JSON_TREE_MAX_LINES_EXPANDED : JSON_TREE_MAX_LINES_COLLAPSED;
1131
+ const maxScalarLen = this.#expanded ? JSON_TREE_SCALAR_LEN_EXPANDED : JSON_TREE_SCALAR_LEN_COLLAPSED;
1132
+ const tree = renderJsonTreeLines(parsed, theme, maxDepth, maxLines, maxScalarLen);
1133
+
1134
+ if (tree.lines.length > 0) {
1135
+ lines.push(...tree.lines);
1136
+ if (!this.#expanded) {
1137
+ lines.push(formatExpandHint(theme, this.#expanded, true));
1138
+ } else if (tree.truncated) {
1139
+ lines.push(theme.fg("dim", "…"));
1140
+ }
1141
+ return lines.join("\n");
1142
+ }
1143
+ } catch {
1144
+ // Fall through to raw output
1145
+ }
1146
+ }
1147
+
1148
+ const outputLines = textContent.split("\n");
1149
+ const maxOutputLines = this.#expanded ? 12 : 4;
1150
+ const displayLines = outputLines.slice(0, maxOutputLines);
1151
+
1152
+ for (const line of displayLines) {
1153
+ lines.push(theme.fg("toolOutput", truncateToWidth(replaceTabs(line), contentWidth)));
1154
+ }
1155
+
1156
+ if (outputLines.length > maxOutputLines) {
1157
+ const remaining = outputLines.length - maxOutputLines;
1158
+ lines.push(`${theme.fg("dim", `… ${remaining} more lines`)} ${formatExpandHint(theme, this.#expanded, true)}`);
1159
+ } else if (!this.#expanded) {
1160
+ lines.push(formatExpandHint(theme, this.#expanded, true));
1161
+ }
1162
+
1163
+ return lines.join("\n");
1164
+ }
1165
+ }