# ADR-073: create-readme local-mode path resolution via context.worktree

## Статус
Accepted (2026-07-31)

## Контекст

Тулза `create-readme` (`.opencode/tools/create-readme.ts`) работает в двух
режимах: локальном (`file_path`, без `repo`) и удалённом (`repo: owner/name`
через `gh api`). В удалённом режиме `spawnSync` вызовы корректно передавали
`cwd: context.worktree` — рабочую директорию сессии пользователя. В локальном
режиме `writeFileSync(file_path, ...)` / `readFileSync(file_path, ...)`
вызывались с относительным `file_path` (default `README.md`), который
резолвился относительно **CWD процесса плагина Bun**, а не относительно
`context.worktree`. В продакшене CWD плагина ≠ рабочая директория
пользователя — файл писался/читался не туда, отчёт `README.md created at
README.md` был ложным success (issue #148).

Асимметрия: `spawnSync` получал `cwd`, а `fs.*Sync` — нет. Тестовый лоадер
`tests/_ts_loader.mjs` не поддерживал `import { readFileSync, writeFileSync }
from "fs"` и расширенный TS-синтаксис (многострочные type-алиасы, non-null
assertions, type annotations в переменных) — локальный режим тулзы нельзя
было протестировать.

## Решение

1. **Резолв пути относительно worktree**: `const absPath =
   path.resolve(context.worktree, file_path)` — симметрично с `spawnSync`
   в удалённом режиме. `writeFileSync(absPath, ...)` / `readFileSync(absPath,
   ...)` работают с абсолютным путём. Существующий файл гарантированно
   перезаписывается.

2. **Расширение `_ts_loader.mjs`**: `stripTs` теперь обрабатывает `fs`
   импорты, многострочные `type X = { ... }`, type annotations в
   `const/let/var`, non-null assertions `x!`. `loadTool(spawnSyncImpl,
   fsImpl)` передаёт `fs` модуль в sandbox. Это открывает возможность
   тестировать любую тулзу, использующую `fs` в локальном режиме.

## Альтернативы

- **`process.chdir(context.worktree)` в начале `execute()`**: меняло бы CWD
  процесса, но побочные эффекты на другие тулзы в том же процессе
  неприемлемы (гонки, неявное состояние). Отвергнуто.

- **Передача `file_path` как абсолютного всегда (валидировать на входе)**:
  ломало бы существующие вызовы с относительным `file_path` (default
  `README.md`). `path.resolve(worktree, file_path)` прозрачно обрабатывает
  оба случая (относительный → относительно worktree; абсолютный → как есть).

- **Не расширять лоадер, тестировать только через интеграцию**: медленнее,
  хрупче, не ловит регрессии на уровне `execute()`. Расширение лоадера
  позволяет точечные unit-тесты с реальным `fs` во временных директориях.