diff --git a/.claude/code-paths b/.claude/code-paths index 3c11b1a..f39e01d 100644 --- a/.claude/code-paths +++ b/.claude/code-paths @@ -1,2 +1,3 @@ hooks/ skills/ +plugins/ diff --git a/CLAUDE.md b/CLAUDE.md index 4da0a06..abc1a72 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -24,6 +24,7 @@ ## Команды - `bash tests/run.sh [имя]` — весь набор тестов. Зелёным считается только весь набор. +- `claude plugin test plugins/feature`, `claude plugin validate plugins/feature` — тесты и манифест мода `/feature` (входят в `tests/run.sh`). Попробовать мод из worktree: `claude --plugin-dir /plugins/feature`. - `bash install.sh --check` — проверка окружения: бинарники, плагины, конфликты. - `bash install.sh` — установка глобальной части, идемпотентно. - `bash skills/harness-doctor/scripts/doctor.sh [проект]` — отчёт и самотест хуков. Только чтение. @@ -35,6 +36,7 @@ - `tests/run.sh` — автоматические тесты источников (хуки через фиктивный JSON, скрипты во временных каталогах, размеры). Самотест хуков в `doctor.sh` проверяет установленные копии; перед ним `bash install.sh`. - Ручная проверка хука: на main в любом репозитории попросить агента создать файл, ожидается `BLOCKED`. - `tests/` покрывает `role-hint` и скрипты `install.sh`, `doctor.sh`, `link-roles.sh`; регрессионные тесты `guard-main` и `require-plan` на реальных командах из транскриптов (бэклог ретро B2) пока не сделаны. +- `tests/test-feature-plugin.sh` прогоняет тесты мода `/feature` через `claude plugin test` (нужен `claude` в PATH, иначе пропуск с пометкой). Мод читает форматы обвязки — ledger, таблицу `## Findings`, `Decisions made without discussion`, планы; меняешь формат — правь мод и его тесты в том же PR (контракт — `plugins/feature/README.md`). ## Текущая работа Бэклог обвязки — `docs/retro/2026-10-11.md`, раздел 4 (B1–B12), решения владельца — раздел 5. Порядок: B1+B2 (guard-main по цели записи, тесты хуков), затем B5+B6 (роли и память, спека `docs/superpowers/specs/2026-10-11-roles-and-memory-design.md`), затем B3/B4/B10. Находки ретро маркируются `RT-n`. @@ -44,4 +46,4 @@ - Когда brainstorming классифицировал задачу как architectural, структуру change создать через `openspec new change ` (или `/opsx:propose `), а содержимое proposal.md, specs/ и design.md написать по итогам brainstorming. tasks.md из OpenSpec не заполнять — задачи живут в плане superpowers. - `/opsx:apply` не использовать: исполнение идёт через writing-plans и SDD/executing-plans. - `openspec archive ` — после merge PR, как часть чеклиста закрытия. -- Хук require-plan защищает любой каталог `src/` на любой глубине. Если код лежит иначе — перечислить каталоги (префиксы от корня, по одному в строке) в `.claude/code-paths`. В этом репозитории код — `hooks/` и `skills/`, они перечислены в `.claude/code-paths`. +- Хук require-plan защищает любой каталог `src/` на любой глубине. Если код лежит иначе — перечислить каталоги (префиксы от корня, по одному в строке) в `.claude/code-paths`. В этом репозитории код — `hooks/`, `skills/` и `plugins/`, они перечислены в `.claude/code-paths`. diff --git a/tests/test-feature-plugin.sh b/tests/test-feature-plugin.sh new file mode 100644 index 0000000..4657288 --- /dev/null +++ b/tests/test-feature-plugin.sh @@ -0,0 +1,20 @@ +# Мод /feature (plugins/feature): его тесты и проверка манифеста — часть набора обвязки. +# Мод читает форматы обвязки (ledger, ## Findings, Decisions в design.md, планы): правка формата +# без правки мода должна ронять этот набор. Нужен `claude` в PATH; без него — пропуск с пометкой. +P="$ROOT/plugins/feature" +assert_file "мод: манифест" "$P/.claude-plugin/plugin.json" +assert_grep "мод: имя feature" '"name": "feature"' "$P/.claude-plugin/plugin.json" +assert_file "мод: README с контрактом" "$P/README.md" +if command -v claude >/dev/null 2>&1; then + # claude читает свою конфигурацию из настоящего HOME, не из временного + out=$(HOME="$REAL_HOME" claude plugin test "$P" 2>&1); code=$? + if [ "$code" = 0 ] && printf '%s' "$out" | grep -qE '(^| )0 fail'; then + ok "мод: claude plugin test ($(printf '%s' "$out" | grep -oE '[0-9]+ pass' | head -1))" + else + fail "мод: claude plugin test" "exit $code; $(printf '%s' "$out" | grep -E 'fail|Error' | head -3 | tr '\n' ' ')" + fi + out=$(HOME="$REAL_HOME" claude plugin validate "$P" 2>&1); code=$? + [ "$code" = 0 ] && ok "мод: claude plugin validate" || fail "мод: claude plugin validate" "exit $code; $(printf '%s' "$out" | tail -3 | tr '\n' ' ')" +else + printf ' skip мод: claude не найден в PATH — тесты мода не запускались\n' +fi