@nitra/cursor 12.11.2 → 12.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/bin/n-cursor.js +5 -37
  3. package/package.json +1 -1
  4. package/rules/bun/docs/index.md +2 -2
  5. package/rules/bun/docs/main.md +8 -9
  6. package/rules/bun/js/docs/index.md +3 -2
  7. package/rules/bun/main.json +1 -1
  8. package/rules/bun/main.mdc +3 -1
  9. package/rules/bun/main.mjs +63 -3
  10. package/rules/changelog/js/docs/index.md +3 -2
  11. package/rules/ci4/main.mdc +1 -0
  12. package/rules/ci4/policy/vscode_extensions/docs/index.md +11 -0
  13. package/rules/ga/main.mdc +9 -1
  14. package/rules/ga/policy/vscode_extensions/docs/index.md +11 -0
  15. package/rules/graphql/policy/vscode_extensions/docs/index.md +11 -0
  16. package/rules/js/js/dep-policy.mdc +19 -0
  17. package/rules/js/js/dep-policy.mjs +14 -6
  18. package/rules/js/js/docs/index.md +5 -5
  19. package/rules/js/main.mdc +4 -0
  20. package/rules/js/policy/vscode_extensions/docs/index.md +11 -0
  21. package/rules/js-run/js/docs/index.md +3 -2
  22. package/rules/js-run/main.mdc +3 -0
  23. package/rules/nginx-default-tpl/policy/vscode_extensions/docs/index.md +11 -0
  24. package/rules/npm-module/main.mdc +4 -0
  25. package/rules/python/docs/index.md +2 -2
  26. package/rules/python/docs/main.md +13 -10
  27. package/rules/python/main.mjs +43 -0
  28. package/rules/rego/main.mdc +2 -0
  29. package/rules/rego/policy/vscode_extensions/docs/index.md +11 -0
  30. package/rules/rust/docs/index.md +2 -2
  31. package/rules/rust/docs/main.md +10 -7
  32. package/rules/rust/main.json +1 -1
  33. package/rules/rust/main.mjs +23 -1
  34. package/rules/rust/policy/vscode_extensions/docs/index.md +11 -0
  35. package/rules/security/main.mdc +2 -0
  36. package/rules/style/js/docs/index.md +3 -2
  37. package/rules/style/main.mdc +5 -1
  38. package/rules/style/policy/vscode_extensions/docs/index.md +11 -0
  39. package/rules/tauri/policy/vscode_extensions/docs/index.md +11 -0
  40. package/rules/test/main.mdc +2 -1
  41. package/rules/text/main.mdc +9 -0
  42. package/rules/text/policy/vscode_extensions/docs/index.md +11 -0
  43. package/scripts/docs/index.md +14 -13
  44. package/scripts/docs/update-blue-oak.md +28 -0
  45. package/scripts/lib/blue-oak.mjs +45 -0
  46. package/scripts/lib/docs/blue-oak.md +29 -0
  47. package/scripts/lib/docs/index.md +35 -35
  48. package/scripts/lib/docs/run-rule.md +8 -6
  49. package/scripts/lib/fix/docs/index.md +12 -10
  50. package/scripts/lib/fix/docs/t0.md +7 -7
  51. package/scripts/lib/fix/t0.mjs +1 -2
  52. package/scripts/lib/run-rule.mjs +0 -11
  53. package/scripts/update-blue-oak.mjs +51 -0
  54. package/skills/doc-aggregate/SKILL.md +8 -18
  55. package/skills/doc-aggregate/js/docs/index.md +0 -1
  56. package/scripts/lib/check-mdc-template-refs.mjs +0 -57
  57. package/scripts/lib/docs/check-mdc-template-refs.md +0 -22
  58. package/skills/doc-aggregate/js/docgen-scan.mjs +0 -195
  59. package/skills/doc-aggregate/js/docs/docgen-scan.md +0 -76
@@ -0,0 +1,11 @@
1
+ ---
2
+ type: Directory Index
3
+ title: npm/rules/rego/policy/vscode_extensions
4
+ resource: npm/rules/rego/policy/vscode_extensions/
5
+ ---
6
+
7
+ # npm/rules/rego/policy/vscode_extensions
8
+
9
+ | Файл | Тип |
10
+ | ----------------------------------------------------- | --------- |
11
+ | [fix-vscode_extensions.mjs](fix-vscode_extensions.md) | JS Module |
@@ -6,6 +6,6 @@ resource: npm/rules/rust/
6
6
 
7
7
  # npm/rules/rust
8
8
 
9
- | Файл | Тип |
10
- | ------------------- | --------- |
9
+ | Файл | Тип |
10
+ |---|---|
11
11
  | [main.mjs](main.md) | JS Module |
@@ -3,23 +3,26 @@ type: JS Module
3
3
  title: main.mjs
4
4
  resource: npm/rules/rust/main.mjs
5
5
  docgen:
6
- crc: 93c44fd7
6
+ crc: bbddef51
7
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
8
  score: 100
9
9
  ---
10
10
 
11
- Модуль надає інструменти для забезпечення якості коду Rust. Він дозволяє виконати перевірку коду на відповідність заданим Lint-правилам або запустити повну оркестрацію форматування та аналізу коду через `cargo`. Функціонал реалізується через публічні функції `run` та `lint`.
11
+ ## Огляд
12
+
13
+ Модуль надає інструменти для забезпечення якості коду на Rust. Він дозволяє виконати перевірку стилю за допомогою функції `lint` або запустити повну оркестрацію, що включає форматування та аналіз, за допомогою функції `run`. (rust.mdc)
12
14
 
