Skip to content

fix(entrypoint): clone into dev home for tilde TARGET_DIR (empty app folder)#414

Merged
skulidropek merged 6 commits into
ProverCoderAI:mainfrom
konard:issue-413-cb2a359e0ffa
Jun 17, 2026
Merged

fix(entrypoint): clone into dev home for tilde TARGET_DIR (empty app folder)#414
skulidropek merged 6 commits into
ProverCoderAI:mainfrom
konard:issue-413-cb2a359e0ffa

Conversation

@konard

@konard konard commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Problem

Closes #413.

When running docker-git clone, the repository was not cloned into the workspace app folder — the folder ended up empty. The reporter's terminal showed an empty ~/~/app (main)> prompt and they had to git clone manually.

This is the same class of bug as #408/#409, but #409 fixed the wrong file (the standalone base-image entrypoint.sh, which the panel/CLI clone flow does not use). The real clone flow uses the generated per-project entrypoint produced by templates-entrypoint/base.ts.

Root cause

The generated entrypoint runs as root (sshd), so $HOME resolves to /root. When a tilde TARGET_DIR (~ or ~/...) reached the entrypoint — e.g. via the TARGET_DIR env override — it was expanded against $HOME:

if [[ "$TARGET_DIR" == "~" ]]; then
  TARGET_DIR="$HOME"            # -> /root
elif [[ "$TARGET_DIR" == "~/"* ]]; then
  TARGET_DIR="$HOME${TARGET_DIR:1}"  # -> /root/app
fi

The auto-clone then runs as su - <sshUser> (the unprivileged dev user). Cloning into the root-owned /root/app fails with permission denied, so the repository never lands in the prepared home and the workspace app folder stays empty.

Fix

Expand the tilde against the unprivileged user's home /home/<sshUser> instead of root's $HOME, so the clone always lands in the dev-owned workspace:

if [[ "$TARGET_DIR" == "~" ]]; then
  TARGET_DIR="/home/${config.sshUser}"
elif [[ "$TARGET_DIR" == "~/"* ]]; then
  TARGET_DIR="/home/${config.sshUser}${TARGET_DIR:1}"
fi

Applied to both copies of the template:

  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/src/lib/core/templates-entrypoint/base.ts

Reproduction & verification

Reproduced end-to-end in Docker with the generated entrypoint logic:

  • Before (expand against $HOME): resolved TARGET_DIR=/root/appfatal: could not create work tree dir '/root/app': Permission denied/home/dev/app empty.
  • After (expand against /home/$SSH_USER): resolved TARGET_DIR=/home/dev/appCloning into '/home/dev/app'... → workspace contains .git + cloned files.

Tests

Added renderEntrypoint tilde target dir expansion to packages/lib/tests/core/templates.test.ts:

  • asserts a bare ~ expands to /home/<sshUser> (not $HOME//root)
  • asserts ~/... expands to /home/<sshUser>/...
  • property test over generated configs ensures it never emits TARGET_DIR="$HOME"

Verified the tests fail on the old $HOME code and pass with the fix (55/55 in the suite).

Release

Added changeset entrypoint-tilde-clone-target.md (patch for @prover-coder-ai/docker-git).

Adding .gitkeep for PR creation (default mode).
This file will be removed when the task is complete.

Issue: ProverCoderAI#413
@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8442a0c2-b1b2-4ef8-a3b7-d00a8c3b1fcc

📥 Commits

Reviewing files that changed from the base of the PR and between 62e4916 and 6e2e0bf.

📒 Files selected for processing (2)
  • packages/container/src/core/templates-entrypoint/base.ts
  • packages/container/tests/core/templates.test.ts
💤 Files with no reviewable changes (2)
  • packages/container/tests/core/templates.test.ts
  • packages/container/src/core/templates-entrypoint/base.ts
📜 Recent review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: Build
  • GitHub Check: Dist deps prune
  • GitHub Check: Test
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Browser command)
  • GitHub Check: Lint
  • GitHub Check: Types
  • GitHub Check: Final build (windows-latest)

📝 Walkthrough

Summary by CodeRabbit

Релиз-ноты

  • Bug Fixes

    • Исправлена ошибка при использовании tilde-пути (~ или ~/...) в параметре TARGET_DIR команды docker-git clone. Теперь путь корректно разворачивается в домашнюю директорию SSH-пользователя, исключая ошибки разрешений доступа.
  • Tests

    • Добавлены тесты для проверки корректного расширения tilde-путей в целевой директории.

