@kr78/pi-coding-agent 17.2.10

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 (1593) hide show
  1. package/CHANGELOG.md +14861 -0
  2. package/README.md +35 -0
  3. package/dist/CHANGELOG-chtdxh1z.md +14861 -0
  4. package/dist/cli.js +20483 -0
  5. package/dist/template-c2hyaytt.js +1653 -0
  6. package/dist/template-f8wx9vfn.css +1355 -0
  7. package/dist/template-qat058wr.html +55 -0
  8. package/dist/tool-views.generated-jdfmzwmn.js +35 -0
  9. package/examples/README.md +21 -0
  10. package/examples/custom-tools/README.md +104 -0
  11. package/examples/custom-tools/hello/index.ts +20 -0
  12. package/examples/extensions/README.md +142 -0
  13. package/examples/extensions/api-demo.ts +78 -0
  14. package/examples/extensions/chalk-logger.ts +25 -0
  15. package/examples/extensions/hello.ts +31 -0
  16. package/examples/extensions/pirate.ts +43 -0
  17. package/examples/extensions/plan-mode.ts +549 -0
  18. package/examples/extensions/reload-runtime.ts +38 -0
  19. package/examples/extensions/thinking-note.ts +13 -0
  20. package/examples/extensions/tools.ts +145 -0
  21. package/examples/extensions/with-deps/index.ts +36 -0
  22. package/examples/extensions/with-deps/package-lock.json +31 -0
  23. package/examples/extensions/with-deps/package.json +17 -0
  24. package/examples/hooks/README.md +56 -0
  25. package/examples/hooks/auto-commit-on-exit.ts +48 -0
  26. package/examples/hooks/confirm-destructive.ts +58 -0
  27. package/examples/hooks/custom-compaction.ts +115 -0
  28. package/examples/hooks/dirty-repo-guard.ts +51 -0
  29. package/examples/hooks/file-trigger.ts +40 -0
  30. package/examples/hooks/git-checkpoint.ts +52 -0
  31. package/examples/hooks/handoff.ts +149 -0
  32. package/examples/hooks/permission-gate.ts +33 -0
  33. package/examples/hooks/protected-paths.ts +29 -0
  34. package/examples/hooks/qna.ts +118 -0
  35. package/examples/hooks/status-line.ts +39 -0
  36. package/examples/sdk/01-minimal.ts +21 -0
  37. package/examples/sdk/02-custom-model.ts +49 -0
  38. package/examples/sdk/03-custom-prompt.ts +46 -0
  39. package/examples/sdk/04-skills.ts +43 -0
  40. package/examples/sdk/06-extensions.ts +82 -0
  41. package/examples/sdk/06-hooks.ts +61 -0
  42. package/examples/sdk/07-context-files.ts +35 -0
  43. package/examples/sdk/08-prompt-templates.ts +41 -0
  44. package/examples/sdk/08-slash-commands.ts +46 -0
  45. package/examples/sdk/09-api-keys-and-oauth.ts +54 -0
  46. package/examples/sdk/11-sessions.ts +47 -0
  47. package/examples/sdk/12-redis-sessions.ts +54 -0
  48. package/examples/sdk/13-sql-sessions.ts +61 -0
  49. package/examples/sdk/README.md +169 -0
  50. package/package.json +587 -0
  51. package/scripts/bench-guard.ts +71 -0
  52. package/scripts/bench-title-models.ts +332 -0
  53. package/scripts/build-binary.ts +117 -0
  54. package/scripts/bundle-dist.ts +123 -0
  55. package/scripts/compile-binary.ts +69 -0
  56. package/scripts/embed-mupdf-wasm.ts +67 -0
  57. package/scripts/format-prompts.ts +68 -0
  58. package/scripts/generate-aria-snapshot.ts +134 -0
  59. package/scripts/generate-docs-index.ts +58 -0
  60. package/scripts/generate-share-viewer.ts +34 -0
  61. package/scripts/legacy-pi-virtual-module.ts +205 -0
  62. package/scripts/measure-prompt-tokens.ts +63 -0
  63. package/scripts/omp +51 -0
  64. package/scripts/omp.ts +19 -0
  65. package/scripts/security-compare.ts +40 -0
  66. package/src/advisor/advise-tool.ts +234 -0
  67. package/src/advisor/config.ts +341 -0
  68. package/src/advisor/emission-guard.ts +172 -0
  69. package/src/advisor/index.ts +6 -0
  70. package/src/advisor/runtime.ts +1412 -0
  71. package/src/advisor/transcript-recorder.ts +215 -0
  72. package/src/advisor/watchdog.ts +135 -0
  73. package/src/async/index.ts +1 -0
  74. package/src/async/job-manager.ts +847 -0
  75. package/src/auto-thinking/classifier.ts +220 -0
  76. package/src/autolearn/controller.ts +152 -0
  77. package/src/autolearn/managed-skills.ts +255 -0
  78. package/src/autoresearch/command-resume.md +14 -0
  79. package/src/autoresearch/dashboard.ts +436 -0
  80. package/src/autoresearch/git.ts +331 -0
  81. package/src/autoresearch/helpers.ts +218 -0
  82. package/src/autoresearch/index.ts +541 -0
  83. package/src/autoresearch/prompt-setup.md +43 -0
  84. package/src/autoresearch/prompt.md +103 -0
  85. package/src/autoresearch/resume-message.md +10 -0
  86. package/src/autoresearch/state.ts +273 -0
  87. package/src/autoresearch/storage.ts +700 -0
  88. package/src/autoresearch/tools/init-experiment.ts +268 -0
  89. package/src/autoresearch/tools/log-experiment.ts +520 -0
  90. package/src/autoresearch/tools/run-experiment.ts +407 -0
  91. package/src/autoresearch/tools/update-notes.ts +109 -0
  92. package/src/autoresearch/types.ts +168 -0
  93. package/src/capability/context-file.ts +44 -0
  94. package/src/capability/extension-module.ts +34 -0
  95. package/src/capability/extension.ts +47 -0
  96. package/src/capability/fs.ts +117 -0
  97. package/src/capability/hook.ts +40 -0
  98. package/src/capability/index.ts +467 -0
  99. package/src/capability/instruction.ts +37 -0
  100. package/src/capability/mcp.ts +115 -0
  101. package/src/capability/prompt.ts +35 -0
  102. package/src/capability/rule-buckets.ts +66 -0
  103. package/src/capability/rule.ts +298 -0
  104. package/src/capability/settings.ts +34 -0
  105. package/src/capability/skill.ts +69 -0
  106. package/src/capability/slash-command.ts +40 -0
  107. package/src/capability/ssh.ts +41 -0
  108. package/src/capability/system-prompt.ts +34 -0
  109. package/src/capability/tool.ts +38 -0
  110. package/src/capability/types.ts +187 -0
  111. package/src/cleanse/agent.ts +226 -0
  112. package/src/cleanse/balance.ts +79 -0
  113. package/src/cleanse/checkers.ts +996 -0
  114. package/src/cleanse/index.ts +190 -0
  115. package/src/cleanse/loop.ts +51 -0
  116. package/src/cleanse/parsers.ts +726 -0
  117. package/src/cleanse/progress.ts +50 -0
  118. package/src/cleanse/prompts/assignment.md +47 -0
  119. package/src/cleanse/types.ts +72 -0
  120. package/src/cli/agents-cli.ts +138 -0
  121. package/src/cli/args.ts +368 -0
  122. package/src/cli/auth-broker-cli.ts +940 -0
  123. package/src/cli/auth-gateway-cli.ts +674 -0
  124. package/src/cli/bench-cli.ts +990 -0
  125. package/src/cli/browser-relay-cli.ts +119 -0
  126. package/src/cli/classify-install-target.ts +76 -0
  127. package/src/cli/claude-trace-cli.ts +795 -0
  128. package/src/cli/command-help.ts +107 -0
  129. package/src/cli/commands/init-xdg.ts +27 -0
  130. package/src/cli/completion-gen.ts +550 -0
  131. package/src/cli/config-cli.ts +459 -0
  132. package/src/cli/dry-balance-cli.ts +864 -0
  133. package/src/cli/extension-flags.ts +48 -0
  134. package/src/cli/file-processor.ts +132 -0
  135. package/src/cli/flag-tables.ts +367 -0
  136. package/src/cli/gallery-cli.ts +272 -0
  137. package/src/cli/gallery-fixtures/agentic.ts +420 -0
  138. package/src/cli/gallery-fixtures/codeintel.ts +187 -0
  139. package/src/cli/gallery-fixtures/edit.ts +254 -0
  140. package/src/cli/gallery-fixtures/fs.ts +245 -0
  141. package/src/cli/gallery-fixtures/index.ts +40 -0
  142. package/src/cli/gallery-fixtures/interaction.ts +46 -0
  143. package/src/cli/gallery-fixtures/memory.ts +81 -0
  144. package/src/cli/gallery-fixtures/misc.ts +177 -0
  145. package/src/cli/gallery-fixtures/search.ts +135 -0
  146. package/src/cli/gallery-fixtures/shell.ts +241 -0
  147. package/src/cli/gallery-fixtures/types.ts +57 -0
  148. package/src/cli/gallery-fixtures/web.ts +158 -0
  149. package/src/cli/gallery-screenshot.ts +279 -0
  150. package/src/cli/gc-cli.ts +1566 -0
  151. package/src/cli/grep-cli.ts +161 -0
  152. package/src/cli/grievances-cli.ts +256 -0
  153. package/src/cli/help-extra.ts +89 -0
  154. package/src/cli/initial-message.ts +58 -0
  155. package/src/cli/models-cli.ts +385 -0
  156. package/src/cli/plugin-cli.ts +996 -0
  157. package/src/cli/profile-alias.ts +369 -0
  158. package/src/cli/profile-bootstrap.ts +233 -0
  159. package/src/cli/read-cli.ts +99 -0
  160. package/src/cli/session-picker.ts +110 -0
  161. package/src/cli/setup-cli.ts +312 -0
  162. package/src/cli/setup-model-picker.ts +43 -0
  163. package/src/cli/shell-cli.ts +176 -0
  164. package/src/cli/ssh-cli.ts +179 -0
  165. package/src/cli/startup-cwd.ts +58 -0
  166. package/src/cli/stats-cli.ts +229 -0
  167. package/src/cli/thinking-levels.ts +7 -0
  168. package/src/cli/tiny-models-cli.ts +153 -0
  169. package/src/cli/ttsr-cli.ts +1013 -0
  170. package/src/cli/update-cli.ts +1184 -0
  171. package/src/cli/usage-cli.ts +1084 -0
  172. package/src/cli/usage-error.ts +7 -0
  173. package/src/cli/web-search-cli.ts +144 -0
  174. package/src/cli/worktree-cli.ts +311 -0
  175. package/src/cli-commands.ts +308 -0
  176. package/src/cli.ts +428 -0
  177. package/src/collab/crypto.ts +63 -0
  178. package/src/collab/display-name.ts +13 -0
  179. package/src/collab/guest.ts +764 -0
  180. package/src/collab/host.ts +692 -0
  181. package/src/collab/protocol.ts +296 -0
  182. package/src/collab/relay-client.ts +282 -0
  183. package/src/collab/replication-shrink.ts +111 -0
  184. package/src/commands/acp.ts +35 -0
  185. package/src/commands/agents.ts +58 -0
  186. package/src/commands/auth-broker.ts +100 -0
  187. package/src/commands/auth-gateway.ts +70 -0
  188. package/src/commands/bench.ts +64 -0
  189. package/src/commands/browser-relay.ts +53 -0
  190. package/src/commands/cleanse.ts +45 -0
  191. package/src/commands/commit.ts +47 -0
  192. package/src/commands/complete.ts +67 -0
  193. package/src/commands/completions.ts +61 -0
  194. package/src/commands/config.ts +52 -0
  195. package/src/commands/dry-balance.ts +43 -0
  196. package/src/commands/gallery.ts +61 -0
  197. package/src/commands/gc.ts +47 -0
  198. package/src/commands/grep.ts +49 -0
  199. package/src/commands/grievances.ts +52 -0
  200. package/src/commands/install.ts +107 -0
  201. package/src/commands/join.ts +40 -0
  202. package/src/commands/launch-help.ts +116 -0
  203. package/src/commands/launch.ts +34 -0
  204. package/src/commands/models.ts +61 -0
  205. package/src/commands/plugin.ts +79 -0
  206. package/src/commands/read.ts +39 -0
  207. package/src/commands/say.ts +146 -0
  208. package/src/commands/setup.ts +68 -0
  209. package/src/commands/share.ts +71 -0
  210. package/src/commands/shell.ts +30 -0
  211. package/src/commands/ssh.ts +61 -0
  212. package/src/commands/stats.ts +30 -0
  213. package/src/commands/tiny-models.ts +36 -0
  214. package/src/commands/token.ts +164 -0
  215. package/src/commands/ttsr.ts +125 -0
  216. package/src/commands/update.ts +34 -0
  217. package/src/commands/usage.ts +55 -0
  218. package/src/commands/web-search.ts +43 -0
  219. package/src/commands/worktree.ts +63 -0
  220. package/src/commit/agentic/agent.ts +322 -0
  221. package/src/commit/agentic/fallback.ts +96 -0
  222. package/src/commit/agentic/index.ts +383 -0
  223. package/src/commit/agentic/lock-files.ts +107 -0
  224. package/src/commit/agentic/prompts/analyze-file.md +22 -0
  225. package/src/commit/agentic/prompts/session-user.md +25 -0
  226. package/src/commit/agentic/prompts/split-confirm.md +1 -0
  227. package/src/commit/agentic/prompts/system.md +38 -0
  228. package/src/commit/agentic/state.ts +60 -0
  229. package/src/commit/agentic/tools/analyze-file.ts +148 -0
  230. package/src/commit/agentic/tools/git-file-diff.ts +191 -0
  231. package/src/commit/agentic/tools/git-hunk.ts +52 -0
  232. package/src/commit/agentic/tools/git-overview.ts +62 -0
  233. package/src/commit/agentic/tools/index.ts +54 -0
  234. package/src/commit/agentic/tools/propose-changelog.ts +147 -0
  235. package/src/commit/agentic/tools/propose-commit.ts +109 -0
  236. package/src/commit/agentic/tools/recent-commits.ts +81 -0
  237. package/src/commit/agentic/tools/schemas.ts +11 -0
  238. package/src/commit/agentic/tools/split-commit.ts +241 -0
  239. package/src/commit/agentic/topo-sort.ts +44 -0
  240. package/src/commit/agentic/trivial.ts +51 -0
  241. package/src/commit/agentic/validation.ts +183 -0
  242. package/src/commit/analysis/conventional.ts +64 -0
  243. package/src/commit/analysis/index.ts +4 -0
  244. package/src/commit/analysis/scope.ts +242 -0
  245. package/src/commit/analysis/summary.ts +107 -0
  246. package/src/commit/analysis/validation.ts +66 -0
  247. package/src/commit/changelog/detect.ts +40 -0
  248. package/src/commit/changelog/generate.ts +101 -0
  249. package/src/commit/changelog/index.ts +234 -0
  250. package/src/commit/changelog/parse.ts +44 -0
  251. package/src/commit/cli.ts +85 -0
  252. package/src/commit/git/diff.ts +148 -0
  253. package/src/commit/index.ts +5 -0
  254. package/src/commit/map-reduce/index.ts +69 -0
  255. package/src/commit/map-reduce/map-phase.ts +193 -0
  256. package/src/commit/map-reduce/reduce-phase.ts +49 -0
  257. package/src/commit/map-reduce/utils.ts +9 -0
  258. package/src/commit/message.ts +11 -0
  259. package/src/commit/model-selection.ts +95 -0
  260. package/src/commit/pipeline.ts +244 -0
  261. package/src/commit/prompts/analysis-system.md +148 -0
  262. package/src/commit/prompts/analysis-user.md +38 -0
  263. package/src/commit/prompts/changelog-system.md +50 -0
  264. package/src/commit/prompts/changelog-user.md +18 -0
  265. package/src/commit/prompts/file-observer-system.md +24 -0
  266. package/src/commit/prompts/file-observer-user.md +8 -0
  267. package/src/commit/prompts/reduce-system.md +50 -0
  268. package/src/commit/prompts/reduce-user.md +17 -0
  269. package/src/commit/prompts/summary-retry.md +3 -0
  270. package/src/commit/prompts/summary-system.md +38 -0
  271. package/src/commit/prompts/summary-user.md +13 -0
  272. package/src/commit/prompts/types-description.md +2 -0
  273. package/src/commit/shared-llm.ts +70 -0
  274. package/src/commit/types.ts +118 -0
  275. package/src/commit/utils/exclusions.ts +42 -0
  276. package/src/commit/utils.ts +58 -0
  277. package/src/config/api-key-resolver.ts +81 -0
  278. package/src/config/append-only-context-mode.ts +76 -0
  279. package/src/config/config-file.ts +347 -0
  280. package/src/config/inline-tool-descriptors-mode.ts +26 -0
  281. package/src/config/keybindings.ts +703 -0
  282. package/src/config/mcp-schema.json +252 -0
  283. package/src/config/model-discovery.ts +1077 -0
  284. package/src/config/model-registry.ts +2822 -0
  285. package/src/config/model-resolver.ts +2115 -0
  286. package/src/config/model-roles.ts +113 -0
  287. package/src/config/models-config-schema-bundle.ts +315 -0
  288. package/src/config/models-config-schema.ts +14 -0
  289. package/src/config/models-config.ts +130 -0
  290. package/src/config/prompt-templates.ts +205 -0
  291. package/src/config/provider-globals.ts +25 -0
  292. package/src/config/resolve-config-value.ts +95 -0
  293. package/src/config/service-tier.ts +146 -0
  294. package/src/config/settings-schema.ts +5887 -0
  295. package/src/config/settings.ts +2394 -0
  296. package/src/config.ts +242 -0
  297. package/src/cursor-bridge-tools.ts +81 -0
  298. package/src/cursor.ts +960 -0
  299. package/src/dap/client.ts +1043 -0
  300. package/src/dap/config.ts +480 -0
  301. package/src/dap/defaults.json +212 -0
  302. package/src/dap/index.ts +4 -0
  303. package/src/dap/session.ts +1841 -0
  304. package/src/dap/types.ts +611 -0
  305. package/src/debug/index.ts +584 -0
  306. package/src/debug/log-formatting.ts +58 -0
  307. package/src/debug/log-viewer.ts +966 -0
  308. package/src/debug/profiler.ts +168 -0
  309. package/src/debug/protocol-probe.ts +267 -0
  310. package/src/debug/raw-sse-buffer.ts +421 -0
  311. package/src/debug/raw-sse.ts +312 -0
  312. package/src/debug/remote-debugger.ts +151 -0
  313. package/src/debug/report-bundle.ts +411 -0
  314. package/src/debug/system-info.ts +111 -0
  315. package/src/debug/terminal-info.ts +124 -0
  316. package/src/discovery/agent-plugin-format.ts +551 -0
  317. package/src/discovery/agent-plugins.ts +341 -0
  318. package/src/discovery/agents-md.ts +67 -0
  319. package/src/discovery/agents.ts +300 -0
  320. package/src/discovery/at-imports.ts +273 -0
  321. package/src/discovery/builtin-defaults.ts +39 -0
  322. package/src/discovery/builtin-rules/go-add-cleanup.md +33 -0
  323. package/src/discovery/builtin-rules/go-bench-loop.md +36 -0
  324. package/src/discovery/builtin-rules/go-exp-promoted.md +40 -0
  325. package/src/discovery/builtin-rules/go-ioutil.md +37 -0
  326. package/src/discovery/builtin-rules/go-join-hostport.md +30 -0
  327. package/src/discovery/builtin-rules/go-new-expr.md +44 -0
  328. package/src/discovery/builtin-rules/go-rand-v2.md +41 -0
  329. package/src/discovery/builtin-rules/go-range-int.md +45 -0
  330. package/src/discovery/builtin-rules/index.ts +74 -0
  331. package/src/discovery/builtin-rules/rs-box-leak.md +49 -0
  332. package/src/discovery/builtin-rules/rs-future-prelude.md +24 -0
  333. package/src/discovery/builtin-rules/rs-lazylock.md +52 -0
  334. package/src/discovery/builtin-rules/rs-match-ergonomics.md +68 -0
  335. package/src/discovery/builtin-rules/rs-parking-lot.md +45 -0
  336. package/src/discovery/builtin-rules/rs-result-type.md +20 -0
  337. package/src/discovery/builtin-rules/ts-bare-catch.md +39 -0
  338. package/src/discovery/builtin-rules/ts-import-type.md +43 -0
  339. package/src/discovery/builtin-rules/ts-no-any.md +66 -0
  340. package/src/discovery/builtin-rules/ts-no-deprecated-leftovers.md +45 -0
  341. package/src/discovery/builtin-rules/ts-no-dynamic-import.md +40 -0
  342. package/src/discovery/builtin-rules/ts-no-inline-cast-access.md +56 -0
  343. package/src/discovery/builtin-rules/ts-no-local-is-record.md +48 -0
  344. package/src/discovery/builtin-rules/ts-no-return-type.md +45 -0
  345. package/src/discovery/builtin-rules/ts-no-test-timers.md +55 -0
  346. package/src/discovery/builtin-rules/ts-no-tiny-functions.md +51 -0
  347. package/src/discovery/builtin-rules/ts-promise-with-resolvers.md +66 -0
  348. package/src/discovery/builtin-rules/ts-redundant-clear-guard.md +75 -0
  349. package/src/discovery/builtin-rules/ts-set-map.md +28 -0
  350. package/src/discovery/builtin.ts +945 -0
  351. package/src/discovery/claude-plugins.ts +640 -0
  352. package/src/discovery/claude.ts +591 -0
  353. package/src/discovery/cline.ts +83 -0
  354. package/src/discovery/codex.ts +553 -0
  355. package/src/discovery/contained-path.ts +78 -0
  356. package/src/discovery/cursor.ts +223 -0
  357. package/src/discovery/gemini.ts +386 -0
  358. package/src/discovery/github.ts +337 -0
  359. package/src/discovery/helpers.ts +1183 -0
  360. package/src/discovery/index.ts +82 -0
  361. package/src/discovery/mcp-json.ts +182 -0
  362. package/src/discovery/omp-extension-roots.ts +272 -0
  363. package/src/discovery/omp-plugins.ts +409 -0
  364. package/src/discovery/opencode.ts +441 -0
  365. package/src/discovery/plugin-dir-roots.ts +28 -0
  366. package/src/discovery/ssh.ts +153 -0
  367. package/src/discovery/substitute-plugin-root.ts +77 -0
  368. package/src/discovery/vscode.ts +106 -0
  369. package/src/discovery/windsurf.ts +149 -0
  370. package/src/edit/apply-patch/index.ts +87 -0
  371. package/src/edit/apply-patch/parser.ts +174 -0
  372. package/src/edit/diff.ts +1008 -0
  373. package/src/edit/edit-clipboard.ts +23 -0
  374. package/src/edit/file-snapshot-store.ts +148 -0
  375. package/src/edit/hashline/block-resolver.ts +33 -0
  376. package/src/edit/hashline/diff.ts +402 -0
  377. package/src/edit/hashline/execute.ts +313 -0
  378. package/src/edit/hashline/filesystem.ts +247 -0
  379. package/src/edit/hashline/index.ts +5 -0
  380. package/src/edit/hashline/noop-loop-guard.ts +99 -0
  381. package/src/edit/hashline/params.ts +12 -0
  382. package/src/edit/index.ts +699 -0
  383. package/src/edit/modes/apply-patch.lark +19 -0
  384. package/src/edit/modes/apply-patch.ts +53 -0
  385. package/src/edit/modes/patch.ts +1958 -0
  386. package/src/edit/modes/replace.ts +1191 -0
  387. package/src/edit/normalize.ts +345 -0
  388. package/src/edit/notebook.ts +242 -0
  389. package/src/edit/read-file.ts +25 -0
  390. package/src/edit/renderer.ts +998 -0
  391. package/src/edit/snapshot-details.ts +77 -0
  392. package/src/edit/streaming.ts +710 -0
  393. package/src/eval/agent-bridge.ts +224 -0
  394. package/src/eval/backend-helpers.ts +48 -0
  395. package/src/eval/backend.ts +71 -0
  396. package/src/eval/bridge-timeout.ts +65 -0
  397. package/src/eval/budget-bridge.ts +48 -0
  398. package/src/eval/completion-bridge.ts +212 -0
  399. package/src/eval/concurrency-bridge.ts +34 -0
  400. package/src/eval/executor-base.ts +562 -0
  401. package/src/eval/idle-timeout.ts +91 -0
  402. package/src/eval/index.ts +6 -0
  403. package/src/eval/jl/executor.ts +551 -0
  404. package/src/eval/jl/index.ts +54 -0
  405. package/src/eval/jl/kernel.ts +236 -0
  406. package/src/eval/jl/prelude.jl +736 -0
  407. package/src/eval/jl/prelude.ts +3 -0
  408. package/src/eval/jl/runner.jl +666 -0
  409. package/src/eval/jl/runtime.ts +118 -0
  410. package/src/eval/js/context-manager.ts +872 -0
  411. package/src/eval/js/executor.ts +178 -0
  412. package/src/eval/js/index.ts +41 -0
  413. package/src/eval/js/process-entry.ts +31 -0
  414. package/src/eval/js/shared/helpers.ts +170 -0
  415. package/src/eval/js/shared/indirect-eval.ts +30 -0
  416. package/src/eval/js/shared/local-module-loader.ts +364 -0
  417. package/src/eval/js/shared/prelude.ts +2 -0
  418. package/src/eval/js/shared/prelude.txt +294 -0
  419. package/src/eval/js/shared/rewrite-imports.ts +550 -0
  420. package/src/eval/js/shared/runtime.ts +590 -0
  421. package/src/eval/js/shared/types.ts +18 -0
  422. package/src/eval/js/tool-bridge.ts +163 -0
  423. package/src/eval/js/worker-core.ts +380 -0
  424. package/src/eval/js/worker-entry.ts +37 -0
  425. package/src/eval/js/worker-protocol.ts +47 -0
  426. package/src/eval/kernel-base.ts +569 -0
  427. package/src/eval/py/display.ts +71 -0
  428. package/src/eval/py/executor.ts +643 -0
  429. package/src/eval/py/index.ts +57 -0
  430. package/src/eval/py/kernel.ts +235 -0
  431. package/src/eval/py/prelude.py +673 -0
  432. package/src/eval/py/prelude.ts +3 -0
  433. package/src/eval/py/runner.py +1425 -0
  434. package/src/eval/py/runtime.ts +276 -0
  435. package/src/eval/py/spawn-options.ts +134 -0
  436. package/src/eval/py/tool-bridge.ts +201 -0
  437. package/src/eval/rb/executor.ts +511 -0
  438. package/src/eval/rb/index.ts +54 -0
  439. package/src/eval/rb/kernel.ts +231 -0
  440. package/src/eval/rb/prelude.rb +551 -0
  441. package/src/eval/rb/prelude.ts +3 -0
  442. package/src/eval/rb/runner.rb +581 -0
  443. package/src/eval/rb/runtime.ts +132 -0
  444. package/src/eval/runtime-env.ts +104 -0
  445. package/src/eval/session-id.ts +8 -0
  446. package/src/eval/types.ts +48 -0
  447. package/src/exa/index.ts +2 -0
  448. package/src/exa/mcp-client.ts +370 -0
  449. package/src/exa/types.ts +69 -0
  450. package/src/exec/bash-executor.ts +627 -0
  451. package/src/exec/direnv.ts +145 -0
  452. package/src/exec/exec.ts +53 -0
  453. package/src/exec/non-interactive-env.ts +118 -0
  454. package/src/export/custom-share.ts +65 -0
  455. package/src/export/html/args.ts +20 -0
  456. package/src/export/html/index.ts +320 -0
  457. package/src/export/html/share-loader.js +102 -0
  458. package/src/export/html/template.css +1355 -0
  459. package/src/export/html/template.html +55 -0
  460. package/src/export/html/template.js +1653 -0
  461. package/src/export/html/tool-views.generated.js +35 -0
  462. package/src/export/html/vendor/highlight.min.js +1213 -0
  463. package/src/export/html/vendor/marked.min.js +6 -0
  464. package/src/export/html/web-palette.ts +126 -0
  465. package/src/export/share.ts +686 -0
  466. package/src/export/ttsr.ts +590 -0
  467. package/src/extensibility/custom-commands/bundled/ci-green/index.ts +54 -0
  468. package/src/extensibility/custom-commands/bundled/review/index.ts +698 -0
  469. package/src/extensibility/custom-commands/index.ts +2 -0
  470. package/src/extensibility/custom-commands/loader.ts +242 -0
  471. package/src/extensibility/custom-commands/types.ts +119 -0
  472. package/src/extensibility/custom-tools/index.ts +7 -0
  473. package/src/extensibility/custom-tools/loader.ts +301 -0
  474. package/src/extensibility/custom-tools/types.ts +287 -0
  475. package/src/extensibility/custom-tools/wrapper.ts +50 -0
  476. package/src/extensibility/extensions/compact-handler.ts +40 -0
  477. package/src/extensibility/extensions/get-commands-handler.ts +78 -0
  478. package/src/extensibility/extensions/index.ts +16 -0
  479. package/src/extensibility/extensions/load-errors.ts +13 -0
  480. package/src/extensibility/extensions/loader.ts +663 -0
  481. package/src/extensibility/extensions/managed-timers.ts +83 -0
  482. package/src/extensibility/extensions/model-api.ts +39 -0
  483. package/src/extensibility/extensions/runner.ts +1396 -0
  484. package/src/extensibility/extensions/types.ts +1603 -0
  485. package/src/extensibility/extensions/wrapper.ts +395 -0
  486. package/src/extensibility/hooks/index.ts +6 -0
  487. package/src/extensibility/hooks/loader.ts +243 -0
  488. package/src/extensibility/hooks/runner.ts +425 -0
  489. package/src/extensibility/hooks/tool-wrapper.ts +124 -0
  490. package/src/extensibility/hooks/types.ts +612 -0
  491. package/src/extensibility/legacy-pi-ai-shim.ts +161 -0
  492. package/src/extensibility/legacy-pi-coding-agent-shim.ts +1460 -0
  493. package/src/extensibility/legacy-pi-tui-shim.ts +43 -0
  494. package/src/extensibility/legacy-typebox.ts +101 -0
  495. package/src/extensibility/plugins/bun-git-cache.ts +91 -0
  496. package/src/extensibility/plugins/doctor.ts +65 -0
  497. package/src/extensibility/plugins/git-url.ts +367 -0
  498. package/src/extensibility/plugins/index.ts +9 -0
  499. package/src/extensibility/plugins/installer.ts +201 -0
  500. package/src/extensibility/plugins/legacy-pi-compat.ts +2643 -0
  501. package/src/extensibility/plugins/legacy-pi-virtual-modules.d.ts +4 -0
  502. package/src/extensibility/plugins/loader.ts +535 -0
  503. package/src/extensibility/plugins/manager.ts +1142 -0
  504. package/src/extensibility/plugins/marketplace/cache.ts +136 -0
  505. package/src/extensibility/plugins/marketplace/fetcher.ts +316 -0
  506. package/src/extensibility/plugins/marketplace/index.ts +6 -0
  507. package/src/extensibility/plugins/marketplace/manager.ts +927 -0
  508. package/src/extensibility/plugins/marketplace/registry.ts +192 -0
  509. package/src/extensibility/plugins/marketplace/source-resolver.ts +147 -0
  510. package/src/extensibility/plugins/marketplace/types.ts +192 -0
  511. package/src/extensibility/plugins/marketplace-auto-update.ts +49 -0
  512. package/src/extensibility/plugins/parser.ts +107 -0
  513. package/src/extensibility/plugins/runtime-config.ts +9 -0
  514. package/src/extensibility/plugins/types.ts +194 -0
  515. package/src/extensibility/session-handler-types.ts +21 -0
  516. package/src/extensibility/shared-events.ts +401 -0
  517. package/src/extensibility/skills.ts +531 -0
  518. package/src/extensibility/slash-commands.ts +131 -0
  519. package/src/extensibility/tool-event-input.ts +80 -0
  520. package/src/extensibility/tool-proxy.ts +28 -0
  521. package/src/extensibility/utils.ts +192 -0
  522. package/src/goals/index.ts +3 -0
  523. package/src/goals/runtime.ts +521 -0
  524. package/src/goals/state.ts +37 -0
  525. package/src/goals/tools/goal-tool.ts +251 -0
  526. package/src/hindsight/backend.ts +354 -0
  527. package/src/hindsight/bank.ts +156 -0
  528. package/src/hindsight/client.ts +680 -0
  529. package/src/hindsight/config.ts +193 -0
  530. package/src/hindsight/content.ts +266 -0
  531. package/src/hindsight/index.ts +8 -0
  532. package/src/hindsight/mental-models.ts +429 -0
  533. package/src/hindsight/seeds.json +32 -0
  534. package/src/hindsight/state.ts +530 -0
  535. package/src/hindsight/transcript.ts +71 -0
  536. package/src/index.ts +66 -0
  537. package/src/internal-urls/agent-protocol.ts +180 -0
  538. package/src/internal-urls/artifact-protocol.ts +151 -0
  539. package/src/internal-urls/docs-index.ts +102 -0
  540. package/src/internal-urls/filesystem-resource.ts +34 -0
  541. package/src/internal-urls/history-protocol.ts +198 -0
  542. package/src/internal-urls/index.ts +28 -0
  543. package/src/internal-urls/issue-pr-protocol.ts +594 -0
  544. package/src/internal-urls/json-query.ts +126 -0
  545. package/src/internal-urls/local-protocol.ts +471 -0
  546. package/src/internal-urls/mcp-protocol.ts +168 -0
  547. package/src/internal-urls/memory-protocol.ts +380 -0
  548. package/src/internal-urls/omp-protocol.ts +94 -0
  549. package/src/internal-urls/parse.ts +103 -0
  550. package/src/internal-urls/registry-helpers.ts +132 -0
  551. package/src/internal-urls/router.ts +153 -0
  552. package/src/internal-urls/rule-protocol.ts +45 -0
  553. package/src/internal-urls/security-protocol.ts +261 -0
  554. package/src/internal-urls/skill-protocol.ts +131 -0
  555. package/src/internal-urls/ssh-protocol.ts +368 -0
  556. package/src/internal-urls/types.ts +196 -0
  557. package/src/internal-urls/vault-protocol.ts +940 -0
  558. package/src/internal-urls/xd-protocol.ts +46 -0
  559. package/src/irc/bus.ts +380 -0
  560. package/src/jsonrpc/message-framing.ts +142 -0
  561. package/src/launch/broker.ts +1368 -0
  562. package/src/launch/client.ts +521 -0
  563. package/src/launch/ensure.ts +73 -0
  564. package/src/launch/paths.ts +14 -0
  565. package/src/launch/presence.ts +82 -0
  566. package/src/launch/protocol.ts +448 -0
  567. package/src/launch/spawn-options.ts +17 -0
  568. package/src/launch/terminal-output-worker-client.ts +53 -0
  569. package/src/launch/terminal-output-worker-protocol.ts +11 -0
  570. package/src/launch/terminal-output-worker.ts +23 -0
  571. package/src/launch/terminal-output.ts +46 -0
  572. package/src/lib/xai-http.ts +150 -0
  573. package/src/live/attestation.ts +91 -0
  574. package/src/live/controller.ts +517 -0
  575. package/src/live/prompts/agent-final-message.md +3 -0
  576. package/src/live/prompts/live-instructions.md +23 -0
  577. package/src/live/protocol.ts +233 -0
  578. package/src/live/transport.ts +422 -0
  579. package/src/live/visualizer.ts +221 -0
  580. package/src/live/voices.ts +18 -0
  581. package/src/lsp/client.ts +1465 -0
  582. package/src/lsp/clients/biome-client.ts +263 -0
  583. package/src/lsp/clients/index.ts +50 -0
  584. package/src/lsp/clients/lsp-linter-client.ts +85 -0
  585. package/src/lsp/clients/swiftlint-client.ts +120 -0
  586. package/src/lsp/config.ts +549 -0
  587. package/src/lsp/defaults.json +499 -0
  588. package/src/lsp/deferred-diagnostics.ts +66 -0
  589. package/src/lsp/diagnostics-ledger.ts +51 -0
  590. package/src/lsp/edits.ts +288 -0
  591. package/src/lsp/format-options.ts +119 -0
  592. package/src/lsp/index.ts +2821 -0
  593. package/src/lsp/lspmux.ts +233 -0
  594. package/src/lsp/mux/daemon.ts +348 -0
  595. package/src/lsp/mux/protocol.ts +96 -0
  596. package/src/lsp/mux/server.ts +797 -0
  597. package/src/lsp/render.ts +668 -0
  598. package/src/lsp/startup-events.ts +13 -0
  599. package/src/lsp/types.ts +479 -0
  600. package/src/lsp/utils.ts +747 -0
  601. package/src/main.ts +1799 -0
  602. package/src/markit/NOTICE +32 -0
  603. package/src/markit/converters/docx.ts +56 -0
  604. package/src/markit/converters/epub.ts +136 -0
  605. package/src/markit/converters/pdf/columns.ts +103 -0
  606. package/src/markit/converters/pdf/extract.ts +598 -0
  607. package/src/markit/converters/pdf/grid.ts +780 -0
  608. package/src/markit/converters/pdf/headers.ts +106 -0
  609. package/src/markit/converters/pdf/index.ts +146 -0
  610. package/src/markit/converters/pdf/render.ts +501 -0
  611. package/src/markit/converters/pdf/types.ts +84 -0
  612. package/src/markit/converters/pptx.ts +325 -0
  613. package/src/markit/converters/xlsx.ts +173 -0
  614. package/src/markit/index.ts +2 -0
  615. package/src/markit/registry.ts +59 -0
  616. package/src/markit/types.ts +35 -0
  617. package/src/mcp/client.ts +511 -0
  618. package/src/mcp/config-writer.ts +377 -0
  619. package/src/mcp/config.ts +385 -0
  620. package/src/mcp/index.ts +29 -0
  621. package/src/mcp/json-rpc.ts +122 -0
  622. package/src/mcp/loader.ts +125 -0
  623. package/src/mcp/manager.ts +1524 -0
  624. package/src/mcp/oauth-credentials.ts +104 -0
  625. package/src/mcp/oauth-discovery.ts +587 -0
  626. package/src/mcp/oauth-flow.ts +830 -0
  627. package/src/mcp/render.ts +214 -0
  628. package/src/mcp/request-id.ts +24 -0
  629. package/src/mcp/smithery-auth.ts +108 -0
  630. package/src/mcp/smithery-connect.ts +154 -0
  631. package/src/mcp/smithery-registry.ts +500 -0
  632. package/src/mcp/startup-events.ts +116 -0
  633. package/src/mcp/timeout.ts +59 -0
  634. package/src/mcp/tool-bridge.ts +691 -0
  635. package/src/mcp/tool-cache.ts +117 -0
  636. package/src/mcp/transports/header-policy.ts +95 -0
  637. package/src/mcp/transports/http.ts +508 -0
  638. package/src/mcp/transports/index.ts +7 -0
  639. package/src/mcp/transports/sse.ts +372 -0
  640. package/src/mcp/transports/stdio.ts +905 -0
  641. package/src/mcp/types.ts +467 -0
  642. package/src/memories/index.ts +1434 -0
  643. package/src/memories/storage.ts +578 -0
  644. package/src/memory-backend/index.ts +19 -0
  645. package/src/memory-backend/local-backend.ts +47 -0
  646. package/src/memory-backend/messages.ts +19 -0
  647. package/src/memory-backend/off-backend.ts +25 -0
  648. package/src/memory-backend/resolve.ts +25 -0
  649. package/src/memory-backend/runtime.ts +66 -0
  650. package/src/memory-backend/tool-names.ts +2 -0
  651. package/src/memory-backend/types.ts +166 -0
  652. package/src/mnemopi/backend.ts +629 -0
  653. package/src/mnemopi/config.ts +267 -0
  654. package/src/mnemopi/embed-client.ts +293 -0
  655. package/src/mnemopi/embed-protocol.ts +35 -0
  656. package/src/mnemopi/embed-worker.ts +114 -0
  657. package/src/mnemopi/index.ts +3 -0
  658. package/src/mnemopi/state.ts +940 -0
  659. package/src/modes/acp/acp-agent.ts +2595 -0
  660. package/src/modes/acp/acp-client-bridge.ts +154 -0
  661. package/src/modes/acp/acp-event-mapper.ts +1084 -0
  662. package/src/modes/acp/acp-mode.ts +48 -0
  663. package/src/modes/acp/index.ts +2 -0
  664. package/src/modes/acp/terminal-auth.ts +37 -0
  665. package/src/modes/components/advisor-config.ts +635 -0
  666. package/src/modes/components/advisor-message.ts +109 -0
  667. package/src/modes/components/agent-dashboard.ts +1252 -0
  668. package/src/modes/components/agent-hub-projection.ts +248 -0
  669. package/src/modes/components/agent-hub-renderer.ts +194 -0
  670. package/src/modes/components/agent-hub.ts +1126 -0
  671. package/src/modes/components/agent-transcript-viewer.ts +647 -0
  672. package/src/modes/components/ask-dialog.ts +1017 -0
  673. package/src/modes/components/assistant-message.ts +978 -0
  674. package/src/modes/components/background-tan-message.ts +36 -0
  675. package/src/modes/components/bash-execution.ts +233 -0
  676. package/src/modes/components/bordered-loader.ts +41 -0
  677. package/src/modes/components/btw-panel.ts +161 -0
  678. package/src/modes/components/cache-invalidation-marker.ts +110 -0
  679. package/src/modes/components/chat-block.ts +111 -0
  680. package/src/modes/components/chat-transcript-builder.ts +518 -0
  681. package/src/modes/components/codex-reset-fireworks.ts +369 -0
  682. package/src/modes/components/collab-prompt-message.ts +32 -0
  683. package/src/modes/components/compaction-summary-message.ts +221 -0
  684. package/src/modes/components/copy-selector.ts +218 -0
  685. package/src/modes/components/countdown-timer.ts +75 -0
  686. package/src/modes/components/custom-editor.ts +1036 -0
  687. package/src/modes/components/custom-message.ts +70 -0
  688. package/src/modes/components/diff.ts +254 -0
  689. package/src/modes/components/dynamic-border.ts +37 -0
  690. package/src/modes/components/error-banner.ts +33 -0
  691. package/src/modes/components/eval-execution.ts +169 -0
  692. package/src/modes/components/execution-shared.ts +101 -0
  693. package/src/modes/components/extensions/extension-dashboard.ts +492 -0
  694. package/src/modes/components/extensions/extension-list.ts +507 -0
  695. package/src/modes/components/extensions/index.ts +9 -0
  696. package/src/modes/components/extensions/inspector-panel.ts +326 -0
  697. package/src/modes/components/extensions/state-manager.ts +648 -0
  698. package/src/modes/components/extensions/types.ts +186 -0
  699. package/src/modes/components/footer.ts +274 -0
  700. package/src/modes/components/history-search.ts +268 -0
  701. package/src/modes/components/hook-editor.ts +213 -0
  702. package/src/modes/components/hook-input.ts +87 -0
  703. package/src/modes/components/hook-message.ts +67 -0
  704. package/src/modes/components/hook-selector.ts +691 -0
  705. package/src/modes/components/index.ts +42 -0
  706. package/src/modes/components/keybinding-hints.ts +56 -0
  707. package/src/modes/components/late-diagnostics-message.ts +60 -0
  708. package/src/modes/components/login-dialog.ts +197 -0
  709. package/src/modes/components/logout-account-selector.ts +130 -0
  710. package/src/modes/components/mcp-add-wizard.ts +1413 -0
  711. package/src/modes/components/message-frame.ts +98 -0
  712. package/src/modes/components/model-browser.ts +888 -0
  713. package/src/modes/components/model-hub.ts +2014 -0
  714. package/src/modes/components/model-picker.ts +237 -0
  715. package/src/modes/components/move-overlay.ts +293 -0
  716. package/src/modes/components/oauth-selector.ts +474 -0
  717. package/src/modes/components/omfg-panel.ts +141 -0
  718. package/src/modes/components/overlay-box.ts +109 -0
  719. package/src/modes/components/pause-screen.ts +208 -0
  720. package/src/modes/components/plan-review-overlay.ts +1226 -0
  721. package/src/modes/components/plan-toc.ts +138 -0
  722. package/src/modes/components/plugin-selector.ts +100 -0
  723. package/src/modes/components/plugin-settings.ts +745 -0
  724. package/src/modes/components/queue-mode-selector.ts +61 -0
  725. package/src/modes/components/read-tool-group.ts +856 -0
  726. package/src/modes/components/reset-usage-selector.ts +161 -0
  727. package/src/modes/components/segment-track.ts +89 -0
  728. package/src/modes/components/select-list-mouse-routing.ts +35 -0
  729. package/src/modes/components/selector-helpers.ts +129 -0
  730. package/src/modes/components/session-account-selector.ts +62 -0
  731. package/src/modes/components/session-selector.ts +1035 -0
  732. package/src/modes/components/settings-defs.ts +267 -0
  733. package/src/modes/components/settings-selector.ts +1445 -0
  734. package/src/modes/components/show-images-selector.ts +50 -0
  735. package/src/modes/components/skill-message.ts +110 -0
  736. package/src/modes/components/snapcompact-shape-preview-doc.md +14 -0
  737. package/src/modes/components/snapcompact-shape-preview.ts +192 -0
  738. package/src/modes/components/status-line/component.ts +1843 -0
  739. package/src/modes/components/status-line/context-thresholds.ts +86 -0
  740. package/src/modes/components/status-line/git-utils.ts +42 -0
  741. package/src/modes/components/status-line/index.ts +5 -0
  742. package/src/modes/components/status-line/presets.ts +106 -0
  743. package/src/modes/components/status-line/segments.ts +710 -0
  744. package/src/modes/components/status-line/separators.ts +55 -0
  745. package/src/modes/components/status-line/types.ts +159 -0
  746. package/src/modes/components/stripped-tool-calls-placeholder.ts +35 -0
  747. package/src/modes/components/theme-selector.ts +68 -0
  748. package/src/modes/components/thinking-selector.ts +57 -0
  749. package/src/modes/components/tiny-title-download-progress.ts +90 -0
  750. package/src/modes/components/tips.txt +26 -0
  751. package/src/modes/components/todo-reminder.ts +43 -0
  752. package/src/modes/components/tool-execution.ts +1467 -0
  753. package/src/modes/components/transcript-container.ts +527 -0
  754. package/src/modes/components/tree-selector.ts +1006 -0
  755. package/src/modes/components/ttsr-notification.ts +123 -0
  756. package/src/modes/components/usage-row.ts +52 -0
  757. package/src/modes/components/user-message-selector.ts +227 -0
  758. package/src/modes/components/user-message.ts +167 -0
  759. package/src/modes/components/visual-truncate.ts +63 -0
  760. package/src/modes/components/welcome.ts +578 -0
  761. package/src/modes/controllers/btw-controller.ts +246 -0
  762. package/src/modes/controllers/command-controller-shared.ts +109 -0
  763. package/src/modes/controllers/command-controller.ts +2024 -0
  764. package/src/modes/controllers/event-controller.ts +2173 -0
  765. package/src/modes/controllers/extension-ui-controller.ts +1243 -0
  766. package/src/modes/controllers/input-controller.ts +2037 -0
  767. package/src/modes/controllers/live-command-controller.ts +261 -0
  768. package/src/modes/controllers/mcp-command-controller.ts +2552 -0
  769. package/src/modes/controllers/omfg-controller.ts +287 -0
  770. package/src/modes/controllers/omfg-rule.ts +647 -0
  771. package/src/modes/controllers/selector-controller.ts +2058 -0
  772. package/src/modes/controllers/session-focus-controller.ts +117 -0
  773. package/src/modes/controllers/ssh-command-controller.ts +385 -0
  774. package/src/modes/controllers/streaming-reveal.ts +399 -0
  775. package/src/modes/controllers/tan-command-controller.ts +243 -0
  776. package/src/modes/controllers/todo-command-controller.ts +487 -0
  777. package/src/modes/controllers/tool-args-reveal.ts +591 -0
  778. package/src/modes/data/emojis.json +1 -0
  779. package/src/modes/emoji-autocomplete.ts +285 -0
  780. package/src/modes/github-ref-autocomplete.ts +75 -0
  781. package/src/modes/gradient-highlight.ts +99 -0
  782. package/src/modes/image-references.ts +137 -0
  783. package/src/modes/index.ts +10 -0
  784. package/src/modes/interactive-mode.ts +5055 -0
  785. package/src/modes/internal-url-autocomplete.ts +158 -0
  786. package/src/modes/loop-limit.ts +192 -0
  787. package/src/modes/magic-keyword-boundary.ts +23 -0
  788. package/src/modes/magic-keywords.ts +42 -0
  789. package/src/modes/markdown-prose.ts +247 -0
  790. package/src/modes/oauth-manual-input.ts +69 -0
  791. package/src/modes/orchestrate.ts +43 -0
  792. package/src/modes/print-mode.ts +282 -0
  793. package/src/modes/prompt-action-autocomplete.ts +322 -0
  794. package/src/modes/queue-input.ts +132 -0
  795. package/src/modes/rpc/host-tools.ts +204 -0
  796. package/src/modes/rpc/host-uris.ts +241 -0
  797. package/src/modes/rpc/rpc-client.ts +1213 -0
  798. package/src/modes/rpc/rpc-frame.ts +316 -0
  799. package/src/modes/rpc/rpc-input.ts +38 -0
  800. package/src/modes/rpc/rpc-messages.ts +127 -0
  801. package/src/modes/rpc/rpc-mode.ts +1519 -0
  802. package/src/modes/rpc/rpc-subagents.ts +265 -0
  803. package/src/modes/rpc/rpc-types.ts +544 -0
  804. package/src/modes/running-subagent-badge.ts +13 -0
  805. package/src/modes/runtime-init.ts +144 -0
  806. package/src/modes/session-observer-registry.ts +223 -0
  807. package/src/modes/session-teardown.ts +82 -0
  808. package/src/modes/setup-version.ts +11 -0
  809. package/src/modes/setup-wizard/index.ts +103 -0
  810. package/src/modes/setup-wizard/lazy.ts +16 -0
  811. package/src/modes/setup-wizard/scenes/glyph.ts +103 -0
  812. package/src/modes/setup-wizard/scenes/model.ts +132 -0
  813. package/src/modes/setup-wizard/scenes/outro.ts +35 -0
  814. package/src/modes/setup-wizard/scenes/providers.ts +105 -0
  815. package/src/modes/setup-wizard/scenes/sign-in.ts +312 -0
  816. package/src/modes/setup-wizard/scenes/splash.ts +201 -0
  817. package/src/modes/setup-wizard/scenes/theme.ts +330 -0
  818. package/src/modes/setup-wizard/scenes/types.ts +65 -0
  819. package/src/modes/setup-wizard/scenes/web-search.ts +153 -0
  820. package/src/modes/setup-wizard/startup-splash.ts +107 -0
  821. package/src/modes/setup-wizard/wizard-overlay.ts +335 -0
  822. package/src/modes/shared.ts +49 -0
  823. package/src/modes/skill-command.ts +91 -0
  824. package/src/modes/theme/dark.json +95 -0
  825. package/src/modes/theme/defaults/alabaster.json +93 -0
  826. package/src/modes/theme/defaults/amethyst.json +96 -0
  827. package/src/modes/theme/defaults/anthracite.json +93 -0
  828. package/src/modes/theme/defaults/basalt.json +91 -0
  829. package/src/modes/theme/defaults/birch.json +95 -0
  830. package/src/modes/theme/defaults/dark-abyss.json +91 -0
  831. package/src/modes/theme/defaults/dark-arctic.json +104 -0
  832. package/src/modes/theme/defaults/dark-aurora.json +95 -0
  833. package/src/modes/theme/defaults/dark-catppuccin.json +107 -0
  834. package/src/modes/theme/defaults/dark-cavern.json +91 -0
  835. package/src/modes/theme/defaults/dark-copper.json +95 -0
  836. package/src/modes/theme/defaults/dark-cosmos.json +90 -0
  837. package/src/modes/theme/defaults/dark-cyberpunk.json +102 -0
  838. package/src/modes/theme/defaults/dark-dracula.json +98 -0
  839. package/src/modes/theme/defaults/dark-eclipse.json +91 -0
  840. package/src/modes/theme/defaults/dark-ember.json +95 -0
  841. package/src/modes/theme/defaults/dark-equinox.json +90 -0
  842. package/src/modes/theme/defaults/dark-forest.json +96 -0
  843. package/src/modes/theme/defaults/dark-github.json +105 -0
  844. package/src/modes/theme/defaults/dark-gruvbox.json +112 -0
  845. package/src/modes/theme/defaults/dark-lavender.json +95 -0
  846. package/src/modes/theme/defaults/dark-lunar.json +89 -0
  847. package/src/modes/theme/defaults/dark-midnight.json +95 -0
  848. package/src/modes/theme/defaults/dark-monochrome.json +94 -0
  849. package/src/modes/theme/defaults/dark-monokai.json +98 -0
  850. package/src/modes/theme/defaults/dark-nebula.json +90 -0
  851. package/src/modes/theme/defaults/dark-nord.json +97 -0
  852. package/src/modes/theme/defaults/dark-ocean.json +101 -0
  853. package/src/modes/theme/defaults/dark-one.json +100 -0
  854. package/src/modes/theme/defaults/dark-poimandres.json +143 -0
  855. package/src/modes/theme/defaults/dark-rainforest.json +91 -0
  856. package/src/modes/theme/defaults/dark-reef.json +91 -0
  857. package/src/modes/theme/defaults/dark-retro.json +92 -0
  858. package/src/modes/theme/defaults/dark-rose-pine.json +96 -0
  859. package/src/modes/theme/defaults/dark-sakura.json +95 -0
  860. package/src/modes/theme/defaults/dark-slate.json +95 -0
  861. package/src/modes/theme/defaults/dark-solarized.json +97 -0
  862. package/src/modes/theme/defaults/dark-solstice.json +90 -0
  863. package/src/modes/theme/defaults/dark-starfall.json +91 -0
  864. package/src/modes/theme/defaults/dark-sunset.json +99 -0
  865. package/src/modes/theme/defaults/dark-swamp.json +90 -0
  866. package/src/modes/theme/defaults/dark-synthwave.json +103 -0
  867. package/src/modes/theme/defaults/dark-taiga.json +91 -0
  868. package/src/modes/theme/defaults/dark-terminal.json +95 -0
  869. package/src/modes/theme/defaults/dark-tokyo-night.json +101 -0
  870. package/src/modes/theme/defaults/dark-tundra.json +91 -0
  871. package/src/modes/theme/defaults/dark-twilight.json +91 -0
  872. package/src/modes/theme/defaults/dark-volcanic.json +91 -0
  873. package/src/modes/theme/defaults/graphite.json +92 -0
  874. package/src/modes/theme/defaults/index.ts +199 -0
  875. package/src/modes/theme/defaults/light-arctic.json +107 -0
  876. package/src/modes/theme/defaults/light-aurora-day.json +91 -0
  877. package/src/modes/theme/defaults/light-canyon.json +91 -0
  878. package/src/modes/theme/defaults/light-catppuccin.json +106 -0
  879. package/src/modes/theme/defaults/light-cirrus.json +90 -0
  880. package/src/modes/theme/defaults/light-coral.json +95 -0
  881. package/src/modes/theme/defaults/light-cyberpunk.json +96 -0
  882. package/src/modes/theme/defaults/light-dawn.json +90 -0
  883. package/src/modes/theme/defaults/light-dunes.json +91 -0
  884. package/src/modes/theme/defaults/light-eucalyptus.json +95 -0
  885. package/src/modes/theme/defaults/light-forest.json +100 -0
  886. package/src/modes/theme/defaults/light-frost.json +95 -0
  887. package/src/modes/theme/defaults/light-github.json +115 -0
  888. package/src/modes/theme/defaults/light-glacier.json +91 -0
  889. package/src/modes/theme/defaults/light-gruvbox.json +108 -0
  890. package/src/modes/theme/defaults/light-haze.json +90 -0
  891. package/src/modes/theme/defaults/light-honeycomb.json +95 -0
  892. package/src/modes/theme/defaults/light-lagoon.json +91 -0
  893. package/src/modes/theme/defaults/light-lavender.json +95 -0
  894. package/src/modes/theme/defaults/light-meadow.json +91 -0
  895. package/src/modes/theme/defaults/light-mint.json +95 -0
  896. package/src/modes/theme/defaults/light-monochrome.json +101 -0
  897. package/src/modes/theme/defaults/light-ocean.json +99 -0
  898. package/src/modes/theme/defaults/light-one.json +99 -0
  899. package/src/modes/theme/defaults/light-opal.json +91 -0
  900. package/src/modes/theme/defaults/light-orchard.json +91 -0
  901. package/src/modes/theme/defaults/light-paper.json +95 -0
  902. package/src/modes/theme/defaults/light-poimandres.json +143 -0
  903. package/src/modes/theme/defaults/light-prism.json +90 -0
  904. package/src/modes/theme/defaults/light-retro.json +98 -0
  905. package/src/modes/theme/defaults/light-sand.json +95 -0
  906. package/src/modes/theme/defaults/light-savanna.json +91 -0
  907. package/src/modes/theme/defaults/light-solarized.json +102 -0
  908. package/src/modes/theme/defaults/light-soleil.json +90 -0
  909. package/src/modes/theme/defaults/light-sunset.json +99 -0
  910. package/src/modes/theme/defaults/light-synthwave.json +98 -0
  911. package/src/modes/theme/defaults/light-tokyo-night.json +111 -0
  912. package/src/modes/theme/defaults/light-wetland.json +91 -0
  913. package/src/modes/theme/defaults/light-zenith.json +89 -0
  914. package/src/modes/theme/defaults/limestone.json +94 -0
  915. package/src/modes/theme/defaults/mahogany.json +97 -0
  916. package/src/modes/theme/defaults/marble.json +93 -0
  917. package/src/modes/theme/defaults/obsidian.json +91 -0
  918. package/src/modes/theme/defaults/onyx.json +91 -0
  919. package/src/modes/theme/defaults/pearl.json +93 -0
  920. package/src/modes/theme/defaults/porcelain.json +91 -0
  921. package/src/modes/theme/defaults/quartz.json +96 -0
  922. package/src/modes/theme/defaults/sandstone.json +95 -0
  923. package/src/modes/theme/defaults/titanium.json +90 -0
  924. package/src/modes/theme/light.json +93 -0
  925. package/src/modes/theme/mermaid-cache.ts +92 -0
  926. package/src/modes/theme/shimmer.ts +305 -0
  927. package/src/modes/theme/theme-schema.json +463 -0
  928. package/src/modes/theme/theme.ts +3171 -0
  929. package/src/modes/turn-budget.ts +31 -0
  930. package/src/modes/types.ts +494 -0
  931. package/src/modes/ultrathink.ts +42 -0
  932. package/src/modes/utils/context-usage.ts +518 -0
  933. package/src/modes/utils/copy-targets.ts +378 -0
  934. package/src/modes/utils/hotkeys-markdown.ts +65 -0
  935. package/src/modes/utils/interactive-context-helpers.ts +31 -0
  936. package/src/modes/utils/keybinding-matchers.ts +86 -0
  937. package/src/modes/utils/tools-markdown.ts +31 -0
  938. package/src/modes/utils/transcript-render-helpers.ts +253 -0
  939. package/src/modes/utils/ui-helpers.ts +976 -0
  940. package/src/modes/warp-events.ts +232 -0
  941. package/src/modes/workflow.ts +55 -0
  942. package/src/plan-mode/approved-plan.ts +194 -0
  943. package/src/plan-mode/model-transition.ts +51 -0
  944. package/src/plan-mode/plan-files.ts +40 -0
  945. package/src/plan-mode/plan-handoff.ts +37 -0
  946. package/src/plan-mode/plan-protection.ts +31 -0
  947. package/src/plan-mode/state.ts +6 -0
  948. package/src/priority.json +60 -0
  949. package/src/prompts/advisor/active-repo-watchdog.md +6 -0
  950. package/src/prompts/advisor/advise-tool.md +3 -0
  951. package/src/prompts/advisor/context-files.md +8 -0
  952. package/src/prompts/advisor/system.md +98 -0
  953. package/src/prompts/agents/designer.md +74 -0
  954. package/src/prompts/agents/frontmatter.md +12 -0
  955. package/src/prompts/agents/init.md +33 -0
  956. package/src/prompts/agents/librarian.md +119 -0
  957. package/src/prompts/agents/reviewer.md +139 -0
  958. package/src/prompts/agents/scout.md +58 -0
  959. package/src/prompts/agents/security-reviewer.md +75 -0
  960. package/src/prompts/agents/task.md +17 -0
  961. package/src/prompts/bench/cache-prefix-chunk.md +1 -0
  962. package/src/prompts/bench/cache-prefix.md +3 -0
  963. package/src/prompts/bench/cache-suffix.md +1 -0
  964. package/src/prompts/bench.md +6 -0
  965. package/src/prompts/ci-green-request.md +36 -0
  966. package/src/prompts/dry-balance-bench.md +8 -0
  967. package/src/prompts/goals/goal-budget-limit.md +16 -0
  968. package/src/prompts/goals/goal-continuation.md +28 -0
  969. package/src/prompts/goals/goal-mode-active.md +23 -0
  970. package/src/prompts/goals/goal-mode-context.md +4 -0
  971. package/src/prompts/goals/goal-todo-context.md +12 -0
  972. package/src/prompts/goals/guided-goal-interview.md +43 -0
  973. package/src/prompts/memories/consolidation.md +30 -0
  974. package/src/prompts/memories/consolidation_system.md +4 -0
  975. package/src/prompts/memories/read-path.md +17 -0
  976. package/src/prompts/memories/stage_one_input.md +6 -0
  977. package/src/prompts/memories/stage_one_system.md +21 -0
  978. package/src/prompts/review-custom-request.md +21 -0
  979. package/src/prompts/review-headless-request.md +16 -0
  980. package/src/prompts/review-request.md +68 -0
  981. package/src/prompts/security/scan-coordinator.md +7 -0
  982. package/src/prompts/security/scan-request.md +21 -0
  983. package/src/prompts/security/validate-request.md +8 -0
  984. package/src/prompts/session/launch-completion.md +1 -0
  985. package/src/prompts/skills/autoload.md +8 -0
  986. package/src/prompts/skills/user-invocation.md +11 -0
  987. package/src/prompts/steering/parent-irc.md +5 -0
  988. package/src/prompts/steering/user-interjection.md +6 -0
  989. package/src/prompts/system/active-repo-context.md +4 -0
  990. package/src/prompts/system/agent-creation-architect.md +50 -0
  991. package/src/prompts/system/agent-creation-user.md +6 -0
  992. package/src/prompts/system/auto-continue.md +1 -0
  993. package/src/prompts/system/auto-thinking-difficulty-local.md +14 -0
  994. package/src/prompts/system/auto-thinking-difficulty.md +14 -0
  995. package/src/prompts/system/autolearn-guidance-learn.md +1 -0
  996. package/src/prompts/system/autolearn-guidance.md +7 -0
  997. package/src/prompts/system/autolearn-nudge-autocontinue.md +5 -0
  998. package/src/prompts/system/background-tan-dispatch.md +8 -0
  999. package/src/prompts/system/btw-user.md +8 -0
  1000. package/src/prompts/system/commit-message-system.md +14 -0
  1001. package/src/prompts/system/computer-safety.md +14 -0
  1002. package/src/prompts/system/custom-system-prompt.md +64 -0
  1003. package/src/prompts/system/eager-task.md +7 -0
  1004. package/src/prompts/system/eager-todo.md +18 -0
  1005. package/src/prompts/system/empty-stop-retry.md +4 -0
  1006. package/src/prompts/system/gemini-tool-call-reminder.md +9 -0
  1007. package/src/prompts/system/interrupted-thinking.md +7 -0
  1008. package/src/prompts/system/irc-autoreply.md +6 -0
  1009. package/src/prompts/system/irc-incoming.md +9 -0
  1010. package/src/prompts/system/manual-continue.md +7 -0
  1011. package/src/prompts/system/mcp-xdev-guidance.md +11 -0
  1012. package/src/prompts/system/memory-consolidation-system.md +8 -0
  1013. package/src/prompts/system/memory-extraction-system.md +26 -0
  1014. package/src/prompts/system/mid-run-todo-nudge.md +3 -0
  1015. package/src/prompts/system/omfg-user.md +50 -0
  1016. package/src/prompts/system/orchestrate-notice.md +40 -0
  1017. package/src/prompts/system/personalities/default.md +18 -0
  1018. package/src/prompts/system/personalities/friendly.md +17 -0
  1019. package/src/prompts/system/personalities/pragmatic.md +15 -0
  1020. package/src/prompts/system/plan-mode-active.md +125 -0
  1021. package/src/prompts/system/plan-mode-approved.md +22 -0
  1022. package/src/prompts/system/plan-mode-compact-instructions.md +17 -0
  1023. package/src/prompts/system/plan-mode-reference.md +10 -0
  1024. package/src/prompts/system/plan-mode-subagent.md +33 -0
  1025. package/src/prompts/system/plan-mode-tool-decision-reminder.md +9 -0
  1026. package/src/prompts/system/plan-yolo-handoff.md +5 -0
  1027. package/src/prompts/system/prewalk-checklist.md +7 -0
  1028. package/src/prompts/system/prewalk-continue.md +1 -0
  1029. package/src/prompts/system/prewalk-plan.md +13 -0
  1030. package/src/prompts/system/project-prompt.md +61 -0
  1031. package/src/prompts/system/recap-user.md +9 -0
  1032. package/src/prompts/system/resolve-device-reminder.md +3 -0
  1033. package/src/prompts/system/rewind-report.md +6 -0
  1034. package/src/prompts/system/side-channel-no-tools.md +3 -0
  1035. package/src/prompts/system/snapcompact-context-frames-note.md +1 -0
  1036. package/src/prompts/system/snapcompact-context-stub.md +1 -0
  1037. package/src/prompts/system/snapcompact-system-frames-note.md +1 -0
  1038. package/src/prompts/system/snapcompact-system-stub.md +1 -0
  1039. package/src/prompts/system/snapcompact-toolresult-note.md +1 -0
  1040. package/src/prompts/system/speech-rewrite.md +15 -0
  1041. package/src/prompts/system/subagent-async-pending.md +6 -0
  1042. package/src/prompts/system/subagent-system-prompt.md +73 -0
  1043. package/src/prompts/system/subagent-user-prompt.md +3 -0
  1044. package/src/prompts/system/subagent-yield-reminder.md +23 -0
  1045. package/src/prompts/system/system-prompt.md +263 -0
  1046. package/src/prompts/system/tan-context-switch.md +17 -0
  1047. package/src/prompts/system/task-label.md +23 -0
  1048. package/src/prompts/system/thinking-loop-redirect.md +10 -0
  1049. package/src/prompts/system/title-marker-instruction.md +1 -0
  1050. package/src/prompts/system/title-system.md +16 -0
  1051. package/src/prompts/system/tool-call-loop-redirect.md +8 -0
  1052. package/src/prompts/system/ttsr-interrupt.md +7 -0
  1053. package/src/prompts/system/ttsr-tool-reminder.md +5 -0
  1054. package/src/prompts/system/ultrathink-notice.md +3 -0
  1055. package/src/prompts/system/unexpected-stop-classifier.md +17 -0
  1056. package/src/prompts/system/unexpected-stop-retry.md +4 -0
  1057. package/src/prompts/system/vibe-mode-active.md +26 -0
  1058. package/src/prompts/system/web-search.md +25 -0
  1059. package/src/prompts/system/workflow-notice.md +112 -0
  1060. package/src/prompts/system/xdev-mount-notice.md +20 -0
  1061. package/src/prompts/tools/apply-patch.md +65 -0
  1062. package/src/prompts/tools/ask.md +22 -0
  1063. package/src/prompts/tools/ast-edit.md +11 -0
  1064. package/src/prompts/tools/ast-grep.md +19 -0
  1065. package/src/prompts/tools/async-result.md +8 -0
  1066. package/src/prompts/tools/bash.md +23 -0
  1067. package/src/prompts/tools/browser.md +29 -0
  1068. package/src/prompts/tools/checkpoint.md +15 -0
  1069. package/src/prompts/tools/computer.md +26 -0
  1070. package/src/prompts/tools/debug.md +3 -0
  1071. package/src/prompts/tools/eval.md +45 -0
  1072. package/src/prompts/tools/github.md +22 -0
  1073. package/src/prompts/tools/glob.md +16 -0
  1074. package/src/prompts/tools/goal.md +11 -0
  1075. package/src/prompts/tools/grep.md +13 -0
  1076. package/src/prompts/tools/hub.md +34 -0
  1077. package/src/prompts/tools/image-attachment-describe-system.md +8 -0
  1078. package/src/prompts/tools/image-attachment-describe.md +10 -0
  1079. package/src/prompts/tools/image-gen.md +7 -0
  1080. package/src/prompts/tools/inspect-image-system.md +20 -0
  1081. package/src/prompts/tools/inspect-image.md +22 -0
  1082. package/src/prompts/tools/learn.md +7 -0
  1083. package/src/prompts/tools/lsp-late-diagnostic.md +8 -0
  1084. package/src/prompts/tools/lsp.md +19 -0
  1085. package/src/prompts/tools/manage-skill.md +9 -0
  1086. package/src/prompts/tools/memory-edit.md +12 -0
  1087. package/src/prompts/tools/patch.md +57 -0
  1088. package/src/prompts/tools/read.md +27 -0
  1089. package/src/prompts/tools/recall.md +7 -0
  1090. package/src/prompts/tools/reflect.md +5 -0
  1091. package/src/prompts/tools/replace.md +30 -0
  1092. package/src/prompts/tools/retain.md +6 -0
  1093. package/src/prompts/tools/rewind.md +14 -0
  1094. package/src/prompts/tools/security-publish.md +1 -0
  1095. package/src/prompts/tools/security-scan.md +1 -0
  1096. package/src/prompts/tools/task-async-contract.md +1 -0
  1097. package/src/prompts/tools/task-summary.md +20 -0
  1098. package/src/prompts/tools/task.md +83 -0
  1099. package/src/prompts/tools/todo.md +42 -0
  1100. package/src/prompts/tools/vibe-kill.md +3 -0
  1101. package/src/prompts/tools/vibe-list.md +3 -0
  1102. package/src/prompts/tools/vibe-send.md +9 -0
  1103. package/src/prompts/tools/vibe-spawn.md +10 -0
  1104. package/src/prompts/tools/vibe-turn-result.md +19 -0
  1105. package/src/prompts/tools/vibe-wait.md +8 -0
  1106. package/src/prompts/tools/web-search.md +8 -0
  1107. package/src/prompts/tools/write.md +14 -0
  1108. package/src/registry/agent-lifecycle.ts +505 -0
  1109. package/src/registry/agent-registry.ts +287 -0
  1110. package/src/registry/persisted-agents.ts +423 -0
  1111. package/src/sdk.ts +3820 -0
  1112. package/src/secrets/index.ts +375 -0
  1113. package/src/secrets/obfuscator.ts +2629 -0
  1114. package/src/secrets/regex.ts +21 -0
  1115. package/src/security/auth.ts +98 -0
  1116. package/src/security/cloud.ts +686 -0
  1117. package/src/security/comparison.ts +255 -0
  1118. package/src/security/contracts/ids.ts +111 -0
  1119. package/src/security/contracts/index.ts +4 -0
  1120. package/src/security/contracts/schemas.ts +219 -0
  1121. package/src/security/contracts/types.ts +254 -0
  1122. package/src/security/contracts/validation.ts +69 -0
  1123. package/src/security/coordinator.ts +708 -0
  1124. package/src/security/importers/codex-security.ts +387 -0
  1125. package/src/security/importers/index.ts +2 -0
  1126. package/src/security/importers/sarif.ts +357 -0
  1127. package/src/security/index.ts +13 -0
  1128. package/src/security/preflight.ts +405 -0
  1129. package/src/security/provenance.ts +106 -0
  1130. package/src/security/publication.ts +326 -0
  1131. package/src/security/remediation.ts +93 -0
  1132. package/src/security/resource-output.ts +50 -0
  1133. package/src/security/sarif.ts +78 -0
  1134. package/src/security/store.ts +430 -0
  1135. package/src/session/acp-permission-gate.ts +165 -0
  1136. package/src/session/agent-session-events.ts +67 -0
  1137. package/src/session/agent-session-types.ts +407 -0
  1138. package/src/session/agent-session.ts +9000 -0
  1139. package/src/session/agent-storage.ts +807 -0
  1140. package/src/session/artifacts.ts +154 -0
  1141. package/src/session/async-job-delivery.ts +82 -0
  1142. package/src/session/auth-broker-config.ts +92 -0
  1143. package/src/session/auth-storage.ts +25 -0
  1144. package/src/session/bash-runner.ts +326 -0
  1145. package/src/session/blob-store.ts +295 -0
  1146. package/src/session/checkpoint-entries.ts +81 -0
  1147. package/src/session/claude-session-store.ts +426 -0
  1148. package/src/session/client-bridge.ts +85 -0
  1149. package/src/session/codex-auto-reset.ts +673 -0
  1150. package/src/session/codex-session-store.ts +673 -0
  1151. package/src/session/compact-modes.ts +105 -0
  1152. package/src/session/credential-pin.ts +93 -0
  1153. package/src/session/eval-runner.ts +219 -0
  1154. package/src/session/exit-diagnostics.ts +310 -0
  1155. package/src/session/foreign-session-import.ts +52 -0
  1156. package/src/session/foreign-session-jsonl.ts +29 -0
  1157. package/src/session/foreign-session-store.ts +26 -0
  1158. package/src/session/history-storage.ts +329 -0
  1159. package/src/session/indexed-session-storage.ts +553 -0
  1160. package/src/session/irc-bridge.ts +203 -0
  1161. package/src/session/launch-completion.ts +37 -0
  1162. package/src/session/messages.ts +1304 -0
  1163. package/src/session/model-controls.ts +757 -0
  1164. package/src/session/prewalk.ts +279 -0
  1165. package/src/session/provider-image-budget.ts +86 -0
  1166. package/src/session/queued-messages.ts +99 -0
  1167. package/src/session/redis-session-storage.ts +257 -0
  1168. package/src/session/retry-fallback-chains.ts +455 -0
  1169. package/src/session/role-models.ts +85 -0
  1170. package/src/session/session-advisors.ts +1896 -0
  1171. package/src/session/session-context.ts +584 -0
  1172. package/src/session/session-dump-format.ts +216 -0
  1173. package/src/session/session-entries.ts +306 -0
  1174. package/src/session/session-handoff.ts +325 -0
  1175. package/src/session/session-history-format.ts +459 -0
  1176. package/src/session/session-listing.ts +715 -0
  1177. package/src/session/session-loader.ts +362 -0
  1178. package/src/session/session-maintenance.ts +3115 -0
  1179. package/src/session/session-manager.ts +2747 -0
  1180. package/src/session/session-memory.ts +222 -0
  1181. package/src/session/session-metadata.ts +53 -0
  1182. package/src/session/session-migrations.ts +78 -0
  1183. package/src/session/session-paths.ts +280 -0
  1184. package/src/session/session-persistence.ts +293 -0
  1185. package/src/session/session-provider-boundary.ts +306 -0
  1186. package/src/session/session-stats.ts +349 -0
  1187. package/src/session/session-storage.ts +774 -0
  1188. package/src/session/session-title-slot.ts +141 -0
  1189. package/src/session/session-tools.ts +1385 -0
  1190. package/src/session/session-workspace.ts +53 -0
  1191. package/src/session/settings-stream-fn.ts +79 -0
  1192. package/src/session/shake-types.ts +43 -0
  1193. package/src/session/snapcompact-inline.ts +545 -0
  1194. package/src/session/snapcompact-savings-journal.ts +113 -0
  1195. package/src/session/sql-session-storage.ts +374 -0
  1196. package/src/session/stream-guards.ts +417 -0
  1197. package/src/session/streaming-output.ts +1459 -0
  1198. package/src/session/todo-tracker.ts +380 -0
  1199. package/src/session/tool-choice-queue.ts +305 -0
  1200. package/src/session/ttsr-coordinator.ts +496 -0
  1201. package/src/session/turn-persistence.ts +142 -0
  1202. package/src/session/turn-recovery.ts +2005 -0
  1203. package/src/session/unexpected-stop-classifier.ts +141 -0
  1204. package/src/session/yield-queue.ts +288 -0
  1205. package/src/slash-commands/acp-builtins.ts +70 -0
  1206. package/src/slash-commands/available-commands.ts +105 -0
  1207. package/src/slash-commands/builtin-registry.ts +3149 -0
  1208. package/src/slash-commands/helpers/active-oauth-account.ts +80 -0
  1209. package/src/slash-commands/helpers/collab-qrcode.ts +28 -0
  1210. package/src/slash-commands/helpers/context-report.ts +66 -0
  1211. package/src/slash-commands/helpers/format.ts +46 -0
  1212. package/src/slash-commands/helpers/logout.ts +108 -0
  1213. package/src/slash-commands/helpers/marketplace-manager.ts +25 -0
  1214. package/src/slash-commands/helpers/mcp.ts +533 -0
  1215. package/src/slash-commands/helpers/parse.ts +85 -0
  1216. package/src/slash-commands/helpers/reset-usage.ts +68 -0
  1217. package/src/slash-commands/helpers/security.ts +451 -0
  1218. package/src/slash-commands/helpers/session-pin.ts +44 -0
  1219. package/src/slash-commands/helpers/ssh.ts +196 -0
  1220. package/src/slash-commands/helpers/stats-dashboard.ts +86 -0
  1221. package/src/slash-commands/helpers/todo.ts +285 -0
  1222. package/src/slash-commands/helpers/usage-report.ts +198 -0
  1223. package/src/slash-commands/marketplace-install-parser.ts +99 -0
  1224. package/src/slash-commands/types.ts +139 -0
  1225. package/src/ssh/config-writer.ts +183 -0
  1226. package/src/ssh/connection-manager.ts +667 -0
  1227. package/src/ssh/file-transfer.ts +214 -0
  1228. package/src/ssh/sshfs-mount.ts +163 -0
  1229. package/src/ssh/utils.ts +51 -0
  1230. package/src/startup-splash.ts +19 -0
  1231. package/src/stt/asr-client.ts +401 -0
  1232. package/src/stt/asr-protocol.ts +65 -0
  1233. package/src/stt/asr-worker.ts +603 -0
  1234. package/src/stt/downloader.ts +142 -0
  1235. package/src/stt/endpointer.ts +259 -0
  1236. package/src/stt/index.ts +6 -0
  1237. package/src/stt/models.ts +150 -0
  1238. package/src/stt/sherpa-runtime.ts +71 -0
  1239. package/src/stt/stt-controller.ts +320 -0
  1240. package/src/stt/submit-trigger.ts +74 -0
  1241. package/src/subprocess/worker-client.ts +463 -0
  1242. package/src/subprocess/worker-runtime.ts +494 -0
  1243. package/src/system-prompt.ts +921 -0
  1244. package/src/task/agents.ts +170 -0
  1245. package/src/task/commands.ts +132 -0
  1246. package/src/task/discovery.ts +145 -0
  1247. package/src/task/executor.ts +3431 -0
  1248. package/src/task/index.ts +1515 -0
  1249. package/src/task/isolation-ownership.ts +106 -0
  1250. package/src/task/isolation-runner.ts +444 -0
  1251. package/src/task/label.ts +40 -0
  1252. package/src/task/name-generator.ts +1577 -0
  1253. package/src/task/omp-command.ts +26 -0
  1254. package/src/task/output-manager.ts +115 -0
  1255. package/src/task/parallel.ts +221 -0
  1256. package/src/task/persisted-revive.ts +173 -0
  1257. package/src/task/prewalk.ts +6 -0
  1258. package/src/task/prompt-policy.ts +8 -0
  1259. package/src/task/provider-concurrency.ts +100 -0
  1260. package/src/task/read-only-policy.ts +27 -0
  1261. package/src/task/render.ts +1830 -0
  1262. package/src/task/renderer.ts +14 -0
  1263. package/src/task/repair-args.ts +118 -0
  1264. package/src/task/spawn-policy.ts +72 -0
  1265. package/src/task/structured-subagent.ts +676 -0
  1266. package/src/task/subprocess-tool-registry.ts +88 -0
  1267. package/src/task/types.ts +555 -0
  1268. package/src/task/worktree.ts +967 -0
  1269. package/src/task/yield-assembly.ts +198 -0
  1270. package/src/telemetry-export.ts +504 -0
  1271. package/src/thinking.ts +377 -0
  1272. package/src/tiny/device.ts +111 -0
  1273. package/src/tiny/dtype.ts +101 -0
  1274. package/src/tiny/message-preproc.ts +155 -0
  1275. package/src/tiny/models.ts +268 -0
  1276. package/src/tiny/text.ts +290 -0
  1277. package/src/tiny/title-client.ts +460 -0
  1278. package/src/tiny/title-protocol.ts +56 -0
  1279. package/src/tiny/worker.ts +354 -0
  1280. package/src/tools/acp-bridge.ts +125 -0
  1281. package/src/tools/approval.ts +245 -0
  1282. package/src/tools/ask.ts +1459 -0
  1283. package/src/tools/ast-edit.ts +718 -0
  1284. package/src/tools/ast-grep.ts +526 -0
  1285. package/src/tools/auto-generated-guard.ts +335 -0
  1286. package/src/tools/bash-interactive.ts +435 -0
  1287. package/src/tools/bash-interceptor.ts +148 -0
  1288. package/src/tools/bash-pty-selection.ts +14 -0
  1289. package/src/tools/bash-skill-urls.ts +350 -0
  1290. package/src/tools/bash.ts +1826 -0
  1291. package/src/tools/browser/aria/aria-snapshot.bundle.txt +7 -0
  1292. package/src/tools/browser/aria/aria-snapshot.ts +131 -0
  1293. package/src/tools/browser/attach.ts +219 -0
  1294. package/src/tools/browser/cmux/cmux-tab.ts +1531 -0
  1295. package/src/tools/browser/cmux/rpc.ts +200 -0
  1296. package/src/tools/browser/cmux/socket-client.ts +445 -0
  1297. package/src/tools/browser/launch.ts +939 -0
  1298. package/src/tools/browser/readable.ts +112 -0
  1299. package/src/tools/browser/registry.ts +447 -0
  1300. package/src/tools/browser/relay/bridge.ts +945 -0
  1301. package/src/tools/browser/relay/daemon.ts +117 -0
  1302. package/src/tools/browser/relay/extension-assets/background.js.txt +242 -0
  1303. package/src/tools/browser/relay/extension-assets/manifest.json.txt +14 -0
  1304. package/src/tools/browser/relay/extension-assets/options.html.txt +53 -0
  1305. package/src/tools/browser/relay/extension-assets/options.js.txt +23 -0
  1306. package/src/tools/browser/relay/kind.ts +41 -0
  1307. package/src/tools/browser/relay/protocol.ts +54 -0
  1308. package/src/tools/browser/relay/server.ts +141 -0
  1309. package/src/tools/browser/render.ts +229 -0
  1310. package/src/tools/browser/run-output.ts +76 -0
  1311. package/src/tools/browser/shared-daemon.ts +139 -0
  1312. package/src/tools/browser/tab-protocol.ts +123 -0
  1313. package/src/tools/browser/tab-supervisor.ts +1077 -0
  1314. package/src/tools/browser/tab-worker-entry.ts +29 -0
  1315. package/src/tools/browser/tab-worker.ts +1982 -0
  1316. package/src/tools/browser.ts +487 -0
  1317. package/src/tools/builtin-names.ts +67 -0
  1318. package/src/tools/checkpoint.ts +137 -0
  1319. package/src/tools/computer/exposure.ts +14 -0
  1320. package/src/tools/computer/protocol.ts +69 -0
  1321. package/src/tools/computer/supervisor.ts +409 -0
  1322. package/src/tools/computer/worker-entry.ts +39 -0
  1323. package/src/tools/computer/worker.ts +745 -0
  1324. package/src/tools/computer-renderer.ts +147 -0
  1325. package/src/tools/computer.ts +222 -0
  1326. package/src/tools/conflict-detect.ts +815 -0
  1327. package/src/tools/context.ts +49 -0
  1328. package/src/tools/debug.ts +1121 -0
  1329. package/src/tools/default-renderer.ts +154 -0
  1330. package/src/tools/essential-tools.ts +46 -0
  1331. package/src/tools/eval-backends.ts +34 -0
  1332. package/src/tools/eval-format/index.ts +24 -0
  1333. package/src/tools/eval-format/javascript.ts +952 -0
  1334. package/src/tools/eval-format/julia.ts +446 -0
  1335. package/src/tools/eval-format/python.ts +544 -0
  1336. package/src/tools/eval-format/ruby.ts +380 -0
  1337. package/src/tools/eval-render.ts +784 -0
  1338. package/src/tools/eval.ts +774 -0
  1339. package/src/tools/fetch.ts +1889 -0
  1340. package/src/tools/file-recorder.ts +35 -0
  1341. package/src/tools/fs-cache-invalidation.ts +28 -0
  1342. package/src/tools/gh-cache-invalidation.ts +175 -0
  1343. package/src/tools/gh-format.ts +12 -0
  1344. package/src/tools/gh-renderer.ts +484 -0
  1345. package/src/tools/gh.ts +3958 -0
  1346. package/src/tools/github-cache.ts +663 -0
  1347. package/src/tools/glob.ts +691 -0
  1348. package/src/tools/grep.ts +1920 -0
  1349. package/src/tools/grouped-file-output.ts +210 -0
  1350. package/src/tools/hub/index.ts +579 -0
  1351. package/src/tools/hub/jobs.ts +714 -0
  1352. package/src/tools/hub/launch.ts +690 -0
  1353. package/src/tools/hub/messaging.ts +735 -0
  1354. package/src/tools/hub/types.ts +117 -0
  1355. package/src/tools/image-gen.ts +1689 -0
  1356. package/src/tools/image-providers.ts +50 -0
  1357. package/src/tools/index.ts +736 -0
  1358. package/src/tools/inspect-image-renderer.ts +133 -0
  1359. package/src/tools/inspect-image.ts +316 -0
  1360. package/src/tools/json-tree.ts +260 -0
  1361. package/src/tools/jtd-to-json-schema.ts +219 -0
  1362. package/src/tools/jtd-to-typescript.ts +136 -0
  1363. package/src/tools/jtd-utils.ts +102 -0
  1364. package/src/tools/learn.ts +141 -0
  1365. package/src/tools/list-limit.ts +40 -0
  1366. package/src/tools/manage-skill.ts +102 -0
  1367. package/src/tools/match-line-format.ts +20 -0
  1368. package/src/tools/memory-edit.ts +61 -0
  1369. package/src/tools/memory-recall.ts +102 -0
  1370. package/src/tools/memory-reflect.ts +88 -0
  1371. package/src/tools/memory-render.ts +211 -0
  1372. package/src/tools/memory-retain.ts +89 -0
  1373. package/src/tools/output-meta.ts +860 -0
  1374. package/src/tools/output-schema-validator.ts +307 -0
  1375. package/src/tools/path-utils.ts +1489 -0
  1376. package/src/tools/plan-mode-guard.ts +155 -0
  1377. package/src/tools/puppeteer/00_stealth_tampering.txt +44 -0
  1378. package/src/tools/puppeteer/01_stealth_activity.txt +80 -0
  1379. package/src/tools/puppeteer/02_stealth_hairline.txt +57 -0
  1380. package/src/tools/puppeteer/03_stealth_botd.txt +380 -0
  1381. package/src/tools/puppeteer/04_stealth_iframe.txt +174 -0
  1382. package/src/tools/puppeteer/05_stealth_webgl.txt +233 -0
  1383. package/src/tools/puppeteer/06_stealth_screen.txt +260 -0
  1384. package/src/tools/puppeteer/07_stealth_fonts.txt +99 -0
  1385. package/src/tools/puppeteer/08_stealth_audio.txt +63 -0
  1386. package/src/tools/puppeteer/09_stealth_locale.txt +51 -0
  1387. package/src/tools/puppeteer/10_stealth_plugins.txt +212 -0
  1388. package/src/tools/puppeteer/11_stealth_hardware.txt +59 -0
  1389. package/src/tools/puppeteer/12_stealth_codecs.txt +42 -0
  1390. package/src/tools/puppeteer/13_stealth_worker.txt +235 -0
  1391. package/src/tools/read.ts +3762 -0
  1392. package/src/tools/render-utils.ts +926 -0
  1393. package/src/tools/renderers.ts +133 -0
  1394. package/src/tools/report-tool-issue.ts +568 -0
  1395. package/src/tools/resolve.ts +423 -0
  1396. package/src/tools/review.ts +103 -0
  1397. package/src/tools/run-scope.ts +417 -0
  1398. package/src/tools/security-scan.ts +287 -0
  1399. package/src/tools/shell-tokenize.ts +213 -0
  1400. package/src/tools/sqlite-reader.ts +884 -0
  1401. package/src/tools/terminal-output.ts +141 -0
  1402. package/src/tools/todo.ts +1226 -0
  1403. package/src/tools/tool-errors.ts +62 -0
  1404. package/src/tools/tool-result.ts +102 -0
  1405. package/src/tools/tool-timeouts.ts +38 -0
  1406. package/src/tools/tts.ts +266 -0
  1407. package/src/tools/vibe.ts +608 -0
  1408. package/src/tools/write.ts +1646 -0
  1409. package/src/tools/xdev.ts +560 -0
  1410. package/src/tools/yield.ts +486 -0
  1411. package/src/tts/downloader.ts +64 -0
  1412. package/src/tts/index.ts +10 -0
  1413. package/src/tts/models.ts +137 -0
  1414. package/src/tts/runtime.ts +21 -0
  1415. package/src/tts/speakable.ts +392 -0
  1416. package/src/tts/speech-enhancer.ts +206 -0
  1417. package/src/tts/streaming-player.ts +120 -0
  1418. package/src/tts/tts-client.ts +475 -0
  1419. package/src/tts/tts-protocol.ts +69 -0
  1420. package/src/tts/tts-worker.ts +434 -0
  1421. package/src/tts/vocalizer.ts +419 -0
  1422. package/src/tts/wav.ts +58 -0
  1423. package/src/tui/code-cell.ts +268 -0
  1424. package/src/tui/file-list.ts +55 -0
  1425. package/src/tui/hyperlink.ts +178 -0
  1426. package/src/tui/index.ts +13 -0
  1427. package/src/tui/output-block.ts +268 -0
  1428. package/src/tui/status-line.ts +54 -0
  1429. package/src/tui/tree-list.ts +172 -0
  1430. package/src/tui/types.ts +15 -0
  1431. package/src/tui/utils.ts +103 -0
  1432. package/src/tui/width-aware-text.ts +58 -0
  1433. package/src/utils/active-repo-context.ts +143 -0
  1434. package/src/utils/block-context.ts +312 -0
  1435. package/src/utils/changelog.ts +373 -0
  1436. package/src/utils/clipboard.ts +361 -0
  1437. package/src/utils/command-args.ts +74 -0
  1438. package/src/utils/commit-message-generator.ts +148 -0
  1439. package/src/utils/cpuprofile.ts +235 -0
  1440. package/src/utils/edit-mode.ts +61 -0
  1441. package/src/utils/enhanced-paste.ts +230 -0
  1442. package/src/utils/event-bus.ts +33 -0
  1443. package/src/utils/external-editor.ts +80 -0
  1444. package/src/utils/fetch-timeout.ts +10 -0
  1445. package/src/utils/file-display-mode.ts +44 -0
  1446. package/src/utils/file-mentions.ts +293 -0
  1447. package/src/utils/git.ts +2472 -0
  1448. package/src/utils/image-loading.ts +236 -0
  1449. package/src/utils/image-resize.ts +420 -0
  1450. package/src/utils/image-vision-fallback.ts +196 -0
  1451. package/src/utils/inspect-image-mode.ts +39 -0
  1452. package/src/utils/ipc.ts +38 -0
  1453. package/src/utils/jj.ts +422 -0
  1454. package/src/utils/lang-from-path.ts +251 -0
  1455. package/src/utils/late-cleanup.ts +17 -0
  1456. package/src/utils/local-date.ts +7 -0
  1457. package/src/utils/mac-file-urls.applescript +37 -0
  1458. package/src/utils/markit-cache.ts +166 -0
  1459. package/src/utils/markit.ts +223 -0
  1460. package/src/utils/mupdf-wasm-embed.ts +12 -0
  1461. package/src/utils/open.ts +126 -0
  1462. package/src/utils/profile-tree.ts +111 -0
  1463. package/src/utils/prompt-path.ts +3 -0
  1464. package/src/utils/qrcode.ts +535 -0
  1465. package/src/utils/sample-profile.ts +437 -0
  1466. package/src/utils/session-color.ts +142 -0
  1467. package/src/utils/shell-snapshot-fn-env.sh +63 -0
  1468. package/src/utils/shell-snapshot.ts +326 -0
  1469. package/src/utils/sixel.ts +69 -0
  1470. package/src/utils/thinking-display.ts +163 -0
  1471. package/src/utils/title-generator.ts +597 -0
  1472. package/src/utils/token-rate.ts +72 -0
  1473. package/src/utils/tool-choice.ts +50 -0
  1474. package/src/utils/tools-manager.ts +411 -0
  1475. package/src/utils/turndown.ts +82 -0
  1476. package/src/utils/zip.ts +1106 -0
  1477. package/src/vibe/runtime.ts +1684 -0
  1478. package/src/vibe/state.ts +4 -0
  1479. package/src/web/kagi.ts +305 -0
  1480. package/src/web/parallel.ts +354 -0
  1481. package/src/web/scrapers/artifacthub.ts +207 -0
  1482. package/src/web/scrapers/arxiv.ts +83 -0
  1483. package/src/web/scrapers/aur.ts +162 -0
  1484. package/src/web/scrapers/biorxiv.ts +133 -0
  1485. package/src/web/scrapers/bluesky.ts +262 -0
  1486. package/src/web/scrapers/brew.ts +172 -0
  1487. package/src/web/scrapers/cheatsh.ts +68 -0
  1488. package/src/web/scrapers/chocolatey.ts +196 -0
  1489. package/src/web/scrapers/choosealicense.ts +95 -0
  1490. package/src/web/scrapers/cisa-kev.ts +87 -0
  1491. package/src/web/scrapers/clojars.ts +154 -0
  1492. package/src/web/scrapers/coingecko.ts +177 -0
  1493. package/src/web/scrapers/crates-io.ts +97 -0
  1494. package/src/web/scrapers/crossref.ts +136 -0
  1495. package/src/web/scrapers/devto.ts +147 -0
  1496. package/src/web/scrapers/discogs.ts +306 -0
  1497. package/src/web/scrapers/discourse.ts +197 -0
  1498. package/src/web/scrapers/dockerhub.ts +138 -0
  1499. package/src/web/scrapers/docs-rs.ts +663 -0
  1500. package/src/web/scrapers/fdroid.ts +134 -0
  1501. package/src/web/scrapers/firefox-addons.ts +191 -0
  1502. package/src/web/scrapers/flathub.ts +223 -0
  1503. package/src/web/scrapers/github-gist.ts +58 -0
  1504. package/src/web/scrapers/github.ts +800 -0
  1505. package/src/web/scrapers/gitlab.ts +401 -0
  1506. package/src/web/scrapers/go-pkg.ts +266 -0
  1507. package/src/web/scrapers/hackage.ts +129 -0
  1508. package/src/web/scrapers/hackernews.ts +189 -0
  1509. package/src/web/scrapers/hex.ts +105 -0
  1510. package/src/web/scrapers/huggingface.ts +321 -0
  1511. package/src/web/scrapers/iacr.ts +89 -0
  1512. package/src/web/scrapers/index.ts +252 -0
  1513. package/src/web/scrapers/jetbrains-marketplace.ts +159 -0
  1514. package/src/web/scrapers/lemmy.ts +203 -0
  1515. package/src/web/scrapers/lobsters.ts +175 -0
  1516. package/src/web/scrapers/mastodon.ts +292 -0
  1517. package/src/web/scrapers/maven.ts +138 -0
  1518. package/src/web/scrapers/mdn.ts +173 -0
  1519. package/src/web/scrapers/metacpan.ts +222 -0
  1520. package/src/web/scrapers/musicbrainz.ts +250 -0
  1521. package/src/web/scrapers/npm.ts +98 -0
  1522. package/src/web/scrapers/nuget.ts +183 -0
  1523. package/src/web/scrapers/nvd.ts +222 -0
  1524. package/src/web/scrapers/ollama.ts +239 -0
  1525. package/src/web/scrapers/open-vsx.ts +106 -0
  1526. package/src/web/scrapers/opencorporates.ts +292 -0
  1527. package/src/web/scrapers/openlibrary.ts +336 -0
  1528. package/src/web/scrapers/orcid.ts +286 -0
  1529. package/src/web/scrapers/osv.ts +176 -0
  1530. package/src/web/scrapers/packagist.ts +160 -0
  1531. package/src/web/scrapers/pub-dev.ts +143 -0
  1532. package/src/web/scrapers/pubmed.ts +211 -0
  1533. package/src/web/scrapers/pypi.ts +112 -0
  1534. package/src/web/scrapers/rawg.ts +110 -0
  1535. package/src/web/scrapers/readthedocs.ts +121 -0
  1536. package/src/web/scrapers/reddit.ts +95 -0
  1537. package/src/web/scrapers/repology.ts +251 -0
  1538. package/src/web/scrapers/rfc.ts +201 -0
  1539. package/src/web/scrapers/rubygems.ts +103 -0
  1540. package/src/web/scrapers/searchcode.ts +189 -0
  1541. package/src/web/scrapers/sec-edgar.ts +261 -0
  1542. package/src/web/scrapers/semantic-scholar.ts +171 -0
  1543. package/src/web/scrapers/snapcraft.ts +187 -0
  1544. package/src/web/scrapers/sourcegraph.ts +336 -0
  1545. package/src/web/scrapers/spdx.ts +108 -0
  1546. package/src/web/scrapers/spotify.ts +198 -0
  1547. package/src/web/scrapers/stackoverflow.ts +120 -0
  1548. package/src/web/scrapers/terraform.ts +277 -0
  1549. package/src/web/scrapers/tldr.ts +47 -0
  1550. package/src/web/scrapers/twitter.ts +94 -0
  1551. package/src/web/scrapers/types.ts +354 -0
  1552. package/src/web/scrapers/utils.ts +109 -0
  1553. package/src/web/scrapers/vimeo.ts +133 -0
  1554. package/src/web/scrapers/vscode-marketplace.ts +187 -0
  1555. package/src/web/scrapers/w3c.ts +156 -0
  1556. package/src/web/scrapers/wikidata.ts +344 -0
  1557. package/src/web/scrapers/wikipedia.ts +84 -0
  1558. package/src/web/scrapers/youtube.ts +325 -0
  1559. package/src/web/search/index.ts +393 -0
  1560. package/src/web/search/provider.ts +272 -0
  1561. package/src/web/search/providers/anthropic.ts +406 -0
  1562. package/src/web/search/providers/base.ts +112 -0
  1563. package/src/web/search/providers/brave.ts +181 -0
  1564. package/src/web/search/providers/browser-headers.ts +82 -0
  1565. package/src/web/search/providers/browser-page.ts +125 -0
  1566. package/src/web/search/providers/codex.ts +788 -0
  1567. package/src/web/search/providers/duckduckgo.ts +382 -0
  1568. package/src/web/search/providers/ecosia.ts +183 -0
  1569. package/src/web/search/providers/exa.ts +513 -0
  1570. package/src/web/search/providers/firecrawl.ts +213 -0
  1571. package/src/web/search/providers/gemini.ts +634 -0
  1572. package/src/web/search/providers/google.ts +195 -0
  1573. package/src/web/search/providers/jina.ts +144 -0
  1574. package/src/web/search/providers/kagi.ts +98 -0
  1575. package/src/web/search/providers/kimi.ts +221 -0
  1576. package/src/web/search/providers/mojeek.ts +220 -0
  1577. package/src/web/search/providers/parallel.ts +186 -0
  1578. package/src/web/search/providers/perplexity-auth.ts +142 -0
  1579. package/src/web/search/providers/perplexity.ts +997 -0
  1580. package/src/web/search/providers/public.ts +199 -0
  1581. package/src/web/search/providers/searxng.ts +467 -0
  1582. package/src/web/search/providers/startpage.ts +225 -0
  1583. package/src/web/search/providers/synthetic.ts +126 -0
  1584. package/src/web/search/providers/tavily.ts +244 -0
  1585. package/src/web/search/providers/tinyfish.ts +166 -0
  1586. package/src/web/search/providers/utils.ts +130 -0
  1587. package/src/web/search/providers/xai.ts +372 -0
  1588. package/src/web/search/providers/zai.ts +452 -0
  1589. package/src/web/search/query.ts +850 -0
  1590. package/src/web/search/render.ts +262 -0
  1591. package/src/web/search/types.ts +518 -0
  1592. package/src/web/search/utils.ts +17 -0
  1593. package/src/workspace-tree.ts +326 -0
