Skip to content

Stabilize project SSH terminal links#309

Merged
skulidropek merged 10 commits into
mainfrom
pr-300
May 18, 2026
Merged

Stabilize project SSH terminal links#309
skulidropek merged 10 commits into
mainfrom
pr-300

Conversation

@skulidropek
Copy link
Copy Markdown
Member

@skulidropek skulidropek commented May 17, 2026

Summary

  • Adds stable project-scoped SSH terminal links with short terminal selectors.
  • Persists active project terminal selection and restores terminal workspace state.
  • Keeps legacy /ssh/session/:id links compatible while moving app routing to dashboard attach flow.
  • Addresses CI and CodeRabbit feedback: no forbidden casts, schema/hook files below max-lines, tmux probe errors are not misreported, property-based selector tests added.

Source TZ / Issues

Requirements Alignment

  • Stable project link: /ssh/<projectKey> remains stable across reloads.
  • Terminal selector: selected terminal is represented as ?t=<short-id> and old ?terminal=<id> remains accepted.
  • Legacy compatibility: /ssh/session/<id> redirects into the project terminal workspace.
  • Durable state: backend persists sessions and active terminal id; frontend restores workspace from session storage.
  • UX: terminal tabs are labeled Terminal 1, Terminal 2; embedded tmux status bar is disabled.
  • Review fixes: tmux availability probe only maps real missing tmux to conflict, not SSH/transport failures.

Verification

  • bun run --cwd packages/app lint
  • bun run --cwd packages/app lint:effect
  • bun run --filter @prover-coder-ai/docker-git test
  • bun run --filter @effect-template/api test
  • bun run --cwd packages/lib lint
  • bun run --cwd packages/lib lint:effect
  • bun --cwd packages/lib vitest run tests/core/templates.test.ts
  • git diff --check
  • MCP Playwright live check for auth, project SSH route, terminal switching, reload, short URL selector, and tmux status bar

@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 17, 2026

AI Session Backup

Commit: 647733f
Status: success
Files: 8 (6.23 MB)
Links: README | Manifest

git status

On branch pr-300
Your branch is up to date with 'origin/pr-300'.

nothing to commit, working tree clean

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 17, 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: ffce9946-7108-4c1f-82bb-a7ac9a07ae3a

📥 Commits

Reviewing files that changed from the base of the PR and between 16a4b55 and a522d65.

📒 Files selected for processing (3)
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/src/web/app-ready-terminal-state-hook.ts
  • packages/lib/src/core/templates/dockerfile.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). (8)
  • GitHub Check: Final build (windows-latest)
  • GitHub Check: E2E (Browser command)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: Lint
🧰 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/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/web/app-ready-terminal-state-hook.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/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/web/app-ready-terminal-state-hook.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/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/web/app-ready-terminal-state-hook.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/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/web/app-ready-terminal-state-hook.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/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/web/app-ready-terminal-state-hook.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/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/web/app-ready-terminal-state-hook.ts
🔇 Additional comments (3)
packages/app/src/lib/core/templates/dockerfile.ts (1)

18-25: LGTM!

Also applies to: 68-68

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

18-25: LGTM!

Also applies to: 68-68

packages/app/src/web/app-ready-terminal-state-hook.ts (1)

2-2: LGTM!

Also applies to: 4-5, 26-29, 31-33, 35-39, 41-43, 45-50, 51-67, 68-70, 72-76, 78-90, 92-97, 99-122, 123-146, 148-172, 176-176, 194-197


📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Сохранение и восстановление терминальных сессий (сервер и браузер).
    • Установка активной терминальной сессии проекта через UI/API.
    • Новые клиентские операции: загрузка workspace и установка active session.
  • Improvements
    • Читаемые заголовки вкладок и строк списка терминалов.
    • Стабильные проектные SSH‑ссылки вида /ssh/?t=.
    • Автосинхронизация выбранной проектной сессии и отложенная загрузка workspace.
    • tmux включён в генерируемые Docker‑образы.
  • Tests
    • Расширено покрытие для persisted-state, выборов сессий и SSH‑ссылок.

Walkthrough

Добавлена durable-модель терминальных сессий с персистентностью в terminal-sessions.json; серверные HTTP/WS-эндпойнты и клиентские хелперы переведены на работу с durable-источником; введены стабильные project-scoped SSH-маршруты (projectSshRoutePath), фронтенд синхронизирует активную сессию с бэкендом; тесты и Dockerfile (tmux) обновлены.

Changes

Terminal Session Durability

