@nitra/cursor 1.28.1 → 1.28.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 +14 -0
- package/package.json +1 -1
- package/rules/efes/efes.mdc +5 -5
- package/rules/efes/policy/package_json_shared/package_json_shared.rego +16 -0
- package/rules/efes/policy/{package_json_docs → package_json_shared}/target.json +1 -1
- package/rules/graphql/graphql.mdc +1 -1
- package/rules/rust/coverage/coverage.mjs +29 -2
- package/rules/rust/rust.mdc +2 -2
- package/rules/tauri/js/cargo_mutants_config.mjs +3 -0
- package/rules/tauri/tauri.mdc +3 -1
- package/rules/efes/policy/package_json_docs/package_json_docs.rego +0 -16
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,20 @@
|
|
|
4
4
|
|
|
5
5
|
Формат — [Keep a Changelog](https://keepachangelog.com/uk/1.1.0/), нумерація — [SemVer](https://semver.org/lang/uk/).
|
|
6
6
|
|
|
7
|
+
## [1.28.3] - 2026-05-28
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- **`rules/efes/`** — слідом за перейменуванням `@nitra/efes-docs` → `@nitra/efes-shared` (репо `efes-cloud/docs` → `efes-cloud/shared`): rego-полісі `npm/rules/efes/policy/package_json_docs/` перейменовано на `package_json_shared/`, namespace `efes.package_json_docs` → `efes.package_json_shared`, перевірка тепер шукає `@nitra/efes-shared` у `devDependencies`. Оновлено `efes.mdc` (version `1.1` → `1.2`) та шлях до GraphQL-схеми у `graphql.mdc` (`node_modules/@nitra/efes-shared/schema/maya.graphql`). Споживачі efes-проєктів мають перейти на `@nitra/efes-shared`.
|
|
12
|
+
|
|
13
|
+
## [1.28.2] - 2026-05-28
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- **`rules/rust/coverage/coverage.mjs`** — `cargo mutants` запускається з `--jobs N` (дефолт `min(4, cpus/2)`, override через env `CARGO_MUTANTS_JOBS`). Прапорець `--in-place` прибраний — cargo-mutants створює власну sandbox-копію в `target/mutants.<i>/`, що **обов'язкове** для `--jobs > 1`. Ефект: ~7× прискорення Rust mutation testing на 8-ядерних машинах (виміряно на Tauri-проєкті: 8 год → ~65 хв). Edge-case `--in-place` лишається доступним користувачам напряму через `cargo mutants --in-place` (наш runner його більше не передає). Експортовано `resolveJobs(envValue)` і `buildCargoMutantsArgs({ manifestPath, outDir, jobs })` як чисті функції для unit-тестів.
|
|
18
|
+
- **`rules/tauri/js/cargo_mutants_config.mjs#TAURI_KEY_SNIPPETS.exclude_globs`** — додано `src/lib.rs` як Tauri runtime entrypoint (`pub fn run`). Один мутант там тримає весь app shell, тому ділить sandbox-фейл з `src/main.rs`. Дзеркальна правка в `tauri.mdc` (canon-TOML і пояснення семантики).
|
|
19
|
+
- **`rules/rust/rust.mdc`** (`version` 1.1 → 1.2), **`rules/tauri/tauri.mdc`** (`version` 1.3 → 1.4) — актуалізовано опис паралельного запуску cargo-mutants і Tauri exclude_globs.
|
|
20
|
+
|
|
7
21
|
## [1.28.0] - 2026-05-27
|
|
8
22
|
|
|
9
23
|
### BREAKING
|
package/package.json
CHANGED
package/rules/efes/efes.mdc
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Правила для проєктів Efes (репозиторії під github.com/efes-cloud)
|
|
3
3
|
alwaysApply: true
|
|
4
|
-
version: '1.
|
|
4
|
+
version: '1.2'
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
Правило **efes** для споживачів **@nitra/cursor** у репозиторіях під **`github.com/efes-cloud/*`**.
|
|
8
8
|
|
|
9
|
-
## `@nitra/efes-
|
|
9
|
+
## `@nitra/efes-shared` у `devDependencies`
|
|
10
10
|
|
|
11
|
-
У кореневому **`package.json`** efes-проєкту в **`devDependencies`** має бути **`@nitra/efes-
|
|
11
|
+
У кореневому **`package.json`** efes-проєкту в **`devDependencies`** має бути **`@nitra/efes-shared`** — пакет зі спільними efes-ресурсами (схеми, скіли, типи; зокрема використовується у `graphql.mdc` як `node_modules/@nitra/efes-shared/schema/maya.graphql`). Версію правило не фіксує — лише presence. Додати:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
bun add -d @nitra/efes-
|
|
14
|
+
bun add -d @nitra/efes-shared
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
## Швидкий gate через conftest (Rego)
|
|
@@ -20,4 +20,4 @@ bun add -d @nitra/efes-docs
|
|
|
20
20
|
|
|
21
21
|
Пакети (директорія в **`npm/rules/efes/policy/`** → namespace → що перевіряє):
|
|
22
22
|
|
|
23
|
-
- **`
|
|
23
|
+
- **`package_json_shared/`** → `efes.package_json_shared` — у кореневому `package.json` `devDependencies` має містити `@nitra/efes-shared` (presence-only, версію не фіксуємо). **Цільові файли:** `package.json`.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Перевірка кореневого `package.json` efes-проєкту: у `devDependencies` має бути
|
|
2
|
+
# `@nitra/efes-shared` (спільні efes-ресурси — схеми, скіли, типи; використовується,
|
|
3
|
+
# зокрема, у `graphql.mdc` як `node_modules/@nitra/efes-shared/schema/maya.graphql`).
|
|
4
|
+
# Версію не фіксуємо — лише presence.
|
|
5
|
+
#
|
|
6
|
+
# Inverse-presence перевірка лишається inline у rego (як `@nitra/cspell-dict`
|
|
7
|
+
# у `text.package_json`).
|
|
8
|
+
package efes.package_json_shared
|
|
9
|
+
|
|
10
|
+
import rego.v1
|
|
11
|
+
|
|
12
|
+
deny contains msg if {
|
|
13
|
+
dev := object.get(input, "devDependencies", {})
|
|
14
|
+
not "@nitra/efes-shared" in object.keys(dev)
|
|
15
|
+
msg := "package.json: devDependencies має містити @nitra/efes-shared — bun add -d @nitra/efes-shared (efes.mdc)"
|
|
16
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://unpkg.com/@nitra/cursor/schemas/target.json",
|
|
3
3
|
"files": { "single": "package.json", "required": true },
|
|
4
|
-
"missingMessage": "package.json не існує — створи його, додай devDependencies['@nitra/efes-
|
|
4
|
+
"missingMessage": "package.json не існує — створи його, додай devDependencies['@nitra/efes-shared'] (efes.mdc)"
|
|
5
5
|
}
|
|
@@ -15,7 +15,7 @@ alwaysApply: false
|
|
|
15
15
|
Підстав свої шляхи до схеми та до файлів з операціями; приклад орієнтиру:
|
|
16
16
|
|
|
17
17
|
```yaml title=".graphqlrc.yml"
|
|
18
|
-
schema: node_modules/@nitra/efes-
|
|
18
|
+
schema: node_modules/@nitra/efes-shared/schema/maya.graphql
|
|
19
19
|
documents:
|
|
20
20
|
- '**/*.{vue,js,ts,tsx}'
|
|
21
21
|
```
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import { spawnSync } from 'node:child_process'
|
|
10
10
|
import { existsSync } from 'node:fs'
|
|
11
11
|
import { mkdtemp, readFile, rm } from 'node:fs/promises'
|
|
12
|
-
import { tmpdir } from 'node:os'
|
|
12
|
+
import { cpus, tmpdir } from 'node:os'
|
|
13
13
|
import { join } from 'node:path'
|
|
14
14
|
|
|
15
15
|
import { hasCargoTomlInTree } from '../lib/has-cargo-toml.mjs'
|
|
@@ -27,6 +27,32 @@ export function detect(cwd) {
|
|
|
27
27
|
return Promise.resolve(hasCargoTomlInTree(cwd, IGNORED_DIR_NAMES))
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Обчислює кількість паралельних воркерів cargo-mutants. Env override через
|
|
32
|
+
* CARGO_MUTANTS_JOBS (валідне ціле >= 1). Fallback — min(4, max(1, cpus/2)):
|
|
33
|
+
* на ≤2 ядрах = 1, на 4 = 2, на 8+ = 4. Стеля 4 — Rust linker bottleneck:
|
|
34
|
+
* вище практичного приросту не дає навіть на 16+ ядрах.
|
|
35
|
+
* @param {string | undefined} envValue значення `process.env.CARGO_MUTANTS_JOBS`
|
|
36
|
+
* @returns {number}
|
|
37
|
+
*/
|
|
38
|
+
export function resolveJobs(envValue) {
|
|
39
|
+
if (envValue !== undefined && envValue !== '') {
|
|
40
|
+
const n = Number.parseInt(envValue, 10)
|
|
41
|
+
if (Number.isFinite(n) && n >= 1) return n
|
|
42
|
+
}
|
|
43
|
+
return Math.min(4, Math.max(1, Math.floor(cpus().length / 2)))
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Будує argv для `cargo mutants`. `--in-place` навмисно відсутній: cargo-mutants
|
|
48
|
+
* створює власну sandbox-копію в `target/mutants.<i>/`, що обов'язкове для `--jobs > 1`.
|
|
49
|
+
* @param {{ manifestPath: string, outDir: string, jobs: number }} opts
|
|
50
|
+
* @returns {string[]}
|
|
51
|
+
*/
|
|
52
|
+
export function buildCargoMutantsArgs({ manifestPath, outDir, jobs }) {
|
|
53
|
+
return ['mutants', '--jobs', String(jobs), '-o', outDir, '--manifest-path', manifestPath]
|
|
54
|
+
}
|
|
55
|
+
|
|
30
56
|
const defaultRunner = {
|
|
31
57
|
runLlvmCov({ manifestPath }) {
|
|
32
58
|
const r = spawnSync('cargo', ['llvm-cov', '--manifest-path', manifestPath, '--json', '--summary-only'], {
|
|
@@ -36,7 +62,8 @@ const defaultRunner = {
|
|
|
36
62
|
return { exitCode: r.status ?? 1, stdout: r.stdout?.toString('utf8') ?? '' }
|
|
37
63
|
},
|
|
38
64
|
runCargoMutants({ manifestPath, outDir }) {
|
|
39
|
-
const
|
|
65
|
+
const jobs = resolveJobs(process.env.CARGO_MUTANTS_JOBS)
|
|
66
|
+
const r = spawnSync('cargo', buildCargoMutantsArgs({ manifestPath, outDir, jobs }), {
|
|
40
67
|
stdio: 'inherit',
|
|
41
68
|
env: process.env
|
|
42
69
|
})
|
package/rules/rust/rust.mdc
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
description: Перевірка Rust коду
|
|
3
3
|
globs: "**/{Cargo.toml,Cargo.lock,rustfmt.toml,clippy.toml,.vscode/extensions.json,package.json},**/*.rs"
|
|
4
4
|
alwaysApply: false
|
|
5
|
-
version: '1.
|
|
5
|
+
version: '1.2'
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
**rustfmt** ([rust-lang/rustfmt](https://github.com/rust-lang/rustfmt)) — форматер; **clippy** ([rust-lang/rust-clippy](https://github.com/rust-lang/rust-clippy)) — лінтер. У скрипті **`lint-rust`** локально йдуть три кроки в одному рядку: `cargo fmt --all` → `cargo clippy --fix --allow-staged --allow-dirty --all-targets --all-features` → фінальний `cargo clippy --all-targets --all-features -- -D warnings`. У CI — без `--fix`: `cargo fmt --all -- --check` і `cargo clippy ... -- -D warnings` (див. `lint-rust.yml`).
|
|
@@ -28,4 +28,4 @@ Tauri-проєкт завжди має `src-tauri/Cargo.toml`, тому прав
|
|
|
28
28
|
|
|
29
29
|
## Покриття + мутаційне тестування Rust
|
|
30
30
|
|
|
31
|
-
Покриття + мутаційне тестування Rust постачаються через `n-cursor coverage` (правило `test.mdc`). Реалізація провайдера — у `npm/rules/rust/coverage/coverage.mjs`: `cargo llvm-cov --json --summary-only` + `cargo mutants --in-place`. Бінарники: `cargo install cargo-llvm-cov && cargo install cargo-mutants`.
|
|
31
|
+
Покриття + мутаційне тестування Rust постачаються через `n-cursor coverage` (правило `test.mdc`). Реалізація провайдера — у `npm/rules/rust/coverage/coverage.mjs`: `cargo llvm-cov --json --summary-only` + `cargo mutants --jobs N` (паралельні воркери, дефолт `min(4, cpus/2)`; override через env `CARGO_MUTANTS_JOBS`). Прапорець `--in-place` прибраний — cargo-mutants створює власну sandbox-копію в `target/mutants.<i>/`, що сумісне з `--jobs > 1`. Бінарники: `cargo install cargo-llvm-cov && cargo install cargo-mutants`.
|
|
@@ -37,8 +37,11 @@ const TAURI_KEY_SNIPPETS = Object.freeze({
|
|
|
37
37
|
exclude_globs: `# Platform bridge / app shell — boundary-файли (тестуються smoke/e2e, не mutation unit).
|
|
38
38
|
# Якщо у bridge-файлі з'являється pure/business logic — винеси її у platform-neutral
|
|
39
39
|
# модуль (src/auth/oauth.rs, src/gmail/message.rs, ...) і тестуй mutation-testing там.
|
|
40
|
+
# src/lib.rs (Tauri pub fn run) — runtime entrypoint, що запускає весь app shell:
|
|
41
|
+
# один мутант там тримає весь Tauri runtime, тому ділить sandbox-фейл з src/main.rs.
|
|
40
42
|
exclude_globs = [
|
|
41
43
|
"src/main.rs",
|
|
44
|
+
"src/lib.rs",
|
|
42
45
|
"src/**/android.rs",
|
|
43
46
|
"src/**/ios.rs",
|
|
44
47
|
"src/**/mobile.rs",
|
package/rules/tauri/tauri.mdc
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
description: Tauri
|
|
3
3
|
globs: "**/src-tauri/**,**/tauri.conf.json"
|
|
4
4
|
alwaysApply: false
|
|
5
|
-
version: '1.
|
|
5
|
+
version: '1.4'
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
У `.vscode/extensions.json` `recommendations` має містити `tauri-apps.tauri-vscode`:
|
|
@@ -36,6 +36,7 @@ additional_cargo_test_args = ["--lib", "--tests"]
|
|
|
36
36
|
|
|
37
37
|
exclude_globs = [
|
|
38
38
|
"src/main.rs",
|
|
39
|
+
"src/lib.rs",
|
|
39
40
|
"src/**/android.rs",
|
|
40
41
|
"src/**/ios.rs",
|
|
41
42
|
"src/**/mobile.rs",
|
|
@@ -49,6 +50,7 @@ exclude_globs = [
|
|
|
49
50
|
Семантика (фіксована між Tauri-проєктами):
|
|
50
51
|
|
|
51
52
|
- **`src/main.rs`** — binary shell entrypoint: запускає Tauri runtime, реєструє plugins/handlers і повертає управління циклу подій. Тестується smoke/e2e (запуск бінарника), не mutation unit;
|
|
53
|
+
- **`src/lib.rs`** — Tauri runtime entrypoint (`pub fn run`): піднімає весь app shell. Один мутант там тримає весь Tauri runtime, тому ділить sandbox-фейл з `src/main.rs` і тестується smoke/e2e, а не mutation unit;
|
|
52
54
|
- **`*android.rs`, `*ios.rs`, `*mobile.rs`** — mobile plugin bridge / platform glue: тонка обгортка над JNI/Objective-C виклики, mapping platform errors, виклики Tauri AppHandle і native API;
|
|
53
55
|
- **`*macos.rs`, `*windows.rs`, `*linux.rs`, `*desktop.rs`** — desktop platform bridge / OS integration glue: opener/window APIs, OS-specific I/O, mapping platform errors.
|
|
54
56
|
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# Перевірка кореневого `package.json` efes-проєкту: у `devDependencies` має бути
|
|
2
|
-
# `@nitra/efes-docs` (контракти/схеми efes-сервісів — використовується, зокрема,
|
|
3
|
-
# у `graphql.mdc` як `node_modules/@nitra/efes-docs/schema/maya.graphql`). Версію
|
|
4
|
-
# не фіксуємо — лише presence.
|
|
5
|
-
#
|
|
6
|
-
# Inverse-presence перевірка лишається inline у rego (як `@nitra/cspell-dict`
|
|
7
|
-
# у `text.package_json`).
|
|
8
|
-
package efes.package_json_docs
|
|
9
|
-
|
|
10
|
-
import rego.v1
|
|
11
|
-
|
|
12
|
-
deny contains msg if {
|
|
13
|
-
dev := object.get(input, "devDependencies", {})
|
|
14
|
-
not "@nitra/efes-docs" in object.keys(dev)
|
|
15
|
-
msg := "package.json: devDependencies має містити @nitra/efes-docs — bun add -d @nitra/efes-docs (efes.mdc)"
|
|
16
|
-
}
|