Skip to content

Handle idle project runtimes#312

Merged
skulidropek merged 8 commits into
mainfrom
issue-306
May 18, 2026
Merged

Handle idle project runtimes#312
skulidropek merged 8 commits into
mainfrom
issue-306

Conversation

@skulidropek
Copy link
Copy Markdown
Member

Summary

  • add project auto-suspend based on agent activity, with live terminal/browser/skiller sessions preventing hard stops
  • add manual resume/suspend APIs and clients, and stop using compose restart policies
  • move Playwright browser runtime to a nested browser container launched by the main project container with dedicated limits

Testing

  • rtk bun run check
  • rtk bun run --cwd packages/lib test -- tests/core/templates.test.ts tests/usecases/prepare-files.test.ts tests/usecases/mcp-playwright.test.ts tests/core/resource-limits.test.ts
  • rtk bun run --cwd packages/api test -- tests/schema.test.ts tests/project-idle-policy.test.ts tests/terminal-sessions.test.ts tests/project-port-forward-core.test.ts
  • rtk bun run --cwd packages/app test -- tests/docker-git/actions-browser.test.ts tests/docker-git/api-client-create.test.ts tests/docker-git/parser-playwright-resource.test.ts tests/docker-git/actions-project-create.test.ts tests/docker-git/actions-projects.test.ts
  • generated browser runtime bash -n
  • generated entrypoint bash -n
  • generated compose docker compose config
  • rtk bun run test (fails in existing lib state-repo tests on git push origin HEAD:refs/heads/main exited with 1)

Closes #306

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 18, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8be47d2a-ec30-4af9-b696-24e596e61def

📥 Commits

Reviewing files that changed from the base of the PR and between 4234a74 and fcb764a.

📒 Files selected for processing (1)
  • packages/api/tests/projects.test.ts
📜 Recent review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Browser command)
  • GitHub Check: Lint
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/api/tests/projects.test.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/api/tests/projects.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/api/tests/projects.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/api/tests/projects.test.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/api/tests/projects.test.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/api/tests/projects.test.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/api/tests/projects.test.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/api/tests/projects.test.ts
🔇 Additional comments (1)
packages/api/tests/projects.test.ts (1)

187-198: ⚡ Quick win

Это изменение — намеренная стабилизация тестов, а не проблемный код.

Коммит fcb764a "Stabilize docker access API test" показывает, что переход с unix socket на TCP 127.0.0.1:1 был целенаправленным для повышения надёжности теста в CI, а не случайным изменением.

  1. Проверка сообщения об ошибке уже встроена в тест (строка 206): expect(failure.message).toContain("Cannot connect to Docker daemon."). Если бы новый метод воспроизведения сбоя не генерировал ожидаемую ошибку, тест не прошёл бы.

  2. Порт 1 — хороший выбор для стабильности, а не плохой: он зарезервирован (tcpmux) и гарантированно недоступен на любой системе, что обеспечивает мгновенный отказ в соединении. Это БОЛЕЕ надёжно, чем unix socket, который может иметь race conditions на уровне файловой системы. Предложение использовать порт 65535 фактически менее надёжно (такой порт может быть занят).

  3. Изменение связано с целями PR: стабилизация тестов критична для вложенного Playwright runtime и авто-suspend функциональности. Подобные улучшения в надёжности тестов — часть подготовки к новым возможностям.

     		> Likely an incorrect or invalid review comment.
    

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Отдельные CPU/RAM лимиты для Playwright при создании/применении проекта; новые операции проекта: apply, resume, suspend.
    • Поддержка вложенного Playwright browser runtime для проектов (автозапуск/управление).
  • Bug Fixes / Improvements

    • Отслеживание активности (браузер, терминал, Skiller, агент) и улучшенная логика авто‑приостановки runtime.
  • Tests

    • Добавлены/обновлены тесты для схем, политики простоя и генерации артефактов.
  • Documentation

    • Терминология обновлена: «browser sidecar» → «Playwright browser runtime».

Walkthrough

PR вводит авто‑приостановку проектов по активности, расширяет runtime‑модель и управление ресурсами, реализует nested Playwright browser runtime, добавляет lifecycle endpoints (apply/resume/suspend), обновляет шаблоны/compose/Dockerfile, клиенты и тесты.

Changes

Основная функциональность автоприостановки и управления ресурсами

