@rt-tools/agent-kit 0.3.0 → 0.5.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.
Files changed (202) hide show
  1. package/README.md +194 -30
  2. package/assets/agents/business-analyst.md +74 -0
  3. package/assets/agents/project-manager.md +70 -0
  4. package/assets/agents/qa-engineer.md +72 -0
  5. package/assets/agents/skill-curator.md +110 -0
  6. package/assets/agents/spec-critic.md +44 -0
  7. package/assets/agents/spec-writer.md +50 -0
  8. package/assets/checks/board.github.mjs +329 -0
  9. package/assets/checks/check-board.github.mjs +181 -0
  10. package/assets/checks/check-doc-paths.mjs +163 -0
  11. package/assets/checks/check-dupes.mjs +277 -0
  12. package/assets/checks/check-lib-layers.mjs +573 -0
  13. package/assets/checks/check-reuse.mjs +208 -0
  14. package/assets/checks/check-schema-drift.mjs +186 -0
  15. package/assets/checks/check-specs.mjs +1086 -0
  16. package/assets/checks/check-styles.mjs +109 -0
  17. package/assets/checks/rt-kit-checks.config.mjs +134 -0
  18. package/assets/checks/task-new.github.mjs +198 -0
  19. package/assets/commands/skill-curator.md +70 -0
  20. package/assets/defaults/gate-map.sh +106 -0
  21. package/assets/defaults/project.sh +204 -0
  22. package/assets/hooks/browser-device-id.sh +0 -0
  23. package/assets/hooks/browser-guard-device-id.sh +2 -1
  24. package/assets/hooks/browser-guard-no-asking.sh +27 -0
  25. package/assets/hooks/browser-guard-no-listing.sh +2 -1
  26. package/assets/hooks/browser-guard-no-other-drivers.sh +2 -1
  27. package/assets/hooks/browser-guard-require-select.sh +2 -1
  28. package/assets/hooks/commit-msg.sh +1 -1
  29. package/assets/hooks/constitution-index.sh +5 -4
  30. package/assets/hooks/dev-server-guard.sh +8 -6
  31. package/assets/hooks/docs-guard.sh +223 -37
  32. package/assets/hooks/git-guard-delivery.sh +171 -31
  33. package/assets/hooks/git-guard-main.sh +1 -0
  34. package/assets/hooks/git-guard-push-tests.sh +34 -13
  35. package/assets/hooks/glossary-load.sh +23 -0
  36. package/assets/hooks/grill-gate.sh +96 -0
  37. package/assets/hooks/lint-after-edit.sh +155 -30
  38. package/assets/hooks/qa-dataid-guard.sh +72 -32
  39. package/assets/hooks/reuse-first-guard.sh +105 -34
  40. package/assets/hooks/skill-gate-rearm.sh +1 -0
  41. package/assets/hooks/skill-gate.sh +75 -15
  42. package/assets/hooks/skill-loaded.sh +1 -0
  43. package/assets/hooks/sql-guard.sh +606 -56
  44. package/assets/hooks/task-context-load.sh +100 -0
  45. package/assets/hooks/task-flow-guard.sh +118 -0
  46. package/assets/laws/{access.md → application/access.md} +1 -4
  47. package/assets/laws/{locales.md → application/locales.md} +1 -3
  48. package/assets/laws/application/money.md +41 -0
  49. package/assets/laws/application/ownership.md +32 -0
  50. package/assets/laws/{search-visibility.md → application/search-visibility.md} +1 -1
  51. package/assets/laws/code-structure.md +7 -6
  52. package/assets/laws/delivery.md +53 -3
  53. package/assets/laws/entity-editing.md +49 -55
  54. package/assets/laws/entity-models.md +4 -14
  55. package/assets/laws/frontend-application.md +5 -5
  56. package/assets/laws/lib-imports.md +14 -1
  57. package/assets/laws/lists.md +33 -0
  58. package/assets/laws/navigation.md +40 -0
  59. package/assets/laws/project-documentation.md +27 -8
  60. package/assets/laws/reuse-first.md +26 -21
  61. package/assets/laws/shared-code.md +13 -1
  62. package/assets/laws/verifiability.md +30 -1
  63. package/assets/laws/work-conduct.md +59 -0
  64. package/assets/patterns/admin-lists-screen.md +131 -0
  65. package/assets/patterns/admin-nav-item.md +71 -0
  66. package/assets/patterns/angular-patterns-state.md +29 -22
  67. package/assets/patterns/api-layer-pair.md +40 -30
  68. package/assets/patterns/browser-verification-measure.md +41 -38
  69. package/assets/patterns/browser-verification-stand.md +106 -42
  70. package/assets/patterns/component-structure-new.md +33 -32
  71. package/assets/patterns/dependencies-upgrade.md +65 -0
  72. package/assets/patterns/doc-style-sweep.md +65 -28
  73. package/assets/patterns/doc-style-write.md +36 -33
  74. package/assets/patterns/entity-aside.md +136 -0
  75. package/assets/patterns/entity-models-new.md +124 -0
  76. package/assets/patterns/entity-store.md +91 -0
  77. package/assets/patterns/git-workflow-commit.azure.md +259 -0
  78. package/assets/patterns/git-workflow-commit.github.md +337 -0
  79. package/assets/patterns/git-workflow-commit.gitlab.md +283 -0
  80. package/assets/patterns/git-workflow-merge.md +42 -25
  81. package/assets/patterns/git-workflow-migration.md +61 -31
  82. package/assets/patterns/git-workflow-restart.md +20 -20
  83. package/assets/patterns/lib-layers-move.md +50 -32
  84. package/assets/patterns/lib-layers-new.md +41 -29
  85. package/assets/patterns/ownership-scope-resolve.md +69 -0
  86. package/assets/patterns/permissions-procedure.md +35 -33
  87. package/assets/patterns/platform-access-di.md +39 -25
  88. package/assets/patterns/pricing-quote.md +71 -0
  89. package/assets/patterns/reuse-first-extend.md +22 -22
  90. package/assets/patterns/seo-page.md +52 -40
  91. package/assets/patterns/seo-verify.md +48 -29
  92. package/assets/patterns/shared-code-new.md +37 -31
  93. package/assets/patterns/spec-driven-domain.md +60 -37
  94. package/assets/patterns/spec-driven-rule.md +55 -40
  95. package/assets/patterns/styling-bem-component.md +43 -32
  96. package/assets/patterns/styling-bem-layout.md +30 -24
  97. package/assets/patterns/task-flow-close.md +154 -0
  98. package/assets/patterns/task-flow-resume.md +94 -0
  99. package/assets/patterns/task-flow-start.md +129 -0
  100. package/assets/patterns/testing-e2e.md +53 -51
  101. package/assets/patterns/testing-unit.md +70 -46
  102. package/assets/patterns/translations-key.md +32 -19
  103. package/assets/patterns/ts-procedure.md +24 -25
  104. package/assets/rules/angular-patterns.md +50 -27
  105. package/assets/rules/api-layer.md +46 -28
  106. package/assets/rules/browser-verification.md +67 -48
  107. package/assets/rules/component-structure.md +43 -27
  108. package/assets/rules/dependencies.md +66 -0
  109. package/assets/rules/doc-style.md +95 -39
  110. package/assets/rules/entity-conventions.md +78 -0
  111. package/assets/rules/entity-models.md +70 -0
  112. package/assets/rules/git-workflow.azure.md +116 -0
  113. package/assets/rules/git-workflow.github.md +123 -0
  114. package/assets/rules/git-workflow.gitlab.md +113 -0
  115. package/assets/rules/lib-layers.md +56 -30
  116. package/assets/rules/lists.md +73 -0
  117. package/assets/rules/navigation.md +78 -0
  118. package/assets/rules/ownership-scope.md +63 -0
  119. package/assets/rules/permissions.md +43 -25
  120. package/assets/rules/platform-access.md +57 -29
  121. package/assets/rules/pricing.md +64 -0
  122. package/assets/rules/reuse-first.md +57 -43
  123. package/assets/rules/seo.md +51 -30
  124. package/assets/rules/shared-code.md +51 -26
  125. package/assets/rules/spec-driven.md +107 -51
  126. package/assets/rules/styling-bem.md +54 -39
  127. package/assets/rules/task-flow.md +150 -0
  128. package/assets/rules/testing.md +78 -47
  129. package/assets/rules/translations.md +48 -31
  130. package/assets/rules/typescript-conventions.md +57 -27
  131. package/assets/skills/agent-kit.md +85 -0
  132. package/assets/skills/write-a-skill.md +108 -0
  133. package/assets/templates/gate-map.sh +23 -15
  134. package/assets/templates/implementation.md +14 -8
  135. package/assets/templates/pattern.md +1 -1
  136. package/assets/templates/project.sh +32 -19
  137. package/assets/templates/rule.md +2 -2
  138. package/assets/variants.json +20 -0
  139. package/assets/workflows/feature.js +134 -0
  140. package/assets/workflows/plan.js +150 -0
  141. package/bin/agent-kit.d.ts.map +1 -1
  142. package/bin/agent-kit.js +78 -5
  143. package/bin/agent-kit.js.map +1 -1
  144. package/bin/prompt.d.ts +5 -0
  145. package/bin/prompt.d.ts.map +1 -1
  146. package/bin/prompt.js +19 -7
  147. package/bin/prompt.js.map +1 -1
  148. package/index.d.ts +1 -0
  149. package/index.d.ts.map +1 -1
  150. package/index.js +1 -0
  151. package/index.js.map +1 -1
  152. package/lib/assets.d.ts +8 -3
  153. package/lib/assets.d.ts.map +1 -1
  154. package/lib/assets.js +13 -3
  155. package/lib/assets.js.map +1 -1
  156. package/lib/catalog.d.ts +52 -5
  157. package/lib/catalog.d.ts.map +1 -1
  158. package/lib/catalog.js +104 -16
  159. package/lib/catalog.js.map +1 -1
  160. package/lib/commands.d.ts +22 -1
  161. package/lib/commands.d.ts.map +1 -1
  162. package/lib/commands.js +202 -14
  163. package/lib/commands.js.map +1 -1
  164. package/lib/companion.d.ts +5 -1
  165. package/lib/companion.d.ts.map +1 -1
  166. package/lib/companion.js +29 -2
  167. package/lib/companion.js.map +1 -1
  168. package/lib/config.d.ts +26 -9
  169. package/lib/config.d.ts.map +1 -1
  170. package/lib/config.js +41 -15
  171. package/lib/config.js.map +1 -1
  172. package/lib/freshness.d.ts +14 -0
  173. package/lib/freshness.d.ts.map +1 -0
  174. package/lib/freshness.js +116 -0
  175. package/lib/freshness.js.map +1 -0
  176. package/lib/hooks-map.d.ts +27 -0
  177. package/lib/hooks-map.d.ts.map +1 -0
  178. package/lib/hooks-map.js +77 -0
  179. package/lib/hooks-map.js.map +1 -0
  180. package/lib/integrity.d.ts +36 -0
  181. package/lib/integrity.d.ts.map +1 -0
  182. package/lib/integrity.js +44 -0
  183. package/lib/integrity.js.map +1 -0
  184. package/lib/picker.d.ts +11 -1
  185. package/lib/picker.d.ts.map +1 -1
  186. package/lib/picker.js +44 -6
  187. package/lib/picker.js.map +1 -1
  188. package/lib/sync.d.ts +26 -0
  189. package/lib/sync.d.ts.map +1 -1
  190. package/lib/sync.js +59 -4
  191. package/lib/sync.js.map +1 -1
  192. package/lib/variants.d.ts +44 -0
  193. package/lib/variants.d.ts.map +1 -0
  194. package/lib/variants.js +82 -0
  195. package/lib/variants.js.map +1 -0
  196. package/package.json +1 -1
  197. package/rt-tools-agent-kit-0.5.0.tgz +0 -0
  198. package/assets/laws/admin-lists.md +0 -35
  199. package/assets/laws/admin-navigation.md +0 -38
  200. package/assets/patterns/git-workflow-commit.md +0 -175
  201. package/assets/rules/git-workflow.md +0 -106
  202. package/rt-tools-agent-kit-0.3.0.tgz +0 -0
