From 6a7a71e20637c11ea5148af004a9203f9761b037 Mon Sep 17 00:00:00 2001 From: Patrick Wozniak Date: Tue, 25 Aug 2026 15:54:29 +0200 Subject: [PATCH] fix(auth): support official Command Code environment names --- scripts/live-e2e-profile.mjs | 3 ++- scripts/pi-authenticated.mjs | 1 + scripts/pi-isolated.mjs | 1 + src/api-key.ts | 1 + src/quota-command.ts | 2 +- tests/test-api-key.ts | 13 ++++++++++--- tests/test-live-e2e.mjs | 2 ++ tests/test-omp-compat.mjs | 2 +- tests/test-pi-authenticated.mjs | 5 +++-- tests/test-pi-isolated.mjs | 6 ++++-- tests/test-pi-local.mjs | 4 ++-- tests/test-quota-command.ts | 2 +- tests/test-smoke.mjs | 3 ++- 13 files changed, 31 insertions(+), 14 deletions(-) diff --git a/scripts/live-e2e-profile.mjs b/scripts/live-e2e-profile.mjs index 01e9bab..3271323 100644 --- a/scripts/live-e2e-profile.mjs +++ b/scripts/live-e2e-profile.mjs @@ -39,10 +39,11 @@ function runProfile(profile, apiKey) { const model = process.env[modelVariable] ?? "deepseek/deepseek-v4-flash" const env = { ...process.env, - COMMANDCODE_API_KEY: apiKey, + COMMAND_CODE_API_KEY: apiKey, COMMANDCODE_E2E_MODEL: model, COMMANDCODE_E2E_PROFILE: profile, } + delete env.COMMANDCODE_API_KEY delete env.COMMANDCODE_E2E_GO_API_KEY delete env.COMMANDCODE_E2E_PROVIDER_API_KEY diff --git a/scripts/pi-authenticated.mjs b/scripts/pi-authenticated.mjs index b0fe10b..974d590 100644 --- a/scripts/pi-authenticated.mjs +++ b/scripts/pi-authenticated.mjs @@ -11,6 +11,7 @@ const env = { ...process.env, PI_SKIP_VERSION_CHECK: "1", } +delete env.COMMAND_CODE_API_KEY delete env.COMMANDCODE_API_KEY const child = spawn( diff --git a/scripts/pi-isolated.mjs b/scripts/pi-isolated.mjs index a725f4e..b66c622 100644 --- a/scripts/pi-isolated.mjs +++ b/scripts/pi-isolated.mjs @@ -22,6 +22,7 @@ const env = { PI_CODING_AGENT_SESSION_DIR: sessionDir, PI_SKIP_VERSION_CHECK: "1", } +delete env.COMMAND_CODE_API_KEY delete env.COMMANDCODE_API_KEY let activeChild diff --git a/src/api-key.ts b/src/api-key.ts index 0ab52f5..f09e155 100644 --- a/src/api-key.ts +++ b/src/api-key.ts @@ -34,6 +34,7 @@ export function getConfiguredApiKey( } = {}, ): string | undefined { const env = options.env ?? process.env + if (env.COMMAND_CODE_API_KEY) return env.COMMAND_CODE_API_KEY if (env.COMMANDCODE_API_KEY) return env.COMMANDCODE_API_KEY const home = options.homeDir?.() ?? homedir() diff --git a/src/quota-command.ts b/src/quota-command.ts index 47f24d9..81a8779 100644 --- a/src/quota-command.ts +++ b/src/quota-command.ts @@ -45,7 +45,7 @@ export function registerCommandCodeQuota( const apiKey = pickCommandCodeApiKey(registryKey, getConfiguredKey()) if (!apiKey) { ctx.ui.notify( - "Command Code quota requires an API key. Run /login and select Command Code, or set COMMANDCODE_API_KEY.", + "Command Code quota requires an API key. Run /login and select Command Code, or set COMMAND_CODE_API_KEY.", "warning", ) return diff --git a/tests/test-api-key.ts b/tests/test-api-key.ts index a497978..f3029cb 100644 --- a/tests/test-api-key.ts +++ b/tests/test-api-key.ts @@ -21,10 +21,17 @@ async function withAuthFile( } describe("getConfiguredApiKey()", () => { - it("prefers the environment variable", () => { + it("prefers the official environment variable and keeps the legacy alias", () => { assert.equal( - getConfiguredApiKey({ env: { COMMANDCODE_API_KEY: "env-key" }, authPaths: [] }), - "env-key", + getConfiguredApiKey({ + env: { COMMAND_CODE_API_KEY: "official-key", COMMANDCODE_API_KEY: "legacy-key" }, + authPaths: [], + }), + "official-key", + ) + assert.equal( + getConfiguredApiKey({ env: { COMMANDCODE_API_KEY: "legacy-key" }, authPaths: [] }), + "legacy-key", ) }) diff --git a/tests/test-live-e2e.mjs b/tests/test-live-e2e.mjs index 88ca636..09d9d48 100644 --- a/tests/test-live-e2e.mjs +++ b/tests/test-live-e2e.mjs @@ -48,6 +48,7 @@ function findPiBinary() { function hasAuthMetadata() { return ( + Boolean(process.env.COMMAND_CODE_API_KEY) || Boolean(process.env.COMMANDCODE_API_KEY) || existsSync(join(homedir(), ".commandcode", "auth.json")) || existsSync(join(homedir(), ".pi", "agent", "auth.json")) @@ -70,6 +71,7 @@ function safeEnv(overrides = {}) { env.PI_CODING_AGENT_DIR = profileAgentDir env.COMMANDCODE_MODELS_CACHE = join(profileAgentDir, "commandcode-models.json") } else { + delete env.COMMAND_CODE_API_KEY delete env.COMMANDCODE_API_KEY } return env diff --git a/tests/test-omp-compat.mjs b/tests/test-omp-compat.mjs index eeb5793..ae64d1c 100644 --- a/tests/test-omp-compat.mjs +++ b/tests/test-omp-compat.mjs @@ -133,7 +133,7 @@ function runOmp(args, timeoutMs = 30_000) { HOME: tempHome, USERPROFILE: tempHome, PI_CODING_AGENT_DIR: join(tempHome, ".omp", "agent"), - COMMANDCODE_API_KEY: "mock-key", + COMMAND_CODE_API_KEY: "mock-key", COMMANDCODE_API_BASE: `${apiBase}/provider/v1`, COMMANDCODE_MODELS_URL: `${apiBase}/provider/v1/models`, }, diff --git a/tests/test-pi-authenticated.mjs b/tests/test-pi-authenticated.mjs index 7f992b3..39fa536 100644 --- a/tests/test-pi-authenticated.mjs +++ b/tests/test-pi-authenticated.mjs @@ -22,7 +22,7 @@ const { writeFileSync } = require("node:fs") writeFileSync(process.env.FAKE_PI_LOG, JSON.stringify({ args: process.argv.slice(2), agentDir: process.env.PI_CODING_AGENT_DIR ?? null, - apiKey: process.env.COMMANDCODE_API_KEY ?? null, + apiKey: process.env.COMMAND_CODE_API_KEY ?? process.env.COMMANDCODE_API_KEY ?? null, skipVersionCheck: process.env.PI_SKIP_VERSION_CHECK, })) NODE @@ -38,7 +38,8 @@ NODE PATH: `${fakeBin}${delimiter}${process.env.PATH ?? ""}`, FAKE_PI_LOG: logPath, PI_CODING_AGENT_DIR: "/existing/pi-agent", - COMMANDCODE_API_KEY: "existing-key", + COMMAND_CODE_API_KEY: "official-existing-key", + COMMANDCODE_API_KEY: "legacy-existing-key", }, encoding: "utf8", }) diff --git a/tests/test-pi-isolated.mjs b/tests/test-pi-isolated.mjs index 0b809a6..3ca85c6 100644 --- a/tests/test-pi-isolated.mjs +++ b/tests/test-pi-isolated.mjs @@ -26,7 +26,8 @@ appendFileSync(process.env.FAKE_PI_LOG, JSON.stringify({ skipVersionCheck: process.env.PI_SKIP_VERSION_CHECK, home: process.env.HOME, userProfile: process.env.USERPROFILE, - inheritedApiKey: process.env.COMMANDCODE_API_KEY ?? null, + inheritedApiKey: + process.env.COMMAND_CODE_API_KEY ?? process.env.COMMANDCODE_API_KEY ?? null, }) + "\\n") NODE if [ "$1" = "install" ]; then exit 0; fi @@ -42,7 +43,8 @@ exit ${exitStatus} ...process.env, PATH: `${fakeBin}${delimiter}${process.env.PATH ?? ""}`, FAKE_PI_LOG: logPath, - COMMANDCODE_API_KEY: "must-not-leak", + COMMAND_CODE_API_KEY: "must-not-leak-official", + COMMANDCODE_API_KEY: "must-not-leak-legacy", }, encoding: "utf8", }) diff --git a/tests/test-pi-local.mjs b/tests/test-pi-local.mjs index 2d0a999..3bce2c8 100644 --- a/tests/test-pi-local.mjs +++ b/tests/test-pi-local.mjs @@ -215,8 +215,8 @@ const env = { PI_CODING_AGENT_DIR: agentDir, PI_CODING_AGENT_SESSION_DIR: join(tempHome, "sessions"), COMMANDCODE_API_BASE: `${apiBase}/provider/v1`, - COMMANDCODE_API_KEY: "mock-key", - COMMANDCODE_ZDR: "1", + COMMAND_CODE_API_KEY: "mock-key", + CMD_ZDR: "1", COMMANDCODE_MODELS_URL: `${apiBase}/provider/v1/models`, } diff --git a/tests/test-quota-command.ts b/tests/test-quota-command.ts index 95692cd..3ae753c 100644 --- a/tests/test-quota-command.ts +++ b/tests/test-quota-command.ts @@ -68,7 +68,7 @@ describe("commandcode-quota command", () => { }) assert.ok(pi.handler) - const ctx = context("$COMMANDCODE_API_KEY") + const ctx = context("$COMMAND_CODE_API_KEY") await pi.handler("", ctx.value) assert.equal(ctx.waited(), true) assert.equal(requestKey, "fallback-key") diff --git a/tests/test-smoke.mjs b/tests/test-smoke.mjs index 2665710..483c00a 100644 --- a/tests/test-smoke.mjs +++ b/tests/test-smoke.mjs @@ -7,7 +7,7 @@ * 3. Can complete a simple prompt (requires Command Code auth) * * Run with: node tests/test-smoke.mjs - * Requires: pi on PATH plus COMMANDCODE_API_KEY or live pi auth files. + * Requires: pi on PATH plus COMMAND_CODE_API_KEY (or legacy COMMANDCODE_API_KEY) or live pi auth files. */ import { spawn } from "node:child_process" @@ -48,6 +48,7 @@ const RPC_QUERY_TIMEOUT = 60_000 function hasCommandCodeAuth() { return ( + !!process.env.COMMAND_CODE_API_KEY || !!process.env.COMMANDCODE_API_KEY || existsSync(join(homedir(), ".commandcode", "auth.json")) || existsSync(join(homedir(), ".pi", "agent", "auth.json"))