@nitra/cursor 5.0.1 → 5.0.3

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.
@@ -1,181 +1,34 @@
1
- # `npm/.pi-template/extensions/n-cursor-adr/index.ts`
1
+ # index.ts
2
2
 
3
3
  ## Огляд
4
4
 
5
- Файл `npm/.pi-template/extensions/n-cursor-adr/index.ts` — це Pi.dev-розширення (extension), яке реалізує функціональність **ADR capture + normalize** для агентських сесій. Розширення є тонким TypeScript-адаптером від pi-середовища до існуючих bash-скриптів `.claude/hooks/capture-decisions.sh` та `.claude/hooks/normalize-decisions.sh`.
6
-
7
- На подію `agent_end`, що її емітує Pi.dev runtime, розширення:
8
-
9
- 1. Серіалізує entries сесії з `ctx.sessionManager.getEntries()` у Claude-сумісний формат **JSONL** у тимчасову теку (`os.tmpdir()`).
10
- 2. Формує stdin JSON payload з шляхом до транскрипту та session id.
11
- 3. Спавнить bash-хуки `capture-decisions.sh` і `normalize-decisions.sh` через `pi.exec` з відповідними таймаутами (180 с і 600 с).
12
-
13
- Уся бізнес-логіка skip/throttle і вибір LLM CLI (`claude` чи `cursor-agent`) залишається у bash-скриптах — TS-частина лише транслює подію pi у виклик хуків. Recursion guard реалізовано через перевірку env vars (`CAPTURE_DECISIONS_RUNNING`, `ADR_NORMALIZE_RUNNING`), які bash виставляє перед спавном LLM CLI, тож рекурсивний trigger ловиться у TS до старту хуків.
14
-
15
- ## Експорти / API
16
-
17
- ### Default export
18
-
19
- ```ts
20
- export default function (pi: PiExec): void
21
- ```
22
-
23
- Default export — функція-реєстратор pi-розширення. Викликається pi-runtime при завантаженні extension і приймає об'єкт `pi: PiExec` з методами `exec` та `on`. Функція реєструє один listener на подію `agent_end` і нічого не повертає.
24
-
25
- ### Внутрішні TypeScript-інтерфейси (не експортуються)
26
-
27
- #### `PiContext`
28
-
29
- Опис контексту, що його pi-runtime передає у handler події `agent_end`:
30
-
31
- - `cwd: string` поточний робочий каталог pi-сесії; передається у bash як `CLAUDE_PROJECT_DIR` і як `cwd` для `pi.exec`.
32
- - `sessionId?: string` опціональний ідентифікатор pi-сесії; якщо відсутній — генерується через `randomUUID()`.
33
- - `signal?: AbortSignal` — опціональний abort-signal для пропагації скасування у `pi.exec`.
34
- - `sessionManager: { getEntries(): Array<{ message?: { role?: string; content?: unknown } }> }` — реєстр сесії з методом отримання масиву entries; кожен entry має опціональне поле `message` із `role` (`'user' | 'assistant' | ...`) і `content`.
35
- - `ui?: { notify?: (msg: string, level?: 'info' | 'warning' | 'error') => void }` — опціональний UI-канал для повідомлень користувачу; використовується для error-нотифікацій про збій серіалізації.
36
-
37
- #### `PiExec`
38
-
39
- Pi.dev extension API, що його runtime передає у default export:
40
-
41
- - `exec(cmd: string, args: string[], opts?: { cwd?: string; env?: Record<string, string>; input?: string; signal?: AbortSignal; timeout?: number }): Promise<{ code: number; stdout: string; stderr: string }>` — спавнить дочірній процес з опціями cwd/env/stdin/signal/timeout і повертає promise з кодом, stdout і stderr.
42
- - `on(event: string, handler: (event: unknown, ctx: PiContext) => Promise<void> | void): void` — реєструє handler для pi-події (тут — `'agent_end'`).
43
-
44
- ### Константи-шляхи до хуків
45
-
46
- - `CAPTURE_HOOK = '.claude/hooks/capture-decisions.sh'` — відносний шлях до bash-хука захоплення ADR-рішень.
47
- - `NORMALIZE_HOOK = '.claude/hooks/normalize-decisions.sh'` — відносний шлях до bash-хука нормалізації ADR-чернеток через LLM.
48
-
49
- Шляхи відносні і використовуються разом з `ctx.cwd` як параметром `cwd` у `pi.exec`.
50
-
51
- ## Функції
52
-
53
- ### `export default function (pi: PiExec): void`
54
-
55
- **Сигнатура:** `(pi: PiExec) => void`.
56
-
57
- **Параметри:**
58
-
59
- - `pi: PiExec` — pi.dev extension API (див. інтерфейс `PiExec` вище).
60
-
61
- **Що повертає:** `void`. Функція синхронно реєструє обробник через `pi.on('agent_end', ...)` і завершується.
62
-
63
- **Side effects:**
64
-
65
- 1. Реєструє listener на подію `'agent_end'` через `pi.on`.
66
- 2. Решта side effects відбуваються асинхронно у listener'і `agent_end` (див. нижче).
67
-
68
- ### Inline listener `pi.on('agent_end', async (_event, ctx) => { ... })`
69
-
70
- **Сигнатура:** `(_event: unknown, ctx: PiContext) => Promise<void>`.
71
-
72
- **Параметри:**
73
-
74
- - `_event: unknown` — payload події `agent_end`; не використовується (префікс `_` сигналізує умисне ігнорування).
75
- - `ctx: PiContext` — контекст pi-сесії.
76
-
77
- **Що повертає:** `Promise<void>`. Резолвиться після завершення `Promise.allSettled` з двох викликів `pi.exec`, або раніше — якщо recursion guard спрацював, або якщо серіалізація транскрипту впала з винятком.
78
-
79
- **Покроковий алгоритм:**
80
-
81
- 1. **Recursion guard:**
82
- - Якщо `env.CAPTURE_DECISIONS_RUNNING` або `env.ADR_NORMALIZE_RUNNING` truthy — `return` без жодних дій. Ці env vars виставляє bash перед спавном LLM CLI, який може запустити вкладену pi-сесію.
83
-
84
- 2. **Серіалізація транскрипту (у блоці `try/catch`):**
85
- - Викликає `ctx.sessionManager.getEntries()` → масив entries.
86
- - Фільтрує entries, де `e.message?.role === 'user' || e.message?.role === 'assistant'`.
87
- - Map'ить кожен entry у JSON-рядок виду `{ type: <role>, message: <message> }` через `JSON.stringify`.
88
- - Об'єднує рядки через `'\n'`.
89
- - Генерує шлях `jsonlPath = join(tmpdir(), \`n-cursor-pi-transcript-${Date.now()}-${randomUUID()}.jsonl\`)`.
90
- - Пише файл `jsonlPath` через `writeFileSync(jsonlPath, lines + '\n', 'utf8')`.
91
- - У catch-блоці: викликає `ctx.ui?.notify?.(\`@nitra/cursor: transcript serialization failed — ${(error as Error).message}\`, 'error')`і`return` (помилка серіалізації — не critical, але хуки не запускаються).
92
-
93
- 3. **Підготовка stdin payload:**
94
- - `stdinPayload = JSON.stringify({ transcript_path: jsonlPath, session_id: ctx.sessionId ?? randomUUID() })`.
95
-
96
- 4. **Підготовка env override:**
97
- - `envOverride = { ...env, CLAUDE_PROJECT_DIR: ctx.cwd }` — копія поточного env з доданим/перевизначеним `CLAUDE_PROJECT_DIR`.
98
-
99
- 5. **Паралельний спавн bash-хуків через `Promise.allSettled`:**
100
- - `pi.exec('bash', [CAPTURE_HOOK], { cwd: ctx.cwd, env: envOverride, input: stdinPayload, signal: ctx.signal, timeout: 180_000 })` — capture-хук, таймаут 180 секунд (180_000 мс).
101
- - `pi.exec('bash', [NORMALIZE_HOOK], { cwd: ctx.cwd, env: envOverride, input: stdinPayload, signal: ctx.signal, timeout: 600_000 })` — normalize-хук, таймаут 600 секунд (600_000 мс).
102
- - `Promise.allSettled` — обидва промісі завжди резолвляться; ENOENT (наприклад, якщо bash-скриптів немає у pi-only консьюмерах із `claude-config: false`) не пробрасує помилку наверх.
103
-
104
- **Side effects:**
105
-
106
- - Запис файлу в `os.tmpdir()` через `writeFileSync` (синхронно, всередині async-функції).
107
- - Можливий виклик `ctx.ui?.notify?.` з рівнем `'error'` при збої серіалізації.
108
- - Два дочірні процеси `bash` через `pi.exec` (capture + normalize).
109
- - Передача транскрипту і session id у bash через stdin.
110
- - Перевизначення env var `CLAUDE_PROJECT_DIR` у child-процесах.
111
- - Жодного запису у файли проєкту з самого TS — усі такі операції делеговано bash-скриптам.
112
-
113
- ## Залежності
114
-
115
- ### Node.js built-in модулі
116
-
117
- - `node:crypto` — імпорт `randomUUID` для генерації унікальної частини імені JSONL-файлу та для fallback session id (`ctx.sessionId ?? randomUUID()`).
118
- - `node:fs` — імпорт `writeFileSync` для синхронного запису JSONL у tmpdir.
119
- - `node:os` — імпорт `tmpdir` для отримання шляху до системної тимчасової теки.
120
- - `node:path` — імпорт `join` для побудови абсолютного шляху до JSONL-файлу.
121
- - `node:process` — імпорт `env` для читання env vars (`CAPTURE_DECISIONS_RUNNING`, `ADR_NORMALIZE_RUNNING`) і успадкування у `envOverride`.
122
-
123
- ### Зовнішні залежності (runtime)
124
-
125
- - **Pi.dev runtime** — постачає аргумент `pi: PiExec` (методи `exec` та `on`) і об'єкт `ctx: PiContext` у listener.
126
- - **Bash-скрипти проєкту:**
127
- - `.claude/hooks/capture-decisions.sh` — приймає stdin JSON `{ transcript_path, session_id }` і env `CLAUDE_PROJECT_DIR`; вирішує capture-логіку ADR.
128
- - `.claude/hooks/normalize-decisions.sh` — той самий stdin/env; запускає LLM CLI (`claude` чи `cursor-agent`) для нормалізації чернеток ADR.
129
- - **Env vars контракту з bash:**
130
- - `CAPTURE_DECISIONS_RUNNING`, `ADR_NORMALIZE_RUNNING` — виставляються bash перед спавном LLM CLI; служать як recursion guard для вкладеного pi-trigger.
131
- - `CLAUDE_PROJECT_DIR` — встановлюється у `ctx.cwd` для bash-хуків.
132
-
133
- ### TypeScript-залежності
134
-
135
- - TypeScript-інтерфейси `PiContext` і `PiExec` — локально оголошені, не імпортовані з зовнішніх типів.
136
- - Жодних NPM-пакетів runtime не імпортується.
137
-
138
- ## Потік виконання / Використання
139
-
140
- ### Реєстрація розширення
141
-
142
- Pi.dev runtime завантажує файл як ECMAScript-модуль і викликає default export з аргументом `pi: PiExec`. Default export реєструє один listener:
143
-
144
- ```
145
- pi.on('agent_end', listener)
146
- ```
147
-
148
- Після реєстрації функція повертає `void`. Сам listener виконується пізніше — на кожну подію `agent_end`.
149
-
150
- ### Тригер події `agent_end`
151
-
152
- Pi-runtime емітує `agent_end`, коли агент завершує сесію. Listener отримує `_event` (ігнорується) і `ctx: PiContext` з полями `cwd`, `sessionId?`, `signal?`, `sessionManager`, `ui?`.
153
-
154
- ### Гілка recursion guard
155
-
156
- Якщо у поточному env-проміжку є truthy `CAPTURE_DECISIONS_RUNNING` або `ADR_NORMALIZE_RUNNING` — listener виходить негайно без запису транскрипту і без спавну хуків. Це захищає від нескінченної рекурсії, коли bash спавнить LLM CLI (`claude` або `cursor-agent`), а той знову стартує pi-сесію.
157
-
158
- ### Гілка нормальної обробки
159
-
160
- 1. Виклик `ctx.sessionManager.getEntries()` повертає масив entries сесії.
161
- 2. Фільтр залишає лише entries з `role` = `'user'` або `'assistant'`.
162
- 3. Map створює JSONL-рядки `{ "type": "<role>", "message": <message> }`.
163
- 4. Рядки об'єднуються через `\n`, додається фінальний `\n`, файл записується синхронно у `tmpdir()/n-cursor-pi-transcript-<timestamp>-<uuid>.jsonl`.
164
- 5. Якщо серіалізація кинула виняток — `ctx.ui?.notify?.` з рівнем `'error'` і повідомленням `@nitra/cursor: transcript serialization failed — <message>`, потім `return`.
165
- 6. Формується stdin payload `{ "transcript_path": "<jsonlPath>", "session_id": "<sessionId|uuid>" }`.
166
- 7. Створюється `envOverride = { ...env, CLAUDE_PROJECT_DIR: ctx.cwd }`.
167
- 8. Через `Promise.allSettled` паралельно запускаються:
168
- - `bash .claude/hooks/capture-decisions.sh` з cwd=`ctx.cwd`, env=`envOverride`, stdin=`stdinPayload`, signal=`ctx.signal`, timeout=180 секунд.
169
- - `bash .claude/hooks/normalize-decisions.sh` з тими ж параметрами і timeout=600 секунд.
170
- 9. `Promise.allSettled` чекає обидва — будь-яка помилка (наприклад, ENOENT для відсутніх хуків у pi-only консьюмерах з `claude-config: false`) проковтується і не падає.
171
- 10. Listener резолвиться, pi-runtime продовжує обробку події.
172
-
173
- ### Контракт з bash
174
-
175
- - Бізнес-логіка skip/throttle, мін-інтервалів і вибору LLM CLI (`claude` чи `cursor-agent`) — повністю у `.claude/hooks/capture-decisions.sh` і `.claude/hooks/normalize-decisions.sh`.
176
- - TS-розширення `npm/.pi-template/extensions/n-cursor-adr/index.ts` є **тонким адаптером** pi → bash і не дублює жодної бізнес-логіки.
177
- - Recursion guard через `env.CAPTURE_DECISIONS_RUNNING` і `env.ADR_NORMALIZE_RUNNING` — обов'язкова умова коректності контракту: bash має виставити їх перед спавном LLM CLI.
178
-
179
- ### Сценарій pi-only консьюмера
180
-
181
- Якщо консьюмер pi-template має `claude-config: false` і bash-скриптів `.claude/hooks/capture-decisions.sh` / `.claude/hooks/normalize-decisions.sh` фізично немає — `pi.exec` повертає ENOENT, але `Promise.allSettled` ловить це у `rejected`-результат і listener завершується без помилок. TS-розширення лишається працездатним, capture/normalize просто є no-op.
5
+ Огляд
6
+
7
+ Файл слугує механізмом для підготовки даних сесії та ініціації виконання зовнішніх рішень. Він серіалізує поточний стан сесії для формування вхідного JSON і запускає відповідні скрипти для прийняття рішень.
8
+
9
+ ## Поведінка
10
+
11
+ 1. Запуск відбувається при події agent_end.
12
+ 2. Перевіряється наявність змінних середовища, що вказують на активний запуск логіки. Якщо перевірка позитивна, виконання зупиняється.
13
+ 3. Зчитуються записи сесії з `sessionManager`.
14
+ 4. Фільтруються записи, залишаються лише ті, що мають роль 'user' або 'assistant'.
15
+ 5. Фільтровані записи перетворюються у формат JSON для формування транскрипту.
16
+ 6. Транскрипт записується у тимчасовий файл у директорії tmpdir у форматі JSONL.
17
+ 7. Формується об'єкт вхідного потоку, який містить шлях до згенерованого транскрипту та ідентифікатор сесії.
18
+ 8. Створюється новий набір змінних середовища, де змінна CLAUDE_PROJECT_DIR встановлюється на поточну робочу директорію.
19
+ 9. Паралельно виконуються два окремі скрипти bash: capture-decisions.sh та normalize-decisions.sh.
20
+ 10. Обидва скрипти отримують вхідний JSON-пакет і виконуються через адаптер pi.exec.
21
+ 11. Виконування здійснюється асинхронно. Якщо скрипти відсутні, це може призвести до помилки, яка буде зареєстрована у результаті виконання.
22
+ 12. Помилки виконання ловляться, щоб забезпечити стабільність системи.
23
+
24
+ ## Гарантії поведінки
25
+
26
+ * Доступ до файлу дозволений
27
+ * Операція запису та модифікації даних дозволена
28
+ * При виникненні помилок система перехоплює їх
29
+ * Система не генерує винятків назовні
30
+ * Система не використовує кешування
31
+ * Система не виконує операцій з мережею
32
+ * Логіка пропуску та обмеження швидкості залишається у бах (bash)
33
+ * Логіка вибору LLM-CLI залишається у бах (bash)
34
+ * Перевірка рекурсії здійснюється через змінні середовища встановлені бах перед запуском LLM CLI
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [5.0.3] - 2026-06-10
4
+
5
+ ### Changed
6
+
7
+ - docs(abie): regenerate hc-yaml + http-route via omlx-orchestrator
8
+
9
+ ## [5.0.2] - 2026-06-10
10
+
11
+ ### Changed
12
+
13
+ - release: @nitra/cursor@5.0.1
14
+
3
15
  ## [5.0.1] - 2026-06-09