@@ -2,52 +2,70 @@
2
2
  name: api-layer
3
3
  kind: rule
4
4
  law: frontend-application
5
- description: Правило под закон «Фронтовое приложение». Брать при правке слоя обращения к серверу во фронтовом домене пары «фасад и служба» и переводчиков моделей при ней. Один вход выборки у списка, общий конвертер страницы, поток вместо ожидания. Готовый код — в паттерне api-layer-pair. Чем это названо здесь — в implementation.md рядом.
5
+ description: Правило под «Закон о фронтовом приложении». Брать при правке слоя api фронтового домена *-api.facade.ts, *-api.service.ts и мапперов в его mappers/ под libs/admin и libs/site. Называет пару «фасад и сервис», один вход выборки у списка и общий конвертер страницы. Готовый код — в паттерне api-layer-pair.
6
6
  ---
7
7
 
8
- # Обращение к серверу — каким приёмом
8
+ # Обращение к серверу — как это устроено здесь
9
9
 
10
- Правило под закон `{{lawsDir}}/frontend-application.md`. Закон говорит, что должно быть верно;
11
- здесь — из чего сложен слой обращения к серверу. Как названы модели выборки, где лежат
12
- переводчики и чем зовётся общий конвертер — `implementation.md` рядом. Состояние
13
- `angular-patterns`, файл компонента `component-structure`, оформление — `styling-bem`,
14
- окружение браузера — `platform-access`. Все пять под одним законом.
10
+ Правило под закон `docs/constitution/frontend-application.md`. Закон говорит, что должно быть
11
+ верно; здесь — из чего сложен слой обращения к серверу. Состояние `angular-patterns`, файл
12
+ компонента `component-structure`, стили — `styling-bem`, окружение браузера
13
+ `platform-access`. Все пять под одним законом.
15
14
 