Layer / File(s) Summary
API contract: UUID requestId
packages/api/src/api/schema.ts
StartProjectTerminalSessionRequestSchema.requestId теперь Schema.UUID.
HTTP Routing: Terminal Session Endpoints
packages/api/src/http.ts
GET/PUT маршруты переведены на read/list Effect-операции, добавлен PUT /projects/by-key/:projectKey/terminal-sessions/active и локальный ридер тела запроса.
Container tasks integration
packages/api/src/services/container-tasks.ts
readContainerTaskSnapshot явно вычисляет terminalSessions через Effect перед возвратом.
Durable Terminal Sessions (server core)
packages/api/src/services/terminal-sessions.ts
Добавлена durable-модель, сериализация terminal-sessions.json, upsert/patch/delete/setActive, очередь персистентности, гидратация in-memory записей и перевод API на Effect-рантайм с унифицированными ошибками.
PTY/tmux lifecycle & helpers
packages/api/src/services/terminal-sessions.ts
Переработан lifecycle PTY/clients (cleanup/detach/finalize), добавлен renderTmuxAttachCommand и подготовка аргументов для spawnPtyBridge; onExit защищён от устаревших событий.
WS attach & verify integration
packages/api/src/services/terminal-sessions.ts
attachTerminalWebSocketServer и verifyTerminalSession гидратируют записи через проектные резолверы; durable delete запускается при close.
Frontend API helpers & response schemas
packages/app/src/web/api.ts, packages/app/src/web/api-*.ts
Добавлены loadProjectTerminalWorkspace и setProjectActiveTerminalSession; схемы API обновлены и вынесены (auth/project/terminal), ProjectTerminalSessionsResponseSchema содержит activeSessionId.
SSH Routing & Terminal Titles
packages/app/src/web/terminal.ts, packages/app/src/web/app-terminal-session-handlers.ts
Добавлены terminalRouteToken, projectSshRoutePath, terminalTitle(s); sessionPath переключён на projectSshRoutePath; newProjectTerminalUrl используется для открытия терминалов.
SSH Link Parsing & Terminal Selection
packages/app/src/web/app-ready-ssh-link-hook.ts
readSshLinkRequestFromHref, извлечение terminalId, селекторы по exact/prefix/newest и отложенная логика attach/schedule реализованы.
Active Terminal Selection Persistence
packages/app/src/web/app-ready-terminal-state-hook.ts
projectActiveTerminalSelection, persistedSelectionRef и persistProjectActiveTerminalSelection отправляют setProjectActiveTerminalSession при изменениях (latest-wins).
Client storage: sessionStorage read/write
packages/app/src/web/app-ready-terminal-storage.ts
readStoredTerminalWorkspace / writeStoredTerminalWorkspace с валидацией и безопасной сериализацией.
UI: Terminal labels, panel & handlers
packages/app/src/web/app-ready-terminal-screen.tsx, packages/app/src/web/panel-project-details.tsx
Terminal tabs и ProjectTerminalSessionRow используют terminalTitleById для человекочитаемых заголовков; labels пробрасываются и ссылки строятся через projectSshRoutePath.
UUID fallback & actions
packages/app/src/web/actions-projects.ts, tests
formatUuidV4 добавлен; fallback для pending id использует UUID v4 генерацию; соответствующие тесты обновлены.
Interactive styles
packages/app/src/web/elements.tsx
interactiveStyle принимает backgroundColor; Box передаёт props.backgroundColor.
Route resolution & app routing
packages/app/src/web/app-terminal-session-core.ts, packages/app/src/web/app.tsx
WebAppRoute убран TerminalSession вариант; resolveWebAppRoute всегда возвращает Dashboard; приложение не рендерит AppTerminalSession по маршруту.
Dockerfile: include tmux
packages/app/src/lib/core/templates/dockerfile.ts, packages/lib/src/core/templates/dockerfile.ts
Добавлен пакет tmux в apt-get install и тест проверяет наличие "sudo tmux".
Backend tests: terminal-sessions.test.ts
packages/api/tests/terminal-sessions.test.ts
Тесты расширены для persisted-state: чтение terminal-sessions.json, гидратация, корреляция requestId, проверки delete/lookup после очистки runtime и tmux-guards.
Frontend tests: actions, ssh-link, url, handlers, terminal helpers
packages/app/tests/docker-git/*
Добавлены/обновлены тесты для генерации pending IDs, ssh-link-hook, app-ready-url, handler-helpers, terminal helper functions и hook persistence.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

✨ 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 pr-300

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: 10

🤖 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/terminal-sessions.ts`:
- Around line 1135-1161: The probeProjectTmuxAvailable helper currently swallows
all errors via Effect.orElseSucceed(() => false), causing network/SSH failures
to be reported as "tmux missing" in ensureProjectTmuxAvailable; change
probeProjectTmuxAvailable to only map the specific CommandFailedError that
indicates tmux is absent to Effect.succeed(false) and rethrow any other errors
(i.e., replace Effect.orElseSucceed with an Effect.catchAll that checks the
error returned by runCommandCapture (CommandFailedError or other) and returns
Effect.succeed(false) only when the error clearly means "tmux not found"
(inspect exitCode or message from CommandFailedError), otherwise return
Effect.fail(err) so ensureProjectTmuxAvailable will surface real SSH/network
errors; use the existing symbols probeProjectTmuxAvailable,
ensureProjectTmuxAvailable, runCommandCapture, CommandFailedError and
renderRemoteTmuxProbeCommand to locate and implement this change.

In `@packages/api/tests/terminal-sessions.test.ts`:
- Around line 125-127: Remove the forbidden type assertion in runTestEffect:
drop the `as Effect.Effect<A, unknown, never>` cast applied to
effect.pipe(Effect.provide(NodeContext.layer)) and return the result of
Effect.runPromise(effect.pipe(Effect.provide(NodeContext.layer))). If TypeScript
then reports unsatisfied requirements, satisfy them by composing additional
Effect.provide(...) layers (or augmenting NodeContext.layer) rather than
reintroducing a type cast; keep references to runTestEffect, Effect.provide and
NodeContext.layer when locating the change.

In `@packages/app/src/lib/core/templates/dockerfile.ts`:
- Line 33: Add the functional comment markers documenting the addition of "tmux"
to the package install list in the Dockerfile generation code: locate the
package string that includes "openssh-server git gh ca-certificates curl unzip
bsdutils sudo tmux" in packages/app/src/lib/core/templates/dockerfile.ts (the
same block that renderDockerfileRtk interacts with) and insert a concise
functional comment block above it using the standardized markers (e.g., CHANGE:
"Add tmux to base image packages", WHY: brief justification, REF: ticket/RTM id
or message, PURITY: SHELL, COMPLEXITY: O(1)) matching the style used by
renderDockerfileRtk so the change follows project guidelines.

In `@packages/app/src/web/actions-projects.ts`:
- Around line 94-107: Add comprehensive TSDoc for the function formatUuidV4:
document its purpose (convert a hex string into an RFC 4122-compliant UUID v4
string), mark it `@pure`, declare `@precondition` (input is a hex string containing
0-9a-fA-F of arbitrary length), state the `@postcondition` (returns a 36-character
UUID v4 string with hyphenation and correct version/variant bits), list
`@invariant`(s) (output length == 36, characters at positions 14 == '4', variant
bits in byte 8 set to 0b10xx), and include `@complexity` (O(n) where n is input
length, bounded to constant work to produce 32 hex chars). Reference the
function name formatUuidV4 and its behavior (pad/truncate to 32 hex chars, set
version to '4' and variant to 0b10xxxx) so the TSDoc fully describes inputs,
outputs, side effects (none), and guarantees.

In `@packages/app/src/web/app-ready-terminal-state-hook.ts`:
- Around line 317-328: Currently every change to terminalWorkspace triggers a
persist via setProjectActiveTerminalSession even when the active tuple hasn't
changed; update the useEffect that calls
projectActiveTerminalSelection(activeTerminalSession(terminalWorkspace)) so it
remembers the last persisted (projectKey, sessionId) pair (e.g., useRef or
useState) and only runs Effect.runPromise when the new active is non-null and
its projectKey or sessionId differ from the remembered pair; use the same unique
symbols (useEffect, projectActiveTerminalSelection, activeTerminalSession,
setProjectActiveTerminalSession, terminalWorkspace) and update the remembered
pair after a successful persist to avoid redundant requests and race conditions.

In `@packages/app/src/web/app-terminal-session-core.ts`:
- Around line 20-21: Функция resolveWebAppRoute всегда возвращает { tag:
"Dashboard" } но тип WebAppRoute по-прежнему содержит вариант TerminalSession,
что приводит к недостижимой ветке; либо удалите TerminalSession из определения
типа WebAppRoute, либо вынесите обработку устаревшего пути в отдельный резолвер
(например resolveLegacyTerminalRoute) и используйте его там, где нужен
legacy-путь; отредактируйте определения и вызовы, чтобы больше не ожидать
TerminalSession от resolveWebAppRoute (обновите места, проверяющие tag ===
"TerminalSession"), и добавьте тест/комментарий, если оставляете отдельный
резолвер для совместимости.

In `@packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts`:
- Around line 24-84: Add property-based tests using fast-check in the existing
test file to cover invariants of selectWorkspaceTerminalSession: import
fast-check (fc) and generate arrays of session objects (use
makeSession/makeSessionPair patterns) with randomized ids, createdAt timestamps
and statuses; write properties that assert (1) exact id match returns that
session, (2) a unique short prefix selects the intended session and an ambiguous
prefix returns null, (3) when requested terminalId is missing we do NOT return a
different session (returns null), and (4) when no selector is provided the
chosen session is the newest non-failed one; structure each property with
fc.property and use the existing selectWorkspaceTerminalSession and makeSession
helpers to build sessions and assert the invariants.

In `@packages/app/tests/docker-git/app-ready-terminal-state-hook.test.ts`:
- Around line 29-51: Replace the example-based tests for
projectActiveTerminalSelection/makeSession with property-based invariants using
fast-check: write fc.property tests that assert for all valid projectKey and
sessionId strings the selection persists (using arbitraries like fc.string or a
constrained fc.string matching "owner/repo"), and that for all pendingConnection
shapes (an arbitrary object with message and phase) the selection is null before
API session exists; also assert for all sessions with browserProjectKey
undefined the selection is null. Use the repository's Effect test utilities (no
async/await) to run the property checks and construct sessions via the existing
makeSession helper inside the property body, ensuring each test uses
fc.assert(fc.property(...)) integrated with the Effect test runner.

In `@packages/lib/src/core/templates/dockerfile.ts`:
- Line 33: Добавьте над изменённой строкой в файле
packages/lib/src/core/templates/dockerfile.ts блок функциональных комментариев в
том же стиле, как в packages/app/src/lib/core/templates/dockerfile.ts: включите
маркеры CHANGE (краткое описание изменения — что добавлено/почему), WHY
(архитектурное/обоснование), REF (ссылка на RTM или ID задачи/PR), и PURITY
(CORE|SHELL) — поместите их прямо над строкой с пакетами "openssh-server git gh
ca-certificates curl unzip bsdutils sudo tmux \", чтобы ясно документировать
изменение и соответствовать гайдам кодирования.
🪄 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: 86578686-c25f-4836-a6d9-468d48137b97

📥 Commits

Reviewing files that changed from the base of the PR and between a0d41a7 and 647733f.

📒 Files selected for processing (27)
  • packages/api/src/api/schema.ts
  • packages/api/src/http.ts
  • packages/api/src/services/container-tasks.ts
  • packages/api/src/services/terminal-sessions.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/web/api-schema.ts
  • packages/app/src/web/api.ts
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/app/src/web/app-ready-terminal-screen.tsx
  • packages/app/src/web/app-ready-terminal-state-hook.ts
  • packages/app/src/web/app-ready-url.ts
  • packages/app/src/web/app-terminal-session-core.ts
  • packages/app/src/web/app-terminal-session-handlers.ts
  • packages/app/src/web/elements.tsx
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/src/web/terminal.ts
  • packages/app/tests/docker-git/actions-projects.test.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/tests/docker-git/app-ready-url.test.ts
  • packages/app/tests/docker-git/app-terminal-session-core.test.ts
  • packages/app/tests/docker-git/app-terminal-session-handlers.test.ts
  • packages/app/tests/docker-git/terminal.test.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.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 (Clone cache)
  • GitHub Check: E2E (Browser command)
  • GitHub Check: E2E (Login context)
  • 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-terminal-session-core.ts
  • packages/app/tests/docker-git/app-terminal-session-core.test.ts
  • packages/app/src/web/api-schema.ts
  • packages/app/tests/docker-git/app-ready-url.test.ts
  • packages/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/tests/docker-git/app-terminal-session-handlers.test.ts
  • packages/app/src/web/app-terminal-session-handlers.ts
  • packages/api/src/api/schema.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/web/elements.tsx
  • packages/lib/tests/core/templates.test.ts
  • packages/app/tests/docker-git/terminal.test.ts
  • packages/api/src/services/container-tasks.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/src/web/panel-project-details.tsx
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/web/app-ready-url.ts
  • packages/app/src/web/api.ts
  • packages/app/src/web/app-ready-terminal-state-hook.ts
  • packages/app/src/web/terminal.ts
  • packages/app/src/web/app-ready-terminal-screen.tsx
  • packages/api/src/http.ts
  • packages/app/tests/docker-git/actions-projects.test.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/api/src/services/terminal-sessions.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-terminal-session-core.ts
  • packages/app/tests/docker-git/app-terminal-session-core.test.ts
  • packages/app/src/web/api-schema.ts
  • packages/app/tests/docker-git/app-ready-url.test.ts
  • packages/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/tests/docker-git/app-terminal-session-handlers.test.ts
  • packages/app/src/web/app-terminal-session-handlers.ts
  • packages/api/src/api/schema.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/web/elements.tsx
  • packages/lib/tests/core/templates.test.ts
  • packages/app/tests/docker-git/terminal.test.ts
  • packages/api/src/services/container-tasks.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/src/web/panel-project-details.tsx
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/web/app-ready-url.ts
  • packages/app/src/web/api.ts
  • packages/app/src/web/app-ready-terminal-state-hook.ts
  • packages/app/src/web/terminal.ts
  • packages/app/src/web/app-ready-terminal-screen.tsx
  • packages/api/src/http.ts
  • packages/app/tests/docker-git/actions-projects.test.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/api/src/services/terminal-sessions.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-terminal-session-core.ts
  • packages/app/tests/docker-git/app-terminal-session-core.test.ts
  • packages/app/src/web/api-schema.ts
  • packages/app/tests/docker-git/app-ready-url.test.ts
  • packages/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/tests/docker-git/app-terminal-session-handlers.test.ts
  • packages/app/src/web/app-terminal-session-handlers.ts
  • packages/api/src/api/schema.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/web/elements.tsx
  • packages/lib/tests/core/templates.test.ts
  • packages/app/tests/docker-git/terminal.test.ts
  • packages/api/src/services/container-tasks.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/src/web/panel-project-details.tsx
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/web/app-ready-url.ts
  • packages/app/src/web/api.ts
  • packages/app/src/web/app-ready-terminal-state-hook.ts
  • packages/app/src/web/terminal.ts
  • packages/app/src/web/app-ready-terminal-screen.tsx
  • packages/api/src/http.ts
  • packages/app/tests/docker-git/actions-projects.test.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/api/src/services/terminal-sessions.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-terminal-session-core.ts
  • packages/app/tests/docker-git/app-terminal-session-core.test.ts
  • packages/app/src/web/api-schema.ts
  • packages/app/tests/docker-git/app-ready-url.test.ts
  • packages/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/tests/docker-git/app-terminal-session-handlers.test.ts
  • packages/app/src/web/app-terminal-session-handlers.ts
  • packages/api/src/api/schema.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/web/elements.tsx
  • packages/lib/tests/core/templates.test.ts
  • packages/app/tests/docker-git/terminal.test.ts
  • packages/api/src/services/container-tasks.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/src/web/panel-project-details.tsx
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/web/app-ready-url.ts
  • packages/app/src/web/api.ts
  • packages/app/src/web/app-ready-terminal-state-hook.ts
  • packages/app/src/web/terminal.ts
  • packages/app/src/web/app-ready-terminal-screen.tsx
  • packages/api/src/http.ts
  • packages/app/tests/docker-git/actions-projects.test.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/api/src/services/terminal-sessions.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-terminal-session-core.ts
  • packages/app/tests/docker-git/app-terminal-session-core.test.ts
  • packages/app/src/web/api-schema.ts
  • packages/app/tests/docker-git/app-ready-url.test.ts
  • packages/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/tests/docker-git/app-terminal-session-handlers.test.ts
  • packages/app/src/web/app-terminal-session-handlers.ts
  • packages/api/src/api/schema.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/web/elements.tsx
  • packages/lib/tests/core/templates.test.ts
  • packages/app/tests/docker-git/terminal.test.ts
  • packages/api/src/services/container-tasks.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/src/web/panel-project-details.tsx
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/web/app-ready-url.ts
  • packages/app/src/web/api.ts
  • packages/app/src/web/app-ready-terminal-state-hook.ts
  • packages/app/src/web/terminal.ts
  • packages/app/src/web/app-ready-terminal-screen.tsx
  • packages/api/src/http.ts
  • packages/app/tests/docker-git/actions-projects.test.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/api/src/services/terminal-sessions.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-terminal-session-core.ts
  • packages/app/tests/docker-git/app-terminal-session-core.test.ts
  • packages/app/src/web/api-schema.ts
  • packages/app/tests/docker-git/app-ready-url.test.ts
  • packages/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/tests/docker-git/app-terminal-session-handlers.test.ts
  • packages/app/src/web/app-terminal-session-handlers.ts
  • packages/api/src/api/schema.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/web/elements.tsx
  • packages/lib/tests/core/templates.test.ts
  • packages/app/tests/docker-git/terminal.test.ts
  • packages/api/src/services/container-tasks.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/src/web/panel-project-details.tsx
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/web/app-ready-url.ts
  • packages/app/src/web/api.ts
  • packages/app/src/web/app-ready-terminal-state-hook.ts
  • packages/app/src/web/terminal.ts
  • packages/app/src/web/app-ready-terminal-screen.tsx
  • packages/api/src/http.ts
  • packages/app/tests/docker-git/actions-projects.test.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/api/src/services/terminal-sessions.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/app/tests/docker-git/app-terminal-session-core.test.ts
  • packages/app/tests/docker-git/app-ready-url.test.ts
  • packages/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/tests/docker-git/app-terminal-session-handlers.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/tests/docker-git/terminal.test.ts
  • packages/app/tests/docker-git/actions-projects.test.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/api/tests/terminal-sessions.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/app/tests/docker-git/app-terminal-session-core.test.ts
  • packages/app/tests/docker-git/app-ready-url.test.ts
  • packages/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/tests/docker-git/app-terminal-session-handlers.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/tests/docker-git/terminal.test.ts
  • packages/app/tests/docker-git/actions-projects.test.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/api/tests/terminal-sessions.test.ts
🪛 GitHub Check: Lint Effect-TS
packages/app/src/web/terminal.ts

[failure] 107-107:
Casting is only allowed in src/core/axioms.ts

🔇 Additional comments (22)
packages/lib/tests/core/templates.test.ts (1)

68-68: LGTM!

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

33-33: Реализация отключения tmux status bar подтверждена.

Логика отключения status bar корректно реализована в слое сервисов (packages/api/src/services/terminal-sessions.ts, функция renderTmuxAttachCommand). Команда tmux set-option -t <name> status off выполняется при инициализации терминальной сессии, с обработкой ошибок через || true. Функциональность покрыта тестами в packages/api/tests/terminal-sessions.test.ts (ожидание "status off" в команде). Dockerfile правильно только устанавливает пакет — конфигурация tmux находится в нужном слое согласно архитектурным принципам.

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

76-106: LGTM!

Also applies to: 108-109, 147-147, 201-201

packages/app/src/web/app-ready-ssh-link-hook.ts (1)

4-17: LGTM!

Also applies to: 35-37, 74-76, 80-82, 84-90, 109-211, 245-249, 267-332

packages/app/src/web/app-ready-terminal-state-hook.ts (1)

8-8: LGTM!

Also applies to: 291-296

packages/app/src/web/app-ready-terminal-screen.tsx (1)

13-14: LGTM!

Also applies to: 139-148, 233-241, 254-255, 271-271, 296-297, 338-339

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

16-17: LGTM!

Also applies to: 127-128, 141-142, 146-147, 221-235

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

17-18: LGTM!

Also applies to: 94-99, 112-113

packages/app/src/web/elements.tsx (1)

80-81: LGTM!

Also applies to: 86-87, 112-116

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

7-8: LGTM!

Also applies to: 84-85, 87-88

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

293-293: LGTM!

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

218-236: LGTM!

packages/app/tests/docker-git/app-ready-url.test.ts (1)

64-89: LGTM!

packages/app/tests/docker-git/app-terminal-session-core.test.ts (1)

23-27: LGTM!

Also applies to: 47-47

packages/app/tests/docker-git/app-terminal-session-handlers.test.ts (1)

25-29: LGTM!

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

88-113: LGTM!

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

109-115: LGTM!

packages/app/tests/docker-git/actions-projects.test.ts (2)

148-216: LGTM!


218-241: LGTM!

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

163-169: LGTM!

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

1579-1590: LGTM!

Also applies to: 1442-1450

packages/api/src/services/container-tasks.ts (1)

369-377: LGTM!

Comment thread packages/api/src/services/terminal-sessions.ts
Comment thread packages/api/tests/terminal-sessions.test.ts Outdated
Comment thread packages/app/src/lib/core/templates/dockerfile.ts
Comment thread packages/app/src/web/actions-projects.ts
Comment thread packages/app/src/web/app-ready-terminal-state-hook.ts
Comment thread packages/app/src/web/app-terminal-session-core.ts
Comment thread packages/app/src/web/terminal.ts Outdated
Comment thread packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
Comment thread packages/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
Comment thread packages/lib/src/core/templates/dockerfile.ts
@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 17, 2026

AI Session Backup

Commit: 4bac82b
Status: success
Files: 8 (7.23 MB)
Links: README | Manifest

git status

On branch pr-300
Your branch is up to date with 'origin/pr-300'.

nothing to commit, working tree clean

@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 17, 2026

AI Session Backup

Commit: b5b8cec
Status: success
Files: 9 (8.01 MB)
Links: README | Manifest

git status

On branch pr-300
Your branch is up to date with 'origin/pr-300'.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/api/tests/terminal-sessions.test.ts (1)

212-436: 🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy lift

Переведите unit-тесты на Effect test utilities без async/await.

В этом блоке тесты массово используют async/await, что расходится с принятым тестовым контрактом в репозитории. Лучше завернуть сценарии в effect-пайплайн и запускать через единый Effect-style harness для детерминированного поведения.

As per coding guidelines, "**/*.{test,spec}.{ts,tsx}: Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await."

