fix(auth): support official Command Code environment names

This commit is contained in:
Patrick Wozniak
2026-08-25 15:54:29 +02:00
parent c51a790530
commit 6a7a71e206
13 changed files with 31 additions and 14 deletions
+2 -1
View File
@@ -39,10 +39,11 @@ function runProfile(profile, apiKey) {
const model = process.env[modelVariable] ?? "deepseek/deepseek-v4-flash" const model = process.env[modelVariable] ?? "deepseek/deepseek-v4-flash"
const env = { const env = {
...process.env, ...process.env,
COMMANDCODE_API_KEY: apiKey, COMMAND_CODE_API_KEY: apiKey,
COMMANDCODE_E2E_MODEL: model, COMMANDCODE_E2E_MODEL: model,
COMMANDCODE_E2E_PROFILE: profile, COMMANDCODE_E2E_PROFILE: profile,
} }
delete env.COMMANDCODE_API_KEY
delete env.COMMANDCODE_E2E_GO_API_KEY delete env.COMMANDCODE_E2E_GO_API_KEY
delete env.COMMANDCODE_E2E_PROVIDER_API_KEY delete env.COMMANDCODE_E2E_PROVIDER_API_KEY
+1
View File
@@ -11,6 +11,7 @@ const env = {
...process.env, ...process.env,
PI_SKIP_VERSION_CHECK: "1", PI_SKIP_VERSION_CHECK: "1",
} }
delete env.COMMAND_CODE_API_KEY
delete env.COMMANDCODE_API_KEY delete env.COMMANDCODE_API_KEY
const child = spawn( const child = spawn(
+1
View File
@@ -22,6 +22,7 @@ const env = {
PI_CODING_AGENT_SESSION_DIR: sessionDir, PI_CODING_AGENT_SESSION_DIR: sessionDir,
PI_SKIP_VERSION_CHECK: "1", PI_SKIP_VERSION_CHECK: "1",
} }
delete env.COMMAND_CODE_API_KEY
delete env.COMMANDCODE_API_KEY delete env.COMMANDCODE_API_KEY
let activeChild let activeChild
+1
View File
@@ -34,6 +34,7 @@ export function getConfiguredApiKey(
} = {}, } = {},
): string | undefined { ): string | undefined {
const env = options.env ?? process.env 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 if (env.COMMANDCODE_API_KEY) return env.COMMANDCODE_API_KEY
const home = options.homeDir?.() ?? homedir() const home = options.homeDir?.() ?? homedir()
+1 -1
View File
@@ -45,7 +45,7 @@ export function registerCommandCodeQuota(
const apiKey = pickCommandCodeApiKey(registryKey, getConfiguredKey()) const apiKey = pickCommandCodeApiKey(registryKey, getConfiguredKey())
if (!apiKey) { if (!apiKey) {
ctx.ui.notify( 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", "warning",
) )
return return
+10 -3
View File
@@ -21,10 +21,17 @@ async function withAuthFile(
} }
describe("getConfiguredApiKey()", () => { describe("getConfiguredApiKey()", () => {
it("prefers the environment variable", () => { it("prefers the official environment variable and keeps the legacy alias", () => {
assert.equal( assert.equal(
getConfiguredApiKey({ env: { COMMANDCODE_API_KEY: "env-key" }, authPaths: [] }), getConfiguredApiKey({
"env-key", 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",
) )
}) })
+2
View File
@@ -48,6 +48,7 @@ function findPiBinary() {
function hasAuthMetadata() { function hasAuthMetadata() {
return ( return (
Boolean(process.env.COMMAND_CODE_API_KEY) ||
Boolean(process.env.COMMANDCODE_API_KEY) || Boolean(process.env.COMMANDCODE_API_KEY) ||
existsSync(join(homedir(), ".commandcode", "auth.json")) || existsSync(join(homedir(), ".commandcode", "auth.json")) ||
existsSync(join(homedir(), ".pi", "agent", "auth.json")) existsSync(join(homedir(), ".pi", "agent", "auth.json"))
@@ -70,6 +71,7 @@ function safeEnv(overrides = {}) {
env.PI_CODING_AGENT_DIR = profileAgentDir env.PI_CODING_AGENT_DIR = profileAgentDir
env.COMMANDCODE_MODELS_CACHE = join(profileAgentDir, "commandcode-models.json") env.COMMANDCODE_MODELS_CACHE = join(profileAgentDir, "commandcode-models.json")
} else { } else {
delete env.COMMAND_CODE_API_KEY
delete env.COMMANDCODE_API_KEY delete env.COMMANDCODE_API_KEY
} }
return env return env
+1 -1
View File
@@ -133,7 +133,7 @@ function runOmp(args, timeoutMs = 30_000) {
HOME: tempHome, HOME: tempHome,
USERPROFILE: tempHome, USERPROFILE: tempHome,
PI_CODING_AGENT_DIR: join(tempHome, ".omp", "agent"), 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_API_BASE: `${apiBase}/provider/v1`,
COMMANDCODE_MODELS_URL: `${apiBase}/provider/v1/models`, COMMANDCODE_MODELS_URL: `${apiBase}/provider/v1/models`,
}, },
+3 -2
View File
@@ -22,7 +22,7 @@ const { writeFileSync } = require("node:fs")
writeFileSync(process.env.FAKE_PI_LOG, JSON.stringify({ writeFileSync(process.env.FAKE_PI_LOG, JSON.stringify({
args: process.argv.slice(2), args: process.argv.slice(2),
agentDir: process.env.PI_CODING_AGENT_DIR ?? null, 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, skipVersionCheck: process.env.PI_SKIP_VERSION_CHECK,
})) }))
NODE NODE
@@ -38,7 +38,8 @@ NODE
PATH: `${fakeBin}${delimiter}${process.env.PATH ?? ""}`, PATH: `${fakeBin}${delimiter}${process.env.PATH ?? ""}`,
FAKE_PI_LOG: logPath, FAKE_PI_LOG: logPath,
PI_CODING_AGENT_DIR: "/existing/pi-agent", 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", encoding: "utf8",
}) })
+4 -2
View File
@@ -26,7 +26,8 @@ appendFileSync(process.env.FAKE_PI_LOG, JSON.stringify({
skipVersionCheck: process.env.PI_SKIP_VERSION_CHECK, skipVersionCheck: process.env.PI_SKIP_VERSION_CHECK,
home: process.env.HOME, home: process.env.HOME,
userProfile: process.env.USERPROFILE, 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") }) + "\\n")
NODE NODE
if [ "$1" = "install" ]; then exit 0; fi if [ "$1" = "install" ]; then exit 0; fi
@@ -42,7 +43,8 @@ exit ${exitStatus}
...process.env, ...process.env,
PATH: `${fakeBin}${delimiter}${process.env.PATH ?? ""}`, PATH: `${fakeBin}${delimiter}${process.env.PATH ?? ""}`,
FAKE_PI_LOG: logPath, 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", encoding: "utf8",
}) })
+2 -2
View File
@@ -215,8 +215,8 @@ const env = {
PI_CODING_AGENT_DIR: agentDir, PI_CODING_AGENT_DIR: agentDir,
PI_CODING_AGENT_SESSION_DIR: join(tempHome, "sessions"), PI_CODING_AGENT_SESSION_DIR: join(tempHome, "sessions"),
COMMANDCODE_API_BASE: `${apiBase}/provider/v1`, COMMANDCODE_API_BASE: `${apiBase}/provider/v1`,
COMMANDCODE_API_KEY: "mock-key", COMMAND_CODE_API_KEY: "mock-key",
COMMANDCODE_ZDR: "1", CMD_ZDR: "1",
COMMANDCODE_MODELS_URL: `${apiBase}/provider/v1/models`, COMMANDCODE_MODELS_URL: `${apiBase}/provider/v1/models`,
} }
+1 -1
View File
@@ -68,7 +68,7 @@ describe("commandcode-quota command", () => {
}) })
assert.ok(pi.handler) assert.ok(pi.handler)
const ctx = context("$COMMANDCODE_API_KEY") const ctx = context("$COMMAND_CODE_API_KEY")
await pi.handler("", ctx.value) await pi.handler("", ctx.value)
assert.equal(ctx.waited(), true) assert.equal(ctx.waited(), true)
assert.equal(requestKey, "fallback-key") assert.equal(requestKey, "fallback-key")
+2 -1
View File
@@ -7,7 +7,7 @@
* 3. Can complete a simple prompt (requires Command Code auth) * 3. Can complete a simple prompt (requires Command Code auth)
* *
* Run with: node tests/test-smoke.mjs * 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" import { spawn } from "node:child_process"
@@ -48,6 +48,7 @@ const RPC_QUERY_TIMEOUT = 60_000
function hasCommandCodeAuth() { function hasCommandCodeAuth() {
return ( return (
!!process.env.COMMAND_CODE_API_KEY ||
!!process.env.COMMANDCODE_API_KEY || !!process.env.COMMANDCODE_API_KEY ||
existsSync(join(homedir(), ".commandcode", "auth.json")) || existsSync(join(homedir(), ".commandcode", "auth.json")) ||
existsSync(join(homedir(), ".pi", "agent", "auth.json")) existsSync(join(homedir(), ".pi", "agent", "auth.json"))