Skip to content

fix(api): mount host docker data for skiller#366

Merged
skulidropek merged 6 commits into
mainfrom
issue-365
Jun 3, 2026
Merged

fix(api): mount host docker data for skiller#366
skulidropek merged 6 commits into
mainfrom
issue-365

Conversation

@skulidropek
Copy link
Copy Markdown
Member

@skulidropek skulidropek commented Jun 3, 2026

Source TZ / Issues

Summary

  • Bind host /var/lib/docker into the default host-mode controller so Skiller can access Docker volume paths returned by docker inspect.
  • Keep isolated runtime on the private docker_git_docker_data volume.
  • Document the host runtime contract and add compose regression coverage.

Requirements Alignment

  • Implemented: host runtime exposes host Docker volume paths to the controller; isolated runtime keeps embedded Docker data isolated; compose/docs/tests updated.
  • Out of scope: frontend Skiller button behavior and Skiller app internals.
  • Security-sensitive changes: host runtime now explicitly bind-mounts /var/lib/docker, matching its existing host Docker socket access model.

Verification

  • bun --cwd packages/app vitest run tests/docker-git/controller-resource-limits.test.ts
  • bun --cwd packages/api vitest run tests/skiller-core.test.ts
  • bun run --cwd packages/app test -- tests/docker-git/controller-resource-limits.test.ts
  • bun run --cwd packages/api test -- tests/skiller-core.test.ts
  • bun run test
  • git diff --check
  • docker compose config for host and isolated volume resolution

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 3, 2026

Review Change Stack

Warning

Review limit reached

@skulidropek, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 35 minutes and 18 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 91d6c9db-058a-4f33-8a69-a848fe7f557b

📥 Commits

Reviewing files that changed from the base of the PR and between f5cdf39 and 61ec4a9.

📒 Files selected for processing (2)
  • packages/api/src/services/skiller.ts
  • packages/api/tests/skiller-routes.test.ts
📝 Walkthrough

Walkthrough

Конфигурации API-контейнера переключены на bind-mount для /var/lib/docker; README и фикстура обновлены; Dockerfile материализует Electron-бинарник в сборке; Skiller получил рефактор подготовки runtime, экспорт типов и новую генерацию команды запуска; добавлены соответствующие тесты.

Изменения

Миграция на bind-mount и обновление Skiller

Layer / File(s) Summary
Конфигурация bind-mount в docker-compose
docker-compose.yml, docker-compose.api.yml
В services.api.volumes заменено монтирование /var/lib/docker с именованного volume docker_git_docker_data на прямой bind-mount /var/lib/docker:/var/lib/docker.
Документация, фикстура и проверки compose режимов
packages/api/README.md, docs/pr-screenshots/issue-365/skiller-projects-after-click.json, packages/app/tests/docker-git/controller-resource-limits.test.ts
README уточнён о монтировании Docker data root; добавлена JSON-фикстура; в тесты добавлены константы и assertions, проверяющие bind-mount в обычном режиме и named-volume в изолированном режиме.
Dockerfile: материализация Electron в билде
packages/api/Dockerfile, packages/app/tests/docker-git/controller-resource-limits.test.ts
Добавлен блок сборки: поиск electron-v*-linux-*.zip в кеше, валидация содержимого, очистка старых артефактов, распаковка в node_modules/electron/dist, запись path.txt и проверка исполняемости бинарника; тесты проверяют наличие этой логики.
Skiller: подготовка runtime и команда запуска
packages/api/src/services/skiller.ts
Добавлены импорт SpawnOptions/runProcess, экспортируемые типы SkillerProcessUser и SkillerLaunchCommand, prepareLaunchScript, расширение skillerHomeEnv, helper'ы для прав/директорий, обновлён prepareSkillerScopeHome, реализовано разрешение и создание локальных аккаунтов и экспорт skillerLaunchCommand; launchSkillerProcess переписан в async и использует новые команды/env.
Тесты Skiller
packages/api/tests/skiller-routes.test.ts
Добавлен импорт skillerLaunchCommand и тесты, проверяющие формирование команды запуска Electron и scoped-запуска через runuser.

Sequence Diagram(s)

sequenceDiagram
  participant openSkiller
  participant prepareSkillerScopeHome
  participant prepareSkillerRuntime
  participant spawnProcess
  openSkiller->>prepareSkillerScopeHome: ensure scope dirs & ownership
  prepareSkillerScopeHome->>prepareSkillerRuntime: provide runtimeRoot & env
  prepareSkillerRuntime->>spawnProcess: run prepareLaunchScript / materialize
  openSkiller->>spawnProcess: launchSkillerProcess uses skillerLaunchCommand + env
Loading

🎯 3 (Moderate) | ⏱️ ~20 minutes

Возможные связанные PRs:

  • ProverCoderAI/docker-git#344: изменения в materialization Electron в packages/api/Dockerfile, пересекающиеся с текущими изменениями этапа skiller-build.

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 выполнены: mount /var/lib/docker, документация, тесты. Но проигнорировано критическое замечание о таймауте в runProcess для bun install/build. Добавить timeout в runProcess с setTimeout/AbortSignal для контроля времени выполнения дочерних процессов, как предложено в review comment.
✅ Passed checks (6 passed)
Check name Status Explanation
Title check ✅ Passed Заголовок ясно описывает основное изменение: привязка Docker-данных хоста для Skiller, что соответствует основной цели PR.
Description check ✅ Passed Описание содержит все требуемые разделы шаблона: Source TZ/Issues, Summary, Requirements Alignment и Verification с подробными шагами проверки.
Linked Issues check ✅ Passed Изменения соответствуют целям issue #365: привязка /var/lib/docker в host-режиме, документирование контракта runtime, добавление тестового покрытия и поддержка scoped запусков Skiller.
Out of Scope Changes check ✅ Passed Все изменения соответствуют целям: Docker Compose конфигурация, документация, тесты, Dockerfile и логика запуска Skiller; нет посторонних изменений.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Security Regression ✅ Passed No security regressions. Bind-mount consistent with host access. Electron zips validated. Safe spawn arg arrays. UID/GID from stats with deterministic names.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-365

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
Copy link
Copy Markdown
Member Author

