@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.
- package/README.md +194 -30
- 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 +329 -0
- package/assets/checks/check-board.github.mjs +181 -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 +1086 -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 +106 -0
- package/assets/defaults/project.sh +204 -0
- package/assets/hooks/browser-device-id.sh +0 -0
- package/assets/hooks/browser-guard-device-id.sh +2 -1
- package/assets/hooks/browser-guard-no-asking.sh +27 -0
- package/assets/hooks/browser-guard-no-listing.sh +2 -1
- package/assets/hooks/browser-guard-no-other-drivers.sh +2 -1
- package/assets/hooks/browser-guard-require-select.sh +2 -1
- package/assets/hooks/commit-msg.sh +1 -1
- package/assets/hooks/constitution-index.sh +5 -4
- package/assets/hooks/dev-server-guard.sh +8 -6
- package/assets/hooks/docs-guard.sh +223 -37
- package/assets/hooks/git-guard-delivery.sh +171 -31
- package/assets/hooks/git-guard-main.sh +1 -0
- package/assets/hooks/git-guard-push-tests.sh +34 -13
- package/assets/hooks/glossary-load.sh +23 -0
- package/assets/hooks/grill-gate.sh +96 -0
- package/assets/hooks/lint-after-edit.sh +155 -30
- package/assets/hooks/qa-dataid-guard.sh +72 -32
- package/assets/hooks/reuse-first-guard.sh +105 -34
- package/assets/hooks/skill-gate-rearm.sh +1 -0
- package/assets/hooks/skill-gate.sh +75 -15
- package/assets/hooks/skill-loaded.sh +1 -0
- package/assets/hooks/sql-guard.sh +606 -56
- package/assets/hooks/task-context-load.sh +100 -0
- package/assets/hooks/task-flow-guard.sh +118 -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 +27 -8
- package/assets/laws/reuse-first.md +26 -21
- package/assets/laws/shared-code.md +13 -1
- package/assets/laws/verifiability.md +30 -1
- package/assets/laws/work-conduct.md +59 -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 +29 -22
- package/assets/patterns/api-layer-pair.md +40 -30
- package/assets/patterns/browser-verification-measure.md +41 -38
- package/assets/patterns/browser-verification-stand.md +106 -42
- package/assets/patterns/component-structure-new.md +33 -32
- package/assets/patterns/dependencies-upgrade.md +65 -0
- package/assets/patterns/doc-style-sweep.md +65 -28
- package/assets/patterns/doc-style-write.md +36 -33
- 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 +337 -0
- package/assets/patterns/git-workflow-commit.gitlab.md +283 -0
- package/assets/patterns/git-workflow-merge.md +42 -25
- package/assets/patterns/git-workflow-migration.md +61 -31
- package/assets/patterns/git-workflow-restart.md +20 -20
- package/assets/patterns/lib-layers-move.md +50 -32
- package/assets/patterns/lib-layers-new.md +41 -29
- package/assets/patterns/ownership-scope-resolve.md +69 -0
- package/assets/patterns/permissions-procedure.md +35 -33
- package/assets/patterns/platform-access-di.md +39 -25
- package/assets/patterns/pricing-quote.md +71 -0
- package/assets/patterns/reuse-first-extend.md +22 -22
- package/assets/patterns/seo-page.md +52 -40
- package/assets/patterns/seo-verify.md +48 -29
- package/assets/patterns/shared-code-new.md +37 -31
- package/assets/patterns/spec-driven-domain.md +60 -37
- package/assets/patterns/spec-driven-rule.md +55 -40
- package/assets/patterns/styling-bem-component.md +43 -32
- package/assets/patterns/styling-bem-layout.md +30 -24
- package/assets/patterns/task-flow-close.md +154 -0
- package/assets/patterns/task-flow-resume.md +94 -0
- package/assets/patterns/task-flow-start.md +129 -0
- package/assets/patterns/testing-e2e.md +53 -51
- package/assets/patterns/testing-unit.md +70 -46
- package/assets/patterns/translations-key.md +32 -19
- package/assets/patterns/ts-procedure.md +24 -25
- package/assets/rules/angular-patterns.md +50 -27
- package/assets/rules/api-layer.md +46 -28
- package/assets/rules/browser-verification.md +67 -48
- package/assets/rules/component-structure.md +43 -27
- package/assets/rules/dependencies.md +66 -0
- package/assets/rules/doc-style.md +95 -39
- 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 +56 -30
- 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 +43 -25
- package/assets/rules/platform-access.md +57 -29
- package/assets/rules/pricing.md +64 -0
- package/assets/rules/reuse-first.md +57 -43
- package/assets/rules/seo.md +51 -30
- package/assets/rules/shared-code.md +51 -26
- package/assets/rules/spec-driven.md +107 -51
- package/assets/rules/styling-bem.md +54 -39
- package/assets/rules/task-flow.md +150 -0
- package/assets/rules/testing.md +78 -47
- package/assets/rules/translations.md +48 -31
- package/assets/rules/typescript-conventions.md +57 -27
- package/assets/skills/agent-kit.md +85 -0
- package/assets/skills/write-a-skill.md +108 -0
- package/assets/templates/gate-map.sh +23 -15
- package/assets/templates/implementation.md +14 -8
- package/assets/templates/pattern.md +1 -1
- package/assets/templates/project.sh +32 -19
- package/assets/templates/rule.md +2 -2
- 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 +8 -3
- package/lib/assets.d.ts.map +1 -1
- package/lib/assets.js +13 -3
- 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 +202 -14
- package/lib/commands.js.map +1 -1
- package/lib/companion.d.ts +5 -1
- package/lib/companion.d.ts.map +1 -1
- package/lib/companion.js +29 -2
- package/lib/companion.js.map +1 -1
- package/lib/config.d.ts +26 -9
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +41 -15
- 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 +27 -0
- package/lib/hooks-map.d.ts.map +1 -0
- package/lib/hooks-map.js +77 -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/sync.d.ts +26 -0
- package/lib/sync.d.ts.map +1 -1
- package/lib/sync.js +59 -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.5.0.tgz +0 -0
- package/assets/laws/admin-lists.md +0 -35
- package/assets/laws/admin-navigation.md +0 -38
- package/assets/patterns/git-workflow-commit.md +0 -175
- package/assets/rules/git-workflow.md +0 -106
- package/rt-tools-agent-kit-0.3.0.tgz +0 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Профиль дерева: чем здесь проверяется правка и что считается переизобретением.
|
|
3
|
+
#
|
|
4
|
+
# Умолчание пакета. Всё, что общего у деревьев этой мастерской, живёт здесь: запускатель Nx,
|
|
5
|
+
# линтер кода, линтер стилей, набор образцов переизобретения. Своё дерево дописывает
|
|
6
|
+
# надстройкой — `.claude/rt-kit/project.sh`: она грузится второй, объявляет ту же функцию
|
|
7
|
+
# заново и вправе позвать отсюда её же с суффиксом `_default`.
|
|
8
|
+
#
|
|
9
|
+
# Каждая функция вправе промолчать. Молчание значит «правила на это нет», и хук пропускает.
|
|
10
|
+
|
|
11
|
+
# Запускатель пакетов — по локфайлу, а не по договорённости: деревья с pnpm и с npm лежат в
|
|
12
|
+
# одной мастерской, и зашитый здесь `npm` в первом же из них печатал бы команду, которой нет.
|
|
13
|
+
rt_runner() {
|
|
14
|
+
root="${CLAUDE_PROJECT_DIR:-.}"
|
|
15
|
+
if [ -f "$root/pnpm-lock.yaml" ]; then
|
|
16
|
+
printf '%s' 'pnpm exec'
|
|
17
|
+
elif [ -f "$root/yarn.lock" ]; then
|
|
18
|
+
printf '%s' 'yarn'
|
|
19
|
+
else
|
|
20
|
+
printf '%s' 'npx'
|
|
21
|
+
fi
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
# Где подняты приложения. Идёт в текст отказа, когда кто-то поднимает второй экземпляр.
|
|
25
|
+
# Порты у каждого дерева свои, поэтому умолчание молчит: назвать чужой порт хуже, чем не назвать.
|
|
26
|
+
RT_STANDS="${RT_STANDS:-}"
|
|
27
|
+
|
|
28
|
+
# Команды, которые обязаны пройти перед пушем. По одной на строку; первая упавшая отбивает пуш.
|
|
29
|
+
# Линтер стилей отдельной строкой: линтер кода файлы стилей не читает вовсе.
|
|
30
|
+
#
|
|
31
|
+
# Первый параметр — база: ветка, относительно которой считается вклад. Пустая означает, что
|
|
32
|
+
# удалённого нет, и тогда гоняется всё: набор строже нужного безопасен, набор уже нужного — нет.
|
|
33
|
+
rt_push_checks_default() {
|
|
34
|
+
runner="$(rt_runner)"
|
|
35
|
+
if [ -n "$1" ]; then
|
|
36
|
+
printf '%s\n' "$runner nx affected -t lint test --base=$1"
|
|
37
|
+
else
|
|
38
|
+
printf '%s\n' "$runner nx run-many -t lint test --all"
|
|
39
|
+
fi
|
|
40
|
+
[ -f "${CLAUDE_PROJECT_DIR:-.}/stylelint.config.js" ] && printf '%s\n' "$runner stylelint \"**/*.scss\" --max-warnings 0"
|
|
41
|
+
|
|
42
|
+
return 0
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
# Какой документ обязан ехать тем же коммитом, что и этот файл. Печатает образец пути или молчит.
|
|
46
|
+
rt_docs_pair_for_default() {
|
|
47
|
+
case "$1" in
|
|
48
|
+
# Тест — не описание кода: он его проверяет.
|
|
49
|
+
*.spec.ts) return 0 ;;
|
|
50
|
+
# Контракт правится вместе со спеком домена: разошедшись, они врут оба.
|
|
51
|
+
*.proto) printf '%s' 'docs/specs/.*/spec\.md' ;;
|
|
52
|
+
# Правило и его спутник здесь не называются: их пару держит сам гард, и держит точнее —
|
|
53
|
+
# он сверяет раздел с утверждениями, а не факт правки файла.
|
|
54
|
+
# Хук и набор его сценариев: гард разбирает текст команд, и уточнение шаблона обычно
|
|
55
|
+
# смещает границу, а не сужает.
|
|
56
|
+
.claude/hooks/*.sh) printf '%s' '.claude/hooks/tests/.*' ;;
|
|
57
|
+
esac
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
# Чем линтуется этот файл сразу после правки. Печатает команду или молчит.
|
|
61
|
+
#
|
|
62
|
+
# Путь подставляется здесь, а не оставляется позиционным параметром: хук исполняет напечатанное
|
|
63
|
+
# вычислением строки, и `$1` в нём разрешился бы в параметр самого хука, то есть в пустоту.
|
|
64
|
+
rt_lint_for_default() {
|
|
65
|
+
runner="$(rt_runner)"
|
|
66
|
+
case "$1" in
|
|
67
|
+
*.scss) printf '%s stylelint --max-warnings 0 "%s"' "$runner" "$1" ;;
|
|
68
|
+
*.ts | *.html) printf '%s eslint "%s"' "$runner" "$1" ;;
|
|
69
|
+
esac
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
# Каталог папок задач. Пусто — ведения работы папкой в дереве нет, и гард замысла молчит.
|
|
73
|
+
RT_TASKS_DIR="${RT_TASKS_DIR:-docs/tasks}"
|
|
74
|
+
|
|
75
|
+
# Каталог записей о законченных работах. Туда переносят то, что объясняет решения закрытой
|
|
76
|
+
# задачи. Гард поставки требует, чтобы ветка, удалившая папку задачи, что-то сюда добавила:
|
|
77
|
+
# удалить проще, чем разобрать, а слова владельца больше нигде не записаны.
|
|
78
|
+
RT_ARCHIVE_DIR="${RT_ARCHIVE_DIR:-docs/archive}"
|
|
79
|
+
|
|
80
|
+
# Где лежат тексты, которые читают до вопроса владельцу: законы, правила и договорённости о
|
|
81
|
+
# продукте. По ним гард разговора судит, читалось ли за ход хоть что-то, и их же называет в
|
|
82
|
+
# подсказке. Пусто у законов и правил разом — дерево этого требования не получает: читать
|
|
83
|
+
# нечего.
|
|
84
|
+
RT_LAWS_DIR="${RT_LAWS_DIR:-docs/constitution}"
|
|
85
|
+
RT_RULES_DIR="${RT_RULES_DIR:-.claude/skills}"
|
|
86
|
+
RT_SPECS_DIR="${RT_SPECS_DIR:-docs/specs}"
|
|
87
|
+
|
|
88
|
+
# Главная ветка. Гарду она нужна, чтобы найти общего предка и понять, что ветка сделала с
|
|
89
|
+
# папкой задачи и с архивом. Если общего предка нет, сравнивать не с чем — проверка молчит.
|
|
90
|
+
RT_MAIN_BRANCH="${RT_MAIN_BRANCH:-main}"
|
|
91
|
+
|
|
92
|
+
# Тело PR по его номеру. Обход требования пишут в PR, а в команде слияния его нет — там только
|
|
93
|
+
# номер. Пустой ответ значит «спросить не у кого»: тогда обход ищется только в тексте команды.
|
|
94
|
+
rt_report_body_default() {
|
|
95
|
+
command -v gh >/dev/null 2>&1 || return 1
|
|
96
|
+
gh pr view "$1" --json body -q '.body' 2>/dev/null
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
# Код приложения ли это. Успех — да, и тогда правка требует замысла на диске.
|
|
100
|
+
#
|
|
101
|
+
# Признак — путь, а не оценка на глаз: оценку назначает тот, кому она мешает, и порог плывёт.
|
|
102
|
+
# Правила, тексты, обвязка и зависимости под требование не попадают — иначе разбор задачи
|
|
103
|
+
# нельзя было бы вести до заведения ветки.
|
|
104
|
+
rt_is_app_code_default() {
|
|
105
|
+
case "$1" in
|
|
106
|
+
*/apps/* | */libs/* | */projects/*) return 0 ;;
|
|
107
|
+
*) return 1 ;;
|
|
108
|
+
esac
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
# Имя ветки, с которой разрешено открывать заявку на слияние: в имени стоит номер задачи.
|
|
112
|
+
# Приставка — либо род правки, либо метка очереди работ: обе формы носят номер, а он и нужен.
|
|
113
|
+
#
|
|
114
|
+
# Хвост после номера — строчными и через дефис. Имя ветки читают глазами в списке и набирают
|
|
115
|
+
# руками, а регистр в нём различает две ветки, отличающиеся только им, — и та, что нужна, при
|
|
116
|
+
# переключении находится не с первого раза.
|
|
117
|
+
rt_task_branch_ok_default() {
|
|
118
|
+
printf '%s' "$1" \
|
|
119
|
+
| grep -qE '^([A-Z]+-)?[0-9]+-[a-z0-9][a-z0-9-]*$|^(feat|fix|refactor|docs|chore|style|perf|test|build|ci)/[0-9]+-[a-z0-9][a-z0-9-]*$'
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
# Адрес боевого хранилища: образец, по которому его узнают в командной строке — порт туннеля,
|
|
123
|
+
# хост, домен. Любая запись по нему отбивается совсем, и опт-аут не действует. Умолчание
|
|
124
|
+
# молчит: чужой адрес здесь опаснее неназванного — он отбивал бы работу с локальной базой.
|
|
125
|
+
RT_PROD_DSN="${RT_PROD_DSN:-}"
|
|
126
|
+
|
|
127
|
+
# Подключения среды разработки в лицо: по одному тексту запроса бой от локальной копии не
|
|
128
|
+
# отличить, база выбирается идентификатором подключения. Идентификаторы локальны для машины.
|
|
129
|
+
RT_PROD_CONNECTIONS="${RT_PROD_CONNECTIONS:-}"
|
|
130
|
+
RT_LOCAL_CONNECTIONS="${RT_LOCAL_CONNECTIONS:-}"
|
|
131
|
+
|
|
132
|
+
# Порты одноразовых баз: по ним вопрос не задаётся. Не назван — исключения нет вовсе.
|
|
133
|
+
RT_SCRATCH_PORT_RE="${RT_SCRATCH_PORT_RE:-}"
|
|
134
|
+
|
|
135
|
+
# Форма номера в заголовке заявки на слияние. Тот же номер стоит у задачи и у ветки.
|
|
136
|
+
RT_TASK_TITLE_RE="${RT_TASK_TITLE_RE:-^\[[A-Za-z]+-[0-9]+\][[:space:]]+[^[:space:]]}"
|
|
137
|
+
|
|
138
|
+
# Чем заводится задача и чем сверяется очередь работ. Идут в текст отказа гарда поставки:
|
|
139
|
+
# отказ без действия обходят, а не исполняют.
|
|
140
|
+
RT_TASK_NEW_CMD="${RT_TASK_NEW_CMD:-npm run task:new}"
|
|
141
|
+
RT_BOARD_CHECK_CMD="${RT_BOARD_CHECK_CMD:-npm run check:board}"
|
|
142
|
+
|
|
143
|
+
# Учётная запись, которую ставят исполнителем. Умолчание молчит: у каждого дерева она своя.
|
|
144
|
+
RT_TASK_BOT="${RT_TASK_BOT:-}"
|
|
145
|
+
|
|
146
|
+
# Состояние задачи одним объектом: exists, open, onBoard, assigned, numbered. Спрашивает
|
|
147
|
+
# помощника очереди работ — того же, которым пользуются сверка и команда заведения, чтобы
|
|
148
|
+
# гард и очередь одинаково понимали «задача в порядке». Нет узла, нет помощника, нет сети —
|
|
149
|
+
# молчание, и ярус состояния пропускается: проверять нечем.
|
|
150
|
+
rt_task_state_default() {
|
|
151
|
+
command -v node >/dev/null 2>&1 || return 1
|
|
152
|
+
[ -f "${RT_BOARD_HELPER:-tools/board.mjs}" ] || return 1
|
|
153
|
+
state="$(node "${RT_BOARD_HELPER:-tools/board.mjs}" task "$1" 2>/dev/null)" || return 1
|
|
154
|
+
[ -z "$state" ] && return 1
|
|
155
|
+
# Ответ с меткой «сети не было» состоянием не является: по нему нельзя отличить задачу,
|
|
156
|
+
# которой нет, от задачи, о которой не спросили.
|
|
157
|
+
printf '%s' "$state" | jq -e 'has("offline") | not' >/dev/null 2>&1 || return 1
|
|
158
|
+
printf '%s' "$state"
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
# Что в этом дереве считается переизобретением. По строке «образец<таб>чем заменить».
|
|
162
|
+
# Образцы узкие намеренно: гард сверяет только НОВЫЙ текст, и широкий образец отбивал бы
|
|
163
|
+
# правку, которая ничего нового не заводит.
|
|
164
|
+
rt_reinvented_in_default() {
|
|
165
|
+
case "$1" in
|
|
166
|
+
*.ts)
|
|
167
|
+
printf '%s\t%s\n' '@(Input|Output|ViewChild|ViewChildren|ContentChild)\(' 'input(), output(), viewChild(), contentChild() — реактивный вход и выход'
|
|
168
|
+
printf '%s\t%s\n' 'get [a-zA-Z]+\(\)[[:space:]]*(:|\{)' 'computed(): производное значение сигналом, а не геттером'
|
|
169
|
+
;;
|
|
170
|
+
*.html)
|
|
171
|
+
printf '%s\t%s\n' '\[ngClass\]|\[class\.' 'директивы класса кита'
|
|
172
|
+
;;
|
|
173
|
+
*.scss)
|
|
174
|
+
printf '%s\t%s\n' '#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?\b' 'токен оформления вместо записанного цвета'
|
|
175
|
+
;;
|
|
176
|
+
esac
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
# Где якорь для спек не требуется. Витрина, корневая разметка и сборка — общее у всех деревьев;
|
|
180
|
+
# своё дерево дописывает надстройкой.
|
|
181
|
+
RT_QA_SKIP_RE="${RT_QA_SKIP_RE:-/node_modules/|/dist/|\.stories\.html\$|/src/index\.html\$}"
|
|
182
|
+
|
|
183
|
+
# По какому имени тег опознаётся компонентом этого дерева. Умолчание — составной тег: имя с
|
|
184
|
+
# дефисом принадлежит компоненту, а не разметке, и это верно везде, где есть свои компоненты.
|
|
185
|
+
RT_QA_COMPONENT_RE="${RT_QA_COMPONENT_RE:--}"
|
|
186
|
+
|
|
187
|
+
# Теги, которые спека не нажимает: оформление, разметка страницы, индикаторы. Перечисляются
|
|
188
|
+
# именами через пробел. Умолчание молчит: у каждого кита свои, а чужое имя здесь глушило бы
|
|
189
|
+
# проверку на теге, которого в этом дереве нет.
|
|
190
|
+
rt_qa_decorative_default() {
|
|
191
|
+
return 0
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
# Умолчания под общими именами. Надстройка проекта объявит любое из них заново — и позовёт
|
|
195
|
+
# отсюда то же имя с суффиксом `_default` для всего, чего не назвала сама.
|
|
196
|
+
rt_push_checks() { rt_push_checks_default "$@"; }
|
|
197
|
+
rt_docs_pair_for() { rt_docs_pair_for_default "$@"; }
|
|
198
|
+
rt_lint_for() { rt_lint_for_default "$@"; }
|
|
199
|
+
rt_task_branch_ok() { rt_task_branch_ok_default "$@"; }
|
|
200
|
+
rt_reinvented_in() { rt_reinvented_in_default "$@"; }
|
|
201
|
+
rt_is_app_code() { rt_is_app_code_default "$@"; }
|
|
202
|
+
rt_qa_decorative() { rt_qa_decorative_default "$@"; }
|
|
203
|
+
rt_task_state() { rt_task_state_default "$@"; }
|
|
204
|
+
rt_report_body() { rt_report_body_default "$@"; }
|
|
File without changes
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
+
# rt-hook: PreToolUse mcp__claude-in-chrome__select_browser
|
|
2
3
|
# Гард выбора браузера. PreToolUse на выборе браузера расширением.
|
|
3
4
|
#
|
|
4
5
|
# Отклоняет любой профиль, кроме закреплённого: чужой стоит лишнего круга и приводит в браузер,
|
|
@@ -11,7 +12,7 @@
|
|
|
11
12
|
|
|
12
13
|
input="$(cat 2>/dev/null)"
|
|
13
14
|
|
|
14
|
-
device_id="$("${CLAUDE_PROJECT_DIR:-.}/
|
|
15
|
+
device_id="$("${CLAUDE_PROJECT_DIR:-.}/.claude/hooks/browser-device-id.sh" 2>/dev/null)"
|
|
15
16
|
[ -z "$device_id" ] && exit 0
|
|
16
17
|
|
|
17
18
|
requested="$(printf '%s' "$input" | jq -r '.tool_input.deviceId // empty' 2>/dev/null)"
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# rt-hook: PreToolUse AskUserQuestion
|
|
3
|
+
# PreToolUse guard for AskUserQuestion.
|
|
4
|
+
#
|
|
5
|
+
# The browser choice is already made and pinned in browser-device-id.sh — asking again is noise, and the
|
|
6
|
+
# answer could only ever be the pinned profile. Only questions actually about PICKING a browser
|
|
7
|
+
# are blocked; every other question passes untouched.
|
|
8
|
+
#
|
|
9
|
+
# A bare "browser"/"браузер" substring is too broad for a web-dev project: questions about
|
|
10
|
+
# client-side code, user agents, cross-browser bugs etc. legitimately use the word without
|
|
11
|
+
# being about which Chrome profile to automate. Anchor on selection phrasing instead
|
|
12
|
+
# (deviceId, "which/what browser", "какой браузер").
|
|
13
|
+
#
|
|
14
|
+
# FAIL-OPEN when browser-device-id.sh prints nothing.
|
|
15
|
+
|
|
16
|
+
input="$(cat 2>/dev/null)"
|
|
17
|
+
|
|
18
|
+
device_id="$("${CLAUDE_PROJECT_DIR:-.}/.claude/hooks/browser-device-id.sh" 2>/dev/null)"
|
|
19
|
+
[ -z "$device_id" ] && exit 0
|
|
20
|
+
|
|
21
|
+
questions="$(printf '%s' "$input" | jq -r '[.tool_input.questions[]? | .question, .header, (.options[]?.label)] | join(" ")' 2>/dev/null)"
|
|
22
|
+
[ -z "$questions" ] && exit 0
|
|
23
|
+
|
|
24
|
+
printf '%s' "$questions" | grep -qiE 'deviceid|device id|(which|what|pick|choose|select)[^.]{0,25}\bbrowser\b|\bbrowser\b[^.]{0,25}(profile|to use)|как(ой|ую)?[^.]{0,15}браузер|брауз[а-я]*[^.]{0,20}(использовать|выбрать|выбор|нужен|запустить)' || exit 0
|
|
25
|
+
|
|
26
|
+
echo "Do not ask which browser to use — the profile is pinned. Call select_browser with deviceId ${device_id} ('Main' profile)." >&2
|
|
27
|
+
exit 2
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
+
# rt-hook: PreToolUse mcp__claude-in-chrome__(list_connected_browsers|switch_browser)
|
|
2
3
|
# Гард перечисления и переключения браузеров. PreToolUse.
|
|
3
4
|
#
|
|
4
5
|
# Сессии проекта живут в одном закреплённом профиле. Перечисление и переключение отдают общие
|
|
@@ -10,7 +11,7 @@
|
|
|
10
11
|
|
|
11
12
|
cat >/dev/null 2>&1
|
|
12
13
|
|
|
13
|
-
device_id="$("${CLAUDE_PROJECT_DIR:-.}/
|
|
14
|
+
device_id="$("${CLAUDE_PROJECT_DIR:-.}/.claude/hooks/browser-device-id.sh" 2>/dev/null)"
|
|
14
15
|
[ -z "$device_id" ] && exit 0
|
|
15
16
|
|
|
16
17
|
echo "Не перечисляй и не переключай браузеры. Вызови выбор браузера с профилем ${device_id} — единственным, где сделан вход." >&2
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
+
# rt-hook: PreToolUse mcp__playwright__.*|mcp__chrome-devtools__.*|Bash
|
|
2
3
|
# Гард обходных путей к браузеру. PreToolUse.
|
|
3
4
|
#
|
|
4
5
|
# Закрепление профиля чего-то стоит только тогда, когда дверь одна. Здесь перечислены двери,
|
|
@@ -13,7 +14,7 @@
|
|
|
13
14
|
|
|
14
15
|
input="$(cat 2>/dev/null)"
|
|
15
16
|
|
|
16
|
-
device_id="$("${CLAUDE_PROJECT_DIR:-.}/
|
|
17
|
+
device_id="$("${CLAUDE_PROJECT_DIR:-.}/.claude/hooks/browser-device-id.sh" 2>/dev/null)"
|
|
17
18
|
[ -z "$device_id" ] && exit 0
|
|
18
19
|
|
|
19
20
|
tool="$(printf '%s' "$input" | jq -r '.tool_name // empty' 2>/dev/null)"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
+
# rt-hook: PreToolUse mcp__claude-in-chrome__.*
|
|
2
3
|
# Гард свежести выбора браузера. PreToolUse на всех остальных вызовах расширения.
|
|
3
4
|
#
|
|
4
5
|
# ЗАЧЕМ ОН ЕСТЬ — отказ, из которого он вырос: расширение действует на тот браузер, который
|
|
@@ -20,7 +21,7 @@
|
|
|
20
21
|
|
|
21
22
|
input="$(cat 2>/dev/null)"
|
|
22
23
|
|
|
23
|
-
device_id="$("${CLAUDE_PROJECT_DIR:-.}/
|
|
24
|
+
device_id="$("${CLAUDE_PROJECT_DIR:-.}/.claude/hooks/browser-device-id.sh" 2>/dev/null)"
|
|
24
25
|
[ -z "$device_id" ] && exit 0
|
|
25
26
|
|
|
26
27
|
tool="$(printf '%s' "$input" | jq -r '.tool_name // empty' 2>/dev/null)"
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# Версионируемый шаблон: рабочая копия хуков гита не версионируется, поэтому файл ставится в
|
|
5
5
|
# неё отдельно — скриптом подготовки при установке зависимостей. Переустановка руками, если
|
|
6
6
|
# подготовка почему-то не отработала:
|
|
7
|
-
# cp
|
|
7
|
+
# cp .claude/hooks/commit-msg.sh .git/hooks/commit-msg && chmod +x .git/hooks/commit-msg
|
|
8
8
|
#
|
|
9
9
|
# Намеренно НЕ через обёртку, подменяющую путь хуков: подмена уводит гит в свой каталог и рвёт
|
|
10
10
|
# остальные хуки, уже лежащие в рабочей копии. Родной путь оставляет их нетронутыми.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
+
# rt-hook: SessionStart startup|resume|compact|clear
|
|
2
3
|
# Вход в слой законов. SessionStart.
|
|
3
4
|
#
|
|
4
5
|
# Файл закона сам по себе не приносит в контекст ничего — его читают, только когда за ним
|
|
@@ -11,7 +12,7 @@
|
|
|
11
12
|
# ОТКАЗ В ПОЛЬЗУ РАБОТЫ: любая ошибка начинает сессию без добавленного контекста (exit 0).
|
|
12
13
|
# Сломанный вход не имеет права остановить сессию.
|
|
13
14
|
|
|
14
|
-
dir="${CLAUDE_PROJECT_DIR:-.}/
|
|
15
|
+
dir="${CLAUDE_PROJECT_DIR:-.}/docs/constitution"
|
|
15
16
|
[ -d "$dir" ] || exit 0
|
|
16
17
|
|
|
17
18
|
index=""
|
|
@@ -19,15 +20,15 @@ for law in "$dir"/*.md; do
|
|
|
19
20
|
[ -f "$law" ] || continue
|
|
20
21
|
title="$(grep -m1 '^# ' "$law" 2>/dev/null | sed 's/^# //')"
|
|
21
22
|
[ -z "$title" ] && continue
|
|
22
|
-
index="${index}
|
|
23
|
+
index="${index} docs/constitution/$(basename "$law") — ${title}"$'\n'
|
|
23
24
|
done
|
|
24
25
|
[ -z "$index" ] && exit 0
|
|
25
26
|
|
|
26
27
|
read -r -d '' context <<EOF
|
|
27
|
-
ЗАКОНЫ ПРОЕКТА (слой @rt-tools/agent-kit, разложен в
|
|
28
|
+
ЗАКОНЫ ПРОЕКТА (слой @rt-tools/agent-kit, разложен в docs/constitution/).
|
|
28
29
|
|
|
29
30
|
Закон говорит, ЧТО должно быть верно, и не знает ни путей, ни имён файлов. Правило — каким
|
|
30
|
-
приёмом это делается — живёт в
|
|
31
|
+
приёмом это делается — живёт в .claude/skills/, а имена этого дерева при нём — в
|
|
31
32
|
implementation.md рядом. Закон не отменяет правила и не заменяется им: перед решением, которое
|
|
32
33
|
закон задевает, читается закон целиком, правило — как обычно.
|
|
33
34
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
+
# rt-hook: PreToolUse Bash|mcp__webstorm__execute_terminal_command|mcp__webstorm__execute_run_configuration|mcp__webstorm__execute_tool
|
|
2
3
|
# Гард второго сервера разработки. PreToolUse.
|
|
3
4
|
#
|
|
4
5
|
# Приложения уже подняты владельцем, и всякая проверка через браузер идёт туда. Второй
|
|
@@ -9,7 +10,7 @@
|
|
|
9
10
|
# Отбивается всё, что ПОДНИМАЕТ сервер. Сборка, тесты, линтеры, запросы к поднятым портам и
|
|
10
11
|
# осмотр слушателей проходят.
|
|
11
12
|
#
|
|
12
|
-
# Где именно подняты приложения, знает профиль проекта:
|
|
13
|
+
# Где именно подняты приложения, знает профиль проекта: .claude/rt-kit/project.sh, переменная
|
|
13
14
|
# RT_STANDS. Нет профиля — текст отказа остаётся общим, сам гард работает.
|
|
14
15
|
|
|
15
16
|
input="$(cat 2>/dev/null)"
|
|
@@ -66,12 +67,13 @@ case "$cmd" in
|
|
|
66
67
|
printf '%s' "$cmd" | grep -qE '(^|[[:space:]])git[[:space:]]+daemon([[:space:]]|$)' || exit 0 ;;
|
|
67
68
|
esac
|
|
68
69
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
# Профиль дерева: сперва умолчание пакета, поверх него — надстройка проекта, если она есть.
|
|
71
|
+
rt_hooks_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
72
|
+
for profile in "$rt_hooks_dir/../rt-kit/defaults/project.sh" "$rt_hooks_dir/../defaults/project.sh" "${CLAUDE_PROJECT_DIR:-.}/.claude/rt-kit/defaults/project.sh" "${CLAUDE_PROJECT_DIR:-.}/.claude/rt-kit/project.sh"; do
|
|
72
73
|
# shellcheck disable=SC1090
|
|
73
|
-
. "$profile" 2>/dev/null
|
|
74
|
-
|
|
74
|
+
[ -f "$profile" ] && . "$profile" 2>/dev/null
|
|
75
|
+
done
|
|
76
|
+
stands="${RT_STANDS:-}"
|
|
75
77
|
|
|
76
78
|
deny() {
|
|
77
79
|
if [ -n "$stands" ]; then
|