157 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 переопределять его (зеркала, локальные
репозитории в тестах).
- Клон — `git clone --depth 1 <repo> $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: <path>, git <short-sha>)`.
- `--check` MUST NOT выполнять сетевые операции: он показывает состояние
существующего клона (`ok: superpowers source (<path>, git <sha>)`) и не
создаёт `$DSH_HOME/superpowers`.
#### Scenario: Первый запуск клонирует источник
- **WHEN** `$DSH_HOME/superpowers` отсутствует, `DSH_SUPERPOWERS_REPO` указывает
на репозиторий superpowers
- **THEN** `--skills` клонирует его в `$DSH_HOME/superpowers`, копирует скиллы в
`$DSH_HOME/skills` и печатает `git <sha>`
#### 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 (<path>, git <sha>)`,
завершается без сетевых ошибок и ничего не клонирует
## MODIFIED Requirements
### Requirement: Источник superpowers задаётся при установке
`dsh/install.sh --skills` SHALL разрешать источник superpowers-скиллов в
порядке приоритета.
- Порядок: `--superpowers-from <dir>` → `$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=<dir>` и флаг `--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 <dir>`; код возврата 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`, предупреждения нет