Walkthrough

В шаблоне bash-entrypoint заменена логика tilde-расширения для TARGET_DIR: вместо $HOME (который при запуске sshd был /root) теперь используется абсолютный путь /home/${config.sshUser}. Добавлены тесты и changeset-запись.

Changes

Исправление tilde-расширения TARGET_DIR в entrypoint

Layer / File(s) Summary
Исправление tilde-расширения и покрывающие тесты
packages/container/src/core/templates-entrypoint/base.ts, packages/container/tests/core/templates.test.ts
Ветки TARGET_DIR == "~" и "~/"* в шаблоне bash-entrypoint теперь подставляют /home/${config.sshUser} вместо $HOME. Добавлены два unit-теста: для фиксированного sshUser="dev" и для property-based конфигураций; оба проверяют отсутствие $HOME в сгенерированном скрипте.
Changeset-запись об исправлении
.changeset/entrypoint-tilde-clone-target.md
Добавлен changeset для @prover-coder-ai/docker-git с описанием исправленного сценария docker-git clone при tilde-пути TARGET_DIR.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes


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 Changeset references wrong package: lists "@prover-coder-ai/docker-git" but changes are in packages/container ('@prover-coder-ai/docker-git-container'). Code changes, tests, and refactoring are cor... Update .changeset/entrypoint-tilde-clone-target.md to reference "@prover-coder-ai/docker-git-container" instead of "@prover-coder-ai/docker-git".
✅ Passed checks (6 passed)
Check name Status Explanation
Title check ✅ Passed Заголовок чётко описывает основное изменение: исправление логики раскрытия тильды в TARGET_DIR для entrypoint, что приводит к успешному клонированию в рабочую папку app вместо оставления её пустой.
Description check ✅ Passed Описание полностью следует структуре шаблона и содержит все необходимые разделы: проблему, корневую причину, исправление, воспроизведение и проверку, тесты и информацию о выпуске.
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 regression found. The fix uses validated sshUser with regex pattern, properly quotes TARGET_DIR in shell commands, and confines any path traversal to /home/dev unprivile...
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

github-actions Bot and others added 3 commits June 17, 2026 06:31
…HOME