Layer / File(s) Summary
Расширение модели runtime‑состояния
packages/lib/src/usecases/project-runtime-state.ts, packages/lib/tests/usecases/project-runtime-state.test.ts
Добавлены типы ProjectRuntimeActivityKind, ProjectRuntimeResourceProfile, ProjectRuntimeStopReason; расширён ProjectRuntimeState новыми полями lastAgentSeenAt*, lastInteractiveSeenAt*, resourceProfile, lastStopReason; обновлена сериализация runtime.json и операции записи/чтения.
Политика idle-решений
packages/api/src/services/project-idle-policy.ts, packages/api/tests/project-idle-policy.test.ts
Реализована decideProjectIdleAction с helper-функциями latestEpoch/hasTimedOut и вариантами действий: IgnoreStopped, KeepRunning, RestoreNormalResources, ThrottleInteractiveIdle, SuspendIdle.
Автоприостановка: конфиг, scan и loop
packages/api/src/services/project-auto-suspend.ts, packages/api/src/program.ts
Добавлен модуль авто‑suspend: resolveProjectAutoSuspendConfig, scanProjectAutoSuspend, runProjectIdleDecision и startProjectAutoSuspendLoop; program запускает фоновой loop.
Управление ресурсами контейнеров и lifecycle helpers
packages/api/src/services/project-lifecycle-resources.ts, packages/lib/src/shell/docker-compose.ts
Функции расчёта/нормализации CPU, best‑effort обновление CPU контейнера, stopProjectBrowserRuntime, suspendProjectRuntime (использует runDockerComposeStop) и applyProjectResourceProfile.
Сервис проектов: up/down/apply/resume/suspend
packages/api/src/services/projects.ts, packages/api/src/http.ts, packages/api/src/api/contracts.ts, packages/api/src/api/schema.ts
Добавлены resumeProject, suspendProject; router выделяет withProjectLifecycleBase с POST /apply, /resume, /suspend, /down; контракты/schemas дополнены cpuLimit/ramLimit и playwrightCpuLimit/playwrightRamLimit.
Отслеживание активности: agents/terminal/browser/skiller
packages/api/src/services/agents.ts, packages/api/src/services/terminal-sessions.ts, packages/api/src/services/project-browser.ts, packages/api/src/services/skiller.ts
Best‑effort записи активности агента и интерактивных сессий (browser HTTP/WebSocket, terminal, skiller), rate‑limited writes, счётчики live‑сессий и экспорт hasLiveProject* функций.
Nested Playwright browser runtime (scripts + entrypoint + Dockerfile)
packages/lib/src/core/templates/playwright-browser-runtime.ts, packages/lib/src/core/templates-entrypoint/playwright-browser.ts, packages/lib/src/core/templates-entrypoint/base.ts, packages/lib/src/core/templates/dockerfile.ts
Новый bash‑скрипт для запуска/очистки nested browser контейнера, entrypoint fragment вызывает start/stop; sshd wrapper гарантирует остановку вложенного браузера; Dockerfile включает runtime файлы и локальный CDP endpoint по умолчанию.
Docker‑compose шаблоны и опции
packages/lib/src/core/templates/docker-compose.ts, packages/lib/src/core/templates.ts, packages/lib/src/shell/files.ts
Compose перестроен: отдельный browser‑service убран, добавлено опциональное монтирование локального docker.sock, env‑плейсхолдеры DOCKER_GIT_BROWSER_*_LIMIT, planFiles получает options и добавляет docker-git-browser-runtime.sh.
Entrypoint и templates integration
packages/lib/src/core/templates-entrypoint.ts, packages/lib/src/core/templates-entrypoint/playwright-browser.ts, packages/lib/src/core/templates-entrypoint/base.ts
Entrypoint вызывает фрагмент Playwright runtime и sshd wrapper теперь корректно останавливает browser runtime при shutdown.
Клиенты и контракты (CLI + web)
packages/app/src/shared/project-resource-request.ts, packages/app/src/web/api-project-core.ts, packages/app/src/docker-git/api-client.ts, packages/app/src/docker-git/api-client-create.ts
Унифицированные типы ProjectResourceLimitRequest/ApplyProjectRequest; CLI/web клиенты передают playwright лимиты; добавлены applyProject, resumeProject, suspendProject.
UI и терминология
packages/app/src/docker-git/cli/usage.ts, packages/app/src/web/actions-browser.ts, packages/app/src/web/panel-browser.tsx, packages/app/src/web/app-ready-browser-openable.ts
Тексты, справка и тесты обновлены: замена терминологии "sidecar" → "runtime".
Тесты и проверки шаблонов
packages/api/tests/*, packages/lib/tests/*, packages/app/tests/*
Добавлены/обновлены тесты для policy, schema, templates, runtime‑state, docker.compose stop и клиентских payloads под новую nested‑архитектуру.

Estimated code review effort:
🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs:

  • ProverCoderAI/docker-git#309: изменяет терминальную/WebSocket‑логику и активные сессии — тесно связанный кодовый контекст для terminal/session changes.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-306

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/api/src/services/project-auto-suspend.ts`:
- Around line 66-74: snapshotHasAgentTask currently swallows any error from
readContainerTaskSnapshot and returns false, which can cause a live agent to be
treated as absent; change snapshotHasAgentTask to not treat inspection errors as
"no agent": when readContainerTaskSnapshot fails, log a warning (including
project.projectDir and the error) and propagate a failure or an explicit
"unknown" result so the upstream scanner (the code that decides SuspendIdle) can
skip this project instead of lowering its state; reference snapshotHasAgentTask
and readContainerTaskSnapshot and ensure the warning is emitted before returning
the non-boolean/failed Effect so callers can detect and skip this project.

In `@packages/api/src/services/project-lifecycle-resources.ts`:
- Around line 50-65: containerExists currently converts any docker inspect
failure into false, and stopProjectBrowserRuntime swallows docker stop errors;
that masks real failures and allows suspendProjectRuntime to mark
lastKnownStatus "stopped" when the container may still be running. Update
containerExists (the function calling runCommandCapture) to only treat the "not
found" case as false by inspecting the CommandFailedError/exitCode/message and
rethrow other errors, and update stopProjectBrowserRuntime to only ignore "no
such container" / not-found errors while propagating other failures; keep the
use of runCommandCapture/CommandFailedError and adjust the Effect.orElse/
orElseSucceed logic so non-not-found errors are not converted into success
values.
- Around line 28-31: throttledCpu currently can increase CPU for small normalCpu
because normalizeCpu enforces a minimum (minimumThrottledCpu); change
throttledCpu so it first computes the clamped candidate = normalizeCpu(normalCpu
* Math.max(0, Math.min(1, factor))) and then returns the minimum of that
candidate and the original normalCpu to avoid raising CPU. Update the
throttledCpu function (and leave normalizeCpu unchanged) so the returned value
is never greater than normalCpu.

In `@packages/api/src/services/projects.ts`:
- Around line 693-699: Remove the illegal type assertion by deleting `as const`
from `buildMode: "reuse" as const` in the function `upProjectComposeOptions` and
add an explicit return type for the function instead; for example declare
`upProjectComposeOptions` to return ` { buildMode: "reuse"; waitForPostStart:
false } | undefined ` (or the appropriate project `ComposeOptions` type) so
`buildMode` is typed as the literal "reuse" without using `as`.

In `@packages/lib/src/core/templates/docker-compose.ts`:
- Line 84: Функция renderOptionalDockerSocketMount возвращает строку, которая
монтирует host /var/run/docker.sock в проектный контейнер — это недопустимо;
вместо этого удалите или закомментируйте этот mount в
renderOptionalDockerSocketMount (и аналогичные места генерации mount'ов), чтобы
больше не включать bind-монт /var/run/docker.sock в docker-compose, и
адаптируйте код генерации/условную логику (в тех же функциях) чтобы использовать
контроллер/API-hop механизм (перенаправление управления контейнерами через
docker-git-api) или вернуть явный placeholder/feature-flag, не монтирующий
сокет, чтобы сохранить безопасность хоста.

In `@packages/lib/src/core/templates/playwright.ts`:
- Around line 299-307: The function docker_git_stop_playwright_browser is
currently using docker rm -f which force-removes the container; change it to
perform a graceful stop (docker stop "$container_name" >/dev/null 2>&1 || true)
so shutdown-trap and normal restarts preserve stopped container state, and leave
removal (docker rm -f) only in explicit recreate/delete code paths (the other
occurrence referenced around the second spot should be updated similarly or left
only in the recreate/delete handler). Ensure you update the
docker_git_stop_playwright_browser implementation (and the mirrored occurrence)
to use docker stop for normal shutdown and keep removal logic only in explicit
delete/recreate functions.

In `@packages/lib/src/usecases/project-runtime-state.ts`:
- Around line 292-338: recordProjectRuntimeActivity and
recordProjectRuntimeResourceProfile perform a naive read-modify-write on the
same runtime.json and race when called concurrently; wrap the whole
read/modify/write sequence in a per-project serialization/lock (or use an atomic
merge with compare-and-swap) so updates don’t clobber each other. Specifically,
introduce a per-project mutex or lock keyed by projectDir used by both
recordProjectRuntimeActivity and recordProjectRuntimeResourceProfile (and any
callers of readProjectRuntimeState/writeProjectRuntimeStateFile), acquire the
lock before calling readProjectRuntimeState and release after
writeProjectRuntimeStateFile finishes; alternatively implement a write that
reads the current file, merges only the intended fields (lastAgentSeenAt*,
lastInteractiveSeenAt*, resourceProfile, lastStopReason, updatedAtIso) with the
new values and uses an atomic replace/compare to ensure you don’t overwrite
concurrent updates (use currentRuntimeClock, toRuntimeStateFile, toRuntimeState,
and the existing read/write helpers to locate code paths).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 682dd264-3c54-4d40-8592-940f8c8fbe2c

📥 Commits

Reviewing files that changed from the base of the PR and between 6ab8042 and df4d2a5.

📒 Files selected for processing (43)
  • packages/api/src/api/contracts.ts
  • packages/api/src/api/schema.ts
  • packages/api/src/http.ts
  • packages/api/src/program.ts
  • packages/api/src/services/agents.ts
  • packages/api/src/services/project-auto-suspend.ts
  • packages/api/src/services/project-browser.ts
  • packages/api/src/services/project-idle-policy.ts
  • packages/api/src/services/project-lifecycle-resources.ts
  • packages/api/src/services/projects.ts
  • packages/api/src/services/skiller.ts
  • packages/api/src/services/terminal-sessions.ts
  • packages/api/tests/project-idle-policy.test.ts
  • packages/api/tests/schema.test.ts
  • packages/app/src/docker-git/api-client-create.ts
  • packages/app/src/docker-git/api-client.ts
  • packages/app/src/docker-git/cli/usage.ts
  • packages/app/src/docker-git/menu-create-shared.ts
  • packages/app/src/docker-git/program-unsupported.ts
  • packages/app/src/web/actions-browser.ts
  • packages/app/src/web/api-project-core.ts
  • packages/app/src/web/api.ts
  • packages/app/src/web/app-ready-browser-openable.ts
  • packages/app/src/web/app-terminal-session-handlers.ts
  • packages/app/src/web/panel-browser.tsx
  • packages/app/tests/docker-git/actions-browser.test.ts
  • packages/app/tests/docker-git/api-client-create.test.ts
  • packages/lib/src/core/templates-entrypoint.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/lib/src/core/templates-entrypoint/playwright-browser.ts
  • packages/lib/src/core/templates.ts
  • packages/lib/src/core/templates/docker-compose.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/src/core/templates/playwright.ts
  • packages/lib/src/shell/docker-compose.ts
  • packages/lib/src/usecases/mcp-playwright.ts
  • packages/lib/src/usecases/project-runtime-state.ts
  • packages/lib/src/usecases/projects.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/tests/shell/docker.test.ts
  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/tests/usecases/prepare-files.test.ts
  • packages/lib/tests/usecases/project-runtime-state.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (OpenCode)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/app/src/web/app-ready-browser-openable.ts
  • packages/app/src/docker-git/program-unsupported.ts
  • packages/app/src/web/panel-browser.tsx
  • packages/lib/src/usecases/mcp-playwright.ts
  • packages/lib/src/shell/docker-compose.ts
  • packages/app/src/docker-git/api-client-create.ts
  • packages/api/tests/schema.test.ts
  • packages/lib/src/core/templates-entrypoint/playwright-browser.ts
  • packages/app/src/web/app-terminal-session-handlers.ts
  • packages/lib/src/core/templates.ts
  • packages/app/src/docker-git/menu-create-shared.ts
  • packages/app/tests/docker-git/actions-browser.test.ts
  • packages/lib/tests/shell/docker.test.ts
  • packages/api/tests/project-idle-policy.test.ts
  • packages/app/src/web/actions-browser.ts
  • packages/app/src/docker-git/api-client.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/tests/docker-git/api-client-create.test.ts
  • packages/app/src/web/api.ts
  • packages/api/src/services/project-idle-policy.ts
  • packages/app/src/docker-git/cli/usage.ts
  • packages/api/src/program.ts
  • packages/lib/src/core/templates-entrypoint.ts
  • packages/lib/src/core/templates/playwright.ts
  • packages/app/src/web/api-project-core.ts
  • packages/api/src/services/skiller.ts
  • packages/api/src/services/agents.ts
  • packages/api/src/api/schema.ts
  • packages/api/src/api/contracts.ts
  • packages/lib/tests/usecases/project-runtime-state.test.ts
  • packages/lib/src/usecases/projects.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/api/src/http.ts
  • packages/api/src/services/project-auto-suspend.ts
  • packages/api/src/services/projects.ts
  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/tests/usecases/prepare-files.test.ts
  • packages/api/src/services/project-lifecycle-resources.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/api/src/services/project-browser.ts
  • packages/api/src/services/terminal-sessions.ts
  • packages/lib/src/core/templates/docker-compose.ts
  • packages/lib/src/usecases/project-runtime-state.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/app/src/web/app-ready-browser-openable.ts
  • packages/app/src/docker-git/program-unsupported.ts
  • packages/app/src/web/panel-browser.tsx
  • packages/lib/src/usecases/mcp-playwright.ts
  • packages/lib/src/shell/docker-compose.ts
  • packages/app/src/docker-git/api-client-create.ts
  • packages/api/tests/schema.test.ts
  • packages/lib/src/core/templates-entrypoint/playwright-browser.ts
  • packages/app/src/web/app-terminal-session-handlers.ts
  • packages/lib/src/core/templates.ts
  • packages/app/src/docker-git/menu-create-shared.ts
  • packages/app/tests/docker-git/actions-browser.test.ts
  • packages/lib/tests/shell/docker.test.ts
  • packages/api/tests/project-idle-policy.test.ts
  • packages/app/src/web/actions-browser.ts
  • packages/app/src/docker-git/api-client.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/tests/docker-git/api-client-create.test.ts
  • packages/app/src/web/api.ts
  • packages/api/src/services/project-idle-policy.ts
  • packages/app/src/docker-git/cli/usage.ts
  • packages/api/src/program.ts
  • packages/lib/src/core/templates-entrypoint.ts
  • packages/lib/src/core/templates/playwright.ts
  • packages/app/src/web/api-project-core.ts
  • packages/api/src/services/skiller.ts
  • packages/api/src/services/agents.ts
  • packages/api/src/api/schema.ts
  • packages/api/src/api/contracts.ts
  • packages/lib/tests/usecases/project-runtime-state.test.ts
  • packages/lib/src/usecases/projects.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/api/src/http.ts
  • packages/api/src/services/project-auto-suspend.ts
  • packages/api/src/services/projects.ts
  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/tests/usecases/prepare-files.test.ts
  • packages/api/src/services/project-lifecycle-resources.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/api/src/services/project-browser.ts
  • packages/api/src/services/terminal-sessions.ts
  • packages/lib/src/core/templates/docker-compose.ts
  • packages/lib/src/usecases/project-runtime-state.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/app/src/web/app-ready-browser-openable.ts
  • packages/app/src/docker-git/program-unsupported.ts
  • packages/app/src/web/panel-browser.tsx
  • packages/lib/src/usecases/mcp-playwright.ts
  • packages/lib/src/shell/docker-compose.ts
  • packages/app/src/docker-git/api-client-create.ts
  • packages/api/tests/schema.test.ts
  • packages/lib/src/core/templates-entrypoint/playwright-browser.ts
  • packages/app/src/web/app-terminal-session-handlers.ts
  • packages/lib/src/core/templates.ts
  • packages/app/src/docker-git/menu-create-shared.ts
  • packages/app/tests/docker-git/actions-browser.test.ts
  • packages/lib/tests/shell/docker.test.ts
  • packages/api/tests/project-idle-policy.test.ts
  • packages/app/src/web/actions-browser.ts
  • packages/app/src/docker-git/api-client.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/tests/docker-git/api-client-create.test.ts
  • packages/app/src/web/api.ts
  • packages/api/src/services/project-idle-policy.ts
  • packages/app/src/docker-git/cli/usage.ts
  • packages/api/src/program.ts
  • packages/lib/src/core/templates-entrypoint.ts
  • packages/lib/src/core/templates/playwright.ts
  • packages/app/src/web/api-project-core.ts
  • packages/api/src/services/skiller.ts
  • packages/api/src/services/agents.ts
  • packages/api/src/api/schema.ts
  • packages/api/src/api/contracts.ts
  • packages/lib/tests/usecases/project-runtime-state.test.ts
  • packages/lib/src/usecases/projects.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/api/src/http.ts
  • packages/api/src/services/project-auto-suspend.ts
  • packages/api/src/services/projects.ts
  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/tests/usecases/prepare-files.test.ts
  • packages/api/src/services/project-lifecycle-resources.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/api/src/services/project-browser.ts
  • packages/api/src/services/terminal-sessions.ts
  • packages/lib/src/core/templates/docker-compose.ts
  • packages/lib/src/usecases/project-runtime-state.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/app/src/web/app-ready-browser-openable.ts
  • packages/app/src/docker-git/program-unsupported.ts
  • packages/app/src/web/panel-browser.tsx
  • packages/lib/src/usecases/mcp-playwright.ts
  • packages/lib/src/shell/docker-compose.ts
  • packages/app/src/docker-git/api-client-create.ts
  • packages/api/tests/schema.test.ts
  • packages/lib/src/core/templates-entrypoint/playwright-browser.ts
  • packages/app/src/web/app-terminal-session-handlers.ts
  • packages/lib/src/core/templates.ts
  • packages/app/src/docker-git/menu-create-shared.ts
  • packages/app/tests/docker-git/actions-browser.test.ts
  • packages/lib/tests/shell/docker.test.ts
  • packages/api/tests/project-idle-policy.test.ts
  • packages/app/src/web/actions-browser.ts
  • packages/app/src/docker-git/api-client.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/tests/docker-git/api-client-create.test.ts
  • packages/app/src/web/api.ts
  • packages/api/src/services/project-idle-policy.ts
  • packages/app/src/docker-git/cli/usage.ts
  • packages/api/src/program.ts
  • packages/lib/src/core/templates-entrypoint.ts
  • packages/lib/src/core/templates/playwright.ts
  • packages/app/src/web/api-project-core.ts
  • packages/api/src/services/skiller.ts
  • packages/api/src/services/agents.ts
  • packages/api/src/api/schema.ts
  • packages/api/src/api/contracts.ts
  • packages/lib/tests/usecases/project-runtime-state.test.ts
  • packages/lib/src/usecases/projects.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/api/src/http.ts
  • packages/api/src/services/project-auto-suspend.ts
  • packages/api/src/services/projects.ts
  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/tests/usecases/prepare-files.test.ts
  • packages/api/src/services/project-lifecycle-resources.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/api/src/services/project-browser.ts
  • packages/api/src/services/terminal-sessions.ts
  • packages/lib/src/core/templates/docker-compose.ts
  • packages/lib/src/usecases/project-runtime-state.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/app/src/web/app-ready-browser-openable.ts
  • packages/app/src/docker-git/program-unsupported.ts
  • packages/app/src/web/panel-browser.tsx
  • packages/lib/src/usecases/mcp-playwright.ts
  • packages/lib/src/shell/docker-compose.ts
  • packages/app/src/docker-git/api-client-create.ts
  • packages/api/tests/schema.test.ts
  • packages/lib/src/core/templates-entrypoint/playwright-browser.ts
  • packages/app/src/web/app-terminal-session-handlers.ts
  • packages/lib/src/core/templates.ts
  • packages/app/src/docker-git/menu-create-shared.ts
  • packages/app/tests/docker-git/actions-browser.test.ts
  • packages/lib/tests/shell/docker.test.ts
  • packages/api/tests/project-idle-policy.test.ts
  • packages/app/src/web/actions-browser.ts
  • packages/app/src/docker-git/api-client.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/tests/docker-git/api-client-create.test.ts
  • packages/app/src/web/api.ts
  • packages/api/src/services/project-idle-policy.ts
  • packages/app/src/docker-git/cli/usage.ts
  • packages/api/src/program.ts
  • packages/lib/src/core/templates-entrypoint.ts
  • packages/lib/src/core/templates/playwright.ts
  • packages/app/src/web/api-project-core.ts
  • packages/api/src/services/skiller.ts
  • packages/api/src/services/agents.ts
  • packages/api/src/api/schema.ts
  • packages/api/src/api/contracts.ts
  • packages/lib/tests/usecases/project-runtime-state.test.ts
  • packages/lib/src/usecases/projects.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/api/src/http.ts
  • packages/api/src/services/project-auto-suspend.ts
  • packages/api/src/services/projects.ts
  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/tests/usecases/prepare-files.test.ts
  • packages/api/src/services/project-lifecycle-resources.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/api/src/services/project-browser.ts
  • packages/api/src/services/terminal-sessions.ts
  • packages/lib/src/core/templates/docker-compose.ts
  • packages/lib/src/usecases/project-runtime-state.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/app/src/web/app-ready-browser-openable.ts
  • packages/app/src/docker-git/program-unsupported.ts
  • packages/app/src/web/panel-browser.tsx
  • packages/lib/src/usecases/mcp-playwright.ts
  • packages/lib/src/shell/docker-compose.ts
  • packages/app/src/docker-git/api-client-create.ts
  • packages/api/tests/schema.test.ts
  • packages/lib/src/core/templates-entrypoint/playwright-browser.ts
  • packages/app/src/web/app-terminal-session-handlers.ts
  • packages/lib/src/core/templates.ts
  • packages/app/src/docker-git/menu-create-shared.ts
  • packages/app/tests/docker-git/actions-browser.test.ts
  • packages/lib/tests/shell/docker.test.ts
  • packages/api/tests/project-idle-policy.test.ts
  • packages/app/src/web/actions-browser.ts
  • packages/app/src/docker-git/api-client.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/tests/docker-git/api-client-create.test.ts
  • packages/app/src/web/api.ts
  • packages/api/src/services/project-idle-policy.ts
  • packages/app/src/docker-git/cli/usage.ts
  • packages/api/src/program.ts
  • packages/lib/src/core/templates-entrypoint.ts
  • packages/lib/src/core/templates/playwright.ts
  • packages/app/src/web/api-project-core.ts
  • packages/api/src/services/skiller.ts
  • packages/api/src/services/agents.ts
  • packages/api/src/api/schema.ts
  • packages/api/src/api/contracts.ts
  • packages/lib/tests/usecases/project-runtime-state.test.ts
  • packages/lib/src/usecases/projects.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/api/src/http.ts
  • packages/api/src/services/project-auto-suspend.ts
  • packages/api/src/services/projects.ts
  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/tests/usecases/prepare-files.test.ts
  • packages/api/src/services/project-lifecycle-resources.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/api/src/services/project-browser.ts
  • packages/api/src/services/terminal-sessions.ts
  • packages/lib/src/core/templates/docker-compose.ts
  • packages/lib/src/usecases/project-runtime-state.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/api/tests/schema.test.ts
  • packages/app/tests/docker-git/actions-browser.test.ts
  • packages/lib/tests/shell/docker.test.ts
  • packages/api/tests/project-idle-policy.test.ts
  • packages/app/tests/docker-git/api-client-create.test.ts
  • packages/lib/tests/usecases/project-runtime-state.test.ts
  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/tests/usecases/prepare-files.test.ts
  • packages/lib/tests/core/templates.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/api/tests/schema.test.ts
  • packages/app/tests/docker-git/actions-browser.test.ts
  • packages/lib/tests/shell/docker.test.ts
  • packages/api/tests/project-idle-policy.test.ts
  • packages/app/tests/docker-git/api-client-create.test.ts
  • packages/lib/tests/usecases/project-runtime-state.test.ts
  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/tests/usecases/prepare-files.test.ts
  • packages/lib/tests/core/templates.test.ts
🔇 Additional comments (26)
packages/app/src/docker-git/cli/usage.ts (1)

29-29: LGTM!

Also applies to: 60-61, 78-78, 104-104

packages/lib/src/usecases/mcp-playwright.ts (1)

31-31: LGTM!

packages/app/src/docker-git/menu-create-shared.ts (1)

85-85: LGTM!

packages/app/src/docker-git/program-unsupported.ts (1)

25-25: LGTM!

packages/app/src/web/actions-browser.ts (1)

8-8: LGTM!

Also applies to: 56-56

packages/app/src/web/app-ready-browser-openable.ts (1)

5-5: LGTM!

packages/app/src/web/app-terminal-session-handlers.ts (1)

49-49: LGTM!

packages/app/src/web/panel-browser.tsx (1)

119-119: LGTM!

packages/app/tests/docker-git/actions-browser.test.ts (1)

68-68: LGTM!

Also applies to: 87-87

packages/api/tests/schema.test.ts (1)

6-6: LGTM!

Also applies to: 41-42, 54-55, 62-85

packages/app/tests/docker-git/api-client-create.test.ts (1)

1-38: LGTM!

packages/lib/tests/core/templates.test.ts (1)

549-549: LGTM!

Also applies to: 571-573, 585-585, 597-609, 612-612, 624-630, 632-632, 644-649

packages/lib/tests/usecases/mcp-playwright.test.ts (1)

121-121: LGTM!

Also applies to: 123-125, 131-131, 139-143, 147-147, 150-150, 153-153, 161-164

packages/lib/tests/usecases/prepare-files.test.ts (1)

251-251: LGTM!

Also applies to: 288-295, 302-302

packages/lib/tests/shell/docker.test.ts (1)

3-8: LGTM!

Also applies to: 83-102

packages/lib/tests/usecases/project-runtime-state.test.ts (1)

10-11: LGTM!

Also applies to: 45-50, 63-68, 92-95, 97-107, 112-117

packages/api/src/services/agents.ts (1)

199-212: LGTM!

Also applies to: 448-448

packages/api/src/services/terminal-sessions.ts (1)

115-116: LGTM!

Also applies to: 182-183, 186-187, 471-490, 1118-1133, 1541-1552, 1567-1567, 1664-1671

packages/api/src/services/skiller.ts (1)

6-6: LGTM!

Also applies to: 468-483, 494-494, 534-537

packages/api/src/services/project-browser.ts (1)

1-1: LGTM!

Also applies to: 54-57, 80-86, 96-99, 128-161, 249-270, 291-335, 461-461, 555-555, 607-607, 615-615, 743-746, 768-769

packages/api/src/http.ts (1)

96-97: LGTM!

Also applies to: 1390-1450

packages/api/src/program.ts (1)

2-2: LGTM!

Also applies to: 10-10, 65-65, 77-84

packages/app/src/docker-git/api-client-create.ts (1)

38-39: LGTM!

packages/app/src/docker-git/api-client.ts (1)

85-94: LGTM!

Also applies to: 207-230

packages/app/src/web/api-project-core.ts (1)

7-18: LGTM!

Also applies to: 35-38, 48-48, 68-84

packages/app/src/web/api.ts (1)

54-55: LGTM!

Also applies to: 58-58

Comment on lines +66 to +74
const snapshotHasAgentTask = (
project: ProjectItem
) =>
readContainerTaskSnapshot(project.projectDir, false).pipe(
Effect.map((snapshot) =>
activeAgents(snapshot.agents).length > 0 || snapshot.tasks.some((task) => task.kind === "agent")
),
Effect.catchAll(() => Effect.succeed(false))
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Не считайте ошибку инспекции признаком idle-состояния.

Если readContainerTaskSnapshot() падает, snapshotHasAgentTask() возвращает false, и дальше scan может выбрать SuspendIdle для проекта с реально работающим агентом. Здесь безопаснее пропускать решение для этого проекта и логировать warning, а не понижать состояние до “агента нет”.

💡 Возможная правка
 const snapshotHasAgentTask = (
   project: ProjectItem
 ) =>
   readContainerTaskSnapshot(project.projectDir, false).pipe(
     Effect.map((snapshot) =>
       activeAgents(snapshot.agents).length > 0 || snapshot.tasks.some((task) => task.kind === "agent")
-    ),
-    Effect.catchAll(() => Effect.succeed(false))
+    )
   )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/services/project-auto-suspend.ts` around lines 66 - 74,
snapshotHasAgentTask currently swallows any error from readContainerTaskSnapshot
and returns false, which can cause a live agent to be treated as absent; change
snapshotHasAgentTask to not treat inspection errors as "no agent": when
readContainerTaskSnapshot fails, log a warning (including project.projectDir and
the error) and propagate a failure or an explicit "unknown" result so the
upstream scanner (the code that decides SuspendIdle) can skip this project
instead of lowering its state; reference snapshotHasAgentTask and
readContainerTaskSnapshot and ensure the warning is emitted before returning the
non-boolean/failed Effect so callers can detect and skip this project.

Comment on lines +28 to +31
const normalizeCpu = (value: number): number => Math.max(minimumThrottledCpu, Math.round(value * 100) / 100)

const throttledCpu = (normalCpu: number, factor: number): number =>
normalizeCpu(normalCpu * Math.max(0, Math.min(1, factor)))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Не повышайте CPU при throttling.

Сейчас throttledCpu() может вернуть 0.25, даже когда обычный лимит проекта ниже этого значения. Для проектов с cpuLimit < 0.25 профиль "interactive-idle-throttled" неожиданно увеличит доступный CPU вместо уменьшения. Ограничьте результат сверху исходным normalCpu.

💡 Возможная правка
 const throttledCpu = (normalCpu: number, factor: number): number =>
-  normalizeCpu(normalCpu * Math.max(0, Math.min(1, factor)))
+  Math.min(
+    normalCpu,
+    normalizeCpu(normalCpu * Math.max(0, Math.min(1, factor)))
+  )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/services/project-lifecycle-resources.ts` around lines 28 -
31, throttledCpu currently can increase CPU for small normalCpu because
normalizeCpu enforces a minimum (minimumThrottledCpu); change throttledCpu so it
first computes the clamped candidate = normalizeCpu(normalCpu * Math.max(0,
Math.min(1, factor))) and then returns the minimum of that candidate and the
original normalCpu to avoid raising CPU. Update the throttledCpu function (and
leave normalizeCpu unchanged) so the returned value is never greater than
normalCpu.

Comment on lines +50 to +65
const containerExists = (
project: ProjectItem,
containerName: string
) =>
runCommandCapture(
{
cwd: project.projectDir,
command: "docker",
args: ["inspect", "-f", "{{.Id}}", containerName]
},
[0, 1],
(exitCode) => new CommandFailedError({ command: "docker inspect", exitCode })
).pipe(
Effect.map((output) => output.trim().length > 0),
Effect.orElseSucceed(() => false)
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Не помечайте проект stopped, если browser runtime фактически не остановлен.

Здесь два слоя маскируют сбой: containerExists() превращает любой docker inspect error в false, а stopProjectBrowserRuntime() глотает ошибки docker stop. В итоге suspendProjectRuntime() может записать lastKnownStatus: "stopped", хотя browser container остался жив или даже не был корректно проверен. Для suspend безопасно игнорировать только реальный not found; остальные ошибки должны прерывать операцию.

Also applies to: 104-133

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/services/project-lifecycle-resources.ts` around lines 50 -
65, containerExists currently converts any docker inspect failure into false,
and stopProjectBrowserRuntime swallows docker stop errors; that masks real
failures and allows suspendProjectRuntime to mark lastKnownStatus "stopped" when
the container may still be running. Update containerExists (the function calling
runCommandCapture) to only treat the "not found" case as false by inspecting the
CommandFailedError/exitCode/message and rethrow other errors, and update
stopProjectBrowserRuntime to only ignore "no such container" / not-found errors
while propagating other failures; keep the use of
runCommandCapture/CommandFailedError and adjust the Effect.orElse/ orElseSucceed
logic so non-not-found errors are not converted into success values.

Comment on lines +693 to +699
const upProjectComposeOptions = (startupMode: NonNullable<UpProjectOptions["startupMode"]>) =>
startupMode === "default"
? undefined
: {
buildMode: "reuse" as const,
waitForPostStart: false
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Проверка наличия type assertion "as const" в изменённом файле
rg -nP '\bas\s+const\b' packages/api/src/services/projects.ts

Repository: ProverCoderAI/docker-git

Length of output: 107


Удалите type assertion as const в upProjectComposeOptions.

На строке 697 используется buildMode: "reuse" as const, что нарушает правило проекта о запрете as в обычном коде. Вместо этого добавьте явную аннотацию возвращаемого типа функции:

💡 Предлагаемое исправление
-const upProjectComposeOptions = (startupMode: NonNullable<UpProjectOptions["startupMode"]>) =>
+const upProjectComposeOptions = (
+  startupMode: NonNullable<UpProjectOptions["startupMode"]>
+): { readonly buildMode: "reuse"; readonly waitForPostStart: false } | undefined =>
   startupMode === "default"
     ? undefined
     : {
-      buildMode: "reuse" as const,
+      buildMode: "reuse",
       waitForPostStart: false
     }

Per coding guidelines: **/*.{ts,tsx}: Type casting with as is strictly forbidden in regular code; permitted ONLY in a single axiomatic module (brands/constructors/constants).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/services/projects.ts` around lines 693 - 699, Remove the
illegal type assertion by deleting `as const` from `buildMode: "reuse" as const`
in the function `upProjectComposeOptions` and add an explicit return type for
the function instead; for example declare `upProjectComposeOptions` to return `
{ buildMode: "reuse"; waitForPostStart: false } | undefined ` (or the
appropriate project `ComposeOptions` type) so `buildMode` is typed as the
literal "reuse" without using `as`.

Comment on lines +299 to +307
docker_git_stop_playwright_browser() {
local container_name="\${DOCKER_GIT_BROWSER_CONTAINER_NAME:-}"
if [[ -z "$container_name" ]]; then
return 0
fi
if ! docker_git_browser_has_docker; then
return 0
fi
docker rm -f "$container_name" >/dev/null 2>&1 || true
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Не используйте docker rm -f как обычный stop-путь.

docker_git_stop_playwright_browser() вызывается и из shutdown-trap, и перед повторным запуском, но сейчас он всегда жёстко удаляет контейнер. Это расходится с ТЗ issue #306: для штатной остановки нужен docker stop, а удаление — только в явном recreate/delete-пути. Иначе suspend/shutdown теряет graceful cleanup и состояние остановленного browser runtime.

💡 Локальная правка
 docker_git_stop_playwright_browser() {
   local container_name="${DOCKER_GIT_BROWSER_CONTAINER_NAME:-}"
   if [[ -z "$container_name" ]]; then
     return 0
   fi
   if ! docker_git_browser_has_docker; then
     return 0
   fi
-  docker rm -f "$container_name" >/dev/null 2>&1 || true
+  docker stop "$container_name" >/dev/null 2>&1 || true
 }
 ...
   docker_git_stop_playwright_browser || true
+  docker rm "$container_name" >/dev/null 2>&1 || true
   docker volume create "$volume_name" >/dev/null

Also applies to: 342-343

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/lib/src/core/templates/playwright.ts` around lines 299 - 307, The
function docker_git_stop_playwright_browser is currently using docker rm -f
which force-removes the container; change it to perform a graceful stop (docker
stop "$container_name" >/dev/null 2>&1 || true) so shutdown-trap and normal
restarts preserve stopped container state, and leave removal (docker rm -f) only
in explicit recreate/delete code paths (the other occurrence referenced around
the second spot should be updated similarly or left only in the recreate/delete
handler). Ensure you update the docker_git_stop_playwright_browser
implementation (and the mirrored occurrence) to use docker stop for normal
shutdown and keep removal logic only in explicit delete/recreate functions.

