You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This defensive cleanup fires before every startup and is unrelated to the actual bring-up logic.
2. Topology-mode two-phase startup (lines 80–102)
When onNetworkReady is provided, the function performs an initial squid-proxy-only start, awaits a caller-supplied callback, then falls through to the normal full bring-up. This conditional path spans ~23 lines inside the function body.
3. Core Docker Compose bring-up (lines 65–78, 104–106)
The runDockerComposeUp inner closure and its single-path invocation is the function's primary intent (~20 lines).
4. Startup error handling, retry, and diagnostics (lines 107–185, ~78 lines)
This is the most complex part: detects which container failed (api-proxy, squid, cli-proxy), conditionally retries once, logs container logs to stderr, constructs specific error messages per container, and delegates to handleHealthcheckError. Spanning 78 lines, it accounts for more than half the function.
Proposed Split
Extract the retry/diagnostic block into a focused helper:
attemptContainerStartup(workDir, composeArgs, skipPull, onNetworkReady)
Handles the topology-mode split start plus the single runDockerComposeUp call (~40 lines). Returns on success; throws on failure.
handleStartupFailure(error, workDir, proxyLogsDir, allowedDomains)
Encapsulates the retry-once logic and all per-container diagnostic paths (~80 lines). Called only in the catch branch.
startContainers reduced to ~40 lines
Pre-cleanup → attemptContainerStartup() → on failure → handleStartupFailure().
Additionally, runAgentCommand (lines 191–268, 88 lines) has the same pattern: a timeout-vs-wait race, log streaming, blocked-domain checking, and exit-code propagation mixed in one function. That function is a separate but related candidate.
The helper functions would be module-private (no callers to update for the extraction). Only startContainers's signature is preserved unchanged.
Effort Estimate
Medium — the retry logic has several branches that need careful extraction to preserve test coverage.
Benefits
startContainers drops from 144 lines to ~40 lines
Retry/diagnostic logic independently testable without mocking the full compose bring-up
Easier to locate the security boundary: orphaned-container cleanup, topology mode, normal startup, and failure diagnostics are each in named, navigable functions
Reduces risk of introducing regressions when modifying one phase (e.g., adding a new per-container failure path)
Detected by Refactoring Scanner workflow. Run date: 2026-07-01
Refactoring Opportunity
Summary
src/container-lifecycle.tsstartContainersspans lines 43–186 (144 lines)src/container-lifecycle.tsinto focused modules #4536 ("Splitsrc/container-lifecycle.tsinto focused modules") was resolved — that split created the current file. The remainingstartContainersfunction still has four distinct concerns.Evidence
startContainers(lines 43–186) orchestrates the entire container bring-up path. It currently handles four distinct concerns:1. Orphaned container pre-cleanup (lines 47–57)
This defensive cleanup fires before every startup and is unrelated to the actual bring-up logic.
2. Topology-mode two-phase startup (lines 80–102)
When
onNetworkReadyis provided, the function performs an initialsquid-proxy-only start, awaits a caller-supplied callback, then falls through to the normal full bring-up. This conditional path spans ~23 lines inside the function body.3. Core Docker Compose bring-up (lines 65–78, 104–106)
The
runDockerComposeUpinner closure and its single-path invocation is the function's primary intent (~20 lines).4. Startup error handling, retry, and diagnostics (lines 107–185, ~78 lines)
This is the most complex part: detects which container failed (
api-proxy,squid,cli-proxy), conditionally retries once, logs container logs to stderr, constructs specific error messages per container, and delegates tohandleHealthcheckError. Spanning 78 lines, it accounts for more than half the function.Proposed Split
Extract the retry/diagnostic block into a focused helper:
attemptContainerStartup(workDir, composeArgs, skipPull, onNetworkReady)Handles the topology-mode split start plus the single
runDockerComposeUpcall (~40 lines). Returns on success; throws on failure.handleStartupFailure(error, workDir, proxyLogsDir, allowedDomains)Encapsulates the retry-once logic and all per-container diagnostic paths (~80 lines). Called only in the catch branch.
startContainersreduced to ~40 linesPre-cleanup →
attemptContainerStartup()→ on failure →handleStartupFailure().Additionally,
runAgentCommand(lines 191–268, 88 lines) has the same pattern: a timeout-vs-wait race, log streaming, blocked-domain checking, and exit-code propagation mixed in one function. That function is a separate but related candidate.Affected Callers
The helper functions would be module-private (no callers to update for the extraction). Only
startContainers's signature is preserved unchanged.Effort Estimate
Medium — the retry logic has several branches that need careful extraction to preserve test coverage.
Benefits
startContainersdrops from 144 lines to ~40 linesDetected by Refactoring Scanner workflow. Run date: 2026-07-01