16
- Правило про фронтовые семьи. На серверной стороне тем же словом называют выход к чужому
17
- сервису, и устроен он иначе.
15
+ Правило про обе фронтовые семьи: `libs/admin/*/api/**` и `libs/site/*/api/**`. На бэкенде слово
16
+ `api` означает выход к чужому сервису и устроено иначе — там `typescript-conventions`.
18
17
 
19
- ## Когда берётся
18
+ ## Как это называется здесь
20
19
 
21
- Правка слоя обращения к серверу во фронтовом домене: фасада, службы, переводчиков моделей при
22
- них.
20
+ | В законе | Здесь |
21
+ | ---------------- | ------------------------------------------------------------------------------ |
22
+ | страница записей | `IPageModel` — `pageNumber`, `pageSize`, `totalCount` |
23
+ | выборка списка | `IList.Query.State` — страница, порядок, условия отбора, строка поиска |
24
+ | ответ списка | `data`, `pageModel`, `sortModel`, `filterModel`, `searchTerm` |
25
+ | путь запроса | экран → стор → `<Сущность>ApiService` → `<Сущность>ApiFacade` → клиент Connect |
23
26
 
24
- ## Что здесь действует
27
+ ## Где это лежит
25
28
 
26
- - **Домен ходит за данными парой классов: фасад зовёт обработчика, служба переводит модели.**
29
+ В этом дереве таблица в `implementation.md` рядом. Пути живут там, а не здесь: правило
30
+ переносится между репозиториями, раскладка — нет, и путь, названный в правиле, врёт в первом
31
+ же дереве, которое держит код иначе.
32
+
33
+ ## Как закон применяется здесь
34
+
35
+ - **Домен ходит за данными парой классов: фасад зовёт процедуру, сервис переводит модели.**
27
36
  Один класс на оба дела означал бы, что подмена источника тянет за собой перевод.