13
15
  ## Поведінка
14
16
 
15
- run виконує перевірку коду Rust відповідно до політик.
16
- lint запускає оркестрацію перевірки коду Rust, використовуючи `cargo` для виконання `rustfmt` та `clippy`.
17
+ run виконує стандартну перевірку для Rust-коду.
18
+
19
+ lint запускає оркестрацію перевірки Rust-коду, включаючи форматування та аналіз.
17
20
 
18
21
  ## Публічний API
19
22
 
20
- run — виконує основну логіку правила, включаючи перевірку аспектів застосування, логіки та посилань.
21
- lint — забезпечує точку входу для статичного аналізу коду Rust.
23
+ run — виконує основну перевірку, що включає перевірку логіки, пов'язаної з JS, політики та посиланнями MDC (rust.mdc).
24
+ lint — забезпечує фіксацію та виконання перевірок стилю коду (аналогічно cargo fmt/clippy) для `n-cursor lint rust`.
22
25
 
23
26
  ## Гарантії поведінки
24
27
 
25
- - Read-only: не виконує операцій запису (ФС/БД).
28
+ - (специфічних машинно-виведених гарантій немає)
@@ -1 +1 @@
1
- { "auto": { "glob": "**/Cargo.toml" }, "lint": "full" }
1
+ { "auto": { "glob": ["**/Cargo.toml", "deny.toml"] }, "lint": "full" }
@@ -1,6 +1,6 @@
1
1
  /** @see ./docs/lint.md */
2
2
  import { spawnSync } from 'node:child_process'
3
- import { existsSync } from 'node:fs'
3
+ import { existsSync, writeFileSync } from 'node:fs'
4
4
  import { join } from 'node:path'
5
5
 
6
6
  import { createCheckReporter } from '../../scripts/lib/check-reporter.mjs'
@@ -8,6 +8,7 @@ import { runStandardLint } from '../../scripts/lib/run-standard-lint.mjs'
8
8
  import { resolveCmd } from '../../scripts/utils/resolve-cmd.mjs'
9
9
  import { isRunAsCli, runRuleCli } from '../../scripts/lib/run-rule-cli.mjs'
10
10
  import { runStandardRule } from '../../scripts/lib/run-standard-rule.mjs'
11
+ import { generateDenyTomlLicenses } from '../../scripts/lib/blue-oak.mjs'
11
12
 
12
13
  /**
13
14
  * Єдиний entrypoint правила (ADR 2026-06-21). `run()` — check-поверхня (applies → JS-concerns
@@ -82,6 +83,27 @@ function runRustLint(cwd = process.cwd(), opts = {}) {
82
83
  pass,
83
84
  fail
84
85
  )
86
+
87
+ // cargo deny check licenses: fix-режим — auto-генерує deny.toml якщо відсутній;
88
+ // readOnly (CI) — відсутність файлу → fail.
89
+ const denyConfigPath = join(cwd, 'deny.toml')
90
+ if (!existsSync(denyConfigPath)) {
91
+ if (readOnly) {
92
+ fail('lint-rust: cargo deny — немає deny.toml; запустіть `npx @nitra/cursor fix rust` локально для генерації (rust.mdc)')
93
+ } else {
94
+ writeFileSync(denyConfigPath, generateDenyTomlLicenses(), 'utf8')
95
+ pass('lint-rust: cargo deny — створено deny.toml з дефолтним allowlist')
96
+ }
97
+ }
98
+ if (existsSync(denyConfigPath)) {
99
+ const hasDeny = spawnSync(cargo, ['deny', '--version'], { stdio: 'ignore', shell: false }).status === 0
100
+ if (hasDeny) {
101
+ runCargo('cargo deny check licenses', cargo, ['deny', 'check', 'licenses'], pass, fail)
102
+ } else {
103
+ pass('lint-rust: cargo deny — не встановлений (cargo install cargo-deny), перевірку ліцензій пропущено')
104
+ }
105
+ }
106
+
85
107
  return reporter.getExitCode()
86
108
  }
87
109
 
@@ -0,0 +1,11 @@
1
+ ---
2
+ type: Directory Index
3
+ title: npm/rules/rust/policy/vscode_extensions
4
+ resource: npm/rules/rust/policy/vscode_extensions/
5
+ ---
6
+
7
+ # npm/rules/rust/policy/vscode_extensions
8
+
9
+ | Файл | Тип |
10
+ | ----------------------------------------------------- | --------- |
11
+ | [fix-vscode_extensions.mjs](fix-vscode_extensions.md) | JS Module |
@@ -9,3 +9,5 @@ version: '2.1'
9
9
  ## Перевірка
10
10
 
11
11
  `npx @nitra/cursor fix security`
12
+ - [lint-security.yml.snippet.yml](./policy/lint_security_yml/template/lint-security.yml.snippet.yml)
13
+ - [package.json.deny.json](./policy/package_json/template/package.json.deny.json)
@@ -6,6 +6,7 @@ resource: npm/rules/style/js/
6
6
 
7
7
  # npm/rules/style/js
8
8
 
9
- | Файл | Тип |
10
- | ------------------------- | --------- |
9
+ | Файл | Тип |
10
+ |---|---|
11
+ | [fix-tooling.mjs](fix-tooling.md) | JS Module |
11
12
  | [tooling.mjs](tooling.md) | JS Module |
@@ -5,4 +5,8 @@ globs: "**/*.{css,scss,vue}"
5
5
  alwaysApply: false