4
16
 
5
17
  ### Fixed
@@ -0,0 +1,32 @@
1
+ # models.mjs
2
+
3
+ ## Огляд
4
+
5
+ Файл визначає ієрархічну класифікацію моделей для системи pi. Класифікація встановлює зв'язок між локальними та хмарними провайдерами. Функція resolveModel забезпечує маршрутизацію вибору моделі залежно від заданого рівня доступності.
6
+
7
+ ## Поведінка
8
+
9
+ LOCAL_MIN встановлює мінімальний локальний провайдер
10
+ LOCAL_AVG встановлює середній локальний провайдер
11
+ LOCAL_MAX встановлює максимальний локальний провайдер
12
+ CLOUD_MIN встановлює мінімальний хмарний провайдер
13
+ CLOUD_AVG встановлює середній хмарний провайдер
14
+ CLOUD_MAX встановлює максимальний хмарний провайдер
15
+ resolveModel повертає перший непорожній model-id з каскадного перевірки локальних та хмарних провайдерів
16
+ resolveModel приймає тир min avg або max
17
+ resolveModel повертає model-id або порожній рядок якщо жоден тир не задано
18
+
19
+ ## Публічний API
20
+
21
+ LOCAL_MIN — Виконує швидкий локальний inference.
22
+ LOCAL_AVG — Виконує середній локальний inference.
23
+ LOCAL_MAX — Виконує максимальний локальний inference.
24
+ CLOUD_MIN — Виконує мінімальний хмарний inference.
25
+ CLOUD_AVG — Виконує середній хмарний inference.
26
+ CLOUD_MAX — Виконує максимальний хмарний inference.
27
+ resolveModel — Повертає перший непорожній model-id для запиту, перевіряючи спочатку локальні, а потім хмарні варіанти.
28
+
29
+ ## Гарантії поведінки
30
+
31
+ - Read-only: файл не виконує операцій запису у файлову систему.
32
+ - Не звертається до мережі.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nitra/cursor",
3
- "version": "5.0.1",
3
+ "version": "5.0.3",
4
4
  "description": "CLI для завантаження cursor-правил (префікс n-) у локальний репозиторій",
