10 KiB
Raw Blame History

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 нет