# Spec Delta: dsh-superpowers-git ## Purpose `dsh/install.sh --skills` получает superpowers из git сам: первый запуск — клон, следующие — обновление до последнего коммита default-ветки. Явные источники остаются приоритетнее и не ходят в сеть; `~/.claude` — по-прежнему legacy-fallback с предупреждением. ## ADDED Requirements ### Requirement: Свежий superpowers из git `dsh/install.sh --skills` MUST получать superpowers-скиллы из git, когда явный источник не задан: клонировать при отсутствии клона и обновлять при каждом следующем запуске. - Репозиторий по умолчанию — `https://github.com/obra/superpowers`; `$DSH_SUPERPOWERS_REPO` MUST переопределять его (зеркала, локальные репозитории в тестах) и MUST применяться к уже существующему клону: перед `fetch` URL `origin` приводится к заданному репозиторию. - Клон — `git clone --depth 1 $DSH_HOME/superpowers`. - Обновление — `git -C $DSH_HOME/superpowers fetch --depth 1 origin` и `git reset --hard FETCH_HEAD`; рабочее дерево управляемое, локальные правки там не сохраняются. - После клона/обновления источником MUST считаться `$DSH_HOME/superpowers/skills` (или сам каталог), только если в нём есть `using-superpowers/SKILL.md`. - Вывод `--skills` MUST называть источник и git-версию: `(source: , git )`. - `--check` MUST NOT выполнять сетевые операции: он показывает состояние существующего клона (`ok: superpowers source (, git )`) и не создаёт `$DSH_HOME/superpowers`. #### Scenario: Первый запуск клонирует источник - **WHEN** `$DSH_HOME/superpowers` отсутствует, `DSH_SUPERPOWERS_REPO` указывает на репозиторий superpowers - **THEN** `--skills` клонирует его в `$DSH_HOME/superpowers`, копирует скиллы в `$DSH_HOME/skills` и печатает `git ` #### Scenario: Повторный запуск обновляет клон - **WHEN** клон уже есть, а в источнике появился новый коммит со скиллом - **THEN** повторный `--skills` обновляет клон до нового коммита, и новый скилл оказывается в `$DSH_HOME/skills` #### Scenario: Нет сети, клон есть - **WHEN** обновление клона не удалось (недоступный репозиторий), но `$DSH_HOME/superpowers` содержит `using-superpowers/SKILL.md` - **THEN** `--skills` печатает `WARN`, использует кэш, копирует скиллы и завершается кодом 0 #### Scenario: Нет сети и нет клона - **WHEN** клонирование не удалось, клона и других источников нет, `$DSH_HOME/skills` пуст - **THEN** `--skills` печатает `FAIL` с репозиторием и подсказкой `--superpowers-from`, код 1; недоклонированный каталог не остаётся на диске #### Scenario: Ручная копия без git - **WHEN** `$DSH_HOME/superpowers` существует, не является git-клоном и содержит `using-superpowers/SKILL.md` - **THEN** каталог используется как есть, `--skills` печатает `WARN` о том, что он не будет обновляться #### Scenario: --check не ходит в сеть - **WHEN** клон существует, а `DSH_SUPERPOWERS_REPO` указывает на недоступный репозиторий - **THEN** `--check` печатает `ok: superpowers source (, git )`, завершается без сетевых ошибок и ничего не клонирует ## MODIFIED Requirements ### Requirement: Источник superpowers задаётся при установке `dsh/install.sh --skills` SHALL разрешать источник superpowers-скиллов в порядке приоритета. - Порядок: `--superpowers-from ` → `$DSH_SUPERPOWERS_SOURCE` → git-клон `$DSH_HOME/superpowers` (обновить существующий или склонировать из `$DSH_SUPERPOWERS_REPO`/`https://github.com/obra/superpowers`) → legacy-кэш Claude Code → legacy `~/.claude/skills`. - Для явного источника (`--superpowers-from`, `$DSH_SUPERPOWERS_SOURCE`) допускаются обе формы: корень superpowers (есть `skills/using-superpowers/SKILL.md`) или сам каталог `skills`; сеть при явном источнике MUST NOT использоваться. - Явно заданный, но невалидный источник MUST приводить к `FAIL` и коду возврата 1: тихий откат на git/legacy запрещён. - Копирование MUST быть заменой каталога назначения (`rm -rf` + `cp -R`), а не симлинком: `~/.dsh/skills` не должен зависеть от каталога-источника. #### Scenario: Явный источник без ~/.claude - **WHEN** `HOME` — пустой temp-каталог без `~/.claude`, а `--superpowers-from` указывает на каталог superpowers - **THEN** `--skills` копирует скиллы в `$DSH_HOME/skills`, печатает источник и завершается кодом 0 #### Scenario: Переменная окружения вместо флага - **WHEN** задан `DSH_SUPERPOWERS_SOURCE=` и флаг `--superpowers-from` не передан - **THEN** источник берётся из переменной; поведение совпадает с флагом #### Scenario: Флаг важнее переменной - **WHEN** заданы и `--superpowers-from`, и `DSH_SUPERPOWERS_SOURCE` - **THEN** используется каталог из флага #### Scenario: Невалидный явный источник - **WHEN** `--superpowers-from` указывает на каталог без `using-superpowers/SKILL.md` - **THEN** `--skills` печатает `FAIL` с ожидаемой структурой и завершается кодом 1, ничего не копируя из git/legacy-источников #### Scenario: Явный источник не трогает git - **WHEN** `--superpowers-from` задан, а `$DSH_HOME/superpowers` отсутствует - **THEN** `--skills` не создаёт `$DSH_HOME/superpowers` ### Requirement: Отсутствие источника не бывает тихим Если источник superpowers не найден, `--skills` MUST различать первичную и повторную установку и MUST NOT завершаться успехом молча. - Если `$DSH_HOME/skills/using-superpowers/SKILL.md` уже существует — `WARN` «источник не найден, копии сохранены» и код 0 (идемпотентный повтор). - Если копий нет — `FAIL` с репозиторием (`$DSH_SUPERPOWERS_REPO`) и подсказкой `--superpowers-from `; код возврата 1. - Локальные скиллы обвязки (`dsh/skills/*`: `role`, `sdd`) MUST ставиться в обоих случаях: они не зависят от superpowers. #### Scenario: Первая установка без источника - **WHEN** `HOME` пуст, `$DSH_HOME/skills` не существует, git-источник недоступен и других источников нет - **THEN** `--skills` печатает `FAIL`, код 1, но `$DSH_HOME/skills/role/SKILL.md` и `$DSH_HOME/skills/sdd/SKILL.md` на месте #### Scenario: Повторная установка без источника - **WHEN** `$DSH_HOME/skills/using-superpowers/SKILL.md` уже есть, источника нет - **THEN** `--skills` печатает `WARN`, код 0, установленные скиллы не удалены ### Requirement: ~/.claude — только legacy-fallback с предупреждением superpowers-скиллы и роли MUST иметь рабочий путь `~/.dsh`; пути `~/.claude` SHALL оставаться fallback'ом для машин, где `--skills --roles` ещё не перезапускали, и MUST сопровождаться предупреждением. - Установка: legacy-кэш Claude Code и `~/.claude/skills` допустимы как источник, но `--skills` печатает `WARN: legacy superpowers source` с подсказкой на git-источник или `--superpowers-from`. - `--check`: legacy-источник — `WARN`, git-клон/явный источник — `ok`, отсутствие — `WARN` с подсказкой, невалидный явный источник — `FAIL` и код 1. - Runtime: bootstrap и резолвер ролей сохраняют порядок `~/.dsh` → `~/.claude`, но при выборе legacy-пути один раз за процесс пишут в лог предупреждение. - Удаление fallback'ов — отдельное изменение; в этом change они не удаляются. #### Scenario: Legacy-кэш как источник установки - **WHEN** в `HOME` есть только кэш Claude Code с superpowers, `$DSH_HOME` пуст, git-источник недоступен - **THEN** `--skills` копирует скиллы и печатает `WARN: legacy superpowers source` #### Scenario: Runtime-предупреждение - **WHEN** bootstrap резолвит `using-superpowers` из `~/.claude/...` - **THEN** в лог один раз за процесс попадает предупреждение с предложением выполнить `dsh/install.sh --skills` #### Scenario: ~/.dsh приоритетнее - **WHEN** существуют и `~/.dsh/skills/using-superpowers/SKILL.md`, и legacy-копия - **THEN** используется `~/.dsh`, предупреждения нет