🤖 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/tests/terminal-sessions.test.ts` around lines 212 - 436, Tests
in this block use async/await directly (e.g., awaiting
runTestEffect(createTerminalSession(projectId)), startTerminalSession,
setProjectActiveTerminalSession, readProjectTerminalSessions,
deleteTerminalSession) which violates the repository's contract that unit tests
must be written with the Effect test utilities; convert each test to produce and
run an Effect rather than using async/await. For each spec, replace top-level
async functions and awaits with an Effect pipeline that composes the mocked
setup (probeProjectSshReadyMock, getProjectMock, runCommandCaptureMock,
upProjectMock, waitForProjectSshReadyMock), the primary call
(createTerminalSession, startTerminalSession, listProjectTerminalSessions,
getProjectTerminalSession, lookupTerminalSessionById,
setProjectActiveTerminalSession, deleteTerminalSession), and assertions inside
the Effect by returning values to be inspected after runTestEffect, then execute
the whole Effect via runTestEffect (or the repository harness) so tests remain
deterministic and consistent with the Effect-style harness; also migrate
teardown/afterEach to runTestEffect(cleanupSessions()) and other cleanup Effects
instead of synchronous/async filesystem calls where equivalents exist.
🤖 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/app/src/web/app-ready-terminal-state-hook.ts`:
- Around line 64-73: Надо защититься от out-of-order завершений
setProjectActiveTerminalSession: перед вызовом setProjectActiveTerminalSession
(включая места с Effect.runPromise и также участок на 97-99) инкрементируйте
локальный монотонный ревизионный счётчик (в поле рядом с
persistedSelectionRef/selectionKey), захватите текущий ревиз в замыкании и при
завершении проверки результата сравните ревиз завершения с актуальным; если они
не совпадают — игнорируйте результат (не вызывать
clearFailedPersistedSelection/Effect.void и не перезаписывать
серверную/локальную селекцию). Обновите persistedSelectionRef/selectionKey
только когда ревизия совпадает, чтобы старые асинхронные ответы не
перезаписывали более свежие изменения.