28
- - **Фасад знает только контракт, служба отдаёт только модель.** Тип из контракта до стора и
37
+ - **Фасад знает только контракт, сервис отдаёт только `State`.** Тип из контракта до стора и
29
38
  шаблона не доходит.
30
- - **У списка один вход — выборка.** Объект, к которому привязан список, род ленты, состояние
31
- подписки — такие же условия отбора, и лежат они в её условиях, а не отдельными входами.
39
+ - **У списка один вход — выборка.** Объект, к которому привязан список, тип фида, состояние
40
+ подписки — такие же условия отбора, и лежат они в `filterModel`.
32
41
  - **Ответ списка ложится в общий конвертер целиком.** Контракт отдаёт страницу в той же форме,
33
- что и модель, и промежуточного объекта в службе не остаётся.
42
+ что и модель, и промежуточного объекта в сервисе не остаётся.
34
43
  - **Поля порядка и отбора — перечисления домена, а не голая строка.** Голая строка означает,
35
- что имя, по которому сервер не сортирует, компилируется и падает уже запросом.
36
- - **Пара отдаёт поток, а не ожидание.** Основа списочного стора работает потоками, и служба на
37
- обещаниях в неё не ложится.
44
+ что имя, по которому сервер не сортирует, компилируется и падает запросом.
45
+ - **Пара отдаёт поток, а не ожидание.** Основа списочного стора работает потоками, и промисный
46
+ сервис в неё не ложится.
47
+
48
+ ## Чего из закона здесь нет
49
+
50
+ Общей выборкой ходят только те списки, которым сервер отдаёт страницу — признак `page_model` в
51
+ ответе процедуры. Заявки и объекты приходят целиком: процедуры со страницей у них пока нет, и
52
+ это долги `Q-L-5` и `Q-L-7`, а не другая форма слоя.
53
+
54
+ Сторы, которые ещё держат прежнюю сигнатуру, зовут поток через `firstValueFrom` и несут над
55
+ классом комментарий с тем, когда мост уйдёт. Новый стор моста не заводит.
38
56
 
39
57
  ## Паттерны
40
58
 
41
- - `api-layer-pair` — готовые фасад, служба и перевод выборки.
59
+ - `api-layer-pair` — готовые фасад, сервис и перевод выборки.
42
60
 
43
61
  ## Ловушки
44
62
 
45
63
  - **Выборка в ответе — применённая, а не запрошенная.** Порядок по умолчанию и отброшенное
46
64
  сервером условие экран иначе не увидит.
47
- - **Одна пара — одна сущность.** У связанных сущностей свои пары, даже когда их обработчики
48
- лежат в одном сервисе контракта.
65
+ - **Одна пара — одна сущность.** У объекта, его прежних адресов и подписок на календари свои
66
+ пары, хотя процедуры лежат в одном proto-сервисе.
49
67
  - **Метод, которого у домена нет, не объявляется.** Список читают все, правят не все.
50
- - **Серверный поток событий — исключение из правила про поток.** Живой срез приходит
51
- асинхронным итератором, и заворачивать его некуда.
52
- - **Своей копии общих переводчиков страницы, порядка и отбора домен не заводит.** Второй
53
- экземпляр ловит проверка повторов — правило `shared-code`.
68
+ - **Серверный стрим — исключение из правила про поток:** живой срез аналитики и лента тредов
69
+ приходят асинхронным итератором, и заворачивать его некуда.
70
+ - Своей копии общих мапперов страницы, порядка и отбора домен не заводит — второй экземпляр
71
+ ловит `npm run check:dupes`.
@@ -2,68 +2,87 @@
2
2
  name: browser-verification
3
3
  kind: rule
4
4
  law: verifiability
5
- description: Правило под закон «Проверяемость». Брать при любой проверке через браузер и при запросах к поднятому приложению из командной строки. Чему на сервере разработки верить нельзя, чем измерять вместо взгляда, почему браузер водится одним драйвером. Готовый код — в паттернах browser-verification-stand и browser-verification-measure. Чем это названо здесь — в implementation.md рядом.
5
+ description: Правило под «Закон о проверяемости». Брать при любой проверке через браузер и при запросах curl или wget к дев-серверу. Называет порты сайта, админки и API, чему на дев-сервере верить нельзя и чем измерять вместо взгляда. Готовый код — в паттернах browser-verification-stand и browser-verification-measure.
6
6
  ---
7
7
 
8
- # Проверка работающего приложения — каким приёмом
8
+ # Проверка работающего приложения — как это устроено здесь
9
9
 
10
- Правило под закон `{{lawsDir}}/verifiability.md`. Закон говорит, что считается подтверждением;
11
- здесь — каким приёмом приложение проверяется живьём. На каких портах оно поднято, каким
12
- драйвером водится браузер и где лежит конфиг прокси — `implementation.md` рядом. Тесты под тем
13
- же законом — правило `testing`.
10
+ Правило под закон `docs/constitution/verifiability.md`. Закон говорит, что считается
11
+ подтверждением; здесь — где живут приложения, чему на них можно верить и чем измерять. Тесты
12
+ под тем же законом правило `testing`.
14
13
 
