@7n/rules 1.43.1 → 1.44.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 +21 -0
- package/docs/vitest.config.md +14 -19
- package/package.json +1 -1
- package/rules/abie/lib/docs/index.md +0 -2
- package/rules/abie/lib/http-route.mjs +1 -0
- package/rules/abie/lib/yaml.mjs +2 -0
- package/rules/ci4/marksman_config/docs/index.md +10 -0
- package/rules/ci4/marksman_config/main.mjs +2 -0
- package/rules/doc-files/docgen-prompts/docs/index.md +9 -0
- package/rules/doc-files/docgen-prompts/main.mjs +5 -0
- package/rules/hasura/internal_urls/docs/index.md +0 -2
- package/rules/hasura/internal_urls/docs/main.md +27 -15
- package/rules/hasura/internal_urls/main.mjs +1 -0
- package/rules/image-avif/avif_generation/docs/index.md +10 -0
- package/rules/image-avif/avif_generation/main.mjs +2 -0
- package/rules/rego/vscode_settings/docs/fix-vscode_settings.md +12 -10
- package/rules/rego/vscode_settings/fix-vscode_settings.mjs +5 -0
- package/rules/tauri/cargo_mutants_config/docs/index.md +0 -2
- package/rules/tauri/cargo_mutants_config/docs/main.md +38 -12
- package/rules/tauri/cargo_mutants_config/main.mjs +5 -1
- package/rules/tauri/core_test_isolation/docs/main.md +19 -16
- package/rules/tauri/core_test_isolation/main.mjs +3 -1
- package/rules/tauri/linux_deps/docs/main.md +25 -18
- package/rules/tauri/linux_deps/main.mjs +2 -1
- package/rules/tauri/release/docs/main.md +20 -12
- package/rules/tauri/release/main.mjs +2 -0
- package/rules/tauri/updater/docs/main.md +31 -14
- package/rules/tauri/updater/main.mjs +4 -0
- package/rules/test/coverage/concern.json +9 -0
- package/rules/test/coverage/fix-worker.mjs +111 -0
- package/rules/test/coverage/lib/classify/apply.mjs +67 -0
- package/rules/test/coverage/lib/classify/cache.mjs +77 -0
- package/rules/test/coverage/lib/classify/docs/apply.md +28 -0
- package/rules/test/coverage/lib/classify/docs/cache.md +34 -0
- package/rules/test/coverage/lib/classify/docs/index.md +37 -0
- package/rules/test/coverage/lib/classify/docs/prompt.md +30 -0
- package/rules/test/coverage/lib/classify/docs/verdict-schema.md +30 -0
- package/rules/test/coverage/lib/classify/index.mjs +140 -0
- package/rules/test/coverage/lib/classify/prompt.mjs +136 -0
- package/rules/test/coverage/lib/classify/verdict-schema.mjs +163 -0
- package/rules/test/coverage/lib/llm.mjs +100 -0
- package/rules/test/coverage/main.mjs +161 -0
- package/rules/test/main.json +1 -0
- package/rules/test/main.mdc +140 -0
- package/rules/test/package_json/concern.json +11 -0
- package/rules/test/package_json/package_json.mdc +18 -0
- package/rules/test/package_json/package_json.rego +25 -0
- package/rules/test/package_json/template/package.json.contains.json +6 -0
- package/rules/text/oxfmtrc/fix-oxfmtrc.mjs +5 -0
- package/rules/text/vscode_settings/fix-vscode_settings.mjs +5 -0
- package/rules/worktree/vscode_settings/docs/fix-vscode_settings.md +10 -7
- package/rules/worktree/vscode_settings/fix-vscode_settings.mjs +5 -0
- package/rules/worktree/zed_settings/fix-zed_settings.mjs +5 -0
- package/schemas/n-rules.json +18 -1
- package/scripts/lib/adr/docs/index.md +0 -2
- package/scripts/lib/adr/docs/normalize-pipeline.md +44 -28
- package/scripts/lib/adr/normalize-pipeline.mjs +11 -0
- package/scripts/lib/auto-worktree.mjs +9 -3
- package/scripts/lib/docs/auto-worktree.md +50 -12
- package/scripts/lib/docs/inline-template-links.md +17 -8
- package/scripts/lib/docs/plugin-api.md +1 -1
- package/scripts/lib/docs/worktree-notice.md +65 -10
- package/scripts/lib/inline-template-links.mjs +5 -0
- package/scripts/lib/lint-surface/docs/run-detectors.md +25 -22
- package/scripts/lib/lint-surface/docs/tier-sampling-experiment.md +30 -14
- package/scripts/lib/lint-surface/run-detectors.mjs +1 -1
- package/scripts/lib/lint-surface/tier-sampling-experiment.mjs +1 -0
- package/scripts/lib/plugin-api.mjs +46 -0
- package/scripts/lib/worktree-notice.mjs +5 -3
- package/scripts/utils/docs/walkDir.md +26 -15
- package/scripts/utils/docs/worktree-fingerprint.md +16 -15
- package/scripts/utils/walkDir.mjs +9 -5
- package/scripts/utils/worktree-fingerprint.mjs +5 -0
- package/skills/storybook/SKILL.md +4 -4
- package/skills/taze/js/migration-cache.mjs +1 -1
|
@@ -3,42 +3,58 @@ type: JS Module
|
|
|
3
3
|
title: normalize-pipeline.mjs
|
|
4
4
|
resource: npm/scripts/lib/adr/normalize-pipeline.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
7
|
-
model:
|
|
6
|
+
crc: 7840afd7
|
|
7
|
+
model: openai-codex/gpt-5.5
|
|
8
|
+
tier: cloud-avg
|
|
9
|
+
score: 100
|
|
10
|
+
issues: judge-refine:kept-original,judge:inaccurate:0.99
|
|
11
|
+
judgeModel: openai-codex/gpt-5.4-mini
|
|
8
12
|
---
|
|
9
13
|
|
|
10
|
-
|
|
14
|
+
## Огляд
|
|
15
|
+
|
|
16
|
+
Файл готує ADR-чернетки до застосування як `operations[]` у тому самому контракті, що й single-shot-пайплайн, сумісному з `apply-ops`: створення нового MADR, доповнення наявного ADR або пропуск. Він існує як локально-орієнтована альтернатива для малої LLM `omlx/gemma-4b`, де JS керує retrieval, кластерами, датами, MADR-каркасом і після кластеризації призначає `op`, а модель дає лише вузькі перевірювані судження та фрагменти змісту.
|
|
11
17
|
|
|
12
18
|
## Поведінка
|
|
13
19
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
normalizePipeline виконує повний конвеєр: ідентифікує кластери чернеток, визначає операції (delete, rewrite, merge-anchor тощо) та ініціює виклики LLM для генерації контенту та додатків.
|
|
20
|
+
`normalizePipeline` приймає батч ADR-чернеток і список уже чистих ADR, після чого веде їх через послідовність дрібних перевірюваних рішень. Глобальні рішення про зв’язки, кластери, цільові документи й фінальні operations залишаються в JS; LLM використовується лише для вузьких локальних суджень і генерації контрольованих фрагментів.
|
|
21
|
+
|
|
22
|
+
На початку потоку `draftTitle` дістає робочу назву кожної чернетки, а `isNoDecision` відсікає записи, де рішення явно не прийняте. Для решти `buildEdges` створює кандидатні зв’язки між чернетками та між чернетками і clean ADR: назви й слаги проходять через `tokenize`, а близькість кандидатів оцінює `jaccard`. Це retrieval-етап: він лише звужує простір порівнянь, а не приймає остаточне рішення про злиття.
|
|
23
|
+
|
|
24
|
+
Далі `normalizePipeline` перевіряє кандидатні зв’язки через LLM-судження «те саме рішення чи ні», консервативно об’єднує підтверджені зв’язки в кластери й призначає для кожної чернетки дію: створити новий ADR, доповнити наявний або пропустити як тривіальну/непридатну. Ізольовані чернетки додатково класифікуються як standalone або trivial, щоб не створювати ADR без достатньої змістовної ваги.
|
|
25
|
+
|
|
26
|
+
Коли потрібен новий ADR, `genMadr` перетворює одну чернетку на MADR-документ. Дату для канонічного каркаса визначає `madrDate`; модель повертає лише зміст секцій, який приводить до стабільної форми `normalizeSections`. Після цього `assembleMadr` збирає повний MADR із контрольованим заголовком, датою, статусом, назвами секцій, fallback-текстами й bullet-структурою. `validateMadr` є фінальним quality gate: невалідний документ не потрапляє в operations як готовий вміст.
|
|
27
|
+
|
|
28
|
+
Коли чернетка має доповнити наявний ADR, `normalizePipeline` генерує лише новий зміст оновлення, а службовий заголовок оновлення та дата лишаються під контролем JS через ту саму політику дат. Це зберігає однаковий формат для створення нових ADR і для merge-доповнень.
|
|
29
|
+
|
|
30
|
+
Результатом `normalizePipeline` є operations у тому самому контракті, що й single-shot-пайплайн, разом зі статистикою та діагностичним trace. Подальше застосування змін виконується спільною apply-логікою поза цим файлом; цей конвеєр лише готує перевірені наміри змін і не покладається на кешування.
|
|
26
31
|
|
|
27
32
|
## Публічний API
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
34
|
+
- tokenize — Токенізує назву/слаг у множину значущих токенів (kebab + пробіли, без стоп-слів).
|
|
35
|
+
- jaccard — Jaccard-схожість двох множин токенів.
|
|
36
|
+
- draftTitle — Витягує заголовок драфта. Капчер пише `## ADR <title>` — він у пріоритеті
|
|
37
|
+
(чернетка може мати контент-заголовки раніше або взагалі не мати ADR-рядка).
|
|
38
|
+
Fallback-и: перший h1, що не є MADR-секцією, інакше '' (caller бере імʼя файлу).
|
|
39
|
+
- isNoDecision — Детермінований no-decision гейт (харднінг #1). Чернетка, де у `Decision Outcome`
|
|
40
|
+
рішення явно НЕ прийняте (transcript обірвався) — не варта окремого ADR: gold
|
|
41
|
+
(sonnet) такі видаляє. Ловимо без LLM, щоб не покладатися на kind-judge малої моделі.
|
|
42
|
+
- buildEdges — Будує кандидати-ребра за лексичною схожістю.
|
|
43
|
+
- validateMadr — Детермінований гейт якості згенерованого MADR.
|
|
44
|
+
- madrDate — Детермінована ISO-дата для поля **Date:**. Пріоритет — `captured` frontmatter
|
|
45
|
+
(перші 10 символів ISO-стемпа); fallback — timestamp-префікс імені файлу
|
|
46
|
+
(`YYMMDD-…` → `20YY-MM-DD`). Каркас MADR не повинен залежати від LLM навіть тут.
|
|
47
|
+
- normalizeSections — Нормалізує сирий JSON-вивід gen-моделі у строгу форму секцій. Толерантна до
|
|
48
|
+
дрібних відхилень малої моделі: рядок замість масиву → масив із одного елемента,
|
|
49
|
+
число/null → рядок/порожньо, обрізає пробіли й порожні елементи.
|
|
50
|
+
- assembleMadr — Детермінована збірка канонічного MADR 4.0.0 з заголовка, дати й секцій-контенту.
|
|
51
|
+
Увесь каркас (Status, назви секцій, шаблон "Chosen option…", fallback-фрази,
|
|
52
|
+
bullets) — тут, не в моделі. Заголовок і дата — JS-власність (draftTitle/captured),
|
|
53
|
+
модель їх не торкається.
|
|
54
|
+
- genMadr — Stage 2: перетворює одну чернетку на валідний MADR-документ. Модель лише
|
|
55
|
+
витягує зміст секцій як JSON; каркас збирає JS, результат проганяється через
|
|
56
|
+
валідатор із ретраями каскаду. При невдачі повертає `valid: false` без вмісту.
|
|
57
|
+
- normalizePipeline — Головний конвеєр. Повертає operations[] (контракт single-shot) + stats.
|
|
42
58
|
|
|
43
59
|
## Гарантії поведінки
|
|
44
60
|
|
|
@@ -459,6 +459,17 @@ export function assembleMadr({ title, date, sections: s }) {
|
|
|
459
459
|
].join('\n')
|
|
460
460
|
}
|
|
461
461
|
|
|
462
|
+
/**
|
|
463
|
+
* Stage 2: перетворює одну чернетку на валідний MADR-документ. Модель лише
|
|
464
|
+
* витягує зміст секцій як JSON; каркас збирає JS, результат проганяється через
|
|
465
|
+
* валідатор із ретраями каскаду. При невдачі повертає `valid: false` без вмісту.
|
|
466
|
+
* @param {string} title заголовок рішення
|
|
467
|
+
* @param {string} body тіло чернетки (обрізається до безпечного розміру)
|
|
468
|
+
* @param {string} captured момент фіксації чернетки (для дати MADR)
|
|
469
|
+
* @param {{allowCloud: boolean, stats: object}} cfg конфіг каскаду й лічильники
|
|
470
|
+
* @param {string} [file] шлях чернетки — fallback-джерело дати
|
|
471
|
+
* @returns {Promise<{content: string | null, slug: string, valid: boolean, error?: string}>} зібраний документ або позначка невдачі
|
|
472
|
+
*/
|
|
462
473
|
export async function genMadr(title, body, captured, cfg, file = '') {
|
|
463
474
|
const date = madrDate(captured, file)
|
|
464
475
|
const slug = slugify(title)
|
|
@@ -28,7 +28,9 @@ async function defaultConfirm(message) {
|
|
|
28
28
|
* Гарантує, що подальші кроки виконуються в ізольованому worktree
|
|
29
29
|
* (`main.json.worktree: true`-контракт), навіть коли викликач — детермінований
|
|
30
30
|
* JS-код, що не годує SKILL.md жодному LLM-агенту (тож агентський preflight-блок
|
|
31
|
-
* з `worktree-notice.mjs` нікому виконувати). Якщо `cwd` вже під `.worktrees/`
|
|
31
|
+
* з `worktree-notice.mjs` нікому виконувати). Якщо `cwd` вже під `.worktrees/`
|
|
32
|
+
* (репо-конвенція) або `.claude/worktrees/` (worktree харнесу Claude Code,
|
|
33
|
+
* куди `npx \@7n/mt worktree create` класти заборонено — `n-worktree.mdc`) —
|
|
32
34
|
* повертає його без змін. Інакше сам створює `.worktrees/<branch>-<suffix>`
|
|
33
35
|
* (`npx \@7n/mt worktree create`) і ставить залежності (`bun install`).
|
|
34
36
|
*
|
|
@@ -62,8 +64,12 @@ export async function ensureRunningInWorktree(
|
|
|
62
64
|
) {
|
|
63
65
|
const toplevelResult = spawnFn('git', ['rev-parse', '--show-toplevel'], { cwd, encoding: 'utf8' })
|
|
64
66
|
const toplevel = toplevelResult.status === 0 ? toplevelResult.stdout.trim() : ''
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
+
const pathSegments = toplevel.replaceAll('\\', '/').split('/')
|
|
68
|
+
const segments = new Set(pathSegments)
|
|
69
|
+
const isClaudeHarnessWorktree = pathSegments.some(
|
|
70
|
+
(seg, i) => seg === '.claude' && pathSegments[i + 1] === 'worktrees'
|
|
71
|
+
)
|
|
72
|
+
if (segments.has('.worktrees') || isClaudeHarnessWorktree) return { cwd, autoCreated: false, branchArg: null }
|
|
67
73
|
|
|
68
74
|
const branchResult = spawnFn('git', ['branch', '--show-current'], { cwd, encoding: 'utf8' })
|
|
69
75
|
const currentBranch = branchResult.status === 0 ? branchResult.stdout.trim() : ''
|
|
@@ -3,28 +3,66 @@ type: JS Module
|
|
|
3
3
|
title: auto-worktree.mjs
|
|
4
4
|
resource: npm/scripts/lib/auto-worktree.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
7
|
-
model:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
judgeModel: openai-codex/gpt-5.4-mini
|
|
6
|
+
crc: 2a9e7bfd
|
|
7
|
+
model: omlx/gemma-4-e2b-it-4bit
|
|
8
|
+
tier: local-min-retry
|
|
9
|
+
score: 90
|
|
11
10
|
---
|
|
12
11
|
|
|
13
12
|
## Огляд
|
|
14
13
|
|
|
15
|
-
|
|
14
|
+
Функції забезпечують ізоляцію роботи з кодом у worktree, перенесення змін між робочими середовищами та керування життєвим циклом створеного worktree. ensureRunningInWorktree гарантує роботу в ізольованому середовищі, bringChangesBackToOriginal переносить модифікації з worktree назад до основного репозиторію, використовуючи механізм копіювання, а не git merge, removeAutoCreatedWorktree забезпечує прибирання, видаляючи сам worktree після завершення операції.
|
|
16
15
|
|
|
17
16
|
## Поведінка
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
- `bringChangesBackToOriginal` — переносить зміни з автоствореного worktree назад у вихідне дерево як untracked/незакомічені правки, включно з додаванням, оновленням і видаленням файлів; перейменування переносить лише в нову назву.
|
|
21
|
-
- `removeAutoCreatedWorktree` — прибирає автостворений worktree разом із його ефемерною гілкою після перенесення змін назад, а у разі збою лише повідомляє про ручне прибирання.
|
|
18
|
+
Поведінка: Функції взаємодіють для ізоляції роботи з кодом у worktree, перенесенні змін між робочими середовищами та керування життєвим циклом створюваного worktree. `ensureRunningInWorktree` гарантує роботу в ізольованому середовищі, тоді як `bringChangesBackToOriginal` переносить модифікації з worktree назад до основного репозиторію, використовуючи механізм копіювання, а не git merge. `removeAutoCreatedWorktree` забезпечує прибирання, видаляючи сам worktree, що виконується лише після завершення операції з `bringChangesBackToOriginal`.
|
|
22
19
|
|
|
23
20
|
## Публічний API
|
|
24
21
|
|
|
25
|
-
- ensureRunningInWorktree —
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
- ensureRunningInWorktree — Гарантує, що подальші кроки виконуються в ізольованому worktree
|
|
23
|
+
(`main.json.worktree: true`-контракт), навіть коли викликач — детермінований
|
|
24
|
+
JS-код, що не годує SKILL.md жодному LLM-агенту (тож агентський preflight-блок
|
|
25
|
+
з `worktree-notice.mjs` нікому виконувати). Якщо `cwd` вже під `.worktrees/`
|
|
26
|
+
(репо-конвенція) або `.claude/worktrees/` (worktree харнесу Claude Code,
|
|
27
|
+
куди `npx \@7n/mt worktree create` класти заборонено — `n-worktree.mdc`) —
|
|
28
|
+
повертає його без змін. Інакше сам створює `.worktrees/<branch>-<suffix>`
|
|
29
|
+
(`npx \@7n/mt worktree create`) і ставить залежності (`bun install`).
|
|
30
|
+
|
|
31
|
+
**Гейт на чисте дерево.** Auto-create читає стан і потім переносить зміни
|
|
32
|
+
назад копіюванням файлів (`bringChangesBackToOriginal`) — а не git merge.
|
|
33
|
+
Якщо у вихідному `cwd` вже є незакомічені зміни, вони НЕ потраплять у щойно
|
|
34
|
+
створений worktree (той — checkout HEAD), і перенесення назад мовчки
|
|
35
|
+
затерло б їх версією з worktree. Тому за замовчуванням (`requireCleanTree:
|
|
36
|
+
true`) на брудному дереві auto-create питає в терміналі (`deps.confirm`,
|
|
37
|
+
дефолт — y/N через stdin; поза TTY одразу "ні") дозвіл закомить і
|
|
38
|
+
запушити зараз через `npx \@7n/n push` (сквош усього робочого дерева в один
|
|
39
|
+
коміт + push у origin — сама команда підтвердження не питає, тому питаємо
|
|
40
|
+
ми, ДО виклику). На "ні"/поза TTY — кидає, як і раніше. Викликач, що
|
|
41
|
+
гарантує чистоту дерева сам (наприклад taze — SKILL.md вимагає цього як
|
|
42
|
+
передумову ще ДО виклику), може передати `requireCleanTree: false`, щоб не
|
|
43
|
+
платити за зайву git-команду і не питати підтвердження.
|
|
44
|
+
- bringChangesBackToOriginal — Переносить зміни з автоствореного worktree назад у вихідне дерево як
|
|
45
|
+
**untracked/незакомічені** правки (просте копіювання файлів, без git
|
|
46
|
+
merge/cherry-pick). Джерело істини — `git status --porcelain` у worktree:
|
|
47
|
+
для кожного шляху копіює файл, якщо він існує (модифікація/додавання), або
|
|
48
|
+
видаляє його у вихідному дереві, якщо existsSync каже, що в worktree його
|
|
49
|
+
вже нема (видалення). Перейменування (`old -> new` у porcelain) переносять
|
|
50
|
+
лише нову назву — стара лишається як була, прийнятний компроміс для
|
|
51
|
+
інструментів, що самі файли не перейменовують (ефект можливий лише як
|
|
52
|
+
побічний результат LLM-рефакторингу чи форматера).
|
|
53
|
+
|
|
54
|
+
**Untracked-директорія цілком.** Git схлопує щойно створену untracked
|
|
55
|
+
директорію в один porcelain-рядок із `/` на кінці (якщо в ній нема жодного
|
|
56
|
+
файлу, вже відомого git) — `copyFile` на такий шлях впав би (`EISDIR`/`ENOENT`)
|
|
57
|
+
і обривав би цикл, гублячи все, що йшло по порядку ітерації ДАЛІ. Такий
|
|
58
|
+
рядок (суфікс `/` або реальний каталог на диску) копіюється рекурсивно
|
|
59
|
+
(`copyDirectoryRecursive`) — весь вміст, а не один `copyFile`.
|
|
60
|
+
- removeAutoCreatedWorktree — Прибирає автостворений worktree разом з його ефемерною git-гілкою
|
|
61
|
+
(`npx \@7n/mt worktree remove <branch>`) — викликати лише ПІСЛЯ
|
|
62
|
+
`bringChangesBackToOriginal`, інакше зміни згорять разом з деревом.
|
|
63
|
+
Не кидає при провалі — це прибирання, а не крок, від якого залежить
|
|
64
|
+
результат прогону; провал лише логується, worktree лишається для
|
|
65
|
+
ручного розбору.
|
|
28
66
|
|
|
29
67
|
## Гарантії поведінки
|
|
30
68
|
|
|
@@ -3,23 +3,32 @@ type: JS Module
|
|
|
3
3
|
title: inline-template-links.mjs
|
|
4
4
|
resource: npm/scripts/lib/inline-template-links.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
7
|
-
model:
|
|
6
|
+
crc: dde8124c
|
|
7
|
+
model: openai-codex/gpt-5.4-mini
|
|
8
|
+
tier: cloud-min
|
|
8
9
|
score: 100
|
|
10
|
+
issues: judge-refine:kept-original,judge:inaccurate:0.96
|
|
11
|
+
judgeModel: openai-codex/gpt-5.4-mini
|
|
9
12
|
---
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
## Огляд
|
|
15
|
+
|
|
16
|
+
Перетворює markdown-лінки на файли з `template/` у fenced-блоки з фактичним вмістом цих файлів і додає знайдені `.mdc`-правила, щоб зібраний `.mdc` лишався самодостатнім для подальшого використання без відносних шляхів. Поведінку реалізують `inlineTemplateLinks` і `appendDiscoveredMdcFiles`.
|
|
12
17
|
|
|
13
18
|
## Поведінка
|
|
14
19
|
|
|
15
|
-
inlineTemplateLinks
|
|
16
|
-
|
|
20
|
+
inlineTemplateLinks спочатку підбирає лише ті markdown-лінки, що ведуть у template-піддерево, і замінює їх самодостатнім вбудованим фрагментом із фактичним вмістом файлу; так правило перестає залежати від відносних посилань. Для вкладених прикладів і слот-файлів відновлюється читабельна назва цілі, зокрема для `package.json.snippet.json` і `package.json`, а формат fenced-блока обирається за розширенням вмісту. Якщо ціль не знайдено, обробка зупиняється з помилкою, щоб згенерований `.mdc` не містив битих посилань.
|
|
21
|
+
|
|
22
|
+
appendDiscoveredMdcFiles далі доповнює вже оброблений текст усіма знайденими `.mdc`-файлами з піддиректорій, які позначені через `concern.json`; це дає змогу зібрати повний пакет правил без ручного перелічення допоміжних файлів. Порядок стабільний: спочатку директори сортуються, потім файли всередині кожного каталогу, а результати додаються в кінець як один суцільний блок. Якщо таких директорій немає, початковий текст лишається без змін.
|
|
17
23
|
|
|
18
24
|
## Публічний API
|
|
19
25
|
|
|
20
|
-
inlineTemplateLinks —
|
|
21
|
-
|
|
26
|
+
- inlineTemplateLinks — Finds markdown links whose path contains /template/ and replaces them with
|
|
27
|
+
inline fenced blocks. Reads file from join(ruleDir, rel-path).
|
|
28
|
+
Throws Error if a matched link target doesn't exist (fail loud — user must know).
|
|
29
|
+
- appendDiscoveredMdcFiles — Appends all *.mdc files from concern subdirectories (those with concern.json).
|
|
30
|
+
Concerns ordered alphabetically; files within each concern ordered alphabetically.
|
|
22
31
|
|
|
23
32
|
## Гарантії поведінки
|
|
24
33
|
|
|
25
|
-
-
|
|
34
|
+
- Власних операцій запису (ФС/БД) у файлі немає; виклики імпортованих модулів можуть писати.
|
|
@@ -3,25 +3,80 @@ type: JS Module
|
|
|
3
3
|
title: worktree-notice.mjs
|
|
4
4
|
resource: npm/scripts/lib/worktree-notice.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
7
|
-
model: omlx/gemma-4-
|
|
6
|
+
crc: 4feb8b6c
|
|
7
|
+
model: omlx/gemma-4-e2b-it-4bit
|
|
8
|
+
tier: local-min-retry
|
|
8
9
|
score: 100
|
|
9
10
|
---
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
## Огляд
|
|
13
|
+
|
|
14
|
+
Цей файл містить інструкції для вбудовування вказівки про використання worktree-гілки в синкнутий текст `SKILL.md`. Він забезпечує ідемпотентне заміщення або видалення цього блоку залежно від значення `main.json.worktree`, забезпечуючи зв'язок з інструкціями щодо роботи з окремими Git-репозиторіями та інструментами для управління залежностями та бінарними викликами.
|
|
15
|
+
|
|
16
|
+
## Behavior
|
|
17
|
+
Транслітерує кирилицю в ASCII для короткого suffix
|
|
18
|
+
@param {string} value вхідний текст
|
|
19
|
+
@returns {string} транслітерований текст
|
|
20
|
+
|
|
21
|
+
### deriveSuffix
|
|
22
|
+
Робить короткий безпечний suffix для worktree-гілки з назви скіла
|
|
23
|
+
@param {string} content вміст `SKILL.md`
|
|
24
|
+
@returns {string} suffix до 10 символів
|
|
25
|
+
викликає: transliterate
|
|
26
|
+
|
|
27
|
+
### buildNoticeBody
|
|
28
|
+
Тіло worktree-інструкції з конкретним суфіксом, щоб агент не питав назву гілки
|
|
29
|
+
@param {string} suffix короткий suffix задачі
|
|
30
|
+
@returns {string} markdown-блок без маркерів
|
|
31
|
+
|
|
32
|
+
### buildBlock
|
|
33
|
+
Канонічний блок worktree-інструкції
|
|
34
|
+
@param {string} content вміст `SKILL.md`
|
|
35
|
+
@returns {string} текст блоку від START до END
|
|
36
|
+
викликає: buildNoticeBody
|
|
37
|
+
|
|
38
|
+
### injectWorktreeNotice
|
|
39
|
+
Вставляє / оновлює / видаляє worktree-блок у вмісті `SKILL.md`
|
|
40
|
+
@param {string} content вміст `SKILL.md`
|
|
41
|
+
@param {boolean} enabled чи має бути блок значення `main.json.worktree`
|
|
42
|
+
@returns {string} оновлений вміст ідемпотентно
|
|
12
43
|
|
|
13
44
|
## Поведінка
|
|
14
45
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
46
|
+
Транслітерує кирилицю в ASCII для короткого suffix
|
|
47
|
+
@param {string} value вхідний текст
|
|
48
|
+
@returns {string} транслітерований текст
|
|
49
|
+
|
|
50
|
+
### deriveSuffix
|
|
51
|
+
Робить короткий безпечний suffix для worktree-гілки з назви скіла
|
|
52
|
+
@param {string} content вміст `SKILL.md`
|
|
53
|
+
@returns {string} suffix до 10 символів
|
|
54
|
+
викликає: transliterate
|
|
55
|
+
|
|
56
|
+
### buildNoticeBody
|
|
57
|
+
Тіло worktree-інструкції з конкретним суфіксом, щоб агент не питав назву гілки
|
|
58
|
+
@param {string} suffix короткий suffix задачі
|
|
59
|
+
@returns {string} markdown-блок без маркерів
|
|
60
|
+
|
|
61
|
+
### buildBlock
|
|
62
|
+
Канонічний блок worktree-інструкції
|
|
63
|
+
@param {string} content вміст `SKILL.md`
|
|
64
|
+
@returns {string} текст блоку від START до END
|
|
65
|
+
викликає: buildNoticeBody, deriveSuffix
|
|
66
|
+
|
|
67
|
+
### injectWorktreeNotice
|
|
68
|
+
Вставляє / оновлює / видаляє worktree-блок у вмісті `SKILL.md`
|
|
69
|
+
@param {string} content вміст `SKILL.md`
|
|
70
|
+
@param {boolean} enabled чи має бути блок значення `main.json.worktree`
|
|
71
|
+
@returns {string} оновлений вміст ідемпотентно
|
|
72
|
+
викликає: buildBlock
|
|
18
73
|
|
|
19
74
|
## Публічний API
|
|
20
75
|
|
|
21
|
-
WORKTREE_START —
|
|
22
|
-
WORKTREE_END —
|
|
23
|
-
injectWorktreeNotice —
|
|
76
|
+
- WORKTREE_START — Маркер початку worktree-блоку (стабільний, не залежить від тексту всередині).
|
|
77
|
+
- WORKTREE_END — Маркер кінця worktree-блоку.
|
|
78
|
+
- injectWorktreeNotice — Вставляє / оновлює / видаляє worktree-блок у вмісті `SKILL.md`.
|
|
24
79
|
|
|
25
80
|
## Гарантії поведінки
|
|
26
81
|
|
|
27
|
-
-
|
|
82
|
+
- Власних операцій запису (ФС/БД) у файлі немає; виклики імпортованих модулів можуть писати.
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Інлайн template-посилань у .mdc-правилах: markdown-лінки на файли з тек
|
|
3
|
+
* template/ замінюються fenced-блоками з фактичним вмістом файлу, щоб
|
|
4
|
+
* згенероване правило було самодостатнім без відносних шляхів.
|
|
5
|
+
*/
|
|
1
6
|
import { existsSync } from 'node:fs'
|
|
2
7
|
import { readFile } from 'node:fs/promises'
|
|
3
8
|
import { basename, extname, join } from 'node:path'
|
|
@@ -3,42 +3,45 @@ type: JS Module
|
|
|
3
3
|
title: run-detectors.mjs
|
|
4
4
|
resource: npm/scripts/lib/lint-surface/run-detectors.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
7
|
-
model:
|
|
6
|
+
crc: e9224e37
|
|
7
|
+
model: openai-codex/gpt-5.4-mini
|
|
8
|
+
tier: cloud-min
|
|
8
9
|
score: 100
|
|
9
|
-
issues: judge:inaccurate:0.
|
|
10
|
+
issues: judge-refine:kept-original,judge:inaccurate:0.99
|
|
10
11
|
judgeModel: openai-codex/gpt-5.4-mini
|
|
11
12
|
---
|
|
12
13
|
|
|
13
14
|
## Огляд
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
Файл формує єдину поверхню для `n-rules lint --no-fix`: від discovery правил і вибору меж запуску до виконання `lint` для кожного concern та збору нормалізованих violations. Його результатом є список порушень, який використовує fix-pipeline для подальшої обробки, тоді як сам detect не змінює дерево файлів.
|
|
16
17
|
|
|
17
18
|
## Поведінка
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
DEFAULT_RULES_DIR визначає шлях до стандартної директорії з правилами.
|
|
21
|
-
buildDetectPlan створює впорядкований план прогону лінтера, збираючи всі відповідні концерни та визначаючи область їх сканування.
|
|
22
|
-
detectAll виконує прохід лінтера у режим детекції, збираючи всі виявлені порушення та повертаючи код виходу.
|
|
20
|
+
DEFAULT_RULES_DIR задає базовий корінь правил, від якого стартує discovery, коли споживач не передав власні каталоги.
|
|
23
21
|
|
|
24
|
-
|
|
22
|
+
buildDetectPlan спочатку визначає набір rules-каталогів, потім відбирає лише доступні concern-и з урахуванням capability, далі будує план виконання за режимом прогону: scoped, delta, full або repo-wide. Сам план фіксує, які concern-и запускаються whole-repo, а які лише по перетину з файлами, щоб detect і fix-pipeline працювали з однаковою картиною.
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
* DEFAULT_RULES_DIR — Містить набір стандартних правил для перевірок.
|
|
29
|
-
* buildDetectPlan — Створює план виконання перевірок, охоплюючи визначені області.
|
|
30
|
-
* detectAll — Виконує повний прохід пошуку проблем і повертає всі виявлені порушення та код виходу.
|
|
31
|
-
* loadEnabledLintRules — Discovery-фасад для споживачів поза detect/fix-конвеєром (`ci plan`): concerns за rule-id + set активних правил.
|
|
32
|
-
* computeActiveDomains — Активність доменів для файлового набору (лише per-file concerns) — єдине джерело правди для `ci plan`: «plan сказав true» ⇔ «lint щось запустить».
|
|
24
|
+
loadEnabledLintRules використовує той самий discovery-ланцюжок, але повертає не план, а повну мапу concern-и за rule-id разом із множиною активних правил. Це потрібно зовнішнім споживачам, які мають знати, що реально доступно для прогону, не запускаючи сам detector-цикл.
|
|
33
25
|
|
|
34
|
-
|
|
26
|
+
computeActiveDomains дає скорочений зріз цієї ж моделі: для заданого набору файлів показує, які rule-id справді активуються хоча б одним per-file concern-ом. Full-scope перевірки тут навмисно не враховуються, бо їхня зона відповідає repo-wide прогону.
|
|
35
27
|
|
|
36
|
-
|
|
28
|
+
detectAll бере готовий план, виконує його, збирає normalized violations і повертає ще й derived exitCode. Увесь шлях read-only: нічого не записує в дерево, не змінює конфіг і не покладається на мутації поза межами збирання результатів. Фільтрація та видимість правил спираються на .n-rules.json, тож саме він визначає, які rules каталоги й concern-и вважаються активними.
|
|
37
29
|
|
|
38
|
-
|
|
30
|
+
## Публічний API
|
|
39
31
|
|
|
40
|
-
|
|
32
|
+
- DEFAULT_RULES_DIR — Цей файл: npm/scripts/lib/lint-surface/run-detectors.mjs → PACKAGE_ROOT = npm (4 dirname угору).
|
|
33
|
+
- buildDetectPlan — Будує план прогону для заданих опцій (discovery + scope-table).
|
|
34
|
+
Спільне джерело для detect-only і fix-pipeline.
|
|
35
|
+
- loadEnabledLintRules — Discovery-фасад для споживачів поза detect/fix-конвеєром (`ci plan`):
|
|
36
|
+
concerns за rule-id (ядро + плагіни, capability-фільтр) і set активних правил.
|
|
37
|
+
- computeActiveDomains — Активність доменів (rule-id) для заданого файлового набору — єдине джерело
|
|
38
|
+
правди для `ci plan`: домен «активний», якщо хоч один його **per-file**
|
|
39
|
+
concern тригериться на цих файлах (та сама таблиця planConcernForDelta, що
|
|
40
|
+
й `lint <domain> --path` → «plan сказав true» ⇔ «lint щось запустить»).
|
|
41
|
+
Правила без жодного per-file concern не потрапляють у результат (їхні
|
|
42
|
+
full-scope перевірки — справа `--repo-wide`).
|
|
43
|
+
- detectAll — Запускає detect-only прохід. Повертає всі violations і похідний exitCode.
|
|
41
44
|
|
|
42
|
-
|
|
45
|
+
## Гарантії поведінки
|
|
43
46
|
|
|
44
|
-
|
|
47
|
+
- Власних операцій запису (ФС/БД) у файлі немає; виклики імпортованих модулів можуть писати.
|
|
@@ -3,32 +3,48 @@ type: JS Module
|
|
|
3
3
|
title: tier-sampling-experiment.mjs
|
|
4
4
|
resource: npm/scripts/lib/lint-surface/tier-sampling-experiment.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
7
|
-
model:
|
|
6
|
+
crc: 959712b3
|
|
7
|
+
model: openai-codex/gpt-5.5
|
|
8
|
+
tier: cloud-avg
|
|
8
9
|
score: 100
|
|
9
|
-
issues: judge:
|
|
10
|
+
issues: judge:error
|
|
10
11
|
judgeModel: openai-codex/gpt-5.4-mini
|
|
11
12
|
---
|
|
12
13
|
|
|
13
14
|
## Огляд
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
Експериментальний harness моделює isolated sampling для окремого tier-а lint fix ladder: будує experiment-only rung-и, проганяє sampling-кандидатів із відкотом до S1 і лишає лише candidate, що пройшов canonical detect. Файл існує, щоб перевіряти sampling/consensus поза production `runFixPipeline`, залишаючи judge/consensus тільки джерелом feedback, а не рішенням про patch.
|
|
17
|
+
|
|
18
|
+
Публічні точки входу: `EXPERIMENT_TIER_ORDER`, `buildExperimentLadder`, `samplingProfilesForTier`, `chooseCleanCandidate`, `runTierSamplingExperiment`.
|
|
19
|
+
|
|
20
|
+
Модуль працює fail-safe: перехоплює помилки й не кидає винятків назовні.
|
|
16
21
|
|
|
17
22
|
## Поведінка
|
|
18
23
|
|
|
19
|
-
EXPERIMENT_TIER_ORDER
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
`EXPERIMENT_TIER_ORDER` задає порядок експериментальних tier-ів, за яким формується ladder для isolated sampling поверх lint fix pipeline.
|
|
25
|
+
|
|
26
|
+
`buildExperimentLadder` створює окремий experiment-only ladder із підтримкою `cloud-max`, не змінюючи production-послідовність `runFixPipeline`. Дані про моделі й timeouts перетворюються на набір rung-ів, які далі використовуються як сценарії окремих випробувань.
|
|
27
|
+
|
|
28
|
+
`samplingProfilesForTier` визначає набір sampling-кандидатів для конкретного tier-а. Якщо для tier-а передані перевизначення, вони стають джерелом профілів; інакше використовується стандартний набір для цього рівня.
|
|
29
|
+
|
|
30
|
+
`runTierSamplingExperiment` бере violations, базовий контекст, rung і sampling-кандидатів, після чого послідовно тестує кожного кандидата в ізольованому стані S1. Для кожної спроби робоче дерево відкочується до початкового snapshot, запускається worker, фіксуються змінені файли, виконується canonical detect і записується результат спроби разом із telemetry та latency.
|
|
31
|
+
|
|
32
|
+
Після всіх спроб `chooseCleanCandidate` обирає лише чистий candidate: пріоритет має менша кількість змінених файлів, менший patch і коротша latency. Якщо чистого кандидата немає, експеримент завершується без застосування patch до робочого дерева.
|
|
33
|
+
|
|
34
|
+
Якщо чистий candidate знайдено, `runTierSamplingExperiment` застосовує саме його зміни як фінальний результат tier sampling. Judge/consensus не приймає рішення про застосування patch: його відповідь повертається тільки як feedback поруч із attempts, selected candidate, фінальними violations і clean-статусом.
|
|
35
|
+
|
|
36
|
+
Модуль працює fail-safe: помилки окремих кандидатів або допоміжних етапів перетворюються на результати спроб і не викидаються назовні. Кешування між запусками або кандидатами не використовується.
|
|
24
37
|
|
|
25
38
|
## Публічний API
|
|
26
39
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
40
|
+
- EXPERIMENT_TIER_ORDER — Порядок tier-ів експериментального ladder — від локальної моделі до найсильнішої хмарної.
|
|
41
|
+
- buildExperimentLadder — Будує experiment-only ladder із `cloud-max`. Production ladder це не змінює.
|
|
42
|
+
- samplingProfilesForTier — Повертає можливі sampling profiles для заданого tier-а.
|
|
43
|
+
- chooseCleanCandidate — Дефолтний вибір найкращого (clean) кандидата серед усіх спроб.
|
|
44
|
+
Вибір відбувається за критеріями: менша кількість змінених файлів, менший розмір patch, менша латентність.
|
|
45
|
+
- runTierSamplingExperiment — Виконує послідовність випробувань (sampling) для одного tier.
|
|
46
|
+
Для кожного кандидата виконується rollback до S1, запускається worker,
|
|
47
|
+
оцінюється чистота, і якщо кандидат обраний, застосовується його patch.
|
|
32
48
|
|
|
33
49
|
## Гарантії поведінки
|
|
34
50
|
|
|
@@ -25,7 +25,7 @@ import { renderViolations, renderDiagnostics } from './render.mjs'
|
|
|
25
25
|
import { createProgressReporter } from './progress.mjs'
|
|
26
26
|
import { runPlanConcurrently } from './scheduler.mjs'
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
/** Цей файл: npm/scripts/lib/lint-surface/run-detectors.mjs → PACKAGE_ROOT = npm (4 dirname угору). */
|
|
29
29
|
export const DEFAULT_RULES_DIR = join(dirname(dirname(dirname(dirname(fileURLToPath(import.meta.url))))), 'rules')
|
|
30
30
|
|
|
31
31
|
/**
|
|
@@ -10,6 +10,7 @@ import { dirname } from 'node:path'
|
|
|
10
10
|
|
|
11
11
|
import { createSnapshot } from './snapshot.mjs'
|
|
12
12
|
|
|
13
|
+
/** Порядок tier-ів експериментального ladder — від локальної моделі до найсильнішої хмарної. */
|
|
13
14
|
export const EXPERIMENT_TIER_ORDER = Object.freeze(['local-min', 'cloud-min', 'cloud-avg', 'cloud-max'])
|
|
14
15
|
|
|
15
16
|
const DEFAULT_LOCAL_TIMEOUT_MS = 300_000
|