From 0243b408a1e9c596170e6ae8666ee8f496d543d5 Mon Sep 17 00:00:00 2001 From: musi Date: Tue, 23 Jun 2026 07:37:57 +0800 Subject: [PATCH] Remove deeplink replace and default actions --- README.md | 7 ++--- src/renderer/pages/home/App.tsx | 15 +++-------- src/renderer/pages/home/shared/providers.ts | 29 +++------------------ src/shared/app.ts | 2 -- src/shared/deep-link.ts | 8 ------ 5 files changed, 10 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index 878e60f..da77cbd 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ The wrapper reads `~/.claude-code-router/config.json`, preserves the old CCR `Pr Supplier websites can open CCR and import a model provider with a custom protocol link: ```text -ccr://provider?name=Example%20AI&base_url=https%3A%2F%2Fapi.example.com%2Fv1&api_key=sk-example&models=example-chat%2Cexample-coder&protocol=openai_chat_completions&set_default=1 +ccr://provider?name=Example%20AI&base_url=https%3A%2F%2Fapi.example.com%2Fv1&api_key=sk-example&models=example-chat%2Cexample-coder&protocol=openai_chat_completions ``` Supported query parameters: @@ -30,8 +30,6 @@ Supported query parameters: - `api_key`: optional provider API key. Aliases: `apiKey`, `apikey`, `key`, `token`. - `models`: comma-separated or newline-separated model list. You can also repeat `model=...`. - `protocol`: one of `openai_chat_completions`, `openai_responses`, `anthropic_messages`, or `gemini_generate_content`. Aliases such as `openai`, `responses`, `anthropic`, and `gemini` are accepted. -- `set_default=1`: make the imported provider the preferred provider. -- `replace=1`: replace an existing provider with the same name or normalized base URL. For larger payloads, pass `payload` as URL-encoded JSON or base64url JSON with the same fields: @@ -41,8 +39,7 @@ For larger payloads, pass `payload` as URL-encoded JSON or base64url JSON with t "baseUrl": "https://api.example.com/v1", "apiKey": "sk-example", "models": ["example-chat", "example-coder"], - "protocol": "openai_chat_completions", - "setDefault": true + "protocol": "openai_chat_completions" } ``` diff --git a/src/renderer/pages/home/App.tsx b/src/renderer/pages/home/App.tsx index 89f7efa..95208fe 100644 --- a/src/renderer/pages/home/App.tsx +++ b/src/renderer/pages/home/App.tsx @@ -11,7 +11,7 @@ import { enforceSingleEnabledGlobalProfilePerAgent, ExtensionConfigTarget, ExtensionDeleteTarget, ExtensionInstallDraft, ExtensionSource, fallbackAgentAnalysis, fallbackConfig, fallbackGatewayStatus, fallbackInfo, fallbackProxyCertificateStatus, fallbackProxyNetworkSnapshot, fallbackProxyStatus, fallbackRequestLogPage, - fallbackUpdateStatus, fallbackUsageStats, findProviderDeepLinkReplacementIndex, formatJson, formatProxyCertificateInstallMessage, GatewayProviderConfig, + fallbackUpdateStatus, fallbackUsageStats, formatJson, formatProxyCertificateInstallMessage, GatewayProviderConfig, fusionCustomMcpServerFromDraft, fusionCustomToolConfigFromProfile, GatewayProviderProbeResult, gatewayServiceMessage, GatewayStatus, getDefaultOnboardingStep, isClaudeDesignPluginConfig, isClaudeDesignRoutingDraftValid, isCursorProxyPluginConfig, isMacPlatform, isPlainRecord, isProfileDraftSubmittable, isProviderNameDuplicate, isProviderProbeCandidateReady, @@ -1231,17 +1231,10 @@ function App() { const probe = await probeProviderDeepLinkPayload(payload); let importedProviderName = payload.name?.trim() || ""; const next = buildConfigUpdate((config) => { - const replaceIndex = payload.replaceExisting - ? findProviderDeepLinkReplacementIndex(config.Providers, payload, probe?.normalizedBaseUrl || payload.baseUrl) - : -1; - const provider = createProviderConfigFromDeepLink(payload, config.Providers, probe, replaceIndex); + const provider = createProviderConfigFromDeepLink(payload, config.Providers, probe); importedProviderName = provider.name; - if (replaceIndex >= 0) { - config.Providers[replaceIndex] = provider; - } else { - config.Providers.push(provider); - } - if (payload.setDefault || !config.preferredProvider) { + config.Providers.push(provider); + if (!config.preferredProvider) { config.preferredProvider = provider.name; } return config; diff --git a/src/renderer/pages/home/shared/providers.ts b/src/renderer/pages/home/shared/providers.ts index 4ae3649..ecd72ba 100644 --- a/src/renderer/pages/home/shared/providers.ts +++ b/src/renderer/pages/home/shared/providers.ts @@ -790,8 +790,7 @@ export async function resolveProviderDeepLinkIcon(payload: ProviderDeepLinkPaylo export function createProviderConfigFromDeepLink( payload: ProviderDeepLinkPayload, providers: GatewayProviderConfig[], - probe: GatewayProviderProbeResult | undefined, - replaceIndex: number + probe: GatewayProviderProbeResult | undefined ): GatewayProviderConfig { const protocol = probe?.detectedProtocol ?? payload.protocol ?? "openai_chat_completions"; const baseUrl = probe?.normalizedBaseUrl || payload.baseUrl; @@ -802,9 +801,8 @@ export function createProviderConfigFromDeepLink( throw new Error("Models are required. Ask the provider to include models=... in the link."); } - const existingName = replaceIndex >= 0 ? providers[replaceIndex]?.name : undefined; - const baseName = payload.name?.trim() || existingName || inferProviderNameFromBaseUrl(baseUrl); - const name = replaceIndex >= 0 ? baseName : uniqueProviderName(providers, baseName); + const baseName = payload.name?.trim() || inferProviderNameFromBaseUrl(baseUrl); + const name = uniqueProviderName(providers, baseName); const keySafetyIssue = providerApiKeySafetyIssue({ apiKey: payload.apiKey, baseUrl, name }); if (keySafetyIssue) { throw new Error(keySafetyIssue.message); @@ -839,23 +837,6 @@ export function createProviderConfigFromDeepLink( }; } -export function findProviderDeepLinkReplacementIndex( - providers: GatewayProviderConfig[], - payload: ProviderDeepLinkPayload, - baseUrl: string -): number { - const name = payload.name?.trim(); - if (name) { - const namedIndex = providers.findIndex((provider) => provider.name === name); - if (namedIndex >= 0) { - return namedIndex; - } - } - - const normalizedBaseUrl = normalizeProviderBaseUrl(baseUrl).toLowerCase(); - return providers.findIndex((provider) => normalizeProviderBaseUrl(providerBaseUrl(provider)).toLowerCase() === normalizedBaseUrl); -} - export function inferProviderNameFromBaseUrl(baseUrl: string): string { try { const url = new URL(providerUrlWithDefaultScheme(baseUrl)); @@ -1445,9 +1426,7 @@ export function createProviderInstallLinkFromDraft(draft: AddProviderDraft, prob ...(draft.icon.trim() ? { icon: draft.icon.trim() } : {}), models, name: providerName, - protocol, - replaceExisting: false, - setDefault: false + protocol }; return `ccr://provider?payload=${base64UrlEncodeText(JSON.stringify(payload))}`; } diff --git a/src/shared/app.ts b/src/shared/app.ts index 8d9080b..b54deb0 100644 --- a/src/shared/app.ts +++ b/src/shared/app.ts @@ -215,8 +215,6 @@ export type ProviderDeepLinkPayload = { models: string[]; name?: string; protocol?: GatewayProviderProtocol; - replaceExisting: boolean; - setDefault: boolean; source?: string; }; diff --git a/src/shared/deep-link.ts b/src/shared/deep-link.ts index 0d06210..2fb8cba 100644 --- a/src/shared/deep-link.ts +++ b/src/shared/deep-link.ts @@ -160,8 +160,6 @@ export function parseProviderDeepLinkPayload(rawUrl: string): ProviderDeepLinkPa firstStringParam(params, ["protocol", "type"]) ?? firstPayloadString(payload, ["protocol", "type"]) ); const models = readDeepLinkModels(params, payload); - const setDefault = readDeepLinkBoolean(params, payload, ["set_default", "setDefault", "default", "preferred"]); - const replaceExisting = readDeepLinkBoolean(params, payload, ["replace", "replace_existing", "replaceExisting", "update"]); const account = readDeepLinkAccount(params, payload); const source = boundedString( firstStringParam(params, ["source", "source_url", "sourceUrl"]) ?? @@ -176,8 +174,6 @@ export function parseProviderDeepLinkPayload(rawUrl: string): ProviderDeepLinkPa models, ...(name ? { name } : {}), ...(protocol ? { protocol } : {}), - replaceExisting, - setDefault, ...(source ? { source } : {}) }; } @@ -232,8 +228,6 @@ function parseProviderPayloadFields( firstStringParam(params, ["protocol", "type"]) ?? firstPayloadString(payload, ["protocol", "type"]) ); const models = readDeepLinkModels(params, payload); - const setDefault = readDeepLinkBoolean(params, payload, ["set_default", "setDefault", "default", "preferred"]); - const replaceExisting = readDeepLinkBoolean(params, payload, ["replace", "replace_existing", "replaceExisting", "update"]); const account = readDeepLinkAccount(params, payload); const source = boundedString( firstStringParam(params, ["source", "source_url", "sourceUrl"]) ?? @@ -251,8 +245,6 @@ function parseProviderPayloadFields( models, ...(name ? { name } : {}), ...(protocol ? { protocol } : {}), - replaceExisting, - setDefault, ...(source ? { source } : {}) }; }