Skip to content

[codex] Add OpenAPI contract and fetch client#427

Merged
skulidropek merged 10 commits into
mainfrom
codex/openapi-fetch-effect-api
Jun 19, 2026
Merged

[codex] Add OpenAPI contract and fetch client#427
skulidropek merged 10 commits into
mainfrom
codex/openapi-fetch-effect-api

Conversation

@skulidropek

@skulidropek skulidropek commented Jun 18, 2026

Copy link
Copy Markdown
Member

Source TZ / Issues

Summary

  • Adds an Effect HttpApi REST contract and generated packages/api/openapi.json for docker-git JSON endpoints.
  • Exposes /openapi.json and /docs from the API server.
  • Adds openapi-fetch plus generated frontend path types and routes migrated frontend REST calls through an Effect boundary.
  • Aligns OpenAPI response status codes and error envelope shape with the real HTTP handlers.
  • Keeps generated OpenAPI path types out of app lint auto-fix and uses typed terminal-session delete endpoints.

Requirements Alignment

  • Implemented:
    • POST create endpoints now document real 201 responses; async endpoints keep 202.
    • API error schema now matches the nested { error: { type, message, details?, provider?, command? } } envelope returned by errorResponse.
    • OpenAPI tests assert path coverage, success status codes, async status codes, and nested error envelope shape.
    • Async project creation shares the same request-body builder and Playwright resource limit fields as sync creation.
    • Terminal close paths are parsed into typed OpenAPI DELETE calls instead of arbitrary requestText paths.
    • openapi-client.ts no longer uses Effect.runSync; nullable success/error branches use Option and error formatting remains Effect-composed.
    • Codex auth response schemas and intentional terminal workspace/list split are documented.
    • scripts/write-openapi.ts reports write failures explicitly.
  • Out of scope:
    • Full Context.Tag/Layer migration for the frontend OpenAPI client cache; documented as a migration limitation to avoid changing every UI call site in this PR.
  • Security-sensitive changes:
    • No new secrets or auth flows. Error schema documents existing command/provider fields already returned by API handlers.

Mathematical Guarantees

  • forall endpoint e in DockerGitApi: e is represented in buildDockerGitOpenApi().paths for documented JSON REST endpoints.
  • forall response r: openApiJsonSchema(schema, request) succeeds only when Schema.decodeUnknown(schema)(r.data) succeeds.
  • Promise interop is isolated inside openapi-client.ts through Effect.tryPromise; exported API functions return Effect.
  • forall create endpoint c documented in DockerGitApi: documented_success_status(c) = actual_http_success_status(c) for the reviewed create endpoints.

Proof of fix

  • Cause: OpenAPI initially documented several create responses as default 200 and used a flat error schema, while http.ts returns 201/202 and nested error envelopes.
  • Solution: update the Effect HttpApi contract, regenerate OpenAPI artifacts, and route frontend helpers through typed/generated paths without leaking generated transport shapes.
  • Regression proof: packages/api/tests/openapi.test.ts now fails on the old 200/flat-error contract and passes with the aligned 201/202 nested-envelope contract.

Verification

  • rtk bun run --cwd packages/app generate:api
  • rtk bun run --cwd packages/api typecheck
  • rtk bun run --cwd packages/api test - 27 files, 196 tests
  • rtk bun run --cwd packages/app lint - 0 errors
  • rtk bun run --cwd packages/app typecheck
  • rtk bun run --cwd packages/app test - 78 files, 453 tests
  • rtk bun run lint:effect - exit code 0; existing warning-only migration blockers remain outside this fix
  • Local fix commit: 68a1d56e

@skulidropek

skulidropek commented Jun 18, 2026

Copy link
Copy Markdown
Member Author

AI Session Backup

Commit: 9bfd067
Status: success
Files: 15 (14.10 MB)
Links: README | Manifest

git status

On branch codex/openapi-fetch-effect-api
Your branch is up to date with 'origin/codex/openapi-fetch-effect-api'.

nothing to commit, working tree clean

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 65030ef6-05ae-46c3-bff7-b0b5440bfc2e

📥 Commits

Reviewing files that changed from the base of the PR and between a0f08e5 and 7b96e06.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • packages/api/tests/openapi.test.ts
  • packages/app/package.json
  • packages/app/src/web/api-create-project.ts
  • packages/app/src/web/api-project-create-body.ts
  • packages/app/src/web/openapi-client.ts
  • packages/app/tests/docker-git/api-create-project.test.ts
  • packages/app/tests/docker-git/api-terminal.test.ts
  • scripts/e2e/local-package-cli.sh

📝 Walkthrough

Summary by CodeRabbit

Примечания к выпуску

  • Новые функции

    • Добавлена интерактивная документация API с интерфейсом Swagger UI (доступна по адресу /docs)
    • Добавлена OpenAPI 3.1 спецификация для всех REST API эндпоинтов (доступна по адресу /openapi.json)
    • Реализована поддержка управления терминальными сессиями через API
  • Улучшения

    • Улучшена надёжность API-клиента с обработкой ошибок и валидацией схем
    • Расширена типизация API-запросов и ответов для всех эндпоинтов

Walkthrough

Добавлен новый workspace packages/openapi с пакетом @prover-coder-ai/docker-git-openapi, содержащим полный Effect HttpApi контракт из 54 эндпоинтов и 60+ схем, типизированный openapi-fetch клиент с Effect-интеграцией и скрипт генерации OpenAPI JSON. В packages/api добавлены маршруты /openapi.json и /docs (Swagger UI). Все API-модули packages/app мигрированы с requestJson/requestText на новые openApiJsonSchema/openApiVoid обёртки, использующие параметризованные path и query параметры вместо ручной сборки URL.

Changes

OpenAPI Contract, Client, and App Migration