---

Outside diff comments:
In `@packages/api/tests/terminal-sessions.test.ts`:
- Around line 212-436: Tests in this block use async/await directly (e.g.,
awaiting runTestEffect(createTerminalSession(projectId)), startTerminalSession,
setProjectActiveTerminalSession, readProjectTerminalSessions,
deleteTerminalSession) which violates the repository's contract that unit tests
must be written with the Effect test utilities; convert each test to produce and
run an Effect rather than using async/await. For each spec, replace top-level
async functions and awaits with an Effect pipeline that composes the mocked
setup (probeProjectSshReadyMock, getProjectMock, runCommandCaptureMock,
upProjectMock, waitForProjectSshReadyMock), the primary call
(createTerminalSession, startTerminalSession, listProjectTerminalSessions,
getProjectTerminalSession, lookupTerminalSessionById,
setProjectActiveTerminalSession, deleteTerminalSession), and assertions inside
the Effect by returning values to be inspected after runTestEffect, then execute
the whole Effect via runTestEffect (or the repository harness) so tests remain
deterministic and consistent with the Effect-style harness; also migrate
teardown/afterEach to runTestEffect(cleanupSessions()) and other cleanup Effects
instead of synchronous/async filesystem calls where equivalents exist.
🪄 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: 4a8ea11a-9792-4baf-89a1-db2779f91f55

