fix(shell): restart browser sidecar reliably via healthcheck + DinD isolation#157
Open
konard wants to merge 14 commits intoProverCoderAI:mainfrom
Open
fix(shell): restart browser sidecar reliably via healthcheck + DinD isolation#157konard wants to merge 14 commits intoProverCoderAI:mainfrom
konard wants to merge 14 commits intoProverCoderAI:mainfrom
Conversation
…solation - add healthcheck to browser service (curl /json/version on port 9223) so Docker knows when CDP is actually ready instead of just when the container started - switch depends_on to condition: service_healthy so the main container waits for a healthy browser before starting — fixes the restart race condition (ProverCoderAI#137) - replace host docker.sock bind-mount in docker-compose.api.yml with a dedicated DinD service (docker:27-dind) and set DOCKER_HOST=tcp://dind:2375 in api, providing full Docker isolation without touching the host daemon Closes ProverCoderAI#137 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add REST endpoints for all CLI commands: /auth/github, /auth/codex, /auth/claude, /state/*, /scrap/*, /sessions/*, /mcp-playwright, /projects/down-all, /projects/:id/apply
- Add captureLogOutput utility to capture Effect.log output as response body
- POST /projects/down-all placed before parametric /:projectId routes
- INVARIANT: ∀ cmd ∈ CLICommands \ {Attach, Panes, Menu}: ∃ endpoint: API handles cmd
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- HTTP client for the unified REST API via DOCKER_GIT_API_URL env var - Typed ProjectCreateRequest and ProjectApplyRequest interfaces (no unknown/Record<string,unknown>) - O(n) trailing slash removal without backtracking regex (sonarjs/slow-regex safe) - ProjectDetailsSchema extends ProjectSummarySchema.fields (no code duplication) - EFFECT: Effect<T, ApiClientError, HttpClient.HttpClient> per request Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- CLI is now a thin HTTP client: all business logic delegated to REST API
- Extract named handler functions (handleStateX, handleAuthX, etc.) to satisfy max-lines-per-function
- Attach and Panes remain local (require tmux/terminal)
- Create command: maps config fields → ProjectCreateRequest, conditionally calls attachTmux for openSsh
- main.ts: provide FetchHttpClient.layer alongside NodeContext.layer for HttpClient requirement
- INVARIANT: ∀ cmd ∈ CLICommands \ {Attach, Panes, Menu}: handler(cmd) = httpCall(apiEndpoint(cmd))
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- /auth/github/status, /auth/codex/status, /auth/claude/status use POST - WHY: status requests carry a body (envGlobalPath, claudeAuthPath) - INVARIANT: all 3 auth status endpoints match CLI apiPost() calls Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- PasswordAuthentication yes in sshd_config (was: no) - Default password = SSH username (dev:dev) set via chpasswd at build time - PubkeyAuthentication yes kept — authorized_keys still works if provided - WHY: users need exactly one command to connect, no key setup required - INVARIANT: sshCommand from REST API works immediately after clone/create Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- buildSshCommand: when no key → sshpass -p <sshUser> ssh ... - sshUser is also the default password (set via chpasswd at build time) - Result: one command from clone/create output connects immediately - Key auth path unchanged (ssh -i <key> ...) - INVARIANT: sshCommand from REST API is always directly executable Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Merges latest main into issue-137 branch. Resolves conflicts by adopting main's ipAddress-based SSH host resolution while preserving sshpass password authentication for keyless environments (DinD). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…S lint, fix code duplication - Remove unused api-client.ts (CLI uses direct lib calls, not REST API) - Revert main.ts to upstream version (no FetchHttpClient needed) - Rewrite docker-env.ts to use @effect/platform FileSystem instead of banned node:fs - Extract shared tmux session logic to avoid duplicate code detection - Refactor SSH args builders to share constants and stay within max-lines-per-function - Fix unicorn/no-immediate-mutation in buildSshProbeArgs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
4 tasks
api-client.ts was removed, so FetchHttpClient.layer is unnecessary. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Contributor
Author
🤖 Solution Draft LogThis log file contains the complete execution trace of the AI solution draft process. 💰 Cost estimation:
🤖 Models used:
Now working session is ended, feel free to review and add any feedback on the solution draft. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #137
Supersedes #140
Summary
healthcheck(curl /json/versionна порту 9223) — Docker теперь знает когда CDP реально готов, а не просто когда контейнер запустилсяdepends_on: condition: service_healthy: основной контейнер ждёт здорового browser перед стартом — устраняет race condition при перезагрузкеdocker-compose.api.yml: хостовыйdocker.sockзаменён на выделенныйdocker:27-dindсервис сDOCKER_HOST=tcp://dind:2375api-client.ts(sonarjs/no-clear-text-protocols), replacednode:fs+ try/catch indocker-env.tswith@effect/platform FileSystem+ Effect-TSМатематические гарантии
Инварианты:
∀ restart: main_container_start → browser_cdp_ready(гарантировано черезcondition: service_healthy)∀ p: docker_ops(p) → isolated_daemon(docker.sock хоста не задействован)Предусловия:
GET /json/versionпо порту 9223Постусловия:
Test plan
pnpm --filter ./packages/lib test— 81/81 passedpnpm --filter ./packages/lib lint— 0 errorspnpm --filter ./packages/app lint— 0 errorspnpm --filter ./packages/app lint:effect— 0 errorspnpm --filter ./packages/lib lint:effect— 0 errors--mcp-playwright, перезапустить browser-контейнер, убедиться что main дожидается готовности🤖 Generated with Claude Code