15
- ## Когда берётся
14
+ ## Как это называется здесь
16
15
 
17
- Любая проверка через браузер, любой запрос к поднятому приложению из командной строки, любой
18
- вывод о вёрстке.
16
+ | В законе | Здесь |
17
+ | --------------------------------- | ----------------------------------------------------------------------------------------------- |
18
+ | работающее приложение | то, что поднято в этом дереве; перечень и порты — в `implementation.md` рядом |
19
+ | место, где его видит пользователь | прод-сборка за настоящим `deploy/nginx.conf`, а не дев-сервер |
20
+ | замер | `getComputedStyle`, `getBoundingClientRect`, контраст, совпадение центров, попадание во вьюпорт |
21
+ | драйвер браузера | `claude-in-chrome` на закреплённом профиле этого дерева |
19
22
 
20
- ## Что здесь действует
23
+ ## Где это лежит
21
24
 
22
- - **Свой сервер разработки не поднимается.** Приложения уже подняты владельцем; второй
23
- экземпляр слушает другой порт и отвечает другой сборкой, а расхождение читается как дефект
24
- правки.
25
+ В этом дереве таблица в `implementation.md` рядом. Пути живут там, а не здесь: правило
26
+ переносится между репозиториями, раскладка — нет, и путь, названный в правиле, врёт в первом
27
+ же дереве, которое держит код иначе.
28
+
29
+ ## Как закон применяется здесь
30
+
31
+ - **Второй экземпляр уже поднятого приложения не поднимается.** До первого запроса выясняется,
32
+ кто отвечает на порту: поднятый заново экземпляр отвечает своей сборкой, а не той, которую
33
+ проверяют. Кто поднимает стенд — владелец или агент, — сказано в именах дерева.
25
34
  - **Браузер водится одним драйвером на закреплённом профиле.** Остальные двери — второй
26
- драйвер, открытие ссылки средствами системы, запуск бинарника — закреплённый профиль не
27
- спрашивают вовсе и приходят в сеанс без входа.
28
- - **Выбор браузера протухает и требует повторного вызова.** Выбор, сделанный в начале сессии,
29
- не держится: после паузы следующий вызов открывает вкладку в другом профиле молча.
35
+ драйвер, `open`, `osascript`, запуск бинарника — закреплённый профиль не спрашивают вовсе.
36
+ - **Выбор браузера протухает и требует повторного вызова.** Выбор, сделанный в начале
37
+ сессии, не держится: после паузы следующий вызов открывает вкладку в другом профиле молча.
30
38
  - **Профиль не выбирается из списка и не спрашивается у владельца.** Список отдаёт неустойчивые
31
39
  имена, которые не опознают ничего, а выбор из него ведёт на профиль без входа.
32
- - **Прод-конфигурация проверяется только за настоящим прокси.** Голый сервер отдачи страниц про
33
- кэш, перенаправления и заголовки не знает ничего.
34
- - **Вывод о вёрстке подкрепляется числом.** «Выглядит нормально» результатом проверки не
35
- является; чем мерить паттерн `browser-verification-measure`.
40
+ - **Прод-конфигурация проверяется только за настоящим прокси.** Голый сервер отдачи страниц
41
+ про кэш, перенаправления и заголовки не знает ничего.
42
+
43
+ Вывод о вёрстке подкрепляется числом: «выглядит нормально» результатом проверки не является.
44
+ Этого не стережёт ничто — как измерять, разобрано в паттерне `browser-verification-measure`.
45
+
46
+ ## Чего из закона здесь нет
47
+
48
+ Проверки на прямое обращение к окружению браузера нет — это `Q-FA-1` в законе о фронтовом
49
+ приложении: такое обращение компилируется и падает только при отдаче страницы сервером.
36
50
 
37
51
  ## Паттерны
38
52
 
39
- - `browser-verification-stand` — честный стенд из прод-сборки, вход в приложение, разбор порта.
40
- - `browser-verification-measure` — замер вместо взгляда, ловушки инструмента снимка экрана.
53
+ - `browser-verification-stand` — честный стенд из прод-сборки, вход в админку, разбор порта.
54
+ - `browser-verification-measure` — замер вместо взгляда, ловушки инструмента `computer`.
41
55
 
42
56
  ## Ловушки
43
57
 
