@rt-tools/agent-kit 0.1.0 → 0.3.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 +88 -9
- package/assets/hooks/browser-device-id.sh +20 -0
- package/assets/hooks/browser-guard-device-id.sh +27 -0
- package/assets/hooks/browser-guard-no-listing.sh +17 -0
- package/assets/hooks/browser-guard-no-other-drivers.sh +78 -0
- package/assets/hooks/browser-guard-require-select.sh +53 -0
- package/assets/hooks/commit-msg.sh +26 -0
- package/assets/hooks/constitution-index.sh +42 -0
- package/assets/hooks/dev-server-guard.sh +113 -0
- package/assets/hooks/docs-guard.sh +96 -0
- package/assets/hooks/git-guard-delivery.sh +110 -0
- package/assets/hooks/git-guard-main.sh +72 -0
- package/assets/hooks/git-guard-push-tests.sh +73 -0
- package/assets/hooks/lint-after-edit.sh +94 -0
- package/assets/hooks/qa-dataid-guard.sh +81 -0
- package/assets/hooks/reuse-first-guard.sh +83 -0
- package/assets/hooks/skill-gate-rearm.sh +22 -0
- package/assets/hooks/skill-gate.sh +68 -0
- package/assets/hooks/skill-loaded.sh +20 -0
- package/assets/hooks/sql-guard.sh +129 -0
- package/assets/laws/access.md +3 -12
- package/assets/laws/admin-lists.md +9 -21
- package/assets/laws/admin-navigation.md +3 -15
- package/assets/laws/code-structure.md +5 -16
- package/assets/laws/delivery.md +2 -16
- package/assets/laws/entity-editing.md +7 -20
- package/assets/laws/entity-models.md +10 -17
- package/assets/laws/frontend-application.md +3 -14
- package/assets/laws/lib-imports.md +0 -13
- package/assets/laws/locales.md +2 -11
- package/assets/laws/project-documentation.md +7 -20
- package/assets/laws/reuse-first.md +0 -9
- package/assets/laws/search-visibility.md +0 -13
- package/assets/laws/shared-code.md +0 -13
- package/assets/laws/verifiability.md +0 -13
- package/assets/patterns/angular-patterns-state.md +94 -0
- package/assets/patterns/api-layer-pair.md +78 -0
- package/assets/patterns/browser-verification-measure.md +83 -0
- package/assets/patterns/browser-verification-stand.md +79 -0
- package/assets/patterns/component-structure-new.md +98 -0
- package/assets/patterns/doc-style-sweep.md +100 -0
- package/assets/patterns/doc-style-write.md +106 -0
- package/assets/patterns/git-workflow-commit.md +175 -0
- package/assets/patterns/git-workflow-merge.md +82 -0
- package/assets/patterns/git-workflow-migration.md +58 -0
- package/assets/patterns/git-workflow-restart.md +49 -0
- package/assets/patterns/lib-layers-move.md +77 -0
- package/assets/patterns/lib-layers-new.md +70 -0
- package/assets/patterns/permissions-procedure.md +69 -0
- package/assets/patterns/platform-access-di.md +70 -0
- package/assets/patterns/reuse-first-extend.md +73 -0
- package/assets/patterns/seo-page.md +92 -0
- package/assets/patterns/seo-verify.md +64 -0
- package/assets/patterns/shared-code-new.md +80 -0
- package/assets/patterns/spec-driven-domain.md +100 -0
- package/assets/patterns/spec-driven-rule.md +112 -0
- package/assets/patterns/styling-bem-component.md +77 -0
- package/assets/patterns/styling-bem-layout.md +67 -0
- package/assets/patterns/testing-e2e.md +90 -0
- package/assets/patterns/testing-unit.md +93 -0
- package/assets/patterns/translations-key.md +51 -0
- package/assets/patterns/ts-procedure.md +66 -0
- package/assets/rules/angular-patterns.md +52 -0
- package/assets/rules/api-layer.md +53 -0
- package/assets/rules/browser-verification.md +69 -0
- package/assets/rules/component-structure.md +48 -0
- package/assets/rules/doc-style.md +61 -0
- package/assets/rules/git-workflow.md +106 -0
- package/assets/rules/lib-layers.md +54 -0
- package/assets/rules/permissions.md +52 -0
- package/assets/rules/platform-access.md +49 -0
- package/assets/rules/reuse-first.md +69 -0
- package/assets/rules/seo.md +50 -0
- package/assets/rules/shared-code.md +45 -0
- package/assets/rules/spec-driven.md +89 -0
- package/assets/rules/styling-bem.md +59 -0
- package/assets/rules/testing.md +69 -0
- package/assets/rules/translations.md +52 -0
- package/assets/rules/typescript-conventions.md +46 -0
- package/assets/templates/gate-map.sh +37 -0
- package/assets/templates/implementation.md +38 -0
- package/assets/templates/pattern.md +4 -0
- package/assets/templates/project.sh +41 -0
- package/assets/templates/rule.md +12 -23
- package/bin/agent-kit.d.ts +1 -1
- package/bin/agent-kit.d.ts.map +1 -1
- package/bin/agent-kit.js +63 -7
- package/bin/agent-kit.js.map +1 -1
- package/bin/prompt.d.ts +9 -0
- package/bin/prompt.d.ts.map +1 -0
- package/bin/prompt.js +57 -0
- package/bin/prompt.js.map +1 -0
- package/index.d.ts +2 -0
- package/index.d.ts.map +1 -1
- package/index.js +2 -0
- package/index.js.map +1 -1
- package/lib/assets.d.ts +10 -2
- package/lib/assets.d.ts.map +1 -1
- package/lib/assets.js +24 -28
- package/lib/assets.js.map +1 -1
- package/lib/catalog.d.ts +44 -0
- package/lib/catalog.d.ts.map +1 -0
- package/lib/catalog.js +86 -0
- package/lib/catalog.js.map +1 -0
- package/lib/commands.d.ts +13 -1
- package/lib/commands.d.ts.map +1 -1
- package/lib/commands.js +106 -11
- package/lib/commands.js.map +1 -1
- package/lib/companion.d.ts +53 -0
- package/lib/companion.d.ts.map +1 -0
- package/lib/companion.js +33 -0
- package/lib/companion.js.map +1 -0
- package/lib/config.d.ts +29 -1
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +43 -6
- package/lib/config.js.map +1 -1
- package/lib/picker.d.ts +47 -0
- package/lib/picker.d.ts.map +1 -0
- package/lib/picker.js +112 -0
- package/lib/picker.js.map +1 -0
- 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 +3 -0
- package/lib/sync.d.ts.map +1 -1
- package/lib/sync.js +20 -1
- package/lib/sync.js.map +1 -1
- package/package.json +1 -1
- package/rt-tools-agent-kit-0.3.0.tgz +0 -0
- package/rt-tools-agent-kit-0.1.0.tgz +0 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec-driven
|
|
3
|
+
kind: rule
|
|
4
|
+
law: project-documentation
|
|
5
|
+
description: Правило под закон «Документация проекта». Брать при правке спека домена, закона и любого скила. Три слоя — закон, правило, паттерн, — обязательные разделы, привязка утверждений к коду, связь сценариев с тестами. Готовый порядок действий — в паттернах spec-driven-domain и spec-driven-rule. Чем это названо здесь — в implementation.md рядом.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Документация проекта — каким приёмом
|
|
9
|
+
|
|
10
|
+
Правило под закон `{{lawsDir}}/project-documentation.md`. Закон говорит, что должно быть верно
|
|
11
|
+
про тексты; здесь — из каких слоёв они сложены и что сверяет машина. Где лежат спеки домена,
|
|
12
|
+
чем они проверяются и какой у них шаблон — `implementation.md` рядом. Формулировки — правило
|
|
13
|
+
`doc-style` под тем же законом.
|
|
14
|
+
|
|
15
|
+
## Когда берётся
|
|
16
|
+
|
|
17
|
+
Правка закона, правила, паттерна или спека домена. Заведение нового слоя документации.
|
|
18
|
+
|
|
19
|
+
## Как сложены слои
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
ЗАКОН {{lawsDir}}/<закон>.md
|
|
23
|
+
верен для любого приложения этого класса; о проекте не знает ничего:
|
|
24
|
+
ни путей, ни имён файлов, ни привязок
|
|
25
|
+
|
|
26
|
+
├─ ПРАВИЛО {{rulesDir}}/<правило>/SKILL.md (kind: rule, law: <закон>)
|
|
27
|
+
│ каким приёмом закон исполняется; несколько правил на закон
|
|
28
|
+
│ {{rulesDir}}/<правило>/implementation.md — имена этого дерева и привязка к коду
|
|
29
|
+
│
|
|
30
|
+
│ └─ ПАТТЕРН {{rulesDir}}/<правило>-<что>/SKILL.md (kind: pattern, rule: <правило>)
|
|
31
|
+
│ готовый код и конкретные приёмы; минимум один на правило
|
|
32
|
+
│
|
|
33
|
+
└─ СПЕК ДОМЕНА как работает домен; объявляет законы, которые применяет
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Ссылки идут только снизу вверх: закон не ссылается ни на правило, ни на спек, ни на файл.
|
|
37
|
+
|
|
38
|
+
## Что здесь действует
|
|
39
|
+
|
|
40
|
+
- **Набор разделов спека задан заранее, и отсутствие раздела — отказ.** «Не применимо» —
|
|
41
|
+
законный ответ, отсутствие раздела — нет: сквозные требования вспоминаются постфактум именно
|
|
42
|
+
тогда, когда для них не заведено места.
|
|
43
|
+
- **Каждое утверждение привязано к месту в коде, и связь сверяется в обе стороны.** Ключ связи
|
|
44
|
+
— сам текст утверждения, поэтому переформулировать его, забыв про привязку, нельзя.
|
|
45
|
+
- **Привязка не ведёт в код, который никто не зовёт.** Символ, объявленный в своём файле и
|
|
46
|
+
больше нигде не встречающийся, местом исполнения не считается.
|
|
47
|
+
- **Таблица обработчиков сверяется с объявлениями в обе стороны.** Иначе обработчик, который
|
|
48
|
+
домен обслуживает, но забыл описать, виден только в объявлении.
|
|
49
|
+
- **Код отказа принимается, только если он в домене бросается.** Коды, выписанные по замыслу,
|
|
50
|
+
живут в документе годами, а на одном из путей обещанный отказ не бросает никто.
|
|
51
|
+
- **Префикс сценариев в домене один.** Второй префикс означает, что домен описан дважды.
|
|
52
|
+
- **У закона обязателен раздел статей, и кроме них он не держит ничего.** Истории правок и
|
|
53
|
+
доводов о выбранном когда-то варианте в законе нет: историю держит система контроля версий, а
|
|
54
|
+
довод с отвергнутой альтернативой — свойство работы, и место ему в «Ловушках» правила.
|
|
55
|
+
- **Закон, назвавший файл проекта, — отказ.** Путям и привязкам место в правиле: иначе закон
|
|
56
|
+
нельзя ни прочитать без знания дерева, ни применить на другом приложении.
|
|
57
|
+
- **Правило объявляет закон, под который написано.** Правило без закона — набор приёмов, из
|
|
58
|
+
которого не видно, что именно должно быть верно.
|
|
59
|
+
- **Спек объявляет законы, которые применяет, и связь сверяется в обе стороны.** Закон,
|
|
60
|
+
названный в тексте спека, обязан стоять в его шапке: иначе по закону не узнать, какие домены
|
|
61
|
+
на нём стоят.
|
|
62
|
+
|
|
63
|
+
## Паттерны
|
|
64
|
+
|
|
65
|
+
- `spec-driven-domain` — заведение и правка спека домена, сценарии, привязка.
|
|
66
|
+
- `spec-driven-rule` — заведение закона, правила и паттерна.
|
|
67
|
+
|
|
68
|
+
## Ловушки
|
|
69
|
+
|
|
70
|
+
- **Список шагов в спеке не заводить.** Шаги — артефакт сессии, им место в ветке или в описании
|
|
71
|
+
PR. Как только в директории появляются «шаги», спек снова становится планом и умирает после
|
|
72
|
+
слияния.
|
|
73
|
+
- **Спек описывает установившееся, а не предстоящее.** Единственное место, где он говорит о
|
|
74
|
+
будущем, — отдельная директория предложенного; после выкатки её текст вливается в спек
|
|
75
|
+
домена, директория удаляется, идентификаторы сценариев не меняются.
|
|
76
|
+
- **Семантику полей не сверяет ничто.** Проверка знает имена обработчиков, коды отказа и связь
|
|
77
|
+
сценариев с тестами; что означает пустое поле — не знает.
|
|
78
|
+
- **Живость символа считается совпадением имени по дереву, а не вызовом.** Символу хватает
|
|
79
|
+
второго упоминания где угодно — в чужом поле с тем же именем, в атрибуте разметки. Место, где
|
|
80
|
+
правило исполняется на самом деле, подтверждается только чтением кода.
|
|
81
|
+
- **Зелёная проверка не значит, что структура верна.** Проверка сверяет структуру с тем, чего
|
|
82
|
+
сама и ждёт: неверная раскладка, совпавшая с её ожиданием, проходит зелёной.
|
|
83
|
+
- **Конфликт слияния в спеке разрешается сохранением обеих сторон, а не выбором одной.** Две
|
|
84
|
+
ветки дописывают в конец одних и тех же списков, и обе стороны верны: конфликт здесь не спор,
|
|
85
|
+
а две дописи в одно место. Номера сценариев при разрешении не пересчитываются — идентификатор
|
|
86
|
+
это ключ связи с тестами, и сдвиг номеров рвёт сверку у соседей, которых правка не касалась.
|
|
87
|
+
Порядок сохранённых сторон держится одинаковым во всех файлах спека, иначе правило, его
|
|
88
|
+
сценарий и его привязка перестают находиться друг по другу. После разрешения гоняется
|
|
89
|
+
проверка спеков: конфликт в тексте кода не задевает, и ни сборка, ни линтеры его не увидят.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: styling-bem
|
|
3
|
+
kind: rule
|
|
4
|
+
law: frontend-application
|
|
5
|
+
description: Правило под закон «Фронтовое приложение». Брать при правке любого файла стилей и шаблона компонента — токены оформления вместо сырых значений, класс директивой, общий слой раскладки, класс без правила. Готовый код — в паттернах styling-bem-layout и styling-bem-component. Чем это названо здесь — в implementation.md рядом.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Оформление — каким приёмом
|
|
9
|
+
|
|
10
|
+
Правило под закон `{{lawsDir}}/frontend-application.md`. Закон говорит, что должно быть верно;
|
|
11
|
+
здесь — каким приёмом это держится. Как названы токены, директивы классов и общий слой
|
|
12
|
+
раскладки — `implementation.md` рядом. Раскладка файла компонента — `component-structure`,
|
|
13
|
+
состояние — `angular-patterns`, окружение браузера — `platform-access`, слой обращения к
|
|
14
|
+
серверу — `api-layer`. Все пять под одним законом.
|
|
15
|
+
|
|
16
|
+
## Когда берётся
|
|
17
|
+
|
|
18
|
+
Правка любого файла стилей и любого шаблона компонента. И раньше всего этого — момент, когда
|
|
19
|
+
рука тянется написать шестнадцатеричный цвет или число на месте.
|
|
20
|
+
|
|
21
|
+
## Что здесь действует
|
|
22
|
+
|
|
23
|
+
- **Оформление берётся токеном, а не пишется значением на месте.** Составные значения — тени,
|
|
24
|
+
обводки — берутся готовым токеном целиком, а не собираются из частей: собранное из частей
|
|
25
|
+
расходится с оригиналом при первой правке шкалы.
|
|
26
|
+
- **У каждого класса элемента есть своё правило стилей.** Класс без правила выглядит рабочим и
|
|
27
|
+
молча ничего не делает.
|
|
28
|
+
- **Класс ставится директивой, а не строкой в атрибуте.** Имя блока элемент получает от
|
|
29
|
+
ближайшего предка, объявившего блок, и повторить этот разбор по тексту шаблона нечем.
|
|
30
|
+
- **Раскладка объявлена в общем слое приложения, а не в стилях экрана.** У компонента экрана
|
|
31
|
+
файл стилей по умолчанию пустой.
|
|
32
|
+
- **Предупреждение линтера стилей роняет прогон наравне с ошибкой.** Иначе запрет читается как
|
|
33
|
+
пожелание: нарушения лежат в дереве, а прогон возвращает успех и гейтом не является.
|
|
34
|
+
|
|
35
|
+
## Паттерны
|
|
36
|
+
|
|
37
|
+
- `styling-bem-layout` — экран на общем слое раскладки, блоки приложения.
|
|
38
|
+
- `styling-bem-component` — стили компонента источника вида, хост, модификаторы.
|
|
39
|
+
|
|
40
|
+
## Ловушки
|
|
41
|
+
|
|
42
|
+
- **Директива элемента без предка, объявившего блок, роняет отрисовку во время работы** —
|
|
43
|
+
сборка и линтер при этом молчат.
|
|
44
|
+
- **Директива блока на контейнере без своего узла класса не ставит вовсе:** такой узел это
|
|
45
|
+
комментарий, и имя блока он только объявляет потомкам. Класс блока экрана вешает хост.
|
|
46
|
+
- **Выравнивание по центру в прокручиваемой ленте уводит первые элементы за нулевой скролл** —
|
|
47
|
+
доскроллить до них невозможно. В прокручиваемых лентах берётся безопасный вариант
|
|
48
|
+
выравнивания.
|
|
49
|
+
- **Резерв под полосу прокрутки на корне сужает содержащий блок для закреплённых элементов.**
|
|
50
|
+
Попап, выровненный по правому краю, встаёт на ширину резерва левее своей кнопки.
|
|
51
|
+
- **Изнутри компонента до соседнего хоста не дотянуться.** Разделитель между повторяющимися
|
|
52
|
+
хостами объявляется через отрицание первого, а не соседним селектором.
|
|
53
|
+
- **Атрибут доступности визуального состояния не даёт.** Браузер стилизует собственное
|
|
54
|
+
состояние элемента, а атрибуты доступности — нет: к каждому такому атрибуту заводится своё
|
|
55
|
+
правило.
|
|
56
|
+
- **Гарнитуру с корня элементы формы не наследуют** — браузер задаёт им свой шрифт.
|
|
57
|
+
Наследование включается глобально и не сбрасывается.
|
|
58
|
+
- **Комментарии-выключатели линтера стилей не ставятся.** Селекторы объединяются вложенностью.
|
|
59
|
+
- **При переносе стилей новых объявлений не появляется** — только перемещение существующих.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: testing
|
|
3
|
+
kind: rule
|
|
4
|
+
law: verifiability
|
|
5
|
+
description: Правило под закон «Проверяемость». Брать при правке любого файла спеки и всего, что лежит в сквозных прогонах. Идентификатор сценария в заголовке теста, отметка непокрытого, вынос решения в чистую функцию, выключатели разрушающих спек. Готовый код — в паттернах testing-unit и testing-e2e. Чем это названо здесь — в implementation.md рядом.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Проверяемость — каким приёмом
|
|
9
|
+
|
|
10
|
+
Правило под закон `{{lawsDir}}/verifiability.md`. Закон говорит, что считается подтверждением;
|
|
11
|
+
здесь — каким приёмом это делается. Чем это названо в этом дереве, каким прогонщиком гоняется и
|
|
12
|
+
где лежит — `implementation.md` рядом. Проверка работающего приложения глазами и замером —
|
|
13
|
+
правило `browser-verification` под тем же законом.
|
|
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
|
+
|
|
45
|
+
## Паттерны
|
|
46
|
+
|
|
47
|
+
- `testing-unit` — тест на чистую функцию, на обработчик серверной стороны и разовый
|
|
48
|
+
тест-доказательство, который не коммитится.
|
|
49
|
+
- `testing-e2e` — прогон сквозных тестов, стенд под настоящим прокси, выключатели.
|
|
50
|
+
|
|
51
|
+
## Ловушки
|
|
52
|
+
|
|
53
|
+
- **Зелёный прогон тестов не значит, что хоть один файл исполнялся.** Либа без своего конфига
|
|
54
|
+
прогонщика не запускает ничего. Либа с конфигом, но без единого файла спеки, проходит зелёной
|
|
55
|
+
из-за настройки «успех при отсутствии тестов», и на глаз эти два случая неотличимы: в обоих
|
|
56
|
+
прогон успешен. Перед правкой в незнакомой либе проверяется, есть ли в ней хоть один файл
|
|
57
|
+
спеки; если нет — первый заводится этой же правкой, а не откладывается: откладывать здесь не
|
|
58
|
+
с чего, долг уже накоплен.
|
|
59
|
+
- **«Executable doesn't exist» — состояние машины, а не дефект правки.** Обычно установлен один
|
|
60
|
+
движок браузера, остальные падают всегда. Та же ошибка приходит после смены версии
|
|
61
|
+
прогонщика сквозных тестов: браузер ставится под конкретную версию, и после подъёма его надо
|
|
62
|
+
поставить заново. Выглядит это как регрессия обновления, а ею не является.
|
|
63
|
+
- **Первому прогону сразу после установки браузера верить нельзя.** Падения, не повторяющиеся
|
|
64
|
+
ни при отдельном прогоне тех же тестов, ни при втором полном, — свойство первого прогона.
|
|
65
|
+
Такой прогон повторяют, а выводы делают по второму.
|
|
66
|
+
- **Сквозные тесты без учётных данных в окружении пропускаются молча.** В отчёте они значатся
|
|
67
|
+
пропущенными, и прогон выглядит успешным.
|
|
68
|
+
- **Поднятый сервер разработки проверкой не является.** Это шаг правила `browser-verification`,
|
|
69
|
+
а не тест.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: translations
|
|
3
|
+
kind: rule
|
|
4
|
+
law: locales
|
|
5
|
+
description: Правило под закон «Локали и переводы». Брать при заведении любого видимого текста, правке словарей, префиксов локалей в адресе и перевода содержимого записи. Текст из словаря во всех локалях, пустой перевод как пропуск, производные переводы содержимого, начальная валюта локали. Готовый код — в паттерне translations-key. Чем это названо здесь — в implementation.md рядом.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Локали и переводы — каким приёмом
|
|
9
|
+
|
|
10
|
+
Правило под закон `{{lawsDir}}/locales.md`. Закон говорит, что должно быть верно; здесь — каким
|
|
11
|
+
приёмом это держится. Какие именно локали набраны, чем зовётся библиотека переводов и где лежат
|
|
12
|
+
словари — `implementation.md` рядом.
|
|
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
|
+
- `translations-key` — заведение ключа во всех локалях и подстановка в разметку.
|
|
40
|
+
|
|
41
|
+
## Ловушки
|
|
42
|
+
|
|
43
|
+
- **Полноту словарей держит не работающее приложение, а тест.** Он роняет прогон на
|
|
44
|
+
недостающем или пустом ключе; без него дыра видна только на экране.
|
|
45
|
+
- **Наборы ключей сверяются внутри раздела**, а не по всему словарю сразу: словари разложены на
|
|
46
|
+
общий, публичную часть, письма и внутреннюю часть.
|
|
47
|
+
- **Перевод содержимого идёт до записи, а не после.** Иначе страница оказывается наполовину
|
|
48
|
+
переведённой; кэш сбрасывается после записи и один раз.
|
|
49
|
+
- **Без ключа доступа к переводчику сохранение проходит**, но переводы остаются прежними — и
|
|
50
|
+
единственный признак этого владелец видит предупреждением.
|
|
51
|
+
- **Новый маршрут без ветки под каждую локаль существует только в локали по умолчанию.**
|
|
52
|
+
Остальные адреса отдадут отказ и поисковику, и читателю.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: typescript-conventions
|
|
3
|
+
kind: rule
|
|
4
|
+
law: code-structure
|
|
5
|
+
description: Правило под закон «Устройство кода». Брать при правке любого .ts, кроме тех, у которых есть своё правило, — род объявления в имени, модификаторы доступа, приватные поля, суффикс источника, запрет приведения в переводчике моделей. Чем это названо здесь — в implementation.md рядом.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Устройство кода — каким приёмом
|
|
9
|
+
|
|
10
|
+
Правило под закон `{{lawsDir}}/code-structure.md`. Закон говорит, что должно быть верно про
|
|
11
|
+
объявления; здесь — как это записывается. Какими правилами линтера это держится и где они
|
|
12
|
+
лежат — `implementation.md` рядом.
|
|
13
|
+
|
|
14
|
+
## Когда берётся
|
|
15
|
+
|
|
16
|
+
Правка любого файла с кодом, у которого нет своего правила: функции, типа, перечисления,
|
|
17
|
+
переводчика моделей, обработчика серверной стороны.
|
|
18
|
+
|
|
19
|
+
## Что здесь действует
|
|
20
|
+
|
|
21
|
+
- **Род объявления виден по префиксу имени, и это держат правила линтера.** У интерфейса, у
|
|
22
|
+
типа и у перечисления свои; проверяются все файлы с кодом, а не выборочно.
|
|
23
|
+
- **Источник, за которым следят, назван суффиксом.** Пишущий источник и наблюдаемое, поднятое
|
|
24
|
+
из него, различаются в месте использования, а не переходом к объявлению.
|
|
25
|
+
- **Тип берётся из того пакета, где объявлен.** Своя копия чужого типа расходится с оригиналом
|
|
26
|
+
молча, а компилируется из них только одна.
|
|
27
|
+
- **Отметка об устаревании ставится вместе с обходом потребителей.** Пометка на типе красит
|
|
28
|
+
каждое место, где его ещё зовут: один `@deprecated` на файл даёт замечания во всех чужих
|
|
29
|
+
доменах разом, и правка перестаёт быть локальной.
|
|
30
|
+
- **Приведение значения к типу в переводчике моделей не пишется.** Оно принимает любое значение
|
|
31
|
+
и компилируется — то есть снимает ровно ту проверку, ради которой переводчик и заведён.
|
|
32
|
+
|
|
33
|
+
## Паттерны
|
|
34
|
+
|
|
35
|
+
- `ts-procedure` — завести обработчик серверной стороны: класс, метка, право, регистрация.
|
|
36
|
+
|
|
37
|
+
## Ловушки
|
|
38
|
+
|
|
39
|
+
- **Неиспользуемый параметр убирается, а не переименовывается.** Подчёркивание перед именем
|
|
40
|
+
прячет замечание, но параметр остаётся в сигнатуре и продолжает обещать значение.
|
|
41
|
+
- **Агрегат хранилища своим сгенерированным типом не аннотируется.** Сгенерированный тип шире,
|
|
42
|
+
чем результат выборки, и аннотация врёт — причём в сторону, которую компилятор не оспорит.
|
|
43
|
+
- **Своё правило линтера включается вместе с переводом всех, кого оно ловит.** Включённое
|
|
44
|
+
поверх накопленного даёт красный прогон на файлах, которых правка не касалась.
|
|
45
|
+
- **Приватное поле с решёткой видно только внутри класса.** Там, где к полю обращается шаблон
|
|
46
|
+
или обёртка каркаса, оно объявляется защищённым, а не приватным.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Карта «что правится — какое правило» этого дерева. Её читает хук гейта правил.
|
|
3
|
+
#
|
|
4
|
+
# Живёт в проекте, а не в пакете: имена каталогов, расширения и команды поставки у каждого
|
|
5
|
+
# дерева свои. Пакет везёт механизм, проект — карту.
|
|
6
|
+
#
|
|
7
|
+
# Функция печатает ИМЯ ПРАВИЛА или молчит. Молчание — «правила на это нет», и гейт пропускает.
|
|
8
|
+
#
|
|
9
|
+
# Порядок веток решает: первое совпадение выигрывает, поэтому частное идёт раньше общего.
|
|
10
|
+
# Файл спеки — не файл компонента, и обе ветки обязаны стоять до общей ветки расширения.
|
|
11
|
+
|
|
12
|
+
skill_for() {
|
|
13
|
+
kind="$1"
|
|
14
|
+
target="$2"
|
|
15
|
+
|
|
16
|
+
case "$kind" in
|
|
17
|
+
edit)
|
|
18
|
+
case "$target" in
|
|
19
|
+
# Файлы самого агента правятся без правила: правило на них — это оно само.
|
|
20
|
+
*/.claude/*) return 0 ;;
|
|
21
|
+
*.spec.ts) printf '%s' '<правило про тесты>' ;;
|
|
22
|
+
*.component.ts|*.component.html) printf '%s' '<правило про компонент>' ;;
|
|
23
|
+
*.scss) printf '%s' '<правило про оформление>' ;;
|
|
24
|
+
*/index.ts) printf '%s' '<правило про раскладку либ>' ;;
|
|
25
|
+
*.ts) printf '%s' '<правило про код>' ;;
|
|
26
|
+
*.md) printf '%s' '<правило про тексты>' ;;
|
|
27
|
+
esac
|
|
28
|
+
;;
|
|
29
|
+
bash)
|
|
30
|
+
case "$target" in
|
|
31
|
+
*git\ commit*|*git\ push*|*gh\ pr\ create*) printf '%s' '<правило про поставку>' ;;
|
|
32
|
+
esac
|
|
33
|
+
;;
|
|
34
|
+
esac
|
|
35
|
+
|
|
36
|
+
return 0
|
|
37
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# <имя-правила> — как это устроено здесь
|
|
2
|
+
|
|
3
|
+
Имена этого дерева при правиле `SKILL.md` рядом. Отдельный файл потому, что правило говорит
|
|
4
|
+
приёмом и переносится между репозиториями целиком, а всё, что ниже, верно только здесь и
|
|
5
|
+
устаревает при каждом переименовании.
|
|
6
|
+
|
|
7
|
+
Пока в файле стоит `<!-- заполняет проект -->`, правило считается неразвёрнутым: `agent-kit
|
|
8
|
+
sync --check` отказывает, а агент читает указание, которому здесь нечего назвать.
|
|
9
|
+
|
|
10
|
+
## Как это называется здесь
|
|
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
|
+
- <Команда, которая ловит нарушение, — и что именно она ловит.>
|
|
@@ -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,41 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Профиль этого дерева: что здесь чем зовётся и какими командами проверяется.
|
|
3
|
+
#
|
|
4
|
+
# Живёт в проекте, а не в пакете: механизм у сторожевых хуков общий, а команды, порты и пары
|
|
5
|
+
# «правка — её документ» у каждого дерева свои. Пакет везёт хуки, проект — этот файл.
|
|
6
|
+
#
|
|
7
|
+
# Каждая функция вправе промолчать. Молчание значит «правила на это нет», и хук пропускает:
|
|
8
|
+
# пустой профиль оставляет хуки безвредными, а не отбивающими наугад.
|
|
9
|
+
|
|
10
|
+
# Где подняты приложения. Идёт в текст отказа, когда кто-то поднимает второй экземпляр.
|
|
11
|
+
RT_STANDS='<приложение> http://localhost:<порт>, <приложение> http://localhost:<порт>'
|
|
12
|
+
|
|
13
|
+
# Команды, которые обязаны пройти перед пушем. По одной на строку; первая упавшая отбивает пуш.
|
|
14
|
+
rt_push_checks() {
|
|
15
|
+
cat <<'EOF'
|
|
16
|
+
<команда линтера кода>
|
|
17
|
+
<команда линтера стилей>
|
|
18
|
+
<команда тестов>
|
|
19
|
+
EOF
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
# Какой документ обязан ехать тем же коммитом, что и этот файл. Печатает путь или молчит.
|
|
23
|
+
rt_docs_pair_for() {
|
|
24
|
+
case "$1" in
|
|
25
|
+
*/<каталог правил>/*) printf '%s' '<зеркало правила>' ;;
|
|
26
|
+
*.proto) printf '%s' '<спек задетого домена>' ;;
|
|
27
|
+
esac
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
# Чем линтуется этот файл сразу после правки. Печатает команду или молчит.
|
|
31
|
+
rt_lint_for() {
|
|
32
|
+
case "$1" in
|
|
33
|
+
*.scss) printf '%s' '<команда линтера стилей> "$1"' ;;
|
|
34
|
+
*.ts) printf '%s' '<команда линтера кода> "$1"' ;;
|
|
35
|
+
esac
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# Имя ветки, с которой разрешено открывать PR: номер задачи в имени. Успех — годится.
|
|
39
|
+
rt_task_branch_ok() {
|
|
40
|
+
printf '%s' "$1" | grep -qE '<выражение имени ветки>'
|
|
41
|
+
}
|
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
|
-
Правило под закон `{{lawsDir}}/<закон>.md`. Закон говорит, что должно быть верно; здесь —
|
|
11
|
-
это названо в этом
|
|
10
|
+
Правило под закон `{{lawsDir}}/<закон>.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
|
|
package/bin/agent-kit.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { IOutcomeOfCommand } from '../lib/commands.js';
|
|
3
|
-
export declare function main(argv: readonly string[]): IOutcomeOfCommand
|
|
3
|
+
export declare function main(argv: readonly string[]): Promise<IOutcomeOfCommand>;
|
|
4
4
|
//# sourceMappingURL=agent-kit.d.ts.map
|
package/bin/agent-kit.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-kit.d.ts","sourceRoot":"","sources":["../../../projects/agent-kit/src/bin/agent-kit.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"agent-kit.d.ts","sourceRoot":"","sources":["../../../projects/agent-kit/src/bin/agent-kit.ts"],"names":[],"mappings":";AAaA,OAAO,EAA8B,iBAAiB,EAAc,MAAM,oBAAoB,CAAC;AAwF/F,wBAAsB,IAAI,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAsB9E"}
|