6
6
  ---
7
7
 
8
- Правило **style** для Vue-проєктів: Quasar як стильова система, SCSS-конвенції кольорів і відступів, фікси компонентів, stylelint через `@nitra/stylelint-config`.
8
+ Правило **style** для Vue-проєктів: Quasar як стильова система, SCSS-конвенції кольорів і відступів, фікси компонентів, stylelint через `@nitra/stylelint-config`.
9
+ - [settings.json.snippet.json](./policy/vscode_settings/template/settings.json.snippet.json)
10
+ - [lint-style.yml.snippet.yml](./policy/lint_style_yml/template/lint-style.yml.snippet.yml)
11
+ - [extensions.json.snippet.json](./policy/vscode_extensions/template/extensions.json.snippet.json)
12
+ - [package.json.snippet.json](./policy/package_json/template/package.json.snippet.json)
@@ -0,0 +1,11 @@
1
+ ---
2
+ type: Directory Index
3
+ title: npm/rules/style/policy/vscode_extensions
4
+ resource: npm/rules/style/policy/vscode_extensions/
5
+ ---
6
+
7
+ # npm/rules/style/policy/vscode_extensions
8
+
9
+ | Файл | Тип |
10
+ | ----------------------------------------------------- | --------- |
11
+ | [fix-vscode_extensions.mjs](fix-vscode_extensions.md) | JS Module |
@@ -0,0 +1,11 @@
1
+ ---
2
+ type: Directory Index
3
+ title: npm/rules/tauri/policy/vscode_extensions
4
+ resource: npm/rules/tauri/policy/vscode_extensions/
5
+ ---
6
+
7
+ # npm/rules/tauri/policy/vscode_extensions
8
+
9
+ | Файл | Тип |
10
+ | ----------------------------------------------------- | --------- |
11
+ | [fix-vscode_extensions.mjs](fix-vscode_extensions.md) | JS Module |
@@ -19,4 +19,5 @@ alwaysApply: false
19
19
 
20
20
  ### Multi-workspace iteration
21
21
 
22
- У monorepo `n-cursor coverage` ітерує усі workspaces з власним `package.json` і агрегує метрики lcov + Stryker у єдиний `JS`-рядок `COVERAGE.md`. Workspace без тестів пропускається без помилки.
22
+ У monorepo `n-cursor coverage` ітерує усі workspaces з власним `package.json` і агрегує метрики lcov + Stryker у єдиний `JS`-рядок `COVERAGE.md`. Workspace без тестів пропускається без помилки.
23
+ - [package.json.contains.json](./policy/package_json/template/package.json.contains.json)
@@ -10,3 +10,12 @@ version: '1.30'
10
10
 
11
11
  Rego-пакети, що перевіряються через conftest (auto-discovered за `target.json` поряд із `.rego`):
12
12
 
13
+ - [settings.json.snippet.json](./policy/vscode_settings/template/settings.json.snippet.json)
14
+ - [.oxfmtrc.json.snippet.json](./policy/oxfmtrc/template/.oxfmtrc.json.snippet.json)
15
+ - [.markdownlint-cli2.jsonc.snippet.jsonc](./policy/markdownlint/template/.markdownlint-cli2.jsonc.snippet.jsonc)
16
+ - [.cspell.json.snippet.json](./policy/cspell/template/.cspell.json.snippet.json)
17
+ - [.cspell.json.deny.json](./policy/cspell/template/.cspell.json.deny.json)
18
+ - [.cspell.json.contains.json](./policy/cspell/template/.cspell.json.contains.json)
19
+ - [extensions.json.snippet.json](./policy/vscode_extensions/template/extensions.json.snippet.json)
20
+ - [lint-text.yml.snippet.yml](./policy/lint_text/template/lint-text.yml.snippet.yml)
21
+ - [package.json.deny.json](./policy/package_json/template/package.json.deny.json)
@@ -0,0 +1,11 @@
1
+ ---
2
+ type: Directory Index
3
+ title: npm/rules/text/policy/vscode_extensions
4
+ resource: npm/rules/text/policy/vscode_extensions/
5
+ ---
6
+
7
+ # npm/rules/text/policy/vscode_extensions
8
+
9
+ | Файл | Тип |
10
+ | ----------------------------------------------------- | --------- |
11
+ | [fix-vscode_extensions.mjs](fix-vscode_extensions.md) | JS Module |
@@ -6,17 +6,18 @@ resource: npm/scripts/
6
6
 
7
7
  # npm/scripts
8
8
 
9
- | Файл | Тип |
10
- | ----------------------------------------------------------------------------------- | --------- |
11
- | [auto-rules.mjs](auto-rules.md) | JS Module |
12
- | [auto-skills.mjs](auto-skills.md) | JS Module |
13
- | [build-agents-commands.mjs](build-agents-commands.md) | JS Module |
14
- | [cli-entry.mjs](cli-entry.md) | JS Module |
9
+ | Файл | Тип |
10
+ |---|---|
11
+ | [auto-rules.mjs](auto-rules.md) | JS Module |
12
+ | [auto-skills.mjs](auto-skills.md) | JS Module |
13
+ | [build-agents-commands.mjs](build-agents-commands.md) | JS Module |
14
+ | [cli-entry.mjs](cli-entry.md) | JS Module |
15
15
  | [ensure-nitra-cursor-dev-dependencies.mjs](ensure-nitra-cursor-dev-dependencies.md) | JS Module |