44
- - **Сначала выяснить, что отвечает на порту.** На порту регулярно висит собранный артефакт из
45
- прошлой сессии: он отвечает успехом на старом коде, а заведённого в ветке обработчика у него
46
- нет вовсе и отказ читается как дефект регистрации. Таких процессов бывает несколько, и
47
- завершение по имени команды не попадает ни в один: убивать по идентификатору процесса,
48
- каждый.
49
- - **Инкрементальная сборка протухает поштучно.** Разметка бывает уже новой, а клиентский кусок
50
- — от компиляции до правки. Признак сборки для разработки — имена файлов сборки без хеша.
51
- Расхождение между ответом из командной строки и страницей после оживления — повод пересобрать,
52
- а не искать дефект в коде; вывод «такого маршрута нет» отсюда тоже не следует.
53
- - **Кэш объясняет расхождение, но не подтверждает его.** Вывод «дефекта нет, это кэш» закрывает
54
- разбор, поэтому принимается только после проверки на чистой сборке.
55
- - **Сообщение об отсутствии отладочных API каркаса принадлежит расширению браузера, а не
56
- приложению.** Прод-сборка их не публикует, и лечить это правкой кода не надо: опубликованные,
57
- они дают карту внутренностей любому, кто откроет консоль.
58
- - **Поведение маршрутизации воспроизводится нажатиями.** Подстановка адреса и заход по прямой
59
- ссылке поднимают приложение заново, и накопленного состояния у него нет.
60
- - **Замер отвечает только на заданный вопрос.** Отступы, кегль и скругление сходятся с
61
- образцом, пока никто не спросил про фон на наведении, а держится расхождение при верных
62
- числах ровно столько, сколько его не спрашивают.
58
+ - **Сначала выяснить, что отвечает на порту:** `lsof -nP -iTCP:<порт> -sTCP:LISTEN` до первого
59
+ запроса. На 3333 регулярно висит собранный артефакт из прошлой сессии он отвечает 200
60
+ старым кодом, а заведённой в ветке процедуры у него нет вовсе, и 404 читается как дефект
61
+ регистрации. Таких процессов бывает несколько; `pkill` по `nx serve api` не попадает ни в
62
+ один — убивать по PID из `lsof`, каждый.
63
+ - Инкрементальная сборка протухает поштучно: разметка на 4900 бывает уже новая, а клиентский
64
+ чанк — от компиляции до правки. Признак дев-сборки — имена бандла без хеша (`main.js`).
65
+ Расхождение между `curl` и страницей после гидратации — повод пересобрать, а не искать
66
+ дефект в коде. Отсюда же нельзя делать вывод «такого маршрута нет»: сверяться с
67
+ `app.routes.ts`.
68
+ - **Кэш объясняет расхождение, но не подтверждает его.** В `.angular/cache/…/vite/deps` лежат
69
+ только пакеты из `node_modules`, кода репозитория там нет вовсе. Вывод «дефекта нет, это
70
+ кэш» закрывает разбор, поэтому принимается только после проверки на чистой сборке три
71
+ круга ушло на застрявшую панель ленты событий, пока дефект лежал в снятии аутлета.
72
+ - Сообщение `Angular debugging APIs are not available` в консоли принадлежит расширению
73
+ Chrome, а не приложению: прод-сборка не публикует `window.ng`. Лечить правкой кода не надо —
74
+ `window.ng` в проде это карта внутренностей в руках любого, кто откроет консоль.
75
+ - Поведение роутера воспроизводится нажатиями: подстановка адреса и заход по прямой ссылке
76
+ поднимают приложение заново, и накопленного состояния у него нет.
77
+ - Замер отвечает только на заданный вопрос. Строки попапа профиля сошлись с образцом по
78
+ отступам, кеглю и скруглению, а фон на наведении образец в этом месте не красит вовсе —
79
+ полноширинная подсветка держалась два круга при верных числах.
63
80
  - **Если сменилась версия пакета, который рисует вёрстку, экраны обходят руками.** Тесты
64
- нажимают по меткам и остаются зелёными, даже когда отступ съехал, размер пропал, а строка
65
- стала другой высоты: они проверяют переходы, а не вид. Пары снимков тут тоже мало — смотрят
66
- по очереди все экраны, которые этот пакет рисует.
67
- - **Путей запуска несколько, и проверять их надо порознь.** Локальная команда, образ и состав
68
- прода разные пути; переменная, заданная в команде проверки, не говорит про образ ничего.
69
- Пути перечисляются до проверки, а не после того, как один из них сошёлся.
81
+ нажимают по `qa-dataid` и остаются зелёными, даже когда отступ съехал, размер пропал, а
82
+ строка стала другой высоты: они проверяют переходы, а не вид. Пары скриншотов тут тоже мало
83
+ — смотрят по очереди все экраны, которые этот пакет рисует.
84
+ - **Путей запуска здесь три, и проверять их надо порознь:** локальная команда, образ
85
+ `deploy/api.Dockerfile` и состав `docker-compose.prod.yml`. Переменная, заданная в команде
86
+ проверки, не говорит про образ ничего: в составе прода она есть, а ручной прогон того же
87
+ образа идёт без неё. Пути перечисляются до проверки, а не после того, как один из них
88
+ сошёлся.
@@ -2,33 +2,45 @@
2
2
  name: component-structure
3
3
  kind: rule
4
4
  law: frontend-application
5
- description: Правило под закон «Фронтовое приложение». Брать при правке любого файла компонента и его шаблона порядок свойств декоратора, группировка импортов, договорённости шаблона, обязательный якорь для спек, класс блока на хосте. Готовый код — в паттерне component-structure-new. Чем это названо здесь — в implementation.md рядом.
5
+ description: Правило под «Закон о фронтовом приложении». Брать при правке любого *.component.ts и его шаблона. Называет порядок свойств декоратора, группировку импортов, договорённости шаблона и обязательный qa-dataid. Готовый код — в паттерне component-structure-new.
6
6
  ---
7
7
 
8
- # Файл компонента — каким приёмом
8
+ # Файл компонента — как это устроено здесь
9
9
 
