@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,1459 @@
1
+ /**
2
+ * Ask Tool - Interactive user prompting during execution
3
+ *
4
+ * Use this tool when you need to ask the user questions during execution.
5
+ * This allows you to:
6
+ * 1. Gather user preferences or requirements
7
+ * 2. Clarify ambiguous instructions
8
+ * 3. Get decisions on implementation choices as you work
9
+ * 4. Offer choices to the user about what direction to take
10
+ *
11
+ * Usage notes:
12
+ * - Users will always be able to select "Other" to provide custom text input
13
+ * - Use multi: true to allow multiple answers to be selected for a question
14
+ * - Use recommended: <index> to mark the default option; "(Recommended)" suffix is added automatically
15
+ * - Questions may time out and auto-select the recommended option (configurable, disabled in plan mode)
16
+ */
17
+
18
+ import { type as arkType } from "@oh-my-pi/omptype";
19
+ import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
20
+ import type { ToolExample } from "@oh-my-pi/pi-ai";
21
+ import {
22
+ type Component,
23
+ Ellipsis,
24
+ Markdown,
25
+ type MarkdownTheme,
26
+ renderInlineMarkdown,
27
+ replaceTabs,
28
+ TERMINAL,
29
+ Text,
30
+ truncateToWidth,
31
+ visibleWidth,
32
+ } from "@oh-my-pi/pi-tui";
33
+ import { prompt, untilAborted } from "@oh-my-pi/pi-utils";
34
+ import type { RenderResultOptions } from "../extensibility/custom-tools/types";
35
+ import type { ExtensionUISelectItem } from "../extensibility/extensions";
36
+ import { getMarkdownTheme, type Theme, theme } from "../modes/theme/theme";
37
+ import askDescription from "../prompts/tools/ask.md" with { type: "text" };
38
+ import { vocalizer } from "../tts/vocalizer";
39
+ import { framedBlock, outputBlockContentWidth, renderStatusLine } from "../tui";
40
+ import type { ToolSession } from ".";
41
+ import { formatErrorMessage, formatMeta, formatTitle } from "./render-utils";
42
+ import { ToolAbortError } from "./tool-errors";
43
+
44
+ // =============================================================================
45
+ // Types
46
+ // =============================================================================
47
+
48
+ const OTHER_OPTION = "Other (type your own)";
49
+ const CHAT_ABOUT_THIS_OPTION = "Chat about this";
50
+ const NEXT_OPTION = "Next →";
51
+ const RESERVED_OPTION_LABELS: Record<string, true> = {
52
+ [OTHER_OPTION]: true,
53
+ [CHAT_ABOUT_THIS_OPTION]: true,
54
+ [NEXT_OPTION]: true,
55
+ };
56
+
57
+ const OptionItem = arkType({
58
+ label: arkType("string").describe("display label"),
59
+ "description?": arkType("string").describe("optional explanatory text displayed below the label"),
60
+ "preview?": arkType("string").describe("optional rich preview content for interactive ask dialogs"),
61
+ });
62
+
63
+ const QuestionItem = arkType({
64
+ id: arkType("string").describe("question id"),
65
+ question: arkType("string").describe("question text"),
66
+ "header?": arkType("string").describe("optional short display chip for rich ask dialogs"),
67
+ options: OptionItem.array().describe("available options"),
68
+ "multi?": arkType("boolean").describe("allow multiple selections"),
69
+ "recommended?": arkType("number").describe("recommended option index"),
70
+ }).narrow((question, ctx) => {
71
+ const reserved = question.options.find(option => RESERVED_OPTION_LABELS[option.label] === true);
72
+ return (
73
+ reserved === undefined ||
74
+ ctx.mustBe(`defined with option labels that do not collide with reserved runtime labels: ${reserved.label}`)
75
+ );
76
+ });
77
+
78
+ const askSchema = arkType({
79
+ questions: QuestionItem.array().atLeastLength(1).describe("questions to ask"),
80
+ });
81
+
82
+ export type AskToolInput = typeof askSchema.infer;
83
+
84
+ /**
85
+ * Recover a validated `questions` payload from a persisted `ask` toolCall's
86
+ * `arguments`. Used by `/tree` re-answer (issue #5642): selecting a past
87
+ * `ask` toolResult re-opens the picker with the *original* questions, so the
88
+ * new answer branches as a sibling instead of mutating the old one. Runs the
89
+ * same schema the live tool call validated against — legacy/corrupted
90
+ * persisted args fail closed (`undefined`) rather than feeding malformed
91
+ * data back into the picker.
92
+ */
93
+ export function recoverAskQuestions(toolCallArguments: unknown): AskToolInput["questions"] | undefined {
94
+ const parsed = askSchema(toolCallArguments);
95
+ if (parsed instanceof arkType.errors) return undefined;
96
+ return parsed.questions;
97
+ }
98
+
99
+ /** Result for a single question */
100
+ export interface QuestionResult {
101
+ id: string;
102
+ question: string;
103
+ options: string[];
104
+ multi: boolean;
105
+ selectedOptions: string[];
106
+ customInput?: string;
107
+ /** Optional note attached to the selected answer in the rich ask dialog. */
108
+ note?: string;
109
+ /** True when the answer was auto-selected because the dialog timed out. */
110
+ timedOut?: boolean;
111
+ }
112
+
113
+ export interface AskToolDetails {
114
+ question?: string;
115
+ options?: string[];
116
+ multi?: boolean;
117
+ selectedOptions?: string[];
118
+ customInput?: string;
119
+ /** Optional note attached to the selected answer in the rich ask dialog. */
120
+ note?: string;
121
+ /** True when the answer was auto-selected because the dialog timed out. */
122
+ timedOut?: boolean;
123
+ /** Multi-part question mode */
124
+ results?: QuestionResult[];
125
+ /** Chat redirect: the user chose "Chat about this" instead of answering. */
126
+ chatRedirect?: boolean;
127
+ /** Questions surfaced when chatRedirect is true. */
128
+ questions?: string[];
129
+ }
130
+
131
+ interface AskOption {
132
+ label: string;
133
+ description?: string;
134
+ }
135
+
136
+ function getAskOptionLabel(option: AskOption): string {
137
+ return option.label;
138
+ }
139
+
140
+ function getSelectOptionLabel(option: ExtensionUISelectItem): string {
141
+ return typeof option === "string" ? option : option.label;
142
+ }
143
+
144
+ function toSelectOption(option: AskOption, label = option.label): ExtensionUISelectItem {
145
+ return option.description ? { label, description: option.description } : label;
146
+ }
147
+
148
+ // =============================================================================
149
+ // Constants
150
+ // =============================================================================
151
+
152
+ const RECOMMENDED_SUFFIX = " (Recommended)";
153
+ // Window after the timeout deadline within which an `undefined` selection is
154
+ // attributed to a UI-enforced timeout (for surfaces that close the dialog at
155
+ // the deadline but never invoke `onTimeout`). Cancels beyond it are user Esc.
156
+ const TIMEOUT_DETECTION_TOLERANCE_MS = 1_000;
157
+
158
+ function getDoneOptionLabel(): string {
159
+ return `${theme.status.success} Done selecting`;
160
+ }
161
+
162
+ /** Add "(Recommended)" suffix to the option at the given index if not already present */
163
+ function addRecommendedSuffix(options: AskOption[], recommendedIndex?: number): ExtensionUISelectItem[] {
164
+ if (recommendedIndex === undefined || recommendedIndex < 0 || recommendedIndex >= options.length) {
165
+ return options.map(option => toSelectOption(option));
166
+ }
167
+ return options.map((option, i) => {
168
+ const label =
169
+ i === recommendedIndex && !option.label.endsWith(RECOMMENDED_SUFFIX)
170
+ ? option.label + RECOMMENDED_SUFFIX
171
+ : option.label;
172
+ return toSelectOption(option, label);
173
+ });
174
+ }
175
+
176
+ function getAutoSelectionOnTimeout(options: AskOption[], recommended?: number): string[] {
177
+ if (options.length === 0) return [];
178
+ if (typeof recommended === "number" && recommended >= 0 && recommended < options.length) {
179
+ return [options[recommended]!.label];
180
+ }
181
+ return [options[0]!.label];
182
+ }
183
+
184
+ /** Strip "(Recommended)" suffix from a label */
185
+ function stripRecommendedSuffix(label: string): string {
186
+ return label.endsWith(RECOMMENDED_SUFFIX) ? label.slice(0, -RECOMMENDED_SUFFIX.length) : label;
187
+ }
188
+
189
+ interface CustomInputContext {
190
+ selectionMarker: "radio" | "checkbox";
191
+ checkedIndices?: readonly number[];
192
+ markableCount: number;
193
+ }
194
+
195
+ /** Hard caps for the editor title rendered while the user types an `Other`
196
+ * custom answer. {@link HookEditorComponent} renders the title via a single
197
+ * `Text` child stacked above the prompt editor with no `maxVisible` windowing,
198
+ * so the title MUST fit a normal terminal:
199
+ * - {@link MAX_CUSTOM_INPUT_OPTION_ROWS}: at most this many option-row entries
200
+ * survive {@link pickCustomInputOptionWindow}, regardless of total options.
201
+ * - {@link MAX_CUSTOM_INPUT_TITLE_ROWS}: hard cap on rendered title rows after
202
+ * every line is pre-truncated to one row at the live terminal width. Sized
203
+ * so a 24-row terminal still has space for the input row, hint, and chrome.
204
+ */
205
+ const MAX_CUSTOM_INPUT_OPTION_ROWS = 8;
206
+ const MAX_CUSTOM_INPUT_TITLE_ROWS = 16;
207
+ const MIN_CUSTOM_INPUT_CONTENT_WIDTH = 20;
208
+ /** Subtracted from the terminal width to leave room for the surrounding
209
+ * `Text(... padX=1)` padding + DynamicBorder vertical chrome. */
210
+ const CUSTOM_INPUT_CHROME_COLUMNS = 4;
211
+ const CUSTOM_INPUT_DESCRIPTION_INDENT = " ";
212
+
213
+ function customInputContentWidth(): number {
214
+ const cols = process.stdout.columns ?? 80;
215
+ return Math.max(MIN_CUSTOM_INPUT_CONTENT_WIDTH, cols - CUSTOM_INPUT_CHROME_COLUMNS);
216
+ }
217
+
218
+ function clampLineToWidth(line: string, width: number): string {
219
+ if (visibleWidth(line) <= width) return line;
220
+ return truncateToWidth(line, width, Ellipsis.Unicode);
221
+ }
222
+
223
+ function flattenDescription(text: string): string {
224
+ return text.replace(/\s+/g, " ").trim();
225
+ }
226
+
227
+ function getSelectOptionDescription(option: ExtensionUISelectItem): string | undefined {
228
+ return typeof option === "string" ? undefined : option.description;
229
+ }
230
+
231
+ interface CustomInputOptionGap {
232
+ total: number;
233
+ checked: number;
234
+ }
235
+
236
+ interface CustomInputOptionWindow {
237
+ indices: number[];
238
+ gapBefore: Map<number, CustomInputOptionGap>;
239
+ }
240
+
241
+ /** Window the option list so the title stays bounded. Required rows are the
242
+ * selected `Other` row and the first option as an anchor; checked rows fill
243
+ * the remaining budget before unselected leading rows. Hidden checked options
244
+ * are summarized in gap markers so the rendered option-row count still never
245
+ * exceeds {@link MAX_CUSTOM_INPUT_OPTION_ROWS}. */
246
+ function pickCustomInputOptionWindow(
247
+ total: number,
248
+ selectedIndex: number,
249
+ checked: ReadonlySet<number>,
250
+ ): CustomInputOptionWindow {
251
+ if (total === 0) return { indices: [], gapBefore: new Map() };
252
+ if (total <= MAX_CUSTOM_INPUT_OPTION_ROWS) {
253
+ return {
254
+ indices: Array.from({ length: total }, (_, i) => i),
255
+ gapBefore: new Map(),
256
+ };
257
+ }
258
+ const keep = new Set<number>();
259
+ const addIfRoom = (index: number) => {
260
+ if (index >= 0 && index < total && keep.size < MAX_CUSTOM_INPUT_OPTION_ROWS) {
261
+ keep.add(index);
262
+ }
263
+ };
264
+ addIfRoom(selectedIndex);
265
+ addIfRoom(0);
266
+ for (const i of [...checked].sort((a, b) => a - b)) {
267
+ addIfRoom(i);
268
+ }
269
+ for (let i = 0; i < total && keep.size < MAX_CUSTOM_INPUT_OPTION_ROWS; i++) {
270
+ addIfRoom(i);
271
+ }
272
+ const indices = [...keep].sort((a, b) => a - b);
273
+ const gapBefore = new Map<number, CustomInputOptionGap>();
274
+ const countCheckedBetween = (startInclusive: number, endExclusive: number): number => {
275
+ let count = 0;
276
+ for (const i of checked) {
277
+ if (i >= startInclusive && i < endExclusive) count++;
278
+ }
279
+ return count;
280
+ };
281
+ let prev = -1;
282
+ for (const idx of indices) {
283
+ if (idx > prev + 1) {
284
+ gapBefore.set(idx, {
285
+ total: idx - prev - 1,
286
+ checked: countCheckedBetween(prev + 1, idx),
287
+ });
288
+ }
289
+ prev = idx;
290
+ }
291
+ if (prev < total - 1) {
292
+ gapBefore.set(total, {
293
+ total: total - 1 - prev,
294
+ checked: countCheckedBetween(prev + 1, total),
295
+ });
296
+ }
297
+ return { indices, gapBefore };
298
+ }
299
+
300
+ interface CustomInputRow {
301
+ text: string;
302
+ /** Lower priority drops first when over budget; negative values are pinned.
303
+ * Gap markers are budgeted rows too so sparse checked selections cannot
304
+ * push the editor input off-screen. */
305
+ priority: number;
306
+ }
307
+
308
+ function buildCustomInputRows(
309
+ question: string,
310
+ options: ExtensionUISelectItem[],
311
+ context: CustomInputContext,
312
+ contentWidth: number,
313
+ ): CustomInputRow[] {
314
+ const selectedIndex = options.findIndex(option => getSelectOptionLabel(option) === OTHER_OPTION);
315
+ const checked = new Set(context.checkedIndices ?? []);
316
+ const window = pickCustomInputOptionWindow(options.length, selectedIndex, checked);
317
+ const rows: CustomInputRow[] = [];
318
+ rows.push({ text: clampLineToWidth(question, contentWidth), priority: -1 });
319
+ rows.push({ text: "", priority: -1 });
320
+
321
+ const emitGap = (gap: CustomInputOptionGap) => {
322
+ const checkedSuffix = gap.checked > 0 ? `, ${gap.checked} checked` : "";
323
+ rows.push({
324
+ text: clampLineToWidth(
325
+ ` … ${gap.total} more option${gap.total === 1 ? "" : "s"}${checkedSuffix} …`,
326
+ contentWidth,
327
+ ),
328
+ priority: 2,
329
+ });
330
+ };
331
+
332
+ for (const index of window.indices) {
333
+ const gap = window.gapBefore.get(index);
334
+ if (gap !== undefined) emitGap(gap);
335
+ const option = options[index]!;
336
+ const label = getSelectOptionLabel(option);
337
+ const isSelected = index === selectedIndex;
338
+ const isMarkable = index < context.markableCount;
339
+ const prefix =
340
+ context.selectionMarker === "radio" && (isMarkable || isSelected)
341
+ ? `${isSelected ? theme.radio.selected : theme.radio.unselected} `
342
+ : context.selectionMarker === "checkbox" && isMarkable
343
+ ? `${checked.has(index) ? theme.checkbox.checked : theme.checkbox.unchecked} `
344
+ : isSelected
345
+ ? `${theme.nav.cursor} `
346
+ : " ";
347
+ rows.push({ text: clampLineToWidth(prefix + label, contentWidth), priority: -1 });
348
+ const description = getSelectOptionDescription(option);
349
+ if (description) {
350
+ const flat = flattenDescription(description);
351
+ if (flat) {
352
+ rows.push({
353
+ text: clampLineToWidth(`${CUSTOM_INPUT_DESCRIPTION_INDENT}${flat}`, contentWidth),
354
+ // Selected (Other) carries no description; favor checked rows
355
+ // when budget pressure forces description rows to be dropped.
356
+ priority: isSelected ? 2 : checked.has(index) ? 1 : 0,
357
+ });
358
+ }
359
+ }
360
+ }
361
+
362
+ const trailingGap = window.gapBefore.get(options.length);
363
+ if (trailingGap !== undefined) emitGap(trailingGap);
364
+ rows.push({ text: "", priority: -1 });
365
+ rows.push({ text: "Enter your response:", priority: -1 });
366
+ return rows;
367
+ }
368
+
369
+ function applyCustomInputRowBudget(rows: CustomInputRow[], budget: number): CustomInputRow[] {
370
+ if (rows.length <= budget) return rows;
371
+ // Drop droppable rows lowest priority first; on ties, drop later rows first
372
+ // so the user still sees the earliest options' descriptions.
373
+ const droppable = rows
374
+ .map((row, index) => ({ row, index }))
375
+ .filter(entry => entry.row.priority >= 0)
376
+ .sort((a, b) => a.row.priority - b.row.priority || b.index - a.index);
377
+ const removed = new Set<number>();
378
+ for (const { index } of droppable) {
379
+ if (rows.length - removed.size <= budget) break;
380
+ removed.add(index);
381
+ }
382
+ return rows.filter((_, i) => !removed.has(i));
383
+ }
384
+
385
+ function formatCustomInputTitle(
386
+ question: string,
387
+ options: ExtensionUISelectItem[],
388
+ context: CustomInputContext,
389
+ ): string {
390
+ const contentWidth = customInputContentWidth();
391
+ const rows = buildCustomInputRows(question, options, context, contentWidth);
392
+ return applyCustomInputRowBudget(rows, MAX_CUSTOM_INPUT_TITLE_ROWS)
393
+ .map(row => row.text)
394
+ .join("\n");
395
+ }
396
+
397
+ // =============================================================================
398
+ // Question Selection Logic
399
+ // =============================================================================
400
+
401
+ interface SelectionResult {
402
+ selectedOptions: string[];
403
+ customInput?: string;
404
+ note?: string;
405
+ timedOut: boolean;
406
+ navigation?: "back" | "forward";
407
+ cancelled?: boolean;
408
+ }
409
+
410
+ interface NavigationControls {
411
+ allowBack: boolean;
412
+ allowForward: boolean;
413
+ progressText?: string;
414
+ }
415
+ interface AskSingleQuestionOptions {
416
+ recommended?: number;
417
+ timeout?: number;
418
+ signal?: AbortSignal;
419
+ initialSelection?: Pick<SelectionResult, "selectedOptions" | "customInput" | "note">;
420
+ navigation?: NavigationControls;
421
+ }
422
+
423
+ interface UIContext {
424
+ timeoutStartsOnPresentation?: boolean;
425
+ select(
426
+ prompt: string,
427
+ options: ExtensionUISelectItem[],
428
+ options_?: {
429
+ initialIndex?: number;
430
+ timeout?: number;
431
+ signal?: AbortSignal;
432
+ outline?: boolean;
433
+ onTimeout?: () => void;
434
+ onTimeoutStart?: () => void;
435
+ onTimeoutReset?: () => void;
436
+ onLeft?: () => void;
437
+ onRight?: () => void;
438
+ helpText?: string;
439
+ selectionMarker?: "radio" | "checkbox";
440
+ checkedIndices?: readonly number[];
441
+ markableCount?: number;
442
+ },
443
+ ): Promise<string | undefined>;
444
+ editor(
445
+ title: string,
446
+ prefill?: string,
447
+ dialogOptions?: { signal?: AbortSignal },
448
+ editorOptions?: { promptStyle?: boolean },
449
+ ): Promise<string | undefined>;
450
+ }
451
+
452
+ async function askSingleQuestion(
453
+ ui: UIContext,
454
+ question: string,
455
+ questionOptions: AskOption[],
456
+ multi: boolean,
457
+ options: AskSingleQuestionOptions = {},
458
+ ): Promise<SelectionResult> {
459
+ const { recommended, timeout, signal, initialSelection, navigation } = options;
460
+ const doneLabel = getDoneOptionLabel();
461
+ let selectedOptions = [...(initialSelection?.selectedOptions ?? [])];
462
+ let customInput = initialSelection?.customInput;
463
+ const note = initialSelection?.note;
464
+ let timedOut = false;
465
+
466
+ const selectOption = async (
467
+ prompt: string,
468
+ optionsToShow: ExtensionUISelectItem[],
469
+ initialIndex?: number,
470
+ marker?: { selectionMarker: "radio" | "checkbox"; checkedIndices?: readonly number[]; markableCount: number },
471
+ ): Promise<{ choice: string | undefined; timedOut: boolean; navigation?: "back" | "forward" }> => {
472
+ let timeoutTriggered = false;
473
+ const onTimeout = () => {
474
+ timeoutTriggered = true;
475
+ };
476
+ let navigationAction: "back" | "forward" | undefined;
477
+ const helpText = navigation
478
+ ? "up/down navigate enter select ←/→ question esc cancel"
479
+ : "up/down navigate enter select esc cancel";
480
+ const timeoutMs = typeof timeout === "number" && timeout > 0 ? timeout : undefined;
481
+ const timeoutController = timeoutMs === undefined ? undefined : new AbortController();
482
+ const dialogSignal =
483
+ signal && timeoutController
484
+ ? AbortSignal.any([signal, timeoutController.signal])
485
+ : (timeoutController?.signal ?? signal);
486
+ let timeoutId: NodeJS.Timeout | undefined;
487
+ let timeoutStartedMs = Date.now();
488
+ const armFallbackTimeout = (durationMs: number) => {
489
+ clearTimeout(timeoutId);
490
+ timeoutStartedMs = Date.now();
491
+ timeoutId = setTimeout(() => {
492
+ timeoutTriggered = true;
493
+ timeoutController?.abort();
494
+ }, durationMs);
495
+ };
496
+ const dialogOptions = {
497
+ initialIndex,
498
+ timeout,
499
+ signal: dialogSignal,
500
+ outline: true,
501
+ onTimeout,
502
+ onTimeoutStart: timeoutMs === undefined ? undefined : () => armFallbackTimeout(timeoutMs),
503
+ onTimeoutReset: timeoutMs === undefined ? undefined : () => armFallbackTimeout(timeoutMs),
504
+ helpText,
505
+ selectionMarker: marker?.selectionMarker,
506
+ checkedIndices: marker?.checkedIndices,
507
+ markableCount: marker?.markableCount,
508
+ onLeft: navigation?.allowBack
509
+ ? () => {
510
+ navigationAction = "back";
511
+ }
512
+ : undefined,
513
+ onRight: navigation?.allowForward
514
+ ? () => {
515
+ navigationAction = "forward";
516
+ }
517
+ : undefined,
518
+ };
519
+ try {
520
+ const runSelect = () => {
521
+ const selection = ui.select(prompt, optionsToShow, dialogOptions);
522
+ if (timeoutMs !== undefined && !ui.timeoutStartsOnPresentation) {
523
+ armFallbackTimeout(timeoutMs);
524
+ }
525
+ return selection;
526
+ };
527
+ const choice = dialogSignal ? await untilAborted(dialogSignal, runSelect) : await runSelect();
528
+ if (!timeoutTriggered && choice === undefined && typeof timeout === "number") {
529
+ // Fallback for UI surfaces that enforce `timeout` without invoking
530
+ // `onTimeout`: their auto-cancel resolves right at the deadline. A
531
+ // cancel arriving well past the deadline is a deliberate user Esc on
532
+ // a surface that kept the dialog open — keep treating it as a cancel.
533
+ const elapsed = Date.now() - timeoutStartedMs;
534
+ timeoutTriggered = elapsed >= timeout && elapsed <= timeout + TIMEOUT_DETECTION_TOLERANCE_MS;
535
+ }
536
+ return { choice, timedOut: timeoutTriggered, navigation: navigationAction };
537
+ } catch (error) {
538
+ if (timeoutTriggered && error instanceof Error && error.name === "AbortError") {
539
+ return { choice: undefined, timedOut: true, navigation: navigationAction };
540
+ }
541
+ throw error;
542
+ } finally {
543
+ clearTimeout(timeoutId);
544
+ }
545
+ };
546
+
547
+ const promptForCustomInput = async (
548
+ title: string,
549
+ optionsToShow: ExtensionUISelectItem[],
550
+ context: CustomInputContext,
551
+ ): Promise<{ input: string | undefined }> => {
552
+ const dialogOptions = signal ? { signal } : undefined;
553
+ const editorTitle = formatCustomInputTitle(title, optionsToShow, context);
554
+ const showCustomInput = () => ui.editor(editorTitle, undefined, dialogOptions, { promptStyle: true });
555
+ const input = signal ? await untilAborted(signal, showCustomInput) : await showCustomInput();
556
+ return { input };
557
+ };
558
+
559
+ const promptWithProgress = navigation?.progressText ? `${question} (${navigation.progressText})` : question;
560
+ if (multi) {
561
+ const selected = new Set<string>(selectedOptions);
562
+ let cursorIndex = Math.min(Math.max(recommended ?? 0, 0), Math.max(questionOptions.length - 1, 0));
563
+ const firstSelected = selectedOptions[0];
564
+ if (firstSelected) {
565
+ const selectedIndex = questionOptions.findIndex(option => option.label === firstSelected);
566
+ if (selectedIndex >= 0) cursorIndex = selectedIndex;
567
+ }
568
+ while (true) {
569
+ const opts: ExtensionUISelectItem[] = questionOptions.map(opt => toSelectOption(opt));
570
+
571
+ if (!navigation?.allowForward && selected.size > 0) {
572
+ opts.push(doneLabel);
573
+ }
574
+ opts.push(OTHER_OPTION);
575
+
576
+ const checkedIndices: number[] = [];
577
+ for (let i = 0; i < questionOptions.length; i++) {
578
+ if (selected.has(questionOptions[i]!.label)) checkedIndices.push(i);
579
+ }
580
+ const prefix = selected.size > 0 ? `(${selected.size} selected) ` : "";
581
+ const {
582
+ choice,
583
+ timedOut: selectTimedOut,
584
+ navigation: arrowNavigation,
585
+ } = await selectOption(`${prefix}${promptWithProgress}`, opts, cursorIndex, {
586
+ selectionMarker: "checkbox",
587
+ checkedIndices,
588
+ markableCount: questionOptions.length,
589
+ });
590
+
591
+ if (arrowNavigation) {
592
+ return { selectedOptions: Array.from(selected), customInput, note, timedOut, navigation: arrowNavigation };
593
+ }
594
+ if (choice === undefined) {
595
+ if (selectTimedOut) {
596
+ timedOut = true;
597
+ break;
598
+ }
599
+ return { selectedOptions: Array.from(selected), customInput, note, timedOut, cancelled: true };
600
+ }
601
+ if (choice === doneLabel) break;
602
+
603
+ if (choice === OTHER_OPTION) {
604
+ if (selectTimedOut) {
605
+ timedOut = true;
606
+ break;
607
+ }
608
+ const customResult = await promptForCustomInput(`${prefix}${promptWithProgress}`, opts, {
609
+ selectionMarker: "checkbox",
610
+ checkedIndices,
611
+ markableCount: questionOptions.length,
612
+ });
613
+ if (customResult.input === undefined) {
614
+ continue;
615
+ }
616
+ customInput = customResult.input;
617
+ break;
618
+ }
619
+
620
+ const selectedIdx = opts.findIndex(opt => getSelectOptionLabel(opt) === choice);
621
+ if (selectedIdx >= 0) {
622
+ cursorIndex = selectedIdx;
623
+ }
624
+
625
+ if (selected.has(choice)) {
626
+ selected.delete(choice);
627
+ } else {
628
+ selected.add(choice);
629
+ }
630
+
631
+ if (selectTimedOut) {
632
+ timedOut = true;
633
+ break;
634
+ }
635
+ }
636
+ selectedOptions = Array.from(selected);
637
+ } else {
638
+ while (true) {
639
+ const displayOptions = addRecommendedSuffix(questionOptions, recommended);
640
+ const optionsWithNavigation: ExtensionUISelectItem[] = [...displayOptions, OTHER_OPTION];
641
+
642
+ let initialIndex = recommended;
643
+ const previouslySelected = selectedOptions[0];
644
+ if (previouslySelected) {
645
+ const selectedIndex = questionOptions.findIndex(option => option.label === previouslySelected);
646
+ if (selectedIndex >= 0) initialIndex = selectedIndex;
647
+ } else if (customInput !== undefined) {
648
+ initialIndex = displayOptions.length;
649
+ }
650
+ if (initialIndex !== undefined) {
651
+ const maxIndex = Math.max(optionsWithNavigation.length - 1, 0);
652
+ initialIndex = Math.max(0, Math.min(initialIndex, maxIndex));
653
+ }
654
+
655
+ const {
656
+ choice,
657
+ timedOut: selectTimedOut,
658
+ navigation: arrowNavigation,
659
+ } = await selectOption(promptWithProgress, optionsWithNavigation, initialIndex, {
660
+ selectionMarker: "radio",
661
+ markableCount: displayOptions.length,
662
+ });
663
+ timedOut = selectTimedOut;
664
+
665
+ if (arrowNavigation) {
666
+ return { selectedOptions, customInput, note, timedOut, navigation: arrowNavigation };
667
+ }
668
+ if (choice === undefined) {
669
+ if (!timedOut) {
670
+ return { selectedOptions, customInput, note, timedOut, cancelled: true };
671
+ }
672
+ break;
673
+ }
674
+ if (choice === OTHER_OPTION) {
675
+ if (selectTimedOut) {
676
+ break;
677
+ }
678
+ const customResult = await promptForCustomInput(promptWithProgress, optionsWithNavigation, {
679
+ selectionMarker: "radio",
680
+ markableCount: displayOptions.length,
681
+ });
682
+ if (customResult.input === undefined) {
683
+ continue;
684
+ }
685
+ customInput = customResult.input;
686
+ selectedOptions = [];
687
+ break;
688
+ }
689
+ selectedOptions = [stripRecommendedSuffix(choice)];
690
+ customInput = undefined;
691
+ break;
692
+ }
693
+ if (timedOut && selectedOptions.length === 0 && customInput === undefined) {
694
+ selectedOptions = getAutoSelectionOnTimeout(questionOptions, recommended);
695
+ }
696
+ if (navigation?.allowForward) {
697
+ return { selectedOptions, customInput, note, timedOut, navigation: "forward" };
698
+ }
699
+ }
700
+
701
+ if (timedOut && selectedOptions.length === 0 && customInput === undefined) {
702
+ selectedOptions = getAutoSelectionOnTimeout(questionOptions, recommended);
703
+ }
704
+
705
+ return { selectedOptions, customInput, note, timedOut };
706
+ }
707
+
708
+ function formatQuestionResult(result: QuestionResult): string {
709
+ const noteSuffix = result.note ? ` (note: ${result.note})` : "";
710
+ if (result.customInput !== undefined) {
711
+ return `${result.id}: "${result.customInput}"${noteSuffix}`;
712
+ }
713
+ if (result.selectedOptions.length > 0) {
714
+ const suffix = `${result.timedOut ? " (auto-selected after timeout)" : ""}${noteSuffix}`;
715
+ return result.multi
716
+ ? `${result.id}: [${result.selectedOptions.join(", ")}]${suffix}`
717
+ : `${result.id}: ${result.selectedOptions[0]}${suffix}`;
718
+ }
719
+ return `${result.id}: (cancelled)${noteSuffix}`;
720
+ }
721
+
722
+ function formatSingleQuestionResponse(result: {
723
+ selectedOptions: string[];
724
+ customInput?: string;
725
+ note?: string;
726
+ timedOut?: boolean;
727
+ multi: boolean;
728
+ }): string {
729
+ const responseParts: string[] = [];
730
+ if (result.selectedOptions.length > 0) {
731
+ const selectedText = result.multi
732
+ ? `User selected: ${result.selectedOptions.join(", ")}`
733
+ : `User selected: ${result.selectedOptions[0]}`;
734
+ responseParts.push(result.timedOut ? `${selectedText} (auto-selected after timeout)` : selectedText);
735
+ }
736
+ if (result.customInput !== undefined) {
737
+ responseParts.push(
738
+ result.customInput.includes("\n")
739
+ ? `User provided custom input:\n${result.customInput
740
+ .split("\n")
741
+ .map(line => ` ${line}`)
742
+ .join("\n")}`
743
+ : `User provided custom input: ${result.customInput}`,
744
+ );
745
+ }
746
+ if (result.note) {
747
+ responseParts.push(
748
+ result.note.includes("\n")
749
+ ? `User added note:\n${result.note
750
+ .split("\n")
751
+ .map(line => ` ${line}`)
752
+ .join("\n")}`
753
+ : `User added note: ${result.note}`,
754
+ );
755
+ }
756
+ return responseParts.length > 0 ? responseParts.join("\n") : "User cancelled the selection";
757
+ }
758
+
759
+ // =============================================================================
760
+ // Tool Class
761
+ // =============================================================================
762
+
763
+ type AskParams = AskToolInput;
764
+
765
+ /**
766
+ * Ask tool for interactive user prompting during execution.
767
+ *
768
+ * Allows gathering user preferences, clarifying instructions, and getting decisions
769
+ * on implementation choices as the agent works.
770
+ */
771
+ export class AskTool implements AgentTool<typeof askSchema, AskToolDetails> {
772
+ readonly name = "ask";
773
+ readonly approval = "read" as const;
774
+ readonly label = "Ask";
775
+ readonly summary = "Ask the user a clarifying question";
776
+ readonly description: string;
777
+ readonly parameters = askSchema;
778
+ readonly strict = true;
779
+
780
+ readonly examples: readonly ToolExample<typeof askSchema.infer>[] = [
781
+ {
782
+ caption: "Single question",
783
+ call: {
784
+ questions: [
785
+ {
786
+ id: "auth_method",
787
+ question: "Which authentication method should this API use?",
788
+ options: [
789
+ { label: "JWT", description: "Bearer tokens for stateless API clients." },
790
+ { label: "OAuth2", description: "Delegated authorization with external identity providers." },
791
+ {
792
+ label: "Session cookies",
793
+ description: "Browser-first authentication backed by server-side sessions.",
794
+ },
795
+ ],
796
+ recommended: 0,
797
+ },
798
+ ],
799
+ },
800
+ },
801
+ {
802
+ caption: "Multiple questions",
803
+ call: {
804
+ questions: [
805
+ {
806
+ id: "storage_type",
807
+ question: "Which storage backend?",
808
+ options: [{ label: "SQLite" }, { label: "PostgreSQL" }],
809
+ },
810
+ {
811
+ id: "auth_method",
812
+ question: "Which auth method?",
813
+ options: [{ label: "JWT" }, { label: "Session cookies" }],
814
+ },
815
+ ],
816
+ },
817
+ },
818
+ ];
819
+ // Run alone in its tool batch. The interactive selector/editor is a single
820
+ // shared UI surface (`ExtensionUiController.showHookSelector` has no queue and
821
+ // overwrites `ctx.hookSelector` on each call), so two concurrent `ask` calls
822
+ // would clobber each other: the second steals focus and orphans the first,
823
+ // whose promise then hangs until the user aborts the whole turn.
824
+ readonly concurrency = "exclusive";
825
+ readonly loadMode = "discoverable";
826
+
827
+ constructor(private readonly session: ToolSession) {
828
+ this.description = prompt.render(askDescription);
829
+ }
830
+
831
+ static createIf(session: ToolSession): AskTool | null {
832
+ return session.hasUI ? new AskTool(session) : null;
833
+ }
834
+
835
+ /** Send terminal notification when ask tool is waiting for input */
836
+ #sendAskNotification(): void {
837
+ const method = this.session.settings.get("ask.notify");
838
+ if (method === "off") return;
839
+ TERMINAL.sendNotification({
840
+ title: "Oh My Pi",
841
+ body: "Waiting for input",
842
+ type: "ask",
843
+ urgency: "normal",
844
+ actions: "focus",
845
+ });
846
+ }
847
+
848
+ async execute(
849
+ _toolCallId: string,
850
+ params: AskParams,
851
+ signal?: AbortSignal,
852
+ _onUpdate?: AgentToolUpdateCallback<AskToolDetails>,
853
+ context?: AgentToolContext,
854
+ ): Promise<AgentToolResult<AskToolDetails>> {
855
+ // Headless fallback
856
+ if (!context?.hasUI || !context.ui) {
857
+ context?.abort();
858
+ throw new ToolAbortError("Ask tool requires interactive mode");
859
+ }
860
+
861
+ const extensionUi = context.ui;
862
+ const ui: UIContext = {
863
+ timeoutStartsOnPresentation: extensionUi.timeoutStartsOnPresentation,
864
+ select: (prompt, options, dialogOptions) => extensionUi.select(prompt, options, dialogOptions),
865
+ editor: (title, prefill, dialogOptions, editorOptions) =>
866
+ extensionUi.editor(title, prefill, dialogOptions, editorOptions),
867
+ };
868
+
869
+ // Determine timeout based on settings and plan mode
870
+ const planModeEnabled = this.session.getPlanModeState?.()?.enabled ?? false;
871
+ // Settings.get("ask.timeout") returns seconds (0 = disabled), convert to ms
872
+ const timeoutSeconds = this.session.settings.get("ask.timeout");
873
+ const settingsTimeout = timeoutSeconds === 0 ? null : timeoutSeconds * 1000;
874
+ const timeout = planModeEnabled ? null : settingsTimeout;
875
+
876
+ // Send notification if waiting and not suppressed
877
+ this.#sendAskNotification();
878
+
879
+ if (params.questions.length === 0) {
880
+ return {
881
+ content: [{ type: "text" as const, text: "Error: questions must not be empty" }],
882
+ details: {},
883
+ };
884
+ }
885
+
886
+ // Speak the question(s) aloud before surfacing them. Ask vocalizes in every
887
+ // mode — it's the assistant addressing the user — gated only by speech.enabled
888
+ // (the vocalizer re-checks the setting and no-ops when disabled).
889
+ if (this.session.settings.get("speech.enabled")) {
890
+ vocalizer.speak(params.questions.map(q => q.question).join("\n"));
891
+ }
892
+
893
+ const richAskDialog = extensionUi.askDialog;
894
+ if (richAskDialog) {
895
+ try {
896
+ const showRichDialog = () =>
897
+ richAskDialog(
898
+ params.questions.map(q => ({
899
+ id: q.id,
900
+ question: q.question,
901
+ ...(q.header?.trim() ? { header: q.header } : {}),
902
+ options: q.options.map(option => ({
903
+ label: option.label,
904
+ ...(option.description?.trim() ? { description: option.description.trim() } : {}),
905
+ ...(option.preview?.trim() ? { preview: option.preview } : {}),
906
+ })),
907
+ ...(q.multi !== undefined ? { multi: q.multi } : {}),
908
+ ...(q.recommended !== undefined ? { recommended: q.recommended } : {}),
909
+ })),
910
+ { timeout: timeout ?? undefined, signal },
911
+ );
912
+ const richResult = signal ? await untilAborted(signal, showRichDialog) : await showRichDialog();
913
+ if (!richResult) {
914
+ context.abort();
915
+ throw new ToolAbortError("Ask tool was cancelled by the user");
916
+ }
917
+ if (richResult.kind === "chat") {
918
+ const questionText = params.questions.map(q => q.question).join("\n");
919
+ return {
920
+ content: [
921
+ {
922
+ type: "text" as const,
923
+ text: `User chose to chat about this instead of answering.\n\nQuestions asked:\n${questionText}`,
924
+ },
925
+ ],
926
+ details: { chatRedirect: true, questions: params.questions.map(q => q.question) },
927
+ };
928
+ }
929
+ if (richResult.results.length !== params.questions.length) {
930
+ throw new Error("Ask dialog returned a result count that does not match the requested questions");
931
+ }
932
+ const results: QuestionResult[] = [];
933
+ for (let index = 0; index < params.questions.length; index++) {
934
+ const question = params.questions[index];
935
+ const result = richResult.results[index];
936
+ if (!question || !result || result.id !== question.id) {
937
+ throw new Error("Ask dialog returned results that do not match the requested question order");
938
+ }
939
+ results.push({
940
+ id: question.id,
941
+ question: question.question,
942
+ options: question.options.map(option => option.label),
943
+ multi: question.multi ?? false,
944
+ selectedOptions: result.selectedOptions,
945
+ customInput: result.customInput,
946
+ note: result.note,
947
+ timedOut: result.timedOut,
948
+ });
949
+ }
950
+ if (params.questions.length === 1) {
951
+ const result = results[0];
952
+ if (
953
+ !result ||
954
+ (!result.timedOut && result.selectedOptions.length === 0 && result.customInput === undefined)
955
+ ) {
956
+ context.abort();
957
+ throw new ToolAbortError("Ask tool was cancelled by the user");
958
+ }
959
+ const details: AskToolDetails = {
960
+ question: result.question,
961
+ options: result.options,
962
+ multi: result.multi,
963
+ selectedOptions: result.selectedOptions,
964
+ customInput: result.customInput,
965
+ note: result.note,
966
+ timedOut: result.timedOut,
967
+ };
968
+ const responseText = formatSingleQuestionResponse(result);
969
+ return { content: [{ type: "text" as const, text: responseText }], details };
970
+ }
971
+ const details: AskToolDetails = { results };
972
+ const responseText = `User answers:\n${results.map(formatQuestionResult).join("\n")}`;
973
+ return { content: [{ type: "text" as const, text: responseText }], details };
974
+ } catch (error) {
975
+ if (error instanceof Error && error.name === "AbortError") {
976
+ throw new ToolAbortError("Ask input was cancelled");
977
+ }
978
+ throw error;
979
+ }
980
+ }
981
+
982
+ const askQuestion = async (
983
+ q: AskParams["questions"][number],
984
+ options?: { previous?: QuestionResult; navigation?: NavigationControls },
985
+ ) => {
986
+ const questionOptions = q.options.map(option => ({
987
+ label: option.label,
988
+ ...(option.description?.trim() ? { description: option.description.trim() } : {}),
989
+ }));
990
+ const optionLabels = questionOptions.map(getAskOptionLabel);
991
+ try {
992
+ const { selectedOptions, customInput, note, navigation, cancelled, timedOut } = await askSingleQuestion(
993
+ ui,
994
+ q.question,
995
+ questionOptions,
996
+ q.multi ?? false,
997
+ {
998
+ recommended: q.recommended,
999
+ timeout: timeout ?? undefined,
1000
+ signal,
1001
+ initialSelection: options?.previous,
1002
+ navigation: options?.navigation,
1003
+ },
1004
+ );
1005
+ return { optionLabels, selectedOptions, customInput, note, navigation, cancelled, timedOut };
1006
+ } catch (error) {
1007
+ if (error instanceof Error && error.name === "AbortError") {
1008
+ throw new ToolAbortError("Ask input was cancelled");
1009
+ }
1010
+ throw error;
1011
+ }
1012
+ };
1013
+
1014
+ if (params.questions.length === 1) {
1015
+ const [q] = params.questions;
1016
+ const { optionLabels, selectedOptions, customInput, note, cancelled, timedOut } = await askQuestion(q);
1017
+
1018
+ if (!timedOut && (cancelled || (selectedOptions.length === 0 && customInput === undefined))) {
1019
+ context.abort();
1020
+ throw new ToolAbortError("Ask tool was cancelled by the user");
1021
+ }
1022
+ const details: AskToolDetails = {
1023
+ question: q.question,
1024
+ options: optionLabels,
1025
+ multi: q.multi ?? false,
1026
+ selectedOptions,
1027
+ customInput,
1028
+ note,
1029
+ timedOut: timedOut || undefined,
1030
+ };
1031
+
1032
+ const responseText = formatSingleQuestionResponse({
1033
+ selectedOptions,
1034
+ customInput,
1035
+ note,
1036
+ timedOut: timedOut || undefined,
1037
+ multi: q.multi ?? false,
1038
+ });
1039
+
1040
+ return { content: [{ type: "text" as const, text: responseText }], details };
1041
+ }
1042
+
1043
+ const resultsByIndex: Array<QuestionResult | undefined> = Array.from({ length: params.questions.length });
1044
+ let questionIndex = 0;
1045
+ while (questionIndex < params.questions.length) {
1046
+ const q = params.questions[questionIndex];
1047
+ if (!q) throw new Error("Ask question index exceeded the requested question list");
1048
+ const previous = resultsByIndex[questionIndex];
1049
+ const navigation: NavigationControls = {
1050
+ allowBack: questionIndex > 0,
1051
+ allowForward: true,
1052
+ progressText: `${questionIndex + 1}/${params.questions.length}`,
1053
+ };
1054
+ const {
1055
+ optionLabels,
1056
+ selectedOptions,
1057
+ customInput,
1058
+ note,
1059
+ navigation: navAction,
1060
+ cancelled,
1061
+ timedOut,
1062
+ } = await askQuestion(q, { previous, navigation });
1063
+
1064
+ if (cancelled && !timedOut) {
1065
+ context.abort();
1066
+ throw new ToolAbortError("Ask tool was cancelled by the user");
1067
+ }
1068
+
1069
+ resultsByIndex[questionIndex] = {
1070
+ id: q.id,
1071
+ question: q.question,
1072
+ options: optionLabels,
1073
+ multi: q.multi ?? false,
1074
+ selectedOptions,
1075
+ customInput,
1076
+ note,
1077
+ timedOut: timedOut || undefined,
1078
+ };
1079
+
1080
+ if (navAction === "back") {
1081
+ questionIndex = Math.max(0, questionIndex - 1);
1082
+ continue;
1083
+ }
1084
+
1085
+ questionIndex += 1;
1086
+ }
1087
+
1088
+ const results = params.questions.map((q, index) => {
1089
+ const result = resultsByIndex[index];
1090
+ if (result) return result;
1091
+ return {
1092
+ id: q.id,
1093
+ question: q.question,
1094
+ options: q.options.map(o => o.label),
1095
+ multi: q.multi ?? false,
1096
+ selectedOptions: [],
1097
+ };
1098
+ });
1099
+
1100
+ const details: AskToolDetails = { results };
1101
+ const responseLines = results.map(formatQuestionResult);
1102
+ const responseText = `User answers:\n${responseLines.join("\n")}`;
1103
+
1104
+ return { content: [{ type: "text" as const, text: responseText }], details };
1105
+ }
1106
+ }
1107
+
1108
+ // =============================================================================
1109
+ // TUI Renderer
1110
+ // =============================================================================
1111
+
1112
+ interface AskRenderOption {
1113
+ label: string;
1114
+ description?: string;
1115
+ }
1116
+
1117
+ interface AskRenderArgs {
1118
+ question?: string;
1119
+ options?: AskRenderOption[];
1120
+ multi?: boolean;
1121
+ questions?: Array<{
1122
+ id: string;
1123
+ question: string;
1124
+ options: AskRenderOption[];
1125
+ multi?: boolean;
1126
+ }>;
1127
+ }
1128
+
1129
+ /**
1130
+ * Coerce an untrusted option list (streamed or model-mangled call args) into
1131
+ * well-formed render options. Bare strings become labels; entries without a
1132
+ * string label are dropped.
1133
+ */
1134
+ function normalizeRenderOptions(raw: unknown): AskRenderOption[] | undefined {
1135
+ if (!Array.isArray(raw)) return undefined;
1136
+ const out: AskRenderOption[] = [];
1137
+ for (const entry of raw) {
1138
+ if (typeof entry === "string") {
1139
+ out.push({ label: entry });
1140
+ continue;
1141
+ }
1142
+ if (!entry || typeof entry !== "object") continue;
1143
+ const { label, description } = entry as Partial<AskRenderOption>;
1144
+ if (typeof label !== "string") continue;
1145
+ out.push(typeof description === "string" ? { label, description } : { label });
1146
+ }
1147
+ return out;
1148
+ }
1149
+
1150
+ /**
1151
+ * Coerce untrusted `questions` call args into a renderable array. Models
1152
+ * occasionally double-encode the array as a JSON string — a bare string passes
1153
+ * a truthy `.length` check but has no `.map`, which used to crash the TUI
1154
+ * render loop. Partially streamed args can also be missing fields.
1155
+ */
1156
+ function normalizeRenderQuestions(raw: unknown): NonNullable<AskRenderArgs["questions"]> | undefined {
1157
+ if (typeof raw === "string") {
1158
+ try {
1159
+ raw = JSON.parse(raw);
1160
+ } catch {
1161
+ return undefined;
1162
+ }
1163
+ }
1164
+ if (!Array.isArray(raw)) return undefined;
1165
+ const out: NonNullable<AskRenderArgs["questions"]> = [];
1166
+ for (const entry of raw) {
1167
+ if (!entry || typeof entry !== "object") continue;
1168
+ const q = entry as Partial<NonNullable<AskRenderArgs["questions"]>[number]>;
1169
+ out.push({
1170
+ id: typeof q.id === "string" ? q.id : "?",
1171
+ question: typeof q.question === "string" ? q.question : "",
1172
+ options: normalizeRenderOptions(q.options) ?? [],
1173
+ multi: q.multi === true,
1174
+ });
1175
+ }
1176
+ return out;
1177
+ }
1178
+
1179
+ /** Render a custom free-text answer as a status line plus indented continuation rows. */
1180
+ function renderCustomInputLines(uiTheme: Theme, customInput: string): string[] {
1181
+ const lines = customInput.split("\n");
1182
+ const out: string[] = [
1183
+ ` ${uiTheme.styledSymbol("status.success", "success")} ${uiTheme.fg("toolOutput", lines[0] ?? "")}`,
1184
+ ];
1185
+ for (let i = 1; i < lines.length; i++) out.push(` ${uiTheme.fg("toolOutput", lines[i])}`);
1186
+ return out;
1187
+ }
1188
+
1189
+ /** Render an answer note with tab replacement and line-width clamping. */
1190
+ function renderNoteLines(uiTheme: Theme, note: string, width: number): string[] {
1191
+ const prefix = " Note: ";
1192
+ const continuationPrefix = " ";
1193
+ const firstLineWidth = Math.max(1, width - visibleWidth(prefix));
1194
+ const continuationWidth = Math.max(1, width - visibleWidth(continuationPrefix));
1195
+ return replaceTabs(note)
1196
+ .split("\n")
1197
+ .map((line, index) => {
1198
+ const linePrefix = index === 0 ? `${uiTheme.fg("dim", " Note:")} ` : continuationPrefix;
1199
+ const maxWidth = index === 0 ? firstLineWidth : continuationWidth;
1200
+ return `${linePrefix}${uiTheme.fg("toolOutput", truncateToWidth(line, maxWidth))}`;
1201
+ });
1202
+ }
1203
+
1204
+ /**
1205
+ * Marker glyph for a question option. Single-choice questions render circular radio
1206
+ * buttons (pick one); multi-select questions render rectangular checkboxes (pick many).
1207
+ */
1208
+ function optionMarker(uiTheme: Theme, multi: boolean | undefined, selected: boolean): string {
1209
+ if (multi) return selected ? uiTheme.checkbox.checked : uiTheme.checkbox.unchecked;
1210
+ return selected ? uiTheme.radio.selected : uiTheme.radio.unselected;
1211
+ }
1212
+
1213
+ /** Render the offered options for a question form as flat marker bullets (no tree guides). */
1214
+ function renderQuestionOptionLines(
1215
+ uiTheme: Theme,
1216
+ mdTheme: MarkdownTheme,
1217
+ options: AskRenderOption[],
1218
+ multi: boolean | undefined,
1219
+ ): string[] {
1220
+ const out: string[] = [];
1221
+ for (const opt of options) {
1222
+ const optLabel = renderInlineMarkdown(opt.label, mdTheme, t => uiTheme.fg("muted", t));
1223
+ out.push(` ${uiTheme.fg("dim", optionMarker(uiTheme, multi, false))} ${optLabel}`);
1224
+ if (opt.description?.trim()) {
1225
+ const description = renderInlineMarkdown(opt.description.trim(), mdTheme, t => uiTheme.fg("dim", t));
1226
+ out.push(` ${uiTheme.fg("dim", "↳")} ${description}`);
1227
+ }
1228
+ }
1229
+ return out;
1230
+ }
1231
+
1232
+ /**
1233
+ * Render the answered option list for a question: every offered option with its
1234
+ * selection marker filled in, plus any custom free-text answer. Flat marker
1235
+ * bullets — the frame is the container, so no tree guides are drawn.
1236
+ */
1237
+ function renderAnswerOptionLines(
1238
+ uiTheme: Theme,
1239
+ mdTheme: MarkdownTheme,
1240
+ options: string[] | undefined,
1241
+ selectedOptions: string[] | undefined,
1242
+ multi: boolean | undefined,
1243
+ customInput: string | undefined,
1244
+ note: string | undefined,
1245
+ width: number,
1246
+ ): string[] {
1247
+ const selected = new Set(selectedOptions ?? []);
1248
+ // Prefer the full recorded option set; fall back to the selected labels when
1249
+ // details omit the options array.
1250
+ const list = options && options.length > 0 ? options : (selectedOptions ?? []);
1251
+
1252
+ // Nothing was chosen (and no custom answer) → a lone cancelled marker.
1253
+ if (selected.size === 0 && customInput === undefined && note === undefined) {
1254
+ return [` ${uiTheme.styledSymbol("status.warning", "warning")} ${uiTheme.fg("warning", "Cancelled")}`];
1255
+ }
1256
+
1257
+ const out: string[] = [];
1258
+ for (const label of list) {
1259
+ const isSelected = selected.has(label);
1260
+ const marker = optionMarker(uiTheme, multi, isSelected);
1261
+ const markerStyled = isSelected ? uiTheme.fg("success", marker) : uiTheme.fg("dim", marker);
1262
+ const labelStyled = renderInlineMarkdown(label, mdTheme, t =>
1263
+ isSelected ? uiTheme.fg("toolOutput", t) : uiTheme.fg("muted", t),
1264
+ );
1265
+ out.push(` ${markerStyled} ${labelStyled}`);
1266
+ }
1267
+ if (customInput !== undefined) out.push(...renderCustomInputLines(uiTheme, customInput));
1268
+ if (note !== undefined) out.push(...renderNoteLines(uiTheme, note, width));
1269
+ return out;
1270
+ }
1271
+
1272
+ export const askToolRenderer = {
1273
+ mergeCallAndResult: true,
1274
+ renderCall(args: AskRenderArgs, _options: RenderResultOptions, uiTheme: Theme): Component {
1275
+ const label = formatTitle("Ask", uiTheme);
1276
+ const mdTheme = getMarkdownTheme();
1277
+ const accentStyle = { color: (t: string) => uiTheme.fg("accent", t) };
1278
+ const md = (text: string, width: number) =>
1279
+ new Markdown(text, 1, 0, mdTheme, accentStyle).render(Math.max(1, outputBlockContentWidth(width) + 1));
1280
+
1281
+ // Multi-part questions: one divider-labelled section per question.
1282
+ // Call args are untrusted (partially streamed or model-mangled) and a
1283
+ // throw here takes down the whole TUI render loop — normalize first.
1284
+ const questions = normalizeRenderQuestions(args.questions);
1285
+ if (questions && questions.length > 0) {
1286
+ const header = `${label} ${uiTheme.fg("muted", `${questions.length} questions`)}`;
1287
+ return framedBlock(uiTheme, width => {
1288
+ const sections = questions.map(q => {
1289
+ const meta: string[] = [];
1290
+ if (q.multi) meta.push("multi");
1291
+ if (q.options?.length) meta.push(`options:${q.options.length}`);
1292
+ const metaStr = meta.length > 0 ? uiTheme.fg("dim", ` · ${meta.join(" · ")}`) : "";
1293
+ // md() returns a shared cached array (module-level Markdown LRU) — copy before appending.
1294
+ const mdLines = md(q.question, width);
1295
+ const lines = q.options?.length
1296
+ ? [...mdLines, ...renderQuestionOptionLines(uiTheme, mdTheme, q.options, q.multi)]
1297
+ : mdLines;
1298
+ return { label: `${uiTheme.fg("dim", `[${q.id}]`)}${metaStr}`, lines };
1299
+ });
1300
+ return { header, sections, state: "pending", borderColor: "borderMuted", width };
1301
+ });
1302
+ }
1303
+
1304
+ // Single question
1305
+ if (typeof args.question !== "string" || !args.question) {
1306
+ const errorLine = formatErrorMessage("No question provided", uiTheme);
1307
+ return framedBlock(uiTheme, width => ({
1308
+ header: errorLine,
1309
+ sections: [],
1310
+ state: "error",
1311
+ borderColor: "error",
1312
+ width,
1313
+ }));
1314
+ }
1315
+
1316
+ const question = args.question;
1317
+ const meta: string[] = [];
1318
+ if (args.multi) meta.push("multi");
1319
+ const questionOptions = normalizeRenderOptions(args.options);
1320
+ if (questionOptions?.length) meta.push(`options:${questionOptions.length}`);
1321
+ const header = `${label}${formatMeta(meta, uiTheme)}`;
1322
+ const multi = args.multi;
1323
+ return framedBlock(uiTheme, width => {
1324
+ // md() returns a shared cached array (module-level Markdown LRU) — copy before appending.
1325
+ const mdLines = md(question, width);
1326
+ const bodyLines = questionOptions?.length
1327
+ ? [...mdLines, ...renderQuestionOptionLines(uiTheme, mdTheme, questionOptions, multi)]
1328
+ : mdLines;
1329
+ return {
1330
+ header,
1331
+ sections: bodyLines.length > 0 ? [{ lines: bodyLines }] : [],
1332
+ state: "pending",
1333
+ borderColor: "borderMuted",
1334
+ width,
1335
+ };
1336
+ });
1337
+ },
1338
+
1339
+ renderResult(
1340
+ result: { content: Array<{ type: string; text?: string }>; details?: AskToolDetails },
1341
+ _options: RenderResultOptions,
1342
+ uiTheme: Theme,
1343
+ ): Component {
1344
+ const { details } = result;
1345
+ const mdTheme = getMarkdownTheme();
1346
+ const accentStyle = { color: (t: string) => uiTheme.fg("accent", t) };
1347
+ const md = (text: string, width: number) =>
1348
+ new Markdown(text, 1, 0, mdTheme, accentStyle).render(Math.max(1, outputBlockContentWidth(width) + 1));
1349
+
1350
+ if (!details) {
1351
+ const txt = result.content[0];
1352
+ const fallback = txt?.type === "text" && txt.text ? txt.text : "";
1353
+ const header = renderStatusLine({ icon: "warning", title: "Ask" }, uiTheme);
1354
+ const body = fallback ? `\n${uiTheme.fg("dim", fallback)}` : "";
1355
+ return new Text(`${header}${body}`, 0, 0);
1356
+ }
1357
+
1358
+ // Chat redirect: user chose "Chat about this" instead of answering.
1359
+ if (details.chatRedirect) {
1360
+ const header = renderStatusLine({ icon: "info", title: "Ask", meta: ["chat redirect"] }, uiTheme);
1361
+ const questions = details.questions ?? [];
1362
+ return framedBlock(uiTheme, width => ({
1363
+ header,
1364
+ sections: questions.length > 0 ? [{ lines: questions.flatMap(q => md(q, width)) }] : [],
1365
+ state: "warning",
1366
+ borderColor: "borderMuted",
1367
+ width,
1368
+ }));
1369
+ }
1370
+
1371
+ // Multi-part results: one divider-labelled section per question.
1372
+ if (details.results && details.results.length > 0) {
1373
+ const results = details.results;
1374
+ const hasAnySelection = results.some(
1375
+ r =>
1376
+ r.customInput !== undefined ||
1377
+ r.note !== undefined ||
1378
+ (r.selectedOptions && r.selectedOptions.length > 0),
1379
+ );
1380
+ const header = renderStatusLine(
1381
+ {
1382
+ icon: hasAnySelection ? "success" : "warning",
1383
+ title: "Ask",
1384
+ meta: [`${results.length} questions`],
1385
+ },
1386
+ uiTheme,
1387
+ );
1388
+ return framedBlock(uiTheme, width => {
1389
+ const sections = results.map(r => {
1390
+ // md() returns a shared cached array (module-level Markdown LRU) — copy before appending.
1391
+ const lines = [
1392
+ ...md(r.question, width),
1393
+ ...renderAnswerOptionLines(
1394
+ uiTheme,
1395
+ mdTheme,
1396
+ r.options,
1397
+ r.selectedOptions,
1398
+ r.multi,
1399
+ r.customInput,
1400
+ r.note,
1401
+ width,
1402
+ ),
1403
+ ];
1404
+ return { label: uiTheme.fg("dim", `[${r.id}]`), lines };
1405
+ });
1406
+ return {
1407
+ header,
1408
+ sections,
1409
+ state: hasAnySelection ? "success" : "warning",
1410
+ borderColor: "borderMuted",
1411
+ width,
1412
+ };
1413
+ });
1414
+ }
1415
+
1416
+ // Single question result
1417
+ if (!details.question) {
1418
+ const txt = result.content[0];
1419
+ const fallback = txt?.type === "text" && txt.text ? txt.text : "";
1420
+ return new Text(fallback, 0, 0);
1421
+ }
1422
+
1423
+ const question = details.question;
1424
+ const hasSelection =
1425
+ details.customInput !== undefined ||
1426
+ details.note !== undefined ||
1427
+ (details.selectedOptions && details.selectedOptions.length > 0);
1428
+ const header = renderStatusLine(
1429
+ hasSelection
1430
+ ? { iconOverride: uiTheme.styledSymbol("tool.ask", "accent"), title: "Ask" }
1431
+ : { icon: "warning", title: "Ask" },
1432
+ uiTheme,
1433
+ );
1434
+ const dOptions = details.options;
1435
+ const dSelected = details.selectedOptions;
1436
+ const dMulti = details.multi;
1437
+ const dCustom = details.customInput;
1438
+ const dNote = details.note;
1439
+ const dTimedOut = details.timedOut;
1440
+ return framedBlock(uiTheme, width => {
1441
+ // md() returns a shared cached array (module-level Markdown LRU) — copy before appending.
1442
+ const bodyLines = [
1443
+ ...md(question, width),
1444
+ ...renderAnswerOptionLines(uiTheme, mdTheme, dOptions, dSelected, dMulti, dCustom, dNote, width),
1445
+ ];
1446
+ if (dTimedOut) {
1447
+ // Distinguish auto-selection from a real user choice in the transcript.
1448
+ bodyLines.push(uiTheme.fg("dim", "auto-selected after timeout — not a user choice"));
1449
+ }
1450
+ return {
1451
+ header,
1452
+ sections: bodyLines.length > 0 ? [{ lines: bodyLines }] : [],
1453
+ state: hasSelection ? "success" : "warning",
1454
+ borderColor: "borderMuted",
1455
+ width,
1456
+ };
1457
+ });
1458
+ },
1459
+ };