16
- | [hook.mjs](hook.md) | JS Module |
17
- | [post-tool-use-check.mjs](post-tool-use-check.md) | JS Module |
18
- | [rename-yaml-extensions.mjs](rename-yaml-extensions.md) | JS Module |
19
- | [skills-cli.mjs](skills-cli.md) | JS Module |
20
- | [sync-claude-config.mjs](sync-claude-config.md) | JS Module |
21
- | [sync-setup-bun-deps-action.mjs](sync-setup-bun-deps-action.md) | JS Module |
22
- | [upgrade-nitra-cursor-and-install.mjs](upgrade-nitra-cursor-and-install.md) | JS Module |
16
+ | [hook.mjs](hook.md) | JS Module |
17
+ | [post-tool-use-check.mjs](post-tool-use-check.md) | JS Module |
18
+ | [rename-yaml-extensions.mjs](rename-yaml-extensions.md) | JS Module |
19
+ | [skills-cli.mjs](skills-cli.md) | JS Module |
20
+ | [sync-claude-config.mjs](sync-claude-config.md) | JS Module |
21
+ | [sync-setup-bun-deps-action.mjs](sync-setup-bun-deps-action.md) | JS Module |
22
+ | [update-blue-oak.mjs](update-blue-oak.md) | JS Module |
23
+ | [upgrade-nitra-cursor-and-install.mjs](upgrade-nitra-cursor-and-install.md) | JS Module |
@@ -0,0 +1,28 @@
1
+ ---
2
+ type: JS Module
3
+ title: update-blue-oak.mjs
4
+ resource: npm/scripts/update-blue-oak.mjs
5
+ docgen:
6
+ crc: f818f73b
7
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
+ score: 95
9
+ ---
10
+
11
+ ## Огляд
12
+
13
+ Оновлює вбудований список ліцензій Blue Oak Council, отримуючи дані з https://blueoakcouncil.org/list.json. Витягує SPDX-ідентифікатори ліцензій рівнів Model, Gold, Silver та Bronze і зберігає їх у npm/data/blue-oak.json. Цей процес запускається вручну у середовищі @nitra/cursor командою bun npm/scripts/update-blue-oak.mjs. Оновлення відбувається рідко, але нові permissive ліцензії з'являються раз на кілька місяців. Lead-рівень (найгірший, GPL-compatible) навмисно виключений.
14
+
15
+ ## Поведінка
16
+
17
+ 1. Завантажує дані з https://blueoakcouncil.org/list.json.
18
+ 2. Перевіряє успішність отримання даних. У разі невдачі зупиняє виконання.
19
+ 3. Парсить отриманий JSON-відповідь.
20
+ 4. Ітерує по рейтингах у даних.
21
+ 5. Для кожного рейтингу перевіряє, чи належить він до рівнів Model, Gold, Silver або Bronze.
22
+ 6. Якщо рейтинг відповідає критеріям, витягує всі SPDX-ідентифікатори ліцензій, пов'язані з цим рейтингом, та додає їх до списку.
23
+ 7. Формує об'єкт, що містить версію даних та зібраний список SPDX-ідентифікаторів.
24
+ 8. Зберігає цей об'єкт у файл blue-oak.json у каталозі data.
25
+
26
+ ## Гарантії поведінки
27
+
28
+ - (специфічних машинно-виведених гарантій немає)
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Читає вбудований Blue Oak Council snapshot (`npm/data/blue-oak.json`).
3
+ * Повертає множину SPDX-ідентифікаторів рівнів Model+Gold+Silver+Bronze.
4
+ */
5
+ import { readFileSync } from 'node:fs'
6
+ import { dirname, join } from 'node:path'
7
+ import { fileURLToPath } from 'node:url'
8
+
9
+ const DATA_PATH = join(dirname(dirname(dirname(fileURLToPath(import.meta.url)))), 'data', 'blue-oak.json')
10
+
11
+ /**
12
+ * Множина SPDX-ідентифікаторів Blue Oak Bronze і вище (Model+Gold+Silver+Bronze).
13
+ * Ліцензії з цього списку вважаються permissive-safe для комерційного проєкту.
14
+ * @returns {Set<string>}
15
+ */
16
+ export function getBronzeAndAbove() {
17
+ const { bronzeAndAbove } = JSON.parse(readFileSync(DATA_PATH, 'utf8'))
18
+ return new Set(bronzeAndAbove)
19
+ }
20
+
21
+ /**
22
+ * Генерує TOML-рядок `[licenses]` для `deny.toml` (cargo-deny) на основі Blue Oak Bronze+.
23
+ * @returns {string}
24
+ */
25
+ export function generateDenyTomlLicenses() {
26
+ const ids = [...getBronzeAndAbove()].toSorted()
27
+ const lines = ids.map(id => ` "${id}",`).join('\n')
28
+ return `[licenses]\nallow = [\n${lines}\n]\n`
29
+ }
30
+
31
+ /**
32
+ * Перевіряє SPDX-вираз проти Blue Oak Bronze+ allowlist.
33
+ * Підтримує: одиночний ID, `A OR B` (будь-який дозволений = OK), `A AND B` (усі мають бути дозволені).
34
+ * `NOASSERTION` і `NONE` завжди → false.
35
+ * @param {string} expression SPDX-вираз з pip-licenses або іншого інструмента
36
+ * @param {Set<string>} allowed множина дозволених SPDX-ідентифікаторів
37
+ * @returns {boolean}
38
+ */
39
+ export function isSpdxAllowed(expression, allowed) {
40
+ if (!expression || expression === 'NOASSERTION' || expression === 'NONE') return false
41
+ const clean = s => s.trim().replace(/^\(|\)$/g, '')
42
+ if (expression.includes(' AND ')) return expression.split(' AND ').every(p => allowed.has(clean(p)))
43
+ if (expression.includes(' OR ')) return expression.split(' OR ').some(p => allowed.has(clean(p)))
44
+ return allowed.has(clean(expression))
45
+ }
@@ -0,0 +1,29 @@
1
+ ---
2
+ type: JS Module
3
+ title: blue-oak.mjs
4
+ resource: npm/scripts/lib/blue-oak.mjs
5
+ docgen:
6
+ crc: 9039e57f
7
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
+ score: 100
9
+ ---
10
+
11
+ ## Огляд
12
+
13
+ Модуль читає конфігурацію Blue Oak Council (`blue-oak.json`) для визначення дозволених рівнів SPDX. Він повертає множину SPDX-ідентифікаторів рівнів Model, Gold, Silver та Bronze. Модуль також генерує правила заборони ліцензій у форматі TOML та перевіряє відповідність будь-якого SPDX-ідентифікатора цьому списку.
14
+
15
+ ## Поведінка
16
+
17
+ getBronzeAndAbove повертає множину SPDX-ідентифікаторів рівнів Model+Gold+Silver+Bronze, які беруться з конфігурації blue-oak.json.
18
+ generateDenyTomlLicenses генерує TOML-рядок для `deny.toml` (cargo-deny), дозволяючи лише SPDX-ідентифікатори, що знаходяться у множині Blue Oak Bronze+.
19
+ isSpdxAllowed перевіряє, чи відповідає наданий SPDX-вираз дозволеним ідентифікаторам, враховуючи логічні оператори `AND` та `OR`.
20
+
21
+ ## Публічний API
22
+
23
+ getBronzeAndAbove — Визначає набір SPDX-ідентифікаторів (Model, Gold, Silver, Bronze), які вважаються безпечними для комерційного використання.
24
+ generateDenyTomlLicenses — Створює конфігураційний рядок TOML для файлу `deny.toml`, що забороняє використання ліцензій нижче рівня Blue Oak Bronze.
25
+ isSpdxAllowed — Визначає, чи відповідає заданий SPDX-ідентифікатор дозволеному списку Blue Oak Bronze+ згідно з логікою (одиночний ID, `A OR B`, `A AND B`).
26
+
27
+ ## Гарантії поведінки
28
+
29
+ - Read-only: не виконує операцій запису (ФС/БД).
@@ -6,39 +6,39 @@ resource: npm/scripts/lib/
6
6
 