Скриншоты работы приложения для issue #365. Это не CI и не файлы: кадры сняты с web UI после реального CDP click по кнопке Skiller.

Проверка в proof-среде:

  • POST /api/projects/by-key/53a9af0e027e/terminal-sessions/15aca7aa-9b45-4845-8872-0dba1f0ff8bb/skiller/open -> 202 Accepted
  • /api/ssh/session/15aca7aa-9b45-4845-8872-0dba1f0ff8bb/skiller/app/ -> 200, assets загружены
  • /api/ssh/session/15aca7aa-9b45-4845-8872-0dba1f0ff8bb/skiller/trpc/get_app_version -> 200
  1. Terminal UI: кнопка Skiller видна рядом с Open browser.

01 before Skiller

  1. Кнопка Skiller нажимается. Красный marker добавлен поверх кадра, потому что headless Chrome screenshots не рисуют курсор; в этот момент был отправлен Input.dispatchMouseEvent(mousePressed).

02 Skiller mouse down

  1. После отпускания кнопки backend принял open-запрос (202 Accepted).

03 after click 202

  1. Страница Skiller открылась через session-scoped route.

04 Skiller app loaded

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

🤖 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/Dockerfile`:
- Around line 124-130: The unzip step that writes into
node_modules/electron/dist using electron_zip is unsafe to path traversal;
before calling unzip in the Dockerfile, ensure electron_zip is non-empty (fail
with a clear error) and validate the archive contents for unsafe paths (reject
entries with '..' or leading '/') and/or verify a checksum for the expected
Electron version, then only run unzip when validation passes; update the block
referencing electron_zip and node_modules/electron/dist to perform these checks
and fail the build on detection of unsafe paths or missing zip.

In `@packages/api/src/services/skiller.ts`:
- Around line 366-369: The code currently launches Skiller via
skillerLaunchCommand as root/bash which runs the process under the controller
UID/GID; instead, ensure Skiller is executed with the owner UID/GID of
scope.hostHomePath (the same user chown'd in prepareSkillerScopeHome) by
changing skillerLaunchCommand to either wrap launchScript with a uid/gid switch
(e.g., gosu/su-exec or sudo -u equivalent) or by invoking an exec path that sets
process credentials before exec; also ensure the runtime mounts map
/home/<sshUser> and the project targetDir to the controller-visible Docker
volume paths so filesystem access is limited to the active project container.
Use the symbols skillerLaunchCommand and prepareSkillerScopeHome to locate where
to apply these changes.

In `@packages/api/tests/skiller-routes.test.ts`:
- Around line 35-41: The test 'launches Electron as the controller process user'
pins an implementation detail (absence of "setpriv") rather than the contract;
remove the expect(...not.toContain("setpriv")) assertion and instead assert that
skillerLaunchCommand() produces the expected Docker volume mappings for
controller-visible paths. Concretely, in the test that calls
skillerLaunchCommand(), keep the command and electron path assertions, drop the
"setpriv" negative check, and add assertions on the args array (e.g., using
expect.arrayContaining and expect.stringContaining or regex) that verify docker
volume flags ("-v" or "--volume") map "/home/<sshUser>" and the project
targetDir to controller-visible volume paths (look for strings containing
"/home/" and the project targetDir identifier) so the test verifies filesystem
scoping rather than forbidding a specific privilege-drop mechanism.

In `@packages/app/tests/docker-git/controller-resource-limits.test.ts`:
- Around line 98-108: The test in describe("controller Skiller Dockerfile") is
brittle because it asserts exact shell lines via toContain; update the test to
assert the key elements more flexibly: read the Dockerfile with
readComposeFile("packages/api/Dockerfile") as before but replace the exact
toContain checks with either regex matches or separate contains for the variable
definition (electron_zip), the unzip invocation (unzip -q ...
node_modules/electron/dist), and the executable check (test -x
node_modules/electron/dist/electron); also consider renaming the suite to
something specific (e.g., "materialize Electron binary in API Dockerfile") and
keep the test as a regression check if you must assert an exact pattern.
🪄 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: a1240847-ec81-4a84-9d05-f0db3923db98

📥 Commits

Reviewing files that changed from the base of the PR and between 6eabb7e and b652ffb.

📒 Files selected for processing (4)
  • packages/api/Dockerfile
  • packages/api/src/services/skiller.ts
  • packages/api/tests/skiller-routes.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.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: E2E (Clone cache)
  • GitHub Check: E2E (Browser command)
  • GitHub Check: E2E (Login context)
  • GitHub Check: Lint
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: Test
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: Final build (windows-latest)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{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/skiller-routes.test.ts
  • packages/api/src/services/skiller.ts
  • packages/app/tests/docker-git/controller-resource-limits.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/skiller-routes.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.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/skiller-routes.test.ts
  • packages/api/src/services/skiller.ts
  • packages/app/tests/docker-git/controller-resource-limits.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/skiller-routes.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.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/skiller-routes.test.ts
  • packages/api/src/services/skiller.ts
  • packages/app/tests/docker-git/controller-resource-limits.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/skiller-routes.test.ts
  • packages/api/src/services/skiller.ts
  • packages/app/tests/docker-git/controller-resource-limits.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/skiller-routes.test.ts
  • packages/api/src/services/skiller.ts
  • packages/app/tests/docker-git/controller-resource-limits.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/skiller-routes.test.ts
  • packages/api/Dockerfile
  • packages/api/src/services/skiller.ts
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
**/{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
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Applies to docs/integrations/**/*.(ts|js)?(@(routes|handlers|api|middleware))* : API must scope Skiller filesystem access to the active project container by mapping `/home/<sshUser>` and project `targetDir` to controller-visible Docker volume paths
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: docker-git must not import Skiller source code into the docker-git web bundle; serve Skiller browser UI from Skiller's own built renderer and proxy tRPC requests to Skiller's separate backend process
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Applies to docs/integrations/**/*.(ts|js)?(@(routes|handlers|api))* : API endpoint `POST /projects/by-key/:projectKey/terminal-sessions/:sessionId/skiller/open` must launch Skiller Electron app, register terminal session filesystem scope, and write output to ~/.docker-git/logs/skiller.log
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Run `bun run skiller:check` after updating the Skiller pin in addition to docker-git `typecheck` and `check` scripts to verify integration
📚 Learning: 2026-05-14T16:02:05.012Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Applies to docs/integrations/**/*.(ts|js)?(@(routes|handlers|api))* : API endpoint `POST /projects/by-key/:projectKey/terminal-sessions/:sessionId/skiller/open` must launch Skiller Electron app, register terminal session filesystem scope, and write output to ~/.docker-git/logs/skiller.log

Applied to files:

  • packages/api/tests/skiller-routes.test.ts
  • packages/api/src/services/skiller.ts
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
📚 Learning: 2026-05-14T16:02:05.012Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Applies to docs/integrations/**/*.(ts|js)?(@(routes|handlers|api|services))* : API must resolve Codex global skills from `~/.codex/skills` within the selected container volume, not falling back to controller's own `~/.codex/skills`

Applied to files:

  • packages/api/tests/skiller-routes.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
📚 Learning: 2026-05-14T16:02:05.012Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: docker-git must not import Skiller source code into the docker-git web bundle; serve Skiller browser UI from Skiller's own built renderer and proxy tRPC requests to Skiller's separate backend process

Applied to files:

  • packages/api/tests/skiller-routes.test.ts
  • packages/api/Dockerfile
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
📚 Learning: 2026-05-14T16:02:05.012Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Applies to docs/integrations/**/*.(ts|js|sh|bash)?(launcher|skiller)* : Skiller launcher must use `xvfb-run` if available when API process has no `$DISPLAY` environment variable to enable headless startup

Applied to files:

  • packages/api/tests/skiller-routes.test.ts
  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-14T16:02:05.012Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Applies to docs/integrations/**/*.(ts|js)?(@(routes|handlers|api|middleware))* : API must scope Skiller filesystem access to the active project container by mapping `/home/<sshUser>` and project `targetDir` to controller-visible Docker volume paths

Applied to files:

  • packages/api/tests/skiller-routes.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
📚 Learning: 2026-05-18T07:43:38.131Z
Learnt from: skulidropek
Repo: ProverCoderAI/docker-git PR: 313
File: packages/api/src/services/panel-cloudflare-tunnel.ts:123-135
Timestamp: 2026-05-18T07:43:38.131Z
Learning: In this repo’s ProverCoderAI/docker-git architecture, it is intentional for service modules under packages/api/src/services/ to call Node.js APIs directly (e.g., fs, child_process, fetch). Do not treat direct Node API usage in these service modules as a dependency-injection (DI) violation. This codebase provides the NodeContext at the program boundary (entry point) rather than injecting Context.Tag/Layer services into individual service modules; reviewers should only flag DI/context issues if the expected boundary setup is missing.

Applied to files:

  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-22T21:08:22.631Z
Learnt from: skulidropek
Repo: ProverCoderAI/docker-git PR: 344
File: packages/app/src/docker-git/controller-compose.ts:34-40
Timestamp: 2026-05-22T21:08:22.631Z
Learning: In the docker-git project, `${DOCKER_GIT_CONTROLLER_BUILD_SKILLER:-1}` in compose files is standard bash parameter expansion with default value `"1"` (not a literal "-1" mode). The supported runtime contract for `DOCKER_GIT_CONTROLLER_BUILD_SKILLER` in `packages/app/src/docker-git/controller-compose.ts` is: unset/`"1"`/`"true"` → `"1"`, `"0"`/`"false"` → `"0"`. There is no `-1` mode. The Dockerfile also declares `ARG DOCKER_GIT_CONTROLLER_BUILD_SKILLER=1`.

Applied to files:

  • packages/app/tests/docker-git/controller-resource-limits.test.ts
🔇 Additional comments (3)
packages/app/tests/docker-git/controller-resource-limits.test.ts (3)

21-22: LGTM!


56-61: LGTM!


88-93: LGTM!

Comment thread packages/api/Dockerfile
Comment thread packages/api/src/services/skiller.ts Outdated
Comment thread packages/api/tests/skiller-routes.test.ts Outdated
Comment thread packages/app/tests/docker-git/controller-resource-limits.test.ts Outdated
@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented Jun 3, 2026

AI Session Backup

Commit: 3d4e7d5
Status: success
Files: 10 (11.48 MB)
Links: README | Manifest

git status

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

nothing to commit, working tree clean

@skulidropek
Copy link
Copy Markdown
Member Author

Updated in 3d4e7d58a56a3d65c44389a743438e5db552e00c.

What changed:

  • scoped Skiller launch now runs Electron via runuser as the owner of the selected project home volume (ubuntu, UID/GID 1000 in the proof run), not as the controller user;
  • preflight patch/install/build remains separate and runs before the credential switch;
  • scoped HOME/XDG runtime dirs are isolated under /tmp/docker-git-skiller/<projectKey> and owned by the selected UID/GID;
  • Docker volume ancestors get only execute (o+x) for known selected volume paths so non-root Electron can stat/register /home/dev/app without read/list/write permissions on Docker data dirs.

Verification run:

rtk proxy bun --cwd packages/api vitest run tests/skiller-routes.test.ts tests/skiller-core.test.ts
rtk proxy bun run --cwd packages/api build
rtk proxy bun --cwd packages/app vitest run tests/docker-git/actions-skiller.test.ts tests/docker-git/app-terminal-session-handlers.test.ts tests/docker-git/controller-resource-limits.test.ts
rtk git diff --check

Fresh runtime proof:

POST /api/projects/by-key/0e9c63fe5287/skiller/open -> ok: true, alreadyRunning: false, pid: 411
xvfb-run  user=ubuntu uid=1000 gid=1000
Xvfb      user=ubuntu uid=1000 gid=1000
electron  user=ubuntu uid=1000 gid=1000
/tmp/docker-git-skiller/0e9c63fe5287/home    drwx------ uid=1000 gid=1000
/tmp/docker-git-skiller/0e9c63fe5287/runtime drwx------ uid=1000 gid=1000
/var/lib/docker/volumes/.../_data/app        uid=1000 gid=1000

Screenshot: Skiller dashboard after successful open:

Skiller dashboard

Screenshot: after a real click on the Projects nav button (clicked=true, href=#/projects in skiller-projects-after-click.json):

Skiller projects after click

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

Caution

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

⚠️ Outside diff range comments (1)
packages/api/src/services/skiller.ts (1)

302-314: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Сначала создайте out/preload, иначе восстановление shim само себя ломает.

Ветка с ln -sf ... out/preload/index.js падает, если out/main и out/renderer уже существуют, а каталог out/preload ещё нет. В Dockerfile этот же контракт уже реализован через mkdir -p out/preload перед ln -sf, так что runtime-скрипт сейчас расходится с образом.

Предлагаемое исправление
 const prepareLaunchScript = [
   "set -euo pipefail",
   "DOCKER_GIT_SKILLER_PATCH=../../patches/skiller/docker-git-browser-folder-picker.patch",
   "DOCKER_GIT_SKILLER_PATCH_MARKER=out/.docker-git-browser-folder-picker.patch",
   "if [ -f ../../scripts/skiller-apply-docker-git-patches.mjs ]; then bun ../../scripts/skiller-apply-docker-git-patches.mjs; fi",
   "if [ ! -d node_modules ]; then bun install --frozen-lockfile; fi",
   "if [ ! -f out/main/index.js ] || [ ! -f out/renderer/index.html ] || { [ -f \"$DOCKER_GIT_SKILLER_PATCH\" ] && [ ! -f \"$DOCKER_GIT_SKILLER_PATCH_MARKER\" ]; } || { [ -f \"$DOCKER_GIT_SKILLER_PATCH\" ] && [ \"$DOCKER_GIT_SKILLER_PATCH\" -nt \"$DOCKER_GIT_SKILLER_PATCH_MARKER\" ]; }; then",
   "  bun run build",
   "  mkdir -p out",
   "  touch \"$DOCKER_GIT_SKILLER_PATCH_MARKER\"",
   "fi",
-  "if [ ! -e out/preload/index.js ]; then ln -sf index.mjs out/preload/index.js; fi"
+  "if [ ! -e out/preload/index.js ]; then",
+  "  mkdir -p out/preload",
+  "  ln -sf index.mjs out/preload/index.js",
+  "fi"
 ].join(\"\\n\")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/services/skiller.ts` around lines 302 - 314, The runtime