Comment on lines +292 to +338
export const recordProjectRuntimeActivity = (
projectDir: string,
activity: ProjectRuntimeActivityKind
): Effect.Effect<ProjectRuntimeState, PlatformError, FileSystem.FileSystem | Path.Path> =>
Effect.gen(function*(_) {
const previous = yield* _(readProjectRuntimeState(projectDir))
const clock = yield* _(currentRuntimeClock())
const next: ProjectRuntimeState = activity === "agent"
? {
...previous,
lastAgentSeenAtIso: clock.iso,
lastAgentSeenAtEpochMs: clock.epochMs,
lastKnownStatus: "running",
lastStopReason: null,
updatedAtIso: clock.iso
}
: {
...previous,
lastInteractiveSeenAtIso: clock.iso,
lastInteractiveSeenAtEpochMs: clock.epochMs,
lastKnownStatus: "running",
lastStopReason: null,
updatedAtIso: clock.iso
}
const written = yield* _(writeProjectRuntimeStateFile(projectDir, toRuntimeStateFile(next, clock)))
return toRuntimeState(written)
})

export const recordProjectRuntimeResourceProfile = (
projectDir: string,
resourceProfile: ProjectRuntimeResourceProfile
): Effect.Effect<ProjectRuntimeState, PlatformError, FileSystem.FileSystem | Path.Path> =>
Effect.gen(function*(_) {
const previous = yield* _(readProjectRuntimeState(projectDir))
const clock = yield* _(currentRuntimeClock())
const written = yield* _(
writeProjectRuntimeStateFile(
projectDir,
toRuntimeStateFile({
...previous,
resourceProfile,
updatedAtIso: clock.iso
}, clock)
)
)
return toRuntimeState(written)
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Сериализация runtime.json теряет обновления при параллельных записях.

recordProjectRuntimeActivity() и recordProjectRuntimeResourceProfile() делают обычный read-modify-write поверх одного файла. В этом PR те же поля теперь обновляют несколько сервисов независимо, поэтому два одновременных вызова легко затирают друг другу lastAgentSeenAt*, lastInteractiveSeenAt*, resourceProfile или lastStopReason. Следствие — ложные idle-решения и авто-suspend для реально активного проекта. Здесь нужна сериализация обновлений per-project или атомарный merge под lock.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/lib/src/usecases/project-runtime-state.ts` around lines 292 - 338,
recordProjectRuntimeActivity and recordProjectRuntimeResourceProfile perform a
naive read-modify-write on the same runtime.json and race when called
concurrently; wrap the whole read/modify/write sequence in a per-project
serialization/lock (or use an atomic merge with compare-and-swap) so updates
don’t clobber each other. Specifically, introduce a per-project mutex or lock
keyed by projectDir used by both recordProjectRuntimeActivity and
recordProjectRuntimeResourceProfile (and any callers of
readProjectRuntimeState/writeProjectRuntimeStateFile), acquire the lock before
calling readProjectRuntimeState and release after writeProjectRuntimeStateFile
finishes; alternatively implement a write that reads the current file, merges
only the intended fields (lastAgentSeenAt*, lastInteractiveSeenAt*,
resourceProfile, lastStopReason, updatedAtIso) with the new values and uses an
atomic replace/compare to ensure you don’t overwrite concurrent updates (use
currentRuntimeClock, toRuntimeStateFile, toRuntimeState, and the existing
read/write helpers to locate code paths).

@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 18, 2026

AI Session Backup

Commit: 09c8174
Status: success
Files: 7 (5.56 MB)
Links: README | Manifest

git status

On branch issue-306
Your branch is up to date with 'origin/issue-306'.

nothing to commit, working tree clean

@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 18, 2026

AI Session Backup

Commit: a06e2c5
Status: success
Files: 7 (5.95 MB)
Links: README | Manifest

git status

On branch issue-306
Your branch is up to date with 'origin/issue-306'.

nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/lib/src/core/templates/docker-compose.ts`:
- Line 84: The template currently unconditionally injects a host Docker socket
bind via renderOptionalDockerSocketMount(), breaking the controller-side Docker
transport contract; change renderOptionalDockerSocketMount to return the mount
only when an explicit flag/parameter (e.g., enableLocalDockerSocket or
runtimeRequestsLocalSocket) is true, and thread that boolean into the code paths
that assemble the Playwright project service (the callsites that currently
include the mount around the Playwright service block). Also make the
conditional decision based on the controller/docker access mode (e.g.,
DOCKER_GIT_PROJECT_DOCKER_HOST or a provided isControllerManagedDocker flag) so
when controller-managed Docker is in use the function returns an empty string
and no bind is added to the final service.

In `@packages/lib/src/core/templates/playwright-browser-runtime.ts`:
- Around line 62-87: Add a startup cleanup that finds detached browser
containers labeled "docker-git.browser=1" and whose
"docker-git.project-container" target no longer exists or is not running, and
forcibly remove them before launching the new container; specifically, use the
existing container_name/main_container/labels (docker-git.browser and
docker-git.project-container) and docker_git_browser_log to log actions, iterate
over docker ps --filter label=docker-git.browser=1 --filter
label=docker-git.project-container to read each browser's
docker-git.project-container label, check whether that project container is
present/running (docker ps -q --filter name=... or inspect), and if
missing/stopped run docker rm -f on the orphaned browser (logging via
docker_git_browser_log) prior to the docker "${args[@]}" "$image_name" start
sequence so orphans don’t hold RAM.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: deb8a7f7-d1ec-4c1b-870b-1e901b26d45f

📥 Commits

Reviewing files that changed from the base of the PR and between 09c8174 and a06e2c5.

📒 Files selected for processing (5)
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/lib/src/core/templates.ts
  • packages/lib/src/core/templates/docker-compose.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
  • packages/lib/src/usecases/projects.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Login context)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/lib/src/core/templates.ts
  • packages/lib/src/usecases/projects.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
  • packages/lib/src/core/templates/docker-compose.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/lib/src/core/templates.ts
  • packages/lib/src/usecases/projects.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
  • packages/lib/src/core/templates/docker-compose.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/lib/src/core/templates.ts
  • packages/lib/src/usecases/projects.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
  • packages/lib/src/core/templates/docker-compose.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/lib/src/core/templates.ts
  • packages/lib/src/usecases/projects.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
  • packages/lib/src/core/templates/docker-compose.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/lib/src/core/templates.ts
  • packages/lib/src/usecases/projects.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
  • packages/lib/src/core/templates/docker-compose.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/lib/src/core/templates.ts
  • packages/lib/src/usecases/projects.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
  • packages/lib/src/core/templates/docker-compose.ts
🔇 Additional comments (2)
packages/lib/src/usecases/projects.ts (1)

3-12: LGTM!

packages/lib/src/core/templates.ts (1)

51-66: LGTM!

Comment thread packages/lib/src/core/templates/docker-compose.ts Outdated
Comment thread packages/lib/src/core/templates/playwright-browser-runtime.ts
@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 18, 2026

AI Session Backup

Commit: 9e50263
Status: success
Files: 7 (7.04 MB)
Links: README | Manifest

git status

On branch issue-306
Your branch is up to date with 'origin/issue-306'.

nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/lib/src/core/templates/playwright-browser-runtime.ts`:
- Line 93: The docker volume creation at the `docker volume create
"$volume_name" >/dev/null` call should not cause the script to exit under `set
-e`; change it to handle failures gracefully (e.g., run the command in a guarded
form like `docker volume create "$volume_name" >/dev/null || { echo "Warning:
failed to create volume $volume_name, continuing"; }` or test return code and
log a warning) so the startup continues on failure; update the invocation near
the `volume_name` usage in the Playwright browser runtime script to swallow the
error and emit a non-fatal warning instead of letting `set -e` abort the
process.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c6efdc28-f772-4089-a080-ad71fa1fe987

📥 Commits

Reviewing files that changed from the base of the PR and between a06e2c5 and 9e50263.

📒 Files selected for processing (7)
  • packages/lib/src/core/templates.ts
  • packages/lib/src/core/templates/docker-compose.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
  • packages/lib/src/shell/files.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/tests/usecases/prepare-files.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Login context)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/lib/src/shell/files.ts
  • packages/lib/tests/usecases/prepare-files.test.ts
  • packages/lib/src/core/templates.ts
  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/src/core/templates/docker-compose.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/lib/src/shell/files.ts
  • packages/lib/tests/usecases/prepare-files.test.ts
  • packages/lib/src/core/templates.ts
  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/src/core/templates/docker-compose.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/lib/src/shell/files.ts
  • packages/lib/tests/usecases/prepare-files.test.ts
  • packages/lib/src/core/templates.ts
  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/src/core/templates/docker-compose.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/lib/src/shell/files.ts
  • packages/lib/tests/usecases/prepare-files.test.ts
  • packages/lib/src/core/templates.ts
  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/src/core/templates/docker-compose.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/lib/src/shell/files.ts
  • packages/lib/tests/usecases/prepare-files.test.ts
  • packages/lib/src/core/templates.ts
  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/src/core/templates/docker-compose.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/lib/src/shell/files.ts
  • packages/lib/tests/usecases/prepare-files.test.ts
  • packages/lib/src/core/templates.ts
  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/src/core/templates/docker-compose.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/lib/tests/usecases/prepare-files.test.ts
  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/tests/core/templates.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/lib/tests/usecases/prepare-files.test.ts
  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/tests/core/templates.test.ts

