@f5-sales-demo/xcsh 19.51.2

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 (899) hide show
  1. package/CHANGELOG.md +7073 -0
  2. package/README.md +14 -0
  3. package/examples/README.md +21 -0
  4. package/examples/custom-tools/README.md +109 -0
  5. package/examples/custom-tools/hello/index.ts +20 -0
  6. package/examples/custom-tools/todo/index.ts +206 -0
  7. package/examples/extensions/README.md +143 -0
  8. package/examples/extensions/api-demo.ts +89 -0
  9. package/examples/extensions/chalk-logger.ts +25 -0
  10. package/examples/extensions/hello.ts +32 -0
  11. package/examples/extensions/pirate.ts +43 -0
  12. package/examples/extensions/plan-mode.ts +551 -0
  13. package/examples/extensions/reload-runtime.ts +37 -0
  14. package/examples/extensions/todo.ts +296 -0
  15. package/examples/extensions/tools.ts +145 -0
  16. package/examples/extensions/with-deps/index.ts +36 -0
  17. package/examples/extensions/with-deps/package-lock.json +31 -0
  18. package/examples/extensions/with-deps/package.json +16 -0
  19. package/examples/hooks/README.md +56 -0
  20. package/examples/hooks/auto-commit-on-exit.ts +48 -0
  21. package/examples/hooks/confirm-destructive.ts +58 -0
  22. package/examples/hooks/custom-compaction.ts +115 -0
  23. package/examples/hooks/dirty-repo-guard.ts +51 -0
  24. package/examples/hooks/file-trigger.ts +40 -0
  25. package/examples/hooks/git-checkpoint.ts +52 -0
  26. package/examples/hooks/handoff.ts +149 -0
  27. package/examples/hooks/permission-gate.ts +33 -0
  28. package/examples/hooks/protected-paths.ts +29 -0
  29. package/examples/hooks/qna.ts +118 -0
  30. package/examples/hooks/status-line.ts +39 -0
  31. package/examples/sdk/01-minimal.ts +21 -0
  32. package/examples/sdk/02-custom-model.ts +49 -0
  33. package/examples/sdk/03-custom-prompt.ts +43 -0
  34. package/examples/sdk/04-skills.ts +43 -0
  35. package/examples/sdk/06-extensions.ts +80 -0
  36. package/examples/sdk/06-hooks.ts +61 -0
  37. package/examples/sdk/07-context-files.ts +35 -0
  38. package/examples/sdk/08-prompt-templates.ts +41 -0
  39. package/examples/sdk/08-slash-commands.ts +46 -0
  40. package/examples/sdk/09-api-keys-and-oauth.ts +54 -0
  41. package/examples/sdk/11-sessions.ts +47 -0
  42. package/examples/sdk/README.md +172 -0
  43. package/package.json +539 -0
  44. package/scripts/build-info/resolvers.ts +51 -0
  45. package/scripts/capture-ax-fixture.ts +84 -0
  46. package/scripts/capture-login-fixture.ts +30 -0
  47. package/scripts/check-workflow-field-coverage.ts +101 -0
  48. package/scripts/extension-uat-harness.ts +340 -0
  49. package/scripts/format-prompts.ts +68 -0
  50. package/scripts/generate-api-spec-index.ts +580 -0
  51. package/scripts/generate-branding-index.ts +81 -0
  52. package/scripts/generate-build-info.ts +106 -0
  53. package/scripts/generate-console-catalog.ts +88 -0
  54. package/scripts/generate-console-field-metadata.ts +74 -0
  55. package/scripts/generate-docs-index.ts +40 -0
  56. package/scripts/generate-template.ts +32 -0
  57. package/scripts/generate-terraform-index.ts +81 -0
  58. package/scripts/mermaid-gallery.ts +132 -0
  59. package/scripts/uat-matrix-modalities.ts +451 -0
  60. package/scripts/uat-matrix-report.ts +175 -0
  61. package/scripts/uat-matrix.ts +353 -0
  62. package/src/async/index.ts +2 -0
  63. package/src/async/job-manager.ts +416 -0
  64. package/src/async/support.ts +5 -0
  65. package/src/autoresearch/apply-contract-to-state.ts +1 -0
  66. package/src/autoresearch/command-resume.md +17 -0
  67. package/src/autoresearch/contract.ts +205 -0
  68. package/src/autoresearch/dashboard.ts +374 -0
  69. package/src/autoresearch/git.ts +191 -0
  70. package/src/autoresearch/helpers.ts +328 -0
  71. package/src/autoresearch/index.ts +402 -0
  72. package/src/autoresearch/prompt.md +236 -0
  73. package/src/autoresearch/resume-message.md +16 -0
  74. package/src/autoresearch/state.ts +303 -0
  75. package/src/autoresearch/tools/init-experiment.ts +400 -0
  76. package/src/autoresearch/tools/log-experiment.ts +793 -0
  77. package/src/autoresearch/tools/run-experiment.ts +679 -0
  78. package/src/autoresearch/types.ts +114 -0
  79. package/src/browser/acquire.ts +249 -0
  80. package/src/browser/actions.ts +126 -0
  81. package/src/browser/auth.ts +176 -0
  82. package/src/browser/ax.ts +134 -0
  83. package/src/browser/cdp-core.ts +45 -0
  84. package/src/browser/cdp-page-actions.ts +51 -0
  85. package/src/browser/chrome-locate.ts +66 -0
  86. package/src/browser/dom-context.ts +89 -0
  87. package/src/browser/dt-context.ts +100 -0
  88. package/src/browser/extension-bridge.ts +182 -0
  89. package/src/browser/extension-page-actions.ts +397 -0
  90. package/src/browser/extension-provider.ts +373 -0
  91. package/src/browser/index.ts +17 -0
  92. package/src/browser/input-commit.ts +74 -0
  93. package/src/browser/native-messaging.ts +20 -0
  94. package/src/browser/page-actions.ts +18 -0
  95. package/src/browser/provider.ts +155 -0
  96. package/src/browser/resolver.ts +126 -0
  97. package/src/browser/selector.ts +40 -0
  98. package/src/bun-imports.d.ts +22 -0
  99. package/src/capability/context-file.ts +43 -0
  100. package/src/capability/extension-module.ts +34 -0
  101. package/src/capability/extension.ts +47 -0
  102. package/src/capability/fs.ts +107 -0
  103. package/src/capability/hook.ts +40 -0
  104. package/src/capability/index.ts +438 -0
  105. package/src/capability/instruction.ts +37 -0
  106. package/src/capability/mcp.ts +74 -0
  107. package/src/capability/prompt.ts +35 -0
  108. package/src/capability/rule.ts +224 -0
  109. package/src/capability/settings.ts +34 -0
  110. package/src/capability/skill.ts +50 -0
  111. package/src/capability/slash-command.ts +40 -0
  112. package/src/capability/ssh.ts +41 -0
  113. package/src/capability/system-prompt.ts +34 -0
  114. package/src/capability/tool.ts +38 -0
  115. package/src/capability/types.ts +168 -0
  116. package/src/cli/agents-cli.ts +138 -0
  117. package/src/cli/args.ts +286 -0
  118. package/src/cli/chrome-cli.ts +88 -0
  119. package/src/cli/classify-install-target.ts +50 -0
  120. package/src/cli/commands/init-xdg.ts +27 -0
  121. package/src/cli/config-cli.ts +418 -0
  122. package/src/cli/file-processor.ts +121 -0
  123. package/src/cli/grep-cli.ts +160 -0
  124. package/src/cli/grievances-cli.ts +78 -0
  125. package/src/cli/initial-message.ts +58 -0
  126. package/src/cli/jupyter-cli.ts +106 -0
  127. package/src/cli/list-models.ts +128 -0
  128. package/src/cli/plugin-cli.ts +964 -0
  129. package/src/cli/read-cli.ts +68 -0
  130. package/src/cli/session-picker.ts +52 -0
  131. package/src/cli/setup-cli.ts +479 -0
  132. package/src/cli/shell-cli.ts +174 -0
  133. package/src/cli/ssh-cli.ts +179 -0
  134. package/src/cli/stats-cli.ts +182 -0
  135. package/src/cli/update-cli.ts +446 -0
  136. package/src/cli/web-search-cli.ts +203 -0
  137. package/src/cli.ts +123 -0
  138. package/src/commands/agents.ts +57 -0
  139. package/src/commands/chrome-host.ts +71 -0
  140. package/src/commands/chrome.ts +28 -0
  141. package/src/commands/commit.ts +36 -0
  142. package/src/commands/config.ts +51 -0
  143. package/src/commands/grep.ts +48 -0
  144. package/src/commands/grievances.ts +20 -0
  145. package/src/commands/jupyter.ts +32 -0
  146. package/src/commands/launch.ts +144 -0
  147. package/src/commands/plugin.ts +78 -0
  148. package/src/commands/read.ts +33 -0
  149. package/src/commands/setup.ts +42 -0
  150. package/src/commands/shell.ts +29 -0
  151. package/src/commands/ssh.ts +60 -0
  152. package/src/commands/stats.ts +29 -0
  153. package/src/commands/update.ts +21 -0
  154. package/src/commands/web-search.ts +46 -0
  155. package/src/commit/agentic/agent.ts +314 -0
  156. package/src/commit/agentic/fallback.ts +96 -0
  157. package/src/commit/agentic/index.ts +354 -0
  158. package/src/commit/agentic/prompts/analyze-file.md +22 -0
  159. package/src/commit/agentic/prompts/session-user.md +25 -0
  160. package/src/commit/agentic/prompts/split-confirm.md +1 -0
  161. package/src/commit/agentic/prompts/system.md +38 -0
  162. package/src/commit/agentic/state.ts +60 -0
  163. package/src/commit/agentic/tools/analyze-file.ts +127 -0
  164. package/src/commit/agentic/tools/git-file-diff.ts +191 -0
  165. package/src/commit/agentic/tools/git-hunk.ts +50 -0
  166. package/src/commit/agentic/tools/git-overview.ts +81 -0
  167. package/src/commit/agentic/tools/index.ts +54 -0
  168. package/src/commit/agentic/tools/propose-changelog.ts +139 -0
  169. package/src/commit/agentic/tools/propose-commit.ts +122 -0
  170. package/src/commit/agentic/tools/recent-commits.ts +81 -0
  171. package/src/commit/agentic/tools/schemas.ts +31 -0
  172. package/src/commit/agentic/tools/split-commit.ts +251 -0
  173. package/src/commit/agentic/topo-sort.ts +44 -0
  174. package/src/commit/agentic/trivial.ts +51 -0
  175. package/src/commit/agentic/validation.ts +183 -0
  176. package/src/commit/analysis/conventional.ts +122 -0
  177. package/src/commit/analysis/index.ts +4 -0
  178. package/src/commit/analysis/scope.ts +242 -0
  179. package/src/commit/analysis/summary.ts +105 -0
  180. package/src/commit/analysis/validation.ts +66 -0
  181. package/src/commit/changelog/detect.ts +40 -0
  182. package/src/commit/changelog/generate.ts +101 -0
  183. package/src/commit/changelog/index.ts +234 -0
  184. package/src/commit/changelog/parse.ts +44 -0
  185. package/src/commit/cli.ts +85 -0
  186. package/src/commit/git/diff.ts +148 -0
  187. package/src/commit/index.ts +5 -0
  188. package/src/commit/map-reduce/index.ts +69 -0
  189. package/src/commit/map-reduce/map-phase.ts +193 -0
  190. package/src/commit/map-reduce/reduce-phase.ts +108 -0
  191. package/src/commit/map-reduce/utils.ts +9 -0
  192. package/src/commit/message.ts +11 -0
  193. package/src/commit/model-selection.ts +66 -0
  194. package/src/commit/pipeline.ts +242 -0
  195. package/src/commit/prompts/analysis-system.md +148 -0
  196. package/src/commit/prompts/analysis-user.md +38 -0
  197. package/src/commit/prompts/changelog-system.md +50 -0
  198. package/src/commit/prompts/changelog-user.md +18 -0
  199. package/src/commit/prompts/file-observer-system.md +24 -0
  200. package/src/commit/prompts/file-observer-user.md +8 -0
  201. package/src/commit/prompts/reduce-system.md +50 -0
  202. package/src/commit/prompts/reduce-user.md +17 -0
  203. package/src/commit/prompts/summary-retry.md +3 -0
  204. package/src/commit/prompts/summary-system.md +38 -0
  205. package/src/commit/prompts/summary-user.md +13 -0
  206. package/src/commit/prompts/types-description.md +2 -0
  207. package/src/commit/types.ts +118 -0
  208. package/src/commit/utils/exclusions.ts +42 -0
  209. package/src/commit/utils.ts +44 -0
  210. package/src/config/auto-config.ts +698 -0
  211. package/src/config/context-schema.json +115 -0
  212. package/src/config/file-lock.ts +121 -0
  213. package/src/config/keybindings.ts +493 -0
  214. package/src/config/mcp-schema.json +230 -0
  215. package/src/config/model-equivalence.ts +675 -0
  216. package/src/config/model-registry.ts +2265 -0
  217. package/src/config/model-resolver.ts +1289 -0
  218. package/src/config/prompt-templates.ts +271 -0
  219. package/src/config/resolve-config-value.ts +110 -0
  220. package/src/config/settings-schema.ts +2155 -0
  221. package/src/config/settings.ts +730 -0
  222. package/src/config.ts +418 -0
  223. package/src/cursor.ts +323 -0
  224. package/src/dap/client.ts +674 -0
  225. package/src/dap/config.ts +150 -0
  226. package/src/dap/defaults.json +211 -0
  227. package/src/dap/index.ts +4 -0
  228. package/src/dap/session.ts +1255 -0
  229. package/src/dap/types.ts +600 -0
  230. package/src/debug/index.ts +440 -0
  231. package/src/debug/log-formatting.ts +58 -0
  232. package/src/debug/log-viewer.ts +908 -0
  233. package/src/debug/profiler.ts +158 -0
  234. package/src/debug/report-bundle.ts +365 -0
  235. package/src/debug/system-info.ts +107 -0
  236. package/src/discovery/agents-md.ts +67 -0
  237. package/src/discovery/agents.ts +219 -0
  238. package/src/discovery/builtin.ts +851 -0
  239. package/src/discovery/claude-plugins.ts +297 -0
  240. package/src/discovery/claude.ts +543 -0
  241. package/src/discovery/cline.ts +83 -0
  242. package/src/discovery/codex.ts +535 -0
  243. package/src/discovery/cursor.ts +220 -0
  244. package/src/discovery/gemini.ts +396 -0
  245. package/src/discovery/github.ts +118 -0
  246. package/src/discovery/helpers.ts +934 -0
  247. package/src/discovery/index.ts +79 -0
  248. package/src/discovery/language.ts +46 -0
  249. package/src/discovery/mcp-json.ts +171 -0
  250. package/src/discovery/opencode.ts +393 -0
  251. package/src/discovery/plugin-dir-roots.ts +28 -0
  252. package/src/discovery/ssh.ts +153 -0
  253. package/src/discovery/substitute-plugin-root.ts +29 -0
  254. package/src/discovery/vscode.ts +105 -0
  255. package/src/discovery/windsurf.ts +147 -0
  256. package/src/edit/diff.ts +818 -0
  257. package/src/edit/index.ts +481 -0
  258. package/src/edit/line-hash.ts +67 -0
  259. package/src/edit/modes/chunk.ts +762 -0
  260. package/src/edit/modes/hashline.ts +1366 -0
  261. package/src/edit/modes/patch.ts +1791 -0
  262. package/src/edit/modes/replace.ts +1115 -0
  263. package/src/edit/normalize.ts +375 -0
  264. package/src/edit/renderer.ts +627 -0
  265. package/src/exa/factory.ts +61 -0
  266. package/src/exa/index.ts +27 -0
  267. package/src/exa/mcp-client.ts +293 -0
  268. package/src/exa/render.ts +232 -0
  269. package/src/exa/researcher.ts +47 -0
  270. package/src/exa/search.ts +86 -0
  271. package/src/exa/types.ts +166 -0
  272. package/src/exa/websets.ts +247 -0
  273. package/src/exec/bash-executor.ts +332 -0
  274. package/src/exec/exec.ts +53 -0
  275. package/src/exec/idle-timeout-watchdog.ts +126 -0
  276. package/src/exec/non-interactive-env.ts +48 -0
  277. package/src/export/custom-share.ts +65 -0
  278. package/src/export/html/index.ts +161 -0
  279. package/src/export/html/template.css +1001 -0
  280. package/src/export/html/template.generated.ts +2 -0
  281. package/src/export/html/template.html +46 -0
  282. package/src/export/html/template.js +1950 -0
  283. package/src/export/html/template.macro.ts +24 -0
  284. package/src/export/html/vendor/highlight.min.js +1213 -0
  285. package/src/export/html/vendor/marked.min.js +6 -0
  286. package/src/export/ttsr.ts +434 -0
  287. package/src/extensibility/custom-commands/bundled/ci-green/index.ts +25 -0
  288. package/src/extensibility/custom-commands/bundled/review/index.ts +456 -0
  289. package/src/extensibility/custom-commands/index.ts +2 -0
  290. package/src/extensibility/custom-commands/loader.ts +236 -0
  291. package/src/extensibility/custom-commands/types.ts +111 -0
  292. package/src/extensibility/custom-tools/index.ts +7 -0
  293. package/src/extensibility/custom-tools/loader.ts +238 -0
  294. package/src/extensibility/custom-tools/types.ts +251 -0
  295. package/src/extensibility/custom-tools/wrapper.ts +47 -0
  296. package/src/extensibility/extensions/index.ts +15 -0
  297. package/src/extensibility/extensions/loader.ts +572 -0
  298. package/src/extensibility/extensions/runner.ts +848 -0
  299. package/src/extensibility/extensions/types.ts +1394 -0
  300. package/src/extensibility/extensions/wrapper.ts +191 -0
  301. package/src/extensibility/hooks/index.ts +5 -0
  302. package/src/extensibility/hooks/loader.ts +255 -0
  303. package/src/extensibility/hooks/runner.ts +425 -0
  304. package/src/extensibility/hooks/tool-wrapper.ts +108 -0
  305. package/src/extensibility/hooks/types.ts +826 -0
  306. package/src/extensibility/plugins/doctor.ts +66 -0
  307. package/src/extensibility/plugins/git-url.ts +281 -0
  308. package/src/extensibility/plugins/index.ts +9 -0
  309. package/src/extensibility/plugins/installer.ts +192 -0
  310. package/src/extensibility/plugins/loader.ts +267 -0
  311. package/src/extensibility/plugins/manager.ts +731 -0
  312. package/src/extensibility/plugins/marketplace/cache.ts +136 -0
  313. package/src/extensibility/plugins/marketplace/fetcher.ts +318 -0
  314. package/src/extensibility/plugins/marketplace/index.ts +6 -0
  315. package/src/extensibility/plugins/marketplace/manager.ts +781 -0
  316. package/src/extensibility/plugins/marketplace/prerequisites.ts +255 -0
  317. package/src/extensibility/plugins/marketplace/registry.ts +196 -0
  318. package/src/extensibility/plugins/marketplace/source-resolver.ts +147 -0
  319. package/src/extensibility/plugins/marketplace/types.ts +201 -0
  320. package/src/extensibility/plugins/parser.ts +105 -0
  321. package/src/extensibility/plugins/types.ts +194 -0
  322. package/src/extensibility/skills.ts +269 -0
  323. package/src/extensibility/slash-commands.ts +246 -0
  324. package/src/extensibility/tool-proxy.ts +25 -0
  325. package/src/extensibility/utils.ts +38 -0
  326. package/src/index.ts +61 -0
  327. package/src/internal-urls/agent-protocol.ts +136 -0
  328. package/src/internal-urls/api-catalog-resolve.ts +495 -0
  329. package/src/internal-urls/api-catalog-types.ts +94 -0
  330. package/src/internal-urls/api-spec-resolve.ts +1036 -0
  331. package/src/internal-urls/api-spec-types.ts +239 -0
  332. package/src/internal-urls/artifact-protocol.ts +97 -0
  333. package/src/internal-urls/branding-index.generated.ts +88 -0
  334. package/src/internal-urls/build-info-runtime.ts +302 -0
  335. package/src/internal-urls/build-info.generated.ts +33 -0
  336. package/src/internal-urls/computer-profile.ts +692 -0
  337. package/src/internal-urls/console-catalog-types.ts +21 -0
  338. package/src/internal-urls/console-catalog.generated.ts +532 -0
  339. package/src/internal-urls/console-field-metadata-types.ts +59 -0
  340. package/src/internal-urls/console-field-metadata.generated.ts +4841 -0
  341. package/src/internal-urls/console-resolve.ts +178 -0
  342. package/src/internal-urls/docs-index.generated.ts +698 -0
  343. package/src/internal-urls/extension-api.md +147 -0
  344. package/src/internal-urls/index.ts +46 -0
  345. package/src/internal-urls/jobs-protocol.ts +119 -0
  346. package/src/internal-urls/json-query.ts +126 -0
  347. package/src/internal-urls/local-protocol.ts +206 -0
  348. package/src/internal-urls/mcp-protocol.ts +156 -0
  349. package/src/internal-urls/memory-protocol.ts +133 -0
  350. package/src/internal-urls/parse.ts +72 -0
  351. package/src/internal-urls/profile-collectors.ts +106 -0
  352. package/src/internal-urls/router.ts +55 -0
  353. package/src/internal-urls/rule-protocol.ts +55 -0
  354. package/src/internal-urls/skill-protocol.ts +111 -0
  355. package/src/internal-urls/terraform-index.generated.ts +1852 -0
  356. package/src/internal-urls/terraform-resolve.ts +184 -0
  357. package/src/internal-urls/terraform-types.ts +45 -0
  358. package/src/internal-urls/types.ts +52 -0
  359. package/src/internal-urls/user-profile.ts +363 -0
  360. package/src/internal-urls/xcsh-protocol.ts +644 -0
  361. package/src/ipy/cancellation.ts +28 -0
  362. package/src/ipy/executor.ts +1155 -0
  363. package/src/ipy/gateway-coordinator.ts +424 -0
  364. package/src/ipy/kernel.ts +1091 -0
  365. package/src/ipy/modules.ts +144 -0
  366. package/src/ipy/prelude.py +849 -0
  367. package/src/ipy/prelude.ts +3 -0
  368. package/src/ipy/runtime.ts +221 -0
  369. package/src/locales/ar.json +512 -0
  370. package/src/locales/de.json +512 -0
  371. package/src/locales/en.json +549 -0
  372. package/src/locales/es.json +512 -0
  373. package/src/locales/fr.json +512 -0
  374. package/src/locales/hi.json +512 -0
  375. package/src/locales/index.ts +29 -0
  376. package/src/locales/it.json +512 -0
  377. package/src/locales/ja.json +512 -0
  378. package/src/locales/ko.json +512 -0
  379. package/src/locales/pt-br.json +512 -0
  380. package/src/locales/th.json +512 -0
  381. package/src/locales/zh-cn.json +512 -0
  382. package/src/locales/zh-tw.json +512 -0
  383. package/src/lsp/client.ts +941 -0
  384. package/src/lsp/clients/biome-client.ts +202 -0
  385. package/src/lsp/clients/index.ts +50 -0
  386. package/src/lsp/clients/lsp-linter-client.ts +93 -0
  387. package/src/lsp/clients/swiftlint-client.ts +120 -0
  388. package/src/lsp/config.ts +418 -0
  389. package/src/lsp/defaults.json +999 -0
  390. package/src/lsp/edits.ts +109 -0
  391. package/src/lsp/index.ts +1746 -0
  392. package/src/lsp/lspmux.ts +233 -0
  393. package/src/lsp/render.ts +692 -0
  394. package/src/lsp/startup-events.ts +13 -0
  395. package/src/lsp/types.ts +444 -0
  396. package/src/lsp/utils.ts +691 -0
  397. package/src/main.ts +944 -0
  398. package/src/mcp/client.ts +482 -0
  399. package/src/mcp/config-writer.ts +225 -0
  400. package/src/mcp/config.ts +365 -0
  401. package/src/mcp/discoverable-tool-metadata.ts +202 -0
  402. package/src/mcp/index.ts +29 -0
  403. package/src/mcp/json-rpc.ts +84 -0
  404. package/src/mcp/loader.ts +124 -0
  405. package/src/mcp/manager.ts +1152 -0
  406. package/src/mcp/oauth-discovery.ts +349 -0
  407. package/src/mcp/oauth-flow.ts +387 -0
  408. package/src/mcp/render.ts +157 -0
  409. package/src/mcp/smithery-auth.ts +104 -0
  410. package/src/mcp/smithery-connect.ts +145 -0
  411. package/src/mcp/smithery-registry.ts +477 -0
  412. package/src/mcp/tool-bridge.ts +417 -0
  413. package/src/mcp/tool-cache.ts +117 -0
  414. package/src/mcp/transports/http.ts +475 -0
  415. package/src/mcp/transports/index.ts +6 -0
  416. package/src/mcp/transports/stdio.ts +325 -0
  417. package/src/mcp/types.ts +423 -0
  418. package/src/memories/index.ts +1115 -0
  419. package/src/memories/storage.ts +577 -0
  420. package/src/modes/acp/acp-agent.ts +1361 -0
  421. package/src/modes/acp/acp-event-mapper.ts +538 -0
  422. package/src/modes/acp/acp-mode.ts +15 -0
  423. package/src/modes/acp/index.ts +2 -0
  424. package/src/modes/components/agent-dashboard.ts +1124 -0
  425. package/src/modes/components/assistant-message.ts +213 -0
  426. package/src/modes/components/bash-execution.ts +345 -0
  427. package/src/modes/components/bordered-loader.ts +41 -0
  428. package/src/modes/components/branch-summary-message.ts +45 -0
  429. package/src/modes/components/btw-panel.ts +103 -0
  430. package/src/modes/components/compaction-summary-message.ts +51 -0
  431. package/src/modes/components/context-add-wizard.ts +534 -0
  432. package/src/modes/components/countdown-timer.ts +75 -0
  433. package/src/modes/components/custom-editor.ts +238 -0
  434. package/src/modes/components/custom-message.ts +91 -0
  435. package/src/modes/components/diff.ts +210 -0
  436. package/src/modes/components/dynamic-border.ts +25 -0
  437. package/src/modes/components/extensions/extension-dashboard.ts +326 -0
  438. package/src/modes/components/extensions/extension-list.ts +492 -0
  439. package/src/modes/components/extensions/index.ts +9 -0
  440. package/src/modes/components/extensions/inspector-panel.ts +317 -0
  441. package/src/modes/components/extensions/state-manager.ts +587 -0
  442. package/src/modes/components/extensions/types.ts +191 -0
  443. package/src/modes/components/footer.ts +262 -0
  444. package/src/modes/components/gutter-block.ts +315 -0
  445. package/src/modes/components/history-search.ts +158 -0
  446. package/src/modes/components/hook-editor.ts +151 -0
  447. package/src/modes/components/hook-input.ts +81 -0
  448. package/src/modes/components/hook-message.ts +100 -0
  449. package/src/modes/components/hook-selector.ts +192 -0
  450. package/src/modes/components/index.ts +36 -0
  451. package/src/modes/components/keybinding-hints.ts +65 -0
  452. package/src/modes/components/login-dialog.ts +164 -0
  453. package/src/modes/components/mcp-add-wizard.ts +1314 -0
  454. package/src/modes/components/model-selector.ts +946 -0
  455. package/src/modes/components/oauth-selector.ts +211 -0
  456. package/src/modes/components/plugin-selector.ts +95 -0
  457. package/src/modes/components/plugin-settings.ts +477 -0
  458. package/src/modes/components/plugins/index.ts +5 -0
  459. package/src/modes/components/plugins/plugin-dashboard.ts +523 -0
  460. package/src/modes/components/plugins/plugin-inspector-pane.ts +84 -0
  461. package/src/modes/components/plugins/plugin-list-pane.ts +109 -0
  462. package/src/modes/components/plugins/state-manager.ts +229 -0
  463. package/src/modes/components/plugins/types.ts +51 -0
  464. package/src/modes/components/plugins/utils.ts +6 -0
  465. package/src/modes/components/python-execution.ts +244 -0
  466. package/src/modes/components/queue-mode-selector.ts +56 -0
  467. package/src/modes/components/read-tool-group.ts +137 -0
  468. package/src/modes/components/session-observer-overlay.ts +483 -0
  469. package/src/modes/components/session-selector.ts +343 -0
  470. package/src/modes/components/settings-defs.ts +568 -0
  471. package/src/modes/components/settings-selector.ts +641 -0
  472. package/src/modes/components/show-images-selector.ts +45 -0
  473. package/src/modes/components/skill-message.ts +90 -0
  474. package/src/modes/components/status-line/context-gradient.ts +64 -0
  475. package/src/modes/components/status-line/git-utils.ts +42 -0
  476. package/src/modes/components/status-line/hex-ansi.ts +29 -0
  477. package/src/modes/components/status-line/index.ts +4 -0
  478. package/src/modes/components/status-line/presets.ts +174 -0
  479. package/src/modes/components/status-line/segments.ts +494 -0
  480. package/src/modes/components/status-line/separators.ts +55 -0
  481. package/src/modes/components/status-line/token-rate.ts +66 -0
  482. package/src/modes/components/status-line/types.ts +96 -0
  483. package/src/modes/components/status-line-segment-editor.ts +361 -0
  484. package/src/modes/components/status-line.ts +729 -0
  485. package/src/modes/components/theme-selector.ts +63 -0
  486. package/src/modes/components/thinking-selector.ts +52 -0
  487. package/src/modes/components/todo-reminder.ts +54 -0
  488. package/src/modes/components/tool-execution.ts +781 -0
  489. package/src/modes/components/tree-selector.ts +908 -0
  490. package/src/modes/components/ttsr-notification.ts +80 -0
  491. package/src/modes/components/user-message-selector.ts +141 -0
  492. package/src/modes/components/user-message.ts +100 -0
  493. package/src/modes/components/visual-truncate.ts +63 -0
  494. package/src/modes/components/welcome-checks.ts +313 -0
  495. package/src/modes/components/welcome.ts +270 -0
  496. package/src/modes/controllers/btw-controller.ts +193 -0
  497. package/src/modes/controllers/chord-routing.ts +37 -0
  498. package/src/modes/controllers/command-controller.ts +1293 -0
  499. package/src/modes/controllers/context-command-controller.ts +61 -0
  500. package/src/modes/controllers/event-controller.ts +743 -0
  501. package/src/modes/controllers/extension-ui-controller.ts +983 -0
  502. package/src/modes/controllers/input-controller.ts +877 -0
  503. package/src/modes/controllers/mcp-command-controller.ts +1940 -0
  504. package/src/modes/controllers/selector-controller.ts +1292 -0
  505. package/src/modes/controllers/ssh-command-controller.ts +421 -0
  506. package/src/modes/index.ts +34 -0
  507. package/src/modes/interactive-mode.ts +1781 -0
  508. package/src/modes/oauth-manual-input.ts +42 -0
  509. package/src/modes/print-mode.ts +196 -0
  510. package/src/modes/prompt-action-autocomplete.ts +231 -0
  511. package/src/modes/rpc/host-tools.ts +186 -0
  512. package/src/modes/rpc/rpc-client.ts +762 -0
  513. package/src/modes/rpc/rpc-mode.ts +877 -0
  514. package/src/modes/rpc/rpc-types.ts +322 -0
  515. package/src/modes/session-observer-registry.ts +146 -0
  516. package/src/modes/shared.ts +30 -0
  517. package/src/modes/theme/defaults/index.ts +7 -0
  518. package/src/modes/theme/defaults/xcsh-dark.json +113 -0
  519. package/src/modes/theme/defaults/xcsh-light.json +115 -0
  520. package/src/modes/theme/mermaid-cache.ts +151 -0
  521. package/src/modes/theme/mermaid-palette.ts +39 -0
  522. package/src/modes/theme/theme-schema.json +553 -0
  523. package/src/modes/theme/theme.ts +2563 -0
  524. package/src/modes/types.ts +273 -0
  525. package/src/modes/utils/hotkeys-markdown.ts +60 -0
  526. package/src/modes/utils/keybinding-matchers.ts +30 -0
  527. package/src/modes/utils/read-group-outcome-aggregator.ts +55 -0
  528. package/src/modes/utils/sanitize-error-message.ts +60 -0
  529. package/src/modes/utils/tools-markdown.ts +28 -0
  530. package/src/modes/utils/ui-helpers.ts +734 -0
  531. package/src/plan-mode/approved-plan.ts +55 -0
  532. package/src/plan-mode/state.ts +6 -0
  533. package/src/priority.json +37 -0
  534. package/src/prompts/agents/designer.md +67 -0
  535. package/src/prompts/agents/explore.md +61 -0
  536. package/src/prompts/agents/frontmatter.md +10 -0
  537. package/src/prompts/agents/init.md +36 -0
  538. package/src/prompts/agents/librarian.md +121 -0
  539. package/src/prompts/agents/plan.md +49 -0
  540. package/src/prompts/agents/reviewer.md +127 -0
  541. package/src/prompts/agents/task.md +16 -0
  542. package/src/prompts/ci-green-request.md +35 -0
  543. package/src/prompts/compaction/branch-summary-context.md +5 -0
  544. package/src/prompts/compaction/branch-summary-preamble.md +2 -0
  545. package/src/prompts/compaction/branch-summary.md +30 -0
  546. package/src/prompts/compaction/compaction-short-summary.md +9 -0
  547. package/src/prompts/compaction/compaction-summary-context.md +5 -0
  548. package/src/prompts/compaction/compaction-summary.md +38 -0
  549. package/src/prompts/compaction/compaction-turn-prefix.md +17 -0
  550. package/src/prompts/compaction/compaction-update-summary.md +45 -0
  551. package/src/prompts/memories/consolidation.md +30 -0
  552. package/src/prompts/memories/read-path.md +11 -0
  553. package/src/prompts/memories/stage_one_input.md +6 -0
  554. package/src/prompts/memories/stage_one_system.md +21 -0
  555. package/src/prompts/review-request.md +70 -0
  556. package/src/prompts/system/agent-creation-architect.md +65 -0
  557. package/src/prompts/system/agent-creation-user.md +6 -0
  558. package/src/prompts/system/auto-handoff-threshold-focus.md +1 -0
  559. package/src/prompts/system/btw-user.md +8 -0
  560. package/src/prompts/system/commit-message-system.md +2 -0
  561. package/src/prompts/system/custom-system-prompt.md +82 -0
  562. package/src/prompts/system/eager-todo.md +13 -0
  563. package/src/prompts/system/file-operations.md +10 -0
  564. package/src/prompts/system/handoff-document.md +48 -0
  565. package/src/prompts/system/plan-mode-active.md +114 -0
  566. package/src/prompts/system/plan-mode-approved.md +23 -0
  567. package/src/prompts/system/plan-mode-reference.md +14 -0
  568. package/src/prompts/system/plan-mode-subagent.md +34 -0
  569. package/src/prompts/system/plan-mode-tool-decision-reminder.md +9 -0
  570. package/src/prompts/system/subagent-submit-reminder.md +7 -0
  571. package/src/prompts/system/subagent-system-prompt.md +36 -0
  572. package/src/prompts/system/subagent-user-prompt.md +12 -0
  573. package/src/prompts/system/summarization-system.md +3 -0
  574. package/src/prompts/system/system-prompt.md +698 -0
  575. package/src/prompts/system/title-system.md +2 -0
  576. package/src/prompts/system/ttsr-interrupt.md +7 -0
  577. package/src/prompts/system/web-search.md +28 -0
  578. package/src/prompts/tools/ask.md +28 -0
  579. package/src/prompts/tools/ast-edit.md +48 -0
  580. package/src/prompts/tools/ast-grep.md +54 -0
  581. package/src/prompts/tools/async-result.md +5 -0
  582. package/src/prompts/tools/bash.md +67 -0
  583. package/src/prompts/tools/browser.md +26 -0
  584. package/src/prompts/tools/calculator.md +10 -0
  585. package/src/prompts/tools/cancel-job.md +5 -0
  586. package/src/prompts/tools/catalog-workflow-runner.md +13 -0
  587. package/src/prompts/tools/checkpoint.md +16 -0
  588. package/src/prompts/tools/chunk-edit.md +279 -0
  589. package/src/prompts/tools/debug.md +43 -0
  590. package/src/prompts/tools/display-image.md +23 -0
  591. package/src/prompts/tools/exit-plan-mode.md +41 -0
  592. package/src/prompts/tools/find.md +26 -0
  593. package/src/prompts/tools/gemini-image.md +7 -0
  594. package/src/prompts/tools/grep.md +29 -0
  595. package/src/prompts/tools/hashline.md +131 -0
  596. package/src/prompts/tools/inspect-image-system.md +20 -0
  597. package/src/prompts/tools/inspect-image.md +32 -0
  598. package/src/prompts/tools/lsp.md +33 -0
  599. package/src/prompts/tools/patch.md +77 -0
  600. package/src/prompts/tools/poll.md +5 -0
  601. package/src/prompts/tools/python.md +60 -0
  602. package/src/prompts/tools/read-chunk.md +35 -0
  603. package/src/prompts/tools/read.md +63 -0
  604. package/src/prompts/tools/render-mermaid.md +9 -0
  605. package/src/prompts/tools/replace.md +36 -0
  606. package/src/prompts/tools/resolve.md +8 -0
  607. package/src/prompts/tools/rewind.md +13 -0
  608. package/src/prompts/tools/search-tool-bm25.md +34 -0
  609. package/src/prompts/tools/ssh.md +44 -0
  610. package/src/prompts/tools/task-summary.md +28 -0
  611. package/src/prompts/tools/task.md +131 -0
  612. package/src/prompts/tools/todo-write.md +89 -0
  613. package/src/prompts/tools/vim.md +98 -0
  614. package/src/prompts/tools/web-search.md +10 -0
  615. package/src/prompts/tools/write.md +14 -0
  616. package/src/prompts/tools/xcsh-api.md +283 -0
  617. package/src/resource-management/index.ts +42 -0
  618. package/src/sdk.ts +2123 -0
  619. package/src/secrets/index.ts +146 -0
  620. package/src/secrets/obfuscator.ts +290 -0
  621. package/src/secrets/regex.ts +21 -0
  622. package/src/services/context-env.ts +102 -0
  623. package/src/services/xcsh-api-client.ts +230 -0
  624. package/src/services/xcsh-context-command.ts +803 -0
  625. package/src/services/xcsh-context-display.ts +49 -0
  626. package/src/services/xcsh-context-indicators.ts +17 -0
  627. package/src/services/xcsh-context-segment.ts +39 -0
  628. package/src/services/xcsh-context.ts +1410 -0
  629. package/src/services/xcsh-env.ts +107 -0
  630. package/src/services/xcsh-knowledge.ts +177 -0
  631. package/src/services/xcsh-table.ts +164 -0
  632. package/src/session/agent-session.ts +6690 -0
  633. package/src/session/agent-storage.ts +451 -0
  634. package/src/session/artifacts.ts +132 -0
  635. package/src/session/auth-storage.ts +17 -0
  636. package/src/session/blob-store.ts +135 -0
  637. package/src/session/compaction/branch-summarization.ts +322 -0
  638. package/src/session/compaction/compaction.ts +1388 -0
  639. package/src/session/compaction/index.ts +7 -0
  640. package/src/session/compaction/pruning.ts +91 -0
  641. package/src/session/compaction/utils.ts +184 -0
  642. package/src/session/history-storage.ts +253 -0
  643. package/src/session/messages.ts +597 -0
  644. package/src/session/session-dump-format.ts +203 -0
  645. package/src/session/session-manager.ts +2816 -0
  646. package/src/session/session-storage.ts +370 -0
  647. package/src/session/streaming-output.ts +770 -0
  648. package/src/session/tool-choice-queue.ts +213 -0
  649. package/src/slash-commands/builtin-registry.ts +1614 -0
  650. package/src/slash-commands/export-command.ts +178 -0
  651. package/src/slash-commands/marketplace-install-parser.ts +99 -0
  652. package/src/slash-commands/resource-commands.ts +250 -0
  653. package/src/ssh/config-writer.ts +183 -0
  654. package/src/ssh/connection-manager.ts +445 -0
  655. package/src/ssh/ssh-executor.ts +131 -0
  656. package/src/ssh/sshfs-mount.ts +137 -0
  657. package/src/ssh/utils.ts +8 -0
  658. package/src/stt/downloader.ts +71 -0
  659. package/src/stt/index.ts +3 -0
  660. package/src/stt/recorder.ts +351 -0
  661. package/src/stt/setup.ts +52 -0
  662. package/src/stt/stt-controller.ts +160 -0
  663. package/src/stt/transcribe.py +70 -0
  664. package/src/stt/transcriber.ts +91 -0
  665. package/src/system-prompt.ts +688 -0
  666. package/src/task/agents.ts +166 -0
  667. package/src/task/commands.ts +131 -0
  668. package/src/task/discovery.ts +126 -0
  669. package/src/task/executor.ts +1324 -0
  670. package/src/task/index.ts +1197 -0
  671. package/src/task/isolation-backend.ts +72 -0
  672. package/src/task/name-generator.ts +1577 -0
  673. package/src/task/output-manager.ts +107 -0
  674. package/src/task/parallel.ts +116 -0
  675. package/src/task/render.ts +1035 -0
  676. package/src/task/subprocess-tool-registry.ts +88 -0
  677. package/src/task/template.ts +33 -0
  678. package/src/task/types.ts +230 -0
  679. package/src/task/worktree.ts +580 -0
  680. package/src/task/xcsh-command.ts +26 -0
  681. package/src/thinking.ts +87 -0
  682. package/src/tools/action-renderer.ts +198 -0
  683. package/src/tools/archive-reader.ts +315 -0
  684. package/src/tools/ask.ts +791 -0
  685. package/src/tools/ast-edit.ts +492 -0
  686. package/src/tools/ast-grep.ts +453 -0
  687. package/src/tools/auto-generated-guard.ts +305 -0
  688. package/src/tools/bash-interactive.ts +383 -0
  689. package/src/tools/bash-interceptor.ts +67 -0
  690. package/src/tools/bash-normalize.ts +107 -0
  691. package/src/tools/bash-skill-urls.ts +246 -0
  692. package/src/tools/bash.ts +878 -0
  693. package/src/tools/browser-renderer.ts +129 -0
  694. package/src/tools/browser.ts +1366 -0
  695. package/src/tools/calculator.ts +543 -0
  696. package/src/tools/cancel-job.ts +100 -0
  697. package/src/tools/catalog-workflow-runner.ts +718 -0
  698. package/src/tools/checkpoint.ts +133 -0
  699. package/src/tools/context.ts +39 -0
  700. package/src/tools/debug.ts +1004 -0
  701. package/src/tools/display-image-renderer.ts +96 -0
  702. package/src/tools/display-image.ts +109 -0
  703. package/src/tools/exit-plan-mode.ts +101 -0
  704. package/src/tools/fetch.ts +1462 -0
  705. package/src/tools/find.ts +437 -0
  706. package/src/tools/fs-cache-invalidation.ts +33 -0
  707. package/src/tools/gemini-image.ts +1004 -0
  708. package/src/tools/grep.ts +705 -0
  709. package/src/tools/index.ts +442 -0
  710. package/src/tools/inspect-image-renderer.ts +101 -0
  711. package/src/tools/inspect-image.ts +176 -0
  712. package/src/tools/json-tree.ts +266 -0
  713. package/src/tools/jtd-to-json-schema.ts +199 -0
  714. package/src/tools/jtd-to-typescript.ts +136 -0
  715. package/src/tools/jtd-utils.ts +102 -0
  716. package/src/tools/list-limit.ts +40 -0
  717. package/src/tools/mermaid-renderer.ts +127 -0
  718. package/src/tools/notebook.ts +288 -0
  719. package/src/tools/output-meta.ts +588 -0
  720. package/src/tools/path-utils.ts +560 -0
  721. package/src/tools/plan-mode-guard.ts +41 -0
  722. package/src/tools/poll-tool.ts +177 -0
  723. package/src/tools/puppeteer/00_stealth_tampering.txt +63 -0
  724. package/src/tools/puppeteer/01_stealth_activity.txt +20 -0
  725. package/src/tools/puppeteer/02_stealth_hairline.txt +11 -0
  726. package/src/tools/puppeteer/03_stealth_botd.txt +384 -0
  727. package/src/tools/puppeteer/04_stealth_iframe.txt +81 -0
  728. package/src/tools/puppeteer/05_stealth_webgl.txt +75 -0
  729. package/src/tools/puppeteer/06_stealth_screen.txt +72 -0
  730. package/src/tools/puppeteer/07_stealth_fonts.txt +97 -0
  731. package/src/tools/puppeteer/08_stealth_audio.txt +51 -0
  732. package/src/tools/puppeteer/09_stealth_locale.txt +46 -0
  733. package/src/tools/puppeteer/10_stealth_plugins.txt +206 -0
  734. package/src/tools/puppeteer/11_stealth_hardware.txt +8 -0
  735. package/src/tools/puppeteer/12_stealth_codecs.txt +40 -0
  736. package/src/tools/puppeteer/13_stealth_worker.txt +74 -0
  737. package/src/tools/python.ts +1184 -0
  738. package/src/tools/read.ts +1591 -0
  739. package/src/tools/render-mermaid.ts +93 -0
  740. package/src/tools/render-utils.ts +677 -0
  741. package/src/tools/renderers.ts +82 -0
  742. package/src/tools/report-tool-issue.ts +80 -0
  743. package/src/tools/resolve.ts +196 -0
  744. package/src/tools/review.ts +238 -0
  745. package/src/tools/search-tool-bm25.ts +288 -0
  746. package/src/tools/sqlite-reader.ts +623 -0
  747. package/src/tools/ssh.ts +322 -0
  748. package/src/tools/submit-result.ts +229 -0
  749. package/src/tools/todo-render.ts +33 -0
  750. package/src/tools/todo-write.ts +440 -0
  751. package/src/tools/tool-errors.ts +62 -0
  752. package/src/tools/tool-result.ts +93 -0
  753. package/src/tools/tool-timeouts.ts +30 -0
  754. package/src/tools/vim.ts +981 -0
  755. package/src/tools/write.ts +671 -0
  756. package/src/tools/xcsh-api-renderer.ts +402 -0
  757. package/src/tools/xcsh-api.ts +887 -0
  758. package/src/tui/code-cell.ts +101 -0
  759. package/src/tui/file-list.ts +47 -0
  760. package/src/tui/index.ts +11 -0
  761. package/src/tui/output-block.ts +175 -0
  762. package/src/tui/status-line.ts +39 -0
  763. package/src/tui/tree-list.ts +84 -0
  764. package/src/tui/types.ts +15 -0
  765. package/src/tui/utils.ts +103 -0
  766. package/src/utils/changelog.ts +98 -0
  767. package/src/utils/clipboard.ts +80 -0
  768. package/src/utils/command-args.ts +76 -0
  769. package/src/utils/commit-message-generator.ts +137 -0
  770. package/src/utils/edit-mode.ts +50 -0
  771. package/src/utils/event-bus.ts +33 -0
  772. package/src/utils/external-editor.ts +65 -0
  773. package/src/utils/file-display-mode.ts +37 -0
  774. package/src/utils/file-mentions.ts +376 -0
  775. package/src/utils/fuzzy.ts +108 -0
  776. package/src/utils/git.ts +1495 -0
  777. package/src/utils/gitstatus.ts +140 -0
  778. package/src/utils/image-convert.ts +27 -0
  779. package/src/utils/image-loading.ts +98 -0
  780. package/src/utils/image-passthrough.ts +118 -0
  781. package/src/utils/image-resize.ts +272 -0
  782. package/src/utils/image-viewer.ts +17 -0
  783. package/src/utils/lang-from-path.ts +239 -0
  784. package/src/utils/markit.ts +81 -0
  785. package/src/utils/open.ts +20 -0
  786. package/src/utils/session-color.ts +55 -0
  787. package/src/utils/shell-snapshot.ts +188 -0
  788. package/src/utils/title-generator.ts +193 -0
  789. package/src/utils/tool-choice.ts +28 -0
  790. package/src/utils/tools-manager.ts +356 -0
  791. package/src/vim/buffer.ts +309 -0
  792. package/src/vim/commands.ts +382 -0
  793. package/src/vim/engine.ts +2426 -0
  794. package/src/vim/parser.ts +151 -0
  795. package/src/vim/render.ts +252 -0
  796. package/src/vim/types.ts +197 -0
  797. package/src/web/kagi.ts +174 -0
  798. package/src/web/parallel.ts +346 -0
  799. package/src/web/scrapers/artifacthub.ts +207 -0
  800. package/src/web/scrapers/arxiv.ts +83 -0
  801. package/src/web/scrapers/aur.ts +162 -0
  802. package/src/web/scrapers/biorxiv.ts +133 -0
  803. package/src/web/scrapers/bluesky.ts +262 -0
  804. package/src/web/scrapers/brew.ts +172 -0
  805. package/src/web/scrapers/cheatsh.ts +68 -0
  806. package/src/web/scrapers/chocolatey.ts +196 -0
  807. package/src/web/scrapers/choosealicense.ts +95 -0
  808. package/src/web/scrapers/cisa-kev.ts +87 -0
  809. package/src/web/scrapers/clojars.ts +154 -0
  810. package/src/web/scrapers/coingecko.ts +177 -0
  811. package/src/web/scrapers/crates-io.ts +110 -0
  812. package/src/web/scrapers/crossref.ts +136 -0
  813. package/src/web/scrapers/devto.ts +147 -0
  814. package/src/web/scrapers/discogs.ts +306 -0
  815. package/src/web/scrapers/discourse.ts +197 -0
  816. package/src/web/scrapers/dockerhub.ts +138 -0
  817. package/src/web/scrapers/docs-rs.ts +653 -0
  818. package/src/web/scrapers/fdroid.ts +134 -0
  819. package/src/web/scrapers/firefox-addons.ts +191 -0
  820. package/src/web/scrapers/flathub.ts +223 -0
  821. package/src/web/scrapers/github-gist.ts +58 -0
  822. package/src/web/scrapers/github.ts +452 -0
  823. package/src/web/scrapers/gitlab.ts +401 -0
  824. package/src/web/scrapers/go-pkg.ts +266 -0
  825. package/src/web/scrapers/hackage.ts +140 -0
  826. package/src/web/scrapers/hackernews.ts +189 -0
  827. package/src/web/scrapers/hex.ts +105 -0
  828. package/src/web/scrapers/huggingface.ts +321 -0
  829. package/src/web/scrapers/iacr.ts +89 -0
  830. package/src/web/scrapers/index.ts +252 -0
  831. package/src/web/scrapers/jetbrains-marketplace.ts +159 -0
  832. package/src/web/scrapers/lemmy.ts +203 -0
  833. package/src/web/scrapers/lobsters.ts +175 -0
  834. package/src/web/scrapers/mastodon.ts +292 -0
  835. package/src/web/scrapers/maven.ts +138 -0
  836. package/src/web/scrapers/mdn.ts +169 -0
  837. package/src/web/scrapers/metacpan.ts +222 -0
  838. package/src/web/scrapers/musicbrainz.ts +250 -0
  839. package/src/web/scrapers/npm.ts +98 -0
  840. package/src/web/scrapers/nuget.ts +183 -0
  841. package/src/web/scrapers/nvd.ts +222 -0
  842. package/src/web/scrapers/ollama.ts +239 -0
  843. package/src/web/scrapers/open-vsx.ts +106 -0
  844. package/src/web/scrapers/opencorporates.ts +292 -0
  845. package/src/web/scrapers/openlibrary.ts +336 -0
  846. package/src/web/scrapers/orcid.ts +286 -0
  847. package/src/web/scrapers/osv.ts +176 -0
  848. package/src/web/scrapers/packagist.ts +160 -0
  849. package/src/web/scrapers/pub-dev.ts +143 -0
  850. package/src/web/scrapers/pubmed.ts +211 -0
  851. package/src/web/scrapers/pypi.ts +112 -0
  852. package/src/web/scrapers/rawg.ts +110 -0
  853. package/src/web/scrapers/readthedocs.ts +120 -0
  854. package/src/web/scrapers/reddit.ts +95 -0
  855. package/src/web/scrapers/repology.ts +251 -0
  856. package/src/web/scrapers/rfc.ts +201 -0
  857. package/src/web/scrapers/rubygems.ts +103 -0
  858. package/src/web/scrapers/searchcode.ts +190 -0
  859. package/src/web/scrapers/sec-edgar.ts +261 -0
  860. package/src/web/scrapers/semantic-scholar.ts +171 -0
  861. package/src/web/scrapers/snapcraft.ts +187 -0
  862. package/src/web/scrapers/sourcegraph.ts +336 -0
  863. package/src/web/scrapers/spdx.ts +108 -0
  864. package/src/web/scrapers/spotify.ts +198 -0
  865. package/src/web/scrapers/stackoverflow.ts +120 -0
  866. package/src/web/scrapers/terraform.ts +277 -0
  867. package/src/web/scrapers/tldr.ts +47 -0
  868. package/src/web/scrapers/twitter.ts +93 -0
  869. package/src/web/scrapers/types.ts +267 -0
  870. package/src/web/scrapers/utils.ts +109 -0
  871. package/src/web/scrapers/vimeo.ts +133 -0
  872. package/src/web/scrapers/vscode-marketplace.ts +187 -0
  873. package/src/web/scrapers/w3c.ts +156 -0
  874. package/src/web/scrapers/wikidata.ts +344 -0
  875. package/src/web/scrapers/wikipedia.ts +84 -0
  876. package/src/web/scrapers/youtube.ts +313 -0
  877. package/src/web/search/errors.ts +120 -0
  878. package/src/web/search/index.ts +346 -0
  879. package/src/web/search/params.ts +129 -0
  880. package/src/web/search/provider.ts +97 -0
  881. package/src/web/search/providers/anthropic.ts +339 -0
  882. package/src/web/search/providers/base.ts +35 -0
  883. package/src/web/search/providers/brave.ts +150 -0
  884. package/src/web/search/providers/codex.ts +402 -0
  885. package/src/web/search/providers/exa.ts +264 -0
  886. package/src/web/search/providers/firecrawl.ts +115 -0
  887. package/src/web/search/providers/gemini.ts +566 -0
  888. package/src/web/search/providers/jina.ts +99 -0
  889. package/src/web/search/providers/kagi.ts +70 -0
  890. package/src/web/search/providers/kimi.ts +157 -0
  891. package/src/web/search/providers/parallel.ts +63 -0
  892. package/src/web/search/providers/perplexity.ts +546 -0
  893. package/src/web/search/providers/synthetic.ts +113 -0
  894. package/src/web/search/providers/tavily.ts +162 -0
  895. package/src/web/search/providers/utils.ts +36 -0
  896. package/src/web/search/providers/zai.ts +311 -0
  897. package/src/web/search/render.ts +348 -0
  898. package/src/web/search/types.ts +438 -0
  899. package/src/web/search/utils.ts +17 -0