📥 Commits

Reviewing files that changed from the base of the PR and between 647733f and 4bac82b.

📒 Files selected for processing (19)
  • packages/api/src/services/terminal-sessions.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/api-project-schema.ts
  • packages/app/src/web/api-schema.ts
  • packages/app/src/web/api-terminal-schema.ts
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/app/src/web/app-ready-terminal-screen.tsx
  • packages/app/src/web/app-ready-terminal-state-hook.ts
  • packages/app/src/web/app-ready-terminal-storage.ts
  • packages/app/src/web/app-terminal-session-core.ts
  • packages/app/src/web/app.tsx
  • packages/app/src/web/elements.tsx
  • packages/app/src/web/terminal.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/lib/src/core/templates/dockerfile.ts
💤 Files with no reviewable changes (1)
  • packages/app/src/web/app.tsx
📜 Review details
🧰 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/elements.tsx
  • packages/app/src/web/app-ready-terminal-storage.ts
  • packages/app/src/web/api-terminal-schema.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/app-terminal-session-core.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/src/web/terminal.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/web/api-project-schema.ts
  • packages/app/src/web/app-ready-terminal-state-hook.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/app/src/web/app-ready-terminal-screen.tsx
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/app/src/web/api-schema.ts
  • packages/api/src/services/terminal-sessions.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/elements.tsx
  • packages/app/src/web/app-ready-terminal-storage.ts
  • packages/app/src/web/api-terminal-schema.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/app-terminal-session-core.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/src/web/terminal.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/web/api-project-schema.ts
  • packages/app/src/web/app-ready-terminal-state-hook.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/app/src/web/app-ready-terminal-screen.tsx
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/app/src/web/api-schema.ts
  • packages/api/src/services/terminal-sessions.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/elements.tsx
  • packages/app/src/web/app-ready-terminal-storage.ts
  • packages/app/src/web/api-terminal-schema.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/app-terminal-session-core.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/src/web/terminal.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/web/api-project-schema.ts
  • packages/app/src/web/app-ready-terminal-state-hook.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/app/src/web/app-ready-terminal-screen.tsx
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/app/src/web/api-schema.ts
  • packages/api/src/services/terminal-sessions.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/elements.tsx
  • packages/app/src/web/app-ready-terminal-storage.ts
  • packages/app/src/web/api-terminal-schema.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/app-terminal-session-core.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/src/web/terminal.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/web/api-project-schema.ts
  • packages/app/src/web/app-ready-terminal-state-hook.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/app/src/web/app-ready-terminal-screen.tsx
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/app/src/web/api-schema.ts
  • packages/api/src/services/terminal-sessions.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/elements.tsx
  • packages/app/src/web/app-ready-terminal-storage.ts
  • packages/app/src/web/api-terminal-schema.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/app-terminal-session-core.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/src/web/terminal.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/web/api-project-schema.ts
  • packages/app/src/web/app-ready-terminal-state-hook.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/app/src/web/app-ready-terminal-screen.tsx
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/app/src/web/api-schema.ts
  • packages/api/src/services/terminal-sessions.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/elements.tsx
  • packages/app/src/web/app-ready-terminal-storage.ts
  • packages/app/src/web/api-terminal-schema.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/app-terminal-session-core.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/src/web/terminal.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/web/api-project-schema.ts
  • packages/app/src/web/app-ready-terminal-state-hook.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/app/src/web/app-ready-terminal-screen.tsx
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/app/src/web/api-schema.ts
  • packages/api/src/services/terminal-sessions.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/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/api/tests/terminal-sessions.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/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/api/tests/terminal-sessions.test.ts