@@ -0,0 +1,1830 @@
1
+ /**
2
+ * TUI rendering for task tool.
3
+ *
4
+ * Provides renderCall and renderResult functions for displaying
5
+ * task execution in the terminal UI.
6
+ */
7
+ import path from "node:path";
8
+ import type { Component } from "@oh-my-pi/pi-tui";
9
+ import { Container, Markdown, Text } from "@oh-my-pi/pi-tui";
10
+ import { formatNumber, sanitizeText } from "@oh-my-pi/pi-utils";
11
+ import { settings } from "../config/settings";
12
+ import type { RenderResultOptions } from "../extensibility/custom-tools/types";
13
+ import { formatContextUsage } from "../modes/components/status-line/context-thresholds";
14
+ import { getMarkdownTheme, type Theme } from "../modes/theme/theme";
15
+ import { stripGeneratedOutputNotice, stripRawOutputArtifactNotice } from "../tools/output-meta";
16
+ import {
17
+ capPreviewLines,
18
+ formatBadge,
19
+ formatDuration,
20
+ formatExpandHint,
21
+ formatMoreItems,
22
+ formatStatusIcon,
23
+ previewLine,
24
+ previewWindowRows,
25
+ replaceTabs,
26
+ type ToolUIStatus,
27
+ truncateToWidth,
28
+ } from "../tools/render-utils";
29
+ import {
30
+ type FindingDetails,
31
+ type FindingPriority,
32
+ getPriorityInfo,
33
+ PRIORITY_LABELS,
34
+ parseFindingDetails,
35
+ type SubmitReviewDetails,
36
+ } from "../tools/review";
37
+ import { framedBlock, renderStatusLine } from "../tui";
38
+ import { repairDoubleEncodedJsonString } from "./repair-args";
39
+ import { subprocessToolRegistry } from "./subprocess-tool-registry";
40
+ import type { AgentProgress, SingleResult, TaskItem, TaskParams, TaskToolDetails, YieldItem } from "./types";
41
+ import { assembleYieldResult } from "./yield-assembly";
42
+
43
+ /** Render context threaded in from `ToolExecutionComponent.#buildRenderContext`. */
44
+ interface TaskRenderContext {
45
+ hasResult?: boolean;
46
+ /**
47
+ * The block left the transcript live region (detached spawn the transcript
48
+ * has moved past, or a sealed block): progress rows render static gray, so
49
+ * commit-eligible rows do not repaint after entering native scrollback.
50
+ */
51
+ frozen?: boolean;
52
+ /**
53
+ * Wall clock for time-derived rows (current-tool elapsed, retry countdown).
54
+ * The component freezes it once the block settles or any of its rows enter
55
+ * native scrollback, so identical-input rebuilds stay byte-identical with
56
+ * committed history. Absent: render with the live clock.
57
+ */
58
+ nowMs?: number;
59
+ }
60
+ type TaskRenderOptions = RenderResultOptions & { renderContext?: TaskRenderContext };
61
+
62
+ const MAX_NESTED_TASK_RENDER_DEPTH = 8;
63
+
64
+ function renderNestedCycleLine(theme: Theme): string {
65
+ return theme.fg("dim", "… nested task progress already shown");
66
+ }
67
+
68
+ /**
69
+ * Get status icon for agent state.
70
+ * For running status, uses animated spinner if spinnerFrame is provided.
71
+ * Maps AgentProgress status to styled icon format.
72
+ */
73
+ function getStatusIcon(status: AgentProgress["status"], theme: Theme, spinnerFrame?: number): string {
74
+ switch (status) {
75
+ case "pending":
76
+ return formatStatusIcon("pending", theme);
77
+ case "running":
78
+ return formatStatusIcon("running", theme, spinnerFrame);
79
+ case "completed":
80
+ return formatStatusIcon("success", theme);
81
+ case "failed":
82
+ return formatStatusIcon("error", theme);
83
+ case "aborted":
84
+ return formatStatusIcon("aborted", theme);
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Append tool-count, context, and cost stats to a status line string.
90
+ */
91
+ function appendAgentStats(
92
+ line: string,
93
+ opts: {
94
+ toolCount?: number;
95
+ requests?: number;
96
+ tokens: number;
97
+ contextTokens?: number;
98
+ contextWindow?: number;
99
+ cost: number;
100
+ resolvedModel?: string;
101
+ showResolvedModelBadge?: boolean;
102
+ },
103
+ theme: Theme,
104
+ ): string {
105
+ if (opts.toolCount) {
106
+ line += `${theme.sep.dot}${theme.fg("dim", `${formatNumber(opts.toolCount)} ${theme.icon.extensionTool}`)}`;
107
+ }
108
+ if (opts.requests) {
109
+ line += `${theme.sep.dot}${theme.fg("dim", `${formatNumber(opts.requests)} req`)}`;
110
+ }
111
+ // Current per-turn context — match the status line's `<pct>%/<window>` gauge (e.g. `5.1%/1M`).
112
+ if (opts.contextTokens && opts.contextTokens > 0) {
113
+ const ctx =
114
+ opts.contextWindow && opts.contextWindow > 0
115
+ ? formatContextUsage((opts.contextTokens / opts.contextWindow) * 100, opts.contextWindow)
116
+ : `${formatNumber(opts.contextTokens)}`;
117
+ line += `${theme.sep.dot}${theme.fg("dim", ctx)}`;
118
+ }
119
+ if (opts.cost > 0) {
120
+ line += `${theme.sep.dot}${theme.fg("statusLineCost", `$${opts.cost.toFixed(2)}`)}`;
121
+ }
122
+ if (opts.resolvedModel && opts.showResolvedModelBadge) {
123
+ line += `${theme.sep.dot}${theme.fg("dim", truncateToWidth(replaceTabs(opts.resolvedModel), 30))}`;
124
+ }
125
+ return line;
126
+ }
127
+
128
+ function formatFindingSummary(findings: FindingDetails[], theme: Theme): string {
129
+ if (findings.length === 0) return theme.fg("dim", "Findings: none");
130
+
131
+ const counts: { [P in FindingPriority]?: number } = {};
132
+ for (const finding of findings) {
133
+ counts[finding.priority] = (counts[finding.priority] ?? 0) + 1;
134
+ }
135
+
136
+ const parts: string[] = [];
137
+ for (const label of PRIORITY_LABELS) {
138
+ const { symbol, color } = getPriorityInfo(label);
139
+ const count = counts[label] ?? 0;
140
+ const text = theme.fg(color, `${label}:${count}`);
141
+ parts.push(theme.styledSymbol(symbol, color) ? `${theme.styledSymbol(symbol, color)} ${text}` : text);
142
+ }
143
+
144
+ return `${theme.fg("dim", "Findings:")} ${parts.join(theme.sep.dot)}`;
145
+ }
146
+
147
+ function normalizeFindings(value: unknown): FindingDetails[] {
148
+ if (!Array.isArray(value)) return [];
149
+ const findings: FindingDetails[] = [];
150
+ for (const item of value) {
151
+ const finding = parseFindingDetails(item);
152
+ if (finding) findings.push(finding);
153
+ }
154
+ return findings;
155
+ }
156
+
157
+ /** Reviewer output declares `findings` as an array, so a lone finding section still assembles as a list. */
158
+ const REVIEWER_ARRAY_LABELS: ReadonlySet<string> = new Set(["findings"]);
159
+
160
+ function extractIncrementalReviewResult(
161
+ items: RenderYieldItem[],
162
+ ): { summary: SubmitReviewDetails; findings: FindingDetails[] } | undefined {
163
+ const yieldItems: YieldItem[] = items.map(item => ({
164
+ data: item.data,
165
+ type: item.type,
166
+ status: item.status === "aborted" ? "aborted" : item.status === "success" ? "success" : undefined,
167
+ useLastTurn: item.useLastTurn,
168
+ }));
169
+ const assembled = assembleYieldResult(yieldItems, undefined, REVIEWER_ARRAY_LABELS);
170
+ const data = assembled?.data;
171
+ if (!data || typeof data !== "object" || Array.isArray(data)) return undefined;
172
+ const record = data as Record<string, unknown>;
173
+ const overallCorrectness = record.overall_correctness;
174
+ const explanation = record.explanation;
175
+ const confidence = record.confidence;
176
+ if (
177
+ (overallCorrectness !== "correct" && overallCorrectness !== "incorrect") ||
178
+ typeof explanation !== "string" ||
179
+ typeof confidence !== "number"
180
+ ) {
181
+ return undefined;
182
+ }
183
+ return {
184
+ summary: {
185
+ overall_correctness: overallCorrectness,
186
+ explanation,
187
+ confidence,
188
+ },
189
+ findings: normalizeFindings(record.findings),
190
+ };
191
+ }
192
+
193
+ interface RenderYieldItem {
194
+ data?: unknown;
195
+ type?: string | string[];
196
+ status?: string;
197
+ useLastTurn?: boolean;
198
+ }
199
+
200
+ /**
201
+ * Normalize the `yield` slot of `extractedToolData` into an array of
202
+ * yield-detail records. The subprocess executor always populates this slot as
203
+ * `unknown[]` (see `executor.ts` `extractData` handler), but the renderer
204
+ * MUST also tolerate a stray single object — optional chaining short-circuits
205
+ * on `null`/`undefined` only, so calling `.map` on a plain object would throw
206
+ * `TypeError: completeData?.map is not a function` and crash the TUI.
207
+ * A single object is wrapped as a 1-element array so the review verdict still
208
+ * renders; non-object primitives drop out.
209
+ */
210
+ function normalizeYieldData(value: unknown): RenderYieldItem[] {
211
+ const items = Array.isArray(value) ? value : value !== null && typeof value === "object" ? [value] : [];
212
+ const normalized: RenderYieldItem[] = [];
213
+ for (const item of items) {
214
+ if (item === null || typeof item !== "object") continue;
215
+ const record = item as Record<string, unknown>;
216
+ const typeValue = record.type;
217
+ let type: RenderYieldItem["type"];
218
+ if (typeof typeValue === "string") {
219
+ type = typeValue;
220
+ } else if (Array.isArray(typeValue)) {
221
+ const labels: string[] = [];
222
+ let allLabels = true;
223
+ for (const label of typeValue) {
224
+ if (typeof label !== "string") {
225
+ allLabels = false;
226
+ break;
227
+ }
228
+ labels.push(label);
229
+ }
230
+ if (allLabels) type = labels;
231
+ }
232
+ normalized.push({
233
+ data: record.data,
234
+ type,
235
+ status: typeof record.status === "string" ? record.status : undefined,
236
+ useLastTurn: record.useLastTurn === true ? true : undefined,
237
+ });
238
+ }
239
+ return normalized;
240
+ }
241
+
242
+ function getRenderYieldLabels(type: RenderYieldItem["type"]): string[] {
243
+ if (typeof type === "string") {
244
+ const label = type.trim();
245
+ return label ? [label] : [];
246
+ }
247
+ if (!Array.isArray(type)) return [];
248
+ const labels: string[] = [];
249
+ for (const value of type) {
250
+ const label = value.trim();
251
+ if (label) labels.push(label);
252
+ }
253
+ return labels;
254
+ }
255
+
256
+ function formatYieldPreview(item: RenderYieldItem): string {
257
+ if (item.useLastTurn === true && item.data === undefined) return "last assistant turn";
258
+ if (item.data === undefined) return "last assistant turn";
259
+ if (typeof item.data === "string") return previewLine(replaceTabs(sanitizeText(item.data)), 70);
260
+ try {
261
+ return previewLine(replaceTabs(sanitizeText(JSON.stringify(item.data) ?? "null")), 70);
262
+ } catch {
263
+ return previewLine(replaceTabs(sanitizeText(String(item.data))), 70);
264
+ }
265
+ }
266
+
267
+ function renderTypedYieldSections(value: unknown, continuePrefix: string, expanded: boolean, theme: Theme): string[] {
268
+ const typedItems: Array<{ item: RenderYieldItem; labels: string[] }> = [];
269
+ for (const item of normalizeYieldData(value)) {
270
+ const labels = getRenderYieldLabels(item.type);
271
+ if (labels.length === 0) continue;
272
+ typedItems.push({ item, labels });
273
+ }
274
+ const displayCount = expanded ? typedItems.length : 3;
275
+ const lines: string[] = [];
276
+ for (const { item, labels } of typedItems.slice(-displayCount)) {
277
+ const terminal = !Array.isArray(item.type);
278
+ const prefix = terminal ? "yield" : "yield+";
279
+ const label = `${prefix}[${labels.join(", ")}]`;
280
+ lines.push(`${continuePrefix}${theme.fg("dim", label)}: ${theme.fg("dim", formatYieldPreview(item))}`);
281
+ }
282
+ if (typedItems.length > displayCount) {
283
+ lines.push(`${continuePrefix}${theme.fg("dim", formatMoreItems(typedItems.length - displayCount, "yield"))}`);
284
+ }
285
+ return lines;
286
+ }
287
+
288
+ function formatJsonScalar(value: unknown, _theme: Theme): string {
289
+ if (value === null) return "null";
290
+ if (typeof value === "string") {
291
+ const trimmed = truncateToWidth(sanitizeText(value), 70);
292
+ return `"${trimmed}"`;
293
+ }
294
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
295
+ return "";
296
+ }
297
+
298
+ export function formatTaskId(id: string): string {
299
+ // Ids are name-based (e.g. "Anna", "Anna-2"); a "." separates nesting levels
300
+ // (e.g. "Anna.Bob"). Render the hierarchy with a ">" breadcrumb.
301
+ const sanitizedId = sanitizeText(id);
302
+ const segments = sanitizedId.split(".");
303
+ return segments.length < 2 ? sanitizedId : segments.join(">");
304
+ }
305
+
306
+ const MISSING_YIELD_WARNING_PREFIX = "SYSTEM WARNING: Subagent exited without calling yield tool";
307
+
308
+ function extractMissingYieldWarning(output: string): { warning?: string; rest: string } {
309
+ const lines = output.split("\n");
310
+ const firstLine = lines[0]?.trim() ?? "";
311
+ if (!firstLine.startsWith(MISSING_YIELD_WARNING_PREFIX)) {
312
+ return { rest: output };
313
+ }
314
+ const rest = lines
315
+ .slice(1)
316
+ .join("\n")
317
+ .replace(/^\s*\n+/, "");
318
+ return { warning: firstLine, rest };
319
+ }
320
+
321
+ function buildTreePrefix(ancestors: boolean[], theme: Theme): string {
322
+ return ancestors.map(hasNext => (hasNext ? `${theme.tree.vertical} ` : " ")).join("");
323
+ }
324
+
325
+ function renderJsonTreeLines(
326
+ value: unknown,
327
+ theme: Theme,
328
+ maxDepth: number,
329
+ maxLines: number,
330
+ ): { lines: string[]; truncated: boolean } {
331
+ const lines: string[] = [];
332
+ let truncated = false;
333
+
334
+ const iconObject = theme.styledSymbol("icon.folder", "muted");
335
+ const iconArray = theme.styledSymbol("icon.package", "muted");
336
+ const iconScalar = theme.styledSymbol("icon.file", "muted");
337
+
338
+ const pushLine = (line: string) => {
339
+ if (lines.length >= maxLines) {
340
+ truncated = true;
341
+ return false;
342
+ }
343
+ lines.push(line);
344
+ return true;
345
+ };
346
+
347
+ const renderNode = (val: unknown, key: string | undefined, ancestors: boolean[], isLast: boolean, depth: number) => {
348
+ if (lines.length >= maxLines) {
349
+ truncated = true;
350
+ return;
351
+ }
352
+
353
+ const connector = isLast ? theme.tree.last : theme.tree.branch;
354
+ const prefix = `${buildTreePrefix(ancestors, theme)}${theme.fg("dim", connector)} `;
355
+ const scalar = formatJsonScalar(val, theme);
356
+
357
+ if (scalar) {
358
+ const label = key ? theme.fg("muted", sanitizeText(key)) : theme.fg("muted", "value");
359
+ pushLine(`${prefix}${iconScalar} ${label}: ${theme.fg("dim", scalar)}`);
360
+ return;
361
+ }
362
+
363
+ if (Array.isArray(val)) {
364
+ const header = key ? theme.fg("muted", sanitizeText(key)) : theme.fg("muted", "array");
365
+ pushLine(`${prefix}${iconArray} ${header}`);
366
+ if (val.length === 0) {
367
+ pushLine(
368
+ `${buildTreePrefix([...ancestors, !isLast], theme)}${theme.fg("dim", theme.tree.last)} ${theme.fg(
369
+ "dim",
370
+ "[]",
371
+ )}`,
372
+ );
373
+ return;
374
+ }
375
+ if (depth >= maxDepth) {
376
+ pushLine(
377
+ `${buildTreePrefix([...ancestors, !isLast], theme)}${theme.fg("dim", theme.tree.last)} ${theme.fg(
378
+ "dim",
379
+ "…",
380
+ )}`,
381
+ );
382
+ return;
383
+ }
384
+ const nextAncestors = [...ancestors, !isLast];
385
+ for (let i = 0; i < val.length; i++) {
386
+ renderNode(val[i], `[${i}]`, nextAncestors, i === val.length - 1, depth + 1);
387
+ if (lines.length >= maxLines) {
388
+ truncated = true;
389
+ return;
390
+ }
391
+ }
392
+ return;
393
+ }
394
+
395
+ if (val && typeof val === "object") {
396
+ const header = key ? theme.fg("muted", sanitizeText(key)) : theme.fg("muted", "object");
397
+ pushLine(`${prefix}${iconObject} ${header}`);
398
+ const entries = Object.entries(val as Record<string, unknown>);
399
+ if (entries.length === 0) {
400
+ pushLine(
401
+ `${buildTreePrefix([...ancestors, !isLast], theme)}${theme.fg("dim", theme.tree.last)} ${theme.fg(
402
+ "dim",
403
+ "{}",
404
+ )}`,
405
+ );
406
+ return;
407
+ }
408
+ if (depth >= maxDepth) {
409
+ pushLine(
410
+ `${buildTreePrefix([...ancestors, !isLast], theme)}${theme.fg("dim", theme.tree.last)} ${theme.fg(
411
+ "dim",
412
+ "…",
413
+ )}`,
414
+ );
415
+ return;
416
+ }
417
+ const nextAncestors = [...ancestors, !isLast];
418
+ for (let i = 0; i < entries.length; i++) {
419
+ const [childKey, child] = entries[i];
420
+ renderNode(child, childKey, nextAncestors, i === entries.length - 1, depth + 1);
421
+ if (lines.length >= maxLines) {
422
+ truncated = true;
423
+ return;
424
+ }
425
+ }
426
+ return;
427
+ }
428
+
429
+ const label = key ? theme.fg("muted", sanitizeText(key)) : theme.fg("muted", "value");
430
+ pushLine(`${prefix}${iconScalar} ${label}: ${theme.fg("dim", sanitizeText(String(val)))}`);
431
+ };
432
+
433
+ const renderRoot = (val: unknown) => {
434
+ if (Array.isArray(val)) {
435
+ for (let i = 0; i < val.length; i++) {
436
+ renderNode(val[i], `[${i}]`, [], i === val.length - 1, 1);
437
+ if (lines.length >= maxLines) {
438
+ truncated = true;
439
+ return;
440
+ }
441
+ }
442
+ return;
443
+ }
444
+ if (val && typeof val === "object") {
445
+ const entries = Object.entries(val as Record<string, unknown>);
446
+ for (let i = 0; i < entries.length; i++) {
447
+ const [childKey, child] = entries[i];
448
+ renderNode(child, childKey, [], i === entries.length - 1, 1);
449
+ if (lines.length >= maxLines) {
450
+ truncated = true;
451
+ return;
452
+ }
453
+ }
454
+ return;
455
+ }
456
+ renderNode(val, undefined, [], true, 0);
457
+ };
458
+
459
+ renderRoot(value);
460
+
461
+ return { lines, truncated };
462
+ }
463
+
464
+ const BASH_WALL_TIME_NOTICE_RE = /^Wall time: \d+(?:\.\d+)? seconds$/u;
465
+ const BASH_EXIT_CODE_NOTICE_RE = /^Command exited with code -?\d+$/u;
466
+
467
+ function stripRecentOutputNoticeLine(text: string): string {
468
+ const trimmed = text.trimEnd();
469
+ const lineStart = trimmed.lastIndexOf("\n");
470
+ const candidateStart = lineStart === -1 ? 0 : lineStart + 1;
471
+ const line = trimmed.slice(candidateStart);
472
+ if (!BASH_WALL_TIME_NOTICE_RE.test(line) && !BASH_EXIT_CODE_NOTICE_RE.test(line)) return text;
473
+ return trimmed.slice(0, lineStart === -1 ? 0 : lineStart).trimEnd();
474
+ }
475
+
476
+ function sanitizeRecentOutput(output: string): string {
477
+ let text = sanitizeText(output).trimEnd();
478
+ while (text) {
479
+ const withoutArtifactNotice = stripRawOutputArtifactNotice(text).text;
480
+ if (withoutArtifactNotice !== text) {
481
+ text = withoutArtifactNotice;
482
+ continue;
483
+ }
484
+ const withoutOutputNotice = stripGeneratedOutputNotice(text);
485
+ if (withoutOutputNotice !== text) {
486
+ text = withoutOutputNotice;
487
+ continue;
488
+ }
489
+ const withoutRuntimeNotice = stripRecentOutputNoticeLine(text);
490
+ if (withoutRuntimeNotice !== text) {
491
+ text = withoutRuntimeNotice;
492
+ continue;
493
+ }
494
+ break;
495
+ }
496
+ return text;
497
+ }
498
+
499
+ function renderOutputSection(
500
+ output: string,
501
+ continuePrefix: string,
502
+ expanded: boolean,
503
+ theme: Theme,
504
+ maxCollapsed = 3,
505
+ maxExpanded = 10,
506
+ warning?: string,
507
+ ): string[] {
508
+ const lines: string[] = [];
509
+ const sanitizedOutput = sanitizeText(output);
510
+ const trimmedOutput = sanitizedOutput.trimEnd();
511
+ if (!trimmedOutput && !warning) return lines;
512
+
513
+ if (warning) {
514
+ lines.push(`${continuePrefix}${theme.fg("dim", "Output")}`);
515
+ lines.push(
516
+ `${continuePrefix} ${theme.fg("warning", theme.status.warning)} ${theme.fg(
517
+ "dim",
518
+ truncateToWidth(sanitizeText(warning), 80),
519
+ )}`,
520
+ );
521
+
522
+ if (!trimmedOutput) {
523
+ return lines;
524
+ }
525
+
526
+ if (trimmedOutput.startsWith("{") || trimmedOutput.startsWith("[")) {
527
+ try {
528
+ const parsed = JSON.parse(trimmedOutput);
529
+
530
+ if (!expanded) {
531
+ lines.push(`${continuePrefix} ${theme.fg("dim", formatOutputInline(parsed, theme))}`);
532
+ return lines;
533
+ }
534
+
535
+ const tree = renderJsonTreeLines(parsed, theme, expanded ? 6 : 2, expanded ? 24 : 6);
536
+ if (tree.lines.length > 0) {
537
+ for (const line of tree.lines) {
538
+ lines.push(`${continuePrefix} ${line}`);
539
+ }
540
+ if (tree.truncated) {
541
+ lines.push(`${continuePrefix} ${theme.fg("dim", "…")}`);
542
+ }
543
+ return lines;
544
+ }
545
+ } catch {
546
+ // Fall back to raw output
547
+ }
548
+ }
549
+
550
+ const outputLines = trimmedOutput.split("\n");
551
+ const previewCount = expanded ? maxExpanded : maxCollapsed;
552
+ for (const line of outputLines.slice(0, previewCount)) {
553
+ lines.push(`${continuePrefix} ${theme.fg("dim", truncateToWidth(replaceTabs(line), 70))}`);
554
+ }
555
+
556
+ if (outputLines.length > previewCount) {
557
+ lines.push(
558
+ `${continuePrefix} ${theme.fg("dim", formatMoreItems(outputLines.length - previewCount, "line"))}`,
559
+ );
560
+ }
561
+
562
+ return lines;
563
+ }
564
+
565
+ if (trimmedOutput.startsWith("{") || trimmedOutput.startsWith("[")) {
566
+ try {
567
+ const parsed = JSON.parse(trimmedOutput);
568
+
569
+ // Collapsed: inline format like Args
570
+ if (!expanded) {
571
+ lines.push(`${continuePrefix}${theme.fg("dim", formatOutputInline(parsed, theme))}`);
572
+ return lines;
573
+ }
574
+
575
+ // Expanded: tree format
576
+ lines.push(`${continuePrefix}${theme.fg("dim", "Output")}`);
577
+ const tree = renderJsonTreeLines(parsed, theme, expanded ? 6 : 2, expanded ? 24 : 6);
578
+ if (tree.lines.length > 0) {
579
+ for (const line of tree.lines) {
580
+ lines.push(`${continuePrefix} ${line}`);
581
+ }
582
+ if (tree.truncated) {
583
+ lines.push(`${continuePrefix} ${theme.fg("dim", "…")}`);
584
+ }
585
+ return lines;
586
+ }
587
+ } catch {
588
+ // Fall back to raw output
589
+ }
590
+ }
591
+
592
+ lines.push(`${continuePrefix}${theme.fg("dim", "Output")}`);
593
+
594
+ const outputLines = trimmedOutput.split("\n");
595
+ const previewCount = expanded ? maxExpanded : maxCollapsed;
596
+ for (const line of outputLines.slice(0, previewCount)) {
597
+ lines.push(`${continuePrefix} ${theme.fg("dim", truncateToWidth(replaceTabs(line), 70))}`);
598
+ }
599
+
600
+ if (outputLines.length > previewCount) {
601
+ lines.push(`${continuePrefix} ${theme.fg("dim", formatMoreItems(outputLines.length - previewCount, "line"))}`);
602
+ }
603
+
604
+ return lines;
605
+ }
606
+
607
+ function renderTaskSection(
608
+ task: string,
609
+ continuePrefix: string,
610
+ expanded: boolean,
611
+ theme: Theme,
612
+ maxExpanded = 20,
613
+ ): string[] {
614
+ const lines: string[] = [];
615
+ const trimmed = sanitizeText(task).trim();
616
+ if (!expanded || !trimmed) return lines;
617
+
618
+ lines.push(`${continuePrefix}${theme.fg("dim", "Task")}`);
619
+ const taskLines = trimmed.split("\n");
620
+ for (const line of taskLines.slice(0, maxExpanded)) {
621
+ lines.push(`${continuePrefix} ${theme.fg("dim", truncateToWidth(replaceTabs(line), 70))}`);
622
+ }
623
+ if (taskLines.length > maxExpanded) {
624
+ lines.push(`${continuePrefix} ${theme.fg("dim", formatMoreItems(taskLines.length - maxExpanded, "line"))}`);
625
+ }
626
+
627
+ return lines;
628
+ }
629
+
630
+ function formatScalarInline(value: unknown, maxLen: number, _theme: Theme): string {
631
+ if (value === null) return "null";
632
+ if (value === undefined) return "undefined";
633
+ if (typeof value === "boolean") return String(value);
634
+ if (typeof value === "number") return String(value);
635
+ if (typeof value === "string") {
636
+ const sanitizedValue = sanitizeText(value);
637
+ const firstLine = sanitizedValue.split("\n")[0].trim();
638
+ if (firstLine.length === 0) return `"" (${sanitizedValue.split("\n").length} lines)`;
639
+ const preview = truncateToWidth(firstLine, maxLen);
640
+ if (sanitizedValue.includes("\n")) return `"${preview}…" (${sanitizedValue.split("\n").length} lines)`;
641
+ return `"${preview}"`;
642
+ }
643
+ if (Array.isArray(value)) return `[${value.length} items]`;
644
+ if (typeof value === "object") {
645
+ const keys = Object.keys(value);
646
+ return `{${keys.length} keys}`;
647
+ }
648
+ return sanitizeText(String(value));
649
+ }
650
+
651
+ function formatOutputInline(data: unknown, theme: Theme, maxWidth = 80): string {
652
+ if (data === null || data === undefined) return "Output: none";
653
+
654
+ // For scalars, show directly
655
+ if (typeof data !== "object") {
656
+ return `Output: ${formatScalarInline(data, 60, theme)}`;
657
+ }
658
+
659
+ // For arrays, show count and first element preview
660
+ if (Array.isArray(data)) {
661
+ if (data.length === 0) return "Output: []";
662
+ const preview = formatScalarInline(data[0], 40, theme);
663
+ return `Output: [${data.length} items] ${preview}${data.length > 1 ? "…" : ""}`;
664
+ }
665
+
666
+ // For objects, show key=value pairs inline
667
+ const entries = Object.entries(data as Record<string, unknown>);
668
+ if (entries.length === 0) return "Output: {}";
669
+
670
+ const pairs: string[] = [];
671
+ let totalLen = "Output: ".length;
672
+
673
+ for (const [key, value] of entries) {
674
+ const valueStr = formatScalarInline(value, 24, theme);
675
+ const pairStr = `${sanitizeText(key)}=${valueStr}`;
676
+ const addLen = pairs.length > 0 ? pairStr.length + 2 : pairStr.length; // +2 for ", "
677
+
678
+ if (totalLen + addLen > maxWidth && pairs.length > 0) {
679
+ pairs.push("…");
680
+ break;
681
+ }
682
+
683
+ pairs.push(pairStr);
684
+ totalLen += addLen;
685
+ }
686
+
687
+ return `Output: ${pairs.join(", ")}`;
688
+ }
689
+
690
+ /**
691
+ * First line of a streamed `task` brief, trimmed — a row's secondary text.
692
+ * The args stream in token by token, so non-string values fall through to "".
693
+ */
694
+ function taskFirstLine(task: unknown): string {
695
+ if (typeof task !== "string") return "";
696
+ const trimmed = sanitizeText(task).trim();
697
+ const newline = trimmed.indexOf("\n");
698
+ return newline === -1 ? trimmed : trimmed.slice(0, newline);
699
+ }
700
+
701
+ /**
702
+ * Header label for a task call while nothing has spawned yet: the flat form's
703
+ * `agent` type. Batch calls return undefined — each item row carries its own
704
+ * `⟨agent⟩` badge, so a joined list in the header would just repeat them.
705
+ */
706
+ function formatAgentHeaderLabel(args: Partial<TaskParams> | undefined): string | undefined {
707
+ if (!args) return undefined;
708
+ const flat = typeof args.agent === "string" ? args.agent.trim() : "";
709
+ return flat || undefined;
710
+ }
711
+
712
+ /** Dim `⟨agent⟩` badge for a non-default agent type; empty for the generic worker. */
713
+ function agentTypeBadge(agent: string | undefined, theme: Theme): string {
714
+ const trimmed = agent?.trim();
715
+ if (!trimmed || trimmed === "task") return "";
716
+ return ` ${theme.fg("dim", `${theme.format.bracketLeft}${trimmed}${theme.format.bracketRight}`)}`;
717
+ }
718
+
719
+ /**
720
+ * Render the call preview lines for the single spawned agent. The
721
+ * args stream in token by token, so every field access is defensive.
722
+ */
723
+ function renderTaskCallLines(args: Partial<TaskParams> | undefined, theme: Theme): string[] {
724
+ if (!args) return [];
725
+ const bullet = theme.fg("dim", "•");
726
+ const lines: string[] = [];
727
+
728
+ const rawName = typeof args.name === "string" ? args.name.trim() : "";
729
+ const idLabel = rawName ? formatTaskId(rawName) : "";
730
+ const brief = taskFirstLine(args.task);
731
+ if (idLabel || brief) {
732
+ let line = `${bullet} ${theme.fg("accent", theme.bold(idLabel || "agent"))}`;
733
+ if (brief) {
734
+ line += `: ${theme.fg("muted", previewLine(brief, 64))}`;
735
+ }
736
+ line += agentTypeBadge(args.agent, theme);
737
+ lines.push(line);
738
+ }
739
+ lines.push(...renderTaskItemLines(args.tasks, theme));
740
+ return lines;
741
+ }
742
+
743
+ /**
744
+ * Agent rows shown per collapsed task list; the rest fold into a single
745
+ * `… N more agents` summary line (expand uncaps).
746
+ */
747
+ const COLLAPSED_AGENT_LIMIT = 4;
748
+
749
+ /**
750
+ * Render the per-item list (`name` + `task` brief) for a batch call's
751
+ * streaming preview. The args stream in token by token, so the array grows
752
+ * over time and trailing entries may be partially parsed — every field access
753
+ * is defensive.
754
+ */
755
+ function renderTaskItemLines(tasks: TaskItem[] | undefined, theme: Theme): string[] {
756
+ if (!Array.isArray(tasks) || tasks.length === 0) return [];
757
+
758
+ const bullet = theme.fg("dim", "•");
759
+ const cap = Math.min(tasks.length, COLLAPSED_AGENT_LIMIT);
760
+ const lines: string[] = [];
761
+ for (let i = 0; i < cap; i++) {
762
+ const item = tasks[i] as Partial<TaskItem> | undefined;
763
+ const rawName = typeof item?.name === "string" ? item.name.trim() : "";
764
+ const idLabel = rawName ? formatTaskId(rawName) : `#${i + 1}`;
765
+ let line = `${bullet} ${theme.fg("accent", theme.bold(idLabel))}`;
766
+ const brief = taskFirstLine(item?.task);
767
+ if (brief) {
768
+ line += `: ${theme.fg("muted", previewLine(brief, 64))}`;
769
+ }
770
+ line += agentTypeBadge(item?.agent, theme);
771
+ if (item?.isolated === true) {
772
+ line += theme.fg("dim", " [isolated]");
773
+ }
774
+ lines.push(line);
775
+ }
776
+ if (cap < tasks.length) {
777
+ lines.push(`${bullet} ${theme.fg("dim", formatMoreItems(tasks.length - cap, "agent"))}`);
778
+ }
779
+ return lines;
780
+ }
781
+
782
+ /** One renderable frame section: optional label, body rows, leading divider. */
783
+ type TaskRenderSection = { label?: string; lines: readonly string[]; separator?: boolean };
784
+ type AssignmentSectionRenderer = (width: number) => TaskRenderSection;
785
+
786
+ // Default output-block layout is: left border + one-cell content inset + right
787
+ // border. Render markdown at that inner width so the output block does not need
788
+ // to rewrap already-rendered assignment lines.
789
+ const ASSIGNMENT_FRAME_INSET = 3;
790
+
791
+ /**
792
+ * Build the assignment section (the markdown brief handed to the subagent).
793
+ * Rendered in both the streaming call preview and the result frame so the
794
+ * brief stays visible for the whole task lifecycle — not just until the first
795
+ * progress snapshot replaces the call view.
796
+ */
797
+ function createAssignmentSectionRenderer(
798
+ args: Partial<TaskParams> | undefined,
799
+ theme: Theme,
800
+ ): AssignmentSectionRenderer | undefined {
801
+ // `renderResult` receives the raw tool args (unlike `renderCall`, which is
802
+ // fed through `repairTaskParams`), so undo any per-field double-encoding
803
+ // here too. The repair is idempotent on already-clean text.
804
+ const assignment = sanitizeText(
805
+ repairDoubleEncodedJsonString(typeof args?.task === "string" ? args.task : ""),
806
+ ).trim();
807
+ if (!assignment) return undefined;
808
+ return createMarkdownSectionRenderer(assignment, theme);
809
+ }
810
+
811
+ /**
812
+ * Build the shared-context section (the `# Goal / # Constraints` background a
813
+ * batch call hands every subagent). Rendered like the assignment brief so the
814
+ * shared background stays visible for the whole task lifecycle.
815
+ */
816
+ function createContextSectionRenderer(
817
+ args: Partial<TaskParams> | undefined,
818
+ theme: Theme,
819
+ ): AssignmentSectionRenderer | undefined {
820
+ const context = sanitizeText(
821
+ repairDoubleEncodedJsonString(typeof args?.context === "string" ? args.context : ""),
822
+ ).trim();
823
+ if (!context) return undefined;
824
+ return createMarkdownSectionRenderer(context, theme);
825
+ }
826
+
827
+ function createMarkdownSectionRenderer(text: string, theme: Theme): AssignmentSectionRenderer {
828
+ const markdown = new Markdown(text, 0, 0, getMarkdownTheme(), {
829
+ color: line => theme.fg("muted", line),
830
+ });
831
+ return width => ({ lines: markdown.render(Math.max(1, width - ASSIGNMENT_FRAME_INSET)) });
832
+ }
833
+
834
+ /**
835
+ * Render the tool call arguments.
836
+ */
837
+ export function renderCall(args: TaskParams, options: TaskRenderOptions, theme: Theme): Component {
838
+ const showIsolated = "isolated" in args && args.isolated === true;
839
+ // Dispatch glyph from the first frame: spawning is non-blocking, so a
840
+ // pending/hourglass icon would misread the call as something the turn
841
+ // waits on.
842
+ const header = renderStatusLine(
843
+ {
844
+ iconOverride: theme.styledSymbol("tool.task", "accent"),
845
+ title: "Task",
846
+ description: formatAgentHeaderLabel(args),
847
+ },
848
+ theme,
849
+ );
850
+ const assignmentSection = createAssignmentSectionRenderer(args, theme);
851
+ const contextSection = createContextSectionRenderer(args, theme);
852
+ return framedBlock(theme, width => {
853
+ const sections: Array<{ label?: string; lines: readonly string[]; separator?: boolean }> = [];
854
+
855
+ // The call preview only exists to surface the dispatched agent while the
856
+ // args stream in. Once a result snapshot exists, `renderResult` draws the
857
+ // same agent (and the assignment brief) itself, so showing it here would
858
+ // repeat what the result frame already shows.
859
+ if (!options.renderContext?.hasResult) {
860
+ // Mirror renderResult's layout — context, assignment, then the
861
+ // per-agent list — so the agent rows do not jump from above the
862
+ // brief to below it when the first progress snapshot replaces the
863
+ // call view. This also matches the schema's field order (`context`
864
+ // streams before `tasks`), so the streaming preview grows
865
+ // append-only instead of inserting agent rows above the
866
+ // already-rendered markdown and pushing it down on every item.
867
+ if (contextSection) sections.push(contextSection(width));
868
+ if (assignmentSection) sections.push(assignmentSection(width));
869
+ const callLines = renderTaskCallLines(args, theme);
870
+ // Guarded: an empty trailing section would still draw its divider.
871
+ if (callLines.length > 0) sections.push({ separator: true, lines: callLines });
872
+ }
873
+
874
+ return {
875
+ header,
876
+ headerMeta: showIsolated ? "isolated" : undefined,
877
+ sections,
878
+ state: "pending",
879
+ borderColor: "borderMuted",
880
+ width,
881
+ };
882
+ });
883
+ }
884
+
885
+ /**
886
+ * Render streaming progress for a single agent.
887
+ */
888
+ function renderAgentProgress(
889
+ progress: AgentProgress,
890
+ prefix: string,
891
+ continuePrefix: string,
892
+ expanded: boolean,
893
+ theme: Theme,
894
+ spinnerFrame?: number,
895
+ frozen = false,
896
+ seenNestedTasks?: WeakSet<object>,
897
+ nestedDepth = 0,
898
+ nowMs = Date.now(),
899
+ ): string[] {
900
+ const lines: string[] = [];
901
+
902
+ const icon = getStatusIcon(progress.status, theme, spinnerFrame);
903
+ const iconColor =
904
+ progress.status === "completed"
905
+ ? "success"
906
+ : progress.status === "failed" || progress.status === "aborted"
907
+ ? "error"
908
+ : "accent";
909
+
910
+ // Main status line: id: description [status] · stats · ⟨agent⟩
911
+ const trimmedDescription = progress.description?.trim();
912
+ const description = trimmedDescription ? previewLine(sanitizeText(trimmedDescription), 64) : undefined;
913
+ const displayId = formatTaskId(progress.id);
914
+ const titlePart = description ? `${theme.bold(displayId)}: ${description}` : displayId;
915
+ const indent = prefix ? `${prefix} ` : "";
916
+ let statusLine: string;
917
+ if (progress.status === "running" || progress.status === "pending") {
918
+ // Live (or queued) agents use the same dot finished rows keep: detached
919
+ // async spawns can stay "pending" while real work is running, so a
920
+ // pending/hourglass or spinner glyph reads wrong in the transcript. Keep
921
+ // the row static; the Task tool header already carries the dispatch icon.
922
+ const dot = theme.styledSymbol("status.done", frozen ? "dim" : "accent");
923
+ const nameColor = frozen ? "dim" : "accent";
924
+ const name = theme.fg(nameColor, description ? theme.bold(displayId) : displayId);
925
+ statusLine = `${indent}${dot} ${name}`;
926
+ if (description) {
927
+ statusLine += `${theme.fg(nameColor, ":")} ${theme.fg(nameColor, description)}`;
928
+ }
929
+ } else if (progress.status === "completed") {
930
+ // Finished rows keep the dot but settle from accent to the plain
931
+ // foreground: completion reads as a color change, not a new glyph.
932
+ statusLine = `${indent}${theme.styledSymbol("status.done", "text")} ${theme.fg("text", titlePart)}`;
933
+ } else {
934
+ statusLine = `${indent}${theme.fg(iconColor, icon)} ${theme.fg("accent", titlePart)}`;
935
+ }
936
+ statusLine += agentTypeBadge(progress.agent, theme);
937
+
938
+ // Show retry-blocked badge so the parent immediately sees that a child
939
+ // is sleeping on a provider 429, not silently progressing. Wins over the
940
+ // generic running marker because "we're waiting on a quota window" is
941
+ // the operationally meaningful state.
942
+ if (progress.retryState && progress.status === "running") {
943
+ statusLine += ` ${formatBadge("retrying", "warning", theme)}`;
944
+ } else if (progress.retryFailure && (progress.status === "failed" || progress.status === "aborted")) {
945
+ statusLine += ` ${formatBadge("rate-limited", "error", theme)}`;
946
+ } else if (progress.status === "failed" || progress.status === "aborted") {
947
+ const statusLabel = progress.status === "failed" ? "failed" : "aborted";
948
+ statusLine += ` ${formatBadge(statusLabel, iconColor, theme)}`;
949
+ }
950
+
951
+ const showBadge = settings.get("task.showResolvedModelBadge");
952
+ if (progress.status === "running") {
953
+ if (!description) {
954
+ const taskPreview = previewLine(sanitizeText(progress.assignment ?? progress.task), 40);
955
+ statusLine += ` ${theme.fg("muted", taskPreview)}`;
956
+ }
957
+ statusLine = appendAgentStats(statusLine, { ...progress, showResolvedModelBadge: showBadge }, theme);
958
+ } else if (progress.status === "completed") {
959
+ statusLine = appendAgentStats(statusLine, { ...progress, showResolvedModelBadge: showBadge }, theme);
960
+ }
961
+
962
+ lines.push(statusLine);
963
+
964
+ lines.push(...renderTaskSection(progress.assignment ?? progress.task, continuePrefix, expanded, theme));
965
+
966
+ // Current tool (if running) or most recent completed tool
967
+ if (progress.status === "running") {
968
+ if (progress.currentTool) {
969
+ let toolLine = `${continuePrefix}${theme.tree.hook} ${theme.fg("muted", sanitizeText(progress.currentTool))}`;
970
+ const toolDetail = progress.lastIntent ?? progress.currentToolArgs;
971
+ if (toolDetail) {
972
+ toolLine += `: ${theme.fg("dim", previewLine(sanitizeText(toolDetail), 40))}`;
973
+ }
974
+ if (progress.currentToolStartMs) {
975
+ const elapsed = nowMs - progress.currentToolStartMs;
976
+ if (elapsed > 5000) {
977
+ toolLine += `${theme.sep.dot}${theme.fg("warning", formatDuration(elapsed))}`;
978
+ }
979
+ }
980
+ lines.push(toolLine);
981
+ } else if (progress.recentTools.length > 0) {
982
+ // Show most recent completed tool when idle between tools
983
+ const recent = progress.recentTools[0];
984
+ let toolLine = `${continuePrefix}${theme.tree.hook} ${theme.fg("dim", sanitizeText(recent.tool))}`;
985
+ const toolDetail = progress.lastIntent ?? recent.args;
986
+ if (toolDetail) {
987
+ toolLine += `: ${theme.fg("dim", previewLine(sanitizeText(toolDetail), 40))}`;
988
+ }
989
+ lines.push(toolLine);
990
+ }
991
+ }
992
+
993
+ // Retry detail line: surface why the subagent is paused and roughly how
994
+ // long until the next attempt. Without this, the parent UI would just
995
+ // keep spinning while a child sleeps on a 3-hour provider rate-limit.
996
+ if (progress.retryState && progress.status === "running") {
997
+ const remainingMs = Math.max(0, progress.retryState.startedAtMs + progress.retryState.delayMs - nowMs);
998
+ const waitLabel = remainingMs > 0 ? `in ${formatDuration(remainingMs)}` : "now";
999
+ const summary =
1000
+ `retrying ${progress.retryState.attempt}/${progress.retryState.maxAttempts} ${waitLabel}: ` +
1001
+ previewLine(sanitizeText(progress.retryState.errorMessage), 60);
1002
+ lines.push(`${continuePrefix}${theme.tree.hook} ${theme.fg("warning", summary)}`);
1003
+ } else if (progress.retryFailure && progress.status !== "running") {
1004
+ const summary = `auto-retry gave up after ${progress.retryFailure.attempt} attempt${
1005
+ progress.retryFailure.attempt === 1 ? "" : "s"
1006
+ }: ${previewLine(sanitizeText(progress.retryFailure.errorMessage), 80)}`;
1007
+ lines.push(`${continuePrefix}${theme.tree.hook} ${theme.fg("error", summary)}`);
1008
+ }
1009
+
1010
+ // Render extracted tool data inline (e.g., review findings)
1011
+ if (progress.extractedToolData) {
1012
+ // For completed tasks, render review verdicts assembled from incremental
1013
+ // yield sections.
1014
+ if (progress.status === "completed") {
1015
+ const completeData = normalizeYieldData(progress.extractedToolData.yield);
1016
+ const incrementalReview = extractIncrementalReviewResult(completeData);
1017
+ if (incrementalReview) {
1018
+ lines.push(
1019
+ ...renderReviewResult(
1020
+ incrementalReview.summary,
1021
+ incrementalReview.findings,
1022
+ continuePrefix,
1023
+ expanded,
1024
+ theme,
1025
+ ),
1026
+ );
1027
+ return lines; // Review result handles its own rendering
1028
+ }
1029
+ const reviewData = completeData
1030
+ .map(c => c.data as SubmitReviewDetails)
1031
+ .filter(d => d && typeof d === "object" && "overall_correctness" in d);
1032
+ if (reviewData.length > 0) {
1033
+ const summary = reviewData[reviewData.length - 1];
1034
+ const findings: FindingDetails[] = [];
1035
+ lines.push(...renderReviewResult(summary, findings, continuePrefix, expanded, theme));
1036
+ return lines; // Review result handles its own rendering
1037
+ }
1038
+ }
1039
+
1040
+ for (const toolName in progress.extractedToolData) {
1041
+ const dataArray = progress.extractedToolData[toolName];
1042
+ if (toolName === "yield") {
1043
+ lines.push(...renderTypedYieldSections(dataArray, continuePrefix, expanded, theme));
1044
+ continue;
1045
+ }
1046
+
1047
+ // Nested `task` data has its own dedicated tree renderer below that
1048
+ // also merges in the in-flight snapshot — skip the generic inline
1049
+ // path so we don't render twice.
1050
+ if (toolName === "task") continue;
1051
+
1052
+ const handler = subprocessToolRegistry.getHandler(toolName);
1053
+ if (handler?.renderInline) {
1054
+ const displayCount = expanded ? (dataArray as unknown[]).length : 3;
1055
+ const recentData = (dataArray as unknown[]).slice(-displayCount);
1056
+ for (const data of recentData) {
1057
+ const component = handler.renderInline(data, theme);
1058
+ if (component instanceof Text) {
1059
+ lines.push(`${continuePrefix}${component.getText()}`);
1060
+ }
1061
+ }
1062
+ if ((dataArray as unknown[]).length > displayCount) {
1063
+ lines.push(
1064
+ `${continuePrefix}${theme.fg(
1065
+ "dim",
1066
+ formatMoreItems((dataArray as unknown[]).length - displayCount, "item"),
1067
+ )}`,
1068
+ );
1069
+ }
1070
+ }
1071
+ }
1072
+ }
1073
+
1074
+ // Nested `task` tree: completed sub-calls from `extractedToolData.task` plus
1075
+ // the in-flight snapshot (if any). Surfacing this in the live view means
1076
+ // the user sees deep-tree progress without waiting for this agent to finish
1077
+ // its own turn.
1078
+ const completedTaskCalls = (progress.extractedToolData?.task as TaskToolDetails[] | undefined) ?? [];
1079
+ const inflight = progress.inflightTaskDetails;
1080
+ if (completedTaskCalls.length > 0 || inflight) {
1081
+ const snapshots = inflight ? [...completedTaskCalls, inflight] : completedTaskCalls;
1082
+ const nestedLines = renderNestedTaskTree(
1083
+ snapshots,
1084
+ expanded,
1085
+ theme,
1086
+ spinnerFrame,
1087
+ frozen,
1088
+ seenNestedTasks,
1089
+ nestedDepth,
1090
+ nowMs,
1091
+ );
1092
+ for (const line of nestedLines) {
1093
+ lines.push(`${continuePrefix}${line}`);
1094
+ }
1095
+ }
1096
+
1097
+ // Expanded view: recent output and tools
1098
+ if (expanded && progress.status === "running") {
1099
+ const previewRows = previewWindowRows();
1100
+ const output = capPreviewLines(
1101
+ sanitizeRecentOutput([...progress.recentOutput].reverse().join("\n")).split("\n"),
1102
+ theme,
1103
+ {
1104
+ max: previewRows,
1105
+ expandHint: false,
1106
+ },
1107
+ ).join("\n");
1108
+ lines.push(...renderOutputSection(output, continuePrefix, expanded, theme, 2, previewRows));
1109
+ }
1110
+
1111
+ return lines;
1112
+ }
1113
+
1114
+ /**
1115
+ * Render review result with combined verdict + findings in tree structure.
1116
+ */
1117
+ function renderReviewResult(
1118
+ summary: SubmitReviewDetails,
1119
+ findings: FindingDetails[],
1120
+ continuePrefix: string,
1121
+ expanded: boolean,
1122
+ theme: Theme,
1123
+ ): string[] {
1124
+ const lines: string[] = [];
1125
+
1126
+ // Verdict line
1127
+ const verdictColor = summary.overall_correctness === "correct" ? "success" : "error";
1128
+ const isCorrect = summary.overall_correctness === "correct";
1129
+ const verdictIcon = isCorrect
1130
+ ? theme.styledSymbol("status.done", "accent")
1131
+ : theme.fg(verdictColor, theme.status.error);
1132
+ lines.push(
1133
+ `${continuePrefix} Patch is ${theme.fg(verdictColor, summary.overall_correctness)} ${verdictIcon} ${theme.fg(
1134
+ "dim",
1135
+ `(${(summary.confidence * 100).toFixed(0)}% confidence)`,
1136
+ )}`,
1137
+ );
1138
+
1139
+ // Explanation preview (first ~80 chars when collapsed, full when expanded)
1140
+ if (summary.explanation) {
1141
+ if (expanded) {
1142
+ lines.push(`${continuePrefix}${theme.fg("dim", "Summary")}`);
1143
+ const explanationLines = sanitizeText(summary.explanation).split("\n");
1144
+ for (const line of explanationLines) {
1145
+ lines.push(`${continuePrefix} ${theme.fg("dim", replaceTabs(line))}`);
1146
+ }
1147
+ } else {
1148
+ // Preview: first sentence or ~100 chars (flatten tabs/newlines first)
1149
+ const flat = replaceTabs(sanitizeText(summary.explanation)).replace(/[\r\n]+/g, " ");
1150
+ const firstSentence = flat.split(/[.!?]/)[0].trim();
1151
+ const preview = truncateToWidth(`${firstSentence}.`, 100);
1152
+ lines.push(`${continuePrefix}${theme.fg("dim", preview)}`);
1153
+ }
1154
+ }
1155
+
1156
+ // Findings summary + list
1157
+ lines.push(`${continuePrefix}${formatFindingSummary(findings, theme)}`);
1158
+
1159
+ if (findings.length > 0) {
1160
+ lines.push(...renderFindings(findings, continuePrefix, expanded, theme));
1161
+ }
1162
+
1163
+ return lines;
1164
+ }
1165
+
1166
+ /**
1167
+ * Render review findings list.
1168
+ */
1169
+ function renderFindings(findings: FindingDetails[], continuePrefix: string, expanded: boolean, theme: Theme): string[] {
1170
+ const lines: string[] = [];
1171
+
1172
+ // Sort by priority (lower = more severe) when collapsed to show most important first
1173
+ const sortedFindings = expanded
1174
+ ? findings
1175
+ : [...findings].sort((a, b) => getPriorityInfo(a.priority).ord - getPriorityInfo(b.priority).ord);
1176
+ const displayCount = expanded ? sortedFindings.length : Math.min(3, sortedFindings.length);
1177
+
1178
+ for (let i = 0; i < displayCount; i++) {
1179
+ const finding = sortedFindings[i];
1180
+ const isLastFinding = i === displayCount - 1 && (expanded || sortedFindings.length <= 3);
1181
+ const findingPrefix = isLastFinding ? theme.tree.last : theme.tree.branch;
1182
+ const findingContinue = isLastFinding ? " " : `${theme.tree.vertical} `;
1183
+
1184
+ const { color } = getPriorityInfo(finding.priority);
1185
+ const rawTitle = sanitizeText(finding.title?.replace(/^\[P\d\]\s*/, "") ?? "Untitled");
1186
+ const titleText = replaceTabs(rawTitle).replace(/[\r\n]+/g, " ");
1187
+ const loc = `${path.basename(sanitizeText(finding.file_path || "<unknown>"))}:${finding.line_start}`;
1188
+
1189
+ lines.push(
1190
+ `${continuePrefix}${findingPrefix} ${theme.fg(color, `[${finding.priority}]`)} ${titleText} ${theme.fg("dim", loc)}`,
1191
+ );
1192
+
1193
+ // Show body when expanded
1194
+ if (expanded && finding.body) {
1195
+ // Wrap body text
1196
+ const bodyLines = sanitizeText(finding.body).split("\n");
1197
+ for (const bodyLine of bodyLines) {
1198
+ lines.push(`${continuePrefix}${findingContinue}${theme.fg("dim", replaceTabs(bodyLine))}`);
1199
+ }
1200
+ }
1201
+ }
1202
+
1203
+ if (!expanded && findings.length > 3) {
1204
+ lines.push(`${continuePrefix}${theme.fg("dim", formatMoreItems(findings.length - 3, "finding"))}`);
1205
+ }
1206
+
1207
+ return lines;
1208
+ }
1209
+
1210
+ /**
1211
+ * Render final result for a single agent.
1212
+ */
1213
+ function renderAgentResult(
1214
+ result: SingleResult,
1215
+ prefix: string,
1216
+ continuePrefix: string,
1217
+ expanded: boolean,
1218
+ theme: Theme,
1219
+ seenNestedTasks?: WeakSet<object>,
1220
+ nestedDepth = 0,
1221
+ ): string[] {
1222
+ const lines: string[] = [];
1223
+
1224
+ const { warning: missingCompleteWarning, rest: outputWithoutWarning } = extractMissingYieldWarning(result.output);
1225
+ const aborted = result.aborted ?? false;
1226
+ const mergeFailed = !aborted && result.exitCode === 0 && !!result.error;
1227
+ const success = !aborted && result.exitCode === 0 && !result.error;
1228
+ const needsWarning = Boolean(missingCompleteWarning) && success;
1229
+ const icon = aborted
1230
+ ? theme.status.aborted
1231
+ : needsWarning
1232
+ ? theme.status.warning
1233
+ : success
1234
+ ? theme.styledSymbol("status.done", "text")
1235
+ : theme.status.error;
1236
+ const iconColor = needsWarning ? "warning" : success ? "success" : mergeFailed ? "warning" : "error";
1237
+ const statusText = aborted
1238
+ ? "aborted"
1239
+ : needsWarning
1240
+ ? "warning"
1241
+ : success
1242
+ ? "done"
1243
+ : mergeFailed
1244
+ ? "merge failed"
1245
+ : "failed";
1246
+
1247
+ // Main status line: id: description [status] · stats · ⟨agent⟩
1248
+ const trimmedDescription = result.description ? sanitizeText(result.description).trim() : undefined;
1249
+ const description = trimmedDescription ? previewLine(trimmedDescription, 64) : undefined;
1250
+ const displayId = formatTaskId(result.id);
1251
+ const titlePart = description ? `${theme.bold(displayId)}: ${description}` : displayId;
1252
+ let statusLine = `${prefix ? `${prefix} ` : ""}${theme.fg(iconColor, icon)} ${theme.fg(
1253
+ success && !needsWarning ? "text" : "accent",
1254
+ titlePart,
1255
+ )}${agentTypeBadge(result.agent, theme)} ${formatBadge(statusText, iconColor, theme)}`;
1256
+ const showBadge = settings.get("task.showResolvedModelBadge");
1257
+ statusLine = appendAgentStats(
1258
+ statusLine,
1259
+ {
1260
+ tokens: result.tokens,
1261
+ requests: result.requests,
1262
+ contextTokens: result.contextTokens,
1263
+ contextWindow: result.contextWindow,
1264
+ cost: result.usage?.cost.total ?? 0,
1265
+ resolvedModel: result.resolvedModel,
1266
+ showResolvedModelBadge: showBadge,
1267
+ },
1268
+ theme,
1269
+ );
1270
+ statusLine += `${theme.sep.dot}${theme.fg("dim", formatDuration(result.durationMs))}`;
1271
+
1272
+ if (result.truncated) {
1273
+ statusLine += ` ${theme.fg("warning", "[truncated]")}`;
1274
+ }
1275
+
1276
+ lines.push(statusLine);
1277
+
1278
+ lines.push(...renderTaskSection(result.assignment ?? result.task, continuePrefix, expanded, theme));
1279
+
1280
+ if (aborted && result.abortReason) {
1281
+ lines.push(
1282
+ `${continuePrefix}${theme.fg("error", theme.status.aborted)} ${theme.fg(
1283
+ "dim",
1284
+ previewLine(sanitizeText(result.abortReason), 80),
1285
+ )}`,
1286
+ );
1287
+ }
1288
+ // Check for review result from incremental yield sections.
1289
+ // `normalizeYieldData` guards against a stray non-array `yield` slot —
1290
+ // optional chaining on `.map` only short-circuits on null/undefined and
1291
+ // would otherwise crash the renderer with `TypeError: completeData?.map
1292
+ // is not a function` when the slot is a plain object (see issue #1987).
1293
+ const completeData = normalizeYieldData(result.extractedToolData?.yield);
1294
+ const incrementalReview = extractIncrementalReviewResult(completeData);
1295
+
1296
+ if (incrementalReview) {
1297
+ lines.push(
1298
+ ...renderReviewResult(incrementalReview.summary, incrementalReview.findings, continuePrefix, expanded, theme),
1299
+ );
1300
+ return lines;
1301
+ }
1302
+
1303
+ // Extract review verdict from legacy yield summary objects if present.
1304
+ const reviewData = completeData
1305
+ .map(c => c.data as SubmitReviewDetails)
1306
+ .filter(d => d && typeof d === "object" && "overall_correctness" in d);
1307
+ const submitReviewData = reviewData.length > 0 ? reviewData : undefined;
1308
+
1309
+ if (submitReviewData) {
1310
+ const summary = submitReviewData[submitReviewData.length - 1];
1311
+ const findings: FindingDetails[] = [];
1312
+ lines.push(...renderReviewResult(summary, findings, continuePrefix, expanded, theme));
1313
+ return lines;
1314
+ }
1315
+
1316
+ // Check for extracted tool data with custom renderers (skip review tools)
1317
+ let hasCustomRendering = false;
1318
+ const deferredToolLines: string[] = [];
1319
+ if (result.extractedToolData) {
1320
+ for (const toolName in result.extractedToolData) {
1321
+ const dataArray = result.extractedToolData[toolName];
1322
+ if (toolName === "yield") {
1323
+ const yieldLines = renderTypedYieldSections(dataArray, continuePrefix, expanded, theme);
1324
+ if (yieldLines.length > 0) {
1325
+ hasCustomRendering = true;
1326
+ lines.push(...yieldLines);
1327
+ }
1328
+ continue;
1329
+ }
1330
+
1331
+ const isTaskTool = toolName === "task";
1332
+ if (isTaskTool && (dataArray as unknown[]).length > 0) {
1333
+ for (const line of renderNestedTaskResults(
1334
+ dataArray as TaskToolDetails[],
1335
+ expanded,
1336
+ theme,
1337
+ seenNestedTasks,
1338
+ nestedDepth,
1339
+ )) {
1340
+ deferredToolLines.push(`${continuePrefix}${line}`);
1341
+ }
1342
+ continue;
1343
+ }
1344
+
1345
+ const handler = subprocessToolRegistry.getHandler(toolName);
1346
+ if (handler?.renderFinal && (dataArray as unknown[]).length > 0) {
1347
+ const component = handler.renderFinal(dataArray as unknown[], theme, expanded);
1348
+ const target = lines;
1349
+ if (!isTaskTool) {
1350
+ hasCustomRendering = true;
1351
+ target.push(`${continuePrefix}${theme.fg("dim", `Tool: ${toolName}`)}`);
1352
+ }
1353
+ if (component instanceof Text) {
1354
+ // Prefix each line with continuePrefix
1355
+ const text = component.getText();
1356
+ for (const line of text.split("\n")) {
1357
+ target.push(`${continuePrefix}${line}`);
1358
+ }
1359
+ } else if (component instanceof Container) {
1360
+ // For containers, render each child
1361
+ for (const child of (component as Container).children) {
1362
+ if (child instanceof Text) {
1363
+ target.push(`${continuePrefix}${child.getText()}`);
1364
+ }
1365
+ }
1366
+ }
1367
+ }
1368
+ }
1369
+ }
1370
+
1371
+ if (hasCustomRendering && missingCompleteWarning) {
1372
+ lines.push(
1373
+ `${continuePrefix}${theme.fg("warning", theme.status.warning)} ${theme.fg(
1374
+ "dim",
1375
+ truncateToWidth(sanitizeText(missingCompleteWarning), 80),
1376
+ )}`,
1377
+ );
1378
+ }
1379
+
1380
+ // Fallback to output preview if no custom rendering
1381
+ if (!hasCustomRendering) {
1382
+ lines.push(
1383
+ ...renderOutputSection(outputWithoutWarning, continuePrefix, expanded, theme, 3, 12, missingCompleteWarning),
1384
+ );
1385
+ }
1386
+
1387
+ if (deferredToolLines.length > 0) {
1388
+ lines.push(...deferredToolLines);
1389
+ }
1390
+
1391
+ if (result.patchPath && !aborted && result.exitCode === 0) {
1392
+ lines.push(`${continuePrefix}${theme.fg("dim", `Patch: ${result.patchPath}`)}`);
1393
+ } else if (result.branchName && !aborted && result.exitCode === 0) {
1394
+ lines.push(`${continuePrefix}${theme.fg("dim", `Branch: ${result.branchName}`)}`);
1395
+ }
1396
+
1397
+ // Error message
1398
+ if (result.error && (!success || mergeFailed) && (!aborted || result.error !== result.abortReason)) {
1399
+ lines.push(
1400
+ `${continuePrefix}${theme.fg(mergeFailed ? "warning" : "error", previewLine(sanitizeText(result.error), 70))}`,
1401
+ );
1402
+ }
1403
+
1404
+ return lines;
1405
+ }
1406
+
1407
+ /**
1408
+ * Order live progress entries so finished agents render first — sorted by
1409
+ * runtime ascending, matching {@link orderResultsForDisplay} — while
1410
+ * unfinished (pending/running) ones stay pinned at the bottom in dispatch
1411
+ * order. Because a finished agent's runtime is fixed, finalization renders
1412
+ * the same order and rows never reshuffle.
1413
+ */
1414
+ function orderProgressForDisplay(progress: readonly AgentProgress[]): AgentProgress[] {
1415
+ const finished: AgentProgress[] = [];
1416
+ const unfinished: AgentProgress[] = [];
1417
+ for (const p of progress) {
1418
+ (p.status === "pending" || p.status === "running" ? unfinished : finished).push(p);
1419
+ }
1420
+ finished.sort((a, b) => a.durationMs - b.durationMs || a.index - b.index);
1421
+ return finished.concat(unfinished);
1422
+ }
1423
+
1424
+ /**
1425
+ * Order finalized results by runtime ascending (tie-break: dispatch index) so
1426
+ * the finalized list matches the live-progress order produced by
1427
+ * {@link orderProgressForDisplay}.
1428
+ */
1429
+ function orderResultsForDisplay(results: readonly SingleResult[]): SingleResult[] {
1430
+ return [...results].sort((a, b) => a.durationMs - b.durationMs || a.index - b.index);
1431
+ }
1432
+
1433
+ /**
1434
+ * Summary line for progress rows folded away by the collapsed cap: per-status
1435
+ * counts plus the expand hint, e.g. `… 21 more agents (18 pending · 3 done)`.
1436
+ */
1437
+ function formatHiddenProgressLine(hidden: readonly AgentProgress[], theme: Theme): string {
1438
+ const counts: Record<AgentProgress["status"], number> = {
1439
+ pending: 0,
1440
+ running: 0,
1441
+ completed: 0,
1442
+ failed: 0,
1443
+ aborted: 0,
1444
+ };
1445
+ for (const p of hidden) counts[p.status]++;
1446
+ const parts: string[] = [];
1447
+ if (counts.completed > 0) parts.push(theme.fg("dim", `${counts.completed} done`));
1448
+ if (counts.running > 0) parts.push(theme.fg("dim", `${counts.running} running`));
1449
+ if (counts.pending > 0) parts.push(theme.fg("dim", `${counts.pending} pending`));
1450
+ if (counts.failed > 0) parts.push(theme.fg("error", `${counts.failed} failed`));
1451
+ if (counts.aborted > 0) parts.push(theme.fg("error", `${counts.aborted} aborted`));
1452
+ const breakdown =
1453
+ parts.length > 0
1454
+ ? `${theme.fg("dim", " (")}${parts.join(theme.fg("dim", theme.sep.dot))}${theme.fg("dim", ")")}`
1455
+ : "";
1456
+ const hint = formatExpandHint(theme, false, true);
1457
+ return `${theme.fg("dim", formatMoreItems(hidden.length, "agent"))}${breakdown}${hint ? ` ${hint}` : ""}`;
1458
+ }
1459
+
1460
+ /**
1461
+ * Pick the agent rows that stay visible when a finalized batch is collapsed:
1462
+ * problem rows (aborted/failed/merge-failed) claim slots first so they are
1463
+ * never folded away, then fastest finishers fill the remainder. The pick is
1464
+ * filtered out of the display order, so visible rows keep the expanded layout.
1465
+ */
1466
+ function selectCollapsedResults(ordered: readonly SingleResult[]): readonly SingleResult[] {
1467
+ if (ordered.length <= COLLAPSED_AGENT_LIMIT) return ordered;
1468
+ const picked = new Set<SingleResult>();
1469
+ for (const result of ordered) {
1470
+ if (picked.size >= COLLAPSED_AGENT_LIMIT) break;
1471
+ if (result.aborted || result.exitCode !== 0 || result.error) picked.add(result);
1472
+ }
1473
+ for (const result of ordered) {
1474
+ if (picked.size >= COLLAPSED_AGENT_LIMIT) break;
1475
+ picked.add(result);
1476
+ }
1477
+ return ordered.filter(result => picked.has(result));
1478
+ }
1479
+
1480
+ /**
1481
+ * Render the tool result.
1482
+ */
1483
+ export function renderResult(
1484
+ result: { content: Array<{ type: string; text?: string }>; details?: TaskToolDetails; isError?: boolean },
1485
+ options: TaskRenderOptions,
1486
+ theme: Theme,
1487
+ args?: TaskParams,
1488
+ ): Component {
1489
+ const fallbackText = result.content.find(c => c.type === "text")?.text ?? "";
1490
+ const details = result.details;
1491
+ const agentLabel = formatAgentHeaderLabel(args);
1492
+ const assignmentSection = createAssignmentSectionRenderer(args, theme);
1493
+ const contextSection = createContextSectionRenderer(args, theme);
1494
+
1495
+ if (!details) {
1496
+ const text = result.content.find(c => c.type === "text")?.text || "";
1497
+ const errored = result.isError === true;
1498
+ const header = errored
1499
+ ? renderStatusLine({ icon: "error", title: "Task", description: agentLabel }, theme)
1500
+ : renderStatusLine(
1501
+ {
1502
+ iconOverride: theme.styledSymbol("status.done", "accent"),
1503
+ title: "Task",
1504
+ description: agentLabel,
1505
+ },
1506
+ theme,
1507
+ );
1508
+ return framedBlock(theme, width => ({
1509
+ header,
1510
+ sections: [
1511
+ ...(contextSection ? [contextSection(width)] : []),
1512
+ ...(assignmentSection ? [assignmentSection(width)] : []),
1513
+ ...(text ? [{ separator: true, lines: [theme.fg("dim", truncateToWidth(text, width))] }] : []),
1514
+ ],
1515
+ state: errored ? "error" : "success",
1516
+ borderColor: errored ? "error" : "borderMuted",
1517
+ width,
1518
+ }));
1519
+ }
1520
+
1521
+ const hasResults = Boolean(details.results && details.results.length > 0);
1522
+ // Single pass over details.results derives the header booleans AND the footer
1523
+ // counts/totals. This block re-runs ~30×/sec via the 33ms spinner render; the
1524
+ // previous form did 3× `.some()` here plus 3× `.filter()` + `.reduce()` again
1525
+ // inside the frame below (7+ full passes per tick).
1526
+ let abortedCount = 0;
1527
+ let failCount = 0;
1528
+ let mergeFailedCount = 0;
1529
+ let successCount = 0;
1530
+ let requestTotal = 0;
1531
+ if (hasResults) {
1532
+ for (const r of details.results) {
1533
+ requestTotal += r.requests ?? 0;
1534
+ if (r.aborted) abortedCount++;
1535
+ else if (r.exitCode !== 0) failCount++;
1536
+ else if (r.error) mergeFailedCount++;
1537
+ else successCount++;
1538
+ }
1539
+ }
1540
+ const aborted = abortedCount > 0;
1541
+ const failed = failCount > 0;
1542
+ const mergeFailed = mergeFailedCount > 0;
1543
+ const isError = aborted || failed;
1544
+ const agentCount = hasResults ? details.results.length : (details.progress?.length ?? 0);
1545
+ const icon: ToolUIStatus = options.isPartial ? "running" : isError ? "error" : mergeFailed ? "warning" : "success";
1546
+ // Header meta is the spawn count only; each row carries its own ⟨agent⟩
1547
+ // badge, so a joined type list here would repeat them. Before anything
1548
+ // spawns, fall back to the flat form's agent type from the call args.
1549
+ const countLabel = agentCount > 0 ? `${agentCount} ${agentCount === 1 ? "agent" : "agents"}` : undefined;
1550
+ const metaLabel = countLabel ?? agentLabel;
1551
+ const header = renderStatusLine(
1552
+ {
1553
+ icon: icon === "success" || icon === "running" ? undefined : icon,
1554
+ // While agents are in flight the header shows the dispatch glyph, not a
1555
+ // spinner: async spawns return immediately, so "running" means
1556
+ // "delegated to peers", not "this call is blocking the turn".
1557
+ iconOverride:
1558
+ icon === "running"
1559
+ ? theme.styledSymbol("tool.task", "accent")
1560
+ : icon === "success"
1561
+ ? theme.styledSymbol("status.done", "accent")
1562
+ : undefined,
1563
+ title: "Task",
1564
+ meta: metaLabel ? [metaLabel] : undefined,
1565
+ },
1566
+ theme,
1567
+ );
1568
+
1569
+ return framedBlock(theme, width => {
1570
+ const { expanded, isPartial, spinnerFrame } = options;
1571
+ const frozen = options.renderContext?.frozen === true;
1572
+ const nowMs = options.renderContext?.nowMs ?? Date.now();
1573
+ const lines: string[] = [];
1574
+
1575
+ // Result rows win once any exist; progress rows for spawns without a
1576
+ // result (a mixed call's async subset) render as a supplement below.
1577
+ const shouldRenderProgress =
1578
+ Boolean(details.progress && details.progress.length > 0) && details.results.length === 0;
1579
+ if (shouldRenderProgress && details.progress) {
1580
+ const ordered = orderProgressForDisplay(details.progress);
1581
+ // Collapsed view keeps the live edge: finished rows sort to the top of
1582
+ // the display order, so folding from the top keeps running/pending
1583
+ // agents (and their current-tool lines) visible while one summary line
1584
+ // stands in for everything above it.
1585
+ const visible = expanded ? ordered : ordered.slice(Math.max(0, ordered.length - COLLAPSED_AGENT_LIMIT));
1586
+ if (visible.length < ordered.length) {
1587
+ lines.push(formatHiddenProgressLine(ordered.slice(0, ordered.length - visible.length), theme));
1588
+ }
1589
+ for (const progress of visible) {
1590
+ lines.push(
1591
+ ...renderAgentProgress(progress, "", " ", expanded, theme, spinnerFrame, frozen, undefined, 0, nowMs),
1592
+ );
1593
+ }
1594
+ } else if (details.results && details.results.length > 0) {
1595
+ const ordered = orderResultsForDisplay(details.results);
1596
+ const visible = expanded ? ordered : selectCollapsedResults(ordered);
1597
+ for (const res of visible) {
1598
+ lines.push(...renderAgentResult(res, "", " ", expanded, theme));
1599
+ }
1600
+ if (visible.length < ordered.length) {
1601
+ const hint = formatExpandHint(theme, false, true);
1602
+ lines.push(
1603
+ `${theme.fg("dim", formatMoreItems(ordered.length - visible.length, "agent"))}${hint ? ` ${hint}` : ""}`,
1604
+ );
1605
+ }
1606
+
1607
+ // Mixed blocking+async call: async spawns never land in `results`
1608
+ // (their payloads deliver through jobs) — keep their rows visible
1609
+ // beside the finalized inline results, live while running and
1610
+ // settled once their jobs finish.
1611
+ const supplementalProgress = details.progress
1612
+ ? orderProgressForDisplay(
1613
+ details.progress.filter(progress => !details.results.some(res => res.id === progress.id)),
1614
+ )
1615
+ : [];
1616
+ for (const progress of supplementalProgress) {
1617
+ lines.push(
1618
+ ...renderAgentProgress(progress, "", " ", expanded, theme, spinnerFrame, frozen, undefined, 0, nowMs),
1619
+ );
1620
+ }
1621
+
1622
+ const summaryParts: string[] = [];
1623
+ if (abortedCount > 0) summaryParts.push(theme.fg("error", `${abortedCount} aborted`));
1624
+ if (successCount > 0) summaryParts.push(theme.fg("success", `${successCount} succeeded`));
1625
+ if (mergeFailedCount > 0) summaryParts.push(theme.fg("warning", `${mergeFailedCount} merge failed`));
1626
+ if (failCount > 0) summaryParts.push(theme.fg("error", `${failCount} failed`));
1627
+ const totalRequests = requestTotal;
1628
+ if (totalRequests > 0) summaryParts.push(theme.fg("dim", `${formatNumber(totalRequests)} req`));
1629
+ summaryParts.push(theme.fg("dim", formatDuration(details.totalDurationMs)));
1630
+ // Wrap the run summary in the theme's bracket glyphs (dim chrome, colored
1631
+ // counts) to match the bash tool's `[Wall: … | Exit: …]` footer.
1632
+ lines.push(
1633
+ theme.fg("dim", theme.format.bracketLeft) +
1634
+ summaryParts.join(theme.fg("dim", theme.sep.dot)) +
1635
+ theme.fg("dim", theme.format.bracketRight),
1636
+ );
1637
+ }
1638
+
1639
+ const state = isPartial ? "running" : isError ? "error" : mergeFailed ? "warning" : "success";
1640
+ const borderColor = isError ? "error" : "borderMuted";
1641
+
1642
+ if (lines.length === 0) {
1643
+ const text = fallbackText.trim() ? fallbackText : "No results";
1644
+ return {
1645
+ header,
1646
+ sections: [
1647
+ ...(contextSection ? [contextSection(width)] : []),
1648
+ ...(assignmentSection ? [assignmentSection(width)] : []),
1649
+ { separator: true, lines: [theme.fg("dim", truncateToWidth(text, width))] },
1650
+ ],
1651
+ state,
1652
+ borderColor,
1653
+ width,
1654
+ };
1655
+ }
1656
+
1657
+ if (fallbackText.trim()) {
1658
+ const summaryLines = fallbackText.split("\n");
1659
+ const markerIndex = summaryLines.findIndex(
1660
+ line =>
1661
+ line.includes("<system-notification>") ||
1662
+ line.startsWith("Applied patches:") ||
1663
+ line.startsWith("No changes to apply."),
1664
+ );
1665
+ if (markerIndex >= 0) {
1666
+ const extra = summaryLines.slice(markerIndex);
1667
+ for (const line of extra) {
1668
+ if (!line.trim()) continue;
1669
+ lines.push(theme.fg("dim", line));
1670
+ }
1671
+ }
1672
+ }
1673
+
1674
+ while (lines.length > 0 && lines[0].trim() === "") lines.shift();
1675
+ return {
1676
+ header,
1677
+ sections: [
1678
+ ...(contextSection ? [contextSection(width)] : []),
1679
+ ...(assignmentSection ? [assignmentSection(width)] : []),
1680
+ ...(lines.length > 0 ? [{ separator: true, lines }] : []),
1681
+ ],
1682
+ state,
1683
+ borderColor,
1684
+ width,
1685
+ };
1686
+ });
1687
+ }
1688
+
1689
+ function isTaskToolDetails(value: unknown): value is TaskToolDetails {
1690
+ return (
1691
+ Boolean(value) &&
1692
+ typeof value === "object" &&
1693
+ "results" in (value as TaskToolDetails) &&
1694
+ Array.isArray((value as TaskToolDetails).results)
1695
+ );
1696
+ }
1697
+
1698
+ // Nested subagent snapshots sit one or more levels below the frame border, so
1699
+ // they keep tree guides to convey depth (the parent prepends its own continue
1700
+ // prefix). Only the top-level agent list drops guides (the frame is its box).
1701
+ function nestedMarkers(isLast: boolean, theme: Theme): { prefix: string; continuePrefix: string } {
1702
+ return {
1703
+ prefix: isLast ? theme.fg("dim", theme.tree.last) : theme.fg("dim", theme.tree.branch),
1704
+ continuePrefix: isLast ? " " : `${theme.fg("dim", theme.tree.vertical)} `,
1705
+ };
1706
+ }
1707
+
1708
+ function renderNestedTaskResults(
1709
+ detailsList: TaskToolDetails[],
1710
+ expanded: boolean,
1711
+ theme: Theme,
1712
+ seen: WeakSet<object> = new WeakSet<object>(),
1713
+ depth = 0,
1714
+ ): string[] {
1715
+ const lines: string[] = [];
1716
+ for (const details of detailsList) {
1717
+ if (seen.has(details)) {
1718
+ lines.push(renderNestedCycleLine(theme));
1719
+ continue;
1720
+ }
1721
+ if (depth >= MAX_NESTED_TASK_RENDER_DEPTH) {
1722
+ lines.push(theme.fg("dim", "… nested task depth limit reached"));
1723
+ continue;
1724
+ }
1725
+ seen.add(details);
1726
+ if (!details.results || details.results.length === 0) {
1727
+ seen.delete(details);
1728
+ continue;
1729
+ }
1730
+ const ordered = orderResultsForDisplay(details.results);
1731
+ const visible = expanded ? ordered : selectCollapsedResults(ordered);
1732
+ const hiddenCount = ordered.length - visible.length;
1733
+ visible.forEach((result, index) => {
1734
+ const { prefix, continuePrefix } = nestedMarkers(hiddenCount === 0 && index === visible.length - 1, theme);
1735
+ lines.push(...renderAgentResult(result, prefix, continuePrefix, expanded, theme, seen, depth + 1));
1736
+ });
1737
+ if (hiddenCount > 0) {
1738
+ const { prefix } = nestedMarkers(true, theme);
1739
+ lines.push(`${prefix} ${theme.fg("dim", formatMoreItems(hiddenCount, "agent"))}`);
1740
+ }
1741
+ seen.delete(details);
1742
+ }
1743
+ return lines;
1744
+ }
1745
+
1746
+ /**
1747
+ * Render a list of `TaskToolDetails` snapshots — completed (`results[]`) or
1748
+ * in-flight (`progress[]`) — as an interleaved tree. Used by the live progress
1749
+ * view to surface nested subagent activity while this agent is still running.
1750
+ */
1751
+ function renderNestedTaskTree(
1752
+ detailsList: TaskToolDetails[],
1753
+ expanded: boolean,
1754
+ theme: Theme,
1755
+ spinnerFrame?: number,
1756
+ frozen = false,
1757
+ seen: WeakSet<object> = new WeakSet<object>(),
1758
+ depth = 0,
1759
+ nowMs = Date.now(),
1760
+ ): string[] {
1761
+ const lines: string[] = [];
1762
+ for (const details of detailsList) {
1763
+ if (seen.has(details)) {
1764
+ lines.push(renderNestedCycleLine(theme));
1765
+ continue;
1766
+ }
1767
+ if (depth >= MAX_NESTED_TASK_RENDER_DEPTH) {
1768
+ lines.push(theme.fg("dim", "… nested task depth limit reached"));
1769
+ continue;
1770
+ }
1771
+ seen.add(details);
1772
+ const hasResults = Boolean(details.results && details.results.length > 0);
1773
+ if (hasResults) {
1774
+ const ordered = orderResultsForDisplay(details.results);
1775
+ const visible = expanded ? ordered : selectCollapsedResults(ordered);
1776
+ const hiddenCount = ordered.length - visible.length;
1777
+ visible.forEach((result, index) => {
1778
+ const { prefix, continuePrefix } = nestedMarkers(hiddenCount === 0 && index === visible.length - 1, theme);
1779
+ lines.push(...renderAgentResult(result, prefix, continuePrefix, expanded, theme, seen, depth + 1));
1780
+ });
1781
+ if (hiddenCount > 0) {
1782
+ const { prefix } = nestedMarkers(true, theme);
1783
+ lines.push(`${prefix} ${theme.fg("dim", formatMoreItems(hiddenCount, "agent"))}`);
1784
+ }
1785
+ seen.delete(details);
1786
+ continue;
1787
+ }
1788
+ const inflight = details.progress;
1789
+ if (inflight && inflight.length > 0) {
1790
+ const ordered = orderProgressForDisplay(inflight);
1791
+ const visible = expanded ? ordered : ordered.slice(Math.max(0, ordered.length - COLLAPSED_AGENT_LIMIT));
1792
+ const hiddenCount = ordered.length - visible.length;
1793
+ visible.forEach((prog, index) => {
1794
+ const { prefix, continuePrefix } = nestedMarkers(hiddenCount === 0 && index === visible.length - 1, theme);
1795
+ lines.push(
1796
+ ...renderAgentProgress(
1797
+ prog,
1798
+ prefix,
1799
+ continuePrefix,
1800
+ expanded,
1801
+ theme,
1802
+ spinnerFrame,
1803
+ frozen,
1804
+ seen,
1805
+ depth + 1,
1806
+ nowMs,
1807
+ ),
1808
+ );
1809
+ });
1810
+ if (hiddenCount > 0) {
1811
+ const { prefix } = nestedMarkers(true, theme);
1812
+ lines.push(`${prefix} ${theme.fg("dim", formatMoreItems(hiddenCount, "agent"))}`);
1813
+ }
1814
+ }
1815
+ seen.delete(details);
1816
+ }
1817
+ return lines;
1818
+ }
1819
+
1820
+ // Register task tool subprocess handler
1821
+ subprocessToolRegistry.register<TaskToolDetails>("task", {
1822
+ extractData: event => {
1823
+ const details = event.result?.details;
1824
+ return isTaskToolDetails(details) ? details : undefined;
1825
+ },
1826
+ renderFinal: (allData, theme, expanded) => {
1827
+ const lines = renderNestedTaskResults(allData, expanded, theme);
1828
+ return new Text(lines.join("\n"), 0, 0);
1829
+ },
1830
+ });