@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.
- package/CHANGELOG.md +7073 -0
- package/README.md +14 -0
- package/examples/README.md +21 -0
- package/examples/custom-tools/README.md +109 -0
- package/examples/custom-tools/hello/index.ts +20 -0
- package/examples/custom-tools/todo/index.ts +206 -0
- package/examples/extensions/README.md +143 -0
- package/examples/extensions/api-demo.ts +89 -0
- package/examples/extensions/chalk-logger.ts +25 -0
- package/examples/extensions/hello.ts +32 -0
- package/examples/extensions/pirate.ts +43 -0
- package/examples/extensions/plan-mode.ts +551 -0
- package/examples/extensions/reload-runtime.ts +37 -0
- package/examples/extensions/todo.ts +296 -0
- package/examples/extensions/tools.ts +145 -0
- package/examples/extensions/with-deps/index.ts +36 -0
- package/examples/extensions/with-deps/package-lock.json +31 -0
- package/examples/extensions/with-deps/package.json +16 -0
- package/examples/hooks/README.md +56 -0
- package/examples/hooks/auto-commit-on-exit.ts +48 -0
- package/examples/hooks/confirm-destructive.ts +58 -0
- package/examples/hooks/custom-compaction.ts +115 -0
- package/examples/hooks/dirty-repo-guard.ts +51 -0
- package/examples/hooks/file-trigger.ts +40 -0
- package/examples/hooks/git-checkpoint.ts +52 -0
- package/examples/hooks/handoff.ts +149 -0
- package/examples/hooks/permission-gate.ts +33 -0
- package/examples/hooks/protected-paths.ts +29 -0
- package/examples/hooks/qna.ts +118 -0
- package/examples/hooks/status-line.ts +39 -0
- package/examples/sdk/01-minimal.ts +21 -0
- package/examples/sdk/02-custom-model.ts +49 -0
- package/examples/sdk/03-custom-prompt.ts +43 -0
- package/examples/sdk/04-skills.ts +43 -0
- package/examples/sdk/06-extensions.ts +80 -0
- package/examples/sdk/06-hooks.ts +61 -0
- package/examples/sdk/07-context-files.ts +35 -0
- package/examples/sdk/08-prompt-templates.ts +41 -0
- package/examples/sdk/08-slash-commands.ts +46 -0
- package/examples/sdk/09-api-keys-and-oauth.ts +54 -0
- package/examples/sdk/11-sessions.ts +47 -0
- package/examples/sdk/README.md +172 -0
- package/package.json +539 -0
- package/scripts/build-info/resolvers.ts +51 -0
- package/scripts/capture-ax-fixture.ts +84 -0
- package/scripts/capture-login-fixture.ts +30 -0
- package/scripts/check-workflow-field-coverage.ts +101 -0
- package/scripts/extension-uat-harness.ts +340 -0
- package/scripts/format-prompts.ts +68 -0
- package/scripts/generate-api-spec-index.ts +580 -0
- package/scripts/generate-branding-index.ts +81 -0
- package/scripts/generate-build-info.ts +106 -0
- package/scripts/generate-console-catalog.ts +88 -0
- package/scripts/generate-console-field-metadata.ts +74 -0
- package/scripts/generate-docs-index.ts +40 -0
- package/scripts/generate-template.ts +32 -0
- package/scripts/generate-terraform-index.ts +81 -0
- package/scripts/mermaid-gallery.ts +132 -0
- package/scripts/uat-matrix-modalities.ts +451 -0
- package/scripts/uat-matrix-report.ts +175 -0
- package/scripts/uat-matrix.ts +353 -0
- package/src/async/index.ts +2 -0
- package/src/async/job-manager.ts +416 -0
- package/src/async/support.ts +5 -0
- package/src/autoresearch/apply-contract-to-state.ts +1 -0
- package/src/autoresearch/command-resume.md +17 -0
- package/src/autoresearch/contract.ts +205 -0
- package/src/autoresearch/dashboard.ts +374 -0
- package/src/autoresearch/git.ts +191 -0
- package/src/autoresearch/helpers.ts +328 -0
- package/src/autoresearch/index.ts +402 -0
- package/src/autoresearch/prompt.md +236 -0
- package/src/autoresearch/resume-message.md +16 -0
- package/src/autoresearch/state.ts +303 -0
- package/src/autoresearch/tools/init-experiment.ts +400 -0
- package/src/autoresearch/tools/log-experiment.ts +793 -0
- package/src/autoresearch/tools/run-experiment.ts +679 -0
- package/src/autoresearch/types.ts +114 -0
- package/src/browser/acquire.ts +249 -0
- package/src/browser/actions.ts +126 -0
- package/src/browser/auth.ts +176 -0
- package/src/browser/ax.ts +134 -0
- package/src/browser/cdp-core.ts +45 -0
- package/src/browser/cdp-page-actions.ts +51 -0
- package/src/browser/chrome-locate.ts +66 -0
- package/src/browser/dom-context.ts +89 -0
- package/src/browser/dt-context.ts +100 -0
- package/src/browser/extension-bridge.ts +182 -0
- package/src/browser/extension-page-actions.ts +397 -0
- package/src/browser/extension-provider.ts +373 -0
- package/src/browser/index.ts +17 -0
- package/src/browser/input-commit.ts +74 -0
- package/src/browser/native-messaging.ts +20 -0
- package/src/browser/page-actions.ts +18 -0
- package/src/browser/provider.ts +155 -0
- package/src/browser/resolver.ts +126 -0
- package/src/browser/selector.ts +40 -0
- package/src/bun-imports.d.ts +22 -0
- package/src/capability/context-file.ts +43 -0
- package/src/capability/extension-module.ts +34 -0
- package/src/capability/extension.ts +47 -0
- package/src/capability/fs.ts +107 -0
- package/src/capability/hook.ts +40 -0
- package/src/capability/index.ts +438 -0
- package/src/capability/instruction.ts +37 -0
- package/src/capability/mcp.ts +74 -0
- package/src/capability/prompt.ts +35 -0
- package/src/capability/rule.ts +224 -0
- package/src/capability/settings.ts +34 -0
- package/src/capability/skill.ts +50 -0
- package/src/capability/slash-command.ts +40 -0
- package/src/capability/ssh.ts +41 -0
- package/src/capability/system-prompt.ts +34 -0
- package/src/capability/tool.ts +38 -0
- package/src/capability/types.ts +168 -0
- package/src/cli/agents-cli.ts +138 -0
- package/src/cli/args.ts +286 -0
- package/src/cli/chrome-cli.ts +88 -0
- package/src/cli/classify-install-target.ts +50 -0
- package/src/cli/commands/init-xdg.ts +27 -0
- package/src/cli/config-cli.ts +418 -0
- package/src/cli/file-processor.ts +121 -0
- package/src/cli/grep-cli.ts +160 -0
- package/src/cli/grievances-cli.ts +78 -0
- package/src/cli/initial-message.ts +58 -0
- package/src/cli/jupyter-cli.ts +106 -0
- package/src/cli/list-models.ts +128 -0
- package/src/cli/plugin-cli.ts +964 -0
- package/src/cli/read-cli.ts +68 -0
- package/src/cli/session-picker.ts +52 -0
- package/src/cli/setup-cli.ts +479 -0
- package/src/cli/shell-cli.ts +174 -0
- package/src/cli/ssh-cli.ts +179 -0
- package/src/cli/stats-cli.ts +182 -0
- package/src/cli/update-cli.ts +446 -0
- package/src/cli/web-search-cli.ts +203 -0
- package/src/cli.ts +123 -0
- package/src/commands/agents.ts +57 -0
- package/src/commands/chrome-host.ts +71 -0
- package/src/commands/chrome.ts +28 -0
- package/src/commands/commit.ts +36 -0
- package/src/commands/config.ts +51 -0
- package/src/commands/grep.ts +48 -0
- package/src/commands/grievances.ts +20 -0
- package/src/commands/jupyter.ts +32 -0
- package/src/commands/launch.ts +144 -0
- package/src/commands/plugin.ts +78 -0
- package/src/commands/read.ts +33 -0
- package/src/commands/setup.ts +42 -0
- package/src/commands/shell.ts +29 -0
- package/src/commands/ssh.ts +60 -0
- package/src/commands/stats.ts +29 -0
- package/src/commands/update.ts +21 -0
- package/src/commands/web-search.ts +46 -0
- package/src/commit/agentic/agent.ts +314 -0
- package/src/commit/agentic/fallback.ts +96 -0
- package/src/commit/agentic/index.ts +354 -0
- package/src/commit/agentic/prompts/analyze-file.md +22 -0
- package/src/commit/agentic/prompts/session-user.md +25 -0
- package/src/commit/agentic/prompts/split-confirm.md +1 -0
- package/src/commit/agentic/prompts/system.md +38 -0
- package/src/commit/agentic/state.ts +60 -0
- package/src/commit/agentic/tools/analyze-file.ts +127 -0
- package/src/commit/agentic/tools/git-file-diff.ts +191 -0
- package/src/commit/agentic/tools/git-hunk.ts +50 -0
- package/src/commit/agentic/tools/git-overview.ts +81 -0
- package/src/commit/agentic/tools/index.ts +54 -0
- package/src/commit/agentic/tools/propose-changelog.ts +139 -0
- package/src/commit/agentic/tools/propose-commit.ts +122 -0
- package/src/commit/agentic/tools/recent-commits.ts +81 -0
- package/src/commit/agentic/tools/schemas.ts +31 -0
- package/src/commit/agentic/tools/split-commit.ts +251 -0
- package/src/commit/agentic/topo-sort.ts +44 -0
- package/src/commit/agentic/trivial.ts +51 -0
- package/src/commit/agentic/validation.ts +183 -0
- package/src/commit/analysis/conventional.ts +122 -0
- package/src/commit/analysis/index.ts +4 -0
- package/src/commit/analysis/scope.ts +242 -0
- package/src/commit/analysis/summary.ts +105 -0
- package/src/commit/analysis/validation.ts +66 -0
- package/src/commit/changelog/detect.ts +40 -0
- package/src/commit/changelog/generate.ts +101 -0
- package/src/commit/changelog/index.ts +234 -0
- package/src/commit/changelog/parse.ts +44 -0
- package/src/commit/cli.ts +85 -0
- package/src/commit/git/diff.ts +148 -0
- package/src/commit/index.ts +5 -0
- package/src/commit/map-reduce/index.ts +69 -0
- package/src/commit/map-reduce/map-phase.ts +193 -0
- package/src/commit/map-reduce/reduce-phase.ts +108 -0
- package/src/commit/map-reduce/utils.ts +9 -0
- package/src/commit/message.ts +11 -0
- package/src/commit/model-selection.ts +66 -0
- package/src/commit/pipeline.ts +242 -0
- package/src/commit/prompts/analysis-system.md +148 -0
- package/src/commit/prompts/analysis-user.md +38 -0
- package/src/commit/prompts/changelog-system.md +50 -0
- package/src/commit/prompts/changelog-user.md +18 -0
- package/src/commit/prompts/file-observer-system.md +24 -0
- package/src/commit/prompts/file-observer-user.md +8 -0
- package/src/commit/prompts/reduce-system.md +50 -0
- package/src/commit/prompts/reduce-user.md +17 -0
- package/src/commit/prompts/summary-retry.md +3 -0
- package/src/commit/prompts/summary-system.md +38 -0
- package/src/commit/prompts/summary-user.md +13 -0
- package/src/commit/prompts/types-description.md +2 -0
- package/src/commit/types.ts +118 -0
- package/src/commit/utils/exclusions.ts +42 -0
- package/src/commit/utils.ts +44 -0
- package/src/config/auto-config.ts +698 -0
- package/src/config/context-schema.json +115 -0
- package/src/config/file-lock.ts +121 -0
- package/src/config/keybindings.ts +493 -0
- package/src/config/mcp-schema.json +230 -0
- package/src/config/model-equivalence.ts +675 -0
- package/src/config/model-registry.ts +2265 -0
- package/src/config/model-resolver.ts +1289 -0
- package/src/config/prompt-templates.ts +271 -0
- package/src/config/resolve-config-value.ts +110 -0
- package/src/config/settings-schema.ts +2155 -0
- package/src/config/settings.ts +730 -0
- package/src/config.ts +418 -0
- package/src/cursor.ts +323 -0
- package/src/dap/client.ts +674 -0
- package/src/dap/config.ts +150 -0
- package/src/dap/defaults.json +211 -0
- package/src/dap/index.ts +4 -0
- package/src/dap/session.ts +1255 -0
- package/src/dap/types.ts +600 -0
- package/src/debug/index.ts +440 -0
- package/src/debug/log-formatting.ts +58 -0
- package/src/debug/log-viewer.ts +908 -0
- package/src/debug/profiler.ts +158 -0
- package/src/debug/report-bundle.ts +365 -0
- package/src/debug/system-info.ts +107 -0
- package/src/discovery/agents-md.ts +67 -0
- package/src/discovery/agents.ts +219 -0
- package/src/discovery/builtin.ts +851 -0
- package/src/discovery/claude-plugins.ts +297 -0
- package/src/discovery/claude.ts +543 -0
- package/src/discovery/cline.ts +83 -0
- package/src/discovery/codex.ts +535 -0
- package/src/discovery/cursor.ts +220 -0
- package/src/discovery/gemini.ts +396 -0
- package/src/discovery/github.ts +118 -0
- package/src/discovery/helpers.ts +934 -0
- package/src/discovery/index.ts +79 -0
- package/src/discovery/language.ts +46 -0
- package/src/discovery/mcp-json.ts +171 -0
- package/src/discovery/opencode.ts +393 -0
- package/src/discovery/plugin-dir-roots.ts +28 -0
- package/src/discovery/ssh.ts +153 -0
- package/src/discovery/substitute-plugin-root.ts +29 -0
- package/src/discovery/vscode.ts +105 -0
- package/src/discovery/windsurf.ts +147 -0
- package/src/edit/diff.ts +818 -0
- package/src/edit/index.ts +481 -0
- package/src/edit/line-hash.ts +67 -0
- package/src/edit/modes/chunk.ts +762 -0
- package/src/edit/modes/hashline.ts +1366 -0
- package/src/edit/modes/patch.ts +1791 -0
- package/src/edit/modes/replace.ts +1115 -0
- package/src/edit/normalize.ts +375 -0
- package/src/edit/renderer.ts +627 -0
- package/src/exa/factory.ts +61 -0
- package/src/exa/index.ts +27 -0
- package/src/exa/mcp-client.ts +293 -0
- package/src/exa/render.ts +232 -0
- package/src/exa/researcher.ts +47 -0
- package/src/exa/search.ts +86 -0
- package/src/exa/types.ts +166 -0
- package/src/exa/websets.ts +247 -0
- package/src/exec/bash-executor.ts +332 -0
- package/src/exec/exec.ts +53 -0
- package/src/exec/idle-timeout-watchdog.ts +126 -0
- package/src/exec/non-interactive-env.ts +48 -0
- package/src/export/custom-share.ts +65 -0
- package/src/export/html/index.ts +161 -0
- package/src/export/html/template.css +1001 -0
- package/src/export/html/template.generated.ts +2 -0
- package/src/export/html/template.html +46 -0
- package/src/export/html/template.js +1950 -0
- package/src/export/html/template.macro.ts +24 -0
- package/src/export/html/vendor/highlight.min.js +1213 -0
- package/src/export/html/vendor/marked.min.js +6 -0
- package/src/export/ttsr.ts +434 -0
- package/src/extensibility/custom-commands/bundled/ci-green/index.ts +25 -0
- package/src/extensibility/custom-commands/bundled/review/index.ts +456 -0
- package/src/extensibility/custom-commands/index.ts +2 -0
- package/src/extensibility/custom-commands/loader.ts +236 -0
- package/src/extensibility/custom-commands/types.ts +111 -0
- package/src/extensibility/custom-tools/index.ts +7 -0
- package/src/extensibility/custom-tools/loader.ts +238 -0
- package/src/extensibility/custom-tools/types.ts +251 -0
- package/src/extensibility/custom-tools/wrapper.ts +47 -0
- package/src/extensibility/extensions/index.ts +15 -0
- package/src/extensibility/extensions/loader.ts +572 -0
- package/src/extensibility/extensions/runner.ts +848 -0
- package/src/extensibility/extensions/types.ts +1394 -0
- package/src/extensibility/extensions/wrapper.ts +191 -0
- package/src/extensibility/hooks/index.ts +5 -0
- package/src/extensibility/hooks/loader.ts +255 -0
- package/src/extensibility/hooks/runner.ts +425 -0
- package/src/extensibility/hooks/tool-wrapper.ts +108 -0
- package/src/extensibility/hooks/types.ts +826 -0
- package/src/extensibility/plugins/doctor.ts +66 -0
- package/src/extensibility/plugins/git-url.ts +281 -0
- package/src/extensibility/plugins/index.ts +9 -0
- package/src/extensibility/plugins/installer.ts +192 -0
- package/src/extensibility/plugins/loader.ts +267 -0
- package/src/extensibility/plugins/manager.ts +731 -0
- package/src/extensibility/plugins/marketplace/cache.ts +136 -0
- package/src/extensibility/plugins/marketplace/fetcher.ts +318 -0
- package/src/extensibility/plugins/marketplace/index.ts +6 -0
- package/src/extensibility/plugins/marketplace/manager.ts +781 -0
- package/src/extensibility/plugins/marketplace/prerequisites.ts +255 -0
- package/src/extensibility/plugins/marketplace/registry.ts +196 -0
- package/src/extensibility/plugins/marketplace/source-resolver.ts +147 -0
- package/src/extensibility/plugins/marketplace/types.ts +201 -0
- package/src/extensibility/plugins/parser.ts +105 -0
- package/src/extensibility/plugins/types.ts +194 -0
- package/src/extensibility/skills.ts +269 -0
- package/src/extensibility/slash-commands.ts +246 -0
- package/src/extensibility/tool-proxy.ts +25 -0
- package/src/extensibility/utils.ts +38 -0
- package/src/index.ts +61 -0
- package/src/internal-urls/agent-protocol.ts +136 -0
- package/src/internal-urls/api-catalog-resolve.ts +495 -0
- package/src/internal-urls/api-catalog-types.ts +94 -0
- package/src/internal-urls/api-spec-resolve.ts +1036 -0
- package/src/internal-urls/api-spec-types.ts +239 -0
- package/src/internal-urls/artifact-protocol.ts +97 -0
- package/src/internal-urls/branding-index.generated.ts +88 -0
- package/src/internal-urls/build-info-runtime.ts +302 -0
- package/src/internal-urls/build-info.generated.ts +33 -0
- package/src/internal-urls/computer-profile.ts +692 -0
- package/src/internal-urls/console-catalog-types.ts +21 -0
- package/src/internal-urls/console-catalog.generated.ts +532 -0
- package/src/internal-urls/console-field-metadata-types.ts +59 -0
- package/src/internal-urls/console-field-metadata.generated.ts +4841 -0
- package/src/internal-urls/console-resolve.ts +178 -0
- package/src/internal-urls/docs-index.generated.ts +698 -0
- package/src/internal-urls/extension-api.md +147 -0
- package/src/internal-urls/index.ts +46 -0
- package/src/internal-urls/jobs-protocol.ts +119 -0
- package/src/internal-urls/json-query.ts +126 -0
- package/src/internal-urls/local-protocol.ts +206 -0
- package/src/internal-urls/mcp-protocol.ts +156 -0
- package/src/internal-urls/memory-protocol.ts +133 -0
- package/src/internal-urls/parse.ts +72 -0
- package/src/internal-urls/profile-collectors.ts +106 -0
- package/src/internal-urls/router.ts +55 -0
- package/src/internal-urls/rule-protocol.ts +55 -0
- package/src/internal-urls/skill-protocol.ts +111 -0
- package/src/internal-urls/terraform-index.generated.ts +1852 -0
- package/src/internal-urls/terraform-resolve.ts +184 -0
- package/src/internal-urls/terraform-types.ts +45 -0
- package/src/internal-urls/types.ts +52 -0
- package/src/internal-urls/user-profile.ts +363 -0
- package/src/internal-urls/xcsh-protocol.ts +644 -0
- package/src/ipy/cancellation.ts +28 -0
- package/src/ipy/executor.ts +1155 -0
- package/src/ipy/gateway-coordinator.ts +424 -0
- package/src/ipy/kernel.ts +1091 -0
- package/src/ipy/modules.ts +144 -0
- package/src/ipy/prelude.py +849 -0
- package/src/ipy/prelude.ts +3 -0
- package/src/ipy/runtime.ts +221 -0
- package/src/locales/ar.json +512 -0
- package/src/locales/de.json +512 -0
- package/src/locales/en.json +549 -0
- package/src/locales/es.json +512 -0
- package/src/locales/fr.json +512 -0
- package/src/locales/hi.json +512 -0
- package/src/locales/index.ts +29 -0
- package/src/locales/it.json +512 -0
- package/src/locales/ja.json +512 -0
- package/src/locales/ko.json +512 -0
- package/src/locales/pt-br.json +512 -0
- package/src/locales/th.json +512 -0
- package/src/locales/zh-cn.json +512 -0
- package/src/locales/zh-tw.json +512 -0
- package/src/lsp/client.ts +941 -0
- package/src/lsp/clients/biome-client.ts +202 -0
- package/src/lsp/clients/index.ts +50 -0
- package/src/lsp/clients/lsp-linter-client.ts +93 -0
- package/src/lsp/clients/swiftlint-client.ts +120 -0
- package/src/lsp/config.ts +418 -0
- package/src/lsp/defaults.json +999 -0
- package/src/lsp/edits.ts +109 -0
- package/src/lsp/index.ts +1746 -0
- package/src/lsp/lspmux.ts +233 -0
- package/src/lsp/render.ts +692 -0
- package/src/lsp/startup-events.ts +13 -0
- package/src/lsp/types.ts +444 -0
- package/src/lsp/utils.ts +691 -0
- package/src/main.ts +944 -0
- package/src/mcp/client.ts +482 -0
- package/src/mcp/config-writer.ts +225 -0
- package/src/mcp/config.ts +365 -0
- package/src/mcp/discoverable-tool-metadata.ts +202 -0
- package/src/mcp/index.ts +29 -0
- package/src/mcp/json-rpc.ts +84 -0
- package/src/mcp/loader.ts +124 -0
- package/src/mcp/manager.ts +1152 -0
- package/src/mcp/oauth-discovery.ts +349 -0
- package/src/mcp/oauth-flow.ts +387 -0
- package/src/mcp/render.ts +157 -0
- package/src/mcp/smithery-auth.ts +104 -0
- package/src/mcp/smithery-connect.ts +145 -0
- package/src/mcp/smithery-registry.ts +477 -0
- package/src/mcp/tool-bridge.ts +417 -0
- package/src/mcp/tool-cache.ts +117 -0
- package/src/mcp/transports/http.ts +475 -0
- package/src/mcp/transports/index.ts +6 -0
- package/src/mcp/transports/stdio.ts +325 -0
- package/src/mcp/types.ts +423 -0
- package/src/memories/index.ts +1115 -0
- package/src/memories/storage.ts +577 -0
- package/src/modes/acp/acp-agent.ts +1361 -0
- package/src/modes/acp/acp-event-mapper.ts +538 -0
- package/src/modes/acp/acp-mode.ts +15 -0
- package/src/modes/acp/index.ts +2 -0
- package/src/modes/components/agent-dashboard.ts +1124 -0
- package/src/modes/components/assistant-message.ts +213 -0
- package/src/modes/components/bash-execution.ts +345 -0
- package/src/modes/components/bordered-loader.ts +41 -0
- package/src/modes/components/branch-summary-message.ts +45 -0
- package/src/modes/components/btw-panel.ts +103 -0
- package/src/modes/components/compaction-summary-message.ts +51 -0
- package/src/modes/components/context-add-wizard.ts +534 -0
- package/src/modes/components/countdown-timer.ts +75 -0
- package/src/modes/components/custom-editor.ts +238 -0
- package/src/modes/components/custom-message.ts +91 -0
- package/src/modes/components/diff.ts +210 -0
- package/src/modes/components/dynamic-border.ts +25 -0
- package/src/modes/components/extensions/extension-dashboard.ts +326 -0
- package/src/modes/components/extensions/extension-list.ts +492 -0
- package/src/modes/components/extensions/index.ts +9 -0
- package/src/modes/components/extensions/inspector-panel.ts +317 -0
- package/src/modes/components/extensions/state-manager.ts +587 -0
- package/src/modes/components/extensions/types.ts +191 -0
- package/src/modes/components/footer.ts +262 -0
- package/src/modes/components/gutter-block.ts +315 -0
- package/src/modes/components/history-search.ts +158 -0
- package/src/modes/components/hook-editor.ts +151 -0
- package/src/modes/components/hook-input.ts +81 -0
- package/src/modes/components/hook-message.ts +100 -0
- package/src/modes/components/hook-selector.ts +192 -0
- package/src/modes/components/index.ts +36 -0
- package/src/modes/components/keybinding-hints.ts +65 -0
- package/src/modes/components/login-dialog.ts +164 -0
- package/src/modes/components/mcp-add-wizard.ts +1314 -0
- package/src/modes/components/model-selector.ts +946 -0
- package/src/modes/components/oauth-selector.ts +211 -0
- package/src/modes/components/plugin-selector.ts +95 -0
- package/src/modes/components/plugin-settings.ts +477 -0
- package/src/modes/components/plugins/index.ts +5 -0
- package/src/modes/components/plugins/plugin-dashboard.ts +523 -0
- package/src/modes/components/plugins/plugin-inspector-pane.ts +84 -0
- package/src/modes/components/plugins/plugin-list-pane.ts +109 -0
- package/src/modes/components/plugins/state-manager.ts +229 -0
- package/src/modes/components/plugins/types.ts +51 -0
- package/src/modes/components/plugins/utils.ts +6 -0
- package/src/modes/components/python-execution.ts +244 -0
- package/src/modes/components/queue-mode-selector.ts +56 -0
- package/src/modes/components/read-tool-group.ts +137 -0
- package/src/modes/components/session-observer-overlay.ts +483 -0
- package/src/modes/components/session-selector.ts +343 -0
- package/src/modes/components/settings-defs.ts +568 -0
- package/src/modes/components/settings-selector.ts +641 -0
- package/src/modes/components/show-images-selector.ts +45 -0
- package/src/modes/components/skill-message.ts +90 -0
- package/src/modes/components/status-line/context-gradient.ts +64 -0
- package/src/modes/components/status-line/git-utils.ts +42 -0
- package/src/modes/components/status-line/hex-ansi.ts +29 -0
- package/src/modes/components/status-line/index.ts +4 -0
- package/src/modes/components/status-line/presets.ts +174 -0
- package/src/modes/components/status-line/segments.ts +494 -0
- package/src/modes/components/status-line/separators.ts +55 -0
- package/src/modes/components/status-line/token-rate.ts +66 -0
- package/src/modes/components/status-line/types.ts +96 -0
- package/src/modes/components/status-line-segment-editor.ts +361 -0
- package/src/modes/components/status-line.ts +729 -0
- package/src/modes/components/theme-selector.ts +63 -0
- package/src/modes/components/thinking-selector.ts +52 -0
- package/src/modes/components/todo-reminder.ts +54 -0
- package/src/modes/components/tool-execution.ts +781 -0
- package/src/modes/components/tree-selector.ts +908 -0
- package/src/modes/components/ttsr-notification.ts +80 -0
- package/src/modes/components/user-message-selector.ts +141 -0
- package/src/modes/components/user-message.ts +100 -0
- package/src/modes/components/visual-truncate.ts +63 -0
- package/src/modes/components/welcome-checks.ts +313 -0
- package/src/modes/components/welcome.ts +270 -0
- package/src/modes/controllers/btw-controller.ts +193 -0
- package/src/modes/controllers/chord-routing.ts +37 -0
- package/src/modes/controllers/command-controller.ts +1293 -0
- package/src/modes/controllers/context-command-controller.ts +61 -0
- package/src/modes/controllers/event-controller.ts +743 -0
- package/src/modes/controllers/extension-ui-controller.ts +983 -0
- package/src/modes/controllers/input-controller.ts +877 -0
- package/src/modes/controllers/mcp-command-controller.ts +1940 -0
- package/src/modes/controllers/selector-controller.ts +1292 -0
- package/src/modes/controllers/ssh-command-controller.ts +421 -0
- package/src/modes/index.ts +34 -0
- package/src/modes/interactive-mode.ts +1781 -0
- package/src/modes/oauth-manual-input.ts +42 -0
- package/src/modes/print-mode.ts +196 -0
- package/src/modes/prompt-action-autocomplete.ts +231 -0
- package/src/modes/rpc/host-tools.ts +186 -0
- package/src/modes/rpc/rpc-client.ts +762 -0
- package/src/modes/rpc/rpc-mode.ts +877 -0
- package/src/modes/rpc/rpc-types.ts +322 -0
- package/src/modes/session-observer-registry.ts +146 -0
- package/src/modes/shared.ts +30 -0
- package/src/modes/theme/defaults/index.ts +7 -0
- package/src/modes/theme/defaults/xcsh-dark.json +113 -0
- package/src/modes/theme/defaults/xcsh-light.json +115 -0
- package/src/modes/theme/mermaid-cache.ts +151 -0
- package/src/modes/theme/mermaid-palette.ts +39 -0
- package/src/modes/theme/theme-schema.json +553 -0
- package/src/modes/theme/theme.ts +2563 -0
- package/src/modes/types.ts +273 -0
- package/src/modes/utils/hotkeys-markdown.ts +60 -0
- package/src/modes/utils/keybinding-matchers.ts +30 -0
- package/src/modes/utils/read-group-outcome-aggregator.ts +55 -0
- package/src/modes/utils/sanitize-error-message.ts +60 -0
- package/src/modes/utils/tools-markdown.ts +28 -0
- package/src/modes/utils/ui-helpers.ts +734 -0
- package/src/plan-mode/approved-plan.ts +55 -0
- package/src/plan-mode/state.ts +6 -0
- package/src/priority.json +37 -0
- package/src/prompts/agents/designer.md +67 -0
- package/src/prompts/agents/explore.md +61 -0
- package/src/prompts/agents/frontmatter.md +10 -0
- package/src/prompts/agents/init.md +36 -0
- package/src/prompts/agents/librarian.md +121 -0
- package/src/prompts/agents/plan.md +49 -0
- package/src/prompts/agents/reviewer.md +127 -0
- package/src/prompts/agents/task.md +16 -0
- package/src/prompts/ci-green-request.md +35 -0
- package/src/prompts/compaction/branch-summary-context.md +5 -0
- package/src/prompts/compaction/branch-summary-preamble.md +2 -0
- package/src/prompts/compaction/branch-summary.md +30 -0
- package/src/prompts/compaction/compaction-short-summary.md +9 -0
- package/src/prompts/compaction/compaction-summary-context.md +5 -0
- package/src/prompts/compaction/compaction-summary.md +38 -0
- package/src/prompts/compaction/compaction-turn-prefix.md +17 -0
- package/src/prompts/compaction/compaction-update-summary.md +45 -0
- package/src/prompts/memories/consolidation.md +30 -0
- package/src/prompts/memories/read-path.md +11 -0
- package/src/prompts/memories/stage_one_input.md +6 -0
- package/src/prompts/memories/stage_one_system.md +21 -0
- package/src/prompts/review-request.md +70 -0
- package/src/prompts/system/agent-creation-architect.md +65 -0
- package/src/prompts/system/agent-creation-user.md +6 -0
- package/src/prompts/system/auto-handoff-threshold-focus.md +1 -0
- package/src/prompts/system/btw-user.md +8 -0
- package/src/prompts/system/commit-message-system.md +2 -0
- package/src/prompts/system/custom-system-prompt.md +82 -0
- package/src/prompts/system/eager-todo.md +13 -0
- package/src/prompts/system/file-operations.md +10 -0
- package/src/prompts/system/handoff-document.md +48 -0
- package/src/prompts/system/plan-mode-active.md +114 -0
- package/src/prompts/system/plan-mode-approved.md +23 -0
- package/src/prompts/system/plan-mode-reference.md +14 -0
- package/src/prompts/system/plan-mode-subagent.md +34 -0
- package/src/prompts/system/plan-mode-tool-decision-reminder.md +9 -0
- package/src/prompts/system/subagent-submit-reminder.md +7 -0
- package/src/prompts/system/subagent-system-prompt.md +36 -0
- package/src/prompts/system/subagent-user-prompt.md +12 -0
- package/src/prompts/system/summarization-system.md +3 -0
- package/src/prompts/system/system-prompt.md +698 -0
- package/src/prompts/system/title-system.md +2 -0
- package/src/prompts/system/ttsr-interrupt.md +7 -0
- package/src/prompts/system/web-search.md +28 -0
- package/src/prompts/tools/ask.md +28 -0
- package/src/prompts/tools/ast-edit.md +48 -0
- package/src/prompts/tools/ast-grep.md +54 -0
- package/src/prompts/tools/async-result.md +5 -0
- package/src/prompts/tools/bash.md +67 -0
- package/src/prompts/tools/browser.md +26 -0
- package/src/prompts/tools/calculator.md +10 -0
- package/src/prompts/tools/cancel-job.md +5 -0
- package/src/prompts/tools/catalog-workflow-runner.md +13 -0
- package/src/prompts/tools/checkpoint.md +16 -0
- package/src/prompts/tools/chunk-edit.md +279 -0
- package/src/prompts/tools/debug.md +43 -0
- package/src/prompts/tools/display-image.md +23 -0
- package/src/prompts/tools/exit-plan-mode.md +41 -0
- package/src/prompts/tools/find.md +26 -0
- package/src/prompts/tools/gemini-image.md +7 -0
- package/src/prompts/tools/grep.md +29 -0
- package/src/prompts/tools/hashline.md +131 -0
- package/src/prompts/tools/inspect-image-system.md +20 -0
- package/src/prompts/tools/inspect-image.md +32 -0
- package/src/prompts/tools/lsp.md +33 -0
- package/src/prompts/tools/patch.md +77 -0
- package/src/prompts/tools/poll.md +5 -0
- package/src/prompts/tools/python.md +60 -0
- package/src/prompts/tools/read-chunk.md +35 -0
- package/src/prompts/tools/read.md +63 -0
- package/src/prompts/tools/render-mermaid.md +9 -0
- package/src/prompts/tools/replace.md +36 -0
- package/src/prompts/tools/resolve.md +8 -0
- package/src/prompts/tools/rewind.md +13 -0
- package/src/prompts/tools/search-tool-bm25.md +34 -0
- package/src/prompts/tools/ssh.md +44 -0
- package/src/prompts/tools/task-summary.md +28 -0
- package/src/prompts/tools/task.md +131 -0
- package/src/prompts/tools/todo-write.md +89 -0
- package/src/prompts/tools/vim.md +98 -0
- package/src/prompts/tools/web-search.md +10 -0
- package/src/prompts/tools/write.md +14 -0
- package/src/prompts/tools/xcsh-api.md +283 -0
- package/src/resource-management/index.ts +42 -0
- package/src/sdk.ts +2123 -0
- package/src/secrets/index.ts +146 -0
- package/src/secrets/obfuscator.ts +290 -0
- package/src/secrets/regex.ts +21 -0
- package/src/services/context-env.ts +102 -0
- package/src/services/xcsh-api-client.ts +230 -0
- package/src/services/xcsh-context-command.ts +803 -0
- package/src/services/xcsh-context-display.ts +49 -0
- package/src/services/xcsh-context-indicators.ts +17 -0
- package/src/services/xcsh-context-segment.ts +39 -0
- package/src/services/xcsh-context.ts +1410 -0
- package/src/services/xcsh-env.ts +107 -0
- package/src/services/xcsh-knowledge.ts +177 -0
- package/src/services/xcsh-table.ts +164 -0
- package/src/session/agent-session.ts +6690 -0
- package/src/session/agent-storage.ts +451 -0
- package/src/session/artifacts.ts +132 -0
- package/src/session/auth-storage.ts +17 -0
- package/src/session/blob-store.ts +135 -0
- package/src/session/compaction/branch-summarization.ts +322 -0
- package/src/session/compaction/compaction.ts +1388 -0
- package/src/session/compaction/index.ts +7 -0
- package/src/session/compaction/pruning.ts +91 -0
- package/src/session/compaction/utils.ts +184 -0
- package/src/session/history-storage.ts +253 -0
- package/src/session/messages.ts +597 -0
- package/src/session/session-dump-format.ts +203 -0
- package/src/session/session-manager.ts +2816 -0
- package/src/session/session-storage.ts +370 -0
- package/src/session/streaming-output.ts +770 -0
- package/src/session/tool-choice-queue.ts +213 -0
- package/src/slash-commands/builtin-registry.ts +1614 -0
- package/src/slash-commands/export-command.ts +178 -0
- package/src/slash-commands/marketplace-install-parser.ts +99 -0
- package/src/slash-commands/resource-commands.ts +250 -0
- package/src/ssh/config-writer.ts +183 -0
- package/src/ssh/connection-manager.ts +445 -0
- package/src/ssh/ssh-executor.ts +131 -0
- package/src/ssh/sshfs-mount.ts +137 -0
- package/src/ssh/utils.ts +8 -0
- package/src/stt/downloader.ts +71 -0
- package/src/stt/index.ts +3 -0
- package/src/stt/recorder.ts +351 -0
- package/src/stt/setup.ts +52 -0
- package/src/stt/stt-controller.ts +160 -0
- package/src/stt/transcribe.py +70 -0
- package/src/stt/transcriber.ts +91 -0
- package/src/system-prompt.ts +688 -0
- package/src/task/agents.ts +166 -0
- package/src/task/commands.ts +131 -0
- package/src/task/discovery.ts +126 -0
- package/src/task/executor.ts +1324 -0
- package/src/task/index.ts +1197 -0
- package/src/task/isolation-backend.ts +72 -0
- package/src/task/name-generator.ts +1577 -0
- package/src/task/output-manager.ts +107 -0
- package/src/task/parallel.ts +116 -0
- package/src/task/render.ts +1035 -0
- package/src/task/subprocess-tool-registry.ts +88 -0
- package/src/task/template.ts +33 -0
- package/src/task/types.ts +230 -0
- package/src/task/worktree.ts +580 -0
- package/src/task/xcsh-command.ts +26 -0
- package/src/thinking.ts +87 -0
- package/src/tools/action-renderer.ts +198 -0
- package/src/tools/archive-reader.ts +315 -0
- package/src/tools/ask.ts +791 -0
- package/src/tools/ast-edit.ts +492 -0
- package/src/tools/ast-grep.ts +453 -0
- package/src/tools/auto-generated-guard.ts +305 -0
- package/src/tools/bash-interactive.ts +383 -0
- package/src/tools/bash-interceptor.ts +67 -0
- package/src/tools/bash-normalize.ts +107 -0
- package/src/tools/bash-skill-urls.ts +246 -0
- package/src/tools/bash.ts +878 -0
- package/src/tools/browser-renderer.ts +129 -0
- package/src/tools/browser.ts +1366 -0
- package/src/tools/calculator.ts +543 -0
- package/src/tools/cancel-job.ts +100 -0
- package/src/tools/catalog-workflow-runner.ts +718 -0
- package/src/tools/checkpoint.ts +133 -0
- package/src/tools/context.ts +39 -0
- package/src/tools/debug.ts +1004 -0
- package/src/tools/display-image-renderer.ts +96 -0
- package/src/tools/display-image.ts +109 -0
- package/src/tools/exit-plan-mode.ts +101 -0
- package/src/tools/fetch.ts +1462 -0
- package/src/tools/find.ts +437 -0
- package/src/tools/fs-cache-invalidation.ts +33 -0
- package/src/tools/gemini-image.ts +1004 -0
- package/src/tools/grep.ts +705 -0
- package/src/tools/index.ts +442 -0
- package/src/tools/inspect-image-renderer.ts +101 -0
- package/src/tools/inspect-image.ts +176 -0
- package/src/tools/json-tree.ts +266 -0
- package/src/tools/jtd-to-json-schema.ts +199 -0
- package/src/tools/jtd-to-typescript.ts +136 -0
- package/src/tools/jtd-utils.ts +102 -0
- package/src/tools/list-limit.ts +40 -0
- package/src/tools/mermaid-renderer.ts +127 -0
- package/src/tools/notebook.ts +288 -0
- package/src/tools/output-meta.ts +588 -0
- package/src/tools/path-utils.ts +560 -0
- package/src/tools/plan-mode-guard.ts +41 -0
- package/src/tools/poll-tool.ts +177 -0
- package/src/tools/puppeteer/00_stealth_tampering.txt +63 -0
- package/src/tools/puppeteer/01_stealth_activity.txt +20 -0
- package/src/tools/puppeteer/02_stealth_hairline.txt +11 -0
- package/src/tools/puppeteer/03_stealth_botd.txt +384 -0
- package/src/tools/puppeteer/04_stealth_iframe.txt +81 -0
- package/src/tools/puppeteer/05_stealth_webgl.txt +75 -0
- package/src/tools/puppeteer/06_stealth_screen.txt +72 -0
- package/src/tools/puppeteer/07_stealth_fonts.txt +97 -0
- package/src/tools/puppeteer/08_stealth_audio.txt +51 -0
- package/src/tools/puppeteer/09_stealth_locale.txt +46 -0
- package/src/tools/puppeteer/10_stealth_plugins.txt +206 -0
- package/src/tools/puppeteer/11_stealth_hardware.txt +8 -0
- package/src/tools/puppeteer/12_stealth_codecs.txt +40 -0
- package/src/tools/puppeteer/13_stealth_worker.txt +74 -0
- package/src/tools/python.ts +1184 -0
- package/src/tools/read.ts +1591 -0
- package/src/tools/render-mermaid.ts +93 -0
- package/src/tools/render-utils.ts +677 -0
- package/src/tools/renderers.ts +82 -0
- package/src/tools/report-tool-issue.ts +80 -0
- package/src/tools/resolve.ts +196 -0
- package/src/tools/review.ts +238 -0
- package/src/tools/search-tool-bm25.ts +288 -0
- package/src/tools/sqlite-reader.ts +623 -0
- package/src/tools/ssh.ts +322 -0
- package/src/tools/submit-result.ts +229 -0
- package/src/tools/todo-render.ts +33 -0
- package/src/tools/todo-write.ts +440 -0
- package/src/tools/tool-errors.ts +62 -0
- package/src/tools/tool-result.ts +93 -0
- package/src/tools/tool-timeouts.ts +30 -0
- package/src/tools/vim.ts +981 -0
- package/src/tools/write.ts +671 -0
- package/src/tools/xcsh-api-renderer.ts +402 -0
- package/src/tools/xcsh-api.ts +887 -0
- package/src/tui/code-cell.ts +101 -0
- package/src/tui/file-list.ts +47 -0
- package/src/tui/index.ts +11 -0
- package/src/tui/output-block.ts +175 -0
- package/src/tui/status-line.ts +39 -0
- package/src/tui/tree-list.ts +84 -0
- package/src/tui/types.ts +15 -0
- package/src/tui/utils.ts +103 -0
- package/src/utils/changelog.ts +98 -0
- package/src/utils/clipboard.ts +80 -0
- package/src/utils/command-args.ts +76 -0
- package/src/utils/commit-message-generator.ts +137 -0
- package/src/utils/edit-mode.ts +50 -0
- package/src/utils/event-bus.ts +33 -0
- package/src/utils/external-editor.ts +65 -0
- package/src/utils/file-display-mode.ts +37 -0
- package/src/utils/file-mentions.ts +376 -0
- package/src/utils/fuzzy.ts +108 -0
- package/src/utils/git.ts +1495 -0
- package/src/utils/gitstatus.ts +140 -0
- package/src/utils/image-convert.ts +27 -0
- package/src/utils/image-loading.ts +98 -0
- package/src/utils/image-passthrough.ts +118 -0
- package/src/utils/image-resize.ts +272 -0
- package/src/utils/image-viewer.ts +17 -0
- package/src/utils/lang-from-path.ts +239 -0
- package/src/utils/markit.ts +81 -0
- package/src/utils/open.ts +20 -0
- package/src/utils/session-color.ts +55 -0
- package/src/utils/shell-snapshot.ts +188 -0
- package/src/utils/title-generator.ts +193 -0
- package/src/utils/tool-choice.ts +28 -0
- package/src/utils/tools-manager.ts +356 -0
- package/src/vim/buffer.ts +309 -0
- package/src/vim/commands.ts +382 -0
- package/src/vim/engine.ts +2426 -0
- package/src/vim/parser.ts +151 -0
- package/src/vim/render.ts +252 -0
- package/src/vim/types.ts +197 -0
- package/src/web/kagi.ts +174 -0
- package/src/web/parallel.ts +346 -0
- package/src/web/scrapers/artifacthub.ts +207 -0
- package/src/web/scrapers/arxiv.ts +83 -0
- package/src/web/scrapers/aur.ts +162 -0
- package/src/web/scrapers/biorxiv.ts +133 -0
- package/src/web/scrapers/bluesky.ts +262 -0
- package/src/web/scrapers/brew.ts +172 -0
- package/src/web/scrapers/cheatsh.ts +68 -0
- package/src/web/scrapers/chocolatey.ts +196 -0
- package/src/web/scrapers/choosealicense.ts +95 -0
- package/src/web/scrapers/cisa-kev.ts +87 -0
- package/src/web/scrapers/clojars.ts +154 -0
- package/src/web/scrapers/coingecko.ts +177 -0
- package/src/web/scrapers/crates-io.ts +110 -0
- package/src/web/scrapers/crossref.ts +136 -0
- package/src/web/scrapers/devto.ts +147 -0
- package/src/web/scrapers/discogs.ts +306 -0
- package/src/web/scrapers/discourse.ts +197 -0
- package/src/web/scrapers/dockerhub.ts +138 -0
- package/src/web/scrapers/docs-rs.ts +653 -0
- package/src/web/scrapers/fdroid.ts +134 -0
- package/src/web/scrapers/firefox-addons.ts +191 -0
- package/src/web/scrapers/flathub.ts +223 -0
- package/src/web/scrapers/github-gist.ts +58 -0
- package/src/web/scrapers/github.ts +452 -0
- package/src/web/scrapers/gitlab.ts +401 -0
- package/src/web/scrapers/go-pkg.ts +266 -0
- package/src/web/scrapers/hackage.ts +140 -0
- package/src/web/scrapers/hackernews.ts +189 -0
- package/src/web/scrapers/hex.ts +105 -0
- package/src/web/scrapers/huggingface.ts +321 -0
- package/src/web/scrapers/iacr.ts +89 -0
- package/src/web/scrapers/index.ts +252 -0
- package/src/web/scrapers/jetbrains-marketplace.ts +159 -0
- package/src/web/scrapers/lemmy.ts +203 -0
- package/src/web/scrapers/lobsters.ts +175 -0
- package/src/web/scrapers/mastodon.ts +292 -0
- package/src/web/scrapers/maven.ts +138 -0
- package/src/web/scrapers/mdn.ts +169 -0
- package/src/web/scrapers/metacpan.ts +222 -0
- package/src/web/scrapers/musicbrainz.ts +250 -0
- package/src/web/scrapers/npm.ts +98 -0
- package/src/web/scrapers/nuget.ts +183 -0
- package/src/web/scrapers/nvd.ts +222 -0
- package/src/web/scrapers/ollama.ts +239 -0
- package/src/web/scrapers/open-vsx.ts +106 -0
- package/src/web/scrapers/opencorporates.ts +292 -0
- package/src/web/scrapers/openlibrary.ts +336 -0
- package/src/web/scrapers/orcid.ts +286 -0
- package/src/web/scrapers/osv.ts +176 -0
- package/src/web/scrapers/packagist.ts +160 -0
- package/src/web/scrapers/pub-dev.ts +143 -0
- package/src/web/scrapers/pubmed.ts +211 -0
- package/src/web/scrapers/pypi.ts +112 -0
- package/src/web/scrapers/rawg.ts +110 -0
- package/src/web/scrapers/readthedocs.ts +120 -0
- package/src/web/scrapers/reddit.ts +95 -0
- package/src/web/scrapers/repology.ts +251 -0
- package/src/web/scrapers/rfc.ts +201 -0
- package/src/web/scrapers/rubygems.ts +103 -0
- package/src/web/scrapers/searchcode.ts +190 -0
- package/src/web/scrapers/sec-edgar.ts +261 -0
- package/src/web/scrapers/semantic-scholar.ts +171 -0
- package/src/web/scrapers/snapcraft.ts +187 -0
- package/src/web/scrapers/sourcegraph.ts +336 -0
- package/src/web/scrapers/spdx.ts +108 -0
- package/src/web/scrapers/spotify.ts +198 -0
- package/src/web/scrapers/stackoverflow.ts +120 -0
- package/src/web/scrapers/terraform.ts +277 -0
- package/src/web/scrapers/tldr.ts +47 -0
- package/src/web/scrapers/twitter.ts +93 -0
- package/src/web/scrapers/types.ts +267 -0
- package/src/web/scrapers/utils.ts +109 -0
- package/src/web/scrapers/vimeo.ts +133 -0
- package/src/web/scrapers/vscode-marketplace.ts +187 -0
- package/src/web/scrapers/w3c.ts +156 -0
- package/src/web/scrapers/wikidata.ts +344 -0
- package/src/web/scrapers/wikipedia.ts +84 -0
- package/src/web/scrapers/youtube.ts +313 -0
- package/src/web/search/errors.ts +120 -0
- package/src/web/search/index.ts +346 -0
- package/src/web/search/params.ts +129 -0
- package/src/web/search/provider.ts +97 -0
- package/src/web/search/providers/anthropic.ts +339 -0
- package/src/web/search/providers/base.ts +35 -0
- package/src/web/search/providers/brave.ts +150 -0
- package/src/web/search/providers/codex.ts +402 -0
- package/src/web/search/providers/exa.ts +264 -0
- package/src/web/search/providers/firecrawl.ts +115 -0
- package/src/web/search/providers/gemini.ts +566 -0
- package/src/web/search/providers/jina.ts +99 -0
- package/src/web/search/providers/kagi.ts +70 -0
- package/src/web/search/providers/kimi.ts +157 -0
- package/src/web/search/providers/parallel.ts +63 -0
- package/src/web/search/providers/perplexity.ts +546 -0
- package/src/web/search/providers/synthetic.ts +113 -0
- package/src/web/search/providers/tavily.ts +162 -0
- package/src/web/search/providers/utils.ts +36 -0
- package/src/web/search/providers/zai.ts +311 -0
- package/src/web/search/render.ts +348 -0
- package/src/web/search/types.ts +438 -0
- 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
|
+
}
|