Comment thread packages/lib/src/core/templates/playwright-browser-runtime.ts Outdated
@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 18, 2026

AI Session Backup

Commit: 9436a37
Status: success
Files: 7 (7.49 MB)
Links: README | Manifest

git status

On branch issue-306
Your branch is up to date with 'origin/issue-306'.

nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/lib/src/core/templates/playwright-browser-runtime.ts`:
- Around line 88-91: The fixed log path /var/log/docker-git-browser-build.log
used in the docker build invocation inside the script should be replaced with a
securely created unique temporary file (use mktemp) to avoid race conditions and
symlink attacks; update the docker build redirection in the block that currently
runs docker build -t "$image_name" -f "$context_dir/Dockerfile.browser"
"$context_dir" >/var/log/docker-git-browser-build.log 2>&1 || { ... } to write
to a mktemp-created logfile variable, ensure docker_git_browser_log prints that
file path on failure, and add proper cleanup (trap or remove) of the temp file
after the build completes or on exit.
- Around line 1-136: The docker build in docker_git_start_playwright_browser
runs without a timeout and can hang; wrap the build call with a timeout (e.g.,
use the timeout utility: timeout <secs> docker build -t "$image_name" -f
"$context_dir/Dockerfile.browser" "$context_dir"
>/var/log/docker-git-browser-build.log 2>&1) and treat a timeout as a failure by
keeping the existing error block; also update the error log message in that
failure branch to mention timeout possibility so callers see why the build was
aborted. Ensure the change targets the docker build invocation inside
docker_git_start_playwright_browser and preserves the existing log file handling
and early return behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 934e2bb3-5e2e-4cba-a5be-51c0af0a7d9e

📥 Commits

Reviewing files that changed from the base of the PR and between 9e50263 and 9436a37.

📒 Files selected for processing (2)
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
  • packages/lib/tests/usecases/mcp-playwright.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (Browser command)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Clone auto-open SSH)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/lib/tests/usecases/mcp-playwright.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/lib/tests/usecases/mcp-playwright.test.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
🔇 Additional comments (2)
packages/lib/tests/usecases/mcp-playwright.test.ts (1)

94-175: LGTM!

packages/lib/src/core/templates/playwright-browser-runtime.ts (1)

126-136: LGTM!

Comment thread packages/lib/src/core/templates/playwright-browser-runtime.ts
Comment thread packages/lib/src/core/templates/playwright-browser-runtime.ts Outdated
@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 18, 2026

AI Session Backup

Commit: 5e125ba
Status: success
Files: 7 (7.93 MB)
Links: README | Manifest

git status

On branch issue-306
Your branch is up to date with 'origin/issue-306'.

nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/lib/src/core/templates/playwright-browser-runtime.ts`:
- Around line 111-115: The build log referenced in the docker build error path
is removed by the cleanup trap, so update the error branch around the docker
build invocation (the block that calls docker_git_browser_log and returns) to
preserve or emit the log before cleanup: on failure, cat the "$build_log" to
stderr (or copy it to a persistent location) and then call
docker_git_browser_log with the same context so the user can inspect details;
alternatively remove "$build_log" from the cleanup trap so it isn’t deleted on
exit. Target the error-handling block around the timeout docker build call and
the variables/functions "$build_log" and docker_git_browser_log and the
trap/cleanup logic to implement this change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: bdf87eea-9d99-4690-9093-0d9b01030098