🔇 Additional comments (32)
packages/app/src/web/elements.tsx (1)

78-81: LGTM!

Also applies to: 86-90, 115-115

packages/app/src/web/app-ready-terminal-storage.ts (1)

213-234: LGTM!

Also applies to: 253-273

packages/app/src/web/api-terminal-schema.ts (1)

6-30: LGTM!

Also applies to: 32-32

packages/app/src/web/api-auth-schema.ts (1)

5-63: LGTM!

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

4-4: LGTM!

Also applies to: 18-19

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

94-116: LGTM!

Also applies to: 123-123

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

6-13: LGTM!

Also applies to: 41-41

packages/app/tests/docker-git/app-ready-terminal-state-hook.test.ts (1)

49-69: LGTM!

Also applies to: 71-107

packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts (1)

38-155: LGTM!

packages/app/src/web/app-ready-ssh-link-hook.ts (1)

84-90: LGTM!

Also applies to: 108-166, 258-323

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

1-52: LGTM!

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

1135-1158: LGTM!


1592-1613: LGTM!


1477-1493: LGTM!


1469-1475: LGTM!


81-91: LGTM!


145-166: LGTM!


943-972: LGTM!


1202-1256: LGTM!


1014-1062: LGTM!


1-52: LGTM!


1001-1011: LGTM!


