Skip to content

Commit 3c924a0

Browse files
committed
fix(auth): claude oauth login UX
1 parent 0810859 commit 3c924a0

3 files changed

Lines changed: 27 additions & 7 deletions

File tree

packages/lib/src/shell/docker-auth.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,28 @@ export type DockerAuthSpec = {
1414
readonly image: string
1515
readonly volume: DockerVolume
1616
readonly entrypoint?: string
17-
readonly env?: string
17+
readonly env?: string | ReadonlyArray<string>
1818
readonly args: ReadonlyArray<string>
1919
readonly interactive: boolean
2020
}
2121

22+
const appendEnvArgs = (base: Array<string>, env: string | ReadonlyArray<string>) => {
23+
if (typeof env === "string") {
24+
const trimmed = env.trim()
25+
if (trimmed.length > 0) {
26+
base.push("-e", trimmed)
27+
}
28+
return
29+
}
30+
for (const entry of env) {
31+
const trimmed = entry.trim()
32+
if (trimmed.length === 0) {
33+
continue
34+
}
35+
base.push("-e", trimmed)
36+
}
37+
}
38+
2239
const buildDockerArgs = (spec: DockerAuthSpec): ReadonlyArray<string> => {
2340
const base: Array<string> = ["run", "--rm"]
2441
if (spec.interactive) {
@@ -28,8 +45,8 @@ const buildDockerArgs = (spec: DockerAuthSpec): ReadonlyArray<string> => {
2845
base.push("--entrypoint", spec.entrypoint)
2946
}
3047
base.push("-v", `${spec.volume.hostPath}:${spec.volume.containerPath}`)
31-
if (spec.env && spec.env.length > 0) {
32-
base.push("-e", spec.env)
48+
if (spec.env !== undefined) {
49+
appendEnvArgs(base, spec.env)
3350
}
3451
return [...base, spec.image, ...spec.args]
3552
}

packages/lib/src/usecases/auth-claude.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ const runClaudeAuthCommand = (
103103
image: claudeImageName,
104104
hostPath: accountPath,
105105
containerPath: claudeConfigDir,
106-
env: `CLAUDE_CONFIG_DIR=${claudeConfigDir}`,
106+
env: [`CLAUDE_CONFIG_DIR=${claudeConfigDir}`, "BROWSER=echo"],
107107
args,
108108
interactive
109109
}),
@@ -180,7 +180,10 @@ export const authClaudeLogin = (
180180
return Effect.fail(new AuthError({ message: "Claude auth login requires an interactive TTY." }))
181181
}
182182
const accountLabel = normalizeAccountLabel(command.label, "default")
183-
return withClaudeAuth(command, ({ accountPath, cwd }) => runClaudeLogin(cwd, accountPath, true)).pipe(
183+
return Effect.log(
184+
"Claude OAuth: open the URL, then copy the Authentication Code from the browser and paste it here (input is hidden), then press Enter."
185+
).pipe(
186+
Effect.zipRight(withClaudeAuth(command, ({ accountPath, cwd }) => runClaudeLogin(cwd, accountPath, true))),
184187
Effect.zipRight(autoSyncState(`chore(state): auth claude ${accountLabel}`))
185188
)
186189
}

packages/lib/src/usecases/auth-helpers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ type DockerAuthSpecInput = {
77
readonly hostPath: string
88
readonly containerPath: string
99
readonly entrypoint?: string
10-
readonly env?: string
10+
readonly env?: string | ReadonlyArray<string>
1111
readonly args: ReadonlyArray<string>
1212
readonly interactive: boolean
1313
}
@@ -46,7 +46,7 @@ export const buildDockerAuthSpec = (input: DockerAuthSpecInput): DockerAuthSpec
4646
image: input.image,
4747
volume: { hostPath: input.hostPath, containerPath: input.containerPath },
4848
...(typeof input.entrypoint === "string" ? { entrypoint: input.entrypoint } : {}),
49-
...(typeof input.env === "string" ? { env: input.env } : {}),
49+
...(input.env === undefined ? {} : { env: input.env }),
5050
args: input.args,
5151
interactive: input.interactive
5252
})

0 commit comments

Comments
 (0)