@nitra/cursor 5.0.2 → 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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
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
+
3
9
  ## [5.0.2] - 2026-06-10
4
10
 
5
11
  ### Changed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nitra/cursor",
3
- "version": "5.0.2",
3
+ "version": "5.0.3",
4
4
  "description": "CLI для завантаження cursor-правил (префікс n-) у локальний репозиторій",
5
5
  "keywords": [
6
6
  "cli",
@@ -2,25 +2,25 @@
2
2
 
3
3
  ## Огляд
4
4
 
5
- Файл виконує структурну валідацію конфігураційного файлу `hc.yaml` для перевірки відповідності даних визначенню політики перевірки стану. Валідація здійснюється порівнянням даних з контрактом `HealthCheckPolicy`, який визначений у рего-файлі. Ця функція забезпечує перевірку відповідно до схеми, визначеної за посиланням https://datreeio.github.io/CRDs-catalog/networking.gke.io/healthcheckpolicy_v1.json. Використовується константа ABIE_HC_SCHEMA_URL, яка позначає цей URL. Результат валідації повертається у форматі булевого значення або null.
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
- validateAbieHcModeline перевіряє modeline у вхідному контенті.
9
+ validateAbieHcModeline перевіряє modeline у файлі `hc.yaml`.
10
10
 
11
- Перевіряє, чи перший рядок не порожній. Якщо рядок порожній, повертає повідомлення про необхідність формату modeline (abie.mdc).
11
+ Перевіряє, чи перший рядок не порожній. Повертає повідомлення про необхідність наявності modeline `# yaml-language-server: $schema=… (abie.mdc)`.
12
12
 
13
- Перевіряє наявність modeline у першому рядку. Якщо modeline відсутній, повертає повідомлення про необхідність формату modeline (abie.mdc).
13
+ Перевіряє, чи перший рядок містить необхідний modeline. Повертає повідомлення про відсутність modeline $schema (abie.mdc).
14
14
 
15
- Перевіряє, чи значення $schema відповідає очікуваному URL. Якщо значення не відповідає, повертає повідомлення про необхідність використання URL https://datreeio.github.io/CRDs-catalog/networking.gke.io/healthcheckpolicy_v1.json (abie.mdc).
15
+ Перевіряє, чи значення $schema відповідає очікуваному URL. Повертає повідомлення про неправильне значення $schema, включаючи необхідний URL: https://datreeio.github.io/CRDs-catalog/networking.gke.io/healthcheckpolicy_v1.json (abie.mdc).
16
16
 
17
17
  Повертає null у разі успішної валідації.
18
18
 
19
19
  ## Публічний API
20
20
 
21
- ABIE_HC_SCHEMA_URL — Вказує на необхідний URL `$schema` для файлу `hc.yaml` (abie.mdc).
21
+ ABIE_HC_SCHEMA_URL — Зберігає референтний URL `$schema` для файлу `hc.yaml` (abie.mdc).
22
22
 
23
- validateAbieHcModeline — Перевіряє синтаксис modeline (`# yaml-language-server: $schema=...`) у файлі `hc.yaml`.
23
+ validateAbieHcModeline — Перевіряє формат modeline (`# yaml-language-server: $schema=...`) у файлі `hc.yaml`.
24
24
 
25
25
  ## Гарантії поведінки
26
26
 
@@ -2,31 +2,23 @@
2
2
 
3
3
  ## Огляд
4
4
 
5
- Файл надає інструмент для порівняльного аналізу конфігурації. Він використовується для підрахунку кількості посилань на спільні бекенди в базових маніфестах пакета. Ця інформація слугує для синхронізації кількості патчів у потоковому (overlay) прошарку з кількістю базових посилань.
5
+ Файл надає інструмент для порівняльного аналізу конфігурації HTTP-маршрутів. Він виконує порівняння кількості `backendRefs` для сервісів `auth-run-hl` та `file-link-hl` у базових маніфестах пакета з кількістю патчів, визначеною в оверлеях. Цей механізм використовується для синхронізації кількості патчів у верхньому рівні з фактичною кількістю посилань у базі. (abie.mdc)
6
6
 
7
7
  ## Поведінка
8
8
 
9
- ABIE_SHARED_CROSS_NS_BACKEND_NAMES визначає список спільних сервісів, які підлягають аналітиці.
9
+ ABIE_SHARED_CROSS_NS_BACKEND_NAMES
10
+ Визначає список спільних сервісів, які підлягають аналітиці.
10
11
 
11
- ABIE_SHARED_CROSS_NS_BACKEND_SET створює множину спільних сервісів для швидкої перевірки.
12
-
13
- checkSharedBackendRef перевіряє, чи посилається елемент на спільний сервіс, і перевіряє, чи відповідає його імена та namespace вимогам.
14
-
15
- httpRouteDocSharedCrossNsBackendStats збирає кількість посилань на спільні бекенди та фіксує помилки, якщо виявлено порушення вимог до namespace.
16
-
17
- analyzeAbieSharedBackendRefsInPackageK8s збирає статистику щодо посилань на спільні бекенди та помилки щодо namespace з базових YAML-документів пакета, виключаючи оверлей `ua`.
12
+ analyzeAbieSharedBackendRefsInPackageK8s
13
+ Збирає кількість посилань на спільні бекенди та порушення вимог до namespace у базових документах HTTPRoute пакета.
18
14
 
19
15
  ## Публічний API
20
16
 
21
- - ABIE_SHARED_CROSS_NS_BACKEND_NAMES — Ідентифікація назв бекендів, спільних між різними просторами імен.
22
- - analyzeAbieSharedBackendRefsInPackageK8s — Аналізує YAML-файли пакета, збираючи кількість спільних посилань на бекенди та виявляючи базові помилки.
17
+ ABIE_SHARED_CROSS_NS_BACKEND_NAMES — Формує імена для крос-нішових зв'язків між бекендами. (abie.mdc)
18
+
19
+ analyzeAbieSharedBackendRefsInPackageK8s — Збирає кількість спільних посилань `backendRefs` та базові помилки з YAML-файлів пакета, ігноруючи неймспейс `dev`. (abie.mdc)
23
20
 
24
21
  ## Гарантії поведінки
25
22
 
26
- * Функція повертає підрахунок `backendRefs` для спільних сервісів.
27
- * Підрахунок здійснюється у base-маніфестах пакета поза overlay `ua`.
28
- * Використовується `ua_http_route_concern` для синхронізації кількості patch-ів namespace у overlay із кількістю base-reference.
29
- * Функція є read-only.
30
- * Функція не виконує операцій з мережею.
31
- * Функція не використовує кешування.
32
- * Функція не змінює стан системи.
23
+ - Read-only: файл не виконує операцій запису у файлову систему.
24
+ - Не звертається до мережі.
@@ -0,0 +1,95 @@
1
+ /**
2
+ * A/B: docgen Tier 1 через pi cli (з omlx-провайдером у ~/.pi/agent/models.json)
3
+ * vs прямий callOmlxMessages (`N_CURSOR_DOCGEN_BACKEND=omlx`).
4
+ *
5
+ * Однаковий 8-сет файлів, однаковий оркестратор (E1+E2+E3+E4), різний backend.
6
+ * Пише в /tmp/docgen-compare/{pi,direct}/<idx>-<stem>.md і збирає метрики.
7
+ *
8
+ * Запуск: node npm/skills/docgen/js/docgen-compare-pi-vs-direct.mjs [--from N] [--limit N]
9
+ */
10
+ import { readFileSync, mkdirSync, writeFileSync, existsSync } from 'node:fs'
11
+ import { join, resolve, basename } from 'node:path'
12
+ import { fileURLToPath } from 'node:url'
13
+ import { execSync } from 'node:child_process'
14
+ import { env } from 'node:process'
15
+ import { generateDoc } from './docgen-gen.mjs'
16
+ import { extractFacts } from './docgen-extract.mjs'
17
+
18
+ const ROOT = resolve(fileURLToPath(import.meta.url), '../../../../..')
19
+ const TMP = '/tmp/docgen-compare'
20
+
21
+ const args = process.argv.slice(2)
22
+ const limitIdx = args.indexOf('--limit')
23
+ const limit = limitIdx !== -1 ? Number(args[limitIdx + 1]) : 8
24
+ const fromIdx = args.indexOf('--from')
25
+ const from = fromIdx !== -1 ? Number(args[fromIdx + 1]) : 1
26
+
27
+ const scanOut = execSync('node npm/bin/n-cursor.js docgen scan', { cwd: ROOT, encoding: 'utf8' })
28
+ const all = JSON.parse(scanOut)
29
+
30
+ const local = []
31
+ for (const f of all) {
32
+ try {
33
+ const src = readFileSync(join(ROOT, f.sourcePath), 'utf8')
34
+ const facts = extractFacts(src, join(ROOT, f.sourcePath))
35
+ const sym = (facts.internalSymbols ?? []).length
36
+ if (sym < 4) local.push({ ...f, sym })
37
+ } catch {}
38
+ }
39
+ const slice = local.slice(from, from + limit)
40
+
41
+ mkdirSync(join(TMP, 'pi'), { recursive: true })
42
+ mkdirSync(join(TMP, 'direct'), { recursive: true })
43
+
44
+ async function runBackendAsync(kind) {
45
+ if (kind === 'direct') env.N_CURSOR_DOCGEN_BACKEND = 'omlx'
46
+ else delete env.N_CURSOR_DOCGEN_BACKEND
47
+ const out = { ok: 0, err: 0, totalMs: 0, scores: [], lengths: [], errors: [], times: [] }
48
+ console.log(`\n══════ Backend: ${kind} ══════`)
49
+ for (let i = 0; i < slice.length; i++) {
50
+ const f = slice[i]
51
+ const t0 = Date.now()
52
+ const stem = basename(f.sourcePath).replace(/\.[^.]+$/, '')
53
+ const destFile = join(TMP, kind, `${String(i + 1).padStart(2, '0')}-${stem}.md`)
54
+ process.stdout.write(` [${i + 1}/${slice.length}] sym=${f.sym} ${f.sourcePath} ... `)
55
+ try {
56
+ const r = await generateDoc(join(ROOT, f.sourcePath), { symThreshold: 999, cloudModel: null })
57
+ writeFileSync(destFile, r.md)
58
+ const ms = Date.now() - t0
59
+ out.ok++
60
+ out.totalMs += ms
61
+ out.times.push(ms)
62
+ out.scores.push(r.score ?? 0)
63
+ out.lengths.push(r.md.length)
64
+ process.stdout.write(`✓ ${Math.round(ms / 1000)}s score=${r.score ?? '?'} chars=${r.md.length}\n`)
65
+ } catch (error) {
66
+ out.err++
67
+ out.errors.push({ path: f.sourcePath, msg: error.message })
68
+ process.stdout.write(`✗ ${error.message}\n`)
69
+ }
70
+ }
71
+ return out
72
+ }
73
+
74
+ const direct = await runBackendAsync('direct')
75
+ const pi = await runBackendAsync('pi')
76
+
77
+ function avg(a) { return a.length ? Math.round(a.reduce((x, y) => x + y, 0) / a.length) : 0 }
78
+ function median(a) {
79
+ if (!a.length) return 0
80
+ const s = [...a].sort((x, y) => x - y)
81
+ return s[Math.floor(s.length / 2)]
82
+ }
83
+
84
+ const report = {
85
+ files: slice.map(f => f.sourcePath),
86
+ direct: { ok: direct.ok, err: direct.err, avgMs: avg(direct.times), medianMs: median(direct.times), avgScore: avg(direct.scores), avgChars: avg(direct.lengths), totalSec: Math.round(direct.totalMs / 1000) },
87
+ pi: { ok: pi.ok, err: pi.err, avgMs: avg(pi.times), medianMs: median(pi.times), avgScore: avg(pi.scores), avgChars: avg(pi.lengths), totalSec: Math.round(pi.totalMs / 1000) }
88
+ }
89
+ writeFileSync(join(TMP, 'report.json'), JSON.stringify(report, null, 2))
90
+
91
+ console.log(`\n${'─'.repeat(60)}\nA/B SUMMARY (${slice.length} файлів, той самий оркестратор)\n${'─'.repeat(60)}`)
92
+ console.log(`Backend | ok | err | avg s | median s | avg score | avg chars | total s`)
93
+ console.log(`direct (curl) | ${direct.ok} | ${direct.err} | ${Math.round(report.direct.avgMs / 1000)} | ${Math.round(report.direct.medianMs / 1000)} | ${report.direct.avgScore} | ${report.direct.avgChars} | ${report.direct.totalSec}`)
94
+ console.log(`pi cli | ${pi.ok} | ${pi.err} | ${Math.round(report.pi.avgMs / 1000)} | ${Math.round(report.pi.medianMs / 1000)} | ${report.pi.avgScore} | ${report.pi.avgChars} | ${report.pi.totalSec}`)
95
+ console.log(`\nФайли: ${TMP}/{direct,pi}/<idx>-<stem>.md\nReport: ${TMP}/report.json`)