692-712: LGTM!


167-180: LGTM!


223-242: LGTM!


974-1012: LGTM!


280-410: LGTM!


442-491: LGTM!

Also applies to: 605-661, 663-690


487-603: LGTM!


743-930: LGTM!


1064-1131: LGTM!


1538-1576: LGTM!

Comment thread packages/app/src/web/app-ready-terminal-state-hook.ts
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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/api/tests/terminal-sessions.test.ts (1)

212-435: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Нужно привести тесты к обязательному формату PBT + Effect test utilities.

В текущих изменениях тесты остаются в example-based стиле и массово используют async/await. По вашим правилам для *.test.ts нужны property-based инварианты (fast-check) и unit-тесты без async/await, через Effect testing utilities. Это сейчас не соблюдено, поэтому соответствие спецификации неполное.

As per coding guidelines, **/*.test.{ts,tsx}: "Implement property-based testing using fast-check for mathematical properties and invariants." и **/*.{test,spec}.{ts,tsx}: "Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await."

🤖 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/tests/terminal-sessions.test.ts` around lines 212 - 435, The
tests use example-based async/await patterns instead of the required
property-based testing and Effect test utilities; convert each example-style
test (e.g., tests that call createTerminalSession, startTerminalSession,
listProjectTerminalSessions, readProjectTerminalSessions,
setProjectActiveTerminalSession, deleteTerminalSession, renderTmuxAttachCommand)
to the mandated format by: replacing direct async/await calls with the Effect
test runner utilities (use runTestEffect / Effect test helpers for assertions
and avoid top-level async/await), and where invariants exist (session id
uniqueness, persisted IDs/state, phases emitted, tmux-probe behavior) rewrite
them as fast-check properties (fc.property + fc.assert) that generate inputs and
assert invariants; also remove vi.waitFor patterns and instead assert emitted
events deterministically via the Effect test utilities or explicit
synchronisation primitives provided by the test harness. Ensure mocks
(probeProjectSshReadyMock, getProjectMock, runCommandCaptureMock, upProjectMock,
waitForProjectSshReadyMock) remain configured inside the property/body and that
tests continue to reference the same helper functions (readPersistedSessionIds,
readPersistedActiveSessionId, listProjectEventsSince, renderTmuxAttachCommand)
when asserting results.
🤖 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.

Outside diff comments:
In `@packages/api/tests/terminal-sessions.test.ts`:
- Around line 212-435: The tests use example-based async/await patterns instead
of the required property-based testing and Effect test utilities; convert each
example-style test (e.g., tests that call createTerminalSession,
startTerminalSession, listProjectTerminalSessions, readProjectTerminalSessions,
setProjectActiveTerminalSession, deleteTerminalSession, renderTmuxAttachCommand)
to the mandated format by: replacing direct async/await calls with the Effect
test runner utilities (use runTestEffect / Effect test helpers for assertions
and avoid top-level async/await), and where invariants exist (session id
uniqueness, persisted IDs/state, phases emitted, tmux-probe behavior) rewrite
them as fast-check properties (fc.property + fc.assert) that generate inputs and
assert invariants; also remove vi.waitFor patterns and instead assert emitted
events deterministically via the Effect test utilities or explicit
synchronisation primitives provided by the test harness. Ensure mocks
(probeProjectSshReadyMock, getProjectMock, runCommandCaptureMock, upProjectMock,
waitForProjectSshReadyMock) remain configured inside the property/body and that
tests continue to reference the same helper functions (readPersistedSessionIds,
readPersistedActiveSessionId, listProjectEventsSince, renderTmuxAttachCommand)
when asserting results.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3dfab95b-1b61-4899-a9e7-29608b411994

📥 Commits

Reviewing files that changed from the base of the PR and between 4bac82b and b5b8cec.

📒 Files selected for processing (1)
  • packages/api/tests/terminal-sessions.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 (Clone auto-open SSH)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Clone cache)
  • 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/api/tests/terminal-sessions.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/terminal-sessions.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/terminal-sessions.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/terminal-sessions.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/terminal-sessions.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/terminal-sessions.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/terminal-sessions.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/terminal-sessions.test.ts
🔇 Additional comments (1)
packages/api/tests/terminal-sessions.test.ts (1)

27-210: LGTM!

Also applies to: 240-374

@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 17, 2026

AI Session Backup

Commit: d0d6112
Status: success
Files: 9 (8.77 MB)
Links: README | Manifest

git status

On branch pr-300
Your branch is up to date with 'origin/pr-300'.

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/app/src/web/app-ready-terminal-state-hook.ts`:
- Around line 51-56: Add TSDoc blocks for the exported functions
projectActiveTerminalSelection, createProjectActiveTerminalPersistenceRef, and
persistProjectActiveTerminalSelection: for each include the required tags (`@pure`
with true/false per function, `@effect` listing service/effect like
setProjectActiveTerminalSession for persistProjectActiveTerminalSelection,
`@invariant/`@precondition/@postcondition as minimal statements, and `@complexity`),
plus a brief one-line description (e.g., projectActiveTerminalSelection: returns
null if session pending or not project-bound;
createProjectActiveTerminalPersistenceRef: factory for persistence ref;
persistProjectActiveTerminalSelection: writes selection), ensuring the comments
are placed immediately above each exported function declaration.
🪄 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: 58d7857b-b76b-40d7-90a8-22d930d4375a