launch script assigned to prepareLaunchScript attempts to create a symlink with
the line 'ln -sf index.mjs out/preload/index.js' but does not ensure the
out/preload directory exists, causing failures when out/main and out/renderer
exist but out/preload does not; update prepareLaunchScript to run 'mkdir -p
out/preload' (or equivalent) before the ln -sf command so the directory is
created prior to creating the symlink, keeping the rest of the build checks and
markers intact.
🤖 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/skiller.ts`:
- Around line 479-490: The current resolveSkillerProcessAccount function throws
if nameForId(readFileSync("/etc/passwd"...) or nameForId(..."/etc/group"...)
returns null; change it to tolerate missing local accounts by falling back: if
userName or groupName is null, do NOT throw—instead mark the account as
"unresolved" and return a SkillerProcessAccount variant indicating unresolved
names (keep uid/gid), and update the code path that launches the controller (the
caller that uses resolveSkillerProcessAccount and invokes runuser/runas logic)
to either (A) fall back to starting the controller with a safe "bash -c"
unscoped invocation when names are unresolved, or (B) create temporary
/etc/passwd and /etc/group entries (e.g. write to a temp file and use NSS
wrapper or pass via --userns options) before calling runuser; implement option A
as the minimal fix so POST .../skiller/open succeeds for non-local UIDs by using
the bash fallback when resolveSkillerProcessAccount indicates missing names.
Ensure the returned SkillerProcessAccount still includes uid/gid so downstream
logging and path setup (writing to ~/.docker-git/logs/skiller.log) can proceed.
- Around line 522-533: prepareSkillerRuntime currently uses spawnSync which
blocks the event loop when openSkiller is invoked from HTTP handlers; change it
to a non-blocking async implementation (e.g., use child_process.spawn or spawn
with a Promise wrapper, or use exec/execFile with a Promise) and await/result
outside the request path or run it in a background worker so HTTP handlers never
perform synchronous patch/install/build work; specifically replace
prepareSkillerRuntime's spawnSync usage with an asynchronous child-process
approach that pipes logs to logFd and rejects/throws on non-zero exit, and
ensure callers like openSkiller invoke the async function without blocking the
request (or trigger it off-request via background task).

---

Outside diff comments:
In `@packages/api/src/services/skiller.ts`:
- Around line 302-314: The runtime launch script assigned to prepareLaunchScript
attempts to create a symlink with the line 'ln -sf index.mjs
out/preload/index.js' but does not ensure the out/preload directory exists,
causing failures when out/main and out/renderer exist but out/preload does not;
update prepareLaunchScript to run 'mkdir -p out/preload' (or equivalent) before
the ln -sf command so the directory is created prior to creating the symlink,
keeping the rest of the build checks and markers intact.
🪄 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: f90dd2b4-58cc-4b84-926c-f28192e8a117

📥 Commits

Reviewing files that changed from the base of the PR and between b652ffb and 3d4e7d5.

⛔ Files ignored due to path filters (2)
  • docs/pr-screenshots/issue-365/skiller-dashboard.png is excluded by !**/*.png
  • docs/pr-screenshots/issue-365/skiller-projects-after-click.png is excluded by !**/*.png
📒 Files selected for processing (5)
  • docs/pr-screenshots/issue-365/skiller-projects-after-click.json
  • packages/api/Dockerfile
  • packages/api/src/services/skiller.ts
  • packages/api/tests/skiller-routes.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.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 (Runtime volumes + SSH)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: Lint
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: Test
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{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/skiller-routes.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • packages/api/src/services/skiller.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/skiller-routes.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.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/skiller-routes.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • packages/api/src/services/skiller.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/skiller-routes.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.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/skiller-routes.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • packages/api/src/services/skiller.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/skiller-routes.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • packages/api/src/services/skiller.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/skiller-routes.test.ts
  • docs/pr-screenshots/issue-365/skiller-projects-after-click.json
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • packages/api/src/services/skiller.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/skiller-routes.test.ts
  • docs/pr-screenshots/issue-365/skiller-projects-after-click.json
  • packages/api/Dockerfile
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • packages/api/src/services/skiller.ts
**/{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
🧠 Learnings (19)
📓 Common learnings
Learnt from: ezocomp118-source
Repo: ProverCoderAI/docker-git PR: 366
File: packages/api/src/services/skiller.ts:366-369
Timestamp: 2026-06-03T17:35:44.689Z
Learning: In ProverCoderAI/docker-git, launching Electron via `setpriv --reuid/--regid` in the controller container causes a `Trace/breakpoint trap` crash even with `--no-sandbox`. The confirmed workaround is to launch Skiller as the controller user (bash -lc) and enforce project scope at the software level via SkillerContainerScope env vars (HOME, XDG_*, DOCKER_GIT_SKILLER_CONTAINER_HOME_PATH) and the add_project tRPC call. A future fix should use gosu/su-exec or a Chromium-sandbox-compatible credential-drop mechanism instead of setpriv. See PR `#366` for full context.
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Applies to docs/integrations/**/*.(ts|js)?(@(routes|handlers|api|middleware))* : API must scope Skiller filesystem access to the active project container by mapping `/home/<sshUser>` and project `targetDir` to controller-visible Docker volume paths
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: docker-git must not import Skiller source code into the docker-git web bundle; serve Skiller browser UI from Skiller's own built renderer and proxy tRPC requests to Skiller's separate backend process
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Applies to docs/integrations/**/*.(ts|js)?(@(routes|handlers|api))* : API endpoint `POST /projects/by-key/:projectKey/terminal-sessions/:sessionId/skiller/open` must launch Skiller Electron app, register terminal session filesystem scope, and write output to ~/.docker-git/logs/skiller.log
📚 Learning: 2026-05-14T16:02:05.012Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Applies to docs/integrations/**/*.(ts|js)?(@(routes|handlers|api))* : API endpoint `POST /projects/by-key/:projectKey/terminal-sessions/:sessionId/skiller/open` must launch Skiller Electron app, register terminal session filesystem scope, and write output to ~/.docker-git/logs/skiller.log