7
7
  # npm/scripts/lib
8
8
 
9
- | Файл | Тип |
10
- | --------------------------------------------------------------------------- | --------- |
11
- | [assert-project-root.mjs](assert-project-root.md) | JS Module |
12
- | [changed-files.mjs](changed-files.md) | JS Module |
13
- | [check-mdc-template-refs.mjs](check-mdc-template-refs.md) | JS Module |
14
- | [check-reporter.mjs](check-reporter.md) | JS Module |
15
- | [diff-added-lines.mjs](diff-added-lines.md) | JS Module |
9
+ | Файл | Тип |
10
+ |---|---|
11
+ | [assert-project-root.mjs](assert-project-root.md) | JS Module |
12
+ | [blue-oak.mjs](blue-oak.md) | JS Module |
13
+ | [changed-files.mjs](changed-files.md) | JS Module |
14
+ | [check-reporter.mjs](check-reporter.md) | JS Module |
15
+ | [diff-added-lines.mjs](diff-added-lines.md) | JS Module |
16
16
  | [discover-check-rules-from-cursor.mjs](discover-check-rules-from-cursor.md) | JS Module |
17
- | [discover-checkable-rules.mjs](discover-checkable-rules.md) | JS Module |
18
- | [ensure-tool.mjs](ensure-tool.md) | JS Module |
19
- | [generated-markdown.mjs](generated-markdown.md) | JS Module |
20
- | [gha-workflow.mjs](gha-workflow.md) | JS Module |
21
- | [inline-template-links.mjs](inline-template-links.md) | JS Module |
22
- | [list-project-rules-mdc.mjs](list-project-rules-mdc.md) | JS Module |
23
- | [list-rule-ids.mjs](list-rule-ids.md) | JS Module |
24
- | [load-cursor-config.mjs](load-cursor-config.md) | JS Module |
25
- | [mirror-parity.mjs](mirror-parity.md) | JS Module |
26
- | [read-n-cursor-config-lite.mjs](read-n-cursor-config-lite.md) | JS Module |
27
- | [resolve-target-files.mjs](resolve-target-files.md) | JS Module |
28
- | [root-notice.mjs](root-notice.md) | JS Module |
29
- | [rule-meta-helpers.mjs](rule-meta-helpers.md) | JS Module |
30
- | [rule-meta.mjs](rule-meta.md) | JS Module |
31
- | [rule-predicates.mjs](rule-predicates.md) | JS Module |
32
- | [run-conftest-batch.mjs](run-conftest-batch.md) | JS Module |
33
- | [run-lint-step.mjs](run-lint-step.md) | JS Module |
34
- | [run-lint.mjs](run-lint.md) | JS Module |
35
- | [run-rule-cli.mjs](run-rule-cli.md) | JS Module |
36
- | [run-rule.mjs](run-rule.md) | JS Module |
37
- | [run-standard-lint.mjs](run-standard-lint.md) | JS Module |
38
- | [run-standard-rule.mjs](run-standard-rule.md) | JS Module |
39
- | [skill-meta.mjs](skill-meta.md) | JS Module |
40
- | [sync-gitignore-worktree.mjs](sync-gitignore-worktree.md) | JS Module |
41
- | [template.mjs](template.md) | JS Module |
42
- | [timing-summary.mjs](timing-summary.md) | JS Module |
43
- | [workspaces.mjs](workspaces.md) | JS Module |
44
- | [worktree-notice.mjs](worktree-notice.md) | JS Module |
17
+ | [discover-checkable-rules.mjs](discover-checkable-rules.md) | JS Module |
18
+ | [ensure-tool.mjs](ensure-tool.md) | JS Module |
19
+ | [generated-markdown.mjs](generated-markdown.md) | JS Module |
20
+ | [gha-workflow.mjs](gha-workflow.md) | JS Module |
21
+ | [inline-template-links.mjs](inline-template-links.md) | JS Module |
22
+ | [list-project-rules-mdc.mjs](list-project-rules-mdc.md) | JS Module |
23
+ | [list-rule-ids.mjs](list-rule-ids.md) | JS Module |
24
+ | [load-cursor-config.mjs](load-cursor-config.md) | JS Module |
25
+ | [mirror-parity.mjs](mirror-parity.md) | JS Module |
26
+ | [read-n-cursor-config-lite.mjs](read-n-cursor-config-lite.md) | JS Module |
27
+ | [resolve-target-files.mjs](resolve-target-files.md) | JS Module |
28
+ | [root-notice.mjs](root-notice.md) | JS Module |
29
+ | [rule-meta-helpers.mjs](rule-meta-helpers.md) | JS Module |
30
+ | [rule-meta.mjs](rule-meta.md) | JS Module |
31
+ | [rule-predicates.mjs](rule-predicates.md) | JS Module |
32
+ | [run-conftest-batch.mjs](run-conftest-batch.md) | JS Module |
33
+ | [run-lint-step.mjs](run-lint-step.md) | JS Module |
34
+ | [run-lint.mjs](run-lint.md) | JS Module |
35
+ | [run-rule-cli.mjs](run-rule-cli.md) | JS Module |
36
+ | [run-rule.mjs](run-rule.md) | JS Module |
37
+ | [run-standard-lint.mjs](run-standard-lint.md) | JS Module |
38
+ | [run-standard-rule.mjs](run-standard-rule.md) | JS Module |
39
+ | [skill-meta.mjs](skill-meta.md) | JS Module |
40
+ | [sync-gitignore-worktree.mjs](sync-gitignore-worktree.md) | JS Module |
41
+ | [template.mjs](template.md) | JS Module |
42
+ | [timing-summary.mjs](timing-summary.md) | JS Module |
43
+ | [workspaces.mjs](workspaces.md) | JS Module |
44
+ | [worktree-notice.mjs](worktree-notice.md) | JS Module |
@@ -3,23 +3,25 @@ type: JS Module
3
3
  title: run-rule.mjs