📥 Commits

Reviewing files that changed from the base of the PR and between b5b8cec and d0d6112.

📒 Files selected for processing (2)
  • packages/app/src/web/app-ready-terminal-state-hook.ts
  • packages/app/tests/docker-git/app-ready-terminal-state-hook.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: Final build (windows-latest)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: Test
  • GitHub Check: Lint
  • GitHub Check: E2E (Browser command)
  • 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/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/src/web/app-ready-terminal-state-hook.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/app/tests/docker-git/app-ready-terminal-state-hook.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/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/src/web/app-ready-terminal-state-hook.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/app/tests/docker-git/app-ready-terminal-state-hook.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/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/src/web/app-ready-terminal-state-hook.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/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/src/web/app-ready-terminal-state-hook.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/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/src/web/app-ready-terminal-state-hook.ts
**/*

⚙️ CodeRabbit configuration file

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

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

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

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

Files:

  • packages/app/tests/docker-git/app-ready-terminal-state-hook.test.ts
  • packages/app/src/web/app-ready-terminal-state-hook.ts
🔇 Additional comments (7)
packages/app/tests/docker-git/app-ready-terminal-state-hook.test.ts (1)

1-195: LGTM!

packages/app/src/web/app-ready-terminal-state-hook.ts (6)

51-56: LGTM!


58-77: LGTM!


79-101: Защита от out-of-order персистентности корректно реализована.

Проверка inFlightRequest?.selectionKey !== request.selectionKey на строке 85 эффективно игнорирует устаревшие завершения. Это эквивалентно подходу с монотонным счётчиком ревизий из предыдущего обзора, но использует selectionKey как идентификатор версии.


103-126: LGTM!


128-142: LGTM!


144-177: LGTM!

Comment thread packages/app/src/web/app-ready-terminal-state-hook.ts
# Conflicts:
#	packages/app/src/lib/core/templates/dockerfile.ts
#	packages/lib/src/core/templates/dockerfile.ts
@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 18, 2026

AI Session Backup

Commit: 16a4b55
Status: success
Files: 9 (9.44 MB)
Links: README | Manifest

git status

On branch pr-300
Your branch is up to date with 'origin/pr-300'.

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/app/src/lib/core/templates/dockerfile.ts`:
- Around line 18-25: Replace the Latin marker "QUOTE(TZ):" in the functional
comment block for the tmux/dockerfile change with the Cyrillic variant
"QUOTE(ТЗ):" so it matches other comments in the file (e.g., the existing
"QUOTE(ТЗ)" instances); update the comment string in the same block containing
CHANGE/WHY/REF/PURITY/INVARIANT so only the marker text is changed and
formatting remains identical.

In `@packages/lib/src/core/templates/dockerfile.ts`:
- Around line 18-25: В комментарии в шаблоне Dockerfile замените латинский
маркер "QUOTE(TZ):" на кириллический "QUOTE(ТЗ):" чтобы привести этот блок в
соответствие с остальными в файле (встречающимися как "QUOTE(ТЗ)" на других
строках); проверьте и исправьте все другие вхождения "QUOTE(TZ)" в
packages/lib/src/core/templates/dockerfile.ts на "QUOTE(ТЗ)" для консистентности
с гайдлайнами.
🪄 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: 2bef44b0-f577-4c90-a44f-3ccbd068dce6

📥 Commits

Reviewing files that changed from the base of the PR and between d0d6112 and 16a4b55.

📒 Files selected for processing (3)
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.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). (7)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (OpenCode)
  • 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/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.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/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.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/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.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/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.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/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.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/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.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/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/core/templates.test.ts
🔇 Additional comments (3)
packages/app/src/lib/core/templates/dockerfile.ts (1)

68-68: LGTM!

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

68-68: LGTM!

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

200-200: LGTM!

Comment thread packages/app/src/lib/core/templates/dockerfile.ts
Comment thread packages/lib/src/core/templates/dockerfile.ts
@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 18, 2026

AI Session Backup

Commit: a522d65
Status: success
Files: 9 (9.96 MB)
Links: README | Manifest

git status

On branch pr-300
Your branch is up to date with 'origin/pr-300'.

nothing to commit, working tree clean

@skulidropek skulidropek merged commit 5602ee7 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

2 participants