Merge pull request 'chore(openspec): архив change dsh-install-source (#49)' (#65) from chore/archive-dsh-install-source into main
This commit is contained in:
commit
ec7c028f6b
149
openspec/specs/dsh-install/spec.md
Normal file
149
openspec/specs/dsh-install/spec.md
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
# dsh-install Specification
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
Слой установки DSH-обвязки: откуда берутся superpowers-скиллы и роли, что
|
||||||
|
делает `dsh/install.sh --skills/--roles`, какие пути попадают в установленные
|
||||||
|
инструкции. В Claude Code источником служит кэш плагина в `~/.claude`; в DSH
|
||||||
|
источник задаётся установщиком явно (аргумент, переменная или пиннинг в
|
||||||
|
`~/.dsh`), а `~/.claude` остаётся только legacy-fallback'ом с предупреждением.
|
||||||
|
Контракт нужен, чтобы свежая установка на машине без Claude Code проходила
|
||||||
|
полный цикл #48 и чтобы путь `~/.claude` не возвращался в runtime незаметно.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
### Requirement: Источник superpowers задаётся при установке
|
||||||
|
`dsh/install.sh --skills` SHALL разрешать источник superpowers-скиллов в
|
||||||
|
порядке приоритета и MUST NOT исполнять `git clone` и любые сетевые операции.
|
||||||
|
|
||||||
|
- Порядок: `--superpowers-from <dir>` → `$DSH_SUPERPOWERS_SOURCE` →
|
||||||
|
`$DSH_HOME/superpowers/skills` (пиннинг; допускается и корень
|
||||||
|
`$DSH_HOME/superpowers` с подкаталогом `skills/`) → legacy-кэш Claude Code →
|
||||||
|
legacy `~/.claude/skills`.
|
||||||
|
- Для явного источника (`--superpowers-from`, `$DSH_SUPERPOWERS_SOURCE`)
|
||||||
|
допускаются обе формы: корень superpowers (есть `skills/using-superpowers/SKILL.md`)
|
||||||
|
или сам каталог `skills`.
|
||||||
|
- Явно заданный, но невалидный источник MUST приводить к `FAIL` и коду
|
||||||
|
возврата 1: тихий откат на 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, ничего не копируя из legacy-источников
|
||||||
|
|
||||||
|
#### Scenario: Пиннинг в ~/.dsh
|
||||||
|
- **WHEN** существует `$DSH_HOME/superpowers/skills/using-superpowers/SKILL.md`
|
||||||
|
и флаг/переменная не заданы
|
||||||
|
- **THEN** источником служит этот каталог, `--check` печатает
|
||||||
|
`ok: superpowers source (<path>)`
|
||||||
|
|
||||||
|
### Requirement: Отсутствие источника не бывает тихим
|
||||||
|
Если источник superpowers не найден, `--skills` MUST различать первичную и
|
||||||
|
повторную установку и MUST NOT завершаться успехом молча.
|
||||||
|
|
||||||
|
- Если `$DSH_HOME/skills/using-superpowers/SKILL.md` уже существует —
|
||||||
|
`WARN` «источник не найден, копии сохранены» и код 0 (идемпотентный повтор).
|
||||||
|
- Если копий нет — `FAIL` с готовой командой получения источника
|
||||||
|
(`git clone --depth 1 https://github.com/obra/superpowers ~/.dsh/superpowers`)
|
||||||
|
и код возврата 1.
|
||||||
|
- Локальные скиллы обвязки (`dsh/skills/*`: `role`, `sdd`) MUST ставиться в
|
||||||
|
обоих случаях: они не зависят от superpowers.
|
||||||
|
|
||||||
|
#### Scenario: Первая установка без источника
|
||||||
|
- **WHEN** `HOME` пуст, `$DSH_HOME/skills` не существует, источника нет
|
||||||
|
- **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` с
|
||||||
|
подсказкой перейти на пиннинг/флаг.
|
||||||
|
- `--check`: legacy-источник — `WARN`, явный/пиннинг — `ok`, отсутствие —
|
||||||
|
`WARN` с подсказкой, невалидный явный источник — `FAIL` и код 1
|
||||||
|
(пользователь задал его сам, подсказка «нет источника» здесь неверна).
|
||||||
|
- Runtime: bootstrap и резолвер ролей сохраняют порядок `~/.dsh` → `~/.claude`,
|
||||||
|
но при выборе legacy-пути один раз за процесс пишут в лог предупреждение.
|
||||||
|
- Удаление fallback'ов — отдельное изменение; в этом change они не удаляются.
|
||||||
|
|
||||||
|
#### Scenario: Legacy-кэш как источник установки
|
||||||
|
- **WHEN** в `HOME` есть только кэш Claude Code с superpowers, `$DSH_HOME` пуст
|
||||||
|
- **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`, предупреждения нет
|
||||||
|
|
||||||
|
### Requirement: Установленные инструкции DSH не ссылаются на ~/.claude
|
||||||
|
`dsh/install.sh --global` MUST писать `$DSH_HOME/AGENTS.md` так, чтобы пути
|
||||||
|
ролей указывали на DSH-слой, а формат инструкций не выдавался за runtime
|
||||||
|
Claude Code.
|
||||||
|
|
||||||
|
- Строки `~/.claude/roles` в установленной копии MUST заменяться на
|
||||||
|
`~/.dsh/roles`, а adapter-шапка MUST NOT называть пути `~/.claude`: в
|
||||||
|
установленном файле не остаётся ни одного такого пути. `global/CLAUDE.md` в
|
||||||
|
репозитории MUST NOT меняться (его читает Claude Code).
|
||||||
|
- Шапка установленного файла MUST говорить, что проектный `CLAUDE.md` /
|
||||||
|
`AGENTS.md` — это формат файлов инструкций DSH, а не запущенный Claude Code,
|
||||||
|
и что роли лежат в `~/.dsh/roles` (`--roles`), а superpowers-скиллы — в
|
||||||
|
`~/.dsh/skills` (`--skills`).
|
||||||
|
- Повторный `--global` обязан делать бэкап прежнего `AGENTS.md` (как сейчас).
|
||||||
|
|
||||||
|
#### Scenario: Пути ролей после установки
|
||||||
|
- **WHEN** выполнен `--global` во временный `DSH_HOME`
|
||||||
|
- **THEN** в `AGENTS.md` есть `~/.dsh/roles/dev.md` и нет ни одного пути
|
||||||
|
`~/.claude`
|
||||||
|
|
||||||
|
#### Scenario: global/CLAUDE.md не тронут
|
||||||
|
- **WHEN** выполнен `--global`
|
||||||
|
- **THEN** `global/CLAUDE.md` в репозитории побайтно не изменился
|
||||||
|
|
||||||
|
### Requirement: Чистый HOME без ~/.claude проходит установку
|
||||||
|
Установка, bootstrap и skill `role` MUST работать на машине, где Claude Code
|
||||||
|
никогда не устанавливался.
|
||||||
|
|
||||||
|
- `--global --skills --roles` с явным источником superpowers в пустом `HOME`
|
||||||
|
MUST создавать `$DSH_HOME/{AGENTS.md,skills/using-superpowers/SKILL.md,skills/role/SKILL.md,skills/sdd/SKILL.md,roles/dev.md}`.
|
||||||
|
- bootstrap MUST резолвить скилл из `$DSH_HOME/skills` при `home` этого HOME и
|
||||||
|
MUST NOT обращаться к `~/.claude`.
|
||||||
|
- Резолвер ролей MUST находить `$DSH_HOME/roles` при `home` этого HOME.
|
||||||
|
|
||||||
|
#### Scenario: Установка в чистый HOME
|
||||||
|
- **WHEN** `HOME` — пустой temp-каталог, `DSH_HOME=$HOME/.dsh`,
|
||||||
|
`--superpowers-from` указывает на каталог superpowers
|
||||||
|
- **THEN** `--global --skills --roles` завершается кодом 0, все перечисленные
|
||||||
|
файлы на месте, `--check` зелёный по skills и roles
|
||||||
|
|
||||||
|
#### Scenario: Bootstrap в чистом HOME
|
||||||
|
- **WHEN** `prepareBootstrap({ home: <temp HOME> })` вызывается после установки
|
||||||
|
- **THEN** выбранный путь — `$HOME/.dsh/skills/using-superpowers/SKILL.md`,
|
||||||
|
текст содержит маркер `<!-- DSH-HARNESS-BOOTSTRAP:... -->`, предупреждений о
|
||||||
|
legacy нет
|
||||||
Loading…
x
Reference in New Issue
Block a user