4
4
  resource: npm/scripts/lib/run-rule.mjs
5
5
  docgen:
6
- crc: c9b164c7
6
+ crc: 500c35f6
7
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
8
  score: 100
9
9
  ---
10
10
 
11
- Файл оркеструє виконання одного правила під CLI `fix`. Він послідовно застосовує `applies`-гейт, а потім виконує JS-концерни та Policy-концерни. Резолвер ділить кеш між концернами, а кожен concern має власний механізм звітності, що об'єднується в єдиний exit-код правила. Процес спирається на конфігураційні файли, зокрема `target.json` та `.n-cursor.json`.
11
+ ## Огляд
12
+
13
+ Оркестратор виконує логіку одного правила під CLI `fix`. Він послідовно застосовує фільтр застосовності з `js/applies.mjs`. Далі виконуються JS-концерни для перевірки, а потім запускаються Policy-концерни, що зчитують конфігурації з `target.json` та `.n-cursor.json`. Резолвер ділить кеш між концернами, а їхні коди виходу об'єднуються в єдиний результат правила.
12
14
 
13
15
  ## Поведінка
14
16
 
15
- runTemplateSubsetConcern виконує перевірку концерну, де канон визначено у `target.json` як `template`, звіряючи вміст файлів-таргетів з шаблоном, визначеним у відповідному каталозі.
17
+ runTemplateSubsetConcern виконує перевірку концерну, де канон (сніпет) береться з `template.json` та звіряється з вмістом актуальних файлів-таргетів, використовуючи логіку subset-of.
16
18
 
