Skip to content

Commit 20e51ca

Browse files
authored
Merge pull request #441 from skulidropek/pr-440
[codex] fix Claude auth probe and state sync locking
2 parents f601d55 + ae12482 commit 20e51ca

57 files changed

Lines changed: 4798 additions & 688 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
"@prover-coder-ai/docker-git": patch
3+
---
4+
5+
Fix `docker-git auth claude login` failing after a successful OAuth login.
6+
7+
After `claude setup-token` created and persisted the OAuth token, the login
8+
command ran a verification probe (`claude -p ping`) and treated any non-zero
9+
exit as a hard failure, exiting with code 1 even though the token was already
10+
saved. A transient probe failure (network hiccup, rate limit, or token
11+
propagation delay) would therefore discard an otherwise successful login.
12+
13+
The probe failure is now reported as a warning instead of an error, mirroring
14+
`docker-git auth claude status`. The token is kept, and the user is advised to
15+
re-check connectivity later with `docker-git auth claude status`.
16+
17+
Controller startup now also rejects `DOCKER_GIT_CONTROLLER_GPU=all` when
18+
`docker-compose.gpu.yml` exists as a directory instead of a regular file,
19+
matching the extra compose overlay invariant before invoking Docker Compose.

.github/actions/setup/action.yml

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,32 @@ runs:
5757
run: npm install -g node-gyp
5858
- name: Install dependencies
5959
shell: bash
60-
run: bun install --frozen-lockfile
60+
run: |
61+
run_bun_install() {
62+
local timeout_seconds=$((20 * 60))
63+
bun install --frozen-lockfile &
64+
local install_pid="$!"
65+
(
66+
sleep "$timeout_seconds"
67+
echo "bun install exceeded 20 minutes; terminating" >&2
68+
kill "$install_pid" 2>/dev/null || true
69+
) &
70+
local timeout_pid="$!"
71+
local status=0
72+
wait "$install_pid" || status="$?"
73+
kill "$timeout_pid" 2>/dev/null || true
74+
wait "$timeout_pid" 2>/dev/null || true
75+
return "$status"
76+
}
77+
78+
for attempt in 1 2 3; do
79+
if run_bun_install; then
80+
exit 0
81+
fi
82+
if [[ "$attempt" == "3" ]]; then
83+
echo "bun install failed after retries" >&2
84+
exit 1
85+
fi
86+
echo "bun install attempt ${attempt} failed; retrying..." >&2
87+
sleep $((attempt * 2))
88+
done

.github/workflows/check.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,27 @@ jobs:
249249
- name: Login context notice
250250
run: bash scripts/e2e/login-context.sh
251251

252+
e2e-auth-claude-login:
253+
name: E2E (Claude auth login)
254+
runs-on: ubuntu-latest
255+
timeout-minutes: 40
256+
env:
257+
DOCKER_GIT_CONTROLLER_BUILD_SKILLER: "0"
258+
DOCKER_GIT_E2E_REUSE_WORKSPACE_INSTALL: "1"
259+
steps:
260+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
261+
with:
262+
persist-credentials: false
263+
submodules: true
264+
- name: Install dependencies
265+
uses: ./.github/actions/setup
266+
- name: Free Docker disk
267+
uses: ./.github/actions/free-docker-disk
268+
- name: Docker info
269+
run: docker version && docker compose version
270+
- name: Claude auth login warning path
271+
run: bash scripts/e2e/auth-claude-login.sh
272+
252273
e2e-runtime-volumes-ssh:
253274
name: E2E (Runtime volumes + SSH)
254275
runs-on: ubuntu-latest

bun.lock