The generated entrypoint runs as root (sshd), so $HOME is /root. A ~/...
TARGET_DIR reaching the entrypoint was expanded against $HOME -> /root/app,
which the unprivileged 'su - <sshUser>' clone cannot write, so git clone failed
and the workspace 'app' folder stayed empty (issue ProverCoderAI#413). Expand against
/home/<sshUser> so the clone always lands in the dev-owned workspace.

Fixes ProverCoderAI#413
@konard konard changed the title [WIP] Почему-то при docker-git clone не делается git clone в папку app fix(entrypoint): clone into dev home for tilde TARGET_DIR (empty app folder) Jun 17, 2026
@konard konard marked this pull request as ready for review June 17, 2026 06:52

@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: 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/app/CHANGELOG.md`:
- Around line 3-11: The CHANGELOG entry for version 1.3.5 uses an incorrect
commit type (chore instead of fix) and lacks proper traceability and detailed
description of the actual bug fix related to tilde expansion in the entrypoint
script. Update the entry to follow the Conventional Commits format used in
version 1.3.4 by changing the commit type to fix(shell), adding a PR reference
with link, including the commit SHA reference, adding the author attribution,
and replacing the generic message with a detailed explanation of what was fixed
regarding tilde expansion in TARGET_DIR and how it resolves issue `#413`. Ensure
the Updated dependencies section remains unchanged.

In `@packages/app/src/lib/core/templates-entrypoint/base.ts`:
- Around line 19-23: The function `renderEntrypointHeader` and its tilde path
expansion logic (handling "~" and "~/" prefixes) are duplicated identically in
both packages/lib and packages/app, creating maintenance and divergence risks.
Extract this common logic into a separate shared package (such as
`@prover-coder-ai/docker-git-templates`) that both packages can depend on,
ensuring a single source of truth. Alternatively, if architectural constraints
prevent a new shared package, implement a ts-morph synchronization script that
automatically copies the implementation from lib to app during build, and add CI
checks to verify the implementations remain identical. Additionally, expand the
existing test suite in `packages/lib/tests/core/templates.test.ts` to verify
that `renderEntrypointHeader` outputs are identical across both packages, not
just `renderPostPushPrEnsure`.

In `@packages/docker-git-session-sync/CHANGELOG.md`:
- Around line 3-7: The CHANGELOG.md entry for version 1.0.63 currently contains
only a generic "chore: automated version bump" message, but it should include a
meaningful description of the actual fix that was implemented. Replace the
generic message in the Patch Changes section with a user-facing description that
explains what issue was resolved, specifically that the fix addresses the tilde
path resolution problem in docker-git clone operations where the app folder
remained empty due to tilde being resolved relative to the wrong home directory.
The description should be specific enough that users updating the version
understand what has been fixed, following the format of previous changelog
entries like version 1.0.10.

In `@packages/lib/src/core/templates-entrypoint/base.ts`:
- Around line 19-23: The tilde expansion logic in the if/elif block for
TARGET_DIR is missing required documentation comments according to coding
guidelines. Add functional comment documentation above the TARGET_DIR assignment
block that includes all required markers: CHANGE (describing the replacement of
$HOME with explicit /home/${config.sshUser}), WHY (explaining that entrypoint
runs as root via sshd causing $HOME=/root and git clone failures), QUOTE
(referencing the requirement), REF (linking to issue `#413`), SOURCE, FORMAT
THEOREM (defining the expansion behavior), PURITY, INVARIANT (ensuring bash
expands ~ to dev-owned home, never root's), and COMPLEXITY. Follow the exact
format shown in the review comment with proper documentation structure.
🪄 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: cdfe463e-3c6b-431c-a5f9-7e0a2fa9a2cd

📥 Commits

Reviewing files that changed from the base of the PR and between e554ee8 and 62e4916.

📒 Files selected for processing (9)
  • .changeset/entrypoint-tilde-clone-target.md
  • .gitkeep
  • packages/app/CHANGELOG.md
  • packages/app/package.json
  • packages/app/src/lib/core/templates-entrypoint/base.ts
  • packages/docker-git-session-sync/CHANGELOG.md
  • packages/docker-git-session-sync/package.json
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/lib/tests/core/templates.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: Lint
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Browser command)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: Types
  • GitHub Check: Test
  • GitHub Check: Final build (windows-latest)
🧰 Additional context used
📓 Path-based instructions (12)
**/{.git*,config*,*.sh,docker-compose*}

📄 CodeRabbit inference engine (README.md)

Use git credential helper to automatically select correct token by host for HTTPS clone/push operations

Files:

  • .gitkeep
**/{setup,install,config,*.sh,*.md}

📄 CodeRabbit inference engine (README.md)

Ensure default projects directory is ~/.docker-git

Files:

  • packages/docker-git-session-sync/CHANGELOG.md
  • packages/app/CHANGELOG.md
**/*

⚙️ CodeRabbit configuration file

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

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

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

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

Files:

  • packages/docker-git-session-sync/CHANGELOG.md
  • packages/app/package.json
  • packages/docker-git-session-sync/package.json
  • packages/lib/tests/core/templates.test.ts
  • packages/app/CHANGELOG.md
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/src/lib/core/templates-entrypoint/base.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/docker-git-session-sync/CHANGELOG.md
  • packages/app/package.json
  • packages/docker-git-session-sync/package.json
  • packages/lib/tests/core/templates.test.ts
  • packages/app/CHANGELOG.md
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/src/lib/core/templates-entrypoint/base.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

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

Files:

  • packages/app/package.json
  • packages/docker-git-session-sync/package.json
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/src/lib/core/templates-entrypoint/base.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/app/package.json
  • packages/docker-git-session-sync/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/lib/tests/core/templates.test.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/src/lib/core/templates-entrypoint/base.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

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

Files:

  • packages/lib/tests/core/templates.test.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/src/lib/core/templates-entrypoint/base.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/lib/tests/core/templates.test.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/src/lib/core/templates-entrypoint/base.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/lib/tests/core/templates.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/lib/tests/core/templates.test.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/src/lib/core/templates-entrypoint/base.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/lib/tests/core/templates.test.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/src/lib/core/templates-entrypoint/base.ts
🪛 markdownlint-cli2 (0.22.1)
.changeset/entrypoint-tilde-clone-target.md

[warning] 5-5: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

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

470-500: Отличное покрытие тестами с документированием математических инвариантов!

Новые тесты демонстрируют образцовое следование coding guidelines:

  1. Документация: Включены все обязательные маркеры (CHANGE/WHY/QUOTE/REF/FORMAT THEOREM)
  2. Property-based testing: Использование fast-check для проверки инварианта на произвольных входах
  3. Математическая формализация: FORMAT THEOREM: expand("~") = /home/<sshUser> ∧ expand("~/p") = /home/<sshUser>/p
  4. Отрицательные проверки: Явно проверяется отсутствие старой логики с $HOME

Тесты гарантируют, что исправление работает корректно и не регрессирует в будущем.

Минорное улучшение (опционально):

Можно добавить тест для проверки идентичности вывода между packages/lib и packages/app (по аналогии с тестом на строке 503-505 для renderPostPushPrEnsure):

♻️ Предложение для гарантии синхронизации lib и app
it("keeps the lib and app tilde expansion logic in sync", () => {
  const libEntrypoint = renderEntrypoint(makeTemplateConfig({ sshUser: "testuser" }))
  const appEntrypoint = renderAppEntrypoint(makeTemplateConfig({ sshUser: "testuser" }))
  
  // Extract TARGET_DIR expansion logic from both
  const libTildeLogic = libEntrypoint.split('\n').filter(line => 
    line.includes('TARGET_DIR="/home/') || line.includes('if [[ "$TARGET_DIR" == "~"')
  ).join('\n')
  
  const appTildeLogic = appEntrypoint.split('\n').filter(line => 
    line.includes('TARGET_DIR="/home/') || line.includes('if [[ "$TARGET_DIR" == "~"')
  ).join('\n')
  
  expect(libTildeLogic).toBe(appTildeLogic)
})

Source: Coding guidelines

.gitkeep (1)

1-1: LGTM!

.changeset/entrypoint-tilde-clone-target.md (1)

1-16: Changeset правильно описывает исправление для issue #413.

Описание четко формулирует root cause ($HOME=/root при sshd) и решение (использование /home/ для tilde-расширения). Соответствует спеке и обоснованию в commit messages.

Markdownlint warning MD041 о first-line-heading — это false positive для стандартного changeset формата, который начинается с YAML front matter. Может быть проигнорирован.

packages/docker-git-session-sync/package.json (1)

3-3: LGTM!

packages/app/package.json (2)

3-3: LGTM!


1-128: Все три слоя когорты исправления tilde-расширения верифицированы и соответствуют спецификации.

Layer 1 (Реализация): ✅ Оба файла шаблонов entrypoint содержат правильные конструкции:

  • if [[ "$TARGET_DIR" == "~" ]]; then TARGET_DIR="/home/${config.sshUser}"
  • elif [[ "$TARGET_DIR" == "~/"* ]]; then TARGET_DIR="/home/${config.sshUser}${TARGET_DIR:1}"

Layer 2 (Тесты): ✅ packages/lib/tests/core/templates.test.ts содержит two уровня coverage:

  • Unit test: проверяет наличие условия и отсутствие использования $HOME
  • Property-based test (fc.property): валидирует инвариант expand("~") = /home/<sshUser> для всех генерируемых конфигов

Layer 3 (Changeset/Version): ✅ packages/app/CHANGELOG.md актуален, версия 1.3.5 с корректным dependency bump; PR #409 в 1.3.4 содержит описание фикса TARGET_DIR.

Comment thread packages/app/CHANGELOG.md Outdated
Comment on lines +3 to +11
## 1.3.5

### Patch Changes

- chore: automated version bump

- Updated dependencies []:
- @prover-coder-ai/docker-git-session-sync@1.0.63

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

CHANGELOG не содержит информации о реальном исправлении и нарушает Conventional Commits.

Запись для версии 1.3.5 содержит только generic "chore: automated version bump", что затрудняет понимание истории изменений. Для сравнения, запись для версии 1.3.4 (строки 12-23) содержит подробное описание исправления с ссылкой на PR.

Проблемы:

  1. Неправильный тип коммита: Для исправления бага должен использоваться fix(shell): а не chore:
  2. Отсутствует трассируемость: Нет ссылки на issue #413 или PR
  3. Нет описания изменения: Пользователи не поймут, что было исправлено

Согласно coding guidelines, commit messages должны следовать Conventional Commits с областями: feat(core), fix(shell), и т.д.

📝 Предложение для улучшения CHANGELOG
## 1.3.5

### Patch Changes

- [`#XXX`](https://github.com/ProverCoderAI/docker-git/pull/XXX) [`COMMIT_SHA`](https://github.com/ProverCoderAI/docker-git/commit/COMMIT_SHA) Thanks [`@author`](https://github.com/author)! - Fix tilde expansion in entrypoint TARGET_DIR to resolve against SSH user home instead of root's $HOME.

  When the entrypoint script runs as root (via sshd), `$HOME` points to `/root`,
  causing tilde (`~`) in `TARGET_DIR` to expand to `/root/app`. The unprivileged
  SSH user lacks write permissions there, so `git clone` failed and the workspace
  folder remained empty (issue `#413`). Now `~` explicitly expands to
  `/home/<sshUser>`, ensuring proper ownership and permissions.

- Updated dependencies []:
  - `@prover-coder-ai/docker-git-session-sync`@1.0.63
🤖 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/CHANGELOG.md` around lines 3 - 11, The CHANGELOG entry for
version 1.3.5 uses an incorrect commit type (chore instead of fix) and lacks
proper traceability and detailed description of the actual bug fix related to
tilde expansion in the entrypoint script. Update the entry to follow the
Conventional Commits format used in version 1.3.4 by changing the commit type to
fix(shell), adding a PR reference with link, including the commit SHA reference,
adding the author attribution, and replacing the generic message with a detailed
explanation of what was fixed regarding tilde expansion in TARGET_DIR and how it
resolves issue `#413`. Ensure the Updated dependencies section remains unchanged.

Source: Coding guidelines

Comment on lines 19 to 23
if [[ "$TARGET_DIR" == "~" ]]; then
TARGET_DIR="$HOME"
TARGET_DIR="/home/${config.sshUser}"
elif [[ "$TARGET_DIR" == "~/"* ]]; then
TARGET_DIR="$HOME\${TARGET_DIR:1}"
TARGET_DIR="/home/${config.sshUser}\${TARGET_DIR:1}"
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | ⚖️ Poor tradeoff

Дублирование логики между packages/lib и packages/app создает риск расхождения реализаций.

Функция renderEntrypointHeader и её логика раскрытия тильды идентично реализованы в обоих пакетах (packages/lib и packages/app). Хотя архитектурное ограничение "APP работает только с API, и не имеет доступа к LIB" объясняет необходимость дублирования, это создает следующие риски:

  1. Поддерживаемость: Будущие изменения потребуют синхронной правки в двух местах
  2. Расхождение: Высокий риск, что реализации разойдутся при неаккуратном изменении
  3. Нарушение DRY: Одна единица смысла должна иметь одно место определения

Рекомендация:

♻️ Стратегии для устранения дублирования

Вариант 1 (предпочтительный): Вынести общую логику генерации шаблонов в отдельный изолированный пакет @prover-coder-ai/docker-git-templates:

  • Оба пакета (lib и app) могут зависеть от него
  • Соблюдается архитектурное разделение
  • Единый источник истины для логики шаблонов

Вариант 2: Автоматическая синхронизация через ts-morph скрипты:

  • Скрипт копирует реализацию из lib в app при сборке
  • CI проверяет идентичность реализаций
  • Сохраняется текущая структура

Вариант 3: Тесты для гарантии идентичности:

  • Добавить property-based тест, проверяющий, что оба пакета генерируют идентичный вывод для одинаковых входов
  • Минимальное изменение, но не устраняет дублирование

Текущие тесты в packages/lib/tests/core/templates.test.ts (строка 503-505) проверяют синхронизацию между lib и app только для функции renderPostPushPrEnsure, но не для renderEntrypointHeader.

🤖 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/lib/core/templates-entrypoint/base.ts` around lines 19 - 23,
The function `renderEntrypointHeader` and its tilde path expansion logic
(handling "~" and "~/" prefixes) are duplicated identically in both packages/lib
and packages/app, creating maintenance and divergence risks. Extract this common
logic into a separate shared package (such as
`@prover-coder-ai/docker-git-templates`) that both packages can depend on,
ensuring a single source of truth. Alternatively, if architectural constraints
prevent a new shared package, implement a ts-morph synchronization script that
automatically copies the implementation from lib to app during build, and add CI
checks to verify the implementations remain identical. Additionally, expand the
existing test suite in `packages/lib/tests/core/templates.test.ts` to verify
that `renderEntrypointHeader` outputs are identical across both packages, not
just `renderPostPushPrEnsure`.

Source: Coding guidelines

Comment on lines +3 to +7
## 1.0.63

### Patch Changes

- chore: automated version bump

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Запись changelog должна содержать описание исправления, а не только "chore: automated version bump".

Текущая запись в CHANGELOG.md:

## 1.0.63

### Patch Changes

- chore: automated version bump

Однако changeset описывает конкретное исправление: фикс для issue #413 (app folder остаётся пустой при docker-git clone с tilde-путем, потому что tilde разрешается относительно $HOME=/root вместо /home/<sshUser>).

Запись changelog должна содержать пользовательское описание исправления (как, например, версия 1.0.10 с описанием "Add portable launch/build scripts..."), чтобы пользователи, обновляющие версию, поняли, что было исправлено.

📝 Предлагаемое исправление
 ## 1.0.63

 ### Patch Changes

-  - chore: automated version bump
+  - Fixed `docker-git clone` leaving workspace `app` folder empty when `TARGET_DIR` is a tilde path; tilde expansion now resolves to unprivileged SSH user home `/home/<sshUser>` instead of root `$HOME`
🤖 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/docker-git-session-sync/CHANGELOG.md` around lines 3 - 7, The
CHANGELOG.md entry for version 1.0.63 currently contains only a generic "chore:
automated version bump" message, but it should include a meaningful description
of the actual fix that was implemented. Replace the generic message in the Patch
Changes section with a user-facing description that explains what issue was
resolved, specifically that the fix addresses the tilde path resolution problem
in docker-git clone operations where the app folder remained empty due to tilde
being resolved relative to the wrong home directory. The description should be
specific enough that users updating the version understand what has been fixed,
following the format of previous changelog entries like version 1.0.10.

Comment on lines 19 to 23
if [[ "$TARGET_DIR" == "~" ]]; then
TARGET_DIR="$HOME"
TARGET_DIR="/home/${config.sshUser}"
elif [[ "$TARGET_DIR" == "~/"* ]]; then
TARGET_DIR="$HOME\${TARGET_DIR:1}"
TARGET_DIR="/home/${config.sshUser}\${TARGET_DIR:1}"
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Исправление корректно решает проблему раскрытия тильды, но отсутствует документация согласно coding guidelines.

Техническое изменение верно: когда entrypoint запускается от root (через sshd), переменная $HOME указывает на /root, что приводило к проблеме с правами доступа при git clone. Явное указание /home/${config.sshUser} гарантирует, что пути с тильдой раскрываются в домашнюю директорию SSH пользователя, где у него есть права на запись.

Однако согласно coding guidelines, код должен содержать функциональные комментарии для документирования изменения:

// CHANGE: replace $HOME with explicit /home/${config.sshUser} in tilde expansion
// WHY: entrypoint runs as root (via sshd), so $HOME=/root; expanding ~ against $HOME
//      resolved TARGET_DIR to /root/app, which unprivileged SSH user cannot write to,
//      causing git clone to fail and leaving workspace app folder empty (issue `#413`)
// QUOTE(ТЗ): "Почему-то при docker-git clone не делается git clone в папку app"
// REF: issue-413
// SOURCE: n/a
// FORMAT THEOREM: ∀sshUser: expand("~") = /home/sshUser ∧ expand("~/p") = /home/sshUser/p
// PURITY: CORE (pure string template generation)
// INVARIANT: generated bash expands ~ to dev-owned home, never root's $HOME
// COMPLEXITY: O(1)

As per coding guidelines, all changes must include CHANGE/WHY/QUOTE/REF/SOURCE/FORMAT THEOREM markers for traceability and formal reasoning.

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

In `@packages/lib/src/core/templates-entrypoint/base.ts` around lines 19 - 23, The
tilde expansion logic in the if/elif block for TARGET_DIR is missing required
documentation comments according to coding guidelines. Add functional comment
documentation above the TARGET_DIR assignment block that includes all required
markers: CHANGE (describing the replacement of $HOME with explicit
/home/${config.sshUser}), WHY (explaining that entrypoint runs as root via sshd
causing $HOME=/root and git clone failures), QUOTE (referencing the
requirement), REF (linking to issue `#413`), SOURCE, FORMAT THEOREM (defining the
expansion behavior), PURITY, INVARIANT (ensuring bash expands ~ to dev-owned
home, never root's), and COMPLEXITY. Follow the exact format shown in the review
comment with proper documentation structure.

Source: Coding guidelines

@konard

konard commented Jun 17, 2026

Copy link
Copy Markdown
Contributor Author

Working session summary

The fix is complete and pushed; 3 of 4 CI jobs (Snapshot, Checking Dependencies, Final Build) have passed and the "Check" job (lint + typecheck + tests) is still running. A background monitor (bn59vu2ew) will notify me when it finishes. Here's a summary of what was done:

Summary

Issue #413: docker-git clone left the workspace app folder empty (reporter saw ~/~/app (main)> with no files).

Root cause

The generated per-project entrypoint (templates-entrypoint/base.ts) runs as root under sshd, so $HOME = /root. A tilde TARGET_DIR (~ / ~/...) reaching the entrypoint was expanded against $HOME, resolving the clone target to /root/app. The auto-clone then runs as the unprivileged su - <sshUser>, which cannot write to the root-owned /root/appgit clone fails with permission denied → the app folder stays empty.

This is distinct from PR #409, which fixed the wrong file — the standalone base-image entrypoint.sh that the panel/CLI clone flow doesn't use, exactly as the user noted ("это было выполнено не верно").

Fix

Expand the tilde against the unprivileged user's home /home/${config.sshUser} instead of root's $HOME, in both template copies:

  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/src/lib/core/templates-entrypoint/base.ts

Verification

  • Reproduced in Docker: beforeresolved TARGET_DIR=/root/appPermission denied → empty workspace; afterresolved TARGET_DIR=/home/dev/app → clone succeeds with files present.
  • Added renderEntrypoint tilde target dir expansion tests in packages/lib/tests/core/templates.test.ts (including a property test). Confirmed they fail on the old $HOME code and pass with the fix. Full lib suite: 294/294 passing.
  • Added changeset entrypoint-tilde-clone-target.md (patch).

Delivered

I'll confirm once the final CI "Check" job reports its result.


This summary was automatically extracted from the AI working session output.

@konard

konard commented Jun 17, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Solution Draft Log

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost estimation:

  • Public pricing estimate: $8.597816
  • Calculated by Anthropic: $9.610245
  • Difference: $1.012429 (+11.78%)

📊 Context and tokens usage:

Claude Opus 4.8: (3 sub-sessions)

  1. 116.6K / 1M (12%) input tokens, 29.5K / 128K (23%) output tokens
  2. 116.0K / 1M (12%) input tokens, 41.7K / 128K (33%) output tokens
  3. 74.1K / 1M (7%) input tokens, 16.8K / 128K (13%) output tokens

Total: (22.1K new + 274.3K cache writes + 8.5M cache reads) input tokens, 101.3K output tokens, $8.597816 cost

🤖 Models used:

  • Tool: Anthropic Claude Code
  • Requested: opus
  • Model: Claude Opus 4.8 (claude-opus-4-8)

📎 Log file uploaded as Gist (3965KB)


Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard

konard commented Jun 17, 2026

Copy link
Copy Markdown
Contributor Author

✅ Ready to merge

This pull request is now ready to be merged:

  • All CI checks have passed
  • No merge conflicts
  • No pending changes

Monitored by hive-mind with --auto-restart-until-mergeable flag

konard and others added 2 commits June 17, 2026 07:00
…ntainer (ProverCoderAI#414)

main (ProverCoderAI#412) extracted the entrypoint templates from packages/lib into the new
@prover-coder-ai/docker-git-container package. Conflict resolution:
- tilde $HOME -> /home/<sshUser> fix now lives in
  packages/container/src/core/templates-entrypoint/base.ts (git rename-detected)
- its test moved to packages/container/tests/core/templates.test.ts
- dropped the deleted dead copy packages/app/src/lib/.../base.ts
- reverted stray version-bump artifacts (app/session-sync package.json + CHANGELOG);
  the changeset drives release versioning.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@skulidropek skulidropek merged commit 55169a8 into ProverCoderAI:main Jun 17, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Почему-то при docker-git clone не делается git clone в папку app

2 participants