17
- runRule оркеструє виконання одного правила, послідовно застосовуючи `applies`-гейт, виконуючи JS-концерни, запускаючи policy-концерни та перевіряючи відсутність markdown-посилань у `main.mdc`.
19
+ runRule оркеструє виконання одного правила, послідовно застосовуючи applies-гейт, а потім виконуючи JS-концерни та policy-концерни, збираючи загальний exit-код.
18
20
 
19
21
  ## Публічний API
20
22
 
21
- runTemplateSubsetConcern — Порівнює фактичний файл з канонічним шаблоном (`target.json:"check":"template"`), визначаючи, чи всі обов'язкові елементи з шаблону присутні у файлі.
22
- runRule — Виконує окреме правило, перевіряючи його відповідність через гейт, JavaScript-концерни та політики.
23
+ runTemplateSubsetConcern — Порівнює фактичний файл з шаблоном, визначеним у `target.json`, перевіряючи, чи всі обов'язкові елементи з шаблону присутні у файлі.
24
+ runRule — Виконує окреме правило, яке проходить через етапи застосування, перевірки на JS-концерни та політики.
23
25
 
24
26
  ## Гарантії поведінки
25
27
 
@@ -6,14 +6,16 @@ resource: npm/scripts/lib/fix/
6
6
 
7
7
  # npm/scripts/lib/fix
8
8
 
9
- | Файл | Тип |
10
- | ----------------------------------------------------- | --------- |
11
- | [analyze-escalation.mjs](analyze-escalation.md) | JS Module |
12
- | [escalation-log.mjs](escalation-log.md) | JS Module |
13
- | [llm-fix-apply.mjs](llm-fix-apply.md) | JS Module |
14
- | [llm-lint-fix.mjs](llm-lint-fix.md) | JS Module |
15
- | [llm-worker.mjs](llm-worker.md) | JS Module |
16
- | [orchestrator.mjs](orchestrator.md) | JS Module |
9
+ | Файл | Тип |
10
+ |---|---|
11
+ | [analyze-escalation.mjs](analyze-escalation.md) | JS Module |
12
+ | [discover-t0-patterns.mjs](discover-t0-patterns.md) | JS Module |
13
+ | [escalation-log.mjs](escalation-log.md) | JS Module |
14
+ | [llm-fix-apply.mjs](llm-fix-apply.md) | JS Module |
15
+ | [llm-lint-fix.mjs](llm-lint-fix.md) | JS Module |
16
+ | [llm-worker.mjs](llm-worker.md) | JS Module |
17
+ | [orchestrator.mjs](orchestrator.md) | JS Module |
17
18
  | [run-conformance-check.mjs](run-conformance-check.md) | JS Module |
18
- | [t0.mjs](t0.md) | JS Module |
19
- | [verbose-block.mjs](verbose-block.md) | JS Module |
19
+ | [t0.mjs](t0.md) | JS Module |
20
+ | [verbose-block.mjs](verbose-block.md) | JS Module |
21
+ | [vscode-ext-add.mjs](vscode-ext-add.md) | JS Module |
@@ -3,25 +3,25 @@ type: JS Module
3
3
  title: t0.mjs
4
4
  resource: npm/scripts/lib/fix/t0.mjs
5
5
  docgen:
6
- crc: 92c9348d
6
+ crc: 4cee4f45
7
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
8
  score: 100
9
9
  ---
10
10
 
11
11
  ## Огляд
12
12
 
13
- Модуль забезпечує механізм автоматичного застосування паттернів T0-auto. Він дозволяє відфільтровувати правила, до яких застосовуються ці паттерни, та запускає повний цикл перевірки конформності з автоматичним виправленням через `runT0AutoCli`.
13
+ Модуль забезпечує автоматичне застосування паттернів T0-auto до виявлених порушень. Він фільтрує доступні правила за допомогою `filterT0AutoRules`, застосовує паттерни до порушень за допомогою `applyT0Auto` та запускає повний процес перевірки та виведення результатів через `runT0AutoCli`.
14
14
 
15
15
  ## Поведінка
16
16
 
17
- applyT0Auto застосовує всі T0-auto паттерни до одного виявленого порушення, повертаючи результат застосування та список виконаних дій.
18
- filterT0AutoRules повертає список ID правил, для яких існують відповідні T0-auto паттерни, виходячи з виявлених порушень.
19
- runT0AutoCli запускає процес T0-auto: виконує перевірку конформності, застосовує T0-auto до порушень, повторно перевіряє змінені правила та виводить підсумок.
17
+ applyT0Auto застосовує всі T0-auto паттерни до одного виявленого порушення, повертаючи результат застосування та список дій.
18
+ filterT0AutoRules повертає список ID правил, для яких існує хоча б один T0-auto паттерн, виходячи з виявлених порушень.
19
+ runT0AutoCli виконує повний цикл T0-auto: запускає перевірку конформності, застосовує T0-auto до провальних правил, повторно перевіряє змінені правила та виводить підсумок.
20
20
 
21
21
  ## Публічний API
22
22
 
23
- applyT0Auto — застосовує всі T0-auto шаблони до вихідних даних про порушення.
24
- filterT0AutoRules — визначає і повертає ідентифікатори правил, які мають принаймні один T0-auto шаблон, виходячи з результату `fix --json`.
23
+ applyT0Auto — застосовує всі T0-auto шаблони до результату виявлення порушень.
24
+ filterT0AutoRules — визначає і повертає ідентифікатори правил, які мають відповідні T0-auto шаблони у результаті `fix --json`.
25
25
  runT0AutoCli — виконує команду `n-cursor fix-t0 [rule...]`, яка запускає `fix --json`, застосовує T0-auto до кожного порушення, повторно перевіряє check-gate та виводить звіт.