Lines changed: 17 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"workspaces": [
88
"packages/api",
99
"packages/app",
10+
"packages/auth-oauth",
1011
"packages/container",
1112
"packages/docker-git-session-sync",
1213
"packages/lib",
@@ -15,13 +16,13 @@
1516
],
1617
"scripts": {
1718
"setup:pre-commit-hook": "bun scripts/setup-pre-commit-hook.js",
18-
"build": "bun run --filter @prover-coder-ai/docker-git-session-sync build && bun run --filter @prover-coder-ai/docker-git-terminal build && bun run --filter @prover-coder-ai/docker-git build",
19+
"build": "bun run --filter @prover-coder-ai/docker-git-auth-oauth build && bun run --filter @prover-coder-ai/docker-git-session-sync build && bun run --filter @prover-coder-ai/docker-git-terminal build && bun run --filter @prover-coder-ai/docker-git build",
1920
"api:build": "bun run --filter @effect-template/api build",
2021
"api:start": "bun run --filter @effect-template/api start",
2122
"api:dev": "bun run --filter @effect-template/api dev",
2223
"api:test": "bun run --filter @effect-template/api test",
2324
"api:typecheck": "bun run --filter @effect-template/api typecheck",
24-
"check": "bun run --filter @prover-coder-ai/docker-git-session-sync check && bun run --filter @prover-coder-ai/docker-git-terminal check && bun run --filter @prover-coder-ai/docker-git-openapi check && bun run --filter @prover-coder-ai/docker-git check && bun run --filter @effect-template/lib typecheck",
25+
"check": "bun run --filter @prover-coder-ai/docker-git-auth-oauth check && bun run --filter @prover-coder-ai/docker-git-session-sync check && bun run --filter @prover-coder-ai/docker-git-terminal check && bun run --filter @prover-coder-ai/docker-git-openapi check && bun run --filter @prover-coder-ai/docker-git check && bun run --filter @effect-template/lib typecheck",
2526
"check:dist-deps-prune": "bun node_modules/@prover-coder-ai/dist-deps-prune/dist/main.js scan --package ./packages/app/package.json --prune-dev true --silent",
2627
"changeset": "changeset",
2728
"changeset-publish": "bun -e \"if (!process.env.NPM_TOKEN) { console.log('Skipping publish: NPM_TOKEN is not set'); process.exit(0); }\" && changeset publish",
@@ -52,8 +53,8 @@
5253
"lint:effect": "bun run --filter @prover-coder-ai/docker-git-session-sync lint:effect && bun run --filter @prover-coder-ai/docker-git-terminal lint:effect && bun run --filter @prover-coder-ai/docker-git lint:effect && bun run --filter @prover-coder-ai/docker-git-container lint:effect && bun run --filter @effect-template/lib lint:effect && bun run --filter @effect-template/api lint:effect",
5354
"effect:skill:init": "git submodule update --init --checkout third_party/effect-ts-skills",
5455
"effect:skill:check": "bun run effect:skill:init && bash .codex/skills/effect-ts-guide/scripts/run-effect-ts-check.sh packages/app/src/web/api-create-project.ts packages/app/src/web/api-database.ts packages/app/src/web/api-http.ts packages/app/src/web/api-prompts.ts packages/app/src/web/api-skills.ts packages/app/src/web/api-tasks.ts packages/openapi/src --profile strict",
55-
"test": "bun run --filter @prover-coder-ai/docker-git-session-sync test && bun run --filter @prover-coder-ai/docker-git-terminal test && bun run --filter @prover-coder-ai/docker-git test && bun run --filter @effect-template/lib test",
56-
"typecheck": "bun run --filter @prover-coder-ai/docker-git-session-sync typecheck && bun run --filter @prover-coder-ai/docker-git-terminal typecheck && bun run --filter @prover-coder-ai/docker-git-openapi typecheck && bun run --filter @prover-coder-ai/docker-git typecheck && bun run --filter @effect-template/lib typecheck",
56+
"test": "bun run --filter @prover-coder-ai/docker-git-auth-oauth test && bun run --filter @prover-coder-ai/docker-git-session-sync test && bun run --filter @prover-coder-ai/docker-git-terminal test && bun run --filter @prover-coder-ai/docker-git test && bun run --filter @effect-template/lib test",
57+
"typecheck": "bun run --filter @prover-coder-ai/docker-git-auth-oauth typecheck && bun run --filter @prover-coder-ai/docker-git-session-sync typecheck && bun run --filter @prover-coder-ai/docker-git-terminal typecheck && bun run --filter @prover-coder-ai/docker-git-openapi typecheck && bun run --filter @prover-coder-ai/docker-git typecheck && bun run --filter @effect-template/lib typecheck",
5758
"start": "bun run --cwd packages/app build:docker-git && bun ./packages/app/dist/src/docker-git/main.js"
5859
},
5960
"devDependencies": {

packages/api/Dockerfile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,10 @@ RUN set -eu; \
7676
FROM controller-base AS workspace-deps
7777

7878
COPY package.json bun.lock bunfig.toml tsconfig.base.json tsconfig.json ./
79-
RUN mkdir -p packages/api packages/app packages/container packages/docker-git-session-sync packages/lib packages/openapi packages/terminal
79+
RUN mkdir -p packages/api packages/app packages/auth-oauth packages/container packages/docker-git-session-sync packages/lib packages/openapi packages/terminal
8080
COPY packages/api/package.json ./packages/api/package.json
8181
COPY packages/app/package.json ./packages/app/package.json
82+
COPY packages/auth-oauth/package.json ./packages/auth-oauth/package.json
8283
COPY packages/container/package.json ./packages/container/package.json
8384
COPY packages/docker-git-session-sync/package.json ./packages/docker-git-session-sync/package.json
8485
COPY packages/lib/package.json ./packages/lib/package.json
@@ -92,6 +93,7 @@ RUN set -eu; \
9293
--silent \
9394
--filter @effect-template/api \
9495
--filter @effect-template/lib \
96+
--filter @prover-coder-ai/docker-git-auth-oauth \
9597
--filter @prover-coder-ai/docker-git-container \
9698
--filter @prover-coder-ai/docker-git-terminal \
9799
--filter @prover-coder-ai/docker-git-session-sync; then \
@@ -109,12 +111,14 @@ FROM workspace-deps AS workspace-static
109111
COPY patches ./patches
110112
COPY scripts ./scripts
111113
COPY packages/container ./packages/container
114+
COPY packages/auth-oauth ./packages/auth-oauth
112115
COPY packages/docker-git-session-sync ./packages/docker-git-session-sync
113116
COPY packages/lib ./packages/lib
114117
COPY packages/terminal ./packages/terminal
115118

116119
RUN bun run --cwd packages/docker-git-session-sync build
117120
RUN bun run --cwd packages/terminal build
121+
RUN bun run --cwd packages/auth-oauth build
118122
RUN bun run --cwd packages/container build
119123
RUN bun run --cwd packages/lib build
120124

packages/api/src/api/contracts.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,15 @@ export type CodexAuthStatus = {
299299
readonly account: string | null
300300
}
301301

302+
export type ClaudeAuthStatus = {
303+
readonly label: string
304+
readonly message: string
305+
readonly connected: boolean
306+
readonly authPath: string
307+
readonly account: string | null
308+
readonly method: "none" | "oauth-token" | "claude-ai-session"
309+
}
310+
302311
export type GrokAuthStatus = {
303312
readonly label: string
304313
readonly message: string

packages/api/src/api/openapi.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,20 @@ export const CodexStatusResponseSchema = Schema.Struct({
251251
status: CodexAuthStatusSchema
252252
})
253253

254+
export const ClaudeAuthStatusSchema = Schema.Struct({
255+
account: NullableStringSchema,
256+
authPath: Schema.String,
257+
connected: Schema.Boolean,
258+
label: Schema.String,
259+
message: Schema.String,
260+
method: Schema.Literal("none", "oauth-token", "claude-ai-session")
261+
})
262+
263+
export const ClaudeStatusResponseSchema = Schema.Struct({
264+
ok: OptionalOkSchema,
265+
status: ClaudeAuthStatusSchema
266+
})
267+
254268
export const GrokAuthStatusSchema = Schema.Struct({
255269
authPath: Schema.String,
256270
connected: Schema.Boolean,
@@ -601,6 +615,11 @@ const AuthGroup = HttpApiGroup.make("auth")
601615
.setUrlParams(QueryLabelSchema)
602616
.addSuccess(CodexStatusResponseSchema)
603617
)
618+
.add(
619+
endpoint.get("claudeStatus", "/auth/claude/status")
620+
.setUrlParams(QueryLabelSchema)
621+
.addSuccess(ClaudeStatusResponseSchema)
622+
)
604623
.add(
605624
endpoint.post("githubLogin", "/auth/github/login")
606625
.setPayload(GithubAuthLoginRequestSchema)

packages/api/src/http.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ import {
5959
logoutGitAuth,
6060
logoutGitlabAuth,
6161
logoutGithubAuth,
62+
readClaudeAuthStatus,
6263
readCodexAuthStatus,
6364
readGrokAuthStatus,
6465
readGitAuthStatus,
@@ -1138,6 +1139,15 @@ export const makeRouter = () => {
11381139
return yield* _(jsonResponse({ status }, 200))
11391140
}).pipe(Effect.catchAll(errorResponse))
11401141
),
1142+
HttpRouter.get(
1143+
"/auth/claude/status",
1144+
Effect.gen(function*(_) {
1145+
const request = yield* _(HttpServerRequest.HttpServerRequest)
1146+
const label = new URL(request.url, "http://localhost").searchParams.get("label")
1147+
const status = yield* _(readClaudeAuthStatus(label))
1148+
return yield* _(jsonResponse({ status }, 200))
1149+
}).pipe(Effect.catchAll(errorResponse))
1150+
),
11411151
HttpRouter.get(
11421152
"/auth/menu",
11431153
Effect.gen(function*(_) {

0 commit comments

Comments
 (0)