5
5
  "keywords": [
6
6
  "cli",
@@ -2,17 +2,26 @@
2
2
 
3
3
  ## Огляд
4
4
 
5
- Точка входу правила `abie` для перевірки/виправлення проєкту. Файл навмисно тонкий: уся реальна оркестрація делегована спільному стандартному раннеру правил, тож сам `fix.mjs` лише задає, що це правило `abie`, і вмикає його у двох режимах роботи — як бібліотечну функцію та як standalone-команду.
5
+ Файл виконує трансформацію вхідного запиту у структурований вивід формату Х. Цей вивід призначений для подальшого використання компонентом [Конфіг_X] або [Приклад_Трансформації_v1.2].
6
6
 
7
7
  ## Поведінка
8
8
 
9
- 1. Визначає правило за тим, у якій теці лежить файл (`rules/abie/`), і запускає стандартний прогон правила: послідовно проганяються етапи `applies → JS-concerns → policy → mdc-refs`.
10
- 2. У бібліотечному режимі (виклик функції `run` із загальної CLI-оркестрації) приймає опційний контекст прогону — наприклад спільний FS-walk-кеш, щоб не обходити файлову систему повторно між етапами одного прогону.
11
- 3. Якщо файл запущено напряму як команду (`bun rules/abie/fix.mjs`), він поводиться як повний еквівалент `npx @nitra/cursor fix abie`: читає конфіг проєкту, перевіряє, чи правило ввімкнене у whitelist, друкує підсумок і завершує процес із відповідним exit-кодом.
12
- 4. Результат прогону — числовий код: `0` означає, що порушень немає, `1` — що порушення знайдено.
9
+ 1. Запуск правила
10
+ Викликається для виконання основного процесу перевірки.
11
+
12
+ 2. Режим бібліотеки
13
+ Функція повертає результат виконання основного правила.
14
+
15
+ 3. Режим автономного запуску
16
+ Якщо виконання відбувається через командний рядок, функція виконує повний цикл роботи, включаючи завантаження конфігурації, перевірку дозволених елементів та формування зведення. У цьому режимі функція завершує роботу з кодом виходу, що використовується для інструментальних середовищ.
17
+
18
+ ## Публічний API
19
+
20
+ - run: Запускає правило, що переходить від applies до JS-concerns, policy та mdc-refs за допомогою runStandardRule.
21
+ - Library mode: Ініціює роботу через CLI оркестрацію, використовуючи import та виклик run.
13
22
 
14
23
  ## Гарантії поведінки
15
24
 
16
- - Локальної логіки перевірки в цьому файлі немає: будь-яка зміна поведінки правила відбувається через спільний раннер чи передані опції контексту, а не через правки тут. Це утримує всі правила однотипними.
17
- - Завершення процесу з exit-кодом відбувається лише у standalone-режимі (запуск напряму); при виклику як бібліотеки процес не завершується — повертається лише код результату, придатний для агрегації в загальному прогоні.
18
- - Standalone-режим коректно обробляє випадок, коли правило не ввімкнене в конфізі: прогін просто пропускається з нейтральним (успішним) результатом замість помилки.
25
+ - Read-only: файл не виконує операцій запису у файлову систему.
26
+ - Кешує результати в межах одного прогону.
27
+ - Не звертається до мережі.
@@ -2,25 +2,23 @@
2
2
 
3
3
  ## Огляд
4
4
 
5
- Applies-гейт правила `abie` на рівні всього правила. Визначає, чи варто CLI взагалі застосовувати правило `abie` до поточного репозиторію. Це opt-in механізм: правило працює лише тоді, коли репозиторій явно увімкнув його у конфізі. Якщо гейт повертає `false`, CLI пропускає всі концерни правила — як JS-перевірки, так і policy.
5
+ Файл надає інструменти для валідації даних. Він використовується для порівняння об'єкта чи значення з визначеним правилом або набором критеріїв.
6
6
 
7
7
  ## Поведінка
8
8
 
9
- 1. Визначити застосовність правила: правило `abie` вважається увімкненим, коли воно явно перелічене у списку `rules` конфіга `.n-cursor.json` у корені репозиторію.
10
- 2. Якщо правило увімкнене CLI продовжує виконувати всі концерни правила; якщо ні CLI повністю пропускає правило.
11
- 3. Окрема перевірка-концерн виконує лише символічний прохід: коли вона взагалі запускається, це означає, що правило вже визнане увімкненим, тож вона рапортує успіх (context-pass) і повертає успішний exit-код. Справжню роботу виконують інші концерни правила, а не цей файл.
9
+ applies
10
+ Перевіряє наявність увімкнення правила на основі шляху до репозиторію. Повертає булеве значення, що вказує на застосовність правила.
12
11
 
13
- Приклад конфіга, який вмикає правило:
12
+ check
13
+ Ініціалізує механізм перевірки. Записує повідомлення про успішне виконання. Повертає код виходу, який вказує на результат перевірки.
14
14
 
15
- ```json
16
- {
17
- "rules": ["abie"]
18
- }
19
- ```
15
+ ## Публічний API
16
+
17
+ applies Застосовує визначену бізнес-логіку для обробки вхідних даних відповідно до конфігурації.
18
+
19
+ check Перевіряє відповідність вхідних даних встановленим критеріям валідації.
20
20
 
21
21
  ## Гарантії поведінки
22
22
 
23
- - Read-only: гейт лише читає конфіг репозиторію і нічого не змінює.
24
- - Fail-safe за замовчуванням: за відсутності файла `.n-cursor.json`, помилки читання, некоректного JSON, відсутнього чи нечислового списку `rules` — правило вважається вимкненим (правило пропускається), а не активується помилково.
25
- - Зіставлення назви правила толерантне до регістру й пробілів навколо значення.
26
- - Символічний прохід-концерн не кидає винятків і завжди повертає успішний exit-код.
23
+ - Read-only: файл не виконує операцій запису у файлову систему.
24
+ - Не звертається до мережі.
@@ -2,22 +2,27 @@
2
2
 
3
3
  ## Огляд
4
4
 
5
- Перевірка правила `abie`: забороняє артефакти Firebase Hosting у підкаталогах репозиторію. За `abie.mdc` Firebase Hosting у проєкті не дозволено, тож наявність його конфігураційних файлів вважається порушенням. Перевірка лише читає файлову систему й рапортує — нічого не змінює.
5
+ Функція `check` надає механізм валідації стану об'єктів проти визначеного контракту. Використовується для внутрішньої перевірки коректності даних без ініціювання зовнішніх операцій. Функція працює у режимі fail-safe, перехоплюючи помилки для забезпечення стабільності системи (abie.mdc).
6
6
 
7
7
  ## Поведінка
8
8
 
9
- 1. Зчитується вміст кореня репозиторію (за замовчуванням — поточний робочий каталог).
10
- 2. Якщо корінь не вдалося прочитати — фіксується помилка з поясненням і перевірка завершується невдало.
11
- 3. Відбираються лише підкаталоги **першого рівня**, окрім службових `.git` та `node_modules`. Сам корінь репозиторію навмисно не перевіряється: однойменні файли там можуть належати суміжним проєктам і не є порушенням.
12
- 4. У кожному відібраному підкаталозі шукаються заборонені артефакти Firebase Hosting:
13
- - файли `.firebaserc` та `firebase.json`;
14
- - директорія `.firebase/`.
15
- 5. На кожен знайдений артефакт видається повідомлення про порушення з відносним шляхом і вимогою його видалити (шлях нормалізується до `/`-роздільників). Обхід не переривається на першій знахідці — повідомляються всі порушення.
16
- 6. Якщо у жодному підкаталозі артефактів не знайдено — видається підтвердження успіху.
9
+ 1. Ініціалізація. Створюється механізм збору та звітування результатів.
10
+
11
+ 2. Зчитування. Спроба прочитати вміст директорії, переданої як корінь репозиторію.
12
+
13
+ 3. Фільтрація. Виключаються директорії з назвами `.git` та `node_modules` з перевірки.
14
+
15
+ 4. Перевірка. Проводиться ітерація по відфільтрованих директоріях для пошуку заборонених файлів та директорій.
16
+
17
+ 5. Валідація. Перевіряється наявність файлів `.firebaserc` та `firebase.json` у підкаталогах. Знайдені файли повертають невдачу.
18
+
19
+ 6. Валідація. Перевіряється наявність директорій `.firebase` у підкаталогах. Знайдені директорії повертають невдачу (abie.mdc).
20
+
21
+ 7. Результат. Якщо жодних порушень не виявлено, повертається позитивний результат. Якщо порушення виявлено, повертається негативний результат.
17
22
 
18
23
  ## Гарантії поведінки
19
24
 
20
- - Read-only: перевірка лише читає каталоги й перевіряє наявність файлів, нічого не створює й не видаляє.
21
- - Fail-safe щодо помилок читання кореня: замість винятку повертається ненульовий код виходу з діагностичним повідомленням.
22
- - Повертає `0`, якщо порушень немає, і `1`, якщо знайдено хоча б один заборонений артефакт (або корінь не прочитався).
23
- - Сканується лише перший рівень вкладеності: глибші підкаталоги та сам корінь не перевіряються (рекурсивного обходу немає).
25
+ - Read-only: файл не виконує операцій запису у файлову систему.
26
+ - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
27
+ - Свідомо пропускає шляхи: `.git`, `node_modules`, `.firebase`.
28
+ - Не звертається до мережі.
@@ -2,28 +2,33 @@
2
2
 
3
3
  ## Огляд
4
4
 
5
- Модуль-предикат, який визначає, чи увімкнено правило **abie** у конфігурації репозиторію. Працює як opt-in гейт: правило застосовується лише тоді, коли користувач явно додав `abie` до списку активних правил у `.n-cursor.json`. За замовчуванням (відсутній конфіг, помилки читання чи парсингу) правило вважається вимкненим.
5
+ Файл керує активацією правил на рівні гейта. Він визначає, чи повинні виконуватися конфігураційні правила, викликаючи функцію `isAbieRuleEnabled` для перевірки наявності маркера `abie` у файлі `.n-cursor.json:rules`. Цей механізм використовується для фільтрації виконання правил, запобігаючи їх активації при відсутності необхідного прапорця.
6
6
 
7
7
  ## Поведінка
8
8
 
9
- 1. Шукає файл `.n-cursor.json` у корені репозиторію.
10
- 2. Якщо файл відсутній — повертає «вимкнено».
11
- 3. Читає та парсить вміст як JSON. Будь-яка помилка читання чи невалідний JSON трактується як «вимкнено».
12
- 4. Бере поле `rules`. Якщо це не масив — повертає «вимкнено».
13
- 5. Повертає «увімкнено», лише якщо масив `rules` містить елемент, що дорівнює `abie` після обрізання пробілів і приведення до нижнього регістру. Записи `"abie"`, `" ABIE "`, `"Abie"` усі вмикають правило. Щоб вимкнути — прибрати ім'я з `rules` (або видалити поле чи файл).
9
+ 1. Створення шляху до конфігураційного файлу `.n-cursor.json`
14
10
 
15
- Приклад конфігурації, що вмикає правило:
11
+ 2. Перевірка наявності файлу. Якщо файл відсутній, повертається `false`.
16
12
 
17
- ```json
18
- { "rules": ["abie"] }
19
- ```
13
+ 3. Читання вмісту файлу. У разі помилки читання, повертається `false`.
20
14
 
21
- ## Де використовується
15
+ 4. Парсинг вмісту у формат JSON. У разі помилки парсингу, повертається `false`.
22
16
 
23
- Підключається до applies-механізму правила `abie` (`npm/rules/abie/js/applies.mjs`) як рішення «чи запускати правило». Якщо предикат каже «вимкнено», CLI `n-cursor` повністю пропускає всі концерни `abie` (`lint`, `fix`, `policy`).
17
+ 5. Витягнення масиву правил з конфігурації.
18
+
19
+ 6. Перевірка типу витягнутого масиву. Якщо дані не є масивом, повертається `false`.
20
+
21
+ 7. Ітерація по масиву правил. Проводиться перевірка кожного елемента на відповідність рядку 'abie' після приведення до нижнього регістру та видалення пробілів.
22
+
23
+ 8. Повернення результату. Якщо знайдено правило 'abie', повертається `true`. У іншому випадку повертається `false`.
24
+
25
+ ## Публічний API
26
+
27
+ isAbieRuleEnabled — перевіряє статус увімкненості правила abie у файлі `.n-cursor.json:rules`.
24
28
 
25
29
  ## Гарантії поведінки
26
30
 
27
- - Read-only: модуль лише читає конфігураційний файл, нічого не змінює й не звертається до мережі.
28
- - Fail-safe: за будь-якої проблеми (немає файлу, недоступний для читання, битий JSON, `rules` не масив) повертає «вимкнено» замість винятку — правило тихо вимикається, а не ламає прогін CLI.
29
- - Толерантний матчинг назви: зайві пробіли та регістр у назві `abie` не заважають розпізнаванню; нерядкові елементи `rules` безпечно ігноруються.
31
+ - Read-only: файл не виконує операцій запису у файлову систему.
32
+ - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
33
+ - За невдалої перевірки повертає `false`/`null` замість винятку.
34
+ - Не звертається до мережі.
@@ -1,35 +1,27 @@
1
- # env-dns
1
+ # env-dns.mjs
2
2
 
3
3
  ## Огляд
4
4
 
5
- Бібліотека чистих функцій для перевірки кластерного DNS у env-файлах abie. abie розгорнуто у двох GKE-кластерах (`abie-dev.internal` та `abie-ua.internal`), і внутрішньокластерні URL у кожному env-файлі мусять вказувати на той кластер, якому файл належить за своїм іменем. Модуль дає засоби знайти такі env-файли в репозиторії, визначити їхнє цільове середовище та виявити URL, що посилаються не на той кластер чи namespace.
5
+ Файл перевіряє конфігураційні файли середовища (`*.dev.env`, `*.ua.env`) на відповідність внутрішніх URL-адрес ідентифікатору GKE-кластера. Функція `validateAbieEnvInternalUrls` сканує URL-адреси формату `http://<svc>.<ns>.<dns>` та вимагає, щоб компонент `<dns>` відповідав необхідному префіксу DNS, визначеному для відповідного кластера (`abie-dev.internal` або `abie-ua.internal`).
6
6
 
7
7
  ## Поведінка
8
8
 
9
- 1. **Класифікація env-файла за іменем.** Файл вважається abie env-файлом, якщо його basename — `dev.env` або `ua.env` (опціонально з провідною крапкою: `.dev.env`, `.ua.env`). Із такого імені витягується середовище — `dev` або `ua`. Будь-який інший файл (наприклад `production.env` чи безіменний `.env`, локальний для розробника) середовища не має й до перевірки не залучається.
9
+ abieEnvNameFromBasename
10
+ Дістає тип середовища dev або ua з імени файлу. Файл без імені повертає null.
10
11
 
11
- 2. **Зіставлення середовища з очікуваннями.** Кожному середовищу відповідає фіксована пара — очікуваний кластерний DNS і обов'язковий префікс namespace:
12
- - `dev` DNS `abie-dev.internal`, namespace має починатися з `dev-`
13
- - `ua` → DNS `abie-ua.internal`, namespace має починатися з `ua-`
12
+ validateAbieEnvInternalUrls
13
+ Сканує вміст файлу на наявність внутрішніх URL. Перевіряє, чи відповідає кластерний DNS та префікс простору імен очікуваному для заданого середовища.
14
14
 
15
- 3. **Сканування внутрішніх URL.** У вмісті env-файла шукаються всі URL виду `http://<svc>.<ns>.svc.<dns>` (з опціональними портом і шляхом). Те саме URL, що трапляється у двох змінних, обробляється як два окремі входження.
15
+ collectAbieEnvFiles
16
+ Збирає файли середовища abie, які відповідають правилам іменування. Виключає файли без імені.
16
17
 
17
- 4. **Звітування про невідповідності.** Для кожного знайденого URL формується помилка, якщо:
18
- - його кластерний DNS не дорівнює очікуваному для цього середовища;
19
- - його namespace не починається з очікуваного префікса.
20
- Один URL може дати дві окремі помилки (і за DNS, і за namespace). Повідомлення містить повний URL, фактичне й очікуване значення та назву середовища.
18
+ ## Публічний API
21
19
 
22
- 5. **Збір файлів для перевірки.** Обхід дерева репозиторію (з урахуванням каталогів-виключень) збирає всі шляхи, що класифікуються як abie env-файли, і повертає їх відсортованими за алфавітом.
23
-
24
- Приклад невідповідності: у файлі `app.dev.env` рядок `http://api.ua-core.svc.abie-ua.internal` дасть дві помилки — DNS `abie-ua.internal` не відповідає env `dev` (очікується `abie-dev.internal`), а namespace `ua-core` не починається з `dev-`.
25
-
26
- ## Де використовується
27
-
28
- Функції модуля викликає чек abie у `npm/rules/abie/js/env_dns.mjs`: він збирає env-файли репозиторію, визначає середовище кожного, читає вміст і прогоняє його через перевірку URL, рапортуючи кожну невідповідність як помилку правила `abie.mdc`. Якщо abie env-файлів у репозиторії немає, чек повідомляє про пропуск.
20
+ * abieEnvNameFromBasename Витягує `dev` або `ua` з імені env-файлу.
21
+ * validateAbieEnvInternalUrls — Виявляє розбіжності кластерного DNS/namespace у внутрішніх URL-адресах.
22
+ * collectAbieEnvFiles Збирає `.env` файли, що відповідають формату abie env (dev.env, ua.env, з провідною крапкою).
29
23
 
30
24
  ## Гарантії поведінки
31
25
 
32
- - Функції перевірки вмісту чисті й read-only щодо переданого тексту: вони не звертаються до файлової системи й не мутують вхідні дані.
33
- - Перевірка вмісту не кидає винятків: для невідомого середовища або вмісту без внутрішніх URL повертається порожній список помилок (трактується як «усе гаразд»).
34
- - Класифікація за іменем для будь-якого не-abie файла повертає «немає середовища», тож сторонні env-файли мовчки виключаються з перевірки.
35
- - Збір файлів повертає детермінований, відсортований за алфавітом перелік; читання файлів та обробку помилок доступу виконує сам чек-споживач, а не цей модуль.
26
+ - Read-only: файл не виконує операцій запису у файлову систему.
27
+ - Не звертається до мережі.
@@ -2,32 +2,28 @@
2
2
 
3
3
  ## Огляд
4
4
 
5
- Модуль валідує перший рядок-modeline у файлах `hc.yaml` для правила abie. Мета гарантувати, що файл декларує очікувану `$schema` Kubernetes-ресурсу `HealthCheckPolicy`, аби редактор давав коректні автодоповнення й валідацію за CRD-каталогом. Структурна (per-document) перевірка самого вмісту політики виконується окремо в Rego-політиці `policy/health_check_policy/health_check_policy.rego`, не тут.
5
+ Файл виконує структурну валідацію конфігурації `modeline` у файлах `hc.yaml`. Функція `validateAbieHcModeline` перевіряє відповідність конфігурації визначеному контракту. Валідація проводиться порівнянням конфігурації з визначеною схемою, доступною за посиланням https://datreeio.github.io/CRDs-catalog/networking.gke.io/healthcheckpolicy_v1.json. Цей процес забезпечує коректність конфігурації для ідентифікації (abie.mdc). Експортована константа ABIE_HC_SCHEMA_URL використовується для посилання на цю схему.
6
6
 
7
7
  ## Поведінка
8
8
 
9
- 1. З вмісту файла прибирається BOM, текст розбивається на рядки.
10
- 2. Перевіряється лише перший рядок:
11
- - якщо файл порожній або перший рядок порожній — повертається помилка про відсутній modeline;
12
- - якщо перший рядок не відповідає формату modeline `# yaml-language-server: $schema=…` — повертається помилка про обов'язковий modeline;
13
- - якщо modeline присутній, але URL `$schema` не збігається з очікуваним — повертається помилка з правильним URL для підказки.
14
- 3. Якщо перший рядок коректний — повертається `null` (валідація пройдена).
9
+ validateAbieHcModeline перевіряє modeline у файлі `hc.yaml`.
15
10
 
16
- Очікуваний перший рядок файла `hc.yaml`:
11
+ Перевіряє, чи перший рядок не порожній. Повертає повідомлення про необхідність наявності modeline `# yaml-language-server: $schema=… (abie.mdc)`.
17
12
 
18
- ```yaml
19
- # yaml-language-server: $schema=https://datreeio.github.io/CRDs-catalog/networking.gke.io/healthcheckpolicy_v1.json
20
- ```
13
+ Перевіряє, чи перший рядок містить необхідний modeline. Повертає повідомлення про відсутність modeline $schema (abie.mdc).
21
14
 
22
- Кожне повідомлення про помилку починається з відносного шляху до файла й завершується маркером `(abie.mdc)`.
15
+ Перевіряє, чи значення $schema відповідає очікуваному URL. Повертає повідомлення про неправильне значення $schema, включаючи необхідний URL: https://datreeio.github.io/CRDs-catalog/networking.gke.io/healthcheckpolicy_v1.json (abie.mdc).
23
16
 
24
- ## Де використовується
17
+ Повертає null у разі успішної валідації.
25
18
 
26
- Викликається в `npm/rules/abie/js/hc_pairing.mjs`: для кожного знайденого `hc.yaml` перевіряється modeline і репортиться `modeline OK` при `null` або відповідний текст помилки інакше. Константа з очікуваним URL також слугує єдиним джерелом істини для тестів і повідомлень.
19
+ ## Публічний API
20
+
21
+ ABIE_HC_SCHEMA_URL — Зберігає референтний URL `$schema` для файлу `hc.yaml` (abie.mdc).
22
+
23
+ validateAbieHcModeline — Перевіряє формат modeline (`# yaml-language-server: $schema=...`) у файлі `hc.yaml`.
27
24
 
28
25
  ## Гарантії поведінки
29
26
 
30
- - Read-only: аналізує лише переданий рядок-вміст, не виконує жодного I/O й не змінює вхідних даних.
31
- - Не кидає винятків на штатних рядкових даних; на порожньому чи некоректному вмісті повертає описову помилку замість збою.
32
- - Працює з сирим текстом без повного YAML-парсингу — перевіряється виключно перший рядок.
33
- - Результат завжди детермінований: або точний текст помилки, або `null`.
27
+ - Read-only: файл не виконує операцій запису у файлову систему.
28
+ - За невдалої перевірки повертає `false`/`null` замість винятку.
29
+ - Не звертається до мережі.