Applied to files:

  • packages/api/tests/skiller-routes.test.ts
  • packages/api/Dockerfile
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-14T16:02:05.012Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Applies to docs/integrations/**/*.(ts|js|sh|bash)?(launcher|skiller)* : Skiller launcher must use `xvfb-run` if available when API process has no `$DISPLAY` environment variable to enable headless startup

Applied to files:

  • packages/api/tests/skiller-routes.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • packages/api/src/services/skiller.ts
📚 Learning: 2026-06-03T17:35:44.689Z
Learnt from: ezocomp118-source
Repo: ProverCoderAI/docker-git PR: 366
File: packages/api/src/services/skiller.ts:366-369
Timestamp: 2026-06-03T17:35:44.689Z
Learning: In ProverCoderAI/docker-git, launching Electron via `setpriv --reuid/--regid` in the controller container causes a `Trace/breakpoint trap` crash even with `--no-sandbox`. The confirmed workaround is to launch Skiller as the controller user (bash -lc) and enforce project scope at the software level via SkillerContainerScope env vars (HOME, XDG_*, DOCKER_GIT_SKILLER_CONTAINER_HOME_PATH) and the add_project tRPC call. A future fix should use gosu/su-exec or a Chromium-sandbox-compatible credential-drop mechanism instead of setpriv. See PR `#366` for full context.

