@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,625 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Onboarding data layer — provider catalog, env detection, key validation,
|
|
3
|
+
* settings persistence. The interactive flow itself is rendered by Ink
|
|
4
|
+
* (see src/ui/components/OnboardingPrompt.tsx); this module only exposes
|
|
5
|
+
* pure(-ish) helpers it consumes, so there's a single input stack.
|
|
6
|
+
*/
|
|
7
|
+
import { mkdirSync, writeFileSync, readFileSync, existsSync, renameSync } from "node:fs";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import { homedir } from "node:os";
|
|
10
|
+
import { getOpenRouterModels } from "./data/openrouter-models.js";
|
|
11
|
+
import { sanitizeApiKey } from "./llm/api-key-sanitize.js";
|
|
12
|
+
export const PROVIDERS = [
|
|
13
|
+
{
|
|
14
|
+
id: "openrouter",
|
|
15
|
+
name: "OpenRouter (推荐 — 支持所有模型)",
|
|
16
|
+
envKey: "OPENROUTER_API_KEY",
|
|
17
|
+
provider: "openai",
|
|
18
|
+
baseUrl: "https://openrouter.ai/api/v1",
|
|
19
|
+
keyUrl: "https://openrouter.ai/keys",
|
|
20
|
+
keyPrefix: "sk-or-",
|
|
21
|
+
// First entry is the zero-config default (auto-activated when the
|
|
22
|
+
// user starts with only an env key, no onboarding). Sonnet beats Opus
|
|
23
|
+
// here because it's ~5x cheaper and a safer pick for someone who
|
|
24
|
+
// hasn't picked yet — Opus stays one slot away for anyone who wants it.
|
|
25
|
+
models: [
|
|
26
|
+
"anthropic/claude-sonnet-4.6",
|
|
27
|
+
"anthropic/claude-opus-4.7",
|
|
28
|
+
"anthropic/claude-haiku-4.5",
|
|
29
|
+
"openai/gpt-5",
|
|
30
|
+
"openai/gpt-5-mini",
|
|
31
|
+
"openai/gpt-4o",
|
|
32
|
+
"openai/o4-mini",
|
|
33
|
+
"openai/o3",
|
|
34
|
+
"google/gemini-2.5-pro",
|
|
35
|
+
"google/gemini-2.5-flash",
|
|
36
|
+
"deepseek/deepseek-chat",
|
|
37
|
+
"deepseek/deepseek-reasoner",
|
|
38
|
+
"qwen/qwen3-coder",
|
|
39
|
+
"meta-llama/llama-4-maverick",
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: "anthropic",
|
|
44
|
+
name: "Anthropic (直连 Claude API)",
|
|
45
|
+
envKey: "ANTHROPIC_API_KEY",
|
|
46
|
+
provider: "anthropic",
|
|
47
|
+
baseUrl: "https://api.anthropic.com",
|
|
48
|
+
keyUrl: "https://console.anthropic.com/settings/keys",
|
|
49
|
+
keyPrefix: "sk-ant-",
|
|
50
|
+
models: [
|
|
51
|
+
"claude-sonnet-4-6",
|
|
52
|
+
"claude-opus-4-7",
|
|
53
|
+
"claude-haiku-4-5",
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: "openai",
|
|
58
|
+
name: "OpenAI",
|
|
59
|
+
envKey: "OPENAI_API_KEY",
|
|
60
|
+
provider: "openai",
|
|
61
|
+
baseUrl: "https://api.openai.com/v1",
|
|
62
|
+
keyUrl: "https://platform.openai.com/api-keys",
|
|
63
|
+
keyPrefix: "sk-",
|
|
64
|
+
models: ["gpt-5", "gpt-5-mini", "gpt-5-nano", "gpt-4o", "o4-mini", "o3"],
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: "deepseek",
|
|
68
|
+
name: "DeepSeek (官方直连)",
|
|
69
|
+
envKey: "DEEPSEEK_API_KEY",
|
|
70
|
+
provider: "openai",
|
|
71
|
+
baseUrl: "https://api.deepseek.com/v1",
|
|
72
|
+
keyUrl: "https://platform.deepseek.com/api_keys",
|
|
73
|
+
keyPrefix: "sk-",
|
|
74
|
+
models: ["deepseek-v4-pro", "deepseek-v4-flash", "deepseek-chat"],
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
id: "zai",
|
|
78
|
+
name: "Z.AI (GLM 官方)",
|
|
79
|
+
envKey: "ZAI_API_KEY",
|
|
80
|
+
provider: "openai",
|
|
81
|
+
baseUrl: "https://api.z.ai/api/paas/v4",
|
|
82
|
+
keyUrl: "https://z.ai/manage-apikey/apikey-list",
|
|
83
|
+
keyPrefix: "",
|
|
84
|
+
models: ["glm-5.1", "glm-4.6", "glm-4.5-air"],
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
id: "gemini",
|
|
88
|
+
name: "Google Gemini (官方直连)",
|
|
89
|
+
envKey: "GEMINI_API_KEY",
|
|
90
|
+
provider: "openai",
|
|
91
|
+
baseUrl: "https://generativelanguage.googleapis.com/v1beta/openai",
|
|
92
|
+
keyUrl: "https://aistudio.google.com/apikey",
|
|
93
|
+
keyPrefix: "",
|
|
94
|
+
models: [
|
|
95
|
+
"gemini-2.5-pro",
|
|
96
|
+
"gemini-2.5-flash",
|
|
97
|
+
"gemini-2.0-flash",
|
|
98
|
+
],
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
id: "ollama",
|
|
102
|
+
name: "Ollama (本地,无需 Key)",
|
|
103
|
+
envKey: "",
|
|
104
|
+
provider: "openai",
|
|
105
|
+
baseUrl: "http://localhost:11434/v1",
|
|
106
|
+
keyUrl: "https://ollama.com/library",
|
|
107
|
+
keyPrefix: "",
|
|
108
|
+
models: ["llama3.1", "qwen2.5-coder", "deepseek-r1", "mistral", "gemma3"],
|
|
109
|
+
noKey: true,
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
id: "custom",
|
|
113
|
+
name: "自定义 (任何 OpenAI 兼容 API)",
|
|
114
|
+
envKey: "",
|
|
115
|
+
provider: "openai",
|
|
116
|
+
baseUrl: "",
|
|
117
|
+
keyUrl: "",
|
|
118
|
+
keyPrefix: "",
|
|
119
|
+
models: [],
|
|
120
|
+
},
|
|
121
|
+
];
|
|
122
|
+
// ─── Dynamic model list (OpenRouter snapshot) ────────────────────
|
|
123
|
+
/**
|
|
124
|
+
* Curated vendors and how many of their newest models to surface in the
|
|
125
|
+
* onboarding picker. Order matters — first vendors appear first.
|
|
126
|
+
* Tweak this if a new vendor becomes worth exposing in the picker.
|
|
127
|
+
*/
|
|
128
|
+
const OPENROUTER_VENDORS = [
|
|
129
|
+
{ prefix: "anthropic/", take: 4 },
|
|
130
|
+
{ prefix: "openai/", take: 5 },
|
|
131
|
+
{ prefix: "google/", take: 3 },
|
|
132
|
+
{ prefix: "deepseek/", take: 3 },
|
|
133
|
+
{ prefix: "x-ai/", take: 2 },
|
|
134
|
+
{ prefix: "qwen/", take: 2 },
|
|
135
|
+
{ prefix: "meta-llama/", take: 2 },
|
|
136
|
+
{ prefix: "mistralai/", take: 1 },
|
|
137
|
+
];
|
|
138
|
+
/**
|
|
139
|
+
* Build the OpenRouter model picker list from the bundled snapshot.
|
|
140
|
+
* Filters out `:free`/preview variants for the default picker (still
|
|
141
|
+
* reachable via /models add). Returns the hardcoded list as fallback
|
|
142
|
+
* when the snapshot is empty (e.g. fresh checkout before first build).
|
|
143
|
+
*/
|
|
144
|
+
function buildOpenRouterModelList(fallback) {
|
|
145
|
+
const all = getOpenRouterModels();
|
|
146
|
+
if (all.length === 0)
|
|
147
|
+
return fallback;
|
|
148
|
+
const skip = /(?:-guard|-embedding|-rerank|-vision-only|:free)/i;
|
|
149
|
+
const out = [];
|
|
150
|
+
for (const { prefix, take } of OPENROUTER_VENDORS) {
|
|
151
|
+
const candidates = all
|
|
152
|
+
.filter((m) => m.id.startsWith(prefix))
|
|
153
|
+
.filter((m) => !skip.test(m.id) && !m.id.includes("-preview"))
|
|
154
|
+
.slice(0, take);
|
|
155
|
+
out.push(...candidates.map((m) => m.id));
|
|
156
|
+
}
|
|
157
|
+
return out.length > 0 ? out : fallback;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Resolve the model list a provider should expose right now. For
|
|
161
|
+
* OpenRouter this comes from the snapshot; for direct providers it
|
|
162
|
+
* stays hardcoded (snapshot doesn't carry their native IDs).
|
|
163
|
+
*/
|
|
164
|
+
export function resolveProviderModels(provider) {
|
|
165
|
+
if (provider.id === "openrouter") {
|
|
166
|
+
return buildOpenRouterModelList(provider.models);
|
|
167
|
+
}
|
|
168
|
+
return provider.models;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Scan environment for known provider API keys.
|
|
172
|
+
* Returns one entry per provider that has its envKey set.
|
|
173
|
+
*/
|
|
174
|
+
export function detectEnvKeys() {
|
|
175
|
+
const found = [];
|
|
176
|
+
for (const p of PROVIDERS) {
|
|
177
|
+
if (!p.envKey)
|
|
178
|
+
continue;
|
|
179
|
+
const v = process.env[p.envKey];
|
|
180
|
+
if (!v)
|
|
181
|
+
continue;
|
|
182
|
+
// Env-sourced keys frequently carry CRLF/BOM/quotes from how the user set
|
|
183
|
+
// them (cmd `set FOO=...`, dotenv files with stray spaces, Windows clipboards
|
|
184
|
+
// pasted into a shell). Sanitize once at the boundary so downstream code
|
|
185
|
+
// never sees a dirty value.
|
|
186
|
+
const cleaned = sanitizeApiKey(v).value;
|
|
187
|
+
if (cleaned) {
|
|
188
|
+
found.push({ provider: p, envKey: p.envKey, apiKey: cleaned });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return found;
|
|
192
|
+
}
|
|
193
|
+
/** Mask a key for display: "sk-517f...b594" */
|
|
194
|
+
export function maskKey(key) {
|
|
195
|
+
if (key.length <= 12)
|
|
196
|
+
return key.slice(0, 2) + "***";
|
|
197
|
+
return `${key.slice(0, 6)}...${key.slice(-4)}`;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Find a provider definition that matches a given API key.
|
|
201
|
+
* Checks key prefix first, then env var match, then baseUrl.
|
|
202
|
+
*/
|
|
203
|
+
export function detectProviderFromApiKey(apiKey, baseUrl) {
|
|
204
|
+
// 1. Try key prefix match
|
|
205
|
+
for (const p of PROVIDERS) {
|
|
206
|
+
if (p.keyPrefix && apiKey.startsWith(p.keyPrefix))
|
|
207
|
+
return p;
|
|
208
|
+
}
|
|
209
|
+
// 2. Try baseUrl match
|
|
210
|
+
if (baseUrl) {
|
|
211
|
+
for (const p of PROVIDERS) {
|
|
212
|
+
if (p.baseUrl && baseUrl.startsWith(p.baseUrl))
|
|
213
|
+
return p;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// 3. Try env var match
|
|
217
|
+
for (const p of PROVIDERS) {
|
|
218
|
+
if (!p.envKey)
|
|
219
|
+
continue;
|
|
220
|
+
const v = process.env[p.envKey];
|
|
221
|
+
if (v && sanitizeApiKey(v).value === apiKey)
|
|
222
|
+
return p;
|
|
223
|
+
}
|
|
224
|
+
return undefined;
|
|
225
|
+
}
|
|
226
|
+
// ─── API key validation ────────────────────────────────────────────
|
|
227
|
+
export async function validateApiKey(baseUrl, apiKey) {
|
|
228
|
+
try {
|
|
229
|
+
if (baseUrl.includes("openrouter")) {
|
|
230
|
+
const res = await fetch("https://openrouter.ai/api/v1/auth/key", {
|
|
231
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
232
|
+
});
|
|
233
|
+
const data = await res.json();
|
|
234
|
+
return !data.error;
|
|
235
|
+
}
|
|
236
|
+
const url = baseUrl.replace(/\/$/, "") + "/models";
|
|
237
|
+
const res = await fetch(url, {
|
|
238
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
239
|
+
});
|
|
240
|
+
return res.status !== 401 && res.status !== 403;
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
return true; // network error — can't validate, let it pass
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
// ─── Public API ────────────────────────────────────────────────────
|
|
247
|
+
/**
|
|
248
|
+
* Resolve an API key from the canonical fallback chain.
|
|
249
|
+
* Priority: 1) command-line option 2) settings.json 3) all provider env vars
|
|
250
|
+
*/
|
|
251
|
+
export function resolveApiKey(optionsApiKey, settingsApiKey) {
|
|
252
|
+
if (optionsApiKey)
|
|
253
|
+
return optionsApiKey;
|
|
254
|
+
if (settingsApiKey)
|
|
255
|
+
return settingsApiKey;
|
|
256
|
+
for (const p of PROVIDERS) {
|
|
257
|
+
if (!p.envKey)
|
|
258
|
+
continue;
|
|
259
|
+
const v = process.env[p.envKey];
|
|
260
|
+
if (v && v.trim())
|
|
261
|
+
return v.trim();
|
|
262
|
+
}
|
|
263
|
+
return undefined;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Look up a previously-persisted API key for a given provider in
|
|
267
|
+
* ~/.code-shell/settings.json. Matches by baseUrl (each ProviderDef.baseUrl
|
|
268
|
+
* is unique, while `provider` is a generic kind like "openai" shared across
|
|
269
|
+
* multiple endpoints).
|
|
270
|
+
*
|
|
271
|
+
* Returns the first match found in: settings.models[] (preferred — newer),
|
|
272
|
+
* then settings.model (legacy top-level). undefined when nothing matches.
|
|
273
|
+
*/
|
|
274
|
+
export function findSavedKeyForProvider(provider) {
|
|
275
|
+
const file = join(homedir(), ".code-shell", "settings.json");
|
|
276
|
+
if (!existsSync(file))
|
|
277
|
+
return undefined;
|
|
278
|
+
let data;
|
|
279
|
+
try {
|
|
280
|
+
data = JSON.parse(readFileSync(file, "utf-8"));
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
return undefined;
|
|
284
|
+
}
|
|
285
|
+
if (Array.isArray(data?.models)) {
|
|
286
|
+
for (const m of data.models) {
|
|
287
|
+
if (m?.apiKey && m?.baseUrl === provider.baseUrl) {
|
|
288
|
+
return { apiKey: String(m.apiKey), baseUrl: String(m.baseUrl) };
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
if (data?.model?.apiKey && data?.model?.baseUrl === provider.baseUrl) {
|
|
293
|
+
return {
|
|
294
|
+
apiKey: String(data.model.apiKey),
|
|
295
|
+
baseUrl: String(data.model.baseUrl),
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
return undefined;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Return the list of model IDs previously saved under this provider
|
|
302
|
+
* (matched by baseUrl). Used by the onboarding wizard to pre-populate the
|
|
303
|
+
* "model pool" step with the user's prior choices instead of resetting to
|
|
304
|
+
* just the provider's first model.
|
|
305
|
+
*/
|
|
306
|
+
export function loadSavedModelsForProvider(provider) {
|
|
307
|
+
const file = join(homedir(), ".code-shell", "settings.json");
|
|
308
|
+
if (!existsSync(file))
|
|
309
|
+
return [];
|
|
310
|
+
let data;
|
|
311
|
+
try {
|
|
312
|
+
data = JSON.parse(readFileSync(file, "utf-8"));
|
|
313
|
+
}
|
|
314
|
+
catch {
|
|
315
|
+
return [];
|
|
316
|
+
}
|
|
317
|
+
if (!Array.isArray(data?.models))
|
|
318
|
+
return [];
|
|
319
|
+
const out = [];
|
|
320
|
+
for (const m of data.models) {
|
|
321
|
+
if (m?.baseUrl === provider.baseUrl && typeof m?.model === "string") {
|
|
322
|
+
out.push(m.model);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return out;
|
|
326
|
+
}
|
|
327
|
+
export function hasApiKey() {
|
|
328
|
+
// Env variables alone are NOT enough to skip onboarding — they're surfaced
|
|
329
|
+
// as a one-click option on the provider page instead. We only skip when the
|
|
330
|
+
// user has explicitly persisted a config. Checks all three locations the
|
|
331
|
+
// wizard might write to: top-level model.apiKey (legacy), models[].apiKey
|
|
332
|
+
// (per-pool-entry), providers[].apiKey (per-provider — what the current
|
|
333
|
+
// ProviderModelFlow actually writes). Missing any one of these made
|
|
334
|
+
// /logout look like a no-op when the others still held credentials.
|
|
335
|
+
// Reads ~/.code-shell/ only — ~/.claude/ compat was dropped because Claude
|
|
336
|
+
// Code's settings schema diverges and merging broke boot.
|
|
337
|
+
const p = join(homedir(), ".code-shell", "settings.json");
|
|
338
|
+
if (existsSync(p)) {
|
|
339
|
+
try {
|
|
340
|
+
const data = JSON.parse(readFileSync(p, "utf-8"));
|
|
341
|
+
if (data?.model?.apiKey)
|
|
342
|
+
return true;
|
|
343
|
+
if (Array.isArray(data?.models) && data.models.some((m) => m?.apiKey))
|
|
344
|
+
return true;
|
|
345
|
+
if (Array.isArray(data?.providers) && data.providers.some((p) => p?.apiKey))
|
|
346
|
+
return true;
|
|
347
|
+
}
|
|
348
|
+
catch { /* ignore */ }
|
|
349
|
+
}
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
// ─── Model pool helpers ───────────────────────────────────────────
|
|
353
|
+
/** Known max output tokens for common models. */
|
|
354
|
+
const KNOWN_MAX_OUTPUT = {
|
|
355
|
+
"anthropic/claude-opus-4.7": 32000,
|
|
356
|
+
"anthropic/claude-opus-4-7": 32000,
|
|
357
|
+
"claude-opus-4-7": 32000,
|
|
358
|
+
"anthropic/claude-sonnet-4.6": 16000,
|
|
359
|
+
"anthropic/claude-sonnet-4-6": 16000,
|
|
360
|
+
"claude-sonnet-4-6": 16000,
|
|
361
|
+
"anthropic/claude-haiku-4.5": 8192,
|
|
362
|
+
"anthropic/claude-haiku-4-5": 8192,
|
|
363
|
+
"claude-haiku-4-5": 8192,
|
|
364
|
+
"openai/gpt-5": 32000,
|
|
365
|
+
"openai/gpt-5-mini": 32000,
|
|
366
|
+
"openai/gpt-5-nano": 16000,
|
|
367
|
+
"gpt-5": 32000,
|
|
368
|
+
"gpt-5-mini": 32000,
|
|
369
|
+
"gpt-5-nano": 16000,
|
|
370
|
+
"openai/gpt-4o": 16384,
|
|
371
|
+
"gpt-4o": 16384,
|
|
372
|
+
"openai/o4-mini": 100000,
|
|
373
|
+
"o4-mini": 100000,
|
|
374
|
+
"openai/o3": 100000,
|
|
375
|
+
"o3": 100000,
|
|
376
|
+
"google/gemini-2.5-pro": 65536,
|
|
377
|
+
"google/gemini-2.5-flash": 65536,
|
|
378
|
+
"gemini-2.5-pro": 65536,
|
|
379
|
+
"gemini-2.5-flash": 65536,
|
|
380
|
+
"gemini-2.0-flash": 8192,
|
|
381
|
+
"deepseek/deepseek-v3.2": 8192,
|
|
382
|
+
"deepseek/deepseek-r1": 8192,
|
|
383
|
+
"deepseek-v4-flash": 8192,
|
|
384
|
+
"deepseek-v4-pro": 65536,
|
|
385
|
+
"deepseek-chat": 8192,
|
|
386
|
+
"qwen/qwen3-coder": 16384,
|
|
387
|
+
"meta-llama/llama-4-maverick": 32000,
|
|
388
|
+
};
|
|
389
|
+
/**
|
|
390
|
+
* Known context window sizes for direct-provider models (not routed through OpenRouter).
|
|
391
|
+
* These are the models whose IDs don't include a "vendor/" prefix.
|
|
392
|
+
*/
|
|
393
|
+
const KNOWN_CONTEXT_WINDOWS = {
|
|
394
|
+
"deepseek-v4-pro": 1_000_000,
|
|
395
|
+
"deepseek-v4-flash": 1_000_000,
|
|
396
|
+
"deepseek-chat": 1_000_000,
|
|
397
|
+
"deepseek/deepseek-chat": 1_000_000,
|
|
398
|
+
"deepseek/deepseek-v4-pro": 1_000_000,
|
|
399
|
+
"deepseek/deepseek-v4-flash": 1_000_000,
|
|
400
|
+
};
|
|
401
|
+
/**
|
|
402
|
+
* Resolve a model's max-output-token budget. Lookup order:
|
|
403
|
+
* 1. KNOWN_MAX_OUTPUT (covers direct providers like Anthropic/DeepSeek
|
|
404
|
+
* whose IDs aren't in the OpenRouter snapshot)
|
|
405
|
+
* 2. OpenRouter snapshot (covers `vendor/model` style IDs)
|
|
406
|
+
* 3. undefined — caller falls back to its own default
|
|
407
|
+
*
|
|
408
|
+
* Returns undefined (not 0) when nothing is known, so callers can use
|
|
409
|
+
* `?? defaultValue` semantics.
|
|
410
|
+
*/
|
|
411
|
+
export function resolveMaxOutput(model) {
|
|
412
|
+
if (KNOWN_MAX_OUTPUT[model])
|
|
413
|
+
return KNOWN_MAX_OUTPUT[model];
|
|
414
|
+
if (model.includes("/")) {
|
|
415
|
+
const hit = getOpenRouterModels().find((m) => m.id === model);
|
|
416
|
+
if (hit && hit.maxOutputTokens > 0)
|
|
417
|
+
return hit.maxOutputTokens;
|
|
418
|
+
}
|
|
419
|
+
return undefined;
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Resolve a model's context window size. Lookup order:
|
|
423
|
+
* 1. KNOWN_CONTEXT_WINDOWS (covers direct providers like DeepSeek)
|
|
424
|
+
* 2. OpenRouter snapshot (covers `vendor/model` style IDs)
|
|
425
|
+
* 3. undefined — unknown
|
|
426
|
+
*/
|
|
427
|
+
export function resolveContextWindow(model) {
|
|
428
|
+
if (KNOWN_CONTEXT_WINDOWS[model])
|
|
429
|
+
return KNOWN_CONTEXT_WINDOWS[model];
|
|
430
|
+
if (model.includes("/")) {
|
|
431
|
+
const hit = getOpenRouterModels().find((m) => m.id === model);
|
|
432
|
+
if (hit && hit.contextLength > 0)
|
|
433
|
+
return hit.contextLength;
|
|
434
|
+
}
|
|
435
|
+
return undefined;
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Derive a pool key in `provider-model` form. Single source of truth for
|
|
439
|
+
* model alias generation — replaces the old modelKey() function which
|
|
440
|
+
* folded same-family models to one key (e.g. v4-flash and v4-pro both
|
|
441
|
+
* collapsed to "deepseek"), causing the pool to silently shadow entries.
|
|
442
|
+
*
|
|
443
|
+
* ("deepseek", "deepseek-v4-pro") → "deepseek-v4-pro"
|
|
444
|
+
* ("openai", "openai/gpt-5") → "openai-gpt-5"
|
|
445
|
+
* ("anthropic","claude-opus-4-7") → "anthropic-claude-opus-4-7"
|
|
446
|
+
*
|
|
447
|
+
* If the model id already starts with `<provider>-` (e.g. "deepseek-v4-pro"
|
|
448
|
+
* under provider "deepseek"), the prefix isn't duplicated.
|
|
449
|
+
*
|
|
450
|
+
* `used` is a set of already-taken keys; collisions are resolved with a
|
|
451
|
+
* `-2`, `-3`, ... suffix.
|
|
452
|
+
*/
|
|
453
|
+
export function deriveModelPoolKey(providerKind, modelId, used = []) {
|
|
454
|
+
const slash = modelId.lastIndexOf("/");
|
|
455
|
+
const base = slash >= 0 ? modelId.slice(slash + 1) : modelId;
|
|
456
|
+
const prefix = providerKind.toLowerCase();
|
|
457
|
+
const candidate = base.toLowerCase().startsWith(`${prefix}-`) ? base : `${prefix}-${base}`;
|
|
458
|
+
const set = new Set(used);
|
|
459
|
+
if (!set.has(candidate))
|
|
460
|
+
return candidate;
|
|
461
|
+
for (let i = 2;; i++) {
|
|
462
|
+
const k = `${candidate}-${i}`;
|
|
463
|
+
if (!set.has(k))
|
|
464
|
+
return k;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Build model pool entries from a provider's model list.
|
|
469
|
+
*/
|
|
470
|
+
export function buildModelPool(provider, apiKey) {
|
|
471
|
+
const models = resolveProviderModels(provider);
|
|
472
|
+
const used = [];
|
|
473
|
+
return models.map((m) => {
|
|
474
|
+
const key = deriveModelPoolKey(provider.id, m, used);
|
|
475
|
+
used.push(key);
|
|
476
|
+
return {
|
|
477
|
+
key,
|
|
478
|
+
label: modelDisplayName(m),
|
|
479
|
+
provider: provider.provider,
|
|
480
|
+
model: m,
|
|
481
|
+
baseUrl: provider.baseUrl,
|
|
482
|
+
apiKey,
|
|
483
|
+
maxOutputTokens: resolveMaxOutput(m),
|
|
484
|
+
maxContextTokens: resolveContextWindow(m),
|
|
485
|
+
};
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
// ─── Helpers ───────────────────────────────────────────────────────
|
|
489
|
+
export function modelDisplayName(model) {
|
|
490
|
+
const slash = model.lastIndexOf("/");
|
|
491
|
+
const base = slash >= 0 ? model.slice(slash + 1) : model;
|
|
492
|
+
const parts = base.split("-");
|
|
493
|
+
if (parts[0] === "claude") {
|
|
494
|
+
const variant = parts[1] ?? "";
|
|
495
|
+
return `Claude ${variant.charAt(0).toUpperCase() + variant.slice(1)}`;
|
|
496
|
+
}
|
|
497
|
+
if (base.startsWith("gpt-"))
|
|
498
|
+
return `GPT-${parts.slice(1).join("-")}`;
|
|
499
|
+
if (base.startsWith("gemini-"))
|
|
500
|
+
return `Gemini ${parts.slice(1).join("-")}`;
|
|
501
|
+
return base.charAt(0).toUpperCase() + base.slice(1);
|
|
502
|
+
}
|
|
503
|
+
export function saveSettings(result, providerDef, poolModels) {
|
|
504
|
+
const dir = join(homedir(), ".code-shell");
|
|
505
|
+
const file = join(dir, "settings.json");
|
|
506
|
+
mkdirSync(dir, { recursive: true });
|
|
507
|
+
let existing = {};
|
|
508
|
+
if (existsSync(file)) {
|
|
509
|
+
try {
|
|
510
|
+
existing = JSON.parse(readFileSync(file, "utf-8"));
|
|
511
|
+
}
|
|
512
|
+
catch { }
|
|
513
|
+
}
|
|
514
|
+
const updated = {
|
|
515
|
+
...existing,
|
|
516
|
+
model: {
|
|
517
|
+
...(typeof existing.model === "object" ? existing.model : {}),
|
|
518
|
+
provider: result.provider,
|
|
519
|
+
name: result.model,
|
|
520
|
+
apiKey: result.apiKey,
|
|
521
|
+
baseUrl: result.baseUrl,
|
|
522
|
+
},
|
|
523
|
+
};
|
|
524
|
+
// Merge model pool: keep entries from other providers (matched by baseUrl)
|
|
525
|
+
// and replace just the current provider's slice. A naive overwrite would
|
|
526
|
+
// wipe out every other provider's models every time the wizard runs.
|
|
527
|
+
if (providerDef && poolModels && poolModels.length > 0) {
|
|
528
|
+
const newEntries = buildModelPool(providerDef, result.apiKey).filter((e) => new Set(poolModels).has(e.model));
|
|
529
|
+
const existingModels = Array.isArray(existing.models)
|
|
530
|
+
? existing.models
|
|
531
|
+
: [];
|
|
532
|
+
const otherProvider = existingModels.filter((e) => e?.baseUrl !== providerDef.baseUrl);
|
|
533
|
+
updated.models = [...otherProvider, ...newEntries];
|
|
534
|
+
}
|
|
535
|
+
writeFileSync(file, JSON.stringify(updated, null, 2) + "\n", "utf-8");
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Append-only persistence for the new ProviderModelFlow-based onboarding.
|
|
539
|
+
*
|
|
540
|
+
* Writes the new shape:
|
|
541
|
+
* - settings.activeKey — primary source of truth for active model
|
|
542
|
+
* - settings.models[] — self-describing entries (key, provider,
|
|
543
|
+
* model, baseUrl, apiKey, maxOutput, maxContext)
|
|
544
|
+
* - settings.providers[] — credential source for the wizard
|
|
545
|
+
* - settings.model.* — legacy mirror of the active entry, kept in
|
|
546
|
+
* sync so legacy boot paths (cli/main.ts,
|
|
547
|
+
* repl.ts, run.ts) keep working without
|
|
548
|
+
* each having to learn about activeKey
|
|
549
|
+
*
|
|
550
|
+
* Append-only: never removes existing entries. To start over use /logout.
|
|
551
|
+
* Writes atomically via tmp+rename.
|
|
552
|
+
*/
|
|
553
|
+
export function appendOnboardingResult(opts) {
|
|
554
|
+
const dir = join(homedir(), ".code-shell");
|
|
555
|
+
const file = join(dir, "settings.json");
|
|
556
|
+
mkdirSync(dir, { recursive: true });
|
|
557
|
+
let existing = {};
|
|
558
|
+
if (existsSync(file)) {
|
|
559
|
+
try {
|
|
560
|
+
existing = JSON.parse(readFileSync(file, "utf-8"));
|
|
561
|
+
}
|
|
562
|
+
catch {
|
|
563
|
+
/* ignore — corrupt file is replaced */
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
// Append provider (skip if key already present).
|
|
567
|
+
const existingProviders = Array.isArray(existing.providers)
|
|
568
|
+
? existing.providers
|
|
569
|
+
: [];
|
|
570
|
+
let providersOut = existingProviders;
|
|
571
|
+
if (opts.addedProvider) {
|
|
572
|
+
const has = existingProviders.some((p) => p?.key === opts.addedProvider.key);
|
|
573
|
+
if (!has)
|
|
574
|
+
providersOut = [...existingProviders, opts.addedProvider];
|
|
575
|
+
}
|
|
576
|
+
// Append models (skip entries whose key already exists — the wizard
|
|
577
|
+
// already derives unique keys via deriveModelPoolKey, so a collision
|
|
578
|
+
// means the user re-added the exact same alias and we leave the older
|
|
579
|
+
// entry alone rather than silently overwriting credentials).
|
|
580
|
+
const existingModels = Array.isArray(existing.models)
|
|
581
|
+
? existing.models
|
|
582
|
+
: [];
|
|
583
|
+
const existingKeys = new Set(existingModels.map((m) => m?.key));
|
|
584
|
+
const modelsToAppend = opts.addedModels.filter((m) => !existingKeys.has(m.key));
|
|
585
|
+
const updated = {
|
|
586
|
+
...existing,
|
|
587
|
+
activeKey: opts.activeKey,
|
|
588
|
+
model: {
|
|
589
|
+
...(typeof existing.model === "object" && existing.model ? existing.model : {}),
|
|
590
|
+
provider: opts.activeMirror.provider,
|
|
591
|
+
name: opts.activeMirror.model,
|
|
592
|
+
apiKey: opts.activeMirror.apiKey,
|
|
593
|
+
baseUrl: opts.activeMirror.baseUrl,
|
|
594
|
+
},
|
|
595
|
+
providers: providersOut,
|
|
596
|
+
models: [...existingModels, ...modelsToAppend],
|
|
597
|
+
};
|
|
598
|
+
// Atomic write: tmp file in the same dir, then rename (atomic on POSIX).
|
|
599
|
+
const tmp = `${file}.${process.pid}.tmp`;
|
|
600
|
+
writeFileSync(tmp, JSON.stringify(updated, null, 2) + "\n", "utf-8");
|
|
601
|
+
try {
|
|
602
|
+
renameSync(tmp, file);
|
|
603
|
+
}
|
|
604
|
+
catch {
|
|
605
|
+
// Fallback: best-effort direct write if rename fails (e.g. cross-device).
|
|
606
|
+
writeFileSync(file, JSON.stringify(updated, null, 2) + "\n", "utf-8");
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
// saveArenaSettings removed — replaced by saveArenaSettingsByKeys
|
|
610
|
+
export function saveArenaSettingsByKeys(keys) {
|
|
611
|
+
const dir = join(homedir(), ".code-shell");
|
|
612
|
+
const file = join(dir, "settings.json");
|
|
613
|
+
let existing = {};
|
|
614
|
+
if (existsSync(file)) {
|
|
615
|
+
try {
|
|
616
|
+
existing = JSON.parse(readFileSync(file, "utf-8"));
|
|
617
|
+
}
|
|
618
|
+
catch { }
|
|
619
|
+
}
|
|
620
|
+
const updated = {
|
|
621
|
+
...existing,
|
|
622
|
+
arena: { participants: keys },
|
|
623
|
+
};
|
|
624
|
+
writeFileSync(file, JSON.stringify(updated, null, 2) + "\n", "utf-8");
|
|
625
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal `git` subprocess wrappers used by the plugin marketplace. Each
|
|
3
|
+
* function returns a discriminated union so callers can produce useful
|
|
4
|
+
* error messages without try/catching. Mirrors Claude Code's
|
|
5
|
+
* utils/plugins/marketplaceManager.ts:loadAndCacheMarketplace at the
|
|
6
|
+
* subset we need for the MVP.
|
|
7
|
+
*
|
|
8
|
+
* Subprocess lifecycle (spawn, timeout cascade, IO drain, byte cap) is
|
|
9
|
+
* centralized in {@link safeSpawn}; gitOps only owns the error-shape
|
|
10
|
+
* mapping into GitResult.
|
|
11
|
+
*
|
|
12
|
+
* Trust: gitOps is invoked from marketplace install/update actions that the
|
|
13
|
+
* user initiates by typing `/plugin install ...` (or the equivalent). It is
|
|
14
|
+
* NOT exposed to the LLM via tool calls, so it does not need permission
|
|
15
|
+
* classification. See docs/architecture/17 for the trust framing.
|
|
16
|
+
*/
|
|
17
|
+
export type GitResult = {
|
|
18
|
+
ok: true;
|
|
19
|
+
stdout: string;
|
|
20
|
+
} | {
|
|
21
|
+
ok: false;
|
|
22
|
+
error: string;
|
|
23
|
+
};
|
|
24
|
+
export declare function gitClone(url: string, destDir: string, options?: {
|
|
25
|
+
ref?: string;
|
|
26
|
+
}): Promise<GitResult>;
|
|
27
|
+
export declare function gitRevParseHead(repoDir: string): Promise<GitResult>;
|
|
28
|
+
export declare function gitFetchAndReset(repoDir: string, ref?: string): Promise<GitResult>;
|
|
29
|
+
/**
|
|
30
|
+
* Github source helper: convert "owner/repo" to an https clone URL.
|
|
31
|
+
*/
|
|
32
|
+
export declare function githubRepoToCloneUrl(repo: string): string;
|