From be3b8b242fa8d782f55970ad2ce9aaf32d7a7613 Mon Sep 17 00:00:00 2001 From: Brian Staats Date: Wed, 16 Sep 2026 11:00:40 -0700 Subject: [PATCH] Accept Grok XAI_API_KEY auth in poteto-mode preflight `grok models` prints "You are using XAI_API_KEY." for API-key setups (including CLIProxyAPI). Preflight only accepted "logged in", so healthy proxy/API-key installs failed setup-pstack as unauthenticated. --- .../poteto-mode/scripts/runner/run.test.ts | 17 +++++++++++++++++ .../skills/poteto-mode/scripts/runner/run.ts | 9 +++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/plugins/pstack/skills/poteto-mode/scripts/runner/run.test.ts b/plugins/pstack/skills/poteto-mode/scripts/runner/run.test.ts index 20743b52..49976c70 100644 --- a/plugins/pstack/skills/poteto-mode/scripts/runner/run.test.ts +++ b/plugins/pstack/skills/poteto-mode/scripts/runner/run.test.ts @@ -84,6 +84,10 @@ if (name === "grok" && args[0] === "models") { console.error("Not logged in. Run grok auth login."); process.exit(1); } + if (process.env.FAKE_GROK_API_KEY === "1") { + console.log("You are using XAI_API_KEY.\\n\\nAvailable models:\\n * grok-4.6 (default)"); + process.exit(0); + } console.log("You are logged in with grok.com.\\nAvailable models:\\n * grok-4.6 (default)"); process.exit(0); } @@ -241,6 +245,7 @@ beforeEach(() => { delete process.env.FAKE_GROK_TRANSIENT_UNAUTH_PATH; delete process.env.FAKE_GROK_PREFLIGHT_LOG_PATH; delete process.env.FAKE_GROK_MISSING_MODEL; + delete process.env.FAKE_GROK_API_KEY; delete process.env.FAKE_DESCENDANT_HOLDS_PIPES_MS; delete process.env.FAKE_DESCENDANT_PID_PATH; delete process.env.FAKE_SELF_SIGNAL; @@ -265,6 +270,7 @@ afterEach(() => { delete process.env.FAKE_GROK_TRANSIENT_UNAUTH_PATH; delete process.env.FAKE_GROK_PREFLIGHT_LOG_PATH; delete process.env.FAKE_GROK_MISSING_MODEL; + delete process.env.FAKE_GROK_API_KEY; delete process.env.FAKE_DESCENDANT_HOLDS_PIPES_MS; delete process.env.FAKE_DESCENDANT_PID_PATH; delete process.env.FAKE_SELF_SIGNAL; @@ -347,6 +353,17 @@ describe("runLane", () => { ); }, 10_000); + it("accepts Grok API-key authentication preflight", async () => { + process.env.FAKE_GROK_API_KEY = "1"; + const input = options("grok", "grok-api-key-preflight"); + const code = await runMain(input); + expect(code).toBe(0); + expect(receipt(input.receiptPath)).toMatchObject({ + preflight: { status: "passed" }, + }); + expect(receipt(input.receiptPath).preflight.evidence).toMatch(/authenticated/i); + }); + it("classifies Grok authentication failure after two consecutive preflights", async () => { process.env.FAKE_GROK_UNAUTH = "1"; const preflightLog = join(scratch, "grok-unauthenticated.log"); diff --git a/plugins/pstack/skills/poteto-mode/scripts/runner/run.ts b/plugins/pstack/skills/poteto-mode/scripts/runner/run.ts index 054564a4..f40b60d8 100644 --- a/plugins/pstack/skills/poteto-mode/scripts/runner/run.ts +++ b/plugins/pstack/skills/poteto-mode/scripts/runner/run.ts @@ -368,8 +368,13 @@ function preflightPassed(provider: Provider, model: string, result: ProcessResul } case "codex": return /logged in/i.test(combined); - case "grok": - return /logged in/i.test(combined) && combined.includes(model); + case "grok": { + // OAuth session: "You are logged in with grok.com." + // API key (incl. via CLIProxyAPI): "You are using XAI_API_KEY." + const authenticated = + /logged in/i.test(combined) || /using XAI_API_KEY/i.test(combined); + return authenticated && combined.includes(model); + } } }