diff --git a/src/app/api/providers/[id]/test/cliRuntimeProviderMap.ts b/src/app/api/providers/[id]/test/cliRuntimeProviderMap.ts new file mode 100644 index 0000000000..dc3f547f68 --- /dev/null +++ b/src/app/api/providers/[id]/test/cliRuntimeProviderMap.ts @@ -0,0 +1,11 @@ +// Maps a provider id to the CLI tool id whose local runtime must be present +// for the connection-test path to authenticate against a local CLI auth file. +// kilocode is intentionally absent: the provider uses OAuth device flow + direct +// HTTPS to api.kilo.ai and never depends on the kilocode CLI binary at runtime +// (#2404). CLI-tools integration for Kilo (configuring the VSCode extension to +// point at OmniRoute) lives in /api/cli-tools/kilo-settings and keeps its own +// runtime check there. +export const CLI_RUNTIME_PROVIDER_MAP: Record = { + cline: "cline", + qoder: "qoder", +}; diff --git a/src/app/api/providers/[id]/test/route.ts b/src/app/api/providers/[id]/test/route.ts index 2bbf28b039..b82cd00532 100644 --- a/src/app/api/providers/[id]/test/route.ts +++ b/src/app/api/providers/[id]/test/route.ts @@ -102,11 +102,7 @@ const OAUTH_TEST_CONFIG = { }, }; -const CLI_RUNTIME_PROVIDER_MAP = { - cline: "cline", - kilocode: "kilo", - qoder: "qoder", -}; +import { CLI_RUNTIME_PROVIDER_MAP } from "./cliRuntimeProviderMap"; /** POST body is optional; when present, only known fields are validated. */ const providerConnectionTestBodySchema = z.object({ diff --git a/tests/unit/providers-test-route-cli-map.test.ts b/tests/unit/providers-test-route-cli-map.test.ts new file mode 100644 index 0000000000..b433967f55 --- /dev/null +++ b/tests/unit/providers-test-route-cli-map.test.ts @@ -0,0 +1,24 @@ +import test from "node:test"; +import assert from "node:assert/strict"; + +import { CLI_RUNTIME_PROVIDER_MAP } from "../../src/app/api/providers/[id]/test/cliRuntimeProviderMap"; + +// #2404 — Before this fix, the kilocode provider (OAuth device flow + direct HTTPS +// to api.kilo.ai) was gated on the local `kilocode` CLI binary being installed, +// which made the connection test hard-fail with "Local CLI runtime is not installed" +// even when the OAuth token itself was perfectly valid. The CLI binary is only +// relevant for the dashboard's CLI-tools integration, not for the provider itself. +test("CLI_RUNTIME_PROVIDER_MAP must not gate kilocode on a local CLI binary (#2404)", () => { + assert.equal( + CLI_RUNTIME_PROVIDER_MAP.kilocode, + undefined, + "kilocode is an OAuth+HTTPS provider; it must not require the local CLI binary at test time" + ); +}); + +test("CLI_RUNTIME_PROVIDER_MAP still gates providers that actually need a local CLI", () => { + // cline and qoder both read credentials from a local CLI auth file when used + // in their CLI-flavored auth mode, so the runtime check stays meaningful. + assert.equal(CLI_RUNTIME_PROVIDER_MAP.cline, "cline"); + assert.equal(CLI_RUNTIME_PROVIDER_MAP.qoder, "qoder"); +});