10
- Правило под закон `{{lawsDir}}/frontend-application.md`. Закон говорит, что должно быть верно;
11
- здесь — как устроен сам файл компонента и его шаблон. Какой у компонентов префикс, чем зовётся
12
- якорь спек и где лежат правила линтера — `implementation.md` рядом. Состояние и потоки —
13
- `angular-patterns`, оформление — `styling-bem`, окружение браузера — `platform-access`, слой
10
+ Правило под закон `docs/constitution/frontend-application.md`. Закон говорит, что должно быть
11
+ верно; здесь — как устроен сам файл компонента и его шаблон. Состояние и потоки
12
+ `angular-patterns`, стили `styling-bem`, окружение браузера — `platform-access`, слой
14
13
  обращения к серверу — `api-layer`. Все пять под одним законом.
15
14
 
16
- ## Когда берётся
15
+ ## Как это называется здесь
17
16
 
18
- Заведение или правка файла компонента и его шаблона.
17
+ | В законе | Здесь |
18
+ | ---------------------------------- | ---------------------------------------------------------------------------- |
19
+ | компонент | `vm-<имя>` — префикс один на сайт и админку |
20
+ | готовое, а не вычисление в шаблоне | `computed()`; там, где значение приходит из контекста шаблона, — чистый пайп |
21
+ | якорь для проверки | атрибут `qa-dataid` в kebab-case по смыслу элемента |
22
+ | корень разметки | `:host` с классом блока от `host: { class: 'vm-<имя>' }` |
19
23
 
20
- ## Что здесь действует
24
+ ## Где это лежит
21
25
 
22
- - **Шаблон не зовёт методов.** Вызов в привязке считается заново на каждую проверку изменений;
23
- готовое значение объявляется вычисляемым, а там, где оно зависит от контекста шаблона,
24
- чистым преобразователем.
25
- - **Каждый интерактивный элемент несёт якорь для спек.** Это единственная устойчивая зацепка:
26
- классы оформления меняются вместе с вёрсткой, а поиск по роли и тексту ломается на первой же
27
- второй локали.
26
+ В этом дереве таблица в `implementation.md` рядом. Пути живут там, а не здесь: правило
27
+ переносится между репозиториями, раскладка нет, и путь, названный в правиле, врёт в первом
28
+ же дереве, которое держит код иначе.
29
+
30
+ ## Как закон применяется здесь
31
+
32
+ - **Шаблон не зовёт методов.** Правило линтера банит `{{ getTotal() }}` и `@if
33
+ (computeFlag())`, чтения сигналов не трогает.
34
+ - **Каждый интерактивный элемент несёт `qa-dataid`.** Это единственный якорь спек: классы BEM
35
+ меняются вместе с вёрсткой, а поиск по роли и тексту ломается на локалях перевода.
28
36
  - **Класс блока висит на хосте, а не на обёртке внутри шаблона.** Лишняя обёртка вокруг всех
29
- детей — это раскладка, и ей место на хосте.
30
- - **Якорь для спек не заменяет доступности и не снимается при правке вёрстки.** Доступность
31
- отдельно, якорь отдельно; на якорь завязаны спеки, и снятый он роняет их молча.
37
+ детей — это раскладка, и ей место на `:host`.
38
+
39
+ ## Чего из закона здесь нет
40
+
41
+ Порядок свойств декоратора, группировку импортов и самозакрывающиеся теги не проверяет ничто —
42
+ они держатся чтением соседнего файла. Проверки на прямое обращение к окружению браузера тоже
43
+ нет — это `Q-FA-1` в законе.
32
44
 
33
45
  ## Паттерны
34
46
 
@@ -36,13 +48,17 @@ description: Правило под закон «Фронтовое прилож
36
48
 
37
49
  ## Ловушки
38
50
 
39
- - **Ссылка на фрагмент в разметке не прокручивает страницу.** Когда в разметке объявлен
40
- базовый адрес, браузер разрешает фрагмент относительно него: вместо прокрутки получается
41
- полная навигация с перезагрузкой. Прокрутка делается средствами маршрутизатора.
42
- - **Один и тот же компонент в обеих ветках условия — это условная привязка.** Две ветки с
51
+ - **`href="#id"` в разметке не работает.** Сборка одна на все локали, в разметке стоит
52
+ `<base href="/">`, и браузер разрешает фрагмент относительно базы: вместо прокрутки
53
+ получается полная навигация с перезагрузкой. Прокрутка через роутер:
54
+ `<a [routerLink]="[]" fragment="booking">`.
55
+ - **Один и тот же компонент в обеих ветках `@if` — это условная привязка.** Две ветки с
43
56
  разными входами пересоздают компонент и теряют его состояние.
