diff --git a/packages/cli/src/commands/auth/login.test.ts b/packages/cli/src/commands/auth/login.test.ts index ec6db3b2ff..5c19cfb187 100644 --- a/packages/cli/src/commands/auth/login.test.ts +++ b/packages/cli/src/commands/auth/login.test.ts @@ -440,12 +440,10 @@ describe("auth login", () => { expect(deviceAuth.start).toHaveBeenCalledOnce(); }); - it("refuses device authorization when either terminal stream is not a TTY", async () => { - Object.defineProperty(process.stdout, "isTTY", { - configurable: true, - value: undefined, - }); - await expect(runCommand({ device: true })).rejects.toThrow(/Invalid command usage/); - expect(deviceAuth.start).not.toHaveBeenCalled(); + it("runs device authorization without a terminal, where only a URL and code are printed", async () => { + Object.defineProperty(process.stdin, "isTTY", { configurable: true, value: undefined }); + Object.defineProperty(process.stdout, "isTTY", { configurable: true, value: undefined }); + await runCommand({ device: true }); + expect(deviceAuth.start).toHaveBeenCalledOnce(); }); }); diff --git a/packages/cli/src/commands/auth/login.ts b/packages/cli/src/commands/auth/login.ts index 19042b0878..4ef14592bd 100644 --- a/packages/cli/src/commands/auth/login.ts +++ b/packages/cli/src/commands/auth/login.ts @@ -1,5 +1,5 @@ import { failCommand, failUsage, requestCliExit } from "../../utils/commandResult.js"; -import { envFlagEnabled, isAttendedTerminal, isCI } from "../../utils/attendedTerminal.js"; +import { envFlagEnabled, isCI } from "../../utils/attendedTerminal.js"; import { isAgentDriven } from "../../telemetry/agent_runtime.js"; /** * `hyperframes auth login` — sign in to HeyGen. @@ -70,7 +70,8 @@ export default defineCommand({ }, device: { type: "boolean", - description: "Use an attended device code (for SSH/headless terminals; never for CI).", + description: + "Use a device code approved in any browser (for SSH, headless or agent-run terminals; never for CI).", }, }, // fallow-ignore-next-line complexity @@ -123,11 +124,11 @@ function agentShellOnThisMachine(): boolean { return !isCI() && isAgentDriven(); } -function assertAttendedDeviceFlow(): void { - if (!isAttendedTerminal()) { +function assertDeviceFlowAllowed(): void { + if (isCI()) { console.error( c.error( - "`--device` requires an attended terminal and is disabled in CI. Use an API key or workload credential for automation.", + "`--device` needs a person to approve it and is disabled in CI. Use an API key or workload credential for automation.", ), ); failUsage(); @@ -135,7 +136,7 @@ function assertAttendedDeviceFlow(): void { } async function runDeviceLogin(): Promise { - assertAttendedDeviceFlow(); + assertDeviceFlowAllowed(); assertOAuthConfiguredOrExit(); const { trackAuthLoginStarted, trackAuthLoginCompleted, trackAuthLoginFailed, identifyUser } = await import("../../telemetry/index.js");