26
26
 
27
27
  ## Гарантії поведінки
@@ -5,7 +5,6 @@ import { fileURLToPath } from 'node:url'
5
5
  import { discoverT0Patterns } from './discover-t0-patterns.mjs'
6
6
  import { runConformanceCheck } from './run-conformance-check.mjs'
7
7
 
8
- // Паттерни живуть у rule-level fix-*.mjs файлах; агрегуємо тут через discovery.
9
8
  // Top-level await: ініціалізація один раз при завантаженні модуля.
10
9
  const RULES_DIR = join(dirname(fileURLToPath(import.meta.url)), '../../../rules')
11
10
  const PATTERNS = await discoverT0Patterns(RULES_DIR)
@@ -24,7 +23,7 @@ export async function applyT0Auto(ruleId, violationOutput, cwd) {
24
23
  for (const p of PATTERNS) {
25
24
  if (!p.test(violationOutput)) continue
26
25
  // Патерн може бути sync ({ok,action}) або async (Promise) — await нормалізує обидва.
27
- const result = await p.apply(violationOutput, cwd)
26
+ const result = await p.apply(violationOutput, cwd, { ruleId, rulesDir: RULES_DIR })
28
27
  actions.push(`[${p.id}] ${result.action}`)
29
28
  if (result.ok) applied = true
30
29
  }
@@ -15,7 +15,6 @@
15
15
  import { readFile } from 'node:fs/promises'
16
16
  import { join, relative } from 'node:path'
17
17
 
18
- import { findMissingMdcRefs } from './check-mdc-template-refs.mjs'
19
18
  import { createCheckReporter } from './check-reporter.mjs'
20
19
  import { resolveTargetFiles } from './resolve-target-files.mjs'
21
20
  import { runConftestBatch } from './run-conftest-batch.mjs'
@@ -180,15 +179,5 @@ export async function runRule(rule, bundledRulesDir, walkCache) {
180
179
  if (code !== 0) totalCode = 1
181
180
  }
182
181
 
183
- const ruleDir = join(bundledRulesDir, rule.id)
184
- const missing = await findMissingMdcRefs(ruleDir)
185
- if (missing.length > 0) {
186
- const reporter = createCheckReporter()
187
- for (const rel of missing) {
188
- reporter.fail(`main.mdc: відсутнє markdown-посилання на template-файл ${rel}`)
189
- }
190
- if (reporter.getExitCode() !== 0) totalCode = 1
191
- }
192
-
193
182
  return totalCode
194
183
  }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Оновлює вбудований snapshot Blue Oak Council license list.
3
+ *
4
+ * Fetching: https://blueoakcouncil.org/list.json
5
+ * Виводить: npm/data/blue-oak.json — SPDX-ідентифікатори рівнів Model+Gold+Silver+Bronze.
6
+ *
7
+ * Запуск (вручну, у @nitra/cursor):
8
+ * bun npm/scripts/update-blue-oak.mjs
9
+ *
10
+ * Коли запускати:
11
+ * - При апгрейді @nitra/cursor (n-taze або вручну) — Blue Oak список змінюється рідко,
12
+ * але нові permissive ліцензії зʼявляються раз на кілька місяців;
13
+ * - Якщо проєкт падає на license-check через ліцензію якої нема в списку,
14
+ * а вона точно permissive — спочатку перевір, чи вона в Bronze+ на blueoakcouncil.org.
15
+ *
16
+ * Lead-рівень (найгірший, GPL-compatible) — навмисно виключений.
17
+ */
18
+ import { writeFileSync } from 'node:fs'
19
+ import { dirname, join } from 'node:path'
20
+ import { fileURLToPath } from 'node:url'
21
+
22
+ const BLUE_OAK_URL = 'https://blueoakcouncil.org/list.json'
23
+ const OUT_PATH = join(dirname(dirname(fileURLToPath(import.meta.url))), 'data', 'blue-oak.json')
24
+ const KEEP_RATINGS = new Set(['Model', 'Gold', 'Silver', 'Bronze'])
25
+
26
+ console.log(`⬇ Fetching ${BLUE_OAK_URL} …`)
27
+ const res = await fetch(BLUE_OAK_URL)
28
+ if (!res.ok) {
29
+ console.error(`✗ HTTP ${res.status}`)
30
+ process.exit(1)
31
+ }
32
+
33
+ /** @type {{ version: string, ratings: Array<{ name: string, licenses: Array<{ id: string, name: string, url: string }> }> }} */
34
+ const data = await res.json()
35
+
36
+ const bronzeAndAbove = []
37
+ for (const rating of data.ratings) {
38
+ if (KEEP_RATINGS.has(rating.name)) {
39
+ bronzeAndAbove.push(...rating.licenses.map(l => l.id))
40
+ }
41
+ }
42
+
43
+ const out = {
44
+ version: data.version,
45
+ source: BLUE_OAK_URL,
46
+ bronzeAndAbove,
47
+ }
48
+
49
+ writeFileSync(OUT_PATH, JSON.stringify(out, null, 2) + '\n', 'utf8')
50
+ console.log(`✓ ${OUT_PATH}`)
51
+ console.log(` version=${out.version} bronzeAndAbove=${bronzeAndAbove.length} licenses`)