@nitra/cursor 3.27.0 → 3.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/package.json +1 -3
- package/rules/abie/js/applies.mjs +1 -5
- package/rules/abie/js/env_dns.mjs +1 -9
- package/rules/abie/js/firebase_hosting.mjs +1 -5
- package/rules/abie/js/hc_pairing.mjs +1 -8
- package/rules/abie/js/ua_http_route.mjs +1 -10
- package/rules/abie/js/ua_node_selector.mjs +1 -8
- package/rules/adr/js/hooks.mjs +1 -20
- package/rules/bun/js/layout.mjs +1 -19
- package/rules/capacitor/js/platforms.mjs +1 -23
- package/rules/changelog/js/consistency.mjs +1 -29
- package/rules/ci4/js/marksman_config.mjs +1 -19
- package/rules/docker/js/lint.mjs +1 -34
- package/rules/ga/docs/fix.md +4 -4
- package/rules/ga/js/docs/lint.md +3 -3
- package/rules/ga/js/docs/workflows.md +14 -14
- package/rules/ga/js/workflows.mjs +1 -16
- package/rules/ga/lint/docs/lint.md +9 -9
- package/rules/graphql/js/tooling.mjs +1 -9
- package/rules/hasura/js/internal_urls.mjs +1 -24
- package/rules/image-avif/js/avif_generation.mjs +1 -27
- package/rules/image-compress/js/package_setup.mjs +1 -18
- package/rules/js-bun-db/js/safety.mjs +1 -31
- package/rules/js-bun-redis/js/imports.mjs +1 -12
- package/rules/js-lint/js/docs/lint-findings.md +30 -0
- package/rules/js-lint/js/lint-findings.mjs +1 -7
- package/rules/js-lint/js/lint.mjs +1 -10
- package/rules/js-lint/js/tooling.mjs +1 -13
- package/rules/js-lint/js/utils_imports.mjs +1 -18
- package/rules/js-lint-ci/js/lint.mjs +1 -6
- package/rules/js-mssql/js/deps.mjs +1 -10
- package/rules/js-run/js/runtime.mjs +1 -37
- package/rules/js-run/lib/docs/temporal-scan.md +25 -0
- package/rules/k8s/js/manifests.mjs +1 -137
- package/rules/nginx-default-tpl/js/template.mjs +1 -18
- package/rules/npm-module/js/docs/header_doc_pointer.md +25 -0
- package/rules/npm-module/js/header_doc_pointer.mjs +82 -0
- package/rules/npm-module/js/package_structure.mjs +1 -28
- package/rules/npm-module/js/rule_meta.mjs +1 -10
- package/rules/npm-module/js/skill_meta.mjs +1 -13
- package/rules/php/js/tooling.mjs +1 -11
- package/rules/python/js/applies.mjs +1 -8
- package/rules/python/js/tooling.mjs +1 -21
- package/rules/rego/js/applies.mjs +1 -11
- package/rules/rust/js/applies.mjs +1 -7
- package/rules/security/js/sample_secret.mjs +1 -28
- package/rules/security/js/trufflehog.mjs +1 -8
- package/rules/style-lint/js/lint.mjs +1 -5
- package/rules/style-lint/js/tooling.mjs +1 -19
- package/rules/tauri/js/cargo_mutants_config.mjs +1 -20
- package/rules/tauri/js/tooling.mjs +1 -21
- package/rules/test/js/cargo_mutants_config.mjs +1 -12
- package/rules/test/js/location.mjs +1 -9
- package/rules/test/js/no-process-chdir.mjs +1 -21
- package/rules/test/js/no-relative-fs-path.mjs +1 -23
- package/rules/test/js/stryker_config.mjs +4 -25
- package/rules/test/js/vitest-config-pool-forks.mjs +1 -17
- package/rules/text/js/forbidden-prettier.mjs +1 -10
- package/rules/text/js/formatting.mjs +1 -31
- package/rules/vue/js/packages.mjs +1 -24
- package/scripts/coverage-classify/index.mjs +60 -72
- package/scripts/coverage-fix.mjs +26 -23
- package/scripts/dispatcher/lib/subagent-runner.mjs +33 -102
- package/scripts/docs/coverage-fix-extract.md +32 -0
- package/scripts/docs/lint-cli.md +25 -0
- package/scripts/docs/post-tool-use-fix.md +27 -0
- package/scripts/docs/rename-yaml-extensions.md +36 -0
- package/scripts/docs/skills-cli.md +35 -0
- package/scripts/docs/sync-claude-config.md +52 -0
- package/scripts/docs/sync-setup-bun-deps-action.md +26 -0
- package/scripts/docs/upgrade-nitra-cursor-and-install.md +29 -0
- package/scripts/docs/worktree-cli.md +46 -0
- package/scripts/lib/docs/assert-project-root.md +28 -0
- package/scripts/lib/docs/diff-added-lines.md +34 -0
- package/scripts/lib/docs/read-n-cursor-config-lite.md +28 -0
- package/scripts/lib/docs/resolve-target-files.md +34 -0
- package/scripts/lib/docs/root-notice.md +28 -0
- package/scripts/lib/docs/rule-meta-helpers.md +34 -0
- package/scripts/lib/docs/rule-meta.md +34 -0
- package/scripts/lib/docs/rule-predicates.md +30 -0
- package/scripts/lib/docs/run-conftest-batch.md +26 -0
- package/scripts/lib/docs/run-lint-step.md +25 -0
- package/scripts/lib/docs/run-rule-cli.md +27 -0
- package/scripts/lib/docs/run-rule.md +32 -0
- package/scripts/lib/docs/run-standard-lint.md +22 -0
- package/scripts/lib/docs/run-standard-rule.md +24 -0
- package/scripts/lib/docs/skill-meta.md +31 -0
- package/scripts/lib/docs/sync-gitignore-worktree.md +31 -0
- package/scripts/lib/docs/template.md +40 -0
- package/scripts/lib/docs/timing-summary.md +24 -0
- package/scripts/lib/docs/workspaces.md +30 -0
- package/scripts/lib/docs/worktree-notice.md +27 -0
- package/scripts/lib/docs/worktree.md +38 -0
- package/scripts/utils/docs/ast-scan-utils.md +50 -0
- package/scripts/utils/docs/ensure-gitignore-entries.md +28 -0
- package/scripts/utils/docs/find-package-json-paths.md +26 -0
- package/scripts/utils/docs/lock-cache-dir.md +25 -0
- package/scripts/utils/docs/pass.md +25 -0
- package/scripts/utils/docs/resolve-cargo-manifest.md +23 -0
- package/scripts/utils/docs/resolve-cmd.md +29 -0
- package/scripts/utils/docs/resolve-js-root.md +25 -0
- package/scripts/utils/docs/test-helpers.md +36 -0
- package/scripts/utils/docs/walk-cache.md +27 -0
- package/scripts/utils/docs/walkDir.md +32 -0
- package/scripts/utils/docs/with-lock.md +25 -0
- package/scripts/utils/docs/worktree-fingerprint.md +27 -0
- package/skills/docgen/js/docgen-batch.mjs +95 -0
- package/skills/docgen/js/docgen-extract.mjs +33 -18
- package/skills/docgen/js/docgen-gen.mjs +140 -154
- package/skills/docgen/js/docgen-ignore.mjs +1 -6
- package/skills/docgen/js/docgen-prompts.mjs +33 -22
- package/skills/docgen/js/docgen-scan.mjs +1 -8
- package/skills/docgen/js/docs/docgen-extract.md +28 -0
- package/skills/docgen/js/docs/docgen-gen.md +41 -0
- package/skills/docgen/js/docs/docgen-ignore.md +24 -0
- package/skills/docgen/js/docs/docgen-prompts.md +24 -0
- package/skills/docgen/js/docs/docgen-scan.md +48 -0
- package/skills/fix/js/docs/llm-worker.md +27 -0
- package/skills/fix/js/docs/orchestrator.md +32 -0
- package/skills/fix/js/docs/t0.md +29 -0
- package/skills/fix/js/llm-worker.mjs +64 -29
- package/skills/fix/js/orchestrator.mjs +45 -54
- package/skills/fix/js/t0.mjs +16 -32
- package/skills/start-check/js/check.mjs +1 -16
- package/skills/start-check/js/docs/check.md +34 -0
- package/skills/taze/js/diff.mjs +1 -15
- package/skills/taze/js/docs/diff.md +33 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.29.0] - 2026-06-07
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- resolveModel(tier) — прозорий каскадний fallback local→cloud для всіх 3 тирів (min/avg/max)
|
|
8
|
+
|
|
9
|
+
## [3.28.0] - 2026-06-06
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- lib/models.mjs: global model tier classification (LOCAL_MIN/AVG/MAX, CLOUD_MIN/AVG/MAX) via N_*_MODEL env vars; fix llm-worker uses CLOUD_MIN/AVG by default
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- fix orchestrator: concise output — single line when clean, details only when issues occur
|
|
18
|
+
- llm-worker: rename MODEL_HAIKU/SONNET → MODEL/MODEL_HEAVY, helpful error when pi has no API key for provider
|
|
19
|
+
|
|
3
20
|
## [3.27.0] - 2026-06-06
|
|
4
21
|
|
|
5
22
|
### Added
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nitra/cursor",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.29.0",
|
|
4
4
|
"description": "CLI для завантаження cursor-правил (префікс n-) у локальний репозиторій",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -51,8 +51,6 @@
|
|
|
51
51
|
"rename-yaml-extensions": "bun ./bin/n-cursor.js rename-yaml-extensions"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@anthropic-ai/claude-agent-sdk": "^0.3.0",
|
|
55
|
-
"@anthropic-ai/sdk": "^0.100.1",
|
|
56
54
|
"oxc-parser": "^0.128.0",
|
|
57
55
|
"picomatch": "^4.0.4",
|
|
58
56
|
"smol-toml": "^1.6.1",
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Applies-гейт правила abie: rule-level через `isAbieRuleEnabled` (поле `rules` у `.n-cursor.json`).
|
|
3
|
-
* Якщо повертає `false` — CLI пропускає всі концерни (JS і policy) цього правила.
|
|
4
|
-
* `check()` друкує тільки context-pass; решта концернів роблять справжню роботу.
|
|
5
|
-
*/
|
|
1
|
+
/** @see ./docs/applies.md */
|
|
6
2
|
import { createCheckReporter } from '../../../scripts/lib/check-reporter.mjs'
|
|
7
3
|
|
|
8
4
|
import { isAbieRuleEnabled } from '../lib/enabled.mjs'
|
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Скан env-файлів abie (`*.dev.env`, `*.ua.env`): кожен внутрішньокластерний URL
|
|
3
|
-
* `http://<svc>.<ns>.svc.<dns>` має відповідати кластеру за іменем файла:
|
|
4
|
-
* - `dev.env` → `abie-dev.internal` + `dev-*` namespace
|
|
5
|
-
* - `ua.env` → `abie-ua.internal` + `ua-*` namespace
|
|
6
|
-
*
|
|
7
|
-
* Файл `.env` без імені (локальний для розробника) — виключено.
|
|
8
|
-
* @param {string} [cwd] корінь репозиторію
|
|
9
|
-
*/
|
|
1
|
+
/** @see ./docs/env_dns.md */
|
|
10
2
|
import { readFile } from 'node:fs/promises'
|
|
11
3
|
import { basename, relative } from 'node:path'
|
|
12
4
|
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевірка abie: у **підкаталогах першого рівня** (без `.git`/`node_modules`) не має бути
|
|
3
|
-
* `.firebaserc`, `firebase.json`, `.firebase/` (abie.mdc — Firebase Hosting заборонено).
|
|
4
|
-
* У самому корені репозиторію ці імена не перевіряються (можуть бути від суміжних проєктів).
|
|
5
|
-
*/
|
|
1
|
+
/** @see ./docs/firebase_hosting.md */
|
|
6
2
|
import { existsSync } from 'node:fs'
|
|
7
3
|
import { readdir } from 'node:fs/promises'
|
|
8
4
|
import { join } from 'node:path'
|
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевірка abie: для кожного каталогу з `kind: Deployment` під `k8s/` поруч має бути `hc.yaml`
|
|
3
|
-
* з коректним modeline (yaml-language-server $schema).
|
|
4
|
-
*
|
|
5
|
-
* Це JS-частина (FS-парність + modeline). Структурну валідацію `HealthCheckPolicy`
|
|
6
|
-
* (apiVersion, requestPath, port, targetRef з суфіксом `-hl`) робить CLI через
|
|
7
|
-
* `policy/health_check_policy/target.json` (walkGlob по hc.yaml у k8s-дереві).
|
|
8
|
-
*/
|
|
1
|
+
/** @see ./docs/hc_pairing.md */
|
|
9
2
|
import { existsSync } from 'node:fs'
|
|
10
3
|
import { readFile } from 'node:fs/promises'
|
|
11
4
|
import { relative } from 'node:path'
|
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Якщо в каталозі пакета (батько `k8s/`) є `vite.config.{js,mjs,ts}`, у `ua/kustomization.yaml`
|
|
3
|
-
* має бути inline-patch HTTPRoute (непорожній `target.name`): `/spec/hostnames` (домени abie),
|
|
4
|
-
* `/spec/parentRefs/0/namespace` (`ua` або `ua-*`).
|
|
5
|
-
*
|
|
6
|
-
* Для спільних сервісів (`auth-run-hl`, `file-link-hl`) у base-HTTPRoute пакета — кожен `backendRef`
|
|
7
|
-
* має `namespace: dev`; в overlay patch — JSON6902 на `/spec/rules/…/backendRefs/…/namespace` зі
|
|
8
|
-
* `value: ua`. Кількість patch-ів = кількість таких посилань у base.
|
|
9
|
-
* @param {string} [cwd] корінь репозиторію
|
|
10
|
-
*/
|
|
1
|
+
/** @see ./docs/ua_http_route.md */
|
|
11
2
|
import { readFile } from 'node:fs/promises'
|
|
12
3
|
import { relative } from 'node:path'
|
|
13
4
|
|
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Якщо в дереві `k8s/` пакета є `Deployment`, у `ua/kustomization.yaml` має бути inline-patch
|
|
3
|
-
* на `Deployment` з `path /spec/template/spec/nodeSelector` і `preem: false` (abie.mdc).
|
|
4
|
-
*
|
|
5
|
-
* Структурні обмеження JSON6902 (заборона `remove + add` на той самий path) перевіряє k8s.mdc /
|
|
6
|
-
* `k8s.kustomization` rego — тут лише abie-специфічне.
|
|
7
|
-
* @param {string} [cwd] корінь репозиторію
|
|
8
|
-
*/
|
|
1
|
+
/** @see ./docs/ua_node_selector.md */
|
|
9
2
|
import { readFile } from 'node:fs/promises'
|
|
10
3
|
import { relative } from 'node:path'
|
|
11
4
|
|
package/rules/adr/js/hooks.mjs
CHANGED
|
@@ -1,23 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевіряє вимоги правила adr.mdc: ADR Stop-hook'и `capture-decisions.sh` і
|
|
3
|
-
* `normalize-decisions.sh` у Claude Code.
|
|
4
|
-
*
|
|
5
|
-
* Очікування:
|
|
6
|
-
* - `.claude/hooks/capture-decisions.sh` та `.claude/hooks/normalize-decisions.sh`
|
|
7
|
-
* існують і байт-у-байт збігаються з канонічними `.claude-template/hooks/*`
|
|
8
|
-
* пакета (sync керує файлами повністю).
|
|
9
|
-
* - `.claude/settings.json` (project-shared) має managed-групи у `hooks.Stop` для
|
|
10
|
-
* обох скриптів (маркери у `command` — самі шляхи до скриптів).
|
|
11
|
-
* - `.cursor/hooks.json` має managed entries у `hooks.stop` для обох скриптів, щоб
|
|
12
|
-
* Cursor Agent теж запускав ADR capture/normalize після завершення відповіді.
|
|
13
|
-
* - `.claude/settings.local.json` (якщо існує) НЕ має дублів цих managed-груп —
|
|
14
|
-
* після переходу на project-shared такі записи створили б два запуски на одну подію.
|
|
15
|
-
* - `.gitignore` у корені містить шаблон, який покриває
|
|
16
|
-
* `.claude/hooks/capture-decisions.log` і `.claude/hooks/normalize-decisions.log`.
|
|
17
|
-
*
|
|
18
|
-
* LLM CLI (`claude` або `cursor-agent`) у `PATH` — інформативна перевірка: якщо жодного
|
|
19
|
-
* немає, скрипт працює, але мовчки виходить, тому це warning, а не fail.
|
|
20
|
-
*/
|
|
1
|
+
/** @see ./docs/hooks.md */
|
|
21
2
|
import { existsSync } from 'node:fs'
|
|
22
3
|
import { readFile } from 'node:fs/promises'
|
|
23
4
|
import { delimiter, dirname, join } from 'node:path'
|
package/rules/bun/js/layout.mjs
CHANGED
|
@@ -1,22 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевіряє відповідність репозиторію правилам Bun (bun.mdc).
|
|
3
|
-
*
|
|
4
|
-
* **Що тут лишилося** (FS / cross-file — не покривається conftest):
|
|
5
|
-
* - наявність `bun.lock`, `bunfig.toml`, `package.json` у корені (FS-existence);
|
|
6
|
-
* - заборонені lockfile та артефакти yarn/pnpm (`package-lock.json`, `yarn.lock`,
|
|
7
|
-
* `pnpm-lock.yaml`, `.yarnrc.yml`, директорія `.yarn/`);
|
|
8
|
-
* - двосторонній зв'язок `.n-cursor.json:rules` ↔ `package.json:scripts` для правил із
|
|
9
|
-
* `lint-<id>` (`docker`, `k8s`): rule увімкнено → скрипт мусить існувати; rule
|
|
10
|
-
* відсутнє (або в `disable-rules`) → скрипту та згадки `bun run lint-<id>` у
|
|
11
|
-
* агрегованому `scripts.lint` бути **не може** (інакше `bun run lint` падатиме
|
|
12
|
-
* на правилі, яке у конфізі вимкнено).
|
|
13
|
-
*
|
|
14
|
-
* **Що покрила Rego** (`npx \@nitra/cursor check`):
|
|
15
|
-
* - `npm/policy/bun/bunfig/` — `[install].linker == "hoisted"` у `bunfig.toml`;
|
|
16
|
-
* - `npm/policy/bun/package_json/` — відсутність `packageManager` / `dependencies`
|
|
17
|
-
* у кореневому `package.json`, у `devDependencies` лише `@nitra/*`, агрегований
|
|
18
|
-
* `lint`-скрипт покриває всі `lint-*` через `bun run` і завершується `&& oxfmt .`.
|
|
19
|
-
*/
|
|
1
|
+
/** @see ./docs/layout.md */
|
|
20
2
|
import { existsSync } from 'node:fs'
|
|
21
3
|
import { readFile } from 'node:fs/promises'
|
|
22
4
|
import { join } from 'node:path'
|
|
@@ -1,26 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевіряє відповідність проєкту правилам capacitor.mdc для застосунків **Capacitor**.
|
|
3
|
-
*
|
|
4
|
-
* Якщо у репозиторії **немає** ознак Capacitor (див. наведене) — вихід **0**, перевірка не застосовується.
|
|
5
|
-
*
|
|
6
|
-
* **Ознака Capacitor:** наявні **`capacitor.config.json`**, **`capacitor.config.ts`**, **`capacitor.config.mjs`**
|
|
7
|
-
* (у корені) **або** у будь-якому `package.json` (рекурсивно, з пропуском типових каталогів) оголошено
|
|
8
|
-
* хоча б одну залежність **`@capacitor/…`** (у **`dependencies`**, **`devDependencies`**, опційно
|
|
9
|
-
* **`optionalDependencies`**, **`peerDependencies`**).
|
|
10
|
-
*
|
|
11
|
-
* **Версія мінімум 8:** у кожному `package.json`, де вказано **`@capacitor/core`**, діапазон версії
|
|
12
|
-
* мусить допускати лише **Capacitor 8+** (оцінка мінімального **major** з рядка діапазону npm, зокрема
|
|
13
|
-
* `||` і діапазонів через `-` у спрощеному вигляді). **`*`**, **latest** та нерозпізнані випадки — **порушення**:
|
|
14
|
-
* варто задати явний діапазон, наприклад **`^8.0.0`**. Якщо оголошено `capacitor.config.*` без жодного
|
|
15
|
-
* **`@capacitor/core`** у дереві `package.json` — також помилка.
|
|
16
|
-
*
|
|
17
|
-
* **iOS:** зазвичай **без** **Podfile** поза **Pods** (тільки **SPM**). **@nitra/**-плагіни за політикою **SPM** —
|
|
18
|
-
* їх **не** перелічуємо й **не** перевіряємо. Якщо **Podfile** є, його можна зареєструвати як **виняток**
|
|
19
|
-
* (див. **capacitor.mdc**): у кореневому **`package.json`** або
|
|
20
|
-
* **`capacitor.config.json` / `capacitor.config.ts` / `capacitor.config.mjs`**, об’єкт **nitra** з
|
|
21
|
-
* **`iosCocoaPodsBecausePluginsLackSpm: true`** (або **`iosCocoaPodsAllowed: true`**); тоді **Podfile** **не** fail.
|
|
22
|
-
* Якщо **`ios/`** **немає** — iOS-умови не застосовуються.
|
|
23
|
-
*/
|
|
1
|
+
/** @see ./docs/platforms.md */
|
|
24
2
|
import { existsSync } from 'node:fs'
|
|
25
3
|
import { readdir, readFile } from 'node:fs/promises'
|
|
26
4
|
import { join, relative } from 'node:path'
|
|
@@ -1,32 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевіряє, що кожен workspace із релізно-релевантними змінами зафіксував їх через
|
|
3
|
-
* change-файл `<ws>/.changes/*.md` — єдиний дозволений артефакт зміни. Bump `version`
|
|
4
|
-
* і генерацію `CHANGELOG.md` робить виключно `n-cursor release` у CI на `main`.
|
|
5
|
-
*
|
|
6
|
-
* Інваріант (на будь-якій гілці): `version` у дереві не має **випереджати** базу. Лише
|
|
7
|
-
* drift **уперед** (`version` > опублікованої в реєстрі / > git-бази) — ручний bump поза
|
|
8
|
-
* CI — завалює перевірку, навіть із change-файлом. Version **позаду** бази (локаль відстала
|
|
9
|
-
* від уже опублікованого CI-релізу, ще не зроблено `git pull`) — НЕ порушення: це не ручний
|
|
10
|
-
* bump, а git і так не дасть запушити non-fast-forward. Pass лише коли є change-файл, а
|
|
11
|
-
* version не випереджає базу; зміни без change-файлу — fail.
|
|
12
|
-
*
|
|
13
|
-
* Дві моделі бази — на рівні воркспейсу (див. n-changelog.mdc):
|
|
14
|
-
*
|
|
15
|
-
* 1) **registry-published** (npm: `name` + `files`, не `private`; Python: `project.name` +
|
|
16
|
-
* статична `project.version`): база = опублікована версія в npm / PyPI.
|
|
17
|
-
* 2) **local-only** (приватні npm без `files`, Python без імені/версії для реєстру):
|
|
18
|
-
* feature-гілка — `merge-base` з `dev`, інакше з `main`; на `main` — diff від
|
|
19
|
-
* `origin/main` (або `HEAD~1` без remote).
|
|
20
|
-
*
|
|
21
|
-
* Усі `git` і зовнішні виклики — через `execFile` / `fetch`, без shell-інтерполяції.
|
|
22
|
-
*
|
|
23
|
-
* **Autofix-режим** (env `N_CURSOR_CHANGELOG_AUTOFIX=1`, виставляється лише кроком
|
|
24
|
-
* `npm-changelog` у `hk.pkl` для pre-commit): замість `fail` на відсутній change-файл
|
|
25
|
-
* правило саме створює його через `writeChange()` з дефолтами (`bump=patch`,
|
|
26
|
-
* `section=Changed`, `message` = subject останнього коміту) і ставить у git-індекс, щоб
|
|
27
|
-
* коміт не падав. Поза хуком (CI, ручний `fix`/`check`, read-only review) режим вимкнено —
|
|
28
|
-
* поведінка лишається fail-on-missing, тож CI не плодить артефактів.
|
|
29
|
-
*/
|
|
1
|
+
/** @see ./docs/consistency.md */
|
|
30
2
|
import { execFile } from 'node:child_process'
|
|
31
3
|
import { join } from 'node:path'
|
|
32
4
|
import { promisify } from 'node:util'
|
|
@@ -1,22 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Концерн `marksman_config` правила ci4 (ci4.mdc): копіює canonical
|
|
3
|
-
* `.marksman.toml` baseline у корінь cwd, якщо файлу ще немає.
|
|
4
|
-
*
|
|
5
|
-
* Marksman LSP читає `.marksman.toml` для визначення workspace-роота,
|
|
6
|
-
* GLFM-флага (GitHub-Flavored Markdown), стилю wiki-links і code actions.
|
|
7
|
-
* Дефолти marksman не вмикають GLFM і використовують `title-slug-ref` —
|
|
8
|
-
* але portable subset з ci4.mdc вимагає GLFM (alerts/таблиці/todo) +
|
|
9
|
-
* `file-stem` (ADR slug == ім'я файла). Без явного конфіга частина
|
|
10
|
-
* marksman-функцій працює інакше, ніж задокументовано у правилі.
|
|
11
|
-
*
|
|
12
|
-
* Idempotent: якщо `.marksman.toml` вже існує (навіть з кастомним вмістом)
|
|
13
|
-
* — не перетирається, тільки рапортується факт існування. Ручні правки
|
|
14
|
-
* користувача зберігаються між прогонами.
|
|
15
|
-
*
|
|
16
|
-
* Файл скопійовано в `cwd`, бо marksman визначає workspace-root за
|
|
17
|
-
* розташуванням свого `.marksman.toml`. У корені репо марксман бачить
|
|
18
|
-
* і docs/, і README.md усіх workspaces одним workspace-ом.
|
|
19
|
-
*/
|
|
1
|
+
/** @see ./docs/marksman_config.md */
|
|
20
2
|
import { existsSync } from 'node:fs'
|
|
21
3
|
import { copyFile } from 'node:fs/promises'
|
|
22
4
|
import { dirname, join, relative } from 'node:path'
|
package/rules/docker/js/lint.mjs
CHANGED
|
@@ -1,37 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Запускає hadolint для Dockerfile / Containerfile у всьому репозиторії (див. docker.mdc).
|
|
3
|
-
*
|
|
4
|
-
* Додатково переконуються, що образи `oven/bun`, `alpine`, `nginx`, `node` з Docker Hub
|
|
5
|
-
* вказуються через `mirror.gcr.io` (див. `./docker-mirror.mjs`).
|
|
6
|
-
*
|
|
7
|
-
* Також перевіряє, що Dockerfile/Containerfile має **multistage build** і що фінальний stage
|
|
8
|
-
* використовує дозволений runtime-образ (див. docker.mdc):
|
|
9
|
-
* - backend: `mirror.gcr.io/library/alpine:*`, `scratch`, `mirror.gcr.io/library/debian:` з тегом, що
|
|
10
|
-
* містить `slim` (не повний `debian:bookworm`), за винятком PHP/Python — `mirror.gcr.io/library/php:*` або
|
|
11
|
-
* `mirror.gcr.io/library/python:*`
|
|
12
|
-
* - frontend: `mirror.gcr.io/nginxinc/nginx-unprivileged:*`, `mirror.gcr.io/openresty/openresty:*`
|
|
13
|
-
*
|
|
14
|
-
* Якщо в Dockerfile є крок `bun install` і це не frontend-образ (фінальний stage — alpine),
|
|
15
|
-
* то очікується компіляція в один бінарник через `bun build --compile` у build stage, а у
|
|
16
|
-
* фінальному stage не повинно залишатися build tooling (Bun/Node).
|
|
17
|
-
*
|
|
18
|
-
* Виняток — проєкти з нативним `.node`-аддоном (sharp/@img/argon2), який вантажиться через
|
|
19
|
-
* динамічний `require`: їх НЕ можна компілювати (`bun build --compile` не вшиває нативний
|
|
20
|
-
* біндинг → краш у рантаймі). Для них канон — node_modules + `bun <entry>` на базі
|
|
21
|
-
* `mirror.gcr.io/oven/bun:alpine` (див. `../lib/docker-native-addon.mjs`).
|
|
22
|
-
*
|
|
23
|
-
* Мета — щоб у фінальному образі не було build tooling (Bun/Node та залежностей), а лише
|
|
24
|
-
* дозволений runtime (alpine, scratch, debian slim, за потреби php/python, nginx або openresty).
|
|
25
|
-
*
|
|
26
|
-
* Для nginx-образів (`mirror.gcr.io/nginxinc/nginx-unprivileged`) у будь-якому `FROM` очікується
|
|
27
|
-
* тег `alpine-slim` (docker.mdc: мінімальні образи), не `latest` /
|
|
28
|
-
* `alpine` / інші. `nginx-unprivileged` запускається від не-root користувача (uid=101) без явного
|
|
29
|
-
* `USER` у Dockerfile — перевірка non-root для нього пропускається.
|
|
30
|
-
*
|
|
31
|
-
* Знаходить Dockerfile, Dockerfile.*, Containerfile, Containerfile.*; пропускає node_modules, .git
|
|
32
|
-
* тощо. hadolint — нативний бінарник через `ensureTool` (PATH/кеш/авто-install; без docker run).
|
|
33
|
-
* Кореневий .hadolint.yaml підхоплюється hadolint автоматично.
|
|
34
|
-
*/
|
|
1
|
+
/** @see ./docs/lint.md */
|
|
35
2
|
import { readFile } from 'node:fs/promises'
|
|
36
3
|
import { basename, dirname, join } from 'node:path'
|
|
37
4
|
|
package/rules/ga/docs/fix.md
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
## Гарантії поведінки
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
- Запускає процес.
|
|
23
|
+
- Кеш зберігає результати попередніх прогонів.
|
|
24
|
+
- Результат залежить від попередніх прогонів.
|
|
25
|
+
- Немає взаємодії з мережею.
|
package/rules/ga/js/docs/lint.md
CHANGED
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
## Поведінка
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
- `checkShellcheckInstalled`: Перевіряє наявність бінарника `shellcheck` в системному PATH.
|
|
10
|
+
- `checkGaWorkflowFiles`: Перевіряє наявність workflow-файлів з розширенням `.yml` та відсутність інших розширень.
|
|
11
|
+
- `runAllGaRego`: Запускає Rego-перевірки для всіх workflow-файлів, використовуючи `conftest` для аналізу.
|
|
12
|
+
- `check`: Координує всі перевірки, включаючи Rego-аналіз, перевірку workflow-структури та перевірку наявність файлів.
|
|
13
13
|
|
|
14
14
|
## Публічний API
|
|
15
15
|
|
|
@@ -20,13 +20,13 @@
|
|
|
20
20
|
|
|
21
21
|
## Гарантії поведінки
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
- Гарантується наявність файлів `package.json`, `.vscode/*` та `.github/zizmor.yml`.
|
|
24
|
+
- Гарантується, що workflow використовує `actions/checkout@v6` перед локальними операціями.
|
|
25
|
+
- Гарантується, що workflow використовує composite action `action.yml` з `npx @nitra/cursor`.
|
|
26
|
+
- Гарантується, що workflow містить `clean-ga-workflows.yml`, `clean-merged-branch.yml`, `lint-ga.yml` та `git-ai.yml`.
|
|
27
|
+
- Гарантується, що workflow використовує `concurrency` для паралельного виконання.
|
|
28
|
+
- Гарантується, що workflow не містить `oven-sh/setup-bun`, `actions/cache`, `bun install` у `uses` або `run`.
|
|
29
|
+
- Гарантується, що workflow не використовує shell-продовження `\` у `run`.
|
|
30
|
+
- Гарантується, що workflow використовує `shellcheck` локально.
|
|
31
|
+
- Гарантується, що workflow перевіряє наявність файлів за допомогою `git ls-files :(glob)` та `on.*.paths`.
|
|
32
|
+
- Гарантується, що workflow перевіряє наявність файлів, що залишилися від MegaLinter.
|
|
@@ -1,19 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевіряє GitHub Actions за правилом ga.mdc.
|
|
3
|
-
*
|
|
4
|
-
* Workflows лише з розширенням `.yml`, наявність clean/lint workflow,
|
|
5
|
-
* відсутність MegaLinter, виклик у `lint-ga.yml`,
|
|
6
|
-
* наявність composite `.github/actions/setup-bun-deps/action.yml` (його записує npx `\@nitra/cursor`),
|
|
7
|
-
*
|
|
8
|
-
* Структурні поля 4 канонічних workflow (`clean-ga-workflows.yml`, `clean-merged-branch.yml`,
|
|
9
|
-
* `lint-ga.yml`, `git-ai.yml`) і УНІВЕРСАЛЬНІ перевірки для всіх `.github/workflows/*.yml`
|
|
10
|
-
* (`concurrency`, заборонені `oven-sh/setup-bun` / `actions/cache` / `bun install` у `uses`/`run`,
|
|
11
|
-
* shell-продовження `\` у `run`, обов'язковий `actions/checkout@v6` перед локальним
|
|
12
|
-
* `setup-bun-deps`), а також `package.json`, `.vscode/*` і `.github/zizmor.yml` —
|
|
13
|
-
* у Rego-полісі під `npm/policy/ga/`. Тут лишилися FS/git/tooling перевірки:
|
|
14
|
-
* наявність файлів, MegaLinter leftovers, `on.*.paths` через `git ls-files :(glob)`,
|
|
15
|
-
* і локальний `shellcheck`.
|
|
16
|
-
*/
|
|
1
|
+
/** @see ./docs/workflows.md */
|
|
17
2
|
import { existsSync } from 'node:fs'
|
|
18
3
|
import { readdir, readFile } from 'node:fs/promises'
|
|
19
4
|
import { execFileSync } from 'node:child_process'
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Огляд
|
|
4
4
|
|
|
5
|
-
Файл надає CLI-обгортку для інструменту `lint-ga`, який автоматично встановлює необхідні інструменти, такі як `shellcheck` та `conftest`, для перевірки коду. Він послідовно виконує перевірку коду за допомогою Rego та JavaScript, забезпечуючи узгодженість з правилами `ga.mdc`.
|
|
5
|
+
Файл надає CLI-обгортку для інструменту `lint-ga`, який автоматично встановлює необхідні інструменти, такі як `shellcheck` та `conftest`, для перевірки коду. Він послідовно виконує перевірку коду за допомогою Rego та JavaScript, забезпечуючи узгодженість з правилами `ga.mdc`. Цей файл служить централізованим джерелом для виконання та налаштування процесу linting, що спрощує інтеграцію в CI/CD.
|
|
6
6
|
|
|
7
7
|
## Поведінка
|
|
8
8
|
|
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
|
|
18
18
|
## Гарантії поведінки
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
- `ensureTool` встановлює `shellcheck` та `conftest` згідно з обраним методом встановлення (brew, scoop, GitHub Release).
|
|
21
|
+
- Якщо `uv` не встановлено, `uvx zizmor` завершується з помилкою.
|
|
22
|
+
- `bunx github-actionlint` пропускає shell-перевірки в `run:` блоках, якщо `shellcheck` не вказаний у PATH.
|
|
23
|
+
- `runLintGaCli` повертає `false` або `null` при помилках, не викликаючи виняток.
|
|
24
|
+
- Не використовується кешування.
|
|
25
|
+
- `uvx zizmor` вимагає наявності `uv`.
|
|
26
|
+
- Логіка встановлення та запуску перевірок централізована у `rules/ga/fix.mjs`.
|
|
27
|
+
- `runLintGaCli` використовується як підкоманда `lint-ga`.
|
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевіряє правило graphql.mdc: наявність **`.graphqlrc.yml`** і рекомендації
|
|
3
|
-
* **`graphql.vscode-graphql`**, якщо у дереві є **`gql\`…\``**.
|
|
4
|
-
*
|
|
5
|
-
* Обхід репозиторію — **`walkDir`** від **`process.cwd()`** (пропуски як у інших check). Кандидати — **`.vue`** та **`.js`/`.ts`/`.jsx`/`.tsx`** тощо; пропуск **`.d.ts`**, **auto-imports.d.ts** тощо — **`shouldSkipFileForGqlScan`**.
|
|
6
|
-
*
|
|
7
|
-
* Виявлення **`gql`** — **oxc-parser** після витягування `<script>` з SFC (**`graphql-gql-scan.mjs`**). Якщо збігів немає — перевірка завершується успішно без вимог до конфігів.
|
|
8
|
-
* @param {string} cwd корінь репозиторію
|
|
9
|
-
*/
|
|
1
|
+
/** @see ./docs/tooling.md */
|
|
10
2
|
import { existsSync } from 'node:fs'
|
|
11
3
|
import { readFile } from 'node:fs/promises'
|
|
12
4
|
import { join, relative } from 'node:path'
|
|
@@ -1,27 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевіряє правило hasura.mdc для проєктів **nitra** і **abie**: значення
|
|
3
|
-
* `HASURA_GRAPHQL_ENDPOINT` у `*.env` має бути **внутрішнім** кластерним URL,
|
|
4
|
-
* а не публічним доменом.
|
|
5
|
-
*
|
|
6
|
-
* Запускається лише якщо в кореневому `package.json` поле `repository`
|
|
7
|
-
* вказує на `https://github.com/nitra/...` або `https://github.com/abinbevefes/...`
|
|
8
|
-
* (інші репозиторії пропускаються без помилок — як у abie-перевірках).
|
|
9
|
-
*
|
|
10
|
-
* Очікуваний формат URL — кластерний DNS-суфікс `<cluster>.internal`:
|
|
11
|
-
* - GKE / GCP: `http://<service>.<namespace>.svc.<cluster>.internal:<port>`
|
|
12
|
-
* приклад: `http://contract-h-hl.ua-contract.svc.abie-ua.internal:8080`
|
|
13
|
-
*
|
|
14
|
-
* Сегменти беруться з `hasura/k8s/base/svc-hl.yaml` (`metadata.name` —
|
|
15
|
-
* headless, має закінчуватись на `-h-hl`; див. `hasura.svc_hl` / k8s.svc_hl_yaml) і
|
|
16
|
-
* `hasura/k8s/base/namespace.yaml`
|
|
17
|
-
* (`metadata.name` — namespace). Якщо ці YAML є в репозиторії, у URL додатково
|
|
18
|
-
* звіряються конкретні `<service>` і `<namespace>` з ними.
|
|
19
|
-
*
|
|
20
|
-
* Скануються всі файли `*.env` (наприклад `dev.env`, `production.env`); файл
|
|
21
|
-
* `.env` без імені — виключення з правила (локальний файл розробника), його
|
|
22
|
-
* не перевіряємо. Пропускаються `node_modules`, `.git`, `dist`, `coverage`,
|
|
23
|
-
* `.turbo`, `.next` (як у `walkDir`).
|
|
24
|
-
*/
|
|
1
|
+
/** @see ./docs/internal_urls.md */
|
|
25
2
|
import { existsSync } from 'node:fs'
|
|
26
3
|
import { readFile } from 'node:fs/promises'
|
|
27
4
|
import { basename, join, relative } from 'node:path'
|
|
@@ -1,30 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевіряє відповідність репозиторію правилу `image-avif.mdc`: AVIF-генерацію та
|
|
3
|
-
* ув'язування `.avif`-двійників з посиланнями у `.vue`/`.html`.
|
|
4
|
-
*
|
|
5
|
-
* Дії під час `check image-avif`:
|
|
6
|
-
* 1. **Pre-scan**: знайти в `.vue`/`.html` хоча б одне raster-посилання, яке потенційно
|
|
7
|
-
* можна переписати на AVIF-двійник (через `import x from '...png'` або
|
|
8
|
-
* `<img src="...png" />`). Пакети з opt-out `disable-avif: true` пропускаються.
|
|
9
|
-
* Якщо жодного raster-посилання не знайдено → exit 0 одразу (`npx --avif` не запускаємо,
|
|
10
|
-
* rewrite/cleanup-пасс теж пропускаємо — нічого не змінилось би).
|
|
11
|
-
* 2. `npx \@nitra/minify-image --src=. --write --avif` — генерує AVIF-двійники.
|
|
12
|
-
* 3. У кожному workspace-пакеті переписує raster-посилання у `.vue`/`.html` на `.avif`
|
|
13
|
-
* (де AVIF-двійник реально існує на диску). Pakety з `"\@nitra/minify-image": {
|
|
14
|
-
* "disable-avif": true }` у `package.json` пропускаються.
|
|
15
|
-
* 4. Прибирає AVIF-сироти — `<name>.<ext>.avif`, на які не лишилось жодного посилання
|
|
16
|
-
* у `.vue`/`.html` репозиторію, видаляються (умова правила: «AVIF лишається лише
|
|
17
|
-
* там, де заміна вдалася»).
|
|
18
|
-
*
|
|
19
|
-
* Якщо raster-посилання у `.vue`/`.html` не вдалось переписати (наприклад, оригіналу
|
|
20
|
-
* нема на диску → `.avif` теж не згенерувався) — фейл на конкретний файл.
|
|
21
|
-
*
|
|
22
|
-
* Правило самостійне від `image-compress`: AVIF можна вмикати лише в адмінках (де AVIF
|
|
23
|
-
* підтримується сучасними браузерами) і не вмикати в публічних сайтах. Перевірка скрипта
|
|
24
|
-
* `lint-image` (заборона `--avif` у ньому) залишається у `image-compress` — тут вона не
|
|
25
|
-
* дублюється.
|
|
26
|
-
* @param {string} cwd корінь репозиторію
|
|
27
|
-
*/
|
|
1
|
+
/** @see ./docs/avif_generation.md */
|
|
28
2
|
import { existsSync } from 'node:fs'
|
|
29
3
|
import { readFile, unlink, writeFile } from 'node:fs/promises'
|
|
30
4
|
import { join, relative } from 'node:path'
|
|
@@ -1,21 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевіряє вимоги правила `image-compress.mdc` для оптимізації raster/SVG через
|
|
3
|
-
* `@nitra/minify-image` ≥ 3.2.0 (локально).
|
|
4
|
-
*
|
|
5
|
-
* **Що тут лишилося** (FS / cross-file):
|
|
6
|
-
* - наявність `package.json` у корені;
|
|
7
|
-
* - `.n-minify-image.tsv` (committed source of truth з sha1/originalSize/size) НЕ
|
|
8
|
-
* в `.gitignore` — він має бути в git;
|
|
9
|
-
* - застарілий `.minify-image-cache.tsv` (з версій < 3.2) видалений з кореня та
|
|
10
|
-
* з `.gitignore`.
|
|
11
|
-
*
|
|
12
|
-
* **Що покрила Rego** (`npx \@nitra/cursor fix`,
|
|
13
|
-
* `npm/rules/image-compress/policy/package_json/`):
|
|
14
|
-
* - `scripts.lint-image` викликає `npx \@nitra/minify-image --src=. --write`
|
|
15
|
-
* без `--avif` (AVIF — окреме правило `image-avif`);
|
|
16
|
-
* - агрегований `lint` (якщо є) містить `bun run lint-image`;
|
|
17
|
-
* - `@nitra/minify-image` НЕ у `dependencies` / `devDependencies` (через `npx`).
|
|
18
|
-
*/
|
|
1
|
+
/** @see ./docs/package_setup.md */
|
|
19
2
|
import { existsSync } from 'node:fs'
|
|
20
3
|
import { readFile } from 'node:fs/promises'
|
|
21
4
|
import { join } from 'node:path'
|
|
@@ -1,34 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевіряє правило js-bun-db.mdc.
|
|
3
|
-
*
|
|
4
|
-
* 1) У жодному `package.json` (включно з workspace-пакетами) у `dependencies` не повинно
|
|
5
|
-
* бути `pg-format` чи `mysql2` — їх треба замінити на Bun native SQL
|
|
6
|
-
* (`import { sql, SQL } from 'bun'`, https://bun.com/docs/runtime/sql). `pg-format` —
|
|
7
|
-
* ручне форматування SQL через escape; tagged template Bun SQL параметризує значення
|
|
8
|
-
* нативно і не лишає простору для injection. Перевірка цих двох — у Rego-полісі
|
|
9
|
-
* `npm/policy/js_bun_db/package_json/`.
|
|
10
|
-
*
|
|
11
|
-
* 2) Для `pg` діє виключення: Bun SQL поки не реалізує LISTEN/NOTIFY, тож якщо у
|
|
12
|
-
* проекті знайдено реальне використання `LISTEN ...` / `NOTIFY ...` / `UNLISTEN ...`
|
|
13
|
-
* або listener'а `.on('notification', ...)`, dependency `pg` дозволено. Інакше
|
|
14
|
-
* `pg` лишається забороненим — fail з підказкою про виключення. Додатково — per-file:
|
|
15
|
-
* кожен файл з `import ... from 'pg'` повинен сам містити LISTEN/NOTIFY-патерн;
|
|
16
|
-
* звичайні SELECT/INSERT/UPDATE через `pg` (replace на Bun SQL!) не дозволені.
|
|
17
|
-
*
|
|
18
|
-
* 3) Якщо в коді використовується Bun SQL (імпорт `sql`/`SQL` з `'bun'`), додатково
|
|
19
|
-
* перевіряє небезпечні патерни:
|
|
20
|
-
* - `new SQL(...)` всередині функції (пул має бути singleton на рівні модуля).
|
|
21
|
-
* - Будь-який `<obj>.unsafe(...)` без маркера-коментаря `// allow-unsafe: <reason>`
|
|
22
|
-
* на тому ж рядку або рядком вище. `sql.unsafe` за замовчуванням заборонено;
|
|
23
|
-
* допустимий лише для підстановки назви таблиці/колонки чи dynamic SQL/DDL,
|
|
24
|
-
* коли значення контролюється кодом (не user input) — в інших випадках
|
|
25
|
-
* переробляємо на tagged template `sql\`...\${value}...\``.
|
|
26
|
-
* - pg-leftover виклики `<obj>.connect(...)` / `<obj>.end(...)` у файлах, що
|
|
27
|
-
* імпортують Bun SQL: пулом керує Bun, життєвий цикл вручну не потрібен.
|
|
28
|
-
* Opt-out — маркер `// allow-pg-leftover: <reason>`.
|
|
29
|
-
* - Динамічні SQL-списки через `.join(',')` у `IN (...)` / `VALUES (...)`
|
|
30
|
-
* (треба `sql([...])`).
|
|
31
|
-
*/
|
|
1
|
+
/** @see ./docs/safety.md */
|
|
32
2
|
import { existsSync } from 'node:fs'
|
|
33
3
|
import { readFile } from 'node:fs/promises'
|
|
34
4
|
import { join, relative } from 'node:path'
|
|
@@ -1,15 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевіряє правило `js-bun-redis.mdc`.
|
|
3
|
-
*
|
|
4
|
-
* Заборонено в JS/TS-джерелах будь-який `import` / `require` / динамічний `import()` пакетів
|
|
5
|
-
* `ioredis`, `node-redis`, `redis` (та підпакетів `@redis/*`, підшляхів `ioredis/...` /
|
|
6
|
-
* `redis/...`). Замість них треба використовувати Bun native Redis:
|
|
7
|
-
* `import { redis } from 'bun'` (<https://bun.com/docs/runtime/redis>).
|
|
8
|
-
*
|
|
9
|
-
* Перевірку `dependencies` (заборона `ioredis` / `node-redis` / `redis` / `@redis/*` у будь-якому
|
|
10
|
-
* `package.json`) винесено в Rego-полісі `npm/policy/js_bun_redis/package_json/`; її запускає
|
|
11
|
-
* `npx \@nitra/cursor check`. Тут лишився AST-скан коду через `oxc-parser`.
|
|
12
|
-
*/
|
|
1
|
+
/** @see ./docs/imports.md */
|
|
13
2
|
import { existsSync } from 'node:fs'
|
|
14
3
|
import { readFile } from 'node:fs/promises'
|
|
15
4
|
import { join, relative } from 'node:path'
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# lint-findings.mjs
|
|
2
|
+
|
|
3
|
+
## Огляд
|
|
4
|
+
|
|
5
|
+
Цей файл обробляє результати аналізу коду, отримані з інструментів oXlint та eslint, для визначення, чи є знайдені проблеми нові (в diff) чи існують у файлі з самого початку. Він класифікує ці результати, надаючи інформацію про файл та рядок, де проблема виявлена, що допомагає у відстеженні та вирішенні помилок. Це частина системи беклогу #6, яка автоматизує процес класифікації lint-findings.
|
|
6
|
+
|
|
7
|
+
## Поведінка
|
|
8
|
+
|
|
9
|
+
parseOxlint: аналізує JSON-вихід `oxlint --format=json` та повертає список findings з інформацією про файл, рядок, правило та повідомлення.
|
|
10
|
+
parseEslint: аналізує JSON-вихід `eslint --format=json` та повертає список findings з інформацією про файл, рядок, правило та повідомлення.
|
|
11
|
+
classifyFindings: класифікує findings як introduced або pre-existing на основі доданих рядків, використовуючи Map.
|
|
12
|
+
renderFindings: генерує текстовий звіт з розділенням findings на introduced та pre-existing, використовуючи формат `🆕 introduced` та `🗄 pre-existing`.
|
|
13
|
+
|
|
14
|
+
## Публічний API
|
|
15
|
+
|
|
16
|
+
- parseOxlint — Перетворює JSON з результатів інструменту Oxlint на внутрішній об'єкт.
|
|
17
|
+
- parseEslint — Перетворює JSON з результатів інструменту ESLint на внутрішній об'єкт.
|
|
18
|
+
- classifyFindings — Розподіляє знайдені проблеми на нові (introduced) та існуючі (pre-existing).
|
|
19
|
+
- renderFindings — Створює звіт, об'єднуючи нові та існуючі проблеми.
|
|
20
|
+
|
|
21
|
+
## Гарантії поведінки
|
|
22
|
+
|
|
23
|
+
- Функція `parseOxlint` повертає JSON-об'єкт, що містить список діагностик, або `null` у разі помилки парсингу.
|
|
24
|
+
- Функція `parseEslint` повертає масив об'єктів, що містять повідомлення про помилки, або `null` у разі помилки парсингу.
|
|
25
|
+
- Функція `classifyFindings` повертає масив об'єктів, що представляють класифіковані результати, або `null` у разі помилки класифікації.
|
|
26
|
+
- Функція `renderFindings` повертає рядок, що містить представлення результатів, або `null` у разі помилки рендерингу.
|
|
27
|
+
- У разі невдачі будь-якої з функцій, повертається `false`.
|
|
28
|
+
- Функції не кидають винятків.
|
|
29
|
+
- Шляхи файлів, що передаються вхідним функціям, є абсолютними.
|
|
30
|
+
- Результати функцій не кешуються.
|