@@ -0,0 +1,698 @@
1
+ /**
2
+ * Auto-configuration and self-healing for LiteLLM proxy.
3
+ *
4
+ * Runs on every startup to ensure xcsh has a working configuration:
5
+ *
6
+ * 1. Missing config → auto-generate from LITELLM env vars
7
+ * 2. Corrupt config → backup and regenerate
8
+ * 3. Empty config → regenerate
9
+ * 4. Drifted config → detect and auto-fix (URL changed in env)
10
+ * 5. Incomplete config → fill missing fields
11
+ * 6. Outdated config → detect missing/old configVersion, backup and regenerate
12
+ *
13
+ * All fixes create .bak backups before overwriting.
14
+ * All operations are idempotent and safe to run repeatedly.
15
+ */
16
+ import * as fs from "node:fs";
17
+ import * as path from "node:path";
18
+ import { $env, logger, readProviderFromModelsYml } from "@f5xc-salesdemos/pi-utils";
19
+
20
+ /** Current config schema version. Bump when the generated format changes. */
21
+ export const CURRENT_CONFIG_VERSION = 2;
22
+
23
+ // ---------------------------------------------------------------------------
24
+ // Detection
25
+ // ---------------------------------------------------------------------------
26
+
27
+ /** Check if LiteLLM env vars are set and usable. */
28
+ export function hasLiteLLMEnv(): boolean {
29
+ const baseUrl = $env.LITELLM_BASE_URL?.trim();
30
+ const apiKey = $env.LITELLM_API_KEY?.trim();
31
+ return !!baseUrl && !!apiKey && (baseUrl.startsWith("http://") || baseUrl.startsWith("https://"));
32
+ }
33
+
34
+ /** Get the LiteLLM base URL from env, normalized (no trailing slash). */
35
+ function getLiteLLMBaseUrl(): string | undefined {
36
+ const raw = $env.LITELLM_BASE_URL?.trim();
37
+ if (!raw) return undefined;
38
+ return raw.replace(/\/+$/, "");
39
+ }
40
+
41
+ // ---------------------------------------------------------------------------
42
+ // Generation
43
+ // ---------------------------------------------------------------------------
44
+
45
+ export interface GenerateModelsYmlOptions {
46
+ /** API base path for the litellm provider (e.g. "/v1" or "/api/v1"). Defaults to "/v1". */
47
+ apiBasePath?: string;
48
+ /** When provided, write this literal API key value instead of the LITELLM_API_KEY env var reference. */
49
+ apiKeyLiteral?: string;
50
+ }
51
+
52
+ /** Generate models.yml content for LiteLLM proxy. */
53
+ export function generateModelsYml(baseUrl: string, options?: GenerateModelsYmlOptions): string {
54
+ const apiBase = options?.apiBasePath ?? "/v1";
55
+ // When a literal API key is provided, double-quote it to handle YAML-significant
56
+ // characters (: ! # { } [ ] ' " etc.). Escape backslashes and double quotes first.
57
+ const apiKeyValue = options?.apiKeyLiteral
58
+ ? `"${options.apiKeyLiteral.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`
59
+ : "LITELLM_API_KEY";
60
+ const keyComment = options?.apiKeyLiteral
61
+ ? "# API key stored as literal value"
62
+ : "# API key resolved from LITELLM_API_KEY env var at runtime";
63
+ const lines = [
64
+ "# Auto-generated by xcsh for LiteLLM proxy",
65
+ keyComment,
66
+ `configVersion: ${CURRENT_CONFIG_VERSION}`,
67
+ "providers:",
68
+ " anthropic:",
69
+ ` baseUrl: "${baseUrl}/anthropic"`,
70
+ ` apiKey: ${apiKeyValue}`,
71
+ " litellm:",
72
+ ` baseUrl: "${baseUrl}${apiBase}"`,
73
+ ` apiKey: ${apiKeyValue}`,
74
+ " api: openai-completions",
75
+ " discovery:",
76
+ " type: openai-compat",
77
+ ];
78
+
79
+ lines.push("");
80
+ return lines.join("\n");
81
+ }
82
+
83
+ export interface LiteLLMConfig {
84
+ baseUrl: string;
85
+ apiKey: string;
86
+ }
87
+
88
+ /**
89
+ * Read existing models.yml and extract the anthropic provider's base URL and API key.
90
+ *
91
+ * - baseUrl: strips `/anthropic` suffix to recover the root proxy URL
92
+ * - apiKey: env var name → process.env lookup; shell-backed → fall back to env;
93
+ * otherwise literal
94
+ * - Falls back to getLiteLLMBaseUrl() and $env.LITELLM_API_KEY when the file is
95
+ * missing or the anthropic block is incomplete
96
+ */
97
+ export function readLiteLLMConfig(modelsPath: string): LiteLLMConfig | undefined {
98
+ if (!fs.existsSync(modelsPath)) return undefined;
99
+
100
+ const block = readProviderFromModelsYml("anthropic", modelsPath);
101
+
102
+ const resolvedBaseUrl = block?.baseUrl ? block.baseUrl.replace(/\/anthropic\/?$/, "") : getLiteLLMBaseUrl();
103
+
104
+ let resolvedApiKey: string | undefined;
105
+ const apiKey = block?.apiKey;
106
+ if (!apiKey) {
107
+ resolvedApiKey = $env.LITELLM_API_KEY;
108
+ } else if (apiKey.kind === "envVar") {
109
+ resolvedApiKey = process.env[apiKey.name] ?? $env.LITELLM_API_KEY;
110
+ } else if (apiKey.kind === "shellSecret") {
111
+ resolvedApiKey = $env.LITELLM_API_KEY;
112
+ } else {
113
+ resolvedApiKey = apiKey.value;
114
+ }
115
+
116
+ if (!resolvedBaseUrl || !resolvedApiKey) return undefined;
117
+
118
+ return { baseUrl: resolvedBaseUrl, apiKey: resolvedApiKey };
119
+ }
120
+
121
+ /** Generate config.yml with sensible defaults for LiteLLM. */
122
+ export function generateConfigYml(): string {
123
+ return [
124
+ "# Auto-generated by xcsh for LiteLLM proxy",
125
+ "modelRoles:",
126
+ " default: anthropic/claude-opus-4-6",
127
+ "",
128
+ "providers:",
129
+ " image: openai",
130
+ " webSearch: anthropic",
131
+ "",
132
+ "generate_image:",
133
+ " enabled: true",
134
+ "",
135
+ "inspect_image:",
136
+ " enabled: true",
137
+ "",
138
+ "images:",
139
+ " blockImages: false",
140
+ " autoResize: true",
141
+ "",
142
+ "terminal:",
143
+ " showImages: true",
144
+ "",
145
+ ].join("\n");
146
+ }
147
+
148
+ /**
149
+ * Ensure config.yml has a modelRoles.default entry.
150
+ * Existing configs from earlier versions may be missing this, causing xcsh
151
+ * to fall through to the "first available model" fallback which picks stale
152
+ * cached models that the proxy can't serve.
153
+ */
154
+ export function healConfigYmlModelRoles(configPath: string): void {
155
+ try {
156
+ const content = fs.readFileSync(configPath, "utf-8");
157
+ if (content.includes("modelRoles:")) return; // Already has modelRoles
158
+ // Prepend modelRoles section
159
+ const healed = `modelRoles:\n default: anthropic/claude-opus-4-6\n\n${content}`;
160
+ fs.writeFileSync(configPath, healed);
161
+ logger.debug("Healed config.yml: added default modelRoles", { configPath });
162
+ } catch {
163
+ // Best-effort — don't block startup
164
+ }
165
+ }
166
+
167
+ // ---------------------------------------------------------------------------
168
+ // Backup
169
+ // ---------------------------------------------------------------------------
170
+
171
+ /**
172
+ * Extract a double-quoted literal API key from an existing models.yml file.
173
+ * Checks the anthropic and litellm provider blocks; returns undefined if
174
+ * neither has a literal (e.g., both use env var references) or the file is
175
+ * missing.
176
+ */
177
+ export function readApiKeyLiteral(modelsPath: string): string | undefined {
178
+ for (const name of ["anthropic", "litellm"]) {
179
+ const block = readProviderFromModelsYml(name, modelsPath);
180
+ if (block?.apiKey?.kind === "literal" && block.apiKey.wasQuoted) {
181
+ return block.apiKey.value;
182
+ }
183
+ }
184
+ return undefined;
185
+ }
186
+
187
+ /** Create a .bak backup of a file if it exists. Returns true if backed up. */
188
+ function backupIfExists(filePath: string): boolean {
189
+ try {
190
+ if (fs.existsSync(filePath)) {
191
+ fs.copyFileSync(filePath, `${filePath}.bak`);
192
+ return true;
193
+ }
194
+ } catch (err) {
195
+ logger.warn("Failed to create backup", { filePath, err });
196
+ }
197
+ return false;
198
+ }
199
+
200
+ /** Safely write a file, creating parent directories. */
201
+ function safeWrite(filePath: string, content: string): boolean {
202
+ try {
203
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
204
+ fs.writeFileSync(filePath, content, "utf-8");
205
+ return true;
206
+ } catch (err) {
207
+ logger.warn("Failed to write config file", { filePath, err });
208
+ return false;
209
+ }
210
+ }
211
+
212
+ /** Remove the model cache database so discovery re-runs fresh. */
213
+ function clearModelCache(modelsPath: string): void {
214
+ const cacheDbPath = path.join(path.dirname(modelsPath), "models.db");
215
+ try {
216
+ if (fs.existsSync(cacheDbPath)) {
217
+ fs.unlinkSync(cacheDbPath);
218
+ logger.debug("Cleared stale model cache", { cacheDbPath });
219
+ }
220
+ // Also remove WAL/SHM files if present
221
+ for (const suffix of ["-wal", "-shm"]) {
222
+ const walPath = `${cacheDbPath}${suffix}`;
223
+ if (fs.existsSync(walPath)) {
224
+ fs.unlinkSync(walPath);
225
+ }
226
+ }
227
+ } catch {
228
+ // Best-effort — don't block config repair
229
+ }
230
+ }
231
+
232
+ // ---------------------------------------------------------------------------
233
+ // Proxy connection probing
234
+ // ---------------------------------------------------------------------------
235
+
236
+ export interface ProbeResult {
237
+ reachable: boolean;
238
+ models: string[];
239
+ error?: string;
240
+ /** The API base path that worked (e.g. "/v1" or "/api/v1"). */
241
+ apiBasePath?: string;
242
+ }
243
+
244
+ /** Candidate paths to probe for the models endpoint (tried in order). */
245
+ const MODELS_ENDPOINT_PATHS = ["/v1/models", "/api/v1/models"];
246
+
247
+ /**
248
+ * Probe a LiteLLM proxy to validate connectivity and discover available models.
249
+ *
250
+ * Tries multiple endpoint paths in order (/v1/models, then /api/v1/models) to
251
+ * handle deployments where a frontend like Open WebUI intercepts /v1/*.
252
+ *
253
+ * Returns the list of model IDs on success, or an error on failure.
254
+ * Uses a 3-second timeout per endpoint to avoid blocking startup.
255
+ */
256
+ export async function probeLiteLLMConnection(
257
+ baseUrl: string,
258
+ apiKey: string,
259
+ options?: { signal?: AbortSignal; fetch?: typeof globalThis.fetch },
260
+ ): Promise<ProbeResult> {
261
+ const fetchImpl = options?.fetch ?? globalThis.fetch;
262
+ const normalizedUrl = baseUrl.replace(/\/+$/, "");
263
+ let lastError = "";
264
+
265
+ for (const endpointPath of MODELS_ENDPOINT_PATHS) {
266
+ const url = `${normalizedUrl}${endpointPath}`;
267
+ let response: Response;
268
+ try {
269
+ response = await fetchImpl(url, {
270
+ method: "GET",
271
+ headers: {
272
+ Accept: "application/json",
273
+ Authorization: `Bearer ${apiKey}`,
274
+ },
275
+ signal: options?.signal ?? AbortSignal.timeout(3000),
276
+ });
277
+ } catch (err) {
278
+ lastError = err instanceof Error ? err.message : String(err);
279
+ continue;
280
+ }
281
+
282
+ if (!response.ok) {
283
+ lastError = `HTTP ${response.status} ${response.statusText} from ${url}`;
284
+ continue;
285
+ }
286
+
287
+ let payload: unknown;
288
+ try {
289
+ payload = await response.json();
290
+ } catch {
291
+ lastError = `Non-JSON response from ${url}`;
292
+ continue;
293
+ }
294
+
295
+ // OpenAI-compatible /v1/models returns { data: [{ id: "model-name", ... }] }
296
+ const models: string[] = [];
297
+ if (
298
+ payload &&
299
+ typeof payload === "object" &&
300
+ "data" in payload &&
301
+ Array.isArray((payload as { data: unknown }).data)
302
+ ) {
303
+ for (const entry of (payload as { data: Array<{ id?: string }> }).data) {
304
+ if (typeof entry.id === "string" && entry.id.length > 0) {
305
+ models.push(entry.id);
306
+ }
307
+ }
308
+ }
309
+
310
+ if (models.length > 0) {
311
+ // Derive the API base path from the endpoint that worked
312
+ const apiBasePath = endpointPath.replace(/\/models$/, "");
313
+ return { reachable: true, models, apiBasePath };
314
+ }
315
+
316
+ lastError = `No models in response from ${url}`;
317
+ }
318
+
319
+ return { reachable: false, models: [], error: lastError };
320
+ }
321
+
322
+ // ---------------------------------------------------------------------------
323
+ // Auto-config on startup (handles missing file)
324
+ // ---------------------------------------------------------------------------
325
+
326
+ /**
327
+ * Try to auto-generate models.yml and config.yml for LiteLLM.
328
+ * Called when models.yml is not found and LITELLM env vars are set.
329
+ * Returns true if config was generated.
330
+ */
331
+ export function tryAutoConfigLiteLLM(modelsPath: string): boolean {
332
+ if (!hasLiteLLMEnv()) return false;
333
+
334
+ const baseUrl = getLiteLLMBaseUrl();
335
+ if (!baseUrl) return false;
336
+
337
+ if (!safeWrite(modelsPath, generateModelsYml(baseUrl))) return false;
338
+ logger.debug("Auto-configured LiteLLM proxy", { modelsPath, baseUrl });
339
+
340
+ // Write config.yml if it doesn't exist, or heal it if it's missing modelRoles
341
+ const configPath = path.join(path.dirname(modelsPath), "config.yml");
342
+ if (!fs.existsSync(configPath)) {
343
+ safeWrite(configPath, generateConfigYml());
344
+ logger.debug("Auto-generated default config", { configPath });
345
+ } else {
346
+ healConfigYmlModelRoles(configPath);
347
+ }
348
+
349
+ return true;
350
+ }
351
+
352
+ // ---------------------------------------------------------------------------
353
+ // Validation
354
+ // ---------------------------------------------------------------------------
355
+
356
+ export interface ValidationResult {
357
+ valid: boolean;
358
+ errors: string[];
359
+ warnings: string[];
360
+ fixable: boolean;
361
+ }
362
+
363
+ /**
364
+ * Validate existing models.yml against environment.
365
+ *
366
+ * Checks:
367
+ * - File exists and is readable
368
+ * - File is not empty or whitespace-only
369
+ * - Contains expected providers section
370
+ * - configVersion matches CURRENT_CONFIG_VERSION
371
+ * - Anthropic baseUrl matches LITELLM_BASE_URL env var
372
+ * - apiKey env var reference resolves to a set variable
373
+ */
374
+ export function validateModelsConfig(modelsPath: string): ValidationResult {
375
+ const result: ValidationResult = { valid: true, errors: [], warnings: [], fixable: false };
376
+
377
+ // Check file exists
378
+ if (!fs.existsSync(modelsPath)) {
379
+ result.valid = false;
380
+ result.errors.push("models.yml not found");
381
+ result.fixable = hasLiteLLMEnv();
382
+ return result;
383
+ }
384
+
385
+ // Check file is readable
386
+ let content: string;
387
+ try {
388
+ content = fs.readFileSync(modelsPath, "utf-8");
389
+ } catch {
390
+ result.valid = false;
391
+ result.errors.push("models.yml is not readable");
392
+ return result;
393
+ }
394
+
395
+ // Check not empty
396
+ if (content.trim().length === 0) {
397
+ result.valid = false;
398
+ result.errors.push("models.yml is empty");
399
+ result.fixable = hasLiteLLMEnv();
400
+ return result;
401
+ }
402
+
403
+ // Check for providers section (basic structural check)
404
+ if (!content.includes("providers:")) {
405
+ result.valid = false;
406
+ result.errors.push("models.yml missing 'providers:' section");
407
+ result.fixable = hasLiteLLMEnv();
408
+ return result;
409
+ }
410
+
411
+ // Check config version
412
+ if (!content.includes(`configVersion: ${CURRENT_CONFIG_VERSION}`)) {
413
+ result.warnings.push(
414
+ `models.yml missing or outdated configVersion (expected ${CURRENT_CONFIG_VERSION}). Run 'xcsh setup litellm' to upgrade.`,
415
+ );
416
+ result.fixable = true;
417
+ }
418
+
419
+ // Check env var alignment
420
+ const envBaseUrl = getLiteLLMBaseUrl();
421
+ if (envBaseUrl) {
422
+ const expectedAnthropicUrl = `${envBaseUrl}/anthropic`;
423
+ if (!content.includes(expectedAnthropicUrl)) {
424
+ result.warnings.push(
425
+ `Anthropic baseUrl in models.yml does not match LITELLM_BASE_URL. Expected: ${expectedAnthropicUrl}`,
426
+ );
427
+ result.fixable = true;
428
+ }
429
+ }
430
+
431
+ // Check apiKey references a set env var
432
+ if (content.includes("apiKey: LITELLM_API_KEY") && !$env.LITELLM_API_KEY) {
433
+ result.warnings.push("models.yml references LITELLM_API_KEY but the env var is not set");
434
+ }
435
+
436
+ return result;
437
+ }
438
+
439
+ // ---------------------------------------------------------------------------
440
+ // Auto-fix (handles corrupt, drifted, incomplete configs)
441
+ // ---------------------------------------------------------------------------
442
+
443
+ export interface FixResult {
444
+ fixed: boolean;
445
+ changes: string[];
446
+ }
447
+
448
+ /**
449
+ * Auto-fix models.yml issues.
450
+ *
451
+ * Handles:
452
+ * - Corrupt YAML → backup and regenerate
453
+ * - Empty file → regenerate
454
+ * - URL drift → backup and regenerate with new URL
455
+ * - Missing providers section → regenerate
456
+ *
457
+ * Always creates .bak backup before overwriting.
458
+ */
459
+ export function autoFixModelsConfig(modelsPath: string): FixResult {
460
+ if (!hasLiteLLMEnv()) {
461
+ return { fixed: false, changes: ["Cannot fix: LITELLM_BASE_URL or LITELLM_API_KEY not set"] };
462
+ }
463
+
464
+ const baseUrl = getLiteLLMBaseUrl();
465
+ if (!baseUrl) {
466
+ return { fixed: false, changes: ["Cannot fix: LITELLM_BASE_URL is invalid"] };
467
+ }
468
+
469
+ const existingLiteralKey = readApiKeyLiteral(modelsPath);
470
+
471
+ backupIfExists(modelsPath);
472
+
473
+ if (
474
+ !safeWrite(
475
+ modelsPath,
476
+ generateModelsYml(baseUrl, {
477
+ ...(existingLiteralKey ? { apiKeyLiteral: existingLiteralKey } : {}),
478
+ }),
479
+ )
480
+ ) {
481
+ return { fixed: false, changes: [`Write failed: could not write to ${modelsPath}`] };
482
+ }
483
+
484
+ // Clear stale model cache so discovery re-runs with the new config
485
+ clearModelCache(modelsPath);
486
+
487
+ logger.debug("Auto-fixed LiteLLM config", { modelsPath, baseUrl });
488
+ return { fixed: true, changes: [`Regenerated models.yml with baseUrl: ${baseUrl}/anthropic`] };
489
+ }
490
+
491
+ // ---------------------------------------------------------------------------
492
+ // Startup self-healing (called from ModelRegistry on every load)
493
+ // ---------------------------------------------------------------------------
494
+
495
+ /**
496
+ * Comprehensive startup health check for models.yml.
497
+ *
498
+ * Called from ModelRegistry.#loadCustomModels() on every startup.
499
+ * Handles all error conditions:
500
+ *
501
+ * - "not-found" → tryAutoConfigLiteLLM (generate from env)
502
+ * - "error" (corrupt/invalid) → autoFixModelsConfig (backup + regenerate)
503
+ * - "ok" but drifted → autoFixModelsConfig (backup + update URL)
504
+ * - "ok" but outdated configVersion → autoFixModelsConfig (backup + upgrade)
505
+ *
506
+ * Returns true if any repair was performed (caller should invalidate cache and reload).
507
+ */
508
+ export function startupHealthCheck(
509
+ status: "ok" | "not-found" | "error",
510
+ modelsPath: string,
511
+ loadedProviders?: Record<string, { baseUrl?: string }>,
512
+ ): boolean {
513
+ // Case 1: No config file — generate from env
514
+ if (status === "not-found") {
515
+ return tryAutoConfigLiteLLM(modelsPath);
516
+ }
517
+
518
+ // Case 2: Config file exists but failed to parse — backup and regenerate
519
+ if (status === "error") {
520
+ if (!hasLiteLLMEnv()) return false;
521
+ const fix = autoFixModelsConfig(modelsPath);
522
+ return fix.fixed;
523
+ }
524
+
525
+ // Case 3: Config loaded OK — check for drift and auto-fix
526
+ if (status === "ok" && loadedProviders) {
527
+ const envBaseUrl = getLiteLLMBaseUrl();
528
+ if (!envBaseUrl) return false;
529
+
530
+ const anthropicConfig = loadedProviders.anthropic;
531
+ if (!anthropicConfig?.baseUrl) return false;
532
+
533
+ const expectedUrl = `${envBaseUrl}/anthropic`;
534
+ if (anthropicConfig.baseUrl !== expectedUrl) {
535
+ // Only auto-fix configs that were generated by xcsh. User-written configs
536
+ // with a custom proxy URL must never be silently overwritten.
537
+ // Recognize both env-var-ref configs and literal-key configs as auto-generated.
538
+ let isAutoGenerated = false;
539
+ try {
540
+ const content = fs.readFileSync(modelsPath, "utf-8");
541
+ isAutoGenerated = content.includes("Auto-generated by xcsh") || content.includes("apiKey: LITELLM_API_KEY");
542
+ } catch {
543
+ // File unreadable — skip, don't block startup
544
+ }
545
+ if (!isAutoGenerated) return false;
546
+
547
+ logger.warn("LiteLLM config drift detected — auto-fixing", {
548
+ configured: anthropicConfig.baseUrl,
549
+ expected: expectedUrl,
550
+ });
551
+ const fix = autoFixModelsConfig(modelsPath);
552
+ return fix.fixed;
553
+ }
554
+
555
+ // Case 4: Config OK and URL matches — check for structural issues
556
+ try {
557
+ const content = fs.readFileSync(modelsPath, "utf-8");
558
+
559
+ // 4a: configVersion is missing or outdated
560
+ if (!content.includes(`configVersion: ${CURRENT_CONFIG_VERSION}`)) {
561
+ logger.debug("Upgrading models.yml to configVersion", { version: CURRENT_CONFIG_VERSION });
562
+ const fix = autoFixModelsConfig(modelsPath);
563
+ return fix.fixed;
564
+ }
565
+
566
+ // 4b: litellm discovery provider is missing (legacy v1-style config)
567
+ if (!content.includes("type: openai-compat")) {
568
+ logger.debug("Adding litellm discovery provider to models.yml");
569
+ const fix = autoFixModelsConfig(modelsPath);
570
+ return fix.fixed;
571
+ }
572
+ } catch {
573
+ // File read failed — skip structural checks, don't block startup
574
+ }
575
+ }
576
+
577
+ // Always heal config.yml model roles (regardless of models.yml state)
578
+ if (hasLiteLLMEnv()) {
579
+ const configPath = path.join(path.dirname(modelsPath), "config.yml");
580
+ if (fs.existsSync(configPath)) {
581
+ healConfigYmlModelRoles(configPath);
582
+ }
583
+ }
584
+
585
+ return false;
586
+ }
587
+
588
+ // ---------------------------------------------------------------------------
589
+ // Async probe-and-upgrade (called from ModelRegistry.refresh on first run)
590
+ // ---------------------------------------------------------------------------
591
+
592
+ /**
593
+ * Probe the LiteLLM proxy and upgrade config with the correct API base path.
594
+ *
595
+ * This is an async operation that runs during the first ModelRegistry.refresh().
596
+ * It validates proxy connectivity and, if successful, ensures the config uses
597
+ * the correct API base path (e.g. /api/v1 for Open WebUI deployments).
598
+ *
599
+ * Returns true if the config was upgraded (caller should reload).
600
+ */
601
+ export async function probeAndUpgradeLiteLLMConfig(
602
+ modelsPath: string,
603
+ options?: { fetch?: typeof globalThis.fetch },
604
+ ): Promise<boolean> {
605
+ // Try env vars first; fall back to literal key stored in the config
606
+ let baseUrl = getLiteLLMBaseUrl();
607
+ let apiKey = $env.LITELLM_API_KEY?.trim();
608
+
609
+ if (!baseUrl || !apiKey) {
610
+ const existing = readLiteLLMConfig(modelsPath);
611
+ if (existing) {
612
+ baseUrl = baseUrl || existing.baseUrl;
613
+ apiKey = apiKey || existing.apiKey;
614
+ }
615
+ }
616
+
617
+ if (!baseUrl || !apiKey) return false;
618
+
619
+ let content: string;
620
+ try {
621
+ content = fs.readFileSync(modelsPath, "utf-8");
622
+ } catch {
623
+ // File doesn't exist or is unreadable — nothing to upgrade
624
+ return false;
625
+ }
626
+
627
+ // Only upgrade configs that were auto-generated by xcsh. User-written configs
628
+ // with custom proxy URLs must never be silently overwritten by LiteLLM probing.
629
+ // Recognize both env-var-ref configs and literal-key configs as auto-generated.
630
+ if (!content.includes("Auto-generated by xcsh") && !content.includes("apiKey: LITELLM_API_KEY")) {
631
+ return false;
632
+ }
633
+
634
+ // Probe the proxy to find the working API base path
635
+ const probe = await probeLiteLLMConnection(baseUrl, apiKey, { fetch: options?.fetch });
636
+ if (!probe.reachable) {
637
+ logger.warn("LiteLLM proxy unreachable during upgrade probe — keeping existing config", {
638
+ baseUrl,
639
+ error: probe.error,
640
+ });
641
+ return false;
642
+ }
643
+
644
+ if (probe.models.length === 0) {
645
+ logger.warn("LiteLLM proxy returned no models — keeping existing config", { baseUrl });
646
+ return false;
647
+ }
648
+
649
+ // Check if the config already has the correct discovery base path
650
+ const hasDiscovery = content.includes("type: openai-compat");
651
+ const correctBase = `${baseUrl}${probe.apiBasePath}`;
652
+ if (hasDiscovery && content.includes(correctBase)) {
653
+ return false; // Already correct
654
+ }
655
+
656
+ // Upgrade: backup and regenerate with correct base path, preserving literal keys
657
+ const existingLiteralKey = readApiKeyLiteral(modelsPath);
658
+ backupIfExists(modelsPath);
659
+ const newContent = generateModelsYml(baseUrl, {
660
+ apiBasePath: probe.apiBasePath,
661
+ ...(existingLiteralKey ? { apiKeyLiteral: existingLiteralKey } : {}),
662
+ });
663
+ if (!safeWrite(modelsPath, newContent)) {
664
+ return false;
665
+ }
666
+
667
+ logger.debug("Upgraded LiteLLM config", {
668
+ modelsPath,
669
+ baseUrl,
670
+ apiBasePath: probe.apiBasePath,
671
+ models: probe.models.length,
672
+ hadDiscovery: hasDiscovery,
673
+ });
674
+ return true;
675
+ }
676
+
677
+ /**
678
+ * Validate config against env and warn if drifted.
679
+ * Informational only — does not fix. Use startupHealthCheck for auto-fix.
680
+ */
681
+ export function warnIfConfigDrifted(providers: Record<string, { baseUrl?: string }> | undefined): void {
682
+ if (!providers) return;
683
+
684
+ const envBaseUrl = getLiteLLMBaseUrl();
685
+ if (!envBaseUrl) return;
686
+
687
+ const anthropicConfig = providers.anthropic;
688
+ if (!anthropicConfig?.baseUrl) return;
689
+
690
+ const expectedUrl = `${envBaseUrl}/anthropic`;
691
+ if (anthropicConfig.baseUrl !== expectedUrl) {
692
+ logger.warn("LiteLLM config drift detected", {
693
+ configured: anthropicConfig.baseUrl,
694
+ expected: expectedUrl,
695
+ hint: "Run 'xcsh setup litellm' to update",
696
+ });
697
+ }
698
+ }