@nitra/cursor 12.5.0 → 12.6.1

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,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [12.6.1] - 2026-06-21
4
+
5
+ ### Changed
6
+
7
+ - Оновлено text rule docs і helper-приклади на n-cursor lint text без package.json lint-text wrapper.
8
+
9
+ ## [12.6.0] - 2026-06-21
10
+
11
+ ### Changed
12
+
13
+ - Видалено правила для package.json та оновлено логіку перевірок інструментів
14
+
3
15
  ## [12.5.0] - 2026-06-21
4
16
 
5
17
  ### Changed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nitra/cursor",
3
- "version": "12.5.0",
3
+ "version": "12.6.1",
4
4
  "description": "CLI для завантаження cursor-правил (префікс n-) у локальний репозиторій",
5
5
  "keywords": [
6
6
  "cli",
@@ -76,8 +76,7 @@ async function checkLegacyCacheRemoved(pass, fail, cwd) {
76
76
 
77
77
  /**
78
78
  * Перевіряє відповідність проєкту правилу `image-compress.mdc`: `.n-minify-image.tsv` НЕ
79
- * в `.gitignore`, застарілий `.minify-image-cache.tsv` видалений. CI-workflow для image
80
- * не вимагається — лінт зображень виконується лише локально.
79
+ * в `.gitignore`, застарілий `.minify-image-cache.tsv` видалений.
81
80
  * @param {string} [cwd] корінь репозиторію
82
81
  * @returns {Promise<number>} 0 — все OK, 1 — є проблеми
83
82
  */
@@ -89,7 +88,7 @@ export async function check(cwd = process.cwd()) {
89
88
  fail('package.json не знайдено в корені — додай (image-compress.mdc)')
90
89
  return reporter.getExitCode()
91
90
  }
92
- pass('package.json є (структуру перевіряє npx @nitra/cursor fix → image_compress.package_json)')
91
+ pass('package.json є (dependency policy перевіряє npx @nitra/cursor fix → image_compress.package_json)')
93
92
 
94
93
  await checkHashCacheNotIgnored(pass, fail, cwd)
95
94
  await checkLegacyCacheRemoved(pass, fail, cwd)
@@ -18,7 +18,7 @@ export function check() {
18
18
  }
19
19
 
20
20
  if (existsSync('package.json')) {
21
- pass('package.json є (наявність lint-php перевіряє npx @nitra/cursor fix → php.package_json)')
21
+ pass('package.json є')
22
22
  } else {
23
23
  fail('package.json не знайдено в корені — додай (php.mdc)')
24
24
  }
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Канон надходить через --data: { "template": { "snippet": ... } }
4
4
  # Структура --data сформована з template/lint-php.yml.snippet.yml.
5
- # Маркер `run:` (bun run lint-php) збирається з template's php-job steps.
5
+ # Маркер `run:` збирається з template's php-job steps.
6
6
  # Універсальні workflow-перевірки — у `ga.workflow_common`.
7
7
  package php.lint_php_yml
8
8
 
@@ -33,9 +33,9 @@ export function check(cwd = process.cwd()) {
33
33
  }
34
34
 
35
35
  if (existsSync(join(cwd, 'package.json'))) {
36
- pass('package.json є (наявність lint-python перевіряє fix → python.package_json)')
36
+ pass('package.json є')
37
37
  } else {
38
- fail('package.json не знайдено в корені — додай для `bun run lint-python` (python.mdc)')
38
+ fail('package.json не знайдено в корені — додай (python.mdc)')
39
39
  }
40
40
 
41
41
  const wfPath = '.github/workflows/lint-python.yml'
@@ -6,7 +6,7 @@
6
6
  # - кожен `uses` з template (підмножина): actions/checkout@v6,
7
7
  # ./.github/actions/setup-bun-deps, astral-sh/setup-uv@v8.0.0;
8
8
  # - кожен `run` з template має бути присутнім (як substring) серед run-кроків
9
- # input'а: `uv sync --frozen`, `bun run lint-python`.
9
+ # input'а: `uv sync --frozen`, `n-cursor lint python --read-only`.
10
10
  # Заборона Poetry-кроків (snok/install-poetry, `poetry install`) — через відсутність
11
11
  # у каноні: правило вимагає uv-кроки, а нав'язаних poetry-кроків у template немає.
12
12
  # Універсальні workflow-перевірки (name, concurrency, branches) — у `ga.workflow_common`.
@@ -8,7 +8,7 @@ docgen:
8
8
  score: 90
9
9
  ---
10
10
 
11
- runLintTextCli надає CLI-обгортку для послідовного лінтингу текстових файлів (text.mdc). Обгортка автоматично встановлює необхідні інструменти (`shellcheck`, `dotenv-linter`) через `ensureTool` перед виконанням ланцюжка перевірок. Ланцюжок включає: перевірку правопису (`cspell`), аналіз скриптів (`shellcheck`), перевірку конфігураційних файлів (`dotenv-linter`), форматування Markdown (`markdownlint-cli2`) та валідацію схем (`v8r`). При виявленні першого ненульового коду в ланцюжку, цей код повертається як код виходу, і подальші кроки не виконуються. runLintTextCli експортується для використання як підкоманда `lint-text` з `bin/n-cursor.js`.
11
+ runLintTextCli надає внутрішню обгортку для послідовного лінтингу текстових файлів (text.mdc). Обгортка автоматично встановлює необхідні інструменти (`shellcheck`, `dotenv-linter`) через `ensureTool` перед виконанням ланцюжка перевірок. Ланцюжок включає: перевірку правопису (`cspell`), аналіз скриптів (`shellcheck`), перевірку конфігураційних файлів (`dotenv-linter`), форматування Markdown (`markdownlint-cli2`) та валідацію схем (`v8r`). При виявленні першого ненульового коду в ланцюжку, цей код повертається як код виходу, і подальші кроки не виконуються. Зовнішня точка входу правила `n-cursor lint text`.
12
12
 
13
13
  ## Поведінка
14
14
 
@@ -143,7 +143,7 @@ if (isRunAsCli(import.meta.url)) {
143
143
 
144
144
  ### Як частина команди `lint-text`
145
145
 
146
- Раннер призначений для виклику з кореневої лінт-команди репозиторію (`lint-text` у `package.json`). Замість того, щоб запускати `v8r` чотирма (або п’ятьма) окремими командами в `package.json`, використовується один виклик цього модуля, який сам обходить усі типові glob-и:
146
+ Раннер призначений для виклику з правила `n-cursor lint text`. Замість того, щоб запускати `v8r` чотирма (або п’ятьма) окремими командами в `package.json`, використовується один виклик цього модуля, який сам обходить усі типові glob-и:
147
147
 
148
148
  ```bash
149
149
  node ./npm/rules/text/lint/run-v8r.mjs
@@ -117,19 +117,16 @@ version: '1.30'
117
117
 
118
118
  Завжди пиши **JSDoc** до функцій та методів.
119
119
 
120
- **`package.json`:** скрипт **`lint-text`** і devDependencies **`@nitra/cspell-dict`** (**`^2.0.0`** або новіший у лінії 2.x) — з **2.0.0** у пакет транзитивно входять типові **`@cspell/dict-*`**, тому **не** додавай їх окремо в корінь. **`markdownlint-cli2`** викликай у `lint-text` лише через **`bunx markdownlint-cli2`**, не додавай пакет до devDependencies. **`v8r`** лише через **`bunx v8r`** (зазвичай **`bunx v8r`**), не в devDependencies. Окремий пакет **`markdownlint`** не потрібний.
120
+ **`package.json`:** у `devDependencies` має бути **`@nitra/cspell-dict`** (**`^2.0.0`** або новіший у лінії 2.x) — з **2.0.0** у пакет транзитивно входять типові **`@cspell/dict-*`**, тому **не** додавай їх окремо в корінь. Окремий `package.json`-скрипт `lint-text` не потрібен: запуск іде через **`n-cursor lint text`**. **`markdownlint-cli2`** запускається rule-адаптером через **`bunx markdownlint-cli2`**, не додавай пакет до devDependencies. **`v8r`** лише через **`bunx v8r`**, не в devDependencies. Окремий пакет **`markdownlint`** не потрібний.
121
121
 
122
- **shellcheck:** інструмент лише в **`PATH`** (як у **ga.mdc** для `lint-ga`), **не** додавай до `dependencies` / `devDependencies`. Якщо `shellcheck` відсутній — встанови локально (**macOS:** `brew install shellcheck`; **Debian/Ubuntu:** `sudo apt-get install -y shellcheck`; **Arch:** `sudo pacman -S shellcheck`). Канонічний **`lint-text`** делегує до CLI **`n-cursor lint-text`** (бінарка з `node_modules/.bin/` пакету `@nitra/cursor`): після **`cspell .`** виконується **`runShellcheckText()`** з пакета — циклічно **`shellcheck -f diff`** і **`patch -p1`** для авто-виправлень, потім повний прогін **`shellcheck`** по всіх tracked `*.sh` (у git) або по `**/*.sh` без `node_modules`. Потрібен також **`patch`** у `PATH` (на macOS зазвичай уже є).
122
+ **shellcheck:** інструмент лише в **`PATH`** (як у **ga.mdc** для `lint-ga`), **не** додавай до `dependencies` / `devDependencies`. Якщо `shellcheck` відсутній — встанови локально (**macOS:** `brew install shellcheck`; **Debian/Ubuntu:** `sudo apt-get install -y shellcheck`; **Arch:** `sudo pacman -S shellcheck`). Канонічний запуск **`n-cursor lint text`** (бінарка з `node_modules/.bin/` пакету `@nitra/cursor`): після **`cspell .`** виконується **`runShellcheckText()`** з пакета — циклічно **`shellcheck -f diff`** і **`patch -p1`** для авто-виправлень, потім повний прогін **`shellcheck`** по всіх tracked `*.sh` (у git) або по `**/*.sh` без `node_modules`. Потрібен також **`patch`** у `PATH` (на macOS зазвичай уже є).
123
123
 
124
124
  **dotenv-linter:** після shellcheck CLI запускає **`runDotenvLinter()`** з пакета — рекурсивно по `.env*`-файлах проєкту через **`dotenv-linter fix -r --no-backup --quiet . --exclude node_modules --exclude .envrc`**, далі такий самий **`check`** для фінальної перевірки. Інструмент має бути в **`PATH`** і **не** додається в `dependencies` / `devDependencies`. Якщо `dotenv-linter` відсутній — встанови локально (**macOS:** `brew install dotenv-linter`; **Linux:** `curl -sSfL https://git.io/JLbXn | sh -s -- -b /usr/local/bin`; через **cargo:** `cargo install dotenv-linter`).
125
125
 
126
- У v8r **немає** прапорця тихого режиму; CLI-обгортка **`n-cursor lint-text`** на четвертому кроці викликає **`runV8rWithGlobs()`** з пакета (реалізація — `npm/rules/text/js/run-v8r.mjs`): під капотом послідовні **`bunx v8r`** для кожного типу (**json**, **json5**, **yml**, **yaml**, **toml**), бо один процес v8r з кількома глобами падає з **98**, якщо хоч один glob порожній, і тоді інші розширення не перевіряються. Вивід при кодах **0** і **98** не показується. Каталог схем **`schemas/v8r-catalog.json`** пакета `@nitra/cursor` обгортка підставляє в v8r сама.
126
+ У v8r **немає** прапорця тихого режиму; rule-адаптер **`n-cursor lint text`** на четвертому кроці викликає **`runV8rWithGlobs()`** з пакета (реалізація — `npm/rules/text/js/run-v8r.mjs`): під капотом послідовні **`bunx v8r`** для кожного типу (**json**, **json5**, **yml**, **yaml**, **toml**), бо один процес v8r з кількома глобами падає з **98**, якщо хоч один glob порожній, і тоді інші розширення не перевіряються. Вивід при кодах **0** і **98** не показується. Каталог схем **`schemas/v8r-catalog.json`** пакета `@nitra/cursor` обгортка підставляє в v8r сама.
127
127
 
128
128
  ```json title="package.json"
129
129
  {
130
- "scripts": {
131
- "lint-text": "n-cursor lint-text"
132
- },
133
130
  "devDependencies": {
134
131
  "@nitra/cspell-dict": "^2.1.0"
135
132
  }
@@ -174,7 +171,7 @@ version: '1.30'
174
171
 
175
172
  - Канон: [lint-text.yml.snippet.yml](./policy/lint_text/template/lint-text.yml.snippet.yml)
176
173
 
177
- Перед **`./.github/actions/setup-bun-deps`** — **`actions/checkout@v6`** (див. **ga.mdc**). Після composite — кроки **`Install shellcheck`** (apt) і **`Install dotenv-linter`** (curl), бо `n-cursor lint-text` вимагає обидва бінарники в PATH; на ubuntu-latest shellcheck часто вже є, dotenv-linter — ні. Composite: Node 24, Bun, кеш, `bun install --frozen-lockfile`.
174
+ Перед **`./.github/actions/setup-bun-deps`** — **`actions/checkout@v6`** (див. **ga.mdc**). Після composite — кроки **`Install shellcheck`** (apt) і **`Install dotenv-linter`** (curl), бо `n-cursor lint text` вимагає обидва бінарники в PATH; на ubuntu-latest shellcheck часто вже є, dotenv-linter — ні. Composite: Node 24, Bun, кеш, `bun install --frozen-lockfile`.
178
175
 
179
176
  Не дублюй окремий workflow з тими самими кроками cspell/markdownlint.
180
177
 
@@ -198,9 +195,6 @@ version: '1.30'
198
195
 
199
196
  ```json title="package.json"
200
197
  {
201
- "scripts": {
202
- "lint-text": "n-cursor lint-text"
203
- },
204
198
  "devDependencies": {
205
199
  "@nitra/cspell-dict": "^2.1.0"
206
200
  }
@@ -215,9 +209,6 @@ version: '1.30'
215
209
 
216
210
  ```json title="package.json"
217
211
  {
218
- "scripts": {
219
- "lint-text": "n-cursor lint-text"
220
- },
221
212
  "devDependencies": {
222
213
  "@nitra/cspell-dict": "^2.1.0"
223
214
  }
@@ -262,4 +253,4 @@ kebab-case
262
253
 
263
254
  ## Перевірка
264
255
 
265
- `npx @nitra/cursor fix text` (охоплює oxfmt, cspell, shellcheck у `lint-text`, markdownlint, v8r, CI для `lint-text`). Зокрема падає, якщо у корені є `.prettierignore`, `.prettierrc*`, `prettier.config.*` або у `package.json#scripts` зустрічається команда з `prettier` — Prettier повністю заборонено, форматування лише через **oxfmt**.
256
+ `npx @nitra/cursor fix text` (охоплює oxfmt, cspell, shellcheck, markdownlint, v8r і CI для `n-cursor lint text`). Зокрема падає, якщо у корені є `.prettierignore`, `.prettierrc*`, `prettier.config.*` або у `package.json#scripts` зустрічається команда з `prettier` — Prettier повністю заборонено, форматування лише через **oxfmt**.
@@ -12,7 +12,7 @@ docgen:
12
12
 
13
13
  - `check-ga` — загальна перевірка GitHub Actions workflows;
14
14
  - `check-js-lint` — перевірка структури `lint-js.yml`;
15
- - `check-text` — перевірка наявності викликів `bun run lint-text` у CI;
15
+ - `check-text` — перевірка наявності викликів `n-cursor lint text --read-only` у CI;
16
16
  - `check-style-lint` — перевірка викликів стайл-лінту в CI;
17
17
  - `check-npm-module` — перевірка workflow npm-модуля.
18
18
 
@@ -191,7 +191,7 @@ docgen:
191
191
 
192
192
  **Side effects:** немає. Ітерація припиняється на першому збігу (рання передача).
193
193
 
194
- **Типовий приклад:** `anyRunStepIncludes(root, 'bun run lint-text')` для `check-text` — перевірити, що CI взагалі викликає таргет лінту текстів.
194
+ **Типовий приклад:** `anyRunStepIncludes(root, 'n-cursor lint text --read-only')` для `check-text` — перевірити, що CI взагалі викликає таргет лінту текстів.
195
195
 
196
196
  ---
197
197
 
@@ -299,14 +299,14 @@ if (!result.ok) {
299
299
  }
300
300
  ```
301
301
 
302
- ### Приклад: перевірка наявності таргета `bun run lint-text`
302
+ ### Приклад: перевірка наявності таргета `n-cursor lint text --read-only`
303
303
 
304
304
  ```js
305
305
  import { parseWorkflowYaml, anyRunStepIncludes } from './gha-workflow.mjs'
306
306
 
307
307
  const root = parseWorkflowYaml(content)
308
- if (root && !anyRunStepIncludes(root, 'bun run lint-text')) {
309
- console.error('у CI відсутній виклик bun run lint-text')
308
+ if (root && !anyRunStepIncludes(root, 'n-cursor lint text --read-only')) {
309
+ console.error('у CI відсутній виклик n-cursor lint text --read-only')
310
310
  }
311
311
  ```
312
312
 
@@ -135,7 +135,7 @@ export function verifyLintJsWorkflowStructure(root) {
135
135
  }
136
136
 
137
137
  /**
138
- * Чи є в будь-якому `run` кроку підрядок (наприклад `bun run lint-text`).
138
+ * Чи є в будь-якому `run` кроку підрядок (наприклад `n-cursor lint text --read-only`).
139
139
  * @param {Record<string, unknown>} root корінь workflow
140
140
  * @param {string} needle підрядок для пошуку
141
141
  * @returns {boolean} `true`, якщо хоча б один `run` містить `needle`
@@ -3,7 +3,7 @@
3
3
  * команди і прокидає stdout/stderr на користувацькі stream-и (`stdio: 'inherit'`), щоб виглядало
4
4
  * як прямий виклик у shell.
5
5
  *
6
- * Використовується з `n-cursor lint-ga`, `n-cursor lint-text` та інших підкоманд, щоб не дублювати
6
+ * Використовується з rule-адаптерів `n-cursor lint <rule>`, щоб не дублювати
7
7
  * одну й ту саму обгортку у кожному `rules/<id>/js/lint.mjs` (jscpd-clone).
8
8
  */
9
9
  import { spawnSync } from 'node:child_process'
@@ -1,18 +0,0 @@
1
- # Перевірка `package.json` (docker.mdc).
2
- #
3
- # Канон надходить через --data: { "template": { "snippet": ... } }
4
- # Backward-compatible: перевіряє ЛИШЕ зміст значення `scripts.lint-docker`, якщо ключ
5
- # присутній у старому проєкті. Нові проєкти використовують `n-cursor lint docker`
6
- # напряму, без package.json wrapper.
7
- package docker.package_json
8
-
9
- import rego.v1
10
-
11
- # Conditional snippet-check: тільки якщо значення непорожнє у input.
12
- deny contains msg if {
13
- some script_name, expected in data.template.snippet.scripts
14
- actual := object.get(object.get(input, "scripts", {}), script_name, "")
15
- actual != ""
16
- trim_space(actual) != expected
17
- msg := sprintf("package.json: scripts.%s має бути %q (зараз: %q) (docker.mdc)", [script_name, expected, actual])
18
- }
@@ -1,4 +0,0 @@
1
- {
2
- "$schema": "https://unpkg.com/@nitra/cursor/schemas/target.json",
3
- "files": { "single": "package.json" }
4
- }
@@ -1 +0,0 @@
1
- { "scripts": { "lint-docker": "n-cursor lint docker" } }