Applied to files:

  • packages/api/tests/skiller-routes.test.ts
  • packages/api/Dockerfile
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-14T16:02:05.012Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Applies to docs/integrations/**/*.(ts|js)?(@(routes|handlers|api|middleware))* : API must scope Skiller filesystem access to the active project container by mapping `/home/<sshUser>` and project `targetDir` to controller-visible Docker volume paths

Applied to files:

  • packages/api/tests/skiller-routes.test.ts
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-14T16:02:16.256Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-05-14T16:02:16.256Z
Learning: Applies to **/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp} : Fail if changed files introduce path traversal or writes outside intended project/container state directories

Applied to files:

  • packages/api/tests/skiller-routes.test.ts
  • packages/api/Dockerfile
  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-14T16:02:05.012Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: docker-git must not import Skiller source code into the docker-git web bundle; serve Skiller browser UI from Skiller's own built renderer and proxy tRPC requests to Skiller's separate backend process

Applied to files:

  • packages/api/Dockerfile
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-14T16:02:05.012Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Run `bun run skiller:check` after updating the Skiller pin in addition to docker-git `typecheck` and `check` scripts to verify integration

Applied to files:

  • packages/api/Dockerfile
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
📚 Learning: 2026-05-14T16:02:16.256Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-05-14T16:02:16.256Z
Learning: Applies to **/{Dockerfile*,docker-compose*.{yml,yaml},.dockerignore} : Fail if changed files introduce unsafe Docker configuration such as privileged containers, broad host mounts, unbounded Docker socket access, or unnecessary write permissions

