From ba2753dcd1716be7f1966aead0d0fe237eb58b80 Mon Sep 17 00:00:00 2001 From: konard Date: Thu, 12 Mar 2026 11:38:55 +0000 Subject: [PATCH 1/3] Initial commit with task details Adding .gitkeep for PR creation (default mode). This file will be removed when the task is complete. Issue: https://github.com/ProverCoderAI/docker-git/issues/123 --- .gitkeep | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitkeep diff --git a/.gitkeep b/.gitkeep new file mode 100644 index 00000000..44b2bc0a --- /dev/null +++ b/.gitkeep @@ -0,0 +1 @@ +# .gitkeep file auto-generated at 2026-03-12T11:38:55.781Z for PR creation at branch issue-123-a5ba76ddd9e9 for issue https://github.com/ProverCoderAI/docker-git/issues/123 \ No newline at end of file From a0470600af30051351c9cea497b07d2526a378e1 Mon Sep 17 00:00:00 2001 From: konard Date: Thu, 12 Mar 2026 11:44:31 +0000 Subject: [PATCH 2/3] fix(mcp): add retry logic for Playwright MCP browser sidecar startup Add retry mechanism to docker-git-playwright-mcp wrapper to handle browser sidecar startup delays. When Claude Code initializes the MCP server, the browser container may not be ready yet, causing the server to fail with connection errors. - Add configurable retry attempts (MCP_PLAYWRIGHT_RETRY_ATTEMPTS, default: 10) - Add configurable retry delay (MCP_PLAYWRIGHT_RETRY_DELAY, default: 2s) - Extract CDP fetch into a function for cleaner retry loop - Log retry progress to stderr for debugging - Update usage documentation with new environment variables - Add tests verifying retry logic in Dockerfile template Fixes #123 Co-Authored-By: Claude Opus 4.5 --- packages/app/src/docker-git/cli/usage.ts | 2 ++ packages/lib/src/core/templates/dockerfile.ts | 33 ++++++++++++++++++- .../lib/tests/usecases/mcp-playwright.test.ts | 9 +++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/packages/app/src/docker-git/cli/usage.ts b/packages/app/src/docker-git/cli/usage.ts index 5f0bb18a..39e303fa 100644 --- a/packages/app/src/docker-git/cli/usage.ts +++ b/packages/app/src/docker-git/cli/usage.ts @@ -81,6 +81,8 @@ Container runtime env (set via .orch/env/project.env): DOCKER_GIT_ZSH_AUTOSUGGEST_STRATEGY=... Suggestion sources (default: history completion) MCP_PLAYWRIGHT_ISOLATED=1|0 Isolated browser contexts (recommended for many Codex; default: 1) MCP_PLAYWRIGHT_CDP_ENDPOINT=http://... Override CDP endpoint (default: http://dg--browser:9223) + MCP_PLAYWRIGHT_RETRY_ATTEMPTS= Retry attempts for browser sidecar startup wait (default: 10) + MCP_PLAYWRIGHT_RETRY_DELAY= Delay between retry attempts (default: 2) Auth providers: github, gh GitHub CLI auth (tokens saved to env file) diff --git a/packages/lib/src/core/templates/dockerfile.ts b/packages/lib/src/core/templates/dockerfile.ts index 30053b8e..ba7238bf 100644 --- a/packages/lib/src/core/templates/dockerfile.ts +++ b/packages/lib/src/core/templates/dockerfile.ts @@ -105,8 +105,39 @@ if [[ -z "$CDP_ENDPOINT" ]]; then CDP_ENDPOINT="http://__SERVICE_NAME__-browser:9223" fi +# CHANGE: add retry logic for browser sidecar startup wait +# WHY: the browser container may take time to initialize, causing MCP server to fail on first attempt +# QUOTE(issue-123): "Почему MCP сервер лежит с ошибкой?" +# REF: issue-123 +# SOURCE: n/a +# FORMAT THEOREM: forall t in [1..max_attempts]: retry(t) -> eventually(cdp_ready) OR timeout_error +# PURITY: SHELL +# INVARIANT: script exits only after cdp_ready OR all retries exhausted +# COMPLEXITY: O(max_attempts * timeout_per_attempt) +MCP_PLAYWRIGHT_RETRY_ATTEMPTS="\${MCP_PLAYWRIGHT_RETRY_ATTEMPTS:-10}" +MCP_PLAYWRIGHT_RETRY_DELAY="\${MCP_PLAYWRIGHT_RETRY_DELAY:-2}" + +fetch_cdp_version() { + curl -sSf --connect-timeout 3 --max-time 10 -H 'Host: 127.0.0.1:9222' "\${CDP_ENDPOINT%/}/json/version" 2>/dev/null +} + +JSON="" +for attempt in $(seq 1 "$MCP_PLAYWRIGHT_RETRY_ATTEMPTS"); do + if JSON="$(fetch_cdp_version)"; then + break + fi + if [[ "$attempt" -lt "$MCP_PLAYWRIGHT_RETRY_ATTEMPTS" ]]; then + echo "docker-git-playwright-mcp: waiting for browser sidecar (attempt $attempt/$MCP_PLAYWRIGHT_RETRY_ATTEMPTS)..." >&2 + sleep "$MCP_PLAYWRIGHT_RETRY_DELAY" + fi +done + +if [[ -z "$JSON" ]]; then + echo "docker-git-playwright-mcp: failed to connect to CDP endpoint $CDP_ENDPOINT after $MCP_PLAYWRIGHT_RETRY_ATTEMPTS attempts" >&2 + exit 1 +fi + # kechangdev/browser-vnc binds Chromium CDP on 127.0.0.1:9222; it also host-checks HTTP requests. -JSON="$(curl -sSf --connect-timeout 3 --max-time 10 -H 'Host: 127.0.0.1:9222' "\${CDP_ENDPOINT%/}/json/version")" WS_URL="$(printf "%s" "$JSON" | node -e 'const fs=require("fs"); const j=JSON.parse(fs.readFileSync(0,"utf8")); process.stdout.write(j.webSocketDebuggerUrl || "")')" if [[ -z "$WS_URL" ]]; then echo "docker-git-playwright-mcp: webSocketDebuggerUrl missing" >&2 diff --git a/packages/lib/tests/usecases/mcp-playwright.test.ts b/packages/lib/tests/usecases/mcp-playwright.test.ts index dd45763d..f853b4d6 100644 --- a/packages/lib/tests/usecases/mcp-playwright.test.ts +++ b/packages/lib/tests/usecases/mcp-playwright.test.ts @@ -120,6 +120,15 @@ describe("enableMcpPlaywrightProjectFiles", () => { const dockerfileAfter = yield* _(fs.readFileString(path.join(outDir, "Dockerfile"))) expect(dockerfileAfter).toContain("@playwright/mcp") + // CHANGE: verify retry logic is included in docker-git-playwright-mcp wrapper + // WHY: issue-123 requires retry mechanism to handle browser sidecar startup delays + // QUOTE(issue-123): "Почему MCP сервер лежит с ошибкой?" + // REF: issue-123 + expect(dockerfileAfter).toContain("MCP_PLAYWRIGHT_RETRY_ATTEMPTS") + expect(dockerfileAfter).toContain("MCP_PLAYWRIGHT_RETRY_DELAY") + expect(dockerfileAfter).toContain("fetch_cdp_version()") + expect(dockerfileAfter).toContain("waiting for browser sidecar") + const browserDockerfileExists = yield* _(fs.exists(path.join(outDir, "Dockerfile.browser"))) const startExtraExists = yield* _(fs.exists(path.join(outDir, "mcp-playwright-start-extra.sh"))) expect(browserDockerfileExists).toBe(true) From 5a36587622a05f36f11bbf8df2cbb7b90576d01e Mon Sep 17 00:00:00 2001 From: konard Date: Thu, 12 Mar 2026 11:45:33 +0000 Subject: [PATCH 3/3] Revert "Initial commit with task details" This reverts commit ba2753dcd1716be7f1966aead0d0fe237eb58b80. --- .gitkeep | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .gitkeep diff --git a/.gitkeep b/.gitkeep deleted file mode 100644 index 44b2bc0a..00000000 --- a/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -# .gitkeep file auto-generated at 2026-03-12T11:38:55.781Z for PR creation at branch issue-123-a5ba76ddd9e9 for issue https://github.com/ProverCoderAI/docker-git/issues/123 \ No newline at end of file