@cjhyy/code-shell-core 0.5.0-rc.0
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/LICENSE +21 -0
- package/README.md +162 -0
- package/dist/agent/coordinator.d.ts +49 -0
- package/dist/agent/coordinator.js +77 -0
- package/dist/arena/arena.d.ts +43 -0
- package/dist/arena/arena.js +334 -0
- package/dist/arena/context/context-tools.d.ts +16 -0
- package/dist/arena/context/context-tools.js +231 -0
- package/dist/arena/detect-mode.d.ts +20 -0
- package/dist/arena/detect-mode.js +78 -0
- package/dist/arena/digest-builder.d.ts +25 -0
- package/dist/arena/digest-builder.js +120 -0
- package/dist/arena/index.d.ts +29 -0
- package/dist/arena/index.js +29 -0
- package/dist/arena/iterate/convergence.d.ts +25 -0
- package/dist/arena/iterate/convergence.js +103 -0
- package/dist/arena/iterate/formats/index.d.ts +22 -0
- package/dist/arena/iterate/formats/index.js +283 -0
- package/dist/arena/iterate/index.d.ts +11 -0
- package/dist/arena/iterate/index.js +9 -0
- package/dist/arena/iterate/iterative-arena.d.ts +23 -0
- package/dist/arena/iterate/iterative-arena.js +237 -0
- package/dist/arena/iterate/parse.d.ts +42 -0
- package/dist/arena/iterate/parse.js +123 -0
- package/dist/arena/iterate/phases/argue.d.ts +22 -0
- package/dist/arena/iterate/phases/argue.js +159 -0
- package/dist/arena/iterate/phases/revise.d.ts +16 -0
- package/dist/arena/iterate/phases/revise.js +62 -0
- package/dist/arena/iterate/phases/tournament.d.ts +34 -0
- package/dist/arena/iterate/phases/tournament.js +113 -0
- package/dist/arena/iterate/tools/web-tools.d.ts +13 -0
- package/dist/arena/iterate/tools/web-tools.js +54 -0
- package/dist/arena/iterate/types.d.ts +152 -0
- package/dist/arena/iterate/types.js +8 -0
- package/dist/arena/ledger.d.ts +47 -0
- package/dist/arena/ledger.js +151 -0
- package/dist/arena/lenses/architecture.d.ts +5 -0
- package/dist/arena/lenses/architecture.js +22 -0
- package/dist/arena/lenses/engineering.d.ts +5 -0
- package/dist/arena/lenses/engineering.js +22 -0
- package/dist/arena/lenses/general.d.ts +5 -0
- package/dist/arena/lenses/general.js +20 -0
- package/dist/arena/lenses/index.d.ts +16 -0
- package/dist/arena/lenses/index.js +47 -0
- package/dist/arena/lenses/product.d.ts +5 -0
- package/dist/arena/lenses/product.js +22 -0
- package/dist/arena/model-presets.d.ts +23 -0
- package/dist/arena/model-presets.js +44 -0
- package/dist/arena/phases/adjudication.d.ts +24 -0
- package/dist/arena/phases/adjudication.js +144 -0
- package/dist/arena/phases/build-consensus.d.ts +29 -0
- package/dist/arena/phases/build-consensus.js +86 -0
- package/dist/arena/phases/claim-registry.d.ts +26 -0
- package/dist/arena/phases/claim-registry.js +60 -0
- package/dist/arena/phases/cross-review.d.ts +45 -0
- package/dist/arena/phases/cross-review.js +224 -0
- package/dist/arena/phases/debate-rounds.d.ts +27 -0
- package/dist/arena/phases/debate-rounds.js +162 -0
- package/dist/arena/phases/participant-research.d.ts +38 -0
- package/dist/arena/phases/participant-research.js +317 -0
- package/dist/arena/phases/planning-detail-expansion.d.ts +38 -0
- package/dist/arena/phases/planning-detail-expansion.js +121 -0
- package/dist/arena/planner.d.ts +27 -0
- package/dist/arena/planner.js +312 -0
- package/dist/arena/providers/docs.d.ts +6 -0
- package/dist/arena/providers/docs.js +108 -0
- package/dist/arena/providers/git.d.ts +8 -0
- package/dist/arena/providers/git.js +174 -0
- package/dist/arena/providers/index.d.ts +32 -0
- package/dist/arena/providers/index.js +132 -0
- package/dist/arena/providers/none.d.ts +7 -0
- package/dist/arena/providers/none.js +11 -0
- package/dist/arena/providers/repo.d.ts +6 -0
- package/dist/arena/providers/repo.js +255 -0
- package/dist/arena/render/session.d.ts +17 -0
- package/dist/arena/render/session.js +190 -0
- package/dist/arena/render/terminal.d.ts +34 -0
- package/dist/arena/render/terminal.js +286 -0
- package/dist/arena/strategies/discussion.d.ts +25 -0
- package/dist/arena/strategies/discussion.js +143 -0
- package/dist/arena/strategies/index.d.ts +15 -0
- package/dist/arena/strategies/index.js +28 -0
- package/dist/arena/strategies/language-wrapper.d.ts +17 -0
- package/dist/arena/strategies/language-wrapper.js +102 -0
- package/dist/arena/strategies/lens-wrapper.d.ts +16 -0
- package/dist/arena/strategies/lens-wrapper.js +236 -0
- package/dist/arena/strategies/planning.d.ts +30 -0
- package/dist/arena/strategies/planning.js +225 -0
- package/dist/arena/strategies/review.d.ts +26 -0
- package/dist/arena/strategies/review.js +168 -0
- package/dist/arena/strategies/utils.d.ts +39 -0
- package/dist/arena/strategies/utils.js +647 -0
- package/dist/arena/tools/selector.d.ts +17 -0
- package/dist/arena/tools/selector.js +61 -0
- package/dist/arena/transitions.d.ts +48 -0
- package/dist/arena/transitions.js +92 -0
- package/dist/arena/types.d.ts +508 -0
- package/dist/arena/types.js +27 -0
- package/dist/cli/agent-server-stdio.d.ts +32 -0
- package/dist/cli/agent-server-stdio.js +116 -0
- package/dist/colorizer.d.ts +23 -0
- package/dist/colorizer.js +12 -0
- package/dist/context/compaction.d.ts +116 -0
- package/dist/context/compaction.js +534 -0
- package/dist/context/manager.d.ts +145 -0
- package/dist/context/manager.js +423 -0
- package/dist/context/token-counter.d.ts +27 -0
- package/dist/context/token-counter.js +91 -0
- package/dist/context/tool-result-storage.d.ts +96 -0
- package/dist/context/tool-result-storage.js +296 -0
- package/dist/cost-tracker.d.ts +64 -0
- package/dist/cost-tracker.js +314 -0
- package/dist/cron/scheduler.d.ts +34 -0
- package/dist/cron/scheduler.js +115 -0
- package/dist/data/deepseek-models.json +46 -0
- package/dist/data/gemini-models.json +67 -0
- package/dist/data/openai-models.json +175 -0
- package/dist/data/openrouter-models.d.ts +35 -0
- package/dist/data/openrouter-models.js +36 -0
- package/dist/data/openrouter-models.json +4626 -0
- package/dist/data/openrouter-sync.d.ts +16 -0
- package/dist/data/openrouter-sync.js +53 -0
- package/dist/data/static-catalogs.d.ts +25 -0
- package/dist/data/static-catalogs.js +26 -0
- package/dist/data/zai-models.json +56 -0
- package/dist/engine/cost-store.d.ts +22 -0
- package/dist/engine/cost-store.js +15 -0
- package/dist/engine/engine.d.ts +295 -0
- package/dist/engine/engine.js +1467 -0
- package/dist/engine/model-facade.d.ts +24 -0
- package/dist/engine/model-facade.js +194 -0
- package/dist/engine/parse-task.d.ts +59 -0
- package/dist/engine/parse-task.js +135 -0
- package/dist/engine/patch-orphaned-tools.d.ts +52 -0
- package/dist/engine/patch-orphaned-tools.js +95 -0
- package/dist/engine/query.d.ts +50 -0
- package/dist/engine/query.js +107 -0
- package/dist/engine/runtime.d.ts +50 -0
- package/dist/engine/runtime.js +59 -0
- package/dist/engine/streaming-tool-queue.d.ts +34 -0
- package/dist/engine/streaming-tool-queue.js +61 -0
- package/dist/engine/token-budget.d.ts +22 -0
- package/dist/engine/token-budget.js +40 -0
- package/dist/engine/tool-summary.d.ts +13 -0
- package/dist/engine/tool-summary.js +35 -0
- package/dist/engine/turn-loop.d.ts +122 -0
- package/dist/engine/turn-loop.js +602 -0
- package/dist/engine/turn-state.d.ts +20 -0
- package/dist/engine/turn-state.js +17 -0
- package/dist/exceptions.d.ts +61 -0
- package/dist/exceptions.js +116 -0
- package/dist/git/utils.d.ts +35 -0
- package/dist/git/utils.js +98 -0
- package/dist/git/worktree.d.ts +36 -0
- package/dist/git/worktree.js +139 -0
- package/dist/hooks/events.d.ts +114 -0
- package/dist/hooks/events.js +4 -0
- package/dist/hooks/inject.d.ts +19 -0
- package/dist/hooks/inject.js +29 -0
- package/dist/hooks/registry.d.ts +15 -0
- package/dist/hooks/registry.js +84 -0
- package/dist/hooks/shell-runner.d.ts +45 -0
- package/dist/hooks/shell-runner.js +173 -0
- package/dist/index.d.ts +117 -0
- package/dist/index.js +145 -0
- package/dist/llm/api-key-sanitize.d.ts +22 -0
- package/dist/llm/api-key-sanitize.js +81 -0
- package/dist/llm/capabilities/index.d.ts +20 -0
- package/dist/llm/capabilities/index.js +39 -0
- package/dist/llm/capabilities/rules.d.ts +26 -0
- package/dist/llm/capabilities/rules.js +215 -0
- package/dist/llm/capabilities/types.d.ts +114 -0
- package/dist/llm/capabilities/types.js +24 -0
- package/dist/llm/client-base.d.ts +29 -0
- package/dist/llm/client-base.js +137 -0
- package/dist/llm/client-factory.d.ts +10 -0
- package/dist/llm/client-factory.js +29 -0
- package/dist/llm/model-cache.d.ts +21 -0
- package/dist/llm/model-cache.js +46 -0
- package/dist/llm/model-fetcher.d.ts +29 -0
- package/dist/llm/model-fetcher.js +282 -0
- package/dist/llm/model-pool.d.ts +95 -0
- package/dist/llm/model-pool.js +246 -0
- package/dist/llm/provider-catalog.d.ts +32 -0
- package/dist/llm/provider-catalog.js +50 -0
- package/dist/llm/provider-kinds.d.ts +21 -0
- package/dist/llm/provider-kinds.js +132 -0
- package/dist/llm/providers/anthropic.d.ts +19 -0
- package/dist/llm/providers/anthropic.js +267 -0
- package/dist/llm/providers/openai.d.ts +64 -0
- package/dist/llm/providers/openai.js +606 -0
- package/dist/llm/retry.d.ts +12 -0
- package/dist/llm/retry.js +17 -0
- package/dist/llm/stream-watchdog.d.ts +42 -0
- package/dist/llm/stream-watchdog.js +70 -0
- package/dist/llm/token-counter.d.ts +17 -0
- package/dist/llm/token-counter.js +36 -0
- package/dist/llm/types.d.ts +37 -0
- package/dist/llm/types.js +4 -0
- package/dist/logging/logger.d.ts +109 -0
- package/dist/logging/logger.js +390 -0
- package/dist/logging/sanitize-messages.d.ts +42 -0
- package/dist/logging/sanitize-messages.js +150 -0
- package/dist/logging/session-recorder.d.ts +90 -0
- package/dist/logging/session-recorder.js +304 -0
- package/dist/lsp/client.d.ts +41 -0
- package/dist/lsp/client.js +166 -0
- package/dist/lsp/manager.d.ts +40 -0
- package/dist/lsp/manager.js +124 -0
- package/dist/lsp/servers.d.ts +16 -0
- package/dist/lsp/servers.js +60 -0
- package/dist/migrate-models.d.ts +45 -0
- package/dist/migrate-models.js +179 -0
- package/dist/onboarding.d.ts +189 -0
- package/dist/onboarding.js +625 -0
- package/dist/plugins/gitOps.d.ts +32 -0
- package/dist/plugins/gitOps.js +62 -0
- package/dist/plugins/installedPlugins.d.ts +15 -0
- package/dist/plugins/installedPlugins.js +56 -0
- package/dist/plugins/knownMarketplaces.d.ts +10 -0
- package/dist/plugins/knownMarketplaces.js +46 -0
- package/dist/plugins/loadPluginHooks.d.ts +52 -0
- package/dist/plugins/loadPluginHooks.js +162 -0
- package/dist/plugins/marketplaceManager.d.ts +49 -0
- package/dist/plugins/marketplaceManager.js +142 -0
- package/dist/plugins/parseMarketplaceInput.d.ts +16 -0
- package/dist/plugins/parseMarketplaceInput.js +73 -0
- package/dist/plugins/pluginCommandHook.d.ts +54 -0
- package/dist/plugins/pluginCommandHook.js +180 -0
- package/dist/plugins/pluginCommandsLoader.d.ts +25 -0
- package/dist/plugins/pluginCommandsLoader.js +114 -0
- package/dist/plugins/pluginInstaller.d.ts +36 -0
- package/dist/plugins/pluginInstaller.js +228 -0
- package/dist/plugins/schemas.d.ts +9 -0
- package/dist/plugins/schemas.js +136 -0
- package/dist/plugins/types.d.ts +75 -0
- package/dist/plugins/types.js +7 -0
- package/dist/plugins/varRewrite.d.ts +42 -0
- package/dist/plugins/varRewrite.js +129 -0
- package/dist/preset/index.d.ts +60 -0
- package/dist/preset/index.js +159 -0
- package/dist/product/define.d.ts +60 -0
- package/dist/product/define.js +123 -0
- package/dist/product/index.d.ts +5 -0
- package/dist/product/index.js +4 -0
- package/dist/product/types.d.ts +111 -0
- package/dist/product/types.js +21 -0
- package/dist/prompt/composer.d.ts +49 -0
- package/dist/prompt/composer.js +168 -0
- package/dist/prompt/instruction-scanner.d.ts +54 -0
- package/dist/prompt/instruction-scanner.js +187 -0
- package/dist/prompt/section-cache.d.ts +15 -0
- package/dist/prompt/section-cache.js +31 -0
- package/dist/prompt/section-loader.d.ts +26 -0
- package/dist/prompt/section-loader.js +53 -0
- package/dist/prompt/sections/base.md +35 -0
- package/dist/prompt/sections/coding.md +31 -0
- package/dist/prompt/sections/orchestration.md +16 -0
- package/dist/prompt/sections/tone.md +9 -0
- package/dist/protocol/chat-session-manager.d.ts +33 -0
- package/dist/protocol/chat-session-manager.js +65 -0
- package/dist/protocol/chat-session.d.ts +49 -0
- package/dist/protocol/chat-session.js +86 -0
- package/dist/protocol/client.d.ts +104 -0
- package/dist/protocol/client.js +260 -0
- package/dist/protocol/factories.d.ts +93 -0
- package/dist/protocol/factories.js +64 -0
- package/dist/protocol/helpers.d.ts +42 -0
- package/dist/protocol/helpers.js +55 -0
- package/dist/protocol/index.d.ts +4 -0
- package/dist/protocol/index.js +4 -0
- package/dist/protocol/server.d.ts +80 -0
- package/dist/protocol/server.js +855 -0
- package/dist/protocol/transport.d.ts +37 -0
- package/dist/protocol/transport.js +85 -0
- package/dist/protocol/types.d.ts +221 -0
- package/dist/protocol/types.js +61 -0
- package/dist/remote/bridge.d.ts +37 -0
- package/dist/remote/bridge.js +103 -0
- package/dist/run/ArtifactTracker.d.ts +38 -0
- package/dist/run/ArtifactTracker.js +132 -0
- package/dist/run/CheckpointWriter.d.ts +53 -0
- package/dist/run/CheckpointWriter.js +135 -0
- package/dist/run/EngineRunner.d.ts +72 -0
- package/dist/run/EngineRunner.js +119 -0
- package/dist/run/Evaluator.d.ts +56 -0
- package/dist/run/Evaluator.js +62 -0
- package/dist/run/FileRunStore.d.ts +39 -0
- package/dist/run/FileRunStore.js +176 -0
- package/dist/run/Heartbeat.d.ts +54 -0
- package/dist/run/Heartbeat.js +123 -0
- package/dist/run/RunApprovalBackend.d.ts +53 -0
- package/dist/run/RunApprovalBackend.js +85 -0
- package/dist/run/RunLock.d.ts +40 -0
- package/dist/run/RunLock.js +98 -0
- package/dist/run/RunManager.d.ts +82 -0
- package/dist/run/RunManager.js +587 -0
- package/dist/run/RunQueue.d.ts +27 -0
- package/dist/run/RunQueue.js +73 -0
- package/dist/run/RunStore.d.ts +25 -0
- package/dist/run/RunStore.js +9 -0
- package/dist/run/factory.d.ts +63 -0
- package/dist/run/factory.js +51 -0
- package/dist/run/index.d.ts +17 -0
- package/dist/run/index.js +23 -0
- package/dist/run/types.d.ts +136 -0
- package/dist/run/types.js +28 -0
- package/dist/runtime/safe-spawn.d.ts +118 -0
- package/dist/runtime/safe-spawn.js +268 -0
- package/dist/services/analytics.d.ts +29 -0
- package/dist/services/analytics.js +84 -0
- package/dist/services/auto-dream.d.ts +49 -0
- package/dist/services/auto-dream.js +124 -0
- package/dist/services/diagnostics.d.ts +41 -0
- package/dist/services/diagnostics.js +99 -0
- package/dist/services/extract-memories.d.ts +31 -0
- package/dist/services/extract-memories.js +71 -0
- package/dist/services/index.d.ts +11 -0
- package/dist/services/index.js +17 -0
- package/dist/services/memory-orchestrator.d.ts +60 -0
- package/dist/services/memory-orchestrator.js +133 -0
- package/dist/services/notifier.d.ts +25 -0
- package/dist/services/notifier.js +69 -0
- package/dist/services/oauth.d.ts +27 -0
- package/dist/services/oauth.js +153 -0
- package/dist/services/session-memory.d.ts +37 -0
- package/dist/services/session-memory.js +81 -0
- package/dist/session/file-history.d.ts +41 -0
- package/dist/session/file-history.js +115 -0
- package/dist/session/memory.d.ts +104 -0
- package/dist/session/memory.js +310 -0
- package/dist/session/session-manager.d.ts +41 -0
- package/dist/session/session-manager.js +261 -0
- package/dist/session/transcript.d.ts +39 -0
- package/dist/session/transcript.js +186 -0
- package/dist/settings/manager.d.ts +36 -0
- package/dist/settings/manager.js +187 -0
- package/dist/settings/schema.d.ts +1219 -0
- package/dist/settings/schema.js +246 -0
- package/dist/skills/frontmatter.d.ts +13 -0
- package/dist/skills/frontmatter.js +70 -0
- package/dist/skills/index.d.ts +7 -0
- package/dist/skills/index.js +6 -0
- package/dist/skills/scanner.d.ts +31 -0
- package/dist/skills/scanner.js +171 -0
- package/dist/state.d.ts +160 -0
- package/dist/state.js +267 -0
- package/dist/tool-system/builtin/agent-notifications.d.ts +84 -0
- package/dist/tool-system/builtin/agent-notifications.js +197 -0
- package/dist/tool-system/builtin/agent-registry.d.ts +67 -0
- package/dist/tool-system/builtin/agent-registry.js +126 -0
- package/dist/tool-system/builtin/agent-transcript-translator.d.ts +22 -0
- package/dist/tool-system/builtin/agent-transcript-translator.js +160 -0
- package/dist/tool-system/builtin/agent.d.ts +16 -0
- package/dist/tool-system/builtin/agent.js +364 -0
- package/dist/tool-system/builtin/apply-patch/applier.d.ts +26 -0
- package/dist/tool-system/builtin/apply-patch/applier.js +250 -0
- package/dist/tool-system/builtin/apply-patch/index.d.ts +20 -0
- package/dist/tool-system/builtin/apply-patch/index.js +101 -0
- package/dist/tool-system/builtin/apply-patch/parser.d.ts +17 -0
- package/dist/tool-system/builtin/apply-patch/parser.js +212 -0
- package/dist/tool-system/builtin/apply-patch/seek-sequence.d.ts +18 -0
- package/dist/tool-system/builtin/apply-patch/seek-sequence.js +123 -0
- package/dist/tool-system/builtin/apply-patch/types.d.ts +49 -0
- package/dist/tool-system/builtin/apply-patch/types.js +13 -0
- package/dist/tool-system/builtin/arena.d.ts +31 -0
- package/dist/tool-system/builtin/arena.js +416 -0
- package/dist/tool-system/builtin/ask-user.d.ts +20 -0
- package/dist/tool-system/builtin/ask-user.js +99 -0
- package/dist/tool-system/builtin/bash.d.ts +21 -0
- package/dist/tool-system/builtin/bash.js +149 -0
- package/dist/tool-system/builtin/brief.d.ts +6 -0
- package/dist/tool-system/builtin/brief.js +41 -0
- package/dist/tool-system/builtin/config.d.ts +6 -0
- package/dist/tool-system/builtin/config.js +67 -0
- package/dist/tool-system/builtin/cron.d.ts +10 -0
- package/dist/tool-system/builtin/cron.js +61 -0
- package/dist/tool-system/builtin/edit.d.ts +6 -0
- package/dist/tool-system/builtin/edit.js +100 -0
- package/dist/tool-system/builtin/file-cache.d.ts +11 -0
- package/dist/tool-system/builtin/file-cache.js +39 -0
- package/dist/tool-system/builtin/glob.d.ts +7 -0
- package/dist/tool-system/builtin/glob.js +76 -0
- package/dist/tool-system/builtin/grep.d.ts +7 -0
- package/dist/tool-system/builtin/grep.js +150 -0
- package/dist/tool-system/builtin/index.d.ts +20 -0
- package/dist/tool-system/builtin/index.js +449 -0
- package/dist/tool-system/builtin/lsp.d.ts +6 -0
- package/dist/tool-system/builtin/lsp.js +141 -0
- package/dist/tool-system/builtin/mcp-tools.d.ts +10 -0
- package/dist/tool-system/builtin/mcp-tools.js +102 -0
- package/dist/tool-system/builtin/memory.d.ts +26 -0
- package/dist/tool-system/builtin/memory.js +226 -0
- package/dist/tool-system/builtin/notebook-edit.d.ts +6 -0
- package/dist/tool-system/builtin/notebook-edit.js +124 -0
- package/dist/tool-system/builtin/plan.d.ts +15 -0
- package/dist/tool-system/builtin/plan.js +55 -0
- package/dist/tool-system/builtin/powershell.d.ts +11 -0
- package/dist/tool-system/builtin/powershell.js +64 -0
- package/dist/tool-system/builtin/read.d.ts +6 -0
- package/dist/tool-system/builtin/read.js +70 -0
- package/dist/tool-system/builtin/remote-trigger.d.ts +6 -0
- package/dist/tool-system/builtin/remote-trigger.js +54 -0
- package/dist/tool-system/builtin/repl.d.ts +11 -0
- package/dist/tool-system/builtin/repl.js +82 -0
- package/dist/tool-system/builtin/send-message.d.ts +6 -0
- package/dist/tool-system/builtin/send-message.js +47 -0
- package/dist/tool-system/builtin/skill-prompt.d.ts +20 -0
- package/dist/tool-system/builtin/skill-prompt.js +52 -0
- package/dist/tool-system/builtin/skill.d.ts +9 -0
- package/dist/tool-system/builtin/skill.js +55 -0
- package/dist/tool-system/builtin/sleep.d.ts +6 -0
- package/dist/tool-system/builtin/sleep.js +33 -0
- package/dist/tool-system/builtin/task.d.ts +48 -0
- package/dist/tool-system/builtin/task.js +139 -0
- package/dist/tool-system/builtin/tool-search.d.ts +11 -0
- package/dist/tool-system/builtin/tool-search.js +90 -0
- package/dist/tool-system/builtin/web-fetch.d.ts +10 -0
- package/dist/tool-system/builtin/web-fetch.js +328 -0
- package/dist/tool-system/builtin/web-search.d.ts +25 -0
- package/dist/tool-system/builtin/web-search.js +174 -0
- package/dist/tool-system/builtin/worktree.d.ts +10 -0
- package/dist/tool-system/builtin/worktree.js +95 -0
- package/dist/tool-system/builtin/write.d.ts +6 -0
- package/dist/tool-system/builtin/write.js +36 -0
- package/dist/tool-system/context.d.ts +165 -0
- package/dist/tool-system/context.js +18 -0
- package/dist/tool-system/executor.d.ts +49 -0
- package/dist/tool-system/executor.js +495 -0
- package/dist/tool-system/investigation-guard.d.ts +46 -0
- package/dist/tool-system/investigation-guard.js +155 -0
- package/dist/tool-system/mcp-manager.d.ts +67 -0
- package/dist/tool-system/mcp-manager.js +249 -0
- package/dist/tool-system/permission.d.ts +111 -0
- package/dist/tool-system/permission.js +774 -0
- package/dist/tool-system/registry.d.ts +32 -0
- package/dist/tool-system/registry.js +131 -0
- package/dist/tool-system/sandbox/bwrap.d.ts +13 -0
- package/dist/tool-system/sandbox/bwrap.js +63 -0
- package/dist/tool-system/sandbox/index.d.ts +78 -0
- package/dist/tool-system/sandbox/index.js +222 -0
- package/dist/tool-system/sandbox/off.d.ts +2 -0
- package/dist/tool-system/sandbox/off.js +8 -0
- package/dist/tool-system/sandbox/seatbelt.d.ts +18 -0
- package/dist/tool-system/sandbox/seatbelt.js +109 -0
- package/dist/tool-system/task-guard.d.ts +29 -0
- package/dist/tool-system/task-guard.js +70 -0
- package/dist/tool-system/validation.d.ts +5 -0
- package/dist/tool-system/validation.js +39 -0
- package/dist/types.d.ts +376 -0
- package/dist/types.js +4 -0
- package/dist/updater.d.ts +65 -0
- package/dist/updater.js +405 -0
- package/dist/utils/debug.d.ts +41 -0
- package/dist/utils/debug.js +110 -0
- package/dist/utils/earlyInput.d.ts +43 -0
- package/dist/utils/earlyInput.js +166 -0
- package/dist/utils/env.d.ts +24 -0
- package/dist/utils/env.js +104 -0
- package/dist/utils/envUtils.d.ts +51 -0
- package/dist/utils/envUtils.js +135 -0
- package/dist/utils/execFileNoThrow.d.ts +39 -0
- package/dist/utils/execFileNoThrow.js +74 -0
- package/dist/utils/format.d.ts +44 -0
- package/dist/utils/format.js +236 -0
- package/dist/utils/intl.d.ts +22 -0
- package/dist/utils/intl.js +83 -0
- package/dist/utils/lockfile.d.ts +15 -0
- package/dist/utils/lockfile.js +30 -0
- package/dist/utils/memoize.d.ts +19 -0
- package/dist/utils/memoize.js +14 -0
- package/dist/utils/semver.d.ts +6 -0
- package/dist/utils/semver.js +13 -0
- package/dist/utils/sliceAnsi.d.ts +12 -0
- package/dist/utils/sliceAnsi.js +62 -0
- package/dist/utils/systemTheme.d.ts +40 -0
- package/dist/utils/systemTheme.js +108 -0
- package/dist/utils/task-sanitizer.d.ts +6 -0
- package/dist/utils/task-sanitizer.js +24 -0
- package/dist/utils/theme.d.ts +93 -0
- package/dist/utils/theme.js +544 -0
- package/dist/utils/toolDisplay.d.ts +31 -0
- package/dist/utils/toolDisplay.js +188 -0
- package/package.json +72 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LSP client — JSON-RPC over stdio communication with language servers.
|
|
3
|
+
*/
|
|
4
|
+
import { spawn } from "node:child_process";
|
|
5
|
+
import { EventEmitter } from "node:events";
|
|
6
|
+
export class LSPClient extends EventEmitter {
|
|
7
|
+
command;
|
|
8
|
+
args;
|
|
9
|
+
cwd;
|
|
10
|
+
process;
|
|
11
|
+
nextId = 1;
|
|
12
|
+
pending = new Map();
|
|
13
|
+
buffer = "";
|
|
14
|
+
contentLength = -1;
|
|
15
|
+
initialized = false;
|
|
16
|
+
constructor(command, args = [], cwd) {
|
|
17
|
+
super();
|
|
18
|
+
this.command = command;
|
|
19
|
+
this.args = args;
|
|
20
|
+
this.cwd = cwd;
|
|
21
|
+
}
|
|
22
|
+
async start() {
|
|
23
|
+
this.process = spawn(this.command, this.args, {
|
|
24
|
+
cwd: this.cwd,
|
|
25
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
26
|
+
});
|
|
27
|
+
this.process.stdout?.on("data", (data) => this.handleData(data.toString()));
|
|
28
|
+
this.process.stderr?.on("data", (_data) => {
|
|
29
|
+
// LSP servers often log to stderr — ignore
|
|
30
|
+
});
|
|
31
|
+
this.process.on("exit", (code) => {
|
|
32
|
+
this.emit("exit", code);
|
|
33
|
+
this.rejectAll(new Error(`LSP server exited with code ${code}`));
|
|
34
|
+
});
|
|
35
|
+
// Don't keep the event loop alive solely for the LSP child.
|
|
36
|
+
// Call after listeners are wired so event registration doesn't re-ref.
|
|
37
|
+
this.process.unref();
|
|
38
|
+
}
|
|
39
|
+
async initialize(rootUri) {
|
|
40
|
+
const result = await this.request("initialize", {
|
|
41
|
+
processId: process.pid,
|
|
42
|
+
rootUri,
|
|
43
|
+
capabilities: {
|
|
44
|
+
textDocument: {
|
|
45
|
+
definition: { dynamicRegistration: false },
|
|
46
|
+
references: { dynamicRegistration: false },
|
|
47
|
+
hover: { contentFormat: ["plaintext", "markdown"] },
|
|
48
|
+
documentSymbol: { dynamicRegistration: false },
|
|
49
|
+
completion: { dynamicRegistration: false },
|
|
50
|
+
},
|
|
51
|
+
workspace: {
|
|
52
|
+
symbol: { dynamicRegistration: false },
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
await this.notify("initialized", {});
|
|
57
|
+
this.initialized = true;
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
async request(method, params) {
|
|
61
|
+
if (!this.process?.stdin)
|
|
62
|
+
throw new Error("LSP server not started");
|
|
63
|
+
const id = this.nextId++;
|
|
64
|
+
const message = { jsonrpc: "2.0", id, method, params };
|
|
65
|
+
const content = JSON.stringify(message);
|
|
66
|
+
const header = `Content-Length: ${Buffer.byteLength(content)}\r\n\r\n`;
|
|
67
|
+
return new Promise((resolve, reject) => {
|
|
68
|
+
const timer = setTimeout(() => {
|
|
69
|
+
if (this.pending.has(id)) {
|
|
70
|
+
this.pending.delete(id);
|
|
71
|
+
reject(new Error(`LSP request "${method}" timed out`));
|
|
72
|
+
}
|
|
73
|
+
}, 30000);
|
|
74
|
+
// Don't let the timer keep the event loop alive by itself
|
|
75
|
+
timer.unref?.();
|
|
76
|
+
this.pending.set(id, {
|
|
77
|
+
resolve: (value) => { clearTimeout(timer); resolve(value); },
|
|
78
|
+
reject: (err) => { clearTimeout(timer); reject(err); },
|
|
79
|
+
});
|
|
80
|
+
this.process.stdin.write(header + content);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
async notify(method, params) {
|
|
84
|
+
if (!this.process?.stdin)
|
|
85
|
+
throw new Error("LSP server not started");
|
|
86
|
+
const message = { jsonrpc: "2.0", method, params };
|
|
87
|
+
const content = JSON.stringify(message);
|
|
88
|
+
const header = `Content-Length: ${Buffer.byteLength(content)}\r\n\r\n`;
|
|
89
|
+
this.process.stdin.write(header + content);
|
|
90
|
+
}
|
|
91
|
+
async shutdown() {
|
|
92
|
+
if (!this.process)
|
|
93
|
+
return;
|
|
94
|
+
try {
|
|
95
|
+
await this.request("shutdown", {});
|
|
96
|
+
await this.notify("exit", {});
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// Force kill
|
|
100
|
+
}
|
|
101
|
+
this.process.stdout?.removeAllListeners();
|
|
102
|
+
this.process.stderr?.removeAllListeners();
|
|
103
|
+
this.process.removeAllListeners();
|
|
104
|
+
this.process.kill();
|
|
105
|
+
this.process = undefined;
|
|
106
|
+
// Drain pending requests
|
|
107
|
+
for (const { reject } of this.pending.values()) {
|
|
108
|
+
reject(new Error("LSP server shut down"));
|
|
109
|
+
}
|
|
110
|
+
this.pending.clear();
|
|
111
|
+
}
|
|
112
|
+
get isInitialized() {
|
|
113
|
+
return this.initialized;
|
|
114
|
+
}
|
|
115
|
+
get isAlive() {
|
|
116
|
+
return this.process !== undefined && !this.process.killed;
|
|
117
|
+
}
|
|
118
|
+
handleData(data) {
|
|
119
|
+
this.buffer += data;
|
|
120
|
+
while (true) {
|
|
121
|
+
if (this.contentLength < 0) {
|
|
122
|
+
const headerEnd = this.buffer.indexOf("\r\n\r\n");
|
|
123
|
+
if (headerEnd < 0)
|
|
124
|
+
break;
|
|
125
|
+
const header = this.buffer.slice(0, headerEnd);
|
|
126
|
+
const match = header.match(/Content-Length:\s*(\d+)/i);
|
|
127
|
+
if (!match) {
|
|
128
|
+
this.buffer = this.buffer.slice(headerEnd + 4);
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
this.contentLength = parseInt(match[1], 10);
|
|
132
|
+
this.buffer = this.buffer.slice(headerEnd + 4);
|
|
133
|
+
}
|
|
134
|
+
if (this.buffer.length < this.contentLength)
|
|
135
|
+
break;
|
|
136
|
+
const content = this.buffer.slice(0, this.contentLength);
|
|
137
|
+
this.buffer = this.buffer.slice(this.contentLength);
|
|
138
|
+
this.contentLength = -1;
|
|
139
|
+
try {
|
|
140
|
+
const message = JSON.parse(content);
|
|
141
|
+
if ("id" in message && this.pending.has(message.id)) {
|
|
142
|
+
const { resolve, reject } = this.pending.get(message.id);
|
|
143
|
+
this.pending.delete(message.id);
|
|
144
|
+
if (message.error) {
|
|
145
|
+
reject(new Error(`LSP error: ${message.error.message}`));
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
resolve(message.result);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
else if ("method" in message && !("id" in message)) {
|
|
152
|
+
this.emit("notification", message);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
// Skip malformed messages
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
rejectAll(error) {
|
|
161
|
+
for (const { reject } of this.pending.values()) {
|
|
162
|
+
reject(error);
|
|
163
|
+
}
|
|
164
|
+
this.pending.clear();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LSP Server Manager — manages lifecycle of language server instances.
|
|
3
|
+
* Lazy initialization: servers start only when needed.
|
|
4
|
+
*/
|
|
5
|
+
import { LSPClient } from "./client.js";
|
|
6
|
+
type ServerState = "stopped" | "starting" | "ready" | "error";
|
|
7
|
+
export declare class LSPServerManager {
|
|
8
|
+
private servers;
|
|
9
|
+
private rootUri;
|
|
10
|
+
constructor(cwd: string);
|
|
11
|
+
/**
|
|
12
|
+
* Get or start a language server by name.
|
|
13
|
+
*/
|
|
14
|
+
getClient(serverName: string): Promise<LSPClient | undefined>;
|
|
15
|
+
/**
|
|
16
|
+
* Start a specific language server.
|
|
17
|
+
*/
|
|
18
|
+
private startServer;
|
|
19
|
+
/**
|
|
20
|
+
* Check if any LSP server is connected.
|
|
21
|
+
*/
|
|
22
|
+
isConnected(): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* List server statuses.
|
|
25
|
+
*/
|
|
26
|
+
listServers(): Array<{
|
|
27
|
+
name: string;
|
|
28
|
+
language: string;
|
|
29
|
+
state: ServerState;
|
|
30
|
+
error?: string;
|
|
31
|
+
}>;
|
|
32
|
+
/**
|
|
33
|
+
* Shutdown all servers.
|
|
34
|
+
*/
|
|
35
|
+
shutdownAll(): Promise<void>;
|
|
36
|
+
private isCommandAvailable;
|
|
37
|
+
}
|
|
38
|
+
export declare function initializeLSPManager(cwd: string): LSPServerManager;
|
|
39
|
+
export declare function getLSPManager(): LSPServerManager | undefined;
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LSP Server Manager — manages lifecycle of language server instances.
|
|
3
|
+
* Lazy initialization: servers start only when needed.
|
|
4
|
+
*/
|
|
5
|
+
import { LSPClient } from "./client.js";
|
|
6
|
+
import { BUILTIN_LSP_SERVERS } from "./servers.js";
|
|
7
|
+
import { execSync } from "node:child_process";
|
|
8
|
+
import { pathToFileURL } from "node:url";
|
|
9
|
+
export class LSPServerManager {
|
|
10
|
+
servers = new Map();
|
|
11
|
+
rootUri;
|
|
12
|
+
constructor(cwd) {
|
|
13
|
+
this.rootUri = pathToFileURL(cwd).href;
|
|
14
|
+
// Register all built-in servers
|
|
15
|
+
for (const config of BUILTIN_LSP_SERVERS) {
|
|
16
|
+
this.servers.set(config.name, { config, client: undefined, state: "stopped" });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Get or start a language server by name.
|
|
21
|
+
*/
|
|
22
|
+
async getClient(serverName) {
|
|
23
|
+
const managed = this.servers.get(serverName);
|
|
24
|
+
if (!managed)
|
|
25
|
+
return undefined;
|
|
26
|
+
if (managed.state === "ready" && managed.client?.isAlive) {
|
|
27
|
+
return managed.client;
|
|
28
|
+
}
|
|
29
|
+
if (managed.state === "starting") {
|
|
30
|
+
// Wait for it to be ready
|
|
31
|
+
await new Promise((r) => setTimeout(r, 2000));
|
|
32
|
+
return managed.client;
|
|
33
|
+
}
|
|
34
|
+
// Try to start
|
|
35
|
+
return this.startServer(serverName);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Start a specific language server.
|
|
39
|
+
*/
|
|
40
|
+
async startServer(name) {
|
|
41
|
+
const managed = this.servers.get(name);
|
|
42
|
+
if (!managed)
|
|
43
|
+
return undefined;
|
|
44
|
+
// Check if command is available
|
|
45
|
+
if (!this.isCommandAvailable(managed.config.command)) {
|
|
46
|
+
managed.state = "error";
|
|
47
|
+
managed.error = `${managed.config.command} not found. Install: ${managed.config.installHint}`;
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
managed.state = "starting";
|
|
51
|
+
try {
|
|
52
|
+
const client = new LSPClient(managed.config.command, managed.config.args, this.rootUri.replace("file://", ""));
|
|
53
|
+
await client.start();
|
|
54
|
+
await client.initialize(this.rootUri);
|
|
55
|
+
managed.client = client;
|
|
56
|
+
managed.state = "ready";
|
|
57
|
+
return client;
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
managed.state = "error";
|
|
61
|
+
managed.error = err.message;
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Check if any LSP server is connected.
|
|
67
|
+
*/
|
|
68
|
+
isConnected() {
|
|
69
|
+
for (const server of this.servers.values()) {
|
|
70
|
+
if (server.state === "ready" && server.client?.isAlive)
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* List server statuses.
|
|
77
|
+
*/
|
|
78
|
+
listServers() {
|
|
79
|
+
return [...this.servers.values()].map((s) => ({
|
|
80
|
+
name: s.config.name,
|
|
81
|
+
language: s.config.language,
|
|
82
|
+
state: s.state,
|
|
83
|
+
error: s.error,
|
|
84
|
+
}));
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Shutdown all servers.
|
|
88
|
+
*/
|
|
89
|
+
async shutdownAll() {
|
|
90
|
+
for (const server of this.servers.values()) {
|
|
91
|
+
if (server.client?.isAlive) {
|
|
92
|
+
try {
|
|
93
|
+
await server.client.shutdown();
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// Force killed
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
server.state = "stopped";
|
|
100
|
+
server.client = undefined;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
isCommandAvailable(command) {
|
|
104
|
+
try {
|
|
105
|
+
execSync(`which ${command} 2>/dev/null || where ${command} 2>nul`, {
|
|
106
|
+
encoding: "utf-8",
|
|
107
|
+
timeout: 5000,
|
|
108
|
+
});
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// Singleton
|
|
117
|
+
let _manager;
|
|
118
|
+
export function initializeLSPManager(cwd) {
|
|
119
|
+
_manager = new LSPServerManager(cwd);
|
|
120
|
+
return _manager;
|
|
121
|
+
}
|
|
122
|
+
export function getLSPManager() {
|
|
123
|
+
return _manager;
|
|
124
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in language server configurations.
|
|
3
|
+
*/
|
|
4
|
+
export interface LSPServerConfig {
|
|
5
|
+
name: string;
|
|
6
|
+
language: string;
|
|
7
|
+
extensions: string[];
|
|
8
|
+
command: string;
|
|
9
|
+
args: string[];
|
|
10
|
+
installHint: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const BUILTIN_LSP_SERVERS: LSPServerConfig[];
|
|
13
|
+
/**
|
|
14
|
+
* Detect which LSP server to use based on file extension.
|
|
15
|
+
*/
|
|
16
|
+
export declare function detectLSPServer(filePath: string): LSPServerConfig | undefined;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in language server configurations.
|
|
3
|
+
*/
|
|
4
|
+
export const BUILTIN_LSP_SERVERS = [
|
|
5
|
+
{
|
|
6
|
+
name: "typescript",
|
|
7
|
+
language: "typescript",
|
|
8
|
+
extensions: [".ts", ".tsx", ".js", ".jsx"],
|
|
9
|
+
command: "typescript-language-server",
|
|
10
|
+
args: ["--stdio"],
|
|
11
|
+
installHint: "npm install -g typescript-language-server typescript",
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
name: "python",
|
|
15
|
+
language: "python",
|
|
16
|
+
extensions: [".py"],
|
|
17
|
+
command: "pylsp",
|
|
18
|
+
args: [],
|
|
19
|
+
installHint: "pip install python-lsp-server",
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: "go",
|
|
23
|
+
language: "go",
|
|
24
|
+
extensions: [".go"],
|
|
25
|
+
command: "gopls",
|
|
26
|
+
args: ["serve"],
|
|
27
|
+
installHint: "go install golang.org/x/tools/gopls@latest",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: "rust",
|
|
31
|
+
language: "rust",
|
|
32
|
+
extensions: [".rs"],
|
|
33
|
+
command: "rust-analyzer",
|
|
34
|
+
args: [],
|
|
35
|
+
installHint: "rustup component add rust-analyzer",
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "json",
|
|
39
|
+
language: "json",
|
|
40
|
+
extensions: [".json"],
|
|
41
|
+
command: "vscode-json-languageserver",
|
|
42
|
+
args: ["--stdio"],
|
|
43
|
+
installHint: "npm install -g vscode-langservers-extracted",
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: "css",
|
|
47
|
+
language: "css",
|
|
48
|
+
extensions: [".css", ".scss", ".less"],
|
|
49
|
+
command: "vscode-css-languageserver",
|
|
50
|
+
args: ["--stdio"],
|
|
51
|
+
installHint: "npm install -g vscode-langservers-extracted",
|
|
52
|
+
},
|
|
53
|
+
];
|
|
54
|
+
/**
|
|
55
|
+
* Detect which LSP server to use based on file extension.
|
|
56
|
+
*/
|
|
57
|
+
export function detectLSPServer(filePath) {
|
|
58
|
+
const ext = filePath.slice(filePath.lastIndexOf("."));
|
|
59
|
+
return BUILTIN_LSP_SERVERS.find((s) => s.extensions.includes(ext));
|
|
60
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One-shot migration of legacy flat models[] into providers[] + models[].
|
|
3
|
+
*
|
|
4
|
+
* Pure function — takes a snapshot, returns the new snapshot plus a flag.
|
|
5
|
+
* The caller (settings load path) is responsible for writing settings.json
|
|
6
|
+
* and the .bak backup.
|
|
7
|
+
*/
|
|
8
|
+
import type { ProviderConfig } from "./llm/provider-catalog.js";
|
|
9
|
+
interface LegacyModel {
|
|
10
|
+
key: string;
|
|
11
|
+
label?: string;
|
|
12
|
+
provider?: string;
|
|
13
|
+
baseUrl?: string;
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
model: string;
|
|
16
|
+
maxOutputTokens?: number;
|
|
17
|
+
maxContextTokens?: number;
|
|
18
|
+
providerKey?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface MigrationInput {
|
|
21
|
+
providers: ProviderConfig[];
|
|
22
|
+
models: LegacyModel[];
|
|
23
|
+
}
|
|
24
|
+
export interface MigrationOutput {
|
|
25
|
+
providers: ProviderConfig[];
|
|
26
|
+
models: Array<{
|
|
27
|
+
key: string;
|
|
28
|
+
label?: string;
|
|
29
|
+
providerKey: string;
|
|
30
|
+
model: string;
|
|
31
|
+
/**
|
|
32
|
+
* Self-describing legacy fields. Kept (rather than stripped) so model
|
|
33
|
+
* entries stay valid standalone — the engine can read credentials
|
|
34
|
+
* straight off the entry without a ProviderCatalog round-trip.
|
|
35
|
+
*/
|
|
36
|
+
provider?: string;
|
|
37
|
+
baseUrl?: string;
|
|
38
|
+
apiKey?: string;
|
|
39
|
+
maxOutputTokens?: number;
|
|
40
|
+
maxContextTokens?: number;
|
|
41
|
+
}>;
|
|
42
|
+
changed: boolean;
|
|
43
|
+
}
|
|
44
|
+
export declare function migrateModels(input: MigrationInput): MigrationOutput;
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One-shot migration of legacy flat models[] into providers[] + models[].
|
|
3
|
+
*
|
|
4
|
+
* Pure function — takes a snapshot, returns the new snapshot plus a flag.
|
|
5
|
+
* The caller (settings load path) is responsible for writing settings.json
|
|
6
|
+
* and the .bak backup.
|
|
7
|
+
*/
|
|
8
|
+
const BASEURL_KIND_PATTERNS = [
|
|
9
|
+
[/deepseek\.com/i, "deepseek"],
|
|
10
|
+
[/z\.ai/i, "zai"],
|
|
11
|
+
[/anthropic\.com/i, "anthropic"],
|
|
12
|
+
[/openai\.com/i, "openai"],
|
|
13
|
+
[/x\.ai/i, "xai"],
|
|
14
|
+
[/mistral\.ai/i, "mistral"],
|
|
15
|
+
[/groq\.com/i, "groq"],
|
|
16
|
+
[/generativelanguage\.googleapis/i, "google"],
|
|
17
|
+
[/openrouter\.ai/i, "openrouter"],
|
|
18
|
+
[/localhost:11434|127\.0\.0\.1:11434/i, "ollama"],
|
|
19
|
+
];
|
|
20
|
+
function inferKind(baseUrl) {
|
|
21
|
+
if (!baseUrl)
|
|
22
|
+
return "custom";
|
|
23
|
+
for (const [re, kind] of BASEURL_KIND_PATTERNS) {
|
|
24
|
+
if (re.test(baseUrl))
|
|
25
|
+
return kind;
|
|
26
|
+
}
|
|
27
|
+
return "custom";
|
|
28
|
+
}
|
|
29
|
+
function makeFingerprint(m) {
|
|
30
|
+
return `${m.provider ?? ""}|${m.baseUrl ?? ""}|${m.apiKey ?? ""}`;
|
|
31
|
+
}
|
|
32
|
+
function deriveKey(base, used) {
|
|
33
|
+
if (!used.has(base))
|
|
34
|
+
return base;
|
|
35
|
+
for (let i = 2;; i++) {
|
|
36
|
+
const candidate = `${base}-${i}`;
|
|
37
|
+
if (!used.has(candidate))
|
|
38
|
+
return candidate;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Generate `<provider>-<model-id>` style pool key. Mirrors the
|
|
43
|
+
* `deriveModelPoolKey` helper in onboarding.ts — kept inline here to avoid
|
|
44
|
+
* an import cycle (settings/manager.ts → migrate-models.ts → ...).
|
|
45
|
+
*/
|
|
46
|
+
function deriveProviderModelKey(providerKind, modelId, used) {
|
|
47
|
+
const slash = modelId.lastIndexOf("/");
|
|
48
|
+
const base = slash >= 0 ? modelId.slice(slash + 1) : modelId;
|
|
49
|
+
const prefix = providerKind.toLowerCase();
|
|
50
|
+
const candidate = base.toLowerCase().startsWith(`${prefix}-`) ? base : `${prefix}-${base}`;
|
|
51
|
+
if (!used.has(candidate))
|
|
52
|
+
return candidate;
|
|
53
|
+
for (let i = 2;; i++) {
|
|
54
|
+
const k = `${candidate}-${i}`;
|
|
55
|
+
if (!used.has(k))
|
|
56
|
+
return k;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export function migrateModels(input) {
|
|
60
|
+
if (input.models.length === 0) {
|
|
61
|
+
return {
|
|
62
|
+
providers: input.providers,
|
|
63
|
+
models: [],
|
|
64
|
+
changed: false,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
const hasProvidersSection = input.providers.length > 0;
|
|
68
|
+
// Per-entry check (replaces the old "providers non-empty → skip everything"
|
|
69
|
+
// shortcut, which left legacy entries from the previous run forever
|
|
70
|
+
// un-migrated and bleeding key collisions like the two "deepseek" entries
|
|
71
|
+
// that motivated this rewrite).
|
|
72
|
+
// - Needs migration if: no providerKey set, OR
|
|
73
|
+
// - Needs migration if: the entry's `key` collides with a sibling (the
|
|
74
|
+
// old modelKey() helper folded v4-flash + v4-pro to "deepseek").
|
|
75
|
+
const keyCounts = new Map();
|
|
76
|
+
for (const m of input.models)
|
|
77
|
+
keyCounts.set(m.key, (keyCounts.get(m.key) ?? 0) + 1);
|
|
78
|
+
const needsMigration = input.models.some((m) => !m.providerKey || (keyCounts.get(m.key) ?? 0) > 1);
|
|
79
|
+
if (!needsMigration) {
|
|
80
|
+
return {
|
|
81
|
+
providers: input.providers,
|
|
82
|
+
models: input.models.map((m) => ({
|
|
83
|
+
key: m.key,
|
|
84
|
+
label: m.label,
|
|
85
|
+
providerKey: m.providerKey ?? "",
|
|
86
|
+
model: m.model,
|
|
87
|
+
maxOutputTokens: m.maxOutputTokens,
|
|
88
|
+
maxContextTokens: m.maxContextTokens,
|
|
89
|
+
provider: m.provider,
|
|
90
|
+
baseUrl: m.baseUrl,
|
|
91
|
+
apiKey: m.apiKey,
|
|
92
|
+
})),
|
|
93
|
+
changed: false,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
// Build providerKey map from fingerprint (provider|baseUrl|apiKey). Each
|
|
97
|
+
// unique fingerprint becomes one provider entry. Existing providers[] are
|
|
98
|
+
// preserved; new ones are appended.
|
|
99
|
+
const fingerprintToKey = new Map();
|
|
100
|
+
const newProviders = [];
|
|
101
|
+
const usedProviderKeys = new Set(input.providers.map((p) => p.key));
|
|
102
|
+
// Pre-seed: if existing providers[] match a model's fingerprint already,
|
|
103
|
+
// reuse them instead of minting a new key.
|
|
104
|
+
for (const p of input.providers) {
|
|
105
|
+
const fp = `${""}|${p.baseUrl}|${p.apiKey ?? ""}`;
|
|
106
|
+
fingerprintToKey.set(fp, p.key);
|
|
107
|
+
}
|
|
108
|
+
for (const m of input.models) {
|
|
109
|
+
const fp = makeFingerprint(m);
|
|
110
|
+
// Also try matching against existing providers by baseUrl only — the
|
|
111
|
+
// legacy "provider" field on models is a generic kind ("openai") that
|
|
112
|
+
// doesn't disambiguate, so the fingerprint above won't match if the
|
|
113
|
+
// user added the provider via the wizard but kept legacy model entries.
|
|
114
|
+
const existingByUrl = input.providers.find((p) => p.baseUrl === (m.baseUrl ?? ""));
|
|
115
|
+
if (existingByUrl) {
|
|
116
|
+
fingerprintToKey.set(fp, existingByUrl.key);
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (fingerprintToKey.has(fp))
|
|
120
|
+
continue;
|
|
121
|
+
const kind = inferKind(m.baseUrl);
|
|
122
|
+
const key = deriveKey(kind, usedProviderKeys);
|
|
123
|
+
usedProviderKeys.add(key);
|
|
124
|
+
fingerprintToKey.set(fp, key);
|
|
125
|
+
newProviders.push({
|
|
126
|
+
key,
|
|
127
|
+
kind,
|
|
128
|
+
baseUrl: m.baseUrl ?? "",
|
|
129
|
+
apiKey: m.apiKey,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
// Re-key models: any entry whose key collides with a sibling gets a fresh
|
|
133
|
+
// `<provider>-<model-id>` key. Entries that already have a unique key are
|
|
134
|
+
// left alone so user-customized aliases survive migration.
|
|
135
|
+
const usedModelKeys = new Set();
|
|
136
|
+
const newModels = input.models.map((m) => {
|
|
137
|
+
const providerKey = fingerprintToKey.get(makeFingerprint(m));
|
|
138
|
+
const collides = (keyCounts.get(m.key) ?? 0) > 1;
|
|
139
|
+
let key = m.key;
|
|
140
|
+
if (collides) {
|
|
141
|
+
const kind = inferKind(m.baseUrl);
|
|
142
|
+
key = deriveProviderModelKey(kind, m.model, usedModelKeys);
|
|
143
|
+
}
|
|
144
|
+
if (usedModelKeys.has(key)) {
|
|
145
|
+
// Defensive: if the user's original key happens to collide with a
|
|
146
|
+
// freshly minted one, re-derive too.
|
|
147
|
+
const kind = inferKind(m.baseUrl);
|
|
148
|
+
key = deriveProviderModelKey(kind, m.model, usedModelKeys);
|
|
149
|
+
}
|
|
150
|
+
usedModelKeys.add(key);
|
|
151
|
+
return {
|
|
152
|
+
key,
|
|
153
|
+
label: m.label,
|
|
154
|
+
providerKey,
|
|
155
|
+
provider: m.provider,
|
|
156
|
+
model: m.model,
|
|
157
|
+
baseUrl: m.baseUrl,
|
|
158
|
+
apiKey: m.apiKey,
|
|
159
|
+
maxOutputTokens: m.maxOutputTokens,
|
|
160
|
+
maxContextTokens: m.maxContextTokens,
|
|
161
|
+
};
|
|
162
|
+
});
|
|
163
|
+
// De-duplicate: if migration produced two entries with the same key + model
|
|
164
|
+
// (e.g. legacy duplicate that re-keys to the same canonical form), keep
|
|
165
|
+
// only the first.
|
|
166
|
+
const seen = new Set();
|
|
167
|
+
const deduped = newModels.filter((m) => {
|
|
168
|
+
const fp = `${m.key}|${m.model}`;
|
|
169
|
+
if (seen.has(fp))
|
|
170
|
+
return false;
|
|
171
|
+
seen.add(fp);
|
|
172
|
+
return true;
|
|
173
|
+
});
|
|
174
|
+
return {
|
|
175
|
+
providers: hasProvidersSection ? [...input.providers, ...newProviders] : newProviders,
|
|
176
|
+
models: deduped,
|
|
177
|
+
changed: true,
|
|
178
|
+
};
|
|
179
|
+
}
|