Layer / File(s) Summary
Effect HttpApi контракт: схемы и группы эндпоинтов
packages/api/src/api/openapi.ts, packages/api/tests/openapi.test.ts
Определены все доменные схемы (проекты, терминалы, промпты, навыки, задачи, порты, браузер, sharing, auth-интеграции) и собран DockerGitApi с 12 группами эндпоинтов, 400-ошибкой и buildDockerGitOpenApi(). Контрактные тесты проверяют 54 пути, наличие/отсутствие конкретных эндпоинтов, status-коды ответов (201/202 для async), структуру error-envelope, полей в response-схемах и снимки конкретных эндпоинтов (auth/menu, terminal-sessions/active, tasks).
packages/openapi workspace: манифест и конфигурация
packages/openapi/package.json, packages/openapi/tsconfig.json, packages/openapi/src/index.ts, package.json, packages/app/package.json, packages/app/biome.json
Новый ESM-пакет @prover-coder-ai/docker-git-openapi с картой экспортов (., ./client, ./openapi-paths, ./openapi.json) и скриптами generate/check/typecheck. Корневой package.json добавлен в workspaces с скриптом web:generate-api и typecheck-шагом. packages/app получает generate:api скрипт и зависимость на openapi пакет.
packages/openapi/src/client.ts: Effect runtime для openapi-fetch
packages/openapi/src/client.ts
Типизированный клиент с no-cache заголовками, GET cache-busting middleware (timestamp query parameter _), рендерингом ошибок (HTTP 429 спец-кейс, JSON payload fallback), Effect-обёртками runOpenApi (tryPromise), openApiJson (ok-only success), openApiJsonSchema (decode via @effect/schema и TreeFormatter), openApiVoid (ok без error) и makeDockerGitOpenApiRuntime с кэшированием клиента по baseUrl.
Скрипт write-openapi и маршруты Swagger UI
scripts/write-openapi.ts, packages/api/src/http.ts, packages/api/Dockerfile, packages/api/package.json, packages/app/tests/docker-git/controller-resource-limits.test.ts
write-openapi.ts генерирует и записывает openapi.json через Bun.write с обработкой ошибок. В HTTP-роутере добавлены GET /openapi.json (JSON ответ) и GET /docs (Swagger UI HTML). Dockerfile добавляет packages/openapi в stage копирования зависимостей. Добавлен npm-скрипт lint:openapi-contract и тест проверки наличия openapi в Dockerfile.
App-уровень: wiring openapi-client и Codex-схемы
packages/app/src/web/openapi-client.ts, packages/app/src/web/api-auth-schema.ts, packages/app/src/web/api-schema.ts
openapi-client.ts инициализирует openApiRuntime с resolveApiBaseUrl и экспортирует openApiJson/openApiJsonSchema/openApiVoid как алиасы с JSDoc контрактами. Добавлены CodexAuthStatusSchema (account nullable, остальные required) и CodexStatusResponseSchema с переэкспортом через api-schema.ts.
api-project-create-body.ts и хелперы тела запроса
packages/app/src/web/api-project-create-body.ts, packages/app/tests/docker-git/api-create-project.test.ts
Новый модуль экспортирует тип CreateProjectRequestDraft (CreateProjectDraft & ProjectResourceLimitRequest), функции optionalProjectResourceFields (только non-undefined CPU/RAM) и baseCreateProjectBody (фиксирует openSsh: false, useManagedAuthorizedKeys: true). Тесты property-based и детерминированные проверяют сериализацию createProjectAcceptedBody с ресурсными лимитами и фиксированными полями.
Миграция api-project-core.ts и api-create-project.ts
packages/app/src/web/api-project-core.ts, packages/app/src/web/api-create-project.ts
Все project-эндпоинты переведены на openApiJsonSchema с params: { path: { projectId } }. Добавлены локальные хелперы applyProjectBody (условно включает лимиты) и createProjectBody. createProjectAcceptedBody вынесен как экспорт и использует async: true + optionalProjectResourceFields.
api-terminal.ts: обёртки терминальных сессий
packages/app/src/web/api-terminal.ts, packages/app/src/web/api.ts, packages/app/tests/docker-git/api-terminal.test.ts
Новый модуль с 10 typed-обёртками сессий (create/start/delete/load/set-active) и deleteTerminalSessionByPath (regex-маршрутизация auth и project путей, декодирование через decodeURIComponent). api.ts заменяет локальные реализации на ре-экспорт. Тесты покрывают auth-путь, project-путь с percent-encoded projectKey и отклонение неподдерживаемого пути.
Миграция api.ts: dashboard, ports, browser, auth, Codex
packages/app/src/web/api.ts
Мигрирует loadDashboard (GET /health + /projects), port-forward CRUD, project browser, project lifecycle (down/delete/down-all/apply-all), loadGithubStatus/loginGithub, logoutCodex (с CodexStatusResponseSchema), loadAuthSnapshot/runAuthMenuFlow, loadProjectAuthSnapshot/runProjectAuthFlow на openApiJsonSchema/openApiVoid. Ре-экспортирует все терминальные методы из ./api-terminal.js.
Миграция доменных модулей: database, prompts, skills, tasks, share
packages/app/src/web/api-database.ts, packages/app/src/web/api-prompts.ts, packages/app/src/web/api-skills.ts, packages/app/src/web/api-tasks.ts, packages/app/src/web/api-share.ts
Все модули переходят на openApiJsonSchema/openApiVoid с params.path/params.query/body вместо ручных URL-строк. Удалены ручные encodeURIComponent и построители путей. Сохранены маппинги ответов (.profiles, .forwards, .snapshot, .session, .output).
e2e скрипт: подготовка и верификация openapi пакета
scripts/e2e/local-package-cli.sh
Расширены переменные окружения для openapi (pack-log, tarball paths), добавлен вывод openapi pack-log при ошибке, cleanup удаляет packed tarball. Перед подготовкой app-пакета добавлена последовательность: cd в packages/openapi, bun pm pack, проверка tarball на наличие src/index.ts и openapi.json, обновление app зависимостей с file: ссылкой на packed tarball.

Sequence Diagram(s)

sequenceDiagram
  participant AppModule as "App API Module"
  participant openApiJsonSchema as "openApiJsonSchema"
  participant openApiRuntime as "DockerGitOpenApiRuntime"
  participant openapiFetch as "openapi-fetch client"
  participant ApiServer as "API Server"

  AppModule->>openApiJsonSchema: schema + client.GET/POST/DELETE(...)
  openApiJsonSchema->>openApiRuntime: runRuntimeOpenApi
  openApiRuntime->>openapiFetch: resolveBaseUrl → create/cache client
  openapiFetch->>ApiServer: HTTP запрос (с cache-bust для GET)
  ApiServer-->>openapiFetch: { data, error, response }
  openapiFetch-->>openApiRuntime: OpenApiResponse
  openApiRuntime-->>openApiJsonSchema: ApiTransportValue или строка ошибки
  openApiJsonSchema->>openApiJsonSchema: Schema.decodeUnknownEither + TreeFormatter
  openApiJsonSchema-->>AppModule: A или ошибка
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

  • ProverCoderAI/docker-git#312: Добавляет поддержку idle-runtime и поля Playwright resource-limits для проектов, которые этот PR миграции использует в новом apiProjectCreateBody и applyProjectBody хелперах.
  • ProverCoderAI/docker-git#313: Вводит Cloudflare tunnel panel endpoints и Share UI, построенные на OpenAPI контракте и exported PanelCloudflareTunnel* схемах, которые этот PR определяет.

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error)