Applied to files:

  • packages/api/Dockerfile
  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-14T16:02:16.256Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-05-14T16:02:16.256Z
Learning: Applies to **/{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} : Fail if dependency or package-manager changes materially increase supply-chain risk without justification

Applied to files:

  • packages/api/Dockerfile
📚 Learning: 2026-05-14T16:02:16.256Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-05-14T16:02:16.256Z
Learning: Applies to **/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore} : Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Applied to files:

  • packages/api/Dockerfile
📚 Learning: 2026-05-14T16:02:16.256Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-05-14T16:02:16.256Z
Learning: Applies to **/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php} : Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Applied to files:

  • packages/api/Dockerfile
📚 Learning: 2026-05-13T07:10:13.213Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-05-13T07:10:13.213Z
Learning: Applies to **/*.{test,spec}.{ts,tsx} : Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Applied to files:

  • packages/app/tests/docker-git/controller-resource-limits.test.ts
📚 Learning: 2026-05-13T07:09:47.992Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-05-13T07:09:47.992Z
Learning: Applies to **/*.{ts,tsx} : 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).

Applied to files:

  • packages/app/tests/docker-git/controller-resource-limits.test.ts
📚 Learning: 2026-05-13T07:10:13.213Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-05-13T07:10:13.213Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : 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.

Applied to files:

  • packages/app/tests/docker-git/controller-resource-limits.test.ts
📚 Learning: 2026-05-14T16:02:05.012Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Applies to docs/integrations/**/*.(ts|js)?(@(routes|handlers|api|services))* : API must resolve Codex global skills from `~/.codex/skills` within the selected container volume, not falling back to controller's own `~/.codex/skills`

Applied to files:

  • packages/app/tests/docker-git/controller-resource-limits.test.ts
  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-18T07:43:38.131Z
Learnt from: skulidropek
Repo: ProverCoderAI/docker-git PR: 313
File: packages/api/src/services/panel-cloudflare-tunnel.ts:123-135
Timestamp: 2026-05-18T07:43:38.131Z
Learning: In this repo’s ProverCoderAI/docker-git architecture, it is intentional for service modules under packages/api/src/services/ to call Node.js APIs directly (e.g., fs, child_process, fetch). Do not treat direct Node API usage in these service modules as a dependency-injection (DI) violation. This codebase provides the NodeContext at the program boundary (entry point) rather than injecting Context.Tag/Layer services into individual service modules; reviewers should only flag DI/context issues if the expected boundary setup is missing.

Applied to files:

  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-14T16:02:05.012Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Skiller submodule must be pinned to version v0.2.14 at commit 6ff6b9ca1ff2d78d3af7dac47b03ed1c315dab6b from upstream https://github.com/beautyfree/skiller-desktop-skills-manager

Applied to files:

  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-22T21:08:22.631Z
Learnt from: skulidropek
Repo: ProverCoderAI/docker-git PR: 344
File: packages/app/src/docker-git/controller-compose.ts:34-40
Timestamp: 2026-05-22T21:08:22.631Z
Learning: In the docker-git project, `${DOCKER_GIT_CONTROLLER_BUILD_SKILLER:-1}` in compose files is standard bash parameter expansion with default value `"1"` (not a literal "-1" mode). The supported runtime contract for `DOCKER_GIT_CONTROLLER_BUILD_SKILLER` in `packages/app/src/docker-git/controller-compose.ts` is: unset/`"1"`/`"true"` → `"1"`, `"0"`/`"false"` → `"0"`. There is no `-1` mode. The Dockerfile also declares `ARG DOCKER_GIT_CONTROLLER_BUILD_SKILLER=1`.

Applied to files:

  • packages/api/src/services/skiller.ts
🔇 Additional comments (6)
docs/pr-screenshots/issue-365/skiller-projects-after-click.json (1)

1-12: LGTM!

packages/app/tests/docker-git/controller-resource-limits.test.ts (3)

21-22: LGTM!