44
- - **Компонент, который рисуется в перекрытии, из хоста вызывающего не адресуется.** Его
45
- разметка лежит вне хоста, и селектор от хоста до его кнопок не дотянется: такие кнопки носят
46
- собственные якоря в своём шаблоне.
47
- - **Готовое не пишется заново.** Своя разметка с ролью оповещения, таблицы, диалога, вкладок
48
- или подсказки означает, что мимо готового компонента прошли. Правило целиком — `reuse-first`.
57
+ - **Кит, который рисуется в оверлее, из хоста вызывающего не адресуется:** его разметка лежит
58
+ вне хоста, и `[qa-dataid="x"] button` до кнопок не дотянется. Такие кнопки носят собственные
59
+ якоря прямо в шаблоне кита, а гард каталог зависимостей не проверяет.
60
+ - **`qa-dataid` не заменяет `aria-label` и роли:** доступность отдельно, якорь отдельно. И не
61
+ снимается при правке вёрстки на него завязаны спеки.
62
+ - Готовое из кита не пишется заново: своя разметка с `role="alert"`, `<table>`,
63
+ `role="dialog"`, `role="tablist"` или `role="tooltip"` означает, что мимо `<префикс>-message`,
64
+ `<префикс>-table`, `<префикс>-dialog`, `<префикс>-tabs` или `<префикс>-tooltip` прошли. Правило целиком — `reuse-first`.
@@ -0,0 +1,66 @@
1
+ ---
2
+ name: dependencies
3
+ kind: rule
4
+ law: delivery
5
+ description: Правило под «Закон о поставке». Брать при правке package.json, pnpm-lock.yaml и pnpm-workspace.yaml и при обновлении любого пакета. Называет точный номер версии вместо диапазона, снимок дерева, подмену чужих версий, выдержку новой версии и границу переформатирования после обновления форматтера. Готовый порядок — в паттерне dependencies-upgrade.
6
+ ---
7
+
8
+ # Зависимости — как это устроено здесь
9
+
10
+ Правило под закон `docs/constitution/delivery.md`. Закон говорит, что должно быть верно;
11
+ здесь — чем это названо в этом дереве, где лежит и что из закона у нас не применяется. Ветка,
12
+ коммит и выкатка под тем же законом — правило `git-workflow`.
13
+
14
+ ## Как это называется здесь
15
+
16
+ | В законе | Здесь |
17
+ | ---------------------------- | -------------------------------------------------------------------------------------------------- |
18
+ | объявление зависимости | точный номер в `package.json` — `"prettier": "3.9.6"`; `^` и `~` в файле не встречаются ни разу |
19
+ | снимок установленного дерева | `pnpm-lock.yaml`; едет тем же коммитом, что и объявление |
20
+ | подмена чужой версии | `overrides` в `pnpm-workspace.yaml` — там лежат подменённые транзитивные зависимости |
21
+ | выдержка новой версии | `minimumReleaseAge`; пакет, нужный раньше срока, выписывается номером в `minimumReleaseAgeExclude` |
22
+ | менеджер пакетов | pnpm: `npm run` зовёт скрипты, установку делает `pnpm install` |
23
+
24
+ ## Где это лежит
25
+
26
+ В этом дереве — таблица в `implementation.md` рядом. Пути живут там, а не здесь: правило
27
+ переносится между репозиториями, раскладка — нет, и путь, названный в правиле, врёт в первом
28
+ же дереве, которое держит код иначе.
29
+
30
+ ## Как закон применяется здесь
31
+
32
+ - **Версия пакета записана точным номером.** Из диапазона сегодня и через неделю поставится
33
+ разное, и откат правки это не исправит.
34
+ - **Подменённые версии чужих зависимостей собраны в один список, и его пересматривают при
35
+ каждом обновлении.** Подмена, оставшаяся в списке после того, как основной пакет подняли,
36
+ незаметно откатывает его зависимость назад.
37
+ - **Свежая версия сначала выдерживается, а нужная раньше срока выписывается отдельно.** Иначе
38
+ выпуск, который автор успел отозвать, попадёт в снимок.
39
+ - **Переформатируется только то, чьё форматирование проверяет линтер.** Обновлённый форматтер
40
+ меняет все файлы, до которых дотянется, а `.md` и `.json` здесь не проверяет никто: правка в
41
+ них — просто шум, который придётся читать глазами.
42
+
43
+ ## Чего из закона здесь нет
44
+
45
+ Никто не сверяет, что объявленные версии совпадают со снимком: `--frozen-lockfile` стоит
46
+ только в выкатке, а она идёт от пуша в главную ветку, то есть уже после мержа. Диапазоны тоже
47
+ не проверяются: один `^` в `package.json` пройдёт все проверки дерева.
48
+
49
+ ## Паттерны
50
+
51
+ - `dependencies-upgrade` — подъём версий, выбор верхней границы, разбор последствий обновления.
52
+
53
+ ## Ловушки
54
+
55
+ - **Диапазон пропускает версию, которой в реестре нет.** В объявление кита записали `^0.2.0`,
56
+ а снимок остался на прежней версии: объявление выглядело верным, но всё собиралось на 0.1.0,
57
+ где нужного размера у компонента нет вовсе, и главная ветка перестала собираться. Нашли это
58
+ через две недели — когда понадобилось дерево для сравнения, а сравнивать оказалось не с чем.
59
+ - **Верхнюю границу задают peer-диапазоны, а не последний номер в реестре.** TypeScript
60
+ остался на 6.0.3 при вышедшей седьмой версии, потому что Angular объявляет `>=6.0 <6.1`.
61
+ `pnpm install` такую ошибку не ловит: `autoInstallPeers` молча доставляет недостающее.
62
+ - **После обновления плагина линтера появляются правила, которых вчера не было.** eslint 10
63
+ добавил `no-useless-assignment`, `eslint-plugin-playwright` 2 — сразу три правила. Замечания
64
+ приходят на файлы, которых правка не касалась, и выглядят её последствиями.
65
+ - Прогон тестов после обновления — правило `testing`: после смены версии Playwright браузер
66
+ надо поставить заново, и это не регрессия.