Check name Status Explanation Resolution
Requirements Alignment ❌ Error PR core OpenAPI functionality is implemented but violates multiple review-identified code quality requirements: missing explicit type annotations on public exports (openapi-client.ts, createProject... Address 6 code quality issues: Add explicit type annotations to openapi-client.ts exports and builder functions, move @prover-coder-ai/docker-git-openapi to dependencies, validate error messages in tests, add fc.property tests for reques...
✅ Passed checks (6 passed)
Check name Status Explanation
Title check ✅ Passed Заголовок точно отражает основное изменение: добавление OpenAPI контракта и fetch-клиента, что соответствует сути PR.
Description check ✅ Passed Описание содержит практически все требуемые разделы: Source TZ/Issues, Summary, Requirements Alignment (с подробными списками), и Verification с полной информацией о выполненных проверках.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Security Regression ✅ Passed No high-confidence security regressions found. OpenAPI endpoints properly secured with error handling, dependencies are legitimate, path operations are safe from traversal, no XSS vectors in HTML g...
✨ 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 codex/openapi-fetch-effect-api

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@skulidropek skulidropek changed the title feat(api): add OpenAPI contract and fetch client [codex] Add OpenAPI contract and fetch client Jun 18, 2026
@skulidropek skulidropek marked this pull request as draft June 18, 2026 09:58
@skulidropek

skulidropek commented Jun 18, 2026

Copy link
Copy Markdown
Member Author

AI Session Backup

Commit: 38cd8ea
Status: success
Files: 15 (14.73 MB)
Links: README | Manifest

git status

On branch codex/openapi-fetch-effect-api
Your branch is up to date with 'origin/codex/openapi-fetch-effect-api'.

nothing to commit, working tree clean

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 12

Caution

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

⚠️ Outside diff range comments (1)
packages/app/src/web/api-terminal.ts (1)

1-118: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Добавьте обязательную документацию для всех экспортируемых функций терминальных сессий.

Согласно guidelines, каждая экспортируемая функция должна иметь comprehensive TSDoc с аннотациями @effect, @invariant, @throws, @complexity. Для SHELL-функций критично документировать зависимости от внешних сервисов и типизированные ошибки.

📝 Пример документации
/**
 * Создаёт новую терминальную сессию для проекта
 *
 * `@param` projectKey - Ключ проекта (non-empty string)
 * `@returns` Effect с объектом { project, session } или ошибкой
 *
 * `@pure` false - содержит HTTP-эффекты
 * `@effect` OpenAPI client, terminal session service
 * `@invariant` ∀ projectKey: created(session) → session.projectKey = projectKey
 * `@precondition` projectKey.length > 0 ∧ project exists
 * `@postcondition` ∃ sessionId: persisted(session, sessionId)
 * `@complexity` O(1) HTTP request
 * `@throws` Never - все ошибки типизированы как Effect<_, string>
 */
export const createProjectTerminalSession = (projectKey: string) =>
  // ...
🤖 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/app/src/web/api-terminal.ts` around lines 1 - 118, Add comprehensive
TSDoc documentation to all exported terminal session functions
(createProjectTerminalSession, startProjectTerminalSession,
createAuthTerminalSession, deleteProjectTerminalSession,
loadProjectTerminalSessions, loadProjectTerminalWorkspace,
setProjectActiveTerminalSession, loadProjectTerminalSession,
loadTerminalSessionById, deleteTerminalSessionByPath) with required annotations.
Each function must include a description of its purpose, `@param` annotations for
all parameters, `@returns` describing the return Effect, `@effect` documenting
dependencies on external services (OpenAPI client, terminal session service),
`@invariant` describing invariant conditions, `@precondition` and `@postcondition` for
pre/post conditions, `@complexity` indicating O(1) HTTP request, `@pure` false
annotation, and `@throws` documenting typed errors.

Source: Coding guidelines

🤖 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/api/openapi.ts`:
- Around line 487-490: The OpenAPI contract for the
endpoint.post("createProject") method documents successful creation responses
with the default 200 status code, but the actual API server returns 201
(Created) for create operations. Update all create-operation endpoint
definitions to specify status: 201 for the first addSuccess() call that returns
the ProjectResponseSchema or similar resource schemas. This includes not only
the createProject endpoint but also the other create operations at the mentioned
line ranges. Ensure the status code in the OpenAPI contract matches the actual
HTTP response status code returned by the server implementation.
- Around line 468-471: The ApiErrorResponseSchema does not match the actual
error response structure being returned by the errorResponse implementation in
packages/api/src/http.ts. Update the ApiErrorResponseSchema to reflect the
actual nested error object structure instead of treating error as a simple
string field. The schema should define error as a nested object that contains
properties like type, message, and optionally details, provider, and command,
rather than the current flat structure with error and message as direct string
properties.

In `@packages/api/tests/openapi.test.ts`:
- Around line 7-24: The test in the it.effect function only validates the
existence of paths and their count, but does not verify critical contract
details like response status codes (201/202) and the error response schema
structure. Extend the test to include assertions that check
paths["/projects"].post.responses["201"] exists and contains the correct
response definition, add similar checks for other create endpoints that should
return 201/202, and add assertions to verify components.schemas defines the
expected error envelope structure with nested error.type and error.message
properties.

In `@packages/app/src/web/api-auth-schema.ts`:
- Around line 26-37: The exported schemas CodexAuthStatusSchema and
CodexStatusResponseSchema lack required TSDoc documentation. Add comprehensive
TSDoc comments above both schema declarations with `@invariant`, `@precondition`,
and `@postcondition` annotations. Document the validation contracts for each
schema, including what fields are required versus optional, their expected
types, and any validation constraints. Since these are boundary schemas used for
API responses, clearly document the expected data structure and validation
guarantees that consumers can rely on.

In `@packages/app/src/web/api-create-project.ts`:
- Around line 7-21: The createProjectAcceptedBody function uses
CreateProjectDraft as its parameter type, but it is missing playwright resource
limit fields (playwrightCpuLimit and playwrightRamLimit) that are present in the
synchronous createProjectBody function for consistency. Change the parameter
type from CreateProjectDraft to CreateProjectRequestDraft and add the spread of
optionalProjectResourceFields(draft) into the return object body, similar to how
createProjectBody handles it, so that the async variant supports the same
playwright resource fields as the sync variant.

In `@packages/app/src/web/api-project-core.ts`:
- Around line 24-38: Extract the common project creation request body fields
that are duplicated between createProjectBody and createProjectAcceptedBody into
a shared baseCreateProjectBody helper function containing the common fields
(cpuLimit, enableMcpPlaywright, force, forceEnv, gpu, openSsh, outDir, ramLimit,
repoRef, repoUrl, up, useManagedAuthorizedKeys). Update createProjectBody in the
current file to spread baseCreateProjectBody(draft) and
optionalProjectResourceFields(draft), and update createProjectAcceptedBody in
api-create-project.ts to spread baseCreateProjectBody(draft) and async: true.
This eliminates duplication and prevents schema synchronization issues.

In `@packages/app/src/web/api-terminal.ts`:
- Around line 62-80: The functions loadProjectTerminalSessions and
loadProjectTerminalWorkspace both call the same endpoint with identical
parameters but intentionally return different response formats. Add descriptive
comments above each function explaining their distinct purposes:
loadProjectTerminalSessions extracts only the sessions array for UI list
display, while loadProjectTerminalWorkspace returns the complete response object
containing both activeSessionId and sessions for SSH-link initialization.
Additionally, consider renaming loadProjectTerminalSessions to
loadProjectTerminalSessionsList or similar to make the distinction in their
return types explicit and reduce confusion caused by the code duplication.
- Line 117: The deleteTerminalSessionByPath function currently uses a generic
requestText call with an arbitrary path string, but there are typed OpenAPI
endpoints available that should be used instead. The path parameter passed to
this function always follows one of two structured formats: either starting with
`/auth/terminal-sessions/` or `/projects/by-key/`. Refactor
deleteTerminalSessionByPath to parse the path string, extract the necessary
identifiers (sessionId for auth endpoints, and projectKey plus sessionId for
project endpoints), and delegate to the appropriate typed OpenAPI functions
(such as deleteAuthTerminalSession or deleteProjectTerminalSession) instead of
using the generic requestText approach. Alternatively, consider refactoring the
calling code to invoke these typed functions directly rather than routing
through deleteTerminalSessionByPath.

In `@packages/app/src/web/openapi-client.ts`:
- Around line 140-150: Refactor the openApiJson function to use Option type for
better functional semantics instead of undefined checks. Replace the direct
comparisons (error !== undefined and data === undefined) with
Option.fromNullable for both error and data values, then use Option.match to
handle the Some and None cases. This approach will make the nullable value
handling more explicit and align with functional programming patterns used in
the Effect library.
- Around line 91-106: The mutable global variable clientCache and the
getOpenApiClient function violate functional architecture principles by
maintaining implicit global state, making testing difficult and breaking
referential transparency. Either migrate to Effect Layer by creating a
DockerGitApiClient context tag with makeDockerGitApiClientLayer that manages the
client instance through Effect's dependency injection system instead of mutable
globals, or if that cannot be done immediately, add explicit comments
documenting that clientCache is a temporary limitation with TODO to migrate to
Effect Layer, and include notes about TESTABILITY requirements that tests must
reset state between runs.
- Around line 43-49: The safeJson function uses Effect.runSync which breaks
Effect-TS functional composition principles. Either refactor the function to
maintain full Effect composition by returning an Effect rather than executing it
synchronously, or if synchronous execution is necessary for the error rendering
use case, add explanatory comments above the function with the markers PURITY,
WHY, and INVARIANT to document why breaking composition is acceptable in this
specific non-critical path. Use the comment format provided in the review
suggestion to clearly justify the synchronous execution.

In `@scripts/write-openapi.ts`:
- Line 11: The Bun.write call for writing the OpenAPI specification file lacks
error handling for disk write failures such as permission denied or disk full
errors. Wrap the await Bun.write operation in a try/catch block to capture and
handle any errors that occur during the file write operation, ensuring the error
is properly logged and the process exits with an appropriate error code if the
write fails. Alternatively, apply the same Effect.catchAll pattern used in
http.ts to wrap the buildDockerGitOpenApi() call with error handling, or replace
Bun.write with fs.writeFileSync for synchronous error handling consistent with
other scripts in the project.

---

Outside diff comments:
In `@packages/app/src/web/api-terminal.ts`:
- Around line 1-118: Add comprehensive TSDoc documentation to all exported
terminal session functions (createProjectTerminalSession,
startProjectTerminalSession, createAuthTerminalSession,
deleteProjectTerminalSession, loadProjectTerminalSessions,
loadProjectTerminalWorkspace, setProjectActiveTerminalSession,
loadProjectTerminalSession, loadTerminalSessionById,
deleteTerminalSessionByPath) with required annotations. Each function must
include a description of its purpose, `@param` annotations for all parameters,
`@returns` describing the return Effect, `@effect` documenting dependencies on
external services (OpenAPI client, terminal session service), `@invariant`
describing invariant conditions, `@precondition` and `@postcondition` for pre/post
conditions, `@complexity` indicating O(1) HTTP request, `@pure` false annotation,
and `@throws` documenting typed errors.
🪄 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: c6c13a7f-0d41-410a-9cab-82c4db662ced

📥 Commits

Reviewing files that changed from the base of the PR and between 8c976d1 and 38cd8ea.

⛔ Files ignored due to path filters (2)
  • bun.lock is excluded by !**/*.lock
  • packages/app/src/web/generated/openapi-paths.ts is excluded by !**/generated/**
📒 Files selected for processing (21)
  • package.json
  • packages/api/openapi.json
  • packages/api/src/api/openapi.ts
  • packages/api/src/http.ts
  • packages/api/tests/openapi.test.ts
  • packages/app/biome.json
  • packages/app/eslint.config.mts
  • packages/app/package.json
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/api-create-project.ts
  • packages/app/src/web/api-database.ts
  • packages/app/src/web/api-project-core.ts
  • packages/app/src/web/api-prompts.ts
  • packages/app/src/web/api-schema.ts
  • packages/app/src/web/api-share.ts
  • packages/app/src/web/api-skills.ts
  • packages/app/src/web/api-tasks.ts
  • packages/app/src/web/api-terminal.ts
  • packages/app/src/web/api.ts
  • packages/app/src/web/openapi-client.ts
  • scripts/write-openapi.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 (Runtime volumes + SSH)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Clone auto-open SSH)
🧰 Additional context used
📓 Path-based instructions (11)
**/*

⚙️ CodeRabbit configuration file

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

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

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

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

Files:

  • packages/app/eslint.config.mts
  • package.json
  • packages/api/tests/openapi.test.ts
  • scripts/write-openapi.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/api-schema.ts
  • packages/app/biome.json
  • packages/app/src/web/api-share.ts
  • packages/app/src/web/api-prompts.ts
  • packages/app/src/web/api-create-project.ts
  • packages/app/src/web/api-terminal.ts
  • packages/app/src/web/api-tasks.ts
  • packages/app/src/web/api-skills.ts
  • packages/api/src/http.ts
  • packages/app/src/web/openapi-client.ts
  • packages/app/src/web/api-project-core.ts
  • packages/app/src/web/api-database.ts
  • packages/api/src/api/openapi.ts
  • packages/app/package.json
  • packages/app/src/web/api.ts
**

⚙️ CodeRabbit configuration file

**: РОЛЬ: Математик-программист, специализирующийся на формально верифицируемой функциональной архитектуре.

ЦЕЛЬ: Создавать математически доказуемые решения через функциональную парадигму с полным разделением чистых вычислений и контролируемых эффектов.

МОДЕЛЬ РАССУЖДЕНИЯ:

  • Не выдавать “личные мнения”. Формировать вывод как результат симуляции профессионального обсуждения релевантных ролей
    (архитектор Effect/FP, ревьюер типов, страж CORE↔SHELL, тест-инженер).
  • Если запрос сформулирован как “что думаешь”, отвечать в терминах аргументов ролей и выбирать решение
    по критериям инвариантов, типовой безопасности и тестируемости (если пользователь явно просит выбор — выбрать и обосновать).

ПРАВИЛО ПРОЦЕССА (НЕ ФОРМАТ ОТВЕТА):
В начале работы (внутренне) формулировать Deep Research вопрос:
"I am looking for code that does , is there existing code that can do this?"
Далее:

  • если доступен проект/код — сперва искать и переиспользовать существующие паттерны (минимальный корректный diff),
  • если проект недоступен — опираться на предоставленный контекст и явно фиксировать допущения,
  • код писать только после формального понимания задачи (типы/инварианты → архитектура → код → тесты),
  • источники указывать только если реально использован внешний материал; иначе SOURCE: n/a.

ИНСТРУМЕНТАЛЬНОЕ ПОВЕДЕНИЕ (ОБЯЗАТЕЛЬНО, НЕ ФОРМАТ ОТВЕТА):

  • Агент всегда использует доступные инструменты среды (терминал, поиск по проекту, запуск тестов/скриптов, анализ сборки, web-ресёрч при необходимости)
    для ресёрча, проверки гипотез и выполнения действий. Приоритет: проверяемость, воспроизводимость, минимальный риск.
  • Агент не предлагает “гайд” как замену действия. Если действие возможно выполнить инструментами — агент выполняет его сам,
    затем сообщает, что было сделано и как повторить.
  • Любые инструкции (команды/процедуры) агент даёт только после собственной проверки на доступной среде.
    Если проверить невозможно — явно фиксирует ограничение и перечисляе...

Files:

  • packages/app/eslint.config.mts
  • package.json
  • packages/api/tests/openapi.test.ts
  • scripts/write-openapi.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/api-schema.ts
  • packages/app/biome.json
  • packages/app/src/web/api-share.ts
  • packages/app/src/web/api-prompts.ts
  • packages/app/src/web/api-create-project.ts
  • packages/app/src/web/api-terminal.ts
  • packages/app/src/web/api-tasks.ts
  • packages/app/src/web/api-skills.ts
  • packages/api/src/http.ts
  • packages/app/src/web/openapi-client.ts
  • packages/app/src/web/api-project-core.ts
  • packages/app/src/web/api-database.ts
  • packages/api/src/api/openapi.ts
  • packages/app/package.json
  • packages/app/src/web/api.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:

  • package.json
  • packages/api/tests/openapi.test.ts
  • scripts/write-openapi.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/api-schema.ts
  • packages/app/biome.json
  • packages/app/src/web/api-share.ts
  • packages/app/src/web/api-prompts.ts
  • packages/app/src/web/api-create-project.ts
  • packages/app/src/web/api-terminal.ts
  • packages/app/src/web/api-tasks.ts
  • packages/app/src/web/api-skills.ts
  • packages/api/src/http.ts
  • packages/app/src/web/openapi-client.ts
  • packages/app/src/web/api-project-core.ts
  • packages/app/src/web/api-database.ts
  • packages/api/src/api/openapi.ts
  • packages/app/package.json
  • packages/app/src/web/api.ts
**/{package*.json,requirements*.txt,setup.py,setup.cfg,Pipfile,Pipfile.lock,pyproject.toml,pom.xml,build.gradle,Gemfile,Gemfile.lock,go.mod,go.sum,composer.json,Cargo.toml,Cargo.lock}

📄 CodeRabbit inference engine (Custom checks)

Fail if dependency or package-manager changes materially increase supply-chain risk without justification

Files:

  • package.json
  • packages/app/package.json
package.json

📄 CodeRabbit inference engine (AGENTS.md)

Dependencies must include effect ^3.x and @effect/schema ^0.x; prohibit downgrading these versions or introducing incompatible alternatives (async-only libraries without Effect support)

Require Effect and @effect/schema as mandatory dependencies for type-safe effects and validation

Files:

  • package.json
**/*.{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/openapi.test.ts
  • scripts/write-openapi.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/api-schema.ts
  • packages/app/src/web/api-share.ts
  • packages/app/src/web/api-prompts.ts
  • packages/app/src/web/api-create-project.ts
  • packages/app/src/web/api-terminal.ts
  • packages/app/src/web/api-tasks.ts
  • packages/app/src/web/api-skills.ts
  • packages/api/src/http.ts
  • packages/app/src/web/openapi-client.ts
  • packages/app/src/web/api-project-core.ts
  • packages/app/src/web/api-database.ts
  • packages/api/src/api/openapi.ts
  • packages/app/src/web/api.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/openapi.test.ts
  • scripts/write-openapi.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/api-schema.ts
  • packages/app/src/web/api-share.ts
  • packages/app/src/web/api-prompts.ts
  • packages/app/src/web/api-create-project.ts
  • packages/app/src/web/api-terminal.ts
  • packages/app/src/web/api-tasks.ts
  • packages/app/src/web/api-skills.ts
  • packages/api/src/http.ts
  • packages/app/src/web/openapi-client.ts
  • packages/app/src/web/api-project-core.ts
  • packages/app/src/web/api-database.ts
  • packages/api/src/api/openapi.ts
  • packages/app/src/web/api.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: FUNCTIONAL CORE: Write only pure functions with immutable data and mathematical operations in core modules; no side effects, mutations, or external service calls
IMPERATIVE SHELL: Isolate all side effects (IO, network, database, environment/process) in a thin SHELL layer; CORE never calls SHELL, only SHELL → CORE
Never use any type annotation in TypeScript; use unknown only at SHELL boundaries for decoding, never export unknown outside boundary modules
Never use as type assertions in normal code; only permit as in a single 'axiomatic' module (brands, constructors, constants) after which types flow safely without casts
Always use exhaustive pattern matching for union types through .exhaustive() or Match.exhaustive() from effect-ts; never use switch statements or unhandled type branches
Use Effect<Success, Error, Requirements> monad from effect-ts for all effects; compose through pipe() and Effect.flatMap(); never use async/await, raw Promise chains (then/catch), or Promise.all in product code
Interoperate with Promise/exceptions only in SHELL through Effect.try/Effect.tryPromise with typed error mapping; never leave raw exceptions or untyped errors in the domain
Use Effect.acquireRelease + Effect.scoped for resource management with guaranteed finalization; never manage resources with try/finally or manual cleanup
All external services (database, HTTP, environment) must be accessed through Effect-based interfaces and Layer-based dependency injection; never call external APIs directly
Provide comprehensive TSDoc comments with mathematical notation: @pure, @effect, @invariant, @precondition, @postcondition, @complexity, @throws, and CHANGE/WHY/REF/SOURCE/FORMAT THEOREM functional comment markers
No console.*, process direct calls, or untyped environment access in product code; all such operations must be abstracted through Layer-based services in SHELL
Boundary data from external sources (HTTP, database, environment) must be decoded/valida...

Files:

  • packages/api/tests/openapi.test.ts
  • scripts/write-openapi.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/api-schema.ts
  • packages/app/src/web/api-share.ts
  • packages/app/src/web/api-prompts.ts
  • packages/app/src/web/api-create-project.ts
  • packages/app/src/web/api-terminal.ts
  • packages/app/src/web/api-tasks.ts
  • packages/app/src/web/api-skills.ts
  • packages/api/src/http.ts
  • packages/app/src/web/openapi-client.ts
  • packages/app/src/web/api-project-core.ts
  • packages/app/src/web/api-database.ts
  • packages/api/src/api/openapi.ts
  • packages/app/src/web/api.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.{ts,tsx}: Write property-based tests using fast-check (fc.property) to verify mathematical invariants; unit tests must use Effect test utilities without async/await
Every bug fix must be accompanied by a reproducing test case; the test must fail before the fix and pass after; document the Proof of Fix with root cause and solution

Files:

  • packages/api/tests/openapi.test.ts
**/{browser*,server*,app*,*.ts,*.js}

📄 CodeRabbit inference engine (README.md)

Web version must listen on 0.0.0.0 by default for accessibility across LAN devices

Files:

  • packages/api/tests/openapi.test.ts
  • scripts/write-openapi.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/api-schema.ts
  • packages/app/src/web/api-share.ts
  • packages/app/src/web/api-prompts.ts
  • packages/app/src/web/api-create-project.ts
  • packages/app/src/web/api-terminal.ts
  • packages/app/src/web/api-tasks.ts
  • packages/app/src/web/api-skills.ts
  • packages/api/src/http.ts
  • packages/app/src/web/openapi-client.ts
  • packages/app/src/web/api-project-core.ts
  • packages/app/src/web/api-database.ts
  • packages/api/src/api/openapi.ts
  • packages/app/src/web/api.ts
**/{cli*,command*,auto*,*.ts,*.tsx}

📄 CodeRabbit inference engine (README.md)

Implement auto-mode agent selection logic to choose Claude, Codex, Gemini, or Grok randomly from available authorized providers, or allow forced selection with --auto=

Files:

  • packages/api/tests/openapi.test.ts
  • scripts/write-openapi.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/api-schema.ts
  • packages/app/src/web/api-share.ts
  • packages/app/src/web/api-prompts.ts
  • packages/app/src/web/api-create-project.ts
  • packages/app/src/web/api-terminal.ts
  • packages/app/src/web/api-tasks.ts
  • packages/app/src/web/api-skills.ts
  • packages/api/src/http.ts
  • packages/app/src/web/openapi-client.ts
  • packages/app/src/web/api-project-core.ts
  • packages/app/src/web/api-database.ts
  • packages/api/src/api/openapi.ts
  • packages/app/src/web/api.ts
🔇 Additional comments (26)
packages/app/src/web/api-project-core.ts (2)

40-107: LGTM!


6-22: LGTM!

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

23-27: LGTM!

scripts/write-openapi.ts (1)

1-9: LGTM!

packages/app/package.json (2)

21-21: LGTM!


82-84: @effect/schema присутствует в зависимостях с правильной версией.

Проверка подтверждает, что @effect/schema включён в packages/app/package.json с версией ^0.75.5, что соответствует обязательному требованию ^0.x. Наряду с effect ^3.21.3, обе критические зависимости архитектуры присутствуют и корректно версионированы.

package.json (1)

45-45: LGTM!

packages/app/biome.json (1)

9-10: LGTM!

packages/app/eslint.config.mts (1)

307-307: LGTM!

packages/app/src/web/openapi-client.ts (6)

1-30: LGTM!


31-35: LGTM!


64-80: LGTM!


108-114: LGTM!


152-189: LGTM!


191-224: LGTM!

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

11-37: LGTM!

Also applies to: 45-121

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

5-37: LGTM!

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

5-5: LGTM!

Also applies to: 20-54

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

4-40: LGTM!

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

4-4: LGTM!

Also applies to: 28-29, 54-59, 83-84

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

8-9: LGTM!

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

59-70: LGTM!


114-124: LGTM!


259-287: LGTM!


241-245: Отбрасывание ответа в logoutCodex корректно и намеренно.

Функция используется в паттерне logoutCodex(...).pipe(Effect.zipRight(loadAuthState)), где Effect.zipRight явно отбрасывает результат левого эффекта и сохраняет результат правого. Таким образом, Effect.asVoid — это правильное выражение намерения: logout-операция выполняется только для стороны-эффекта (HTTP POST), а результат декодирования не требуется вызывающему коду.

Кроме того, logoutCodex — единственная logout-функция в файле; других logout-функций для сравнения не существует.


179-187: Преобразование String(targetPort) на строке 185 корректно и необходимо.

Проверка OpenAPI-схемы подтверждает: параметр пути определён как Schema.NumberFromString (строка на входе, автоматическое преобразование в число). Клиент передаёт number, конвертирует в string для path-параметра, затем схема декодирует обратно в number для сервиса. Тип-flow согласован и безопасен.

Comment thread packages/api/src/api/openapi.ts
Comment thread packages/api/src/api/openapi.ts
Comment thread packages/api/tests/openapi.test.ts
Comment thread packages/app/src/web/api-auth-schema.ts
Comment thread packages/app/src/web/api-create-project.ts Outdated
Comment thread packages/app/src/web/api-terminal.ts Outdated
Comment thread packages/app/src/web/openapi-client.ts Outdated
Comment thread packages/app/src/web/openapi-client.ts Outdated
Comment thread packages/app/src/web/openapi-client.ts Outdated
Comment thread scripts/write-openapi.ts Outdated
@skulidropek

skulidropek commented Jun 18, 2026

Copy link
Copy Markdown
Member Author

AI Session Backup

Commit: 68a1d56
Status: success
Files: 15 (15.84 MB)
Links: README | Manifest

git status

On branch codex/openapi-fetch-effect-api
Your branch is up to date with 'origin/codex/openapi-fetch-effect-api'.

nothing to commit, working tree clean

@skulidropek

skulidropek commented Jun 18, 2026

Copy link
Copy Markdown
Member Author

AI Session Backup

Commit: 5ca3d90
Status: success
Files: 15 (16.91 MB)
Links: README | Manifest

git status

On branch codex/openapi-fetch-effect-api
Your branch is up to date with 'origin/codex/openapi-fetch-effect-api'.

nothing to commit, working tree clean

@skulidropek

skulidropek commented Jun 18, 2026

Copy link
Copy Markdown
Member Author

AI Session Backup

Commit: c4f39e5
Status: success
Files: 15 (17.10 MB)
Links: README | Manifest

git status

On branch codex/openapi-fetch-effect-api
Your branch is up to date with 'origin/codex/openapi-fetch-effect-api'.

nothing to commit, working tree clean

@skulidropek

skulidropek commented Jun 18, 2026

Copy link
Copy Markdown
Member Author

AI Session Backup

Commit: f1b607c
Status: success
Files: 15 (17.46 MB)
Links: README | Manifest

git status

On branch codex/openapi-fetch-effect-api
Your branch is up to date with 'origin/codex/openapi-fetch-effect-api'.

nothing to commit, working tree clean

@skulidropek

skulidropek commented Jun 18, 2026

Copy link
Copy Markdown
Member Author

AI Session Backup

Commit: a09a3ab
Status: success
Files: 15 (17.52 MB)
Links: README | Manifest

git status

On branch codex/openapi-fetch-effect-api
Your branch is up to date with 'origin/codex/openapi-fetch-effect-api'.

nothing to commit, working tree clean

@skulidropek

skulidropek commented Jun 18, 2026

Copy link
Copy Markdown
Member Author

AI Session Backup

Commit: a0f08e5
Status: success
Files: 16 (19.02 MB)
Links: README | Manifest

git status

On branch codex/openapi-fetch-effect-api
Your branch is up to date with 'origin/codex/openapi-fetch-effect-api'.

nothing to commit, working tree clean

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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/tests/openapi.test.ts`:
- Around line 29-151: The test cases in this file (such as "documents real HTTP
success status codes for create and async endpoints", "documents common API
error statuses for every JSON REST operation", and others) currently only verify
hardcoded path examples against the OpenAPI specification. Per coding guidelines
for *.test.ts files, these tests should use property-based testing with
fast-check's fc.property to verify that the documented invariants (correct
status codes, error envelopes, required fields, response schemas) hold across
arbitrary paths and operations rather than just fixed examples. Refactor the
existing individual it.effect test blocks to use fc.property to generate test
cases dynamically and ensure that regressions across a broader set of paths and
operations would be caught.

In `@packages/app/package.json`:
- Around line 98-99: The package `@prover-coder-ai/docker-git-openapi` is
currently listed in devDependencies but is actually used at runtime in the
application (imported in openapi-client.ts and transitively used in multiple API
modules). Move the `@prover-coder-ai/docker-git-openapi` entry from the
devDependencies section to the dependencies section in packages/app/package.json
to ensure it is properly installed during production builds and avoid runtime
Cannot find module errors when accessing web-API endpoints.

In `@packages/app/src/web/api-create-project.ts`:
- Around line 26-30: The exported function `createProjectAcceptedBody` currently
relies on type inference for its return type instead of explicitly annotating
it. Add an explicit return type annotation to the function signature that
describes the shape of the object being returned, which contains the spread of
baseCreateProjectBody result, the async boolean property set to true, and the
spread of optionalProjectResourceFields result. This ensures the public API
signature complies with the requirement to explicitly type all function return
types without relying on inference.

In `@packages/app/src/web/api-project-create-body.ts`:
- Around line 31-34: The exported functions optionalProjectResourceFields and
baseCreateProjectBody are missing explicit return type annotations on their
public API signatures, which violates TypeScript guidelines. Add explicit return
type annotations to both functions: optionalProjectResourceFields should return
a Readonly object with resource limit fields, and baseCreateProjectBody should
return a Readonly object containing displayName, description, and resourceLimits
properties. Ensure the return types are clearly defined for both the object
structure and any nested properties.

In `@packages/app/src/web/openapi-client.ts`:
- Line 20: The public export aliases openApiJson at line 20 and the two other
exports at lines 33 and 46 are relying on implicit type inference from
openApiRuntime instead of explicitly declaring their types. Add explicit type
annotations to all three exports by specifying the actual type for each one
(e.g., use typeof assertions or explicit type declarations) rather than allowing
TypeScript to infer the types from the openApiRuntime object assignments. This
ensures the module contract remains stable and does not drift when
openApiRuntime implementation changes.

In `@packages/app/tests/docker-git/api-create-project.test.ts`:
- Around line 23-42: The test in the it.effect block for "serializes async
create requests with Playwright resource limits" uses only a single concrete
example instead of property-based testing. Convert this test to use fc.property
(from fast-check) to verify the invariants: that async is always true, openSsh
is always false, useManagedAuthorizedKeys is always true, and that
playwright-related fields (playwrightCpuLimit, playwrightRamLimit) are only
present when they are defined in the CreateProjectRequestDraft. Use Effect
utilities to integrate this property-based test with the existing Effect.sync
structure while maintaining the same assertions about the
createProjectAcceptedBody return value.

In `@packages/app/tests/docker-git/api-terminal.test.ts`:
- Around line 77-83: The test in the it.effect block only validates that the
result is a Left (failure) and no requests were captured, but does not verify
the actual error message content. Enhance the test by extracting the error from
the Left case of the result and adding an expectation to validate that the error
message contains relevant information about why the invalid path was rejected.
This ensures the deleteTerminalSessionByPath function is rejecting the
unsupported terminal close path for the correct reason, not just any failure.
🪄 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: 63e70cb6-3f0a-49a3-9e19-38b3562fe9d4

📥 Commits

Reviewing files that changed from the base of the PR and between 38cd8ea and a0f08e5.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (24)
  • package.json
  • packages/api/Dockerfile
  • packages/api/package.json
  • packages/api/src/api/openapi.ts
  • packages/api/tests/openapi.test.ts
  • packages/app/biome.json
  • packages/app/package.json
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/api-create-project.ts
  • packages/app/src/web/api-project-core.ts
  • packages/app/src/web/api-project-create-body.ts
  • packages/app/src/web/api-terminal.ts
  • packages/app/src/web/api.ts
  • packages/app/src/web/openapi-client.ts
  • packages/app/tests/docker-git/api-create-project.test.ts
  • packages/app/tests/docker-git/api-terminal.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • packages/openapi/openapi.json
  • packages/openapi/package.json
  • packages/openapi/src/client.ts
  • packages/openapi/src/index.ts
  • packages/openapi/src/openapi-paths.ts
  • packages/openapi/tsconfig.json
  • scripts/write-openapi.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). (8)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Login context)
  • GitHub Check: Lint
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (Browser command)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: Test
🧰 Additional context used
📓 Path-based instructions (12)
**/*.{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/openapi/src/index.ts
  • packages/app/tests/docker-git/api-create-project.test.ts
  • packages/app/src/web/api-project-create-body.ts
  • packages/app/tests/docker-git/api-terminal.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • scripts/write-openapi.ts
  • packages/app/src/web/openapi-client.ts
  • packages/app/src/web/api-create-project.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/api-project-core.ts
  • packages/app/src/web/api.ts
  • packages/app/src/web/api-terminal.ts
  • packages/api/tests/openapi.test.ts
  • packages/openapi/src/client.ts
  • packages/api/src/api/openapi.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/openapi/src/index.ts
  • packages/app/tests/docker-git/api-create-project.test.ts
  • packages/app/src/web/api-project-create-body.ts
  • packages/app/tests/docker-git/api-terminal.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • scripts/write-openapi.ts
  • packages/app/src/web/openapi-client.ts
  • packages/app/src/web/api-create-project.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/api-project-core.ts
  • packages/app/src/web/api.ts
  • packages/app/src/web/api-terminal.ts
  • packages/api/tests/openapi.test.ts
  • packages/openapi/src/client.ts
  • packages/api/src/api/openapi.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/openapi/src/index.ts
  • packages/app/tests/docker-git/api-create-project.test.ts
  • packages/api/package.json
  • packages/openapi/tsconfig.json
  • packages/app/biome.json
  • packages/app/src/web/api-project-create-body.ts
  • packages/app/tests/docker-git/api-terminal.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • packages/openapi/package.json
  • scripts/write-openapi.ts
  • packages/app/src/web/openapi-client.ts
  • packages/app/src/web/api-create-project.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/package.json
  • packages/app/src/web/api-project-core.ts
  • packages/app/src/web/api.ts
  • packages/app/src/web/api-terminal.ts
  • packages/api/tests/openapi.test.ts
  • package.json
  • packages/openapi/src/client.ts
  • packages/api/src/api/openapi.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: FUNCTIONAL CORE: Write only pure functions with immutable data and mathematical operations in core modules; no side effects, mutations, or external service calls
IMPERATIVE SHELL: Isolate all side effects (IO, network, database, environment/process) in a thin SHELL layer; CORE never calls SHELL, only SHELL → CORE
Never use any type annotation in TypeScript; use unknown only at SHELL boundaries for decoding, never export unknown outside boundary modules
Never use as type assertions in normal code; only permit as in a single 'axiomatic' module (brands, constructors, constants) after which types flow safely without casts
Always use exhaustive pattern matching for union types through .exhaustive() or Match.exhaustive() from effect-ts; never use switch statements or unhandled type branches
Use Effect<Success, Error, Requirements> monad from effect-ts for all effects; compose through pipe() and Effect.flatMap(); never use async/await, raw Promise chains (then/catch), or Promise.all in product code
Interoperate with Promise/exceptions only in SHELL through Effect.try/Effect.tryPromise with typed error mapping; never leave raw exceptions or untyped errors in the domain
Use Effect.acquireRelease + Effect.scoped for resource management with guaranteed finalization; never manage resources with try/finally or manual cleanup
All external services (database, HTTP, environment) must be accessed through Effect-based interfaces and Layer-based dependency injection; never call external APIs directly
Provide comprehensive TSDoc comments with mathematical notation: @pure, @effect, @invariant, @precondition, @postcondition, @complexity, @throws, and CHANGE/WHY/REF/SOURCE/FORMAT THEOREM functional comment markers
No console.*, process direct calls, or untyped environment access in product code; all such operations must be abstracted through Layer-based services in SHELL
Boundary data from external sources (HTTP, database, environment) must be decoded/valida...

Files:

  • packages/openapi/src/index.ts
  • packages/app/tests/docker-git/api-create-project.test.ts
  • packages/app/src/web/api-project-create-body.ts
  • packages/app/tests/docker-git/api-terminal.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • scripts/write-openapi.ts
  • packages/app/src/web/openapi-client.ts
  • packages/app/src/web/api-create-project.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/api-project-core.ts
  • packages/app/src/web/api.ts
  • packages/app/src/web/api-terminal.ts
  • packages/api/tests/openapi.test.ts
  • packages/openapi/src/client.ts
  • packages/api/src/api/openapi.ts
**/{browser*,server*,app*,*.ts,*.js}

📄 CodeRabbit inference engine (README.md)

Web version must listen on 0.0.0.0 by default for accessibility across LAN devices

Files:

  • packages/openapi/src/index.ts
  • packages/app/tests/docker-git/api-create-project.test.ts
  • packages/app/src/web/api-project-create-body.ts
  • packages/app/tests/docker-git/api-terminal.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • scripts/write-openapi.ts
  • packages/app/src/web/openapi-client.ts
  • packages/app/src/web/api-create-project.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/api-project-core.ts
  • packages/app/src/web/api.ts
  • packages/app/src/web/api-terminal.ts
  • packages/api/tests/openapi.test.ts
  • packages/openapi/src/client.ts
  • packages/api/src/api/openapi.ts
**/{cli*,command*,auto*,*.ts,*.tsx}

📄 CodeRabbit inference engine (README.md)

Implement auto-mode agent selection logic to choose Claude, Codex, Gemini, or Grok randomly from available authorized providers, or allow forced selection with --auto=

Files:

  • packages/openapi/src/index.ts
  • packages/app/tests/docker-git/api-create-project.test.ts
  • packages/app/src/web/api-project-create-body.ts
  • packages/app/tests/docker-git/api-terminal.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • scripts/write-openapi.ts
  • packages/app/src/web/openapi-client.ts
  • packages/app/src/web/api-create-project.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/api-project-core.ts
  • packages/app/src/web/api.ts
  • packages/app/src/web/api-terminal.ts
  • packages/api/tests/openapi.test.ts
  • packages/openapi/src/client.ts
  • packages/api/src/api/openapi.ts
**/*

⚙️ CodeRabbit configuration file

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

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

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

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

Files:

  • packages/openapi/src/index.ts
  • packages/app/tests/docker-git/api-create-project.test.ts
  • packages/api/package.json
  • packages/openapi/tsconfig.json
  • packages/app/biome.json
  • packages/app/src/web/api-project-create-body.ts
  • packages/app/tests/docker-git/api-terminal.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • packages/openapi/package.json
  • scripts/write-openapi.ts
  • packages/app/src/web/openapi-client.ts
  • packages/api/Dockerfile
  • packages/app/src/web/api-create-project.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/package.json
  • packages/app/src/web/api-project-core.ts
  • packages/app/src/web/api.ts
  • packages/app/src/web/api-terminal.ts
  • packages/api/tests/openapi.test.ts
  • package.json
  • packages/openapi/src/client.ts
  • packages/api/src/api/openapi.ts
**

⚙️ CodeRabbit configuration file

**: РОЛЬ: Математик-программист, специализирующийся на формально верифицируемой функциональной архитектуре.

ЦЕЛЬ: Создавать математически доказуемые решения через функциональную парадигму с полным разделением чистых вычислений и контролируемых эффектов.

МОДЕЛЬ РАССУЖДЕНИЯ:

  • Не выдавать “личные мнения”. Формировать вывод как результат симуляции профессионального обсуждения релевантных ролей
    (архитектор Effect/FP, ревьюер типов, страж CORE↔SHELL, тест-инженер).
  • Если запрос сформулирован как “что думаешь”, отвечать в терминах аргументов ролей и выбирать решение
    по критериям инвариантов, типовой безопасности и тестируемости (если пользователь явно просит выбор — выбрать и обосновать).

ПРАВИЛО ПРОЦЕССА (НЕ ФОРМАТ ОТВЕТА):
В начале работы (внутренне) формулировать Deep Research вопрос:
"I am looking for code that does , is there existing code that can do this?"
Далее:

  • если доступен проект/код — сперва искать и переиспользовать существующие паттерны (минимальный корректный diff),
  • если проект недоступен — опираться на предоставленный контекст и явно фиксировать допущения,
  • код писать только после формального понимания задачи (типы/инварианты → архитектура → код → тесты),
  • источники указывать только если реально использован внешний материал; иначе SOURCE: n/a.

ИНСТРУМЕНТАЛЬНОЕ ПОВЕДЕНИЕ (ОБЯЗАТЕЛЬНО, НЕ ФОРМАТ ОТВЕТА):

  • Агент всегда использует доступные инструменты среды (терминал, поиск по проекту, запуск тестов/скриптов, анализ сборки, web-ресёрч при необходимости)
    для ресёрча, проверки гипотез и выполнения действий. Приоритет: проверяемость, воспроизводимость, минимальный риск.
  • Агент не предлагает “гайд” как замену действия. Если действие возможно выполнить инструментами — агент выполняет его сам,
    затем сообщает, что было сделано и как повторить.
  • Любые инструкции (команды/процедуры) агент даёт только после собственной проверки на доступной среде.
    Если проверить невозможно — явно фиксирует ограничение и перечисляе...

Files:

  • packages/openapi/src/index.ts
  • packages/app/tests/docker-git/api-create-project.test.ts
  • packages/api/package.json
  • packages/openapi/tsconfig.json
  • packages/app/biome.json
  • packages/app/src/web/api-project-create-body.ts
  • packages/app/tests/docker-git/api-terminal.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • packages/openapi/package.json
  • scripts/write-openapi.ts
  • packages/app/src/web/openapi-client.ts
  • packages/api/Dockerfile
  • packages/app/src/web/api-create-project.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/package.json
  • packages/app/src/web/api-project-core.ts
  • packages/app/src/web/api.ts
  • packages/app/src/web/api-terminal.ts
  • packages/api/tests/openapi.test.ts
  • package.json
  • packages/openapi/src/client.ts
  • packages/api/src/api/openapi.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.{ts,tsx}: Write property-based tests using fast-check (fc.property) to verify mathematical invariants; unit tests must use Effect test utilities without async/await
Every bug fix must be accompanied by a reproducing test case; the test must fail before the fix and pass after; document the Proof of Fix with root cause and solution

Files:

  • packages/app/tests/docker-git/api-create-project.test.ts
  • packages/app/tests/docker-git/api-terminal.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • packages/api/tests/openapi.test.ts
**/{package*.json,requirements*.txt,setup.py,setup.cfg,Pipfile,Pipfile.lock,pyproject.toml,pom.xml,build.gradle,Gemfile,Gemfile.lock,go.mod,go.sum,composer.json,Cargo.toml,Cargo.lock}

📄 CodeRabbit inference engine (Custom checks)

Fail if dependency or package-manager changes materially increase supply-chain risk without justification

Files:

  • packages/api/package.json
  • packages/openapi/package.json
  • packages/app/package.json
  • package.json
**/{Dockerfile*,docker-compose*.{yml,yaml},.dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce unsafe Docker configuration such as privileged containers, broad host mounts, unbounded Docker socket access, or unnecessary write permissions

Files:

  • packages/api/Dockerfile
package.json

📄 CodeRabbit inference engine (AGENTS.md)

Dependencies must include effect ^3.x and @effect/schema ^0.x; prohibit downgrading these versions or introducing incompatible alternatives (async-only libraries without Effect support)

Require Effect and @effect/schema as mandatory dependencies for type-safe effects and validation

Files:

  • package.json
🧠 Learnings (1)
📚 Learning: 2026-06-10T10:21:51.286Z
Learnt from: konard
Repo: ProverCoderAI/docker-git PR: 386
File: packages/app/tests/docker-git/gridland-react-singleton.test.ts:0-0
Timestamp: 2026-06-10T10:21:51.286Z
Learning: In `packages/app/tests/docker-git` tests that inspect the `packages/terminal` workspace (e.g., for React-related versions), remember that `react-dom` is intentionally declared as a `devDependency` in `packages/terminal` (the terminal exports components but does not render to the DOM itself). Therefore, test assertions should not require `react-dom` to appear in `dependencies`; when resolving versions, accept either `dependencies` or `devDependencies` (as `resolveDepVersion` does in `gridland-react-singleton.test.ts`).

Applied to files:

  • packages/app/tests/docker-git/api-create-project.test.ts
  • packages/app/tests/docker-git/api-terminal.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
🪛 OpenGrep (1.22.0)
packages/app/src/web/api-terminal.ts

[ERROR] 172-172: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)


[ERROR] 177-177: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)

🔇 Additional comments (16)
packages/app/src/web/api-auth-schema.ts (1)

26-36: LGTM!

Also applies to: 45-55

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

61-66: LGTM!


68-69: LGTM!


81-82: LGTM!


127-183: Статический анализ — ложное срабатывание: это RegExp.exec(), а не child_process.exec().

OpenGrep ошибочно флагает строки 172 и 177 как command injection. Однако здесь используется RegExp.prototype.exec() для матчинга путей по константным паттернам, а не child_process.exec() для выполнения команд.

Реализация корректна:

  • Паттерны authTerminalClosePathPattern и projectTerminalClosePathPattern — иммутабельные константы с флагом u для Unicode
  • Effect.try правильно обрабатывает ошибки decodeURIComponent
  • Композиция через Effect.flatMap и Effect.all соответствует паттернам SHELL-слоя

Source: Linters/SAST tools

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

62-62: LGTM!

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

1-44: LGTM!

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

3-13: LGTM!

Also applies to: 22-25

packages/openapi/package.json (1)

35-36: Версии TypeScript и зависимостей согласованы — проблем не выявлено.

Проверка всех workspace-пакетов подтвердила, что packages/openapi/package.json использует те же версии, что и остальная монorepo:

  • typescript: ^6.0.3 — единый диапазон для всех пакетов
  • effect: ^3.21.3 — единый диапазон для всех пакетов
  • @effect/schema: ^0.75.5 — единый диапазон для всех пакетов

Toolchain консистентен; supply-chain риск не повышен.

packages/openapi/src/client.ts (1)

87-95: Middleware cache-busting безопасен: query-параметры игнорируются сервером.

Проверка показала, что GET endpoint-ы используют query-параметры (например, /auth/grok/status?label=..., /projects/{projectId}/tasks?lines=...), однако все query-схемы определены через Schema.Struct без forbiddenProperties. По умолчанию @effect/platform HttpApi игнорирует неизвестные параметры при декодировании, поэтому дополнительный параметр _=<timestamp> (строка 93) не вызывает валидационных ошибок (400). Риск, описанный в комментарии, не актуален для данной архитектуры.

			> Likely an incorrect or invalid review comment.
packages/openapi/src/index.ts (1)

1-2: LGTM!

package.json (1)

13-13: LGTM!

Also applies to: 24-24, 46-54

packages/app/package.json (1)

21-21: LGTM!

scripts/write-openapi.ts (1)

9-23: LGTM!

packages/api/Dockerfile (1)

79-85: LGTM!

packages/api/package.json (1)

19-19: LGTM!

Comment thread packages/api/tests/openapi.test.ts
Comment thread packages/app/package.json Outdated
Comment thread packages/app/src/web/api-create-project.ts Outdated
Comment thread packages/app/src/web/api-project-create-body.ts Outdated
Comment thread packages/app/src/web/openapi-client.ts Outdated
Comment thread packages/app/tests/docker-git/api-create-project.test.ts
Comment thread packages/app/tests/docker-git/api-terminal.test.ts
@skulidropek

skulidropek commented Jun 18, 2026

Copy link
Copy Markdown
Member Author

AI Session Backup

Commit: f25cc5e
Status: success
Files: 16 (19.55 MB)
Links: README | Manifest

git status

On branch codex/openapi-fetch-effect-api
Your branch is up to date with 'origin/codex/openapi-fetch-effect-api'.

nothing to commit, working tree clean

@skulidropek

skulidropek commented Jun 18, 2026

Copy link
Copy Markdown
Member Author

AI Session Backup

Commit: 7b96e06
Status: success
Files: 16 (19.66 MB)
Links: README | Manifest

git status

On branch codex/openapi-fetch-effect-api
Your branch is up to date with 'origin/codex/openapi-fetch-effect-api'.

nothing to commit, working tree clean

@skulidropek skulidropek marked this pull request as ready for review June 19, 2026 07:32
@skulidropek skulidropek merged commit 1fcedd3 into main Jun 19, 2026
18 of 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