56-61: LGTM!

Also applies to: 88-93


98-109: LGTM!

packages/api/Dockerfile (1)

125-128: LGTM!

packages/api/tests/skiller-routes.test.ts (1)

35-67: LGTM!

Comment thread packages/api/src/services/skiller.ts
Comment thread packages/api/src/services/skiller.ts Outdated
@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented Jun 3, 2026

AI Session Backup

Commit: f5cdf39
Status: success
Files: 11 (12.22 MB)
Links: README | Manifest

git status

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

nothing to commit, working tree clean

@skulidropek
Copy link
Copy Markdown
Member Author

Addressed review 4421915309 in f5cdf39:

  • prepareLaunchScript now creates out/preload before linking out/preload/index.js.
  • Scoped Skiller no longer requires pre-existing local passwd/group entries for the selected volume owner. Missing UID/GID entries are bootstrapped as deterministic dg-skiller-u*/dg-skiller-g* accounts, then Electron still starts via runuser as the scoped account.
  • prepareSkillerRuntime no longer uses spawnSync; launch preparation is async and openSkiller awaits it through Effect.tryPromise.

Validation:

  • rtk proxy bun --cwd packages/api vitest run tests/skiller-core.test.ts tests/skiller-routes.test.ts
  • rtk proxy bun run --cwd packages/api build
  • rtk proxy bun run --cwd packages/api lint
  • rtk proxy bun run --cwd packages/api test
  • rtk git diff --check

Existing app proof screenshots in this PR:

Skiller dashboard

Projects nav after real click

@skulidropek
Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 3, 2026

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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/api/src/services/skiller.ts`:
- Around line 191-207: runProcess currently spawns child processes without any
time limit; add a timeout mechanism using an AbortController/AbortSignal (create
controller inside runProcess and pass controller.signal into the spawn options)
and start a timer that aborts/kills the child when elapsed, clears the timer on
normal exit, and rejects with a distinct timeout Error; ensure you clean up
event listeners and call child.kill (or let the AbortSignal terminate the
process) and propagate the abort reason so callers of runProcess can distinguish
timeout vs other 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: fe924ac4-e5b6-4abe-a9ab-ece127713ce0

📥 Commits

Reviewing files that changed from the base of the PR and between 3d4e7d5 and f5cdf39.

📒 Files selected for processing (2)
  • packages/api/src/services/skiller.ts
  • packages/api/tests/skiller-routes.test.ts
📜 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/api/tests/skiller-routes.test.ts
  • packages/api/src/services/skiller.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/skiller-routes.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/skiller-routes.test.ts
  • packages/api/src/services/skiller.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/skiller-routes.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/skiller-routes.test.ts
  • packages/api/src/services/skiller.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/skiller-routes.test.ts
  • packages/api/src/services/skiller.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/skiller-routes.test.ts
  • packages/api/src/services/skiller.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/skiller-routes.test.ts
  • packages/api/src/services/skiller.ts
🧠 Learnings (14)
📓 Common learnings
Learnt from: ezocomp118-source
Repo: ProverCoderAI/docker-git PR: 366
File: packages/api/src/services/skiller.ts:366-369
Timestamp: 2026-06-03T17:35:44.689Z
Learning: In ProverCoderAI/docker-git, launching Electron via `setpriv --reuid/--regid` in the controller container causes a `Trace/breakpoint trap` crash even with `--no-sandbox`. The confirmed workaround is to launch Skiller as the controller user (bash -lc) and enforce project scope at the software level via SkillerContainerScope env vars (HOME, XDG_*, DOCKER_GIT_SKILLER_CONTAINER_HOME_PATH) and the add_project tRPC call. A future fix should use gosu/su-exec or a Chromium-sandbox-compatible credential-drop mechanism instead of setpriv. See PR `#366` for full context.
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Applies to docs/integrations/**/*.(ts|js)?(@(routes|handlers|api|middleware))* : API must scope Skiller filesystem access to the active project container by mapping `/home/<sshUser>` and project `targetDir` to controller-visible Docker volume paths
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Applies to docs/integrations/**/*.(ts|js)?(@(routes|handlers|api))* : API endpoint `POST /projects/by-key/:projectKey/terminal-sessions/:sessionId/skiller/open` must launch Skiller Electron app, register terminal session filesystem scope, and write output to ~/.docker-git/logs/skiller.log
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: docker-git must not import Skiller source code into the docker-git web bundle; serve Skiller browser UI from Skiller's own built renderer and proxy tRPC requests to Skiller's separate backend process
📚 Learning: 2026-05-14T16:02:05.012Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Applies to docs/integrations/**/*.(ts|js)?(@(routes|handlers|api))* : API endpoint `POST /projects/by-key/:projectKey/terminal-sessions/:sessionId/skiller/open` must launch Skiller Electron app, register terminal session filesystem scope, and write output to ~/.docker-git/logs/skiller.log

Applied to files:

  • packages/api/tests/skiller-routes.test.ts
  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-14T16:02:05.012Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Applies to docs/integrations/**/*.(ts|js|sh|bash)?(launcher|skiller)* : Skiller launcher must use `xvfb-run` if available when API process has no `$DISPLAY` environment variable to enable headless startup

Applied to files:

  • packages/api/tests/skiller-routes.test.ts
  • packages/api/src/services/skiller.ts
