@rt-tools/agent-kit 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +235 -18
- package/assets/agents/business-analyst.md +74 -0
- package/assets/agents/project-manager.md +70 -0
- package/assets/agents/qa-engineer.md +72 -0
- package/assets/agents/skill-curator.md +110 -0
- package/assets/agents/spec-critic.md +44 -0
- package/assets/agents/spec-writer.md +50 -0
- package/assets/checks/board.github.mjs +286 -0
- package/assets/checks/check-board.github.mjs +188 -0
- package/assets/checks/check-doc-paths.mjs +163 -0
- package/assets/checks/check-dupes.mjs +277 -0
- package/assets/checks/check-lib-layers.mjs +573 -0
- package/assets/checks/check-reuse.mjs +208 -0
- package/assets/checks/check-schema-drift.mjs +186 -0
- package/assets/checks/check-specs.mjs +1007 -0
- package/assets/checks/check-styles.mjs +109 -0
- package/assets/checks/rt-kit-checks.config.mjs +134 -0
- package/assets/checks/task-new.github.mjs +198 -0
- package/assets/commands/skill-curator.md +70 -0
- package/assets/defaults/gate-map.sh +100 -0
- package/assets/defaults/project.sh +179 -0
- package/assets/hooks/browser-device-id.sh +20 -0
- package/assets/hooks/browser-guard-device-id.sh +28 -0
- package/assets/hooks/browser-guard-no-asking.sh +27 -0
- package/assets/hooks/browser-guard-no-listing.sh +18 -0
- package/assets/hooks/browser-guard-no-other-drivers.sh +79 -0
- package/assets/hooks/browser-guard-require-select.sh +54 -0
- package/assets/hooks/commit-msg.sh +26 -0
- package/assets/hooks/constitution-index.sh +43 -0
- package/assets/hooks/dev-server-guard.sh +115 -0
- package/assets/hooks/docs-guard.sh +282 -0
- package/assets/hooks/git-guard-delivery.sh +167 -0
- package/assets/hooks/git-guard-main.sh +73 -0
- package/assets/hooks/git-guard-push-tests.sh +94 -0
- package/assets/hooks/glossary-load.sh +23 -0
- package/assets/hooks/lint-after-edit.sh +219 -0
- package/assets/hooks/qa-dataid-guard.sh +121 -0
- package/assets/hooks/reuse-first-guard.sh +154 -0
- package/assets/hooks/skill-gate-rearm.sh +23 -0
- package/assets/hooks/skill-gate.sh +128 -0
- package/assets/hooks/skill-loaded.sh +21 -0
- package/assets/hooks/sql-guard.sh +679 -0
- package/assets/hooks/task-context-load.sh +100 -0
- package/assets/hooks/task-flow-guard.sh +107 -0
- package/assets/laws/{access.md → application/access.md} +1 -4
- package/assets/laws/{locales.md → application/locales.md} +1 -3
- package/assets/laws/application/money.md +41 -0
- package/assets/laws/application/ownership.md +32 -0
- package/assets/laws/{search-visibility.md → application/search-visibility.md} +1 -1
- package/assets/laws/code-structure.md +7 -6
- package/assets/laws/delivery.md +53 -3
- package/assets/laws/entity-editing.md +49 -55
- package/assets/laws/entity-models.md +4 -14
- package/assets/laws/frontend-application.md +5 -5
- package/assets/laws/lib-imports.md +14 -1
- package/assets/laws/lists.md +33 -0
- package/assets/laws/navigation.md +40 -0
- package/assets/laws/project-documentation.md +17 -8
- package/assets/laws/reuse-first.md +26 -21
- package/assets/laws/shared-code.md +13 -1
- package/assets/laws/verifiability.md +17 -1
- package/assets/laws/work-conduct.md +48 -0
- package/assets/patterns/admin-lists-screen.md +131 -0
- package/assets/patterns/admin-nav-item.md +71 -0
- package/assets/patterns/angular-patterns-state.md +101 -0
- package/assets/patterns/api-layer-pair.md +88 -0
- package/assets/patterns/browser-verification-measure.md +86 -0
- package/assets/patterns/browser-verification-stand.md +143 -0
- package/assets/patterns/component-structure-new.md +99 -0
- package/assets/patterns/dependencies-upgrade.md +65 -0
- package/assets/patterns/doc-style-sweep.md +137 -0
- package/assets/patterns/doc-style-write.md +109 -0
- package/assets/patterns/entity-aside.md +136 -0
- package/assets/patterns/entity-models-new.md +124 -0
- package/assets/patterns/entity-store.md +91 -0
- package/assets/patterns/git-workflow-commit.azure.md +259 -0
- package/assets/patterns/git-workflow-commit.github.md +333 -0
- package/assets/patterns/git-workflow-commit.gitlab.md +283 -0
- package/assets/patterns/git-workflow-merge.md +99 -0
- package/assets/patterns/git-workflow-migration.md +88 -0
- package/assets/patterns/git-workflow-restart.md +49 -0
- package/assets/patterns/lib-layers-move.md +95 -0
- package/assets/patterns/lib-layers-new.md +82 -0
- package/assets/patterns/ownership-scope-resolve.md +69 -0
- package/assets/patterns/permissions-procedure.md +71 -0
- package/assets/patterns/platform-access-di.md +84 -0
- package/assets/patterns/pricing-quote.md +71 -0
- package/assets/patterns/reuse-first-extend.md +73 -0
- package/assets/patterns/seo-page.md +104 -0
- package/assets/patterns/seo-verify.md +83 -0
- package/assets/patterns/shared-code-new.md +86 -0
- package/assets/patterns/spec-driven-domain.md +107 -0
- package/assets/patterns/spec-driven-rule.md +127 -0
- package/assets/patterns/styling-bem-component.md +88 -0
- package/assets/patterns/styling-bem-layout.md +73 -0
- package/assets/patterns/task-flow-close.md +90 -0
- package/assets/patterns/task-flow-resume.md +94 -0
- package/assets/patterns/task-flow-start.md +117 -0
- package/assets/patterns/testing-e2e.md +92 -0
- package/assets/patterns/testing-unit.md +117 -0
- package/assets/patterns/translations-key.md +64 -0
- package/assets/patterns/ts-procedure.md +65 -0
- package/assets/rules/angular-patterns.md +71 -0
- package/assets/rules/api-layer.md +71 -0
- package/assets/rules/browser-verification.md +87 -0
- package/assets/rules/component-structure.md +64 -0
- package/assets/rules/dependencies.md +66 -0
- package/assets/rules/doc-style.md +103 -0
- package/assets/rules/entity-conventions.md +78 -0
- package/assets/rules/entity-models.md +70 -0
- package/assets/rules/git-workflow.azure.md +116 -0
- package/assets/rules/git-workflow.github.md +123 -0
- package/assets/rules/git-workflow.gitlab.md +113 -0
- package/assets/rules/lib-layers.md +80 -0
- package/assets/rules/lists.md +73 -0
- package/assets/rules/navigation.md +78 -0
- package/assets/rules/ownership-scope.md +63 -0
- package/assets/rules/permissions.md +70 -0
- package/assets/rules/platform-access.md +77 -0
- package/assets/rules/pricing.md +64 -0
- package/assets/rules/reuse-first.md +83 -0
- package/assets/rules/seo.md +71 -0
- package/assets/rules/shared-code.md +70 -0
- package/assets/rules/spec-driven.md +135 -0
- package/assets/rules/styling-bem.md +74 -0
- package/assets/rules/task-flow.md +110 -0
- package/assets/rules/testing.md +100 -0
- package/assets/rules/translations.md +69 -0
- package/assets/rules/typescript-conventions.md +76 -0
- package/assets/skills/agent-kit.md +81 -0
- package/assets/skills/write-a-skill.md +108 -0
- package/assets/templates/gate-map.sh +45 -0
- package/assets/templates/implementation.md +44 -0
- package/assets/templates/pattern.md +5 -1
- package/assets/templates/project.sh +54 -0
- package/assets/templates/rule.md +12 -23
- package/assets/variants.json +20 -0
- package/assets/workflows/feature.js +134 -0
- package/assets/workflows/plan.js +150 -0
- package/bin/agent-kit.d.ts.map +1 -1
- package/bin/agent-kit.js +78 -5
- package/bin/agent-kit.js.map +1 -1
- package/bin/prompt.d.ts +5 -0
- package/bin/prompt.d.ts.map +1 -1
- package/bin/prompt.js +19 -7
- package/bin/prompt.js.map +1 -1
- package/index.d.ts +1 -0
- package/index.d.ts.map +1 -1
- package/index.js +1 -0
- package/index.js.map +1 -1
- package/lib/assets.d.ts +14 -1
- package/lib/assets.d.ts.map +1 -1
- package/lib/assets.js +23 -2
- package/lib/assets.js.map +1 -1
- package/lib/catalog.d.ts +52 -5
- package/lib/catalog.d.ts.map +1 -1
- package/lib/catalog.js +104 -16
- package/lib/catalog.js.map +1 -1
- package/lib/commands.d.ts +22 -1
- package/lib/commands.d.ts.map +1 -1
- package/lib/commands.js +218 -11
- package/lib/commands.js.map +1 -1
- package/lib/companion.d.ts +57 -0
- package/lib/companion.d.ts.map +1 -0
- package/lib/companion.js +60 -0
- package/lib/companion.js.map +1 -0
- package/lib/config.d.ts +42 -2
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +60 -2
- package/lib/config.js.map +1 -1
- package/lib/freshness.d.ts +14 -0
- package/lib/freshness.d.ts.map +1 -0
- package/lib/freshness.js +116 -0
- package/lib/freshness.js.map +1 -0
- package/lib/hooks-map.d.ts +24 -0
- package/lib/hooks-map.d.ts.map +1 -0
- package/lib/hooks-map.js +72 -0
- package/lib/hooks-map.js.map +1 -0
- package/lib/integrity.d.ts +36 -0
- package/lib/integrity.d.ts.map +1 -0
- package/lib/integrity.js +44 -0
- package/lib/integrity.js.map +1 -0
- package/lib/picker.d.ts +11 -1
- package/lib/picker.d.ts.map +1 -1
- package/lib/picker.js +44 -6
- package/lib/picker.js.map +1 -1
- package/lib/stamp.d.ts +2 -5
- package/lib/stamp.d.ts.map +1 -1
- package/lib/stamp.js +25 -10
- package/lib/stamp.js.map +1 -1
- package/lib/sync.d.ts +29 -0
- package/lib/sync.d.ts.map +1 -1
- package/lib/sync.js +78 -4
- package/lib/sync.js.map +1 -1
- package/lib/variants.d.ts +44 -0
- package/lib/variants.d.ts.map +1 -0
- package/lib/variants.js +82 -0
- package/lib/variants.js.map +1 -0
- package/package.json +1 -1
- package/rt-tools-agent-kit-0.4.0.tgz +0 -0
- package/assets/laws/admin-lists.md +0 -35
- package/assets/laws/admin-navigation.md +0 -38
- package/rt-tools-agent-kit-0.2.0.tgz +0 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-kit
|
|
3
|
+
description: Переносимый слой правил агента — законы, правила, хуки и проверки, которые везёт пакет, а дерево настраивает надстройками. Брать, когда правится файл с шапкой rt-kit, обновляется пакет, отказывает `sync --check`, или своё поведение надо дописать поверх пакетного. Как заводится сам скил — write-a-skill; устройство слоёв текста — spec-driven.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Переносимый слой правил
|
|
7
|
+
|
|
8
|
+
Законы, правила, паттерны, хуки, проверки и роли везёт пакет; дерево берёт их раскладкой и
|
|
9
|
+
настраивает надстройками. Разложенный файл несёт шапку и правке не подлежит — правится либо
|
|
10
|
+
пакет, либо надстройка.
|
|
11
|
+
|
|
12
|
+
## Когда брать
|
|
13
|
+
|
|
14
|
+
- В файле, который собираешься править, стоит шапка
|
|
15
|
+
`rt-kit v<версия> · <ресурс> · <сумма> · правится надстройкой, не здесь`.
|
|
16
|
+
- Обновился пакет, или `sync --check` отказал в гейте пуша.
|
|
17
|
+
- Своё поведение надо дописать поверх пакетного: гард, карта гейта, набор проверок.
|
|
18
|
+
- Пакет ставится в дерево, где хуки и проверки уже свои.
|
|
19
|
+
|
|
20
|
+
## Где что настраивается
|
|
21
|
+
|
|
22
|
+
| Что меняешь | Куда правка |
|
|
23
|
+
| ---------------------------------------------- | -------------------------------------------------- |
|
|
24
|
+
| какое правило гейт требует под какой файл | `.claude/rt-kit/gate-map.sh` — своя `skill_for` |
|
|
25
|
+
| порты, адреса, линтеры, форма ветки, инвентарь | `.claude/rt-kit/project.sh` — свои `rt_*` |
|
|
26
|
+
| пути и идентификаторы, которыми живут проверки | `.claude/rt-kit/checks.json` |
|
|
27
|
+
| раздел разложенного текста | `.claude/rt-kit/overrides/<идентификатор ресурса>` |
|
|
28
|
+
| что брать, а от чего отказаться | `.claude/rt-kit.json`, ключи `only` и `skip` |
|
|
29
|
+
| сам механизм — гард, проверка, текст правила | ресурс в пакете |
|
|
30
|
+
|
|
31
|
+
Надстройка объявляет функцию заново и вправе позвать умолчание тем же именем с суффиксом
|
|
32
|
+
`_default`. Слияние текста идёт по разделам `## `: совпавший заголовок замещает, новый
|
|
33
|
+
дописывается, пустой снимает раздел пакета.
|
|
34
|
+
|
|
35
|
+
## Порядок
|
|
36
|
+
|
|
37
|
+
Правка ресурса доезжает до дерева только через сборку пакета: строка запуска читает собранное,
|
|
38
|
+
а не исходники ресурсов. Порядок один и тот же всегда — правка, сборка, `sync`. Отказ хотя бы
|
|
39
|
+
по одному файлу не пишет ничего: половина разложенного хуже целого.
|
|
40
|
+
|
|
41
|
+
## Команды
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx agent-kit doctor # что разложено, что отстало, что лежит от отказанного
|
|
45
|
+
npx agent-kit sync # разложить
|
|
46
|
+
npx agent-kit sync --check # ничего не писать, отказать при расхождении
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Установка туда, где уже всё своё
|
|
50
|
+
|
|
51
|
+
1. `init`, затем `skip` на всё, что дерево держит само. Пустая раскладка — законное начало.
|
|
52
|
+
2. Снимок того, что говорят проверки дерева, до единой правки. Он и есть мерило.
|
|
53
|
+
3. Ресурс за ресурсом: пакетную редакцию довести до здешней, предметность вынести в
|
|
54
|
+
надстройку, снять отказ, разложить, прогнать сценарии и сверить снимок.
|
|
55
|
+
4. Разложенное поверх своего пакет не пишет: файл без шапки для него чужой. Снять его —
|
|
56
|
+
решение владельца, и до этого раскладка отказывает поимённо.
|
|
57
|
+
|
|
58
|
+
## Ловушки
|
|
59
|
+
|
|
60
|
+
- **Прогонять сценарии гардов можно, ничего не раскладывая.** Обвязка набора принимает каталог
|
|
61
|
+
гардов переменной, и пакетную редакцию гоняют по сценариям дерева до установки. Заход,
|
|
62
|
+
потраченный на диагноз по последствиям, стоил ровно этой строки.
|
|
63
|
+
- **Отбитая правка не всегда про текст гарда.** Гард зовут по пути, и файл без права на
|
|
64
|
+
запуск отвечает отказом доступа — ненулевым кодом, который читается как «правка отбита».
|
|
65
|
+
Набор при этом отбивает подряд всё, включая сборку и тесты, и причины не называет.
|
|
66
|
+
- **Правка shell-скрипта заменой по шаблону сверяется `bash -n` сразу.** Замена границ
|
|
67
|
+
конструкции не видит: `case` теряет свою `esac`, файл остаётся синтаксически неверным, а
|
|
68
|
+
гард с ошибкой синтаксиса отвечает ненулевым кодом — то есть «правка отбита». Два раза за
|
|
69
|
+
заход, и оба раза это выглядело дефектом самого гарда.
|
|
70
|
+
- **Разложенный файл узнаётся по шапке, а не по каталогу.** Раскладка ложится в те же
|
|
71
|
+
`tools/`, `.claude/hooks/` и `.claude/skills/`, где лежит своё, поэтому карта гейта,
|
|
72
|
+
написанная по путям, требует под него доменное правило — а оно уводит править файл на месте.
|
|
73
|
+
Правка на месте теряется на следующей раскладке, и до тех пор выглядит применённой. Ветка по
|
|
74
|
+
шапке ставится в карте первой и решает раньше путей.
|
|
75
|
+
- **Настройки проверок сливаются на один уровень.** Верхние ключи `checks.json` ложатся поверх
|
|
76
|
+
умолчаний по одному, а вложенный объект замещается целиком: назвав один ключ борды, дерево
|
|
77
|
+
теряет остальные — и увидит это отказом «нет токена бота», то есть как неполадку машины.
|
|
78
|
+
Вложенный раздел заполняется целиком либо не заводится вовсе.
|
|
79
|
+
- **Утверждение правила переезжает вместе с кодом.** Вынесенное в надстройку перестаёт
|
|
80
|
+
находиться по прежнему символу, и привязка в спутнике правила врёт молча — сверка спеков
|
|
81
|
+
ловит это, но только если её позвать.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: write-a-skill
|
|
3
|
+
description: Заведение нового скила — того, у которого нет закона над собой: витрина, генератор, чужой сервис, приём работы этого дерева. Брать, когда просят завести, написать или переписать скил. Форма правила и паттерна сюда не входит — это паттерн spec-driven-rule.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Как заводится скил
|
|
7
|
+
|
|
8
|
+
Скил — это то, что агент загружает перед работой и читает целиком. Отсюда всё остальное: он
|
|
9
|
+
короткий, он объявляет, когда его брать, и он не пересказывает то, что уже написано в соседнем.
|
|
10
|
+
|
|
11
|
+
## Когда брать
|
|
12
|
+
|
|
13
|
+
- Заводится скил, у которого нет закона над собой: витрина, генератор, работа с чужим сервисом,
|
|
14
|
+
приём, принятый в этом дереве.
|
|
15
|
+
- Скил разросся, и его пора делить.
|
|
16
|
+
- Скил есть, но его никто не загружает — надо чинить объявление.
|
|
17
|
+
|
|
18
|
+
**Правило и паттерн сюда не идут.** Правило стоит под законом, паттерн — при правиле, и форму
|
|
19
|
+
обоих держит паттерн `spec-driven-rule`. Скил без закона — третий случай, и только он здесь.
|
|
20
|
+
|
|
21
|
+
## Порядок
|
|
22
|
+
|
|
23
|
+
1. **Спроси, чего не хватает.** Какую работу скил закрывает, на чём спотыкались без него, нужны
|
|
24
|
+
ли готовые команды или хватает порядка действий. Скил, написанный без этого, пересказывает
|
|
25
|
+
документацию инструмента — а её агент и так знает.
|
|
26
|
+
2. **Напиши черновик.** Один файл. Дополнительные — только когда первый перестаёт читаться
|
|
27
|
+
целиком.
|
|
28
|
+
3. **Покажи владельцу.** Скил действует на все будущие сессии, и заводить его молча нельзя.
|
|
29
|
+
|
|
30
|
+
## Что в файле
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
<имя-скила>/
|
|
34
|
+
├── SKILL.md # обязателен, и обычно единственный
|
|
35
|
+
├── <ЧТО-ТО>.md # отдельный файл — когда SKILL.md перестал читаться целиком
|
|
36
|
+
└── scripts/ # готовые скрипты, если операция детерминированная
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Вступление между `---` — `name` и `description`, дальше заголовок и разделы. Первым разделом —
|
|
40
|
+
«Когда брать»: агент решает по нему, а не по названию.
|
|
41
|
+
|
|
42
|
+
## Объявление решает всё
|
|
43
|
+
|
|
44
|
+
`description` — **единственное, что агент видит**, когда решает, грузить скил или нет. Он стоит
|
|
45
|
+
в системном приглашении рядом с описаниями всех остальных, и выбор идёт по ним.
|
|
46
|
+
|
|
47
|
+
Оно отвечает на два вопроса: что скил даёт и когда его брать. Пиши третьим лицом, до 1024
|
|
48
|
+
знаков: первая фраза — что делает, вторая — «Брать, когда…», третья — чего в нём нет и где это
|
|
49
|
+
искать.
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
✓ Заведение нового скила — того, у которого нет закона над собой. Брать, когда просят
|
|
53
|
+
завести, написать или переписать скил. Форма правила и паттерна сюда не входит — это
|
|
54
|
+
паттерн spec-driven-rule.
|
|
55
|
+
|
|
56
|
+
✗ Помогает со скилами.
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Второе объявление не даёт агенту ни одного способа отличить этот скил от соседнего — и он не
|
|
60
|
+
загрузит ни один.
|
|
61
|
+
|
|
62
|
+
Строка «чего здесь нет» не украшение: скилов в дереве десятки, и половина ошибок выбора — это
|
|
63
|
+
взятый соседний. Назови его по имени.
|
|
64
|
+
|
|
65
|
+
## Готовые команды вместо описания
|
|
66
|
+
|
|
67
|
+
Скрипт кладётся рядом со скилом, когда операция детерминированная — проверка, приведение к
|
|
68
|
+
форме, разбор вывода. Такое дешевле позвать, чем породить заново, и ошибку в нём видно один раз,
|
|
69
|
+
а не в каждом порождении.
|
|
70
|
+
|
|
71
|
+
Порядок действий, зависящий от того, что нашлось, скриптом не становится: он остаётся текстом.
|
|
72
|
+
|
|
73
|
+
## Когда делить
|
|
74
|
+
|
|
75
|
+
Делить, когда:
|
|
76
|
+
|
|
77
|
+
- файл перестал читаться целиком — по опыту это около сотни строк;
|
|
78
|
+
- в нём два разных предмета, и второй нужен раз в месяц;
|
|
79
|
+
- готовый код занял больше места, чем объяснение, зачем он.
|
|
80
|
+
|
|
81
|
+
Не делить ради красоты: два файла вместо одного стоят одного лишнего перехода при каждом
|
|
82
|
+
чтении, а ссылка глубже одного уровня не читается вовсе.
|
|
83
|
+
|
|
84
|
+
## Чем скил вредит
|
|
85
|
+
|
|
86
|
+
- **Пересказ документации инструмента.** Агент читает скил при каждой работе; строка, которую он
|
|
87
|
+
знает и без того, вытесняет ту, которой не знает.
|
|
88
|
+
- **Дублирование соседа.** Два скила об одном начинают противоречить друг другу, и первым это
|
|
89
|
+
замечает тот, кто выполнил оба.
|
|
90
|
+
- **То, что устареет вместе с кодом.** Скил, называющий версию, число или имя файла, которое
|
|
91
|
+
правится чаще раза в квартал, врёт молча.
|
|
92
|
+
- **Длина.** Скил в три экрана перестают читать целиком, а читают до первого знакомого раздела.
|
|
93
|
+
|
|
94
|
+
## Перед тем как отдать
|
|
95
|
+
|
|
96
|
+
- [ ] в объявлении есть «Брать, когда…» и назван сосед, которого брать не надо;
|
|
97
|
+
- [ ] первый раздел — «Когда брать»;
|
|
98
|
+
- [ ] файл читается целиком за один заход;
|
|
99
|
+
- [ ] ни одной строки, которая повторяет соседний скил;
|
|
100
|
+
- [ ] ничего, что устареет само собой: версий, чисел, сроков;
|
|
101
|
+
- [ ] есть хотя бы один готовый пример, а не только объяснение;
|
|
102
|
+
- [ ] ссылки уходят на один уровень, не глубже.
|
|
103
|
+
|
|
104
|
+
## Чтобы скил загружали
|
|
105
|
+
|
|
106
|
+
Написанного мало: скил, который никто не открывает, не действует. Новый скил либо называется в
|
|
107
|
+
карте гейта этого дерева, либо его зовёт по имени другой скил или роль. Скил, не названный
|
|
108
|
+
нигде, останется декорацией.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Надстройка карты гейта: то, чего нет у других деревьев мастерской.
|
|
3
|
+
#
|
|
4
|
+
# Скопировать в `.claude/rt-kit/gate-map.sh` и дописать своё. Файл необязателен: без него
|
|
5
|
+
# действует умолчание пакета — `.claude/rt-kit/defaults/gate-map.sh`, где уже разобраны тесты,
|
|
6
|
+
# компоненты, стили, барели, манифесты, документы и команды поставки.
|
|
7
|
+
#
|
|
8
|
+
# Заводить эту надстройку стоит ровно тогда, когда у дерева есть род файлов, которого нет у
|
|
9
|
+
# остальных: витрина, свой генератор, чужая раскладка каталогов.
|
|
10
|
+
#
|
|
11
|
+
# Функция печатает ИМЯ ПРАВИЛА или молчит. Имён может быть несколько, по одному в строке.
|
|
12
|
+
# Порядок веток решает: первое совпадение выигрывает, поэтому частное идёт раньше общего — и
|
|
13
|
+
# своё частное обязано стоять ДО вызова умолчания, иначе общая ветка расширения его перехватит.
|
|
14
|
+
|
|
15
|
+
skill_for() {
|
|
16
|
+
kind="$1"
|
|
17
|
+
target="$2"
|
|
18
|
+
written="$3"
|
|
19
|
+
|
|
20
|
+
case "$kind" in
|
|
21
|
+
edit)
|
|
22
|
+
case "$target" in
|
|
23
|
+
# Пример: у витрины своё правило, пакет такого не везёт.
|
|
24
|
+
# *.stories.ts | *.mdx) printf '%s\n' '<правило витрины>' ; return 0 ;;
|
|
25
|
+
|
|
26
|
+
# Пример: домен, который правится по своему правилу.
|
|
27
|
+
# */libs/<домен>/*) printf '%s\n' '<правило домена>' ; return 0 ;;
|
|
28
|
+
*) ;;
|
|
29
|
+
esac
|
|
30
|
+
;;
|
|
31
|
+
bash)
|
|
32
|
+
case "$target" in
|
|
33
|
+
# Пример: своя команда развёртывания.
|
|
34
|
+
# *<команда>*) printf '%s\n' '<правило>' ; return 0 ;;
|
|
35
|
+
*) ;;
|
|
36
|
+
esac
|
|
37
|
+
;;
|
|
38
|
+
esac
|
|
39
|
+
|
|
40
|
+
# Всё, что дерево не назвало своим, разбирает умолчание пакета. Проверка на объявленность
|
|
41
|
+
# нужна ровно в одном промежутке: пакет обновлён, а `sync` в этом дереве ещё не прогнан.
|
|
42
|
+
command -v skill_for_default >/dev/null 2>&1 && skill_for_default "$kind" "$target" "$written"
|
|
43
|
+
|
|
44
|
+
return 0
|
|
45
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# <имя-правила> — что здесь своё
|
|
2
|
+
|
|
3
|
+
Имена и привязки этого дерева при правиле `SKILL.md` рядом.
|
|
4
|
+
|
|
5
|
+
Правило говорит приёмом и называет пути, общие для деревьев мастерской, — их переписывать
|
|
6
|
+
здесь не надо. Сюда идёт только то, чего пакет знать не может: как названы вещи именно в этом
|
|
7
|
+
репозитории, и в каком его файле каждая статья правила исполняется.
|
|
8
|
+
|
|
9
|
+
Пока в файле стоит `<!-- заполняет проект -->`, правило считается неразвёрнутым: `agent-kit
|
|
10
|
+
sync --check` отказывает, а агент читает указание, у которого здесь нет адресата.
|
|
11
|
+
|
|
12
|
+
## Как это называется здесь
|
|
13
|
+
|
|
14
|
+
Только то, что расходится с правилом: ключ задач, адрес борды, префикс компонентов, имя
|
|
15
|
+
владеющей сущности, валюта хранения, набор областей коммита. Строку, которая просто повторяет
|
|
16
|
+
правило, сюда не переносят — она устареет отдельно от него.
|
|
17
|
+
|
|
18
|
+
| В правиле | Здесь |
|
|
19
|
+
| ----------------- | ------------------------------------------- |
|
|
20
|
+
| <понятие правила> | <имя в этом коде> <!-- заполняет проект --> |
|
|
21
|
+
|
|
22
|
+
## Где это лежит
|
|
23
|
+
|
|
24
|
+
| Что | Где |
|
|
25
|
+
| ---------- | ---------------------------------- |
|
|
26
|
+
| <механизм> | `<путь>` <!-- заполняет проект --> |
|
|
27
|
+
|
|
28
|
+
## Где исполняются статьи
|
|
29
|
+
|
|
30
|
+
Первая колонка — статья дословно, как она написана в разделе «Как закон применяется здесь»
|
|
31
|
+
(жирная часть пункта). Статья без строки и строка без статьи — расхождение: правило обещает то,
|
|
32
|
+
чего в дереве нет, либо в дереве стоит то, о чём правило молчит.
|
|
33
|
+
|
|
34
|
+
| Статья | Где исполняется |
|
|
35
|
+
| ----------------- | ------------------------------------------- |
|
|
36
|
+
| <статья дословно> | `<путь>:<символ>` <!-- заполняет проект --> |
|
|
37
|
+
|
|
38
|
+
## Что ещё стоит знать при чтении кода
|
|
39
|
+
|
|
40
|
+
- <Что видно только изнутри этого дерева: почему приём выглядит здесь именно так.>
|
|
41
|
+
|
|
42
|
+
## Чем это проверяется
|
|
43
|
+
|
|
44
|
+
- <Команда, которая ловит нарушение, — и что именно она ловит.>
|
|
@@ -8,7 +8,7 @@ description: Паттерн правила <имя-правила>. Брать <
|
|
|
8
8
|
# <Что собирается>
|
|
9
9
|
|
|
10
10
|
Паттерн правила `<имя-правила>`. Что при этом должно быть верно — закон
|
|
11
|
-
`
|
|
11
|
+
`docs/constitution/<закон>.md`.
|
|
12
12
|
|
|
13
13
|
## Когда брать
|
|
14
14
|
|
|
@@ -18,6 +18,10 @@ description: Паттерн правила <имя-правила>. Брать <
|
|
|
18
18
|
|
|
19
19
|
<Готовый код целиком, а не пересказ: паттерн берут, чтобы не писать заново.>
|
|
20
20
|
|
|
21
|
+
Имена в примере безымянные — `libs/<домен>`, `<Feature>Component`, `<app>`. Настоящие имена
|
|
22
|
+
этого дерева стоят в `implementation.md` при правиле: пример, написанный на чужих именах,
|
|
23
|
+
читается как рабочий код и переносится в дерево вместе с ними.
|
|
24
|
+
|
|
21
25
|
```
|
|
22
26
|
<код>
|
|
23
27
|
```
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Надстройка профиля дерева: команды, стенды и пары «правка — документ» этого репозитория.
|
|
3
|
+
#
|
|
4
|
+
# Скопировать в `.claude/rt-kit/project.sh` и дописать своё. Файл необязателен: без него
|
|
5
|
+
# действует умолчание пакета — `.claude/rt-kit/defaults/project.sh`, где запускатель выбирается
|
|
6
|
+
# по локфайлу, а линтеры, форма имени ветки и образцы переизобретения уже названы.
|
|
7
|
+
#
|
|
8
|
+
# Каждая функция вправе промолчать. Молчание значит «правила на это нет», и хук пропускает.
|
|
9
|
+
# Объявленная здесь функция замещает умолчание ЦЕЛИКОМ — чтобы дописать, а не заменить, зовите
|
|
10
|
+
# из неё то же имя с суффиксом `_default`.
|
|
11
|
+
|
|
12
|
+
# Где подняты приложения. Идёт в текст отказа, когда кто-то поднимает второй экземпляр.
|
|
13
|
+
# Умолчание молчит: чужой порт назвать хуже, чем не назвать никакого.
|
|
14
|
+
RT_STANDS='<приложение> http://localhost:<порт>, <приложение> http://localhost:<порт>'
|
|
15
|
+
|
|
16
|
+
# Адрес боевого хранилища. Любая запись по нему отбивается совсем, и опт-аут не действует.
|
|
17
|
+
RT_PROD_DSN='<хост боевого хранилища>'
|
|
18
|
+
|
|
19
|
+
# Пути, у которых якорь для сквозных тестов не требуется.
|
|
20
|
+
RT_QA_SKIP_RE='<выражение путей>'
|
|
21
|
+
|
|
22
|
+
# Команды, которые обязаны пройти перед пушем. По одной на строку; первая упавшая отбивает пуш.
|
|
23
|
+
rt_push_checks() {
|
|
24
|
+
rt_push_checks_default
|
|
25
|
+
# printf '%s\n' '<своя проверка>'
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
# Какой документ обязан ехать тем же коммитом, что и этот файл. Печатает образец пути или молчит.
|
|
29
|
+
rt_docs_pair_for() {
|
|
30
|
+
case "$1" in
|
|
31
|
+
# <свой путь>) printf '%s' '<образец пути документа>' ; return 0 ;;
|
|
32
|
+
*) ;;
|
|
33
|
+
esac
|
|
34
|
+
|
|
35
|
+
rt_docs_pair_for_default "$1"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# Чем линтуется этот файл сразу после правки. Печатает команду или молчит.
|
|
39
|
+
rt_lint_for() {
|
|
40
|
+
rt_lint_for_default "$1"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
# Имя ветки, с которой разрешено открывать заявку на слияние. Успех — годится.
|
|
44
|
+
rt_task_branch_ok() {
|
|
45
|
+
rt_task_branch_ok_default "$1"
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
# Что в этом дереве считается переизобретением. По строке «образец<таб>чем заменить».
|
|
49
|
+
rt_reinvented_in() {
|
|
50
|
+
rt_reinvented_in_default "$1"
|
|
51
|
+
# case "$1" in
|
|
52
|
+
# *.ts) printf '%s\t%s\n' '<образец>' '<чем заменить>' ;;
|
|
53
|
+
# esac
|
|
54
|
+
}
|
package/assets/templates/rule.md
CHANGED
|
@@ -2,37 +2,26 @@
|
|
|
2
2
|
name: <имя-правила>
|
|
3
3
|
kind: rule
|
|
4
4
|
law: <закон>
|
|
5
|
-
description: Правило
|
|
5
|
+
description: Правило под закон «<Название закона>». Брать при <когда> — <каким приёмом это делается>. Готовый код — в паттернах <имена>.
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
# <О чём закон> —
|
|
8
|
+
# <О чём закон> — каким приёмом
|
|
9
9
|
|
|
10
|
-
Правило под закон `
|
|
11
|
-
это названо в этом
|
|
10
|
+
Правило под закон `docs/constitution/<закон>.md`. Закон говорит, что должно быть верно; здесь — каким
|
|
11
|
+
приёмом это делается. Чем это названо в этом дереве и где лежит — `implementation.md` рядом:
|
|
12
|
+
правило переносится между репозиториями, имена — нет.
|
|
12
13
|
|
|
13
|
-
##
|
|
14
|
+
## Когда берётся
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
| ---------------- | ----------------- |
|
|
17
|
-
| <понятие закона> | <имя в этом коде> |
|
|
16
|
+
<Правка, по которой правило узнаётся. Гейт зовёт его по этому признаку, а не по названию.>
|
|
18
17
|
|
|
19
|
-
##
|
|
18
|
+
## Что здесь действует
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
Каждый пункт начинается жирной статьёй, и у каждой статьи есть строка в `implementation.md`
|
|
21
|
+
рядом. Утверждение, которому места в коде не нашлось, сюда не ставится: оно уходит прозой в
|
|
22
|
+
«Ловушки» или статьёй в закон.
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
Каждый пункт начинается жирной фразой, и у каждой жирной фразы есть строка в
|
|
28
|
-
`implementation.md` рядом. Утверждение, которому места в коде не нашлось, сюда не ставится: оно
|
|
29
|
-
уходит прозой в «Ловушки» или вопросом `Q-N` в закон.
|
|
30
|
-
|
|
31
|
-
- **<Утверждение одной фразой.>** <Что сломается иначе — не больше двух предложений.>
|
|
32
|
-
|
|
33
|
-
## Чего из закона здесь нет
|
|
34
|
-
|
|
35
|
-
<Что из закона этот проект не применяет и почему; ссылка на открытый вопрос закона.>
|
|
24
|
+
- **<Статья одной фразой.>** <Что сломается иначе — не больше двух предложений.>
|
|
36
25
|
|
|
37
26
|
## Паттерны
|
|
38
27
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"host": {
|
|
3
|
+
"question": "Где лежит репозиторий и очередь работ?",
|
|
4
|
+
"title": "хостинг репозитория",
|
|
5
|
+
"options": [
|
|
6
|
+
{
|
|
7
|
+
"value": "github",
|
|
8
|
+
"title": "GitHub — gh, issues, Projects"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"value": "gitlab",
|
|
12
|
+
"title": "GitLab — glab, issues, Boards"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"value": "azure",
|
|
16
|
+
"title": "Azure DevOps — az repos, work items, Boards"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
export const meta = {
|
|
2
|
+
name: 'feature',
|
|
3
|
+
description: 'План от PM, реализация по шагам, веер проверок QA и приёмка по исходному запросу',
|
|
4
|
+
whenToUse: 'Крупная правка, которая заденет несколько слоёв: контракт, хранилище, приложения, переводы',
|
|
5
|
+
phases: [
|
|
6
|
+
{ title: 'План', detail: 'PM разбивает задачу на шаги с признаками готовности' },
|
|
7
|
+
{ title: 'Реализация', detail: 'по шагу за раз — рабочее дерево одно на всех' },
|
|
8
|
+
{ title: 'Проверка', detail: 'QA веером: тесты, сборка, браузер, состязательный разбор' },
|
|
9
|
+
{ title: 'Приёмка', detail: 'PM сверяет сделанное с исходным запросом' },
|
|
10
|
+
],
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
// Задача приходит строкой в args; без неё сценарий бессмыслен.
|
|
14
|
+
const task = typeof args === 'string' ? args : (args?.task ?? '');
|
|
15
|
+
if (!task) {
|
|
16
|
+
throw new Error('Нужна задача: передай её строкой в args');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const PLAN = {
|
|
20
|
+
type: 'object',
|
|
21
|
+
additionalProperties: false,
|
|
22
|
+
required: ['steps', 'risks', 'acceptance'],
|
|
23
|
+
properties: {
|
|
24
|
+
steps: {
|
|
25
|
+
type: 'array',
|
|
26
|
+
maxItems: 6,
|
|
27
|
+
items: {
|
|
28
|
+
type: 'object',
|
|
29
|
+
additionalProperties: false,
|
|
30
|
+
required: ['title', 'scope', 'done'],
|
|
31
|
+
properties: {
|
|
32
|
+
title: { type: 'string' },
|
|
33
|
+
scope: { type: 'string', description: 'что входит и что НЕ входит' },
|
|
34
|
+
done: { type: 'string', description: 'проверяемый признак готовности' },
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
risks: { type: 'array', items: { type: 'string' } },
|
|
39
|
+
acceptance: { type: 'array', items: { type: 'string' }, description: 'критерии приёмки по исходному запросу' },
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const FINDINGS = {
|
|
44
|
+
type: 'object',
|
|
45
|
+
additionalProperties: false,
|
|
46
|
+
required: ['findings', 'checked'],
|
|
47
|
+
properties: {
|
|
48
|
+
findings: {
|
|
49
|
+
type: 'array',
|
|
50
|
+
items: {
|
|
51
|
+
type: 'object',
|
|
52
|
+
additionalProperties: false,
|
|
53
|
+
required: ['what', 'where', 'evidence', 'severity'],
|
|
54
|
+
properties: {
|
|
55
|
+
what: { type: 'string' },
|
|
56
|
+
where: { type: 'string' },
|
|
57
|
+
evidence: { type: 'string', description: 'вывод команды или замер, а не пересказ' },
|
|
58
|
+
severity: { type: 'string', enum: ['blocker', 'major', 'minor'] },
|
|
59
|
+
preExisting: { type: 'boolean' },
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
checked: { type: 'array', items: { type: 'string' } },
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
phase('План');
|
|
68
|
+
const plan = await agent(
|
|
69
|
+
`Задача от пользователя:\n\n${task}\n\nРазбери её и верни план. Шагов не больше шести; ` +
|
|
70
|
+
`каждый — самостоятельная правка с проверяемым признаком готовности.`,
|
|
71
|
+
{ agentType: 'project-manager', label: 'план', schema: PLAN }
|
|
72
|
+
);
|
|
73
|
+
log(`План: ${plan.steps.length} шаг(ов), рисков ${plan.risks.length}`);
|
|
74
|
+
|
|
75
|
+
// Шаги идут по очереди, а не веером: рабочее дерево одно, и параллельные
|
|
76
|
+
// правки одних и тех же файлов затирали бы друг друга.
|
|
77
|
+
phase('Реализация');
|
|
78
|
+
const done = [];
|
|
79
|
+
for (const [index, step] of plan.steps.entries()) {
|
|
80
|
+
const result = await agent(
|
|
81
|
+
`Задача целиком: ${task}\n\nТвой шаг ${index + 1} из ${plan.steps.length}: ${step.title}\n` +
|
|
82
|
+
`Границы: ${step.scope}\nПризнак готовности: ${step.done}\n\n` +
|
|
83
|
+
`Уже сделано на предыдущих шагах:\n${done.join('\n') || '— ничего'}\n\n` +
|
|
84
|
+
`Соблюдай правила дерева из CLAUDE.md и .claude/skills. Перед правкой файла загрузи ` +
|
|
85
|
+
`подходящее правило через инструмент Skill — иначе гейт правил заблокирует правку. ` +
|
|
86
|
+
`Никаких git-команд. Верни коротко: какие файлы изменил и чем подтверждается признак готовности.`,
|
|
87
|
+
{ label: `шаг ${index + 1}: ${step.title}`, phase: 'Реализация' }
|
|
88
|
+
);
|
|
89
|
+
done.push(`${step.title}: ${result ?? 'шаг не выполнен'}`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Здесь барьер оправдан: приёмке нужны все находки разом, а измерения
|
|
93
|
+
// независимы и честно параллелятся.
|
|
94
|
+
phase('Проверка');
|
|
95
|
+
const LENSES = [
|
|
96
|
+
{ key: 'тесты', prompt: 'Прогони юнит-тесты и e2e по затронутому. Отдели новые падения от доэтапных.' },
|
|
97
|
+
{ key: 'сборка', prompt: 'Прогони сборки затронутых приложений и линтеры. Доэтапные ошибки помечай как доэтапные.' },
|
|
98
|
+
{
|
|
99
|
+
key: 'браузер',
|
|
100
|
+
prompt: 'Проверь результат в браузере замерами: вычисленные стили, геометрия, контраст. Серверы разработки уже подняты — свой не поднимай.',
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
key: 'разбор',
|
|
104
|
+
prompt: 'Состязательно разбери правку: граничные значения, вторая локаль, тёмная тема, узкий экран, отвалившийся сервер, отдача страницы сервером.',
|
|
105
|
+
},
|
|
106
|
+
];
|
|
107
|
+
const reports = (
|
|
108
|
+
await parallel(
|
|
109
|
+
LENSES.map(
|
|
110
|
+
(lens) => () =>
|
|
111
|
+
agent(`Задача, которую выполняли: ${task}\n\nЧто сделано:\n${done.join('\n')}\n\n${lens.prompt}`, {
|
|
112
|
+
agentType: 'qa-engineer',
|
|
113
|
+
label: `qa: ${lens.key}`,
|
|
114
|
+
phase: 'Проверка',
|
|
115
|
+
schema: FINDINGS,
|
|
116
|
+
})
|
|
117
|
+
)
|
|
118
|
+
)
|
|
119
|
+
).filter(Boolean);
|
|
120
|
+
|
|
121
|
+
const findings = reports.flatMap((report) => report.findings);
|
|
122
|
+
const blockers = findings.filter((finding) => finding.severity === 'blocker' && !finding.preExisting);
|
|
123
|
+
log(`Находок ${findings.length}, из них блокеров ${blockers.length}`);
|
|
124
|
+
|
|
125
|
+
phase('Приёмка');
|
|
126
|
+
const verdict = await agent(
|
|
127
|
+
`Исходный запрос пользователя:\n\n${task}\n\nКритерии приёмки:\n${plan.acceptance.join('\n')}\n\n` +
|
|
128
|
+
`Что сделано:\n${done.join('\n')}\n\nНаходки проверяющих:\n${JSON.stringify(findings, null, 1)}\n\n` +
|
|
129
|
+
`Вынеси вердикт: что принято, что нет и почему. Отдельно назови, что из исходного запроса ` +
|
|
130
|
+
`осталось незакрытым или тихо сузилось.`,
|
|
131
|
+
{ agentType: 'project-manager', label: 'приёмка', phase: 'Приёмка' }
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
return { plan, done, findings, blockers, verdict };
|