📥 Commits

Reviewing files that changed from the base of the PR and between 9436a37 and 5e125ba.

📒 Files selected for processing (2)
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
  • packages/lib/tests/usecases/mcp-playwright.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: Test
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (Browser command)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: Lint
  • GitHub Check: Final build (windows-latest)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/lib/tests/usecases/mcp-playwright.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/lib/tests/usecases/mcp-playwright.test.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/lib/tests/usecases/mcp-playwright.test.ts
  • packages/lib/src/core/templates/playwright-browser-runtime.ts
🔇 Additional comments (7)
packages/lib/src/core/templates/playwright-browser-runtime.ts (4)

1-2: LGTM!

Also applies to: 6-19


40-69: LGTM!


121-146: LGTM!


150-160: LGTM!

packages/lib/tests/usecases/mcp-playwright.test.ts (3)

121-125: LGTM!


131-143: LGTM!


147-172: LGTM!

Comment thread packages/lib/src/core/templates/playwright-browser-runtime.ts
@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 18, 2026

AI Session Backup

Commit: 4234a74
Status: success
Files: 7 (8.22 MB)
Links: README | Manifest

git status

On branch issue-306
Your branch is up to date with 'origin/issue-306'.

nothing to commit, working tree clean

@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 18, 2026

AI Session Backup

Commit: fcb764a
Status: success
Files: 7 (8.89 MB)
Links: README | Manifest

git status

On branch issue-306
Your branch is up to date with 'origin/issue-306'.

nothing to commit, working tree clean

@skulidropek skulidropek merged commit 4b12e16 into main May 18, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Сделать что бы контейнеры не вислеи запущенными

1 participant