📚 Learning: 2026-06-03T17:35:44.689Z
Learnt from: ezocomp118-source
Repo: ProverCoderAI/docker-git PR: 366
File: packages/api/src/services/skiller.ts:366-369
Timestamp: 2026-06-03T17:35:44.689Z
Learning: In ProverCoderAI/docker-git, launching Electron via `setpriv --reuid/--regid` in the controller container causes a `Trace/breakpoint trap` crash even with `--no-sandbox`. The confirmed workaround is to launch Skiller as the controller user (bash -lc) and enforce project scope at the software level via SkillerContainerScope env vars (HOME, XDG_*, DOCKER_GIT_SKILLER_CONTAINER_HOME_PATH) and the add_project tRPC call. A future fix should use gosu/su-exec or a Chromium-sandbox-compatible credential-drop mechanism instead of setpriv. See PR `#366` for full context.

Applied to files:

  • packages/api/tests/skiller-routes.test.ts
  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-14T16:02:05.012Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Applies to docs/integrations/**/*.(ts|js)?(@(routes|handlers|api|middleware))* : API must scope Skiller filesystem access to the active project container by mapping `/home/<sshUser>` and project `targetDir` to controller-visible Docker volume paths

Applied to files:

  • packages/api/tests/skiller-routes.test.ts
  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-14T16:02:16.256Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-05-14T16:02:16.256Z
Learning: Applies to **/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp} : Fail if changed files introduce path traversal or writes outside intended project/container state directories

Applied to files:

  • packages/api/tests/skiller-routes.test.ts
  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-14T16:02:05.012Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: docker-git must not import Skiller source code into the docker-git web bundle; serve Skiller browser UI from Skiller's own built renderer and proxy tRPC requests to Skiller's separate backend process

Applied to files:

  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-14T16:02:05.012Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Applies to docs/integrations/**/*.(ts|js)?(@(routes|handlers|api|services))* : API must resolve Codex global skills from `~/.codex/skills` within the selected container volume, not falling back to controller's own `~/.codex/skills`

Applied to files:

  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-14T16:02:16.256Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-05-14T16:02:16.256Z
Learning: Applies to **/{Dockerfile*,docker-compose*.{yml,yaml},.dockerignore} : Fail if changed files introduce unsafe Docker configuration such as privileged containers, broad host mounts, unbounded Docker socket access, or unnecessary write permissions

Applied to files:

  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-18T07:43:38.131Z
Learnt from: skulidropek
Repo: ProverCoderAI/docker-git PR: 313
File: packages/api/src/services/panel-cloudflare-tunnel.ts:123-135
Timestamp: 2026-05-18T07:43:38.131Z
Learning: In this repo’s ProverCoderAI/docker-git architecture, it is intentional for service modules under packages/api/src/services/ to call Node.js APIs directly (e.g., fs, child_process, fetch). Do not treat direct Node API usage in these service modules as a dependency-injection (DI) violation. This codebase provides the NodeContext at the program boundary (entry point) rather than injecting Context.Tag/Layer services into individual service modules; reviewers should only flag DI/context issues if the expected boundary setup is missing.

Applied to files:

  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-14T16:02:05.012Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Skiller submodule must be pinned to version v0.2.14 at commit 6ff6b9ca1ff2d78d3af7dac47b03ed1c315dab6b from upstream https://github.com/beautyfree/skiller-desktop-skills-manager

Applied to files:

  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-14T16:02:05.012Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Run `bun run skiller:check` after updating the Skiller pin in addition to docker-git `typecheck` and `check` scripts to verify integration

Applied to files:

  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-14T16:02:05.012Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: docs/integrations/skiller.md:0-0
Timestamp: 2026-05-14T16:02:05.012Z
Learning: Initialize Skiller submodule using `bun run skiller:init` command and do not include the submodule in root workspace configuration

Applied to files:

  • packages/api/src/services/skiller.ts
📚 Learning: 2026-05-13T07:10:13.213Z
Learnt from: CR
Repo: ProverCoderAI/docker-git PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-05-13T07:10:13.213Z
Learning: Interop with Promise/exceptions is permitted ONLY in SHELL via `Effect.try` or `Effect.tryPromise` with typed error mapping.

Applied to files:

  • packages/api/src/services/skiller.ts
🔇 Additional comments (12)
packages/api/src/services/skiller.ts (11)

52-69: LGTM!


331-335: LGTM!


365-385: LGTM!


500-517: LGTM!


519-534: LGTM!


536-566: LGTM!


568-578: LGTM!


580-606: LGTM!


608-613: LGTM!


651-696: LGTM!


758-764: LGTM!

packages/api/tests/skiller-routes.test.ts (1)

69-75: LGTM!

Comment thread packages/api/src/services/skiller.ts Outdated
@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented Jun 3, 2026

AI Session Backup

Commit: 61ec4a9
Status: success
Files: 12 (12.94 MB)
Links: README | Manifest

git status

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

nothing to commit, working tree clean

@skulidropek
Copy link
Copy Markdown
Member Author

Addressed review 4422425479 in 61ec4a9:

  • Added a default 300s timeout to runProcess.
  • Child processes now receive an AbortController signal, are SIGTERM-killed on timeout, and clean up timer/listeners on completion.
  • Timeout rejects as SkillerProcessTimeoutError so callers can distinguish it from spawn failures and non-zero exit codes.
  • Added a regression test for a stalled child process.

Validation:

  • rtk proxy bun --cwd packages/api vitest run tests/skiller-routes.test.ts
  • rtk proxy bun run --cwd packages/api build
  • rtk proxy bun run --cwd packages/api lint
  • rtk proxy bun run --cwd packages/api test
  • rtk git diff --check

Existing app proof screenshots remain in this PR:

Skiller dashboard

Projects nav after real click

@skulidropek
Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 3, 2026

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@skulidropek skulidropek merged commit e285b1f into main Jun 3, 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.

Почему-то кнопка skiller не работает

2 participants