157 lines
10 KiB
Markdown
157 lines
10 KiB
Markdown
# 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`, предупреждения нет
|