@nitra/cursor 5.3.4 → 6.0.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/.claude-template/settings.template.json +2 -2
- package/.pi-template/extensions/n-cursor-adr/docs/index.md +13 -24
- package/CHANGELOG.md +21 -0
- package/bin/n-cursor.js +47 -24
- package/lib/docs/models.md +29 -18
- package/lib/docs/omlx-trace.md +51 -0
- package/lib/docs/omlx.md +31 -15
- package/lib/omlx.mjs +2 -5
- package/package.json +1 -1
- package/rules/abie/docs/fix.md +17 -11
- package/rules/adr/docs/fix.md +25 -140
- package/rules/bun/docs/fix.md +18 -151
- package/rules/capacitor/docs/fix.md +16 -13
- package/rules/capacitor/js/docs/platforms.md +31 -43
- package/rules/changelog/docs/fix.md +25 -169
- package/rules/ci4/docs/fix.md +11 -14
- package/rules/doc-files/doc-files.mdc +60 -0
- package/rules/doc-files/docs/fix.md +31 -0
- package/rules/doc-files/fix.mjs +19 -0
- package/{skills → rules}/doc-files/js/docgen-extract.mjs +42 -19
- package/{skills → rules}/doc-files/js/docgen-files-batch.mjs +18 -5
- package/{skills → rules}/doc-files/js/docgen-gen.mjs +46 -5
- package/{skills → rules}/doc-files/js/docgen-ignore.mjs +2 -1
- package/{skills → rules}/doc-files/js/docgen-scan.mjs +11 -3
- package/{skills → rules}/doc-files/js/docs/docgen-crc.md +1 -1
- package/{skills → rules}/doc-files/js/docs/docgen-extract-anchors.md +1 -1
- package/{skills → rules}/doc-files/js/docs/docgen-extract.md +2 -2
- package/{skills → rules}/doc-files/js/docs/docgen-files-batch.md +2 -2
- package/{skills → rules}/doc-files/js/docs/docgen-gen.md +2 -2
- package/{skills → rules}/doc-files/js/docs/docgen-ignore.md +4 -4
- package/rules/doc-files/js/docs/docgen-prompts.md +39 -0
- package/rules/doc-files/js/docs/docgen-scan.md +54 -0
- package/rules/doc-files/js/docs/lint.md +36 -0
- package/rules/doc-files/js/docs/units-js.md +31 -0
- package/rules/doc-files/js/docs/units-rs.md +35 -0
- package/rules/doc-files/js/docs/units.md +30 -0
- package/rules/doc-files/js/lint.mjs +96 -0
- package/{skills → rules}/doc-files/js/units-rs.mjs +37 -17
- package/rules/doc-files/lint/docs/lint.md +37 -0
- package/rules/doc-files/lint/lint.mjs +105 -0
- package/rules/doc-files/meta.json +1 -0
- package/rules/docker/docs/fix.md +21 -161
- package/rules/efes/docs/fix.md +23 -194
- package/rules/feedback/docs/fix.md +10 -8
- package/rules/ga/docs/fix.md +10 -5
- package/rules/ga/meta.json +1 -1
- package/rules/graphql/docs/fix.md +23 -119
- package/rules/hasura/docs/fix.md +19 -5
- package/rules/hasura/js/docs/internal_urls.md +34 -307
- package/rules/image-avif/docs/fix.md +16 -127
- package/rules/image-compress/docs/fix.md +20 -141
- package/rules/image-compress/js/docs/package_setup.md +22 -182
- package/rules/js-bun-db/docs/fix.md +23 -139
- package/rules/js-bun-db/js/docs/safety.md +33 -221
- package/rules/js-bun-redis/docs/fix.md +25 -114
- package/rules/js-bun-redis/js/docs/imports.md +18 -166
- package/rules/js-lint/docs/fix.md +30 -108
- package/rules/js-lint/js/docs/lint-findings.md +37 -17
- package/rules/js-lint/js/docs/lint.md +22 -238
- package/rules/js-lint/js/docs/tooling.md +34 -331
- package/rules/js-lint/js/lint.mjs +19 -12
- package/rules/js-lint/js-lint.mdc +1 -1
- package/rules/js-lint/meta.json +1 -1
- package/rules/js-lint-ci/docs/fix.md +16 -149
- package/rules/js-lint-ci/js/docs/lint.md +16 -136
- package/rules/js-lint-ci/js-lint-ci.mdc +1 -1
- package/rules/js-lint-ci/meta.json +1 -1
- package/rules/js-mssql/docs/fix.md +18 -123
- package/rules/js-mssql/js/docs/deps.md +28 -251
- package/rules/js-run/docs/fix.md +23 -138
- package/rules/js-run/js/docs/runtime.md +24 -378
- package/rules/k8s/docs/fix.md +18 -123
- package/rules/nginx-default-tpl/docs/fix.md +22 -118
- package/rules/nginx-default-tpl/js/docs/template.md +38 -360
- package/rules/npm-module/docs/fix.md +27 -89
- package/rules/npm-module/js/docs/header_doc_pointer.md +15 -15
- package/rules/npm-module/js/docs/package_structure.md +36 -258
- package/rules/npm-module/js/docs/rule_meta.md +25 -127
- package/rules/npm-module/js/docs/skill_meta.md +18 -180
- package/rules/npm-module/js/rule_meta.mjs +3 -3
- package/rules/php/docs/fix.md +21 -98
- package/rules/php/js/docs/tooling.md +20 -143
- package/rules/python/docs/fix.md +25 -157
- package/rules/python/js/docs/applies.md +20 -98
- package/rules/python/js/docs/tooling.md +27 -144
- package/rules/rego/docs/fix.md +24 -112
- package/rules/rego/js/docs/applies.md +20 -164
- package/rules/rego/js/docs/lint.md +15 -110
- package/rules/rego/meta.json +1 -1
- package/rules/release/docs/fix.md +16 -114
- package/rules/rust/docs/fix.md +24 -119
- package/rules/rust/js/docs/applies.md +20 -129
- package/rules/security/docs/fix.md +21 -78
- package/rules/security/js/docs/sample_secret.md +23 -182
- package/rules/security/js/docs/trufflehog.md +19 -128
- package/rules/security/meta.json +1 -1
- package/rules/style-lint/docs/fix.md +16 -150
- package/rules/style-lint/js/docs/lint.md +21 -172
- package/rules/style-lint/js/docs/tooling.md +19 -184
- package/rules/style-lint/js/lint.mjs +4 -3
- package/rules/style-lint/meta.json +1 -1
- package/rules/tauri/docs/fix.md +26 -152
- package/rules/tauri/js/docs/cargo_mutants_config.md +21 -159
- package/rules/tauri/js/docs/tooling.md +20 -217
- package/rules/test/docs/fix.md +19 -127
- package/rules/test/js/data/stryker_config/docs/stryker.config.baseline.md +15 -127
- package/rules/test/js/data/stryker_config/docs/stryker.config.vue.baseline.md +17 -153
- package/rules/test/js/docs/cargo_mutants_config.md +24 -164
- package/rules/test/js/docs/location.md +24 -126
- package/rules/test/js/docs/no-process-chdir.md +20 -151
- package/rules/test/js/docs/no-relative-fs-path.md +24 -261
- package/rules/test/js/docs/stryker_config.md +48 -148
- package/rules/test/js/docs/vitest-config-pool-forks.md +21 -164
- package/rules/text/docs/fix.md +25 -113
- package/rules/text/js/docs/forbidden-prettier.md +21 -132
- package/rules/text/js/docs/formatting.md +60 -251
- package/rules/text/js/docs/lint.md +17 -114
- package/rules/text/js/lint.mjs +5 -3
- package/rules/text/lint/docs/lint.md +1 -1
- package/rules/text/lint/docs/run-dotenv-linter.md +1 -1
- package/rules/text/lint/docs/run-shellcheck.md +1 -1
- package/rules/text/lint/lint.mjs +13 -9
- package/rules/text/lint/run-dotenv-linter.mjs +13 -10
- package/rules/text/lint/run-shellcheck.mjs +10 -6
- package/rules/text/meta.json +1 -1
- package/rules/vue/docs/fix.md +25 -118
- package/rules/vue/js/docs/packages.md +25 -323
- package/rules/worktree/docs/fix.md +31 -150
- package/scripts/coverage-classify/docs/index.md +23 -209
- package/scripts/coverage-classify/docs/verdict-schema.md +14 -159
- package/scripts/dispatcher/docs/trace.md +35 -0
- package/scripts/docs/auto-rules.md +37 -361
- package/scripts/docs/lint-cli.md +12 -13
- package/scripts/docs/post-tool-use-fix.md +16 -15
- package/scripts/docs/skills-cli.md +26 -23
- package/scripts/docs/sync-claude-config.md +94 -34
- package/scripts/docs/worktree-cli.md +11 -34
- package/scripts/lib/docs/assert-project-root.md +14 -16
- package/scripts/lib/docs/changed-files.md +24 -139
- package/scripts/lib/docs/discover-check-rules-from-cursor.md +14 -146
- package/scripts/lib/docs/rule-meta.md +1 -1
- package/scripts/lib/docs/rule-predicates.md +20 -17
- package/scripts/lib/docs/run-rule-cli.md +14 -18
- package/scripts/lib/docs/run-rule.md +13 -20
- package/scripts/lib/docs/run-standard-rule.md +12 -15
- package/scripts/lib/docs/sync-gitignore-worktree.md +15 -18
- package/scripts/lib/rule-meta.mjs +10 -6
- package/scripts/lib/rule-predicates.mjs +1 -1
- package/scripts/lint-cli.mjs +28 -20
- package/scripts/sync-claude-config.mjs +4 -1
- package/scripts/utils/docs/with-lock.md +19 -12
- package/scripts/utils/with-lock.mjs +4 -2
- package/skills/doc-aggregate/SKILL.md +2 -2
- package/skills/doc-aggregate/js/docgen-ignore.mjs +6 -6
- package/skills/doc-aggregate/js/docs/docgen-ignore.md +1 -1
- package/skills/doc-aggregate/js/docs/docgen-scan.md +78 -0
- package/skills/doc-files/.changes/260612-0031.md +5 -0
- package/skills/doc-files/.changes/260612-0036.md +5 -0
- package/skills/doc-files/.changes/260612-0114.md +5 -0
- package/skills/doc-files/SKILL.md +6 -6
- package/skills/fix/js/docs/llm-worker.md +17 -15
- package/skills/fix/js/docs/orchestrator.md +30 -23
- package/skills/fix/js/docs/t0.md +26 -16
- package/skills/start-check/js/docs/check.md +26 -22
- package/skills/taze/js/docs/diff.md +44 -20
- package/skills/doc-files/js/docs/docgen-prompts.md +0 -32
- package/skills/doc-files/js/docs/docgen-scan.md +0 -25
- package/skills/doc-files/js/docs/units-rs.md +0 -35
- /package/{skills → rules}/doc-files/js/docgen-crc.mjs +0 -0
- /package/{skills → rules}/doc-files/js/docgen-extract-anchors.mjs +0 -0
- /package/{skills → rules}/doc-files/js/docgen-prompts.mjs +0 -0
- /package/{skills → rules}/doc-files/js/units-js.mjs +0 -0
- /package/{skills → rules}/doc-files/js/units.mjs +0 -0
|
@@ -1,163 +1,31 @@
|
|
|
1
1
|
---
|
|
2
2
|
docgen:
|
|
3
3
|
source: npm/scripts/lib/discover-check-rules-from-cursor.mjs
|
|
4
|
-
crc:
|
|
4
|
+
crc: 9a6916e1
|
|
5
|
+
score: 100
|
|
5
6
|
---
|
|
6
7
|
|
|
7
8
|
# discover-check-rules-from-cursor.mjs
|
|
8
9
|
|
|
9
10
|
## Огляд
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
Файл зчитує базові імена файлів `.mdc` у директорії `.cursor/rules/` та генерує список ідентифікаторів правил для `npx @nitra/cursor fix`, використовуючи перевірку через JS-концерн або policy з `target.json`.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
2. **Реєстр пакета** — список id правил, для яких у пакеті `@nitra/cursor` існує programmatic перевірка (JS-концерн або policy з `target.json`); цей список зазвичай приходить із функції `discoverCheckableRules`.
|
|
14
|
+
## Поведінка
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
MANAGED_RULE_FILE_PREFIX Визначає префікс керованих правил пакета у файлах `.cursor/rules/`.
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
- залишаються лише ті id, для яких у пакеті є реальна перевірка;
|
|
20
|
-
- видалено префікс `n-`, оскільки внутрішня команда `check <id>` оперує «короткими» id (наприклад, `bun`, а не `n-bun`).
|
|
18
|
+
mdcBasenameToCheckId Перетворює базове ім'я `.mdc` у id правила для `check <id>`.
|
|
21
19
|
|
|
22
|
-
|
|
20
|
+
discoverCheckRulesFromCursorRules Будує впорядкований список id перевірок за файлами правил на диску, фільтруючи їх за наявністю у доступних перевірок.
|
|
23
21
|
|
|
24
|
-
##
|
|
22
|
+
## Публічний API
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
MANAGED_RULE_FILE_PREFIX — визначає префікс для керованих правил у директорії `.cursor/rules/`.
|
|
25
|
+
mdcBasenameToCheckId — трансформує базове ім'я файлу `.mdc` у ідентифікатор правила для функції `check`.
|
|
26
|
+
discoverCheckRulesFromCursorRules — створює відсортований список ідентифікаторів перевірок на основі файлів правил з курсору.
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
| ----------------------------------- | ---------- | ------------------------------------------------------------------------------------------------ |
|
|
30
|
-
| `MANAGED_RULE_FILE_PREFIX` | `string` | Константа `'n-'` — префікс імен файлів `.mdc`, які вважаються «керованими» пакетом. |
|
|
31
|
-
| `mdcBasenameToCheckId` | `function` | Перетворює базове ім'я `*.mdc` (із розширенням або без) у id для CLI-команди `check`. |
|
|
32
|
-
| `discoverCheckRulesFromCursorRules` | `function` | Будує впорядкований список id перевірок як перетин «доступних у пакеті» та «присутніх на диску». |
|
|
28
|
+
## Гарантії поведінки
|
|
33
29
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
## Функції
|
|
37
|
-
|
|
38
|
-
### `mdcBasenameToCheckId(mdcBasename)`
|
|
39
|
-
|
|
40
|
-
**Сигнатура:**
|
|
41
|
-
|
|
42
|
-
```js
|
|
43
|
-
export function mdcBasenameToCheckId(mdcBasename: string): string
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
**Параметри:**
|
|
47
|
-
|
|
48
|
-
- `mdcBasename` — рядок, який може бути:
|
|
49
|
-
- чистим базовим іменем файлу, наприклад `'n-bun.mdc'` або `'my-rule.mdc'`;
|
|
50
|
-
- відносним/абсолютним шляхом, наприклад `'.cursor/rules/n-bun.mdc'` (функція сама візьме сегмент після останнього `/`).
|
|
51
|
-
|
|
52
|
-
**Поведінка:**
|
|
53
|
-
|
|
54
|
-
1. Якщо у вхідному рядку є символ `/`, береться підрядок після останнього `/` — таким чином приймаються як «чисті» імена, так і шляхи.
|
|
55
|
-
2. Якщо отриманий рядок закінчується на `.mdc`, розширення відсікається.
|
|
56
|
-
3. Якщо те, що залишилось, починається з `MANAGED_RULE_FILE_PREFIX` (`'n-'`), цей префікс також знімається.
|
|
57
|
-
4. Повертається отриманий «короткий» id.
|
|
58
|
-
|
|
59
|
-
**Повертає:**
|
|
60
|
-
|
|
61
|
-
- `string` — id, придатний для команди `check <id>`. Приклади:
|
|
62
|
-
- `'n-bun.mdc'` → `'bun'`
|
|
63
|
-
- `'.cursor/rules/n-vue.mdc'` → `'vue'`
|
|
64
|
-
- `'my-rule.mdc'` → `'my-rule'`
|
|
65
|
-
- `'n-text'` (без розширення) → `'text'`
|
|
66
|
-
|
|
67
|
-
**Side effects:** немає. Функція суто детермінована, не звертається до файлової системи, не мутує аргументи.
|
|
68
|
-
|
|
69
|
-
**Крайні випадки:**
|
|
70
|
-
|
|
71
|
-
- Backslashes (`\\`) як роздільник шляху **не** розпізнаються — функція оперує лише `/`. Це безпечно для шляхів, які прийшли від утиліт на кшталт `fs.readdir`, що повертають базові імена, або з `path.posix`-стилю.
|
|
72
|
-
- Якщо вхід уже без `.mdc`, він обробляється тим самим алгоритмом (просто пропускається крок зняття розширення).
|
|
73
|
-
- Якщо файл, прибравши `.mdc`, дорівнює саме `'n-'`, повернеться порожній рядок — це не очікувана реальна ситуація, бо керованих правил із порожнім id не буває.
|
|
74
|
-
|
|
75
|
-
### `discoverCheckRulesFromCursorRules(available, mdcBasenames)`
|
|
76
|
-
|
|
77
|
-
**Сигнатура:**
|
|
78
|
-
|
|
79
|
-
```js
|
|
80
|
-
export function discoverCheckRulesFromCursorRules(
|
|
81
|
-
available: string[],
|
|
82
|
-
mdcBasenames: string[],
|
|
83
|
-
): string[]
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
**Параметри:**
|
|
87
|
-
|
|
88
|
-
- `available` — масив id, які пакет уміє перевіряти (програмні перевірки JS-концерну або policy з `target.json`). Зазвичай — результат `discoverCheckableRules` із сусіднього модуля `discover-checkable-rules.mjs`. Очікується алфавітний порядок, але алгоритм не залежить від нього.
|
|
89
|
-
- `mdcBasenames` — масив базових імен файлів `*.mdc`, які реально присутні у `.cursor/rules/` поточного проєкту. Очікується, що масив уже відсортований викликачем (порядок цього масиву визначає порядок результату).
|
|
90
|
-
|
|
91
|
-
**Поведінка:**
|
|
92
|
-
|
|
93
|
-
1. Створюється `Set` `seen` для дедуплікації результату.
|
|
94
|
-
2. Створюється масив `ordered` для збереження порядку входу `mdcBasenames`.
|
|
95
|
-
3. Для кожного `basename`:
|
|
96
|
-
- обчислюється id через `mdcBasenameToCheckId(basename)`;
|
|
97
|
-
- якщо id присутній у `available` **і** ще не доданий — додається в `ordered` та позначається у `seen`.
|
|
98
|
-
4. Повертається `ordered`.
|
|
99
|
-
|
|
100
|
-
**Повертає:**
|
|
101
|
-
|
|
102
|
-
- `string[]` — впорядкований масив унікальних id перевірок:
|
|
103
|
-
- **тільки** ті, що одночасно (а) мають programmatic-перевірку в пакеті і (б) представлені файлом `*.mdc` у `.cursor/rules/`;
|
|
104
|
-
- порядок диктується `mdcBasenames` (тобто реальним порядком файлів у директорії, як його передав викликач);
|
|
105
|
-
- кожен id зустрічається не більше одного разу.
|
|
106
|
-
|
|
107
|
-
**Side effects:** немає. Функція pure, не читає диск, не мутує аргументи (`Set`/`Array` створюються локально).
|
|
108
|
-
|
|
109
|
-
**Крайні випадки:**
|
|
110
|
-
|
|
111
|
-
- Якщо `mdcBasenames` порожній — повертається `[]`.
|
|
112
|
-
- Якщо жоден `id`, отриманий з імен `.mdc`, не присутній у `available` — повертається `[]` (типово для проєктів, де `.cursor/rules/` містить лише сторонні правила без programmatic-перевірок у пакеті).
|
|
113
|
-
- Дублікати у `mdcBasenames` (наприклад, два файли, що дають один і той самий id після відсікання префікса) включаються лише один раз.
|
|
114
|
-
|
|
115
|
-
## Залежності
|
|
116
|
-
|
|
117
|
-
- **Зовнішні (npm/Node):** немає. Файл не використовує жодних імпортів — ні з Node core (`fs`, `path` тощо), ні з npm-пакетів.
|
|
118
|
-
- **Внутрішні (проєкт):** немає прямих імпортів. Очікується, що:
|
|
119
|
-
- аргумент `available` формується сусіднім модулем `discover-checkable-rules.mjs` (експорт `discoverCheckableRules`);
|
|
120
|
-
- аргумент `mdcBasenames` формується викликачем читанням `.cursor/rules/` (через `fs.readdirSync`/`fs.promises.readdir` із подальшим фільтром `.endsWith('.mdc')` та сортуванням).
|
|
121
|
-
|
|
122
|
-
Така архітектура свідомо відокремлює I/O від чистої логіки: цей модуль легко тестувати без файлової системи.
|
|
123
|
-
|
|
124
|
-
## Потік виконання / Використання
|
|
125
|
-
|
|
126
|
-
Типовий сценарій — `npx @nitra/cursor fix` без аргументів. CLI-входу потрібно вирішити, які id перевірок запустити за замовчуванням; для цього він:
|
|
127
|
-
|
|
128
|
-
1. Отримує список програмно перевірюваних правил пакета (`available = discoverCheckableRules(...)`).
|
|
129
|
-
2. Читає директорію `.cursor/rules/` поточного проєкту й відбирає файли з розширенням `.mdc` (`mdcBasenames`), сортує їх.
|
|
130
|
-
3. Викликає `discoverCheckRulesFromCursorRules(available, mdcBasenames)` і отримує **підсумковий** список id.
|
|
131
|
-
4. Для кожного id послідовно запускає команду `check <id>` (наприклад, через `run-rule-cli.mjs`).
|
|
132
|
-
|
|
133
|
-
Приклад інлайн-використання (псевдокод викликача):
|
|
134
|
-
|
|
135
|
-
```js
|
|
136
|
-
import { readdirSync } from 'node:fs'
|
|
137
|
-
import { discoverCheckableRules } from './discover-checkable-rules.mjs'
|
|
138
|
-
import { discoverCheckRulesFromCursorRules } from './discover-check-rules-from-cursor.mjs'
|
|
139
|
-
|
|
140
|
-
const available = discoverCheckableRules(/* … */)
|
|
141
|
-
const mdcBasenames = readdirSync('.cursor/rules')
|
|
142
|
-
.filter(f => f.endsWith('.mdc'))
|
|
143
|
-
.sort()
|
|
144
|
-
const idsToRun = discoverCheckRulesFromCursorRules(available, mdcBasenames)
|
|
145
|
-
// idsToRun: наприклад, ['adr', 'bun', 'ci4', 'text', 'vue']
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
Приклад трансформації імен:
|
|
149
|
-
|
|
150
|
-
| Файл у `.cursor/rules/` | id після `mdcBasenameToCheckId` | Потрапляє у результат? |
|
|
151
|
-
| -------------------------- | ------------------------------- | -------------------------------------------------- |
|
|
152
|
-
| `n-bun.mdc` | `bun` | Так, якщо `available.includes('bun')` |
|
|
153
|
-
| `n-vue.mdc` | `vue` | Так, якщо `available.includes('vue')` |
|
|
154
|
-
| `my-rule.mdc` | `my-rule` | Лише якщо пакет реєструє `my-rule` як перевірюване |
|
|
155
|
-
| `.cursor/rules/n-text.mdc` | `text` | Так, якщо `available.includes('text')` |
|
|
156
|
-
| `n-bun.mdc` (двічі) | `bun` | У результаті — один раз |
|
|
157
|
-
|
|
158
|
-
Таким чином модуль є тонким, але критичним «клейовим» шаром між:
|
|
159
|
-
|
|
160
|
-
- **диском проєкту** (що користувач реально хоче перевіряти, судячи з вмісту `.cursor/rules/`)
|
|
161
|
-
- **реєстром пакета** (що пакет фізично вміє перевіряти автоматично).
|
|
162
|
-
|
|
163
|
-
Файл свідомо тримається без I/O і без зовнішніх залежностей, щоб залишатись повністю детермінованим і легко покритим юніт-тестами (див. сусідню директорію `tests/`).
|
|
30
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
31
|
+
- Не звертається до мережі.
|
|
@@ -1,30 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/scripts/lib/rule-predicates.mjs
|
|
4
|
+
crc: 71fba574
|
|
5
|
+
score: 95
|
|
6
|
+
---
|
|
7
|
+
|
|
1
8
|
# rule-predicates.mjs
|
|
2
9
|
|
|
3
10
|
## Огляд
|
|
4
11
|
|
|
5
|
-
|
|
12
|
+
Реєстр незводимих до даних предикатів для автодетекту правил. Предикати використовують наявність файлів або вмісту для визначення умов. Умови, що вимагають парсингу залежностей чи сканування вмісту, читають дані з різних джерел. Виклик диспетчується через `auto-rules.mjs` за іменем предиката.
|
|
6
13
|
|
|
7
14
|
## Поведінка
|
|
8
15
|
|
|
9
|
-
1.
|
|
10
|
-
2.
|
|
11
|
-
3.
|
|
12
|
-
4.
|
|
13
|
-
5.
|
|
14
|
-
6.
|
|
15
|
-
7. **Перевірка вкладеного `package.json` без `vite`:** Отримує кореневий `package.json`. Перебирає всі вкладені `package.json` (крім кореневого). Якщо вкладений `package.json` не містить `vite` у `devDependencies`, повер
|
|
16
|
+
1. repoUrlMarker: Перевіряє, чи містить URL репозиторію вказаний маркер.
|
|
17
|
+
2. depInAnyPackageJson: Перевіряє наявність пакетів у залежностях.
|
|
18
|
+
3. gqlTaggedTemplate: Перевіряє наявність літерала gql.
|
|
19
|
+
4. hasuraConfigMarker: Перевіряє наявність маркера в конфігурації.yaml.
|
|
20
|
+
5. jsBunDbSignal: Перевіряє наявність залежностей або імпорту SQL з Bun.
|
|
21
|
+
6. nestedPackageWithoutVite: Перевіряє наявність пропущеного пакету у devDependencies.
|
|
16
22
|
|
|
17
23
|
## Публічний API
|
|
18
24
|
|
|
19
|
-
RULE_PREDICATES —
|
|
25
|
+
RULE_PREDICATES — Реєстр предикатів: імʼя → реалізація. Виклик за `meta.json.auto.predicate`.
|
|
20
26
|
|
|
21
27
|
## Гарантії поведінки
|
|
22
28
|
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
- Не
|
|
28
|
-
- Не генерує винятків.
|
|
29
|
-
- Аргументи предиката можуть бути значеннями, отриманими з файлів `meta.json`, шляхів у файловій системі або URL-адрес.
|
|
30
|
-
- Результат залежить від вмісту та структури зазначених джерел.
|
|
29
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
30
|
+
- Перехоплює помилки і не пропускає винятків назовні (fail-safe).
|
|
31
|
+
- За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
|
|
32
|
+
- Свідомо пропускає шляхи: `.git`, `node_modules`.
|
|
33
|
+
- Не звертається до мережі.
|
|
@@ -1,33 +1,29 @@
|
|
|
1
1
|
---
|
|
2
2
|
docgen:
|
|
3
3
|
source: npm/scripts/lib/run-rule-cli.mjs
|
|
4
|
-
crc:
|
|
4
|
+
crc: 21a7b19a
|
|
5
|
+
score: 100
|
|
5
6
|
---
|
|
6
7
|
|
|
7
8
|
# run-rule-cli.mjs
|
|
8
9
|
|
|
9
10
|
## Огляд
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
Файл є автономним CLI-запускачем для одного правила. Він читає конфігурацію з `.n-cursor.json`, перевіряє, чи існує запис для заданого ID у конфігурації, друкує звіт про перевірку та повертає агрегований код виходу.
|
|
12
13
|
|
|
13
14
|
## Поведінка
|
|
14
15
|
|
|
15
|
-
1.
|
|
16
|
-
2.
|
|
17
|
-
3.
|
|
18
|
-
4.
|
|
19
|
-
5.
|
|
20
|
-
6.
|
|
21
|
-
7.
|
|
22
|
-
8.
|
|
23
|
-
9. Повертає код завершення процесу перевірки правила.
|
|
16
|
+
1. Викликається для запуску правила.
|
|
17
|
+
2. Читає конфігурацію з `.n-cursor.json`.
|
|
18
|
+
3. Перевіряє наявність правила у whitelist.
|
|
19
|
+
4. Якщо правило не дозволено, друкує повідомлення про пропуск.
|
|
20
|
+
5. Якщо правило дозволено, друкує повідомлення про перевірку правила.
|
|
21
|
+
6. Використовує кеш для перевірки.
|
|
22
|
+
7. Викликає функцію для виконання стандартного правила з кешем.
|
|
23
|
+
8. Повертає агрегований код виходу.
|
|
24
24
|
|
|
25
25
|
## Гарантії поведінки
|
|
26
26
|
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
- Виводить підсумкову інформацію про результат виконання.
|
|
31
|
-
- Повертає код завершення, що відображає загальний статус виконання.
|
|
32
|
-
- Кешує результати для уникнення повторного виконання, поки не змінено конфігурацію або не було перезапущено.
|
|
33
|
-
- Не здійснює жодних мережевих запитів.
|
|
27
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
28
|
+
- Кешує результати в межах одного прогону.
|
|
29
|
+
- Не звертається до мережі.
|
|
@@ -1,38 +1,31 @@
|
|
|
1
1
|
---
|
|
2
2
|
docgen:
|
|
3
3
|
source: npm/scripts/lib/run-rule.mjs
|
|
4
|
-
crc:
|
|
4
|
+
crc: 27060842
|
|
5
|
+
score: 95
|
|
5
6
|
---
|
|
6
7
|
|
|
7
8
|
# run-rule.mjs
|
|
8
9
|
|
|
9
10
|
## Огляд
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
Файл слугує оркестратором правила. Він координує виконання перевірок, включаючи перевірку гейту, JS-концернів та policy-концернів.
|
|
12
13
|
|
|
13
14
|
## Поведінка
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
runTemplateSubsetConcern
|
|
17
|
+
Перевіряє відповідність фактичного файлу канонічному шаблону.
|
|
18
|
+
|
|
19
|
+
runRule
|
|
20
|
+
Оркеструє виконання правила, включаючи перевірку гейту, JS-концернів та policy-концернів.
|
|
19
21
|
|
|
20
22
|
## Публічний API
|
|
21
23
|
|
|
22
|
-
- runTemplateSubsetConcern —
|
|
23
|
-
- runRule —
|
|
24
|
+
- runTemplateSubsetConcern — Snippet-driven перевірка концерну (`target.json:"check":"template"`): звіряє канон з фактичним файлом за допомогою глибокого підмножинного перевірки. Усі канонічні поля/елементи обов'язкові, зайві дозволені. Масиви співпадають за наявністю (незалежно від порядку). Зміна сніпета негайно впливає на примусовість.
|
|
25
|
+
- runRule — Запускає одне правило: applies-гейт → JS-концерни → policy-концерни.
|
|
24
26
|
|
|
25
27
|
## Гарантії поведінки
|
|
26
28
|
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
- `JS-концерни` можуть викликати `check` для виведення контексту.
|
|
31
|
-
- `Policy-концерни` викликають `runConftestBatch`.
|
|
32
|
-
- `resolveTargetFiles` кешує результати `walkCache` між `JS-концернами`.
|
|
33
|
-
- `createCheckReporter` у `Policy-концерни` OR-ює exit-коди.
|
|
34
|
-
- Exit-код правила — 0 або 1.
|
|
35
|
-
- `runTemplateSubsetConcern` запускає підмножину шаблонів.
|
|
36
|
-
- `runRule` запускає правило.
|
|
37
|
-
- Кеш використовується для зберігання результатів `resolveTargetFiles` у межах прогону.
|
|
38
|
-
- Немає взаємодії з мережею.
|
|
29
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
30
|
+
- Кешує результати в межах одного прогону.
|
|
31
|
+
- Не звертається до мережі.
|
|
@@ -1,30 +1,27 @@
|
|
|
1
1
|
---
|
|
2
2
|
docgen:
|
|
3
3
|
source: npm/scripts/lib/run-standard-rule.mjs
|
|
4
|
-
crc:
|
|
4
|
+
crc: c1ae8f0e
|
|
5
|
+
score: 90
|
|
5
6
|
---
|
|
6
7
|
|
|
7
8
|
# run-standard-rule.mjs
|
|
8
9
|
|
|
9
10
|
## Огляд
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
Файл інкапсулює оркестрацію виконання правил. Він забезпечує запуск правила через визначений шлях, ізолюючи його виконання у блоці `withLock` для уникнення паралельних запусків.
|
|
12
13
|
|
|
13
14
|
## Поведінка
|
|
14
15
|
|
|
15
|
-
1.
|
|
16
|
-
2.
|
|
17
|
-
3.
|
|
18
|
-
4.
|
|
19
|
-
5.
|
|
20
|
-
6.
|
|
21
|
-
7. Повертає код успіху (0) або код помилки (1) в залежності від результатів виконання правила.
|
|
16
|
+
1. Отримання шляху до правила
|
|
17
|
+
2. Визначення ідентифікатора правила
|
|
18
|
+
3. Охоплення виконання у блоці блокування
|
|
19
|
+
4. Пошук правила
|
|
20
|
+
5. Отримання кешу проходу
|
|
21
|
+
6. Запуск виконання правила
|
|
22
22
|
|
|
23
23
|
## Гарантії поведінки
|
|
24
24
|
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
- Різні правила можуть виконуватися паралельно.
|
|
29
|
-
- Кеш використовується для зберігання результатів виконання правил в межах одного прогону.
|
|
30
|
-
- Не допускається локальна логіка всередині правил. Розширення поведінки реалізується через опції контексту.
|
|
25
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
26
|
+
- Кешує результати в межах одного прогону.
|
|
27
|
+
- Не звертається до мережі.
|
|
@@ -1,31 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/scripts/lib/sync-gitignore-worktree.mjs
|
|
4
|
+
crc: e691c42b
|
|
5
|
+
score: 95
|
|
6
|
+
---
|
|
7
|
+
|
|
1
8
|
# sync-gitignore-worktree.mjs
|
|
2
9
|
|
|
3
10
|
## Огляд
|
|
4
11
|
|
|
5
|
-
|
|
12
|
+
syncGitignoreWorktree
|
|
13
|
+
Додає запис `.worktrees/` до кореневого `.gitignore`. Функція викликається для синхронізації локальних git-worktree з конфігурацією. Функція приймає шлях до кореня проєкту-споживача. Функція повертає результат, що вказує на успішність запису.
|
|
6
14
|
|
|
7
15
|
## Поведінка
|
|
8
16
|
|
|
9
|
-
1.
|
|
10
|
-
2.
|
|
11
|
-
3.
|
|
12
|
-
4. Утиліта додає запис, якщо його ще немає, інакше не робить нічого.
|
|
13
|
-
5. Повертає значення `true`, якщо запис було додано, інакше `false`.
|
|
17
|
+
1. Виклик функції для додавання запису `.worktrees/` до кореневого `.gitignore`.
|
|
18
|
+
2. Передача шляху до кореня проєкту-споживача.
|
|
19
|
+
3. Повернення результату, що вказує на успішність запису.
|
|
14
20
|
|
|
15
21
|
## Публічний API
|
|
16
22
|
|
|
17
|
-
syncGitignoreWorktree —
|
|
23
|
+
syncGitignoreWorktree — Додає `.worktrees/` до `.gitignore` у кореневому файлі.
|
|
18
24
|
|
|
19
25
|
## Гарантії поведінки
|
|
20
26
|
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
- Не викликається в контексті `syncClaudeConfig`.
|
|
24
|
-
- `.worktrees/` є артефактом завжди-активного flow/worktree-tooling.
|
|
25
|
-
- Один запис `.worktrees/` покриває каталог worktree та всі sibling-файли в ньому.
|
|
26
|
-
- Запис безумовний, без гейта за `.n-cursor.json`-правилами.
|
|
27
|
-
- Продюсер артефактів — завжди-активний flow.
|
|
28
|
-
- Делегує наявній idempotent+append-only утиліті `ensureGitignoreEntries`.
|
|
29
|
-
- `ensureGitignoreEntries` не перезаписує/не видаляє наявні рядки.
|
|
30
|
-
- `ensureGitignoreEntries` створює `.gitignore`, якщо нема.
|
|
31
|
-
- Не використовує кешування.
|
|
27
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
28
|
+
- Не звертається до мережі.
|
|
@@ -48,16 +48,20 @@ export function parseRuleAutoSpec(value) {
|
|
|
48
48
|
return null
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
/** Допустимі
|
|
52
|
-
const
|
|
51
|
+
/** Допустимі значення `meta.json.lint` (вісь scope: чи детектор дробиться на changed-set). */
|
|
52
|
+
const LINT_SCOPES = new Set(['per-file', 'full'])
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
|
-
* Нормалізує значення `meta.json.lint` у
|
|
55
|
+
* Нормалізує значення `meta.json.lint` у scope детектора.
|
|
56
|
+
* - `"per-file"` — детектор декомпозується на змінені файли (дельта vs origin);
|
|
57
|
+
* - `"full"` — нероздільно крос-файловий (лише `--full` / CI).
|
|
58
|
+
* Об'єктна форма `{scope, ci}` скасована: CI=`--read-only --full` ганяє все повністю,
|
|
59
|
+
* тож per-rule CI-override не потрібен (spec 2026-06-14-lint-rule-consolidation §3-А).
|
|
56
60
|
* @param {unknown} value значення поля `lint`
|
|
57
|
-
* @returns {'
|
|
61
|
+
* @returns {'per-file' | 'full' | null} scope або `null` (відсутнє/невалідне = не lint-крок)
|
|
58
62
|
*/
|
|
59
|
-
export function
|
|
60
|
-
return typeof value === 'string' &&
|
|
63
|
+
export function parseRuleLintSpec(value) {
|
|
64
|
+
return typeof value === 'string' && LINT_SCOPES.has(value) ? /** @type {'per-file'|'full'} */ (value) : null
|
|
61
65
|
}
|
|
62
66
|
|
|
63
67
|
/**
|
|
@@ -21,7 +21,7 @@ const IGNORED_DIR_NAMES = new Set(['node_modules', '.git', '.next', '.turbo'])
|
|
|
21
21
|
* @param {string[]} keys імена пакетів
|
|
22
22
|
* @returns {Promise<boolean>} true, якщо знайдено хоч один
|
|
23
23
|
*/
|
|
24
|
-
|
|
24
|
+
function anyDepInTree(root, keys) {
|
|
25
25
|
const wanted = new Set(keys)
|
|
26
26
|
/**
|
|
27
27
|
* Чи package.json за `abs` оголошує будь-який пакет із `wanted` у `dependencies`.
|
package/scripts/lint-cli.mjs
CHANGED
|
@@ -1,34 +1,38 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Оркестратор `n-cursor lint` (
|
|
2
|
+
* Оркестратор `n-cursor lint` — дві ортогональні осі (spec 2026-06-14-lint-rule-consolidation
|
|
3
|
+
* + компаньйон 2026-06-14-lint-orchestrator-fix-readonly-unification):
|
|
4
|
+
* - **scope** (`--full`): default = дельта vs origin (лише `per-file` правила);
|
|
5
|
+
* `--full` = весь репо (`per-file` ∪ `full` правила);
|
|
6
|
+
* - **behavior** (`--read-only`): default = fix; `--read-only` = лише детект без мутацій.
|
|
3
7
|
*
|
|
4
|
-
* Data-driven: сканує `rules/<id>/meta.json` за полем `lint` (`
|
|
5
|
-
*
|
|
6
|
-
* -
|
|
7
|
-
* -
|
|
8
|
-
* Порядок правил —
|
|
8
|
+
* Data-driven: сканує `rules/<id>/meta.json` за полем `lint` (`per-file`|`full`),
|
|
9
|
+
* викликає `rules/<id>/js/lint.mjs` → `lint(files, cwd, { readOnly })`:
|
|
10
|
+
* - default scope: `files` = змінені відносно origin (`collectChangedFilesSince`);
|
|
11
|
+
* - `--full`: `files = undefined` — весь проєкт.
|
|
12
|
+
* Порядок правил — алфавітний. Fail-fast: перший ненульовий код спиняє.
|
|
9
13
|
*/
|
|
10
14
|
import { existsSync, readdirSync } from 'node:fs'
|
|
11
15
|
import { dirname, join } from 'node:path'
|
|
12
16
|
import { fileURLToPath } from 'node:url'
|
|
13
17
|
import { cwd as processCwd } from 'node:process'
|
|
14
18
|
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
19
|
+
import { parseRuleLintSpec, readRuleMetaRaw } from './lib/rule-meta.mjs'
|
|
20
|
+
import { collectChangedFilesSince, resolveChangedBase } from './lib/changed-files.mjs'
|
|
17
21
|
|
|
18
22
|
const PACKAGE_ROOT = dirname(dirname(fileURLToPath(import.meta.url)))
|
|
19
23
|
const RULES_DIR = join(PACKAGE_ROOT, 'rules')
|
|
20
24
|
|
|
21
25
|
/**
|
|
22
|
-
* Вибирає id правил для
|
|
26
|
+
* Вибирає id правил для контексту, алфавітно.
|
|
23
27
|
* @param {Record<string, {lint?: unknown}>} metaById мапа id → meta-обʼєкт
|
|
24
|
-
* @param {
|
|
28
|
+
* @param {boolean} full `false` → лише `per-file` правила; `true` → усі (`per-file` ∪ `full`)
|
|
25
29
|
* @returns {string[]} відсортовані id
|
|
26
30
|
*/
|
|
27
|
-
export function selectLintRules(metaById,
|
|
31
|
+
export function selectLintRules(metaById, full) {
|
|
28
32
|
const out = []
|
|
29
33
|
for (const [id, raw] of Object.entries(metaById)) {
|
|
30
|
-
const
|
|
31
|
-
if (
|
|
34
|
+
const scope = parseRuleLintSpec(raw?.lint)
|
|
35
|
+
if (scope === 'per-file' || (full && scope === 'full')) out.push(id)
|
|
32
36
|
}
|
|
33
37
|
return out.toSorted((a, b) => a.localeCompare(b))
|
|
34
38
|
}
|
|
@@ -52,22 +56,26 @@ function readAllMeta(rulesDir) {
|
|
|
52
56
|
|
|
53
57
|
/**
|
|
54
58
|
* Запускає lint-оркестрацію.
|
|
55
|
-
* @param {{
|
|
59
|
+
* @param {{ full?: boolean, readOnly?: boolean, cwd?: string, rulesDir?: string, log?: (s: string) => void }} [opts] параметри
|
|
60
|
+
* - `full` — весь репо (`true`) проти дельти vs origin (`false`, default);
|
|
61
|
+
* - `readOnly` — лише детект без мутацій (`true`) проти fix (`false`, default).
|
|
56
62
|
* @returns {Promise<number>} exit code
|
|
57
63
|
*/
|
|
58
64
|
export async function runLint(opts = {}) {
|
|
59
|
-
const
|
|
65
|
+
const full = opts.full === true
|
|
66
|
+
const readOnly = opts.readOnly === true
|
|
60
67
|
const cwd = opts.cwd ?? processCwd()
|
|
61
68
|
const rulesDir = opts.rulesDir ?? RULES_DIR
|
|
62
69
|
const log = opts.log ?? (s => process.stdout.write(s))
|
|
63
70
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
71
|
+
// Default scope — дельта vs origin (merge-base main/origin/main); `--full` — весь репо.
|
|
72
|
+
const changed = full ? undefined : collectChangedFilesSince(resolveChangedBase(cwd), cwd)
|
|
73
|
+
if (!full && changed.length === 0) {
|
|
74
|
+
log('\nℹ️ lint: немає змінених файлів відносно origin — нічого перевіряти.\n')
|
|
67
75
|
return 0
|
|
68
76
|
}
|
|
69
77
|
|
|
70
|
-
const ids = selectLintRules(readAllMeta(rulesDir),
|
|
78
|
+
const ids = selectLintRules(readAllMeta(rulesDir), full)
|
|
71
79
|
for (const id of ids) {
|
|
72
80
|
const lintPath = join(rulesDir, id, 'js', 'lint.mjs')
|
|
73
81
|
if (!existsSync(lintPath)) {
|
|
@@ -75,7 +83,7 @@ export async function runLint(opts = {}) {
|
|
|
75
83
|
continue
|
|
76
84
|
}
|
|
77
85
|
const mod = await import(lintPath)
|
|
78
|
-
const code = await mod.lint(changed, cwd)
|
|
86
|
+
const code = await mod.lint(changed, cwd, { readOnly })
|
|
79
87
|
if (code !== 0) return code
|
|
80
88
|
}
|
|
81
89
|
return 0
|
|
@@ -33,7 +33,9 @@ import { join } from 'node:path'
|
|
|
33
33
|
/** Маркер PostToolUse fix-hook'а (`npx --no \@nitra/cursor post-tool-use-fix`). */
|
|
34
34
|
export const MANAGED_HOOK_COMMAND_MARKER = '@nitra/cursor post-tool-use-fix'
|
|
35
35
|
/** Маркер doc-files staleness-hook'ів (PostToolUse `--hook` і Stop-гейт `--git`). */
|
|
36
|
-
export const DOC_FILES_HOOK_COMMAND_MARKER = '@nitra/cursor doc-files
|
|
36
|
+
export const DOC_FILES_HOOK_COMMAND_MARKER = '@nitra/cursor lint-doc-files'
|
|
37
|
+
/** Legacy-маркер старих doc-files hook'ів (`doc-files check`) — cleanup при ресинку наявних інсталяцій. */
|
|
38
|
+
export const LEGACY_DOC_FILES_HOOK_COMMAND_MARKER = '@nitra/cursor doc-files check'
|
|
37
39
|
/** Legacy-маркер старого Stop-hook'а — лишаємо для cleanup-у при оновленні існуючих інсталяцій. */
|
|
38
40
|
export const LEGACY_STOP_HOOK_COMMAND_MARKER = '@nitra/cursor stop-hook'
|
|
39
41
|
/** Маркер ADR Stop-hook'а — підрядок шляху до bash-скрипта capture-decisions. */
|
|
@@ -51,6 +53,7 @@ export const CURSOR_ADR_NORMALIZE_HOOK_COMMAND_MARKER = '.claude/hooks/normalize
|
|
|
51
53
|
export const MANAGED_HOOK_COMMAND_MARKERS = Object.freeze([
|
|
52
54
|
MANAGED_HOOK_COMMAND_MARKER,
|
|
53
55
|
DOC_FILES_HOOK_COMMAND_MARKER,
|
|
56
|
+
LEGACY_DOC_FILES_HOOK_COMMAND_MARKER,
|
|
54
57
|
LEGACY_STOP_HOOK_COMMAND_MARKER,
|
|
55
58
|
ADR_HOOK_COMMAND_MARKER,
|
|
56
59
|
ADR_NORMALIZE_HOOK_COMMAND_MARKER
|