@nitra/cursor 12.14.0 → 12.15.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 +12 -0
- package/bin/docs/n-cursor.md +1 -4
- package/bin/n-cursor.js +1 -19
- package/package.json +1 -1
- package/rules/bun/docs/main.md +7 -6
- package/rules/python/docs/main.md +11 -11
- package/rules/rust/docs/main.md +5 -5
- package/scripts/docs/update-blue-oak.md +8 -8
- package/scripts/lib/docs/discover-checkable-rules.md +6 -6
- package/scripts/lib/docs/inline-template-links.md +8 -6
- package/scripts/lib/docs/list-project-rules-mdc.md +5 -3
- package/scripts/lib/docs/root-notice.md +13 -16
- package/scripts/lib/docs/run-lint.md +10 -8
- package/scripts/lib/docs/skill-meta.md +11 -9
- package/scripts/lib/fix/docs/discover-t0-patterns.md +10 -13
- package/scripts/lib/fix/docs/index.md +0 -1
- package/scripts/lib/fix/docs/llm-worker.md +8 -13
- package/scripts/lib/fix/docs/orchestrator.md +19 -10
- package/scripts/lib/fix/llm-worker.mjs +57 -43
- package/scripts/lib/fix/orchestrator.mjs +5 -4
- package/scripts/lib/root-notice.mjs +2 -2
- package/scripts/lib/run-lint.mjs +2 -10
- package/scripts/lib/skill-meta.mjs +1 -1
- package/scripts/utils/docs/walkDir.md +17 -20
- package/scripts/lib/fix/analyze-escalation.mjs +0 -353
- package/scripts/lib/fix/docs/analyze-escalation.md +0 -44
- package/skills/start-check/SKILL.md +0 -74
- package/skills/start-check/js/check.mjs +0 -198
- package/skills/start-check/js/docs/check.md +0 -42
- package/skills/start-check/js/docs/index.md +0 -11
- package/skills/start-check/main.json +0 -1
|
@@ -3,29 +3,38 @@ type: JS Module
|
|
|
3
3
|
title: orchestrator.mjs
|
|
4
4
|
resource: npm/scripts/lib/fix/orchestrator.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
6
|
+
crc: c6f15470
|
|
7
7
|
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
8
|
score: 100
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
## Огляд
|
|
12
|
+
|
|
13
|
+
Модуль відповідає за оркестрацію вирішення порушень. Він парсить аргументи для визначення бюджету та фільтрів за допомогою `parseOrchestratorArgs`. Потім він будує послідовність тирів ескалації, використовуючи `buildLadder`, і може ескалувати правила за допомогою `escalateRule`. Нарешті, він виконує повний цикл фіксації порушень через `runOrchestratorCli`.
|
|
12
14
|
|
|
13
15
|
## Поведінка
|
|
14
16
|
|
|
15
|
-
buildLadder будує послідовність тирів ескалації для вирішення
|
|
16
|
-
escalateRule
|
|
17
|
-
parseOrchestratorArgs парсить аргументи командного
|
|
18
|
-
runOrchestratorCli виконує повний
|
|
17
|
+
buildLadder будує послідовність тирів ескалації для вирішення порушень, від локальних до хмарних моделей.
|
|
18
|
+
escalateRule проводить один прогін по послідовності тирів, намагаючись вирішити порушення, і повертає статус вирішення та використаний бюджет хмарних викликів.
|
|
19
|
+
parseOrchestratorArgs парсить аргументи командного рядка, щоб визначити максимальний бюджет хмарних викликів та фільтр правил.
|
|
20
|
+
runOrchestratorCli виконує повний цикл фіксації порушень: початкова перевірка, детермінований фікс T0-auto, ітеративний LLM-фікс за драбиною ескалації, а потім фінальна перевірка.
|
|
19
21
|
|
|
20
22
|
## Публічний API
|
|
21
23
|
|
|
22
|
-
buildLadder — Створює послідовність моделей для ескалації, виходячи з доступних рівнів.
|
|
24
|
+
buildLadder — Створює послідовність моделей для ескалації, виходячи з доступних рівнів.
|
|
25
|
+
|
|
26
|
+
local-min — Перший прохід з локальною мінімальною моделлю.
|
|
27
|
+
local-min-retry — Повторний прохід локальною моделлю з урахуванням результатів попереднього кроку.
|
|
28
|
+
cloud-min — Використання мінімальної хмарної моделі з зворотним зв'язком.
|
|
29
|
+
cloud-avg — Використання середньої хмарної моделі з зворотним зв'язком, обмежене середнім бюджетом.
|
|
23
30
|
|
|
24
|
-
escalateRule —
|
|
31
|
+
escalateRule — Застосовує одне правило по послідовності ескалації до першого успішного перевірки.
|
|
32
|
+
Кожен рунг — Викликає обробника з попереднім результатом, перевіряє правило, фіксує результат у лозі.
|
|
33
|
+
Достроковий вихід — Зупиняє процес при певних умовах (відсутність ключа, пропуск моделі на системному рівні) або перевищенні середнього бюджету.
|
|
25
34
|
|
|
26
|
-
parseOrchestratorArgs — Витягує максимальне значення
|
|
35
|
+
parseOrchestratorArgs — Витягує максимальне значення середнього бюджету з аргументів командного рядка та збирає фільтри правил.
|
|
27
36
|
|
|
28
|
-
runOrchestratorCli — Запускає основний процес
|
|
37
|
+
runOrchestratorCli — Запускає основний процес оркестрації з командного рядка.
|
|
29
38
|
|
|
30
39
|
## Гарантії поведінки
|
|
31
40
|
|
|
@@ -47,54 +47,71 @@ function extractFailPaths(output) {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
50
|
+
* Збирає .mdc-контекст правила з двох джерел у пакеті (`PACKAGE_RULES_DIR`):
|
|
51
|
+
* - `js/<check>.mdc` — описи check-логіки (завжди всі, відсортовані за іменем);
|
|
52
|
+
* - `policy/<c>/<c>.mdc` — concern-специфічний контент: вибираємо лише ті concern/.mdc,
|
|
53
|
+
* чий `target.json → files.single` збігається з failing paths
|
|
54
|
+
* у violation output; якщо жоден не збігається — включаємо всі.
|
|
53
55
|
* @param {string} ruleId ID правила
|
|
54
56
|
* @param {string} violationOutput violation output
|
|
55
|
-
* @returns {string|null} конкатенація
|
|
57
|
+
* @returns {string|null} конкатенація зібраних .mdc або null, якщо нічого не знайдено
|
|
56
58
|
*/
|
|
57
|
-
function
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
59
|
+
function readRuleMdc(ruleId, violationOutput) {
|
|
60
|
+
const ruleDir = join(PACKAGE_RULES_DIR, ruleId)
|
|
61
|
+
const parts = []
|
|
62
|
+
|
|
63
|
+
// 1. js/**/*.mdc — завжди всі
|
|
64
|
+
const jsDir = join(ruleDir, 'js')
|
|
65
|
+
if (existsSync(jsDir)) {
|
|
66
|
+
let jsFiles
|
|
67
|
+
try {
|
|
68
|
+
jsFiles = readdirSync(jsDir)
|
|
69
|
+
.filter(f => f.endsWith('.mdc'))
|
|
70
|
+
.sort()
|
|
71
|
+
} catch {
|
|
72
|
+
jsFiles = []
|
|
73
|
+
}
|
|
74
|
+
for (const f of jsFiles) parts.push(readFileSync(join(jsDir, f), 'utf8').trim())
|
|
70
75
|
}
|
|
71
76
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
let target
|
|
77
|
+
// 2. policy/**/*.mdc — matched через target.json; fallback — всі
|
|
78
|
+
const policyDir = join(ruleDir, 'policy')
|
|
79
|
+
if (existsSync(policyDir)) {
|
|
80
|
+
const failPaths = extractFailPaths(violationOutput)
|
|
81
|
+
let concerns
|
|
79
82
|
try {
|
|
80
|
-
|
|
83
|
+
concerns = readdirSync(policyDir, { withFileTypes: true })
|
|
81
84
|
} catch {
|
|
82
|
-
|
|
85
|
+
concerns = []
|
|
83
86
|
}
|
|
84
87
|
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
const all = []
|
|
89
|
+
const matched = []
|
|
90
|
+
for (const entry of concerns) {
|
|
91
|
+
if (!entry.isDirectory()) continue
|
|
92
|
+
const concernDir = join(policyDir, entry.name)
|
|
93
|
+
const mdcEntry = readdirSync(concernDir).find(f => f.endsWith('.mdc'))
|
|
94
|
+
if (!mdcEntry) continue
|
|
95
|
+
const content = readFileSync(join(concernDir, mdcEntry), 'utf8').trim()
|
|
96
|
+
all.push(content)
|
|
97
|
+
|
|
98
|
+
const targetPath = join(concernDir, 'target.json')
|
|
99
|
+
if (!existsSync(targetPath)) continue
|
|
100
|
+
let target
|
|
101
|
+
try {
|
|
102
|
+
target = JSON.parse(readFileSync(targetPath, 'utf8'))
|
|
103
|
+
} catch {
|
|
104
|
+
continue
|
|
105
|
+
}
|
|
106
|
+
const targetFile = target?.files?.single
|
|
107
|
+
if (!targetFile) continue
|
|
108
|
+
if (failPaths.some(p => p === targetFile || p.endsWith(`/${targetFile}`))) matched.push(content)
|
|
109
|
+
}
|
|
91
110
|
|
|
92
|
-
|
|
93
|
-
if (!mdcEntry) continue
|
|
94
|
-
matched.push(readFileSync(join(concernDir, mdcEntry), 'utf8').trim())
|
|
111
|
+
parts.push(...(matched.length > 0 ? matched : all))
|
|
95
112
|
}
|
|
96
113
|
|
|
97
|
-
return
|
|
114
|
+
return parts.length > 0 ? parts.join('\n\n') : null
|
|
98
115
|
}
|
|
99
116
|
|
|
100
117
|
/**
|
|
@@ -252,7 +269,8 @@ function callModel(prompt, model, caller, timeoutMs, thinkingBudget) {
|
|
|
252
269
|
* `model` — перевизначення моделі; `feedback` — контекст попереднього рунга
|
|
253
270
|
* драбини (retry-with-feedback); `caller` — мітка для wire-trace; `timeoutMs` —
|
|
254
271
|
* per-tier ліміт виклику (драбина: локалі fail-fast, хмара повний);
|
|
255
|
-
* `thinkingBudget` — кількість thinking-токенів для omlx (дефолт `DEFAULT_THINKING_BUDGET`)
|
|
272
|
+
* `thinkingBudget` — кількість thinking-токенів для omlx (дефолт `DEFAULT_THINKING_BUDGET`).
|
|
273
|
+
* `timeoutMs` — per-tier ліміт: локальні 300s (4b повільна, backstop — turn-ceiling), хмарні 120s.
|
|
256
274
|
* @returns {{ ok: boolean, error?: string, changes: Array<{path:string}>, diagnosis: string|null, reasoning: string|null, reasoningSource: string|null, promptSummary: object }}
|
|
257
275
|
*/
|
|
258
276
|
export function runLlmWorker(ruleId, violationOutput, projectRoot, opts = {}) {
|
|
@@ -262,11 +280,8 @@ export function runLlmWorker(ruleId, violationOutput, projectRoot, opts = {}) {
|
|
|
262
280
|
const timeoutMs = opts.timeoutMs
|
|
263
281
|
const thinkingBudget = opts.thinkingBudget ?? DEFAULT_THINKING_BUDGET
|
|
264
282
|
|
|
265
|
-
// 1. Читаємо rule .mdc
|
|
266
|
-
|
|
267
|
-
const subMdc = selectSubCheckMdc(ruleId, violationOutput)
|
|
268
|
-
const mdcPath = join(projectRoot, '.cursor', 'rules', `n-${ruleId}.mdc`)
|
|
269
|
-
const ruleMdc = subMdc ?? (existsSync(mdcPath) ? readFileSync(mdcPath, 'utf8') : '(rule file not found)')
|
|
283
|
+
// 1. Читаємо rule .mdc з джерела пакету: js/**/*.mdc + policy/**/*.mdc.
|
|
284
|
+
const ruleMdc = readRuleMdc(ruleId, violationOutput) ?? '(rule file not found)'
|
|
270
285
|
|
|
271
286
|
// 2. Витягуємо файли з violation output і читаємо їх
|
|
272
287
|
const files = readFilesForFix(extractFilePaths(violationOutput), projectRoot)
|
|
@@ -274,7 +289,6 @@ export function runLlmWorker(ruleId, violationOutput, projectRoot, opts = {}) {
|
|
|
274
289
|
// 3. Будуємо summary промпту (для verbose-блоку) до виклику моделі
|
|
275
290
|
const promptSummary = {
|
|
276
291
|
ruleMdcLen: ruleMdc.length,
|
|
277
|
-
subCheckMdc: !!subMdc,
|
|
278
292
|
violationLen: violationOutput.length,
|
|
279
293
|
filesCount: files.length,
|
|
280
294
|
filesTotalBytes: files.reduce((s, f) => s + f.content.length, 0),
|
|
@@ -16,11 +16,12 @@ import { CLOUD_AVG, CLOUD_MIN, LOCAL_MIN } from '../../../lib/models.mjs'
|
|
|
16
16
|
const DEFAULT_MAX_AVG = 3
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
* Timeout одного LLM-виклику
|
|
20
|
-
*
|
|
21
|
-
* Хмарні —
|
|
19
|
+
* Timeout одного LLM-виклику (або всієї агентної сесії) за тиром.
|
|
20
|
+
* Локальні рунги — 5 хвилин: 4b модель повільна, основний backstop — turn-ceiling (~50).
|
|
21
|
+
* Хмарні — 2 хвилини: API-виклик швидкий, перевищення = transport-помилка.
|
|
22
|
+
* Перевизначення: `N_LOCAL_FIX_TIMEOUT_MS` / `N_CLOUD_FIX_TIMEOUT_MS`.
|
|
22
23
|
*/
|
|
23
|
-
const LOCAL_TIMEOUT_MS = Number(env.N_LOCAL_FIX_TIMEOUT_MS) ||
|
|
24
|
+
const LOCAL_TIMEOUT_MS = Number(env.N_LOCAL_FIX_TIMEOUT_MS) || 300_000
|
|
24
25
|
const CLOUD_TIMEOUT_MS = Number(env.N_CLOUD_FIX_TIMEOUT_MS) || 120_000
|
|
25
26
|
|
|
26
27
|
/** Маркер дружнього повідомлення про відсутній API-ключ (з `llm-worker.callModel`). */
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Worktree-скіли (`worktree: true`) свій root-assert уже мають у worktree-блоці
|
|
7
7
|
* (`worktree-notice.mjs`): корінь worktree = його toplevel. Цей модуль — для
|
|
8
|
-
* не-worktree-кейсу (напр. `n-
|
|
9
|
-
*
|
|
8
|
+
* не-worktree-кейсу (напр. `n-taze`, що мутує `package.json` безпосередньо
|
|
9
|
+
* й має стартувати з кореня монорепо).
|
|
10
10
|
*
|
|
11
11
|
* Блок — інструкція агенту, що читає `SKILL.md`; вставляється між стабільними
|
|
12
12
|
* маркерами, ре-синк ідемпотентний: наявний блок замінюється, при `false` —
|
package/scripts/lib/run-lint.mjs
CHANGED
|
@@ -166,22 +166,14 @@ async function runPerFileRules(ids, ctx) {
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
/**
|
|
169
|
-
* Конформність-фаза `--full
|
|
170
|
-
* (записи саме цього прогону), у fix-режимі по конформності викликає аналіз.
|
|
169
|
+
* Конформність-фаза `--full`.
|
|
171
170
|
* @param {string} cwd корінь
|
|
172
171
|
* @param {boolean} readOnly лише детект
|
|
173
172
|
* @param {(s: string) => void} log логер
|
|
174
173
|
* @returns {Promise<number>} код конформності
|
|
175
174
|
*/
|
|
176
175
|
async function runFullConformancePhase(cwd, readOnly, log) {
|
|
177
|
-
|
|
178
|
-
const escOffset = readOnly ? 0 : escalationLogSize()
|
|
179
|
-
const conformanceCode = await runConformance(cwd, readOnly, log)
|
|
180
|
-
if (!readOnly) {
|
|
181
|
-
reportRunStats(escOffset, log) // резюме викликів моделей (локальна / cloud-min / cloud-avg)
|
|
182
|
-
maybeAnalyzeEscalation(cwd, escOffset, log)
|
|
183
|
-
}
|
|
184
|
-
return conformanceCode
|
|
176
|
+
return runConformance(cwd, readOnly, log)
|
|
185
177
|
}
|
|
186
178
|
|
|
187
179
|
/**
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - `requireRoot` — boolean, опційне: чи скіл вимагає запуску з кореня репо.
|
|
8
8
|
* Worktree-скіли (`worktree:true`) вимагають кореня неявно (корінь worktree =
|
|
9
9
|
* його toplevel), тож для них поле зайве. Явний `requireRoot:true` — для
|
|
10
|
-
* in-place скілів, що мутують CWD без worktree-ізоляції (напр. `n-
|
|
10
|
+
* in-place скілів, що мутують CWD без worktree-ізоляції (напр. `n-taze`).
|
|
11
11
|
*
|
|
12
12
|
* Цим хелпером користуються `auto-skills.mjs` (автоактивація), `n-cursor.js`
|
|
13
13
|
* (sync + вшивання worktree/root-блоку) і check-концерн `npm-module/js/skill_meta.mjs`,
|
|
@@ -3,34 +3,31 @@ type: JS Module
|
|
|
3
3
|
title: walkDir.mjs
|
|
4
4
|
resource: npm/scripts/utils/walkDir.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
6
|
+
crc: 73503ca2
|
|
7
|
+
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
+
score: 100
|
|
7
9
|
---
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
## Огляд
|
|
12
|
+
|
|
13
|
+
Публічна функція `walkDir` здійснює рекурсивний пошук файлів у вказаному каталозі. Вона обходить файлову систему, ігноруючи каталоги `.git` та `node_modules`. Знаходячи кожен файл, вона передає його повний шлях у колбек для подальшої обробки. Компонент є read-only, тобто не виконує записів у файлову систему чи бази даних. При роботі з файловою системою він перехоплює помилки, забезпечуючи безпечну роботу без викидання винятків.
|
|
10
14
|
|
|
11
15
|
## Поведінка
|
|
12
16
|
|
|
13
|
-
1.
|
|
14
|
-
2.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
4. Якщо при спробі `readdir` для каталогу виникає помилка, обхід цього каталогу припиняється.
|
|
21
|
-
5. Обхід завершується, коли всі підкаталоги та файли в заданому дереві були оброблені.
|
|
17
|
+
1. Викликається функція walkDir для початку рекурсивного обходу каталогу.
|
|
18
|
+
2. Система розшифровує вхідний шлях до кореня обходу.
|
|
19
|
+
3. Система формує додаткові правила ігнорування на основі наданих шляхів.
|
|
20
|
+
4. Система завжди ігнорує каталоги .git та node_modules.
|
|
21
|
+
5. Система виконує пошук усіх файлів у каталозі, застосовуючи правила ігнорування, включаючи ті, що визначені в .gitignore.
|
|
22
|
+
6. У разі виникнення помилки під час пошуку, процес обходу припиняється без генерації винятку.
|
|
23
|
+
7. Для кожного знайденого файлу система викликає наданий колбек, передаючи йому повний абсолютний шлях до цього файлу.
|
|
22
24
|
|
|
23
25
|
## Публічний API
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
walkDir — рекурсивно переглядає файли та папки, ігноруючи ті, що вказані у файлі `.gitignore`.
|
|
26
28
|
|
|
27
29
|
## Гарантії поведінки
|
|
28
30
|
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
- Може пропустити каталоги, вказані в `ignorePaths`.
|
|
33
|
-
- У разі невдачі `readdir` для каталогу, функція тихо виходить без викидання помилок.
|
|
34
|
-
- Функція не викидає винятки назовні.
|
|
35
|
-
- У разі невдачі повертає `false` або `null`.
|
|
36
|
-
- Не використовує кешування.
|
|
31
|
+
- Read-only: не виконує операцій запису (ФС/БД).
|
|
32
|
+
- Перехоплює помилки і не пропускає винятків назовні (fail-safe).
|
|
33
|
+
- Свідомо пропускає шляхи: `.git`, `node_modules`.
|