@nitra/cursor 3.24.0 → 3.25.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/n-cursor.js +36 -6
- package/package.json +1 -1
- package/scripts/coverage-fix.mjs +6 -1
- package/skills/fix/SKILL.md +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.25.1] - 2026-06-06
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- coverage --fix: додано permissionMode:'bypassPermissions' у claude-agent-sdk query — без нього headless-агент не отримував дозволу на Edit/Bash і не редагував файли (крутився, палив токени, нічого не писав). Тепер автономний coverage --fix реально дописує тести й ганяє bun test
|
|
8
|
+
|
|
9
|
+
## [3.25.0] - 2026-06-06
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- fix: прапорець `n-cursor fix --json` друкує компактний {total, failed, rules:[{ruleId, ok, output}]} у stdout (per-rule захоплення замість stdio inherit; у json-режимі пропускається ensureHkInstall, щоб stdout лишався чистим JSON). Скіл n-fix більше не парсить термінальний вивід — працює лише з rules[].ok:false. Дефолтна поведінка без прапорця незмінна
|
|
14
|
+
|
|
3
15
|
## [3.24.0] - 2026-06-05
|
|
4
16
|
|
|
5
17
|
### Added
|
package/bin/n-cursor.js
CHANGED
|
@@ -1230,11 +1230,17 @@ function logRemovedManagedItems(title, basePath, names) {
|
|
|
1230
1230
|
* На рівні `runFixCommand` локу нема: різні набори правил можуть прогресувати незалежно,
|
|
1231
1231
|
* а однакові правила серіалізуються в spawn'ах нижче.
|
|
1232
1232
|
* @param {string[]} requestedRules імена правил; порожній масив — discovery з `.cursor/rules/`
|
|
1233
|
+
* @param {{json?: boolean}} [opts] json — друкувати компактний JSON `{total, failed, rules:[{ruleId, ok, output}]}`
|
|
1234
|
+
* замість per-rule stdio + timing (для скілу n-fix: агент читає лише впалі правила, не парсить текст)
|
|
1233
1235
|
* @returns {Promise<void>}
|
|
1234
1236
|
*/
|
|
1235
|
-
async function runFixCommand(requestedRules) {
|
|
1237
|
+
async function runFixCommand(requestedRules, opts = {}) {
|
|
1238
|
+
const json = opts.json === true
|
|
1239
|
+
// json-режим — діагностичний read-only вивід для скілу: пропускаємо встановлення
|
|
1240
|
+
// git-hook (`ensureHkInstall` друкує «Installed hk hook…» у stdout і забруднив би
|
|
1241
|
+
// чистий JSON; сам pre-commit hook для діагностики не потрібен).
|
|
1236
1242
|
const hkBin = ensureTool('hk')
|
|
1237
|
-
ensureHkInstall(hkBin)
|
|
1243
|
+
if (!json) ensureHkInstall(hkBin)
|
|
1238
1244
|
ensureTool('conftest')
|
|
1239
1245
|
|
|
1240
1246
|
const available = await listRuleIds(BUNDLED_RULES_DIR)
|
|
@@ -1261,6 +1267,10 @@ async function runFixCommand(requestedRules) {
|
|
|
1261
1267
|
}
|
|
1262
1268
|
idsToRun = discoverCheckRulesFromCursorRules(available, mdcFiles)
|
|
1263
1269
|
if (idsToRun.length === 0) {
|
|
1270
|
+
if (json) {
|
|
1271
|
+
process.stdout.write(`${JSON.stringify({ total: 0, failed: 0, rules: [] })}\n`)
|
|
1272
|
+
return
|
|
1273
|
+
}
|
|
1264
1274
|
console.log(
|
|
1265
1275
|
`\n🔍 ${PACKAGE_NAME} fix — у ${RULES_DIR}/ немає правил з programmatic перевіркою ` +
|
|
1266
1276
|
`(відповідного fix.mjs у пакеті). Нічого не запущено.\n`
|
|
@@ -1272,16 +1282,29 @@ async function runFixCommand(requestedRules) {
|
|
|
1272
1282
|
let totalFailed = 0
|
|
1273
1283
|
/** @type {{ id: string, ms: number, ok: boolean }[]} */
|
|
1274
1284
|
const timings = []
|
|
1285
|
+
/** @type {{ ruleId: string, ok: boolean, output: string }[]} */
|
|
1286
|
+
const ruleResults = []
|
|
1275
1287
|
for (const id of idsToRun) {
|
|
1276
1288
|
const fixPath = join(BUNDLED_RULES_DIR, id, 'fix.mjs')
|
|
1277
1289
|
const startedAt = Date.now()
|
|
1278
|
-
|
|
1290
|
+
// json-режим: захоплюємо stdout/stderr правила у структуру (а не inherit у термінал),
|
|
1291
|
+
// щоб віддати агенту згруповано {ruleId, ok, output} і він читав лише впалі.
|
|
1292
|
+
const result = json
|
|
1293
|
+
? spawnSync('bun', [fixPath], { encoding: 'utf8' })
|
|
1294
|
+
: spawnSync('bun', [fixPath], { stdio: 'inherit' })
|
|
1279
1295
|
const ok = result.status === 0
|
|
1280
1296
|
timings.push({ id: `fix-${id}`, ms: Date.now() - startedAt, ok })
|
|
1297
|
+
if (json) {
|
|
1298
|
+
ruleResults.push({ ruleId: id, ok, output: `${result.stdout ?? ''}${result.stderr ?? ''}`.trim() })
|
|
1299
|
+
}
|
|
1281
1300
|
if (!ok) totalFailed++
|
|
1282
1301
|
}
|
|
1283
1302
|
|
|
1284
|
-
|
|
1303
|
+
if (json) {
|
|
1304
|
+
process.stdout.write(`${JSON.stringify({ total: idsToRun.length, failed: totalFailed, rules: ruleResults })}\n`)
|
|
1305
|
+
} else {
|
|
1306
|
+
process.stdout.write(formatTimingSummary('Fix timing', timings))
|
|
1307
|
+
}
|
|
1285
1308
|
|
|
1286
1309
|
if (totalFailed > 0) {
|
|
1287
1310
|
throw new Error(`${totalFailed} з ${idsToRun.length} правил мають проблеми`)
|
|
@@ -1573,7 +1596,11 @@ try {
|
|
|
1573
1596
|
await ensureNitraCursorInRootDevDependencies(cwd())
|
|
1574
1597
|
switch (command) {
|
|
1575
1598
|
case 'fix': {
|
|
1576
|
-
|
|
1599
|
+
// --json: компактний {total, failed, rules:[{ruleId, ok, output}]} у stdout для скілу n-fix.
|
|
1600
|
+
await runFixCommand(
|
|
1601
|
+
args.filter(a => a !== '--json'),
|
|
1602
|
+
{ json: args.includes('--json') }
|
|
1603
|
+
)
|
|
1577
1604
|
|
|
1578
1605
|
break
|
|
1579
1606
|
}
|
|
@@ -1582,7 +1609,10 @@ try {
|
|
|
1582
1609
|
console.warn(
|
|
1583
1610
|
`⚠️ Команда \`check\` deprecated — використовуйте \`fix\` (\`npx ${PACKAGE_NAME} fix [<rule>...]\`)`
|
|
1584
1611
|
)
|
|
1585
|
-
await runFixCommand(
|
|
1612
|
+
await runFixCommand(
|
|
1613
|
+
args.filter(a => a !== '--json'),
|
|
1614
|
+
{ json: args.includes('--json') }
|
|
1615
|
+
)
|
|
1586
1616
|
|
|
1587
1617
|
break
|
|
1588
1618
|
}
|
package/package.json
CHANGED
package/scripts/coverage-fix.mjs
CHANGED
|
@@ -39,7 +39,12 @@ export async function fixSurvivedMutants(survived, projectRoot) {
|
|
|
39
39
|
options: {
|
|
40
40
|
cwd: projectRoot,
|
|
41
41
|
maxTurns: 20,
|
|
42
|
-
allowedTools: ['Read', 'Edit', 'Bash']
|
|
42
|
+
allowedTools: ['Read', 'Edit', 'Bash'],
|
|
43
|
+
// Без permissionMode headless-агент SDK не отримує дозволу на запис/Bash —
|
|
44
|
+
// він крутиться, палить токени, але НЕ редагує файли (підтверджено пробом).
|
|
45
|
+
// `bypassPermissions` потрібен, бо агент і пише тести (Edit), і ганяє `bun test` (Bash);
|
|
46
|
+
// `acceptEdits` авто-підтверджує лише edits, а Bash лишився б заблокованим.
|
|
47
|
+
permissionMode: 'bypassPermissions'
|
|
43
48
|
}
|
|
44
49
|
})) {
|
|
45
50
|
if (msg.type === 'text') process.stdout.write(msg.text)
|
package/skills/fix/SKILL.md
CHANGED
|
@@ -12,13 +12,13 @@ description: >-
|
|
|
12
12
|
|
|
13
13
|
## Workflow
|
|
14
14
|
|
|
15
|
-
1. **Діагностика** — запусти перевірку через retry-обгортку `n_cursor_npx` (визначена у worktree-preflight, крок 0.1: переживає транзитну CDN-гонку щойно опублікованої версії, а реальний `❌` від `fix` віддає одразу). За замовчуванням — лише правила з `.cursor/rules/*.mdc`, для яких у пакеті є programmatic check; повний набір — явні аргументи: `n_cursor_npx fix bun ga
|
|
15
|
+
1. **Діагностика** — запусти перевірку через retry-обгортку `n_cursor_npx` (визначена у worktree-preflight, крок 0.1: переживає транзитну CDN-гонку щойно опублікованої версії, а реальний `❌` від `fix` віддає одразу). Прапорець `--json` дає **структурований** результат у stdout, щоб не парсити термінальний текст. За замовчуванням — лише правила з `.cursor/rules/*.mdc`, для яких у пакеті є programmatic check; повний набір — явні аргументи: `n_cursor_npx fix bun ga --json`:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
n_cursor_npx fix
|
|
18
|
+
n_cursor_npx fix --json
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
2. **Аналіз** —
|
|
21
|
+
2. **Аналіз** — розбери JSON `{ total, failed, rules: [{ ruleId, ok, output }] }`. Працюй **лише** з елементами `ok:false`; їх `output` містить готові `❌`-повідомлення правила (не парси stdout вручну, не визначай правила з тексту). Якщо `failed === 0` — нічого виправляти.
|
|
22
22
|
|
|
23
23
|
3. **Виправлення** — для кожного `❌` відкрий відповідне правило з `.cursor/rules/` і виправ:
|
|
24
24
|
- Створи відсутні конфігураційні файли (`.cspell.json`, `.oxfmtrc.json`, `eslint.config.js`, тощо)
|
|
@@ -40,10 +40,10 @@ bun i
|
|
|
40
40
|
oxfmt .
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
6. **Верифікація** — перевір що все виправлено (та сама retry-обгортка `n_cursor_npx`)
|
|
43
|
+
6. **Верифікація** — перевір що все виправлено (та сама retry-обгортка `n_cursor_npx`); чекаєш `failed === 0`:
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
|
-
n_cursor_npx fix
|
|
46
|
+
n_cursor_npx fix --json
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
7. **Результат** —
|
|
49
|
+
7. **Результат** — `failed` має стати `0` (усі правила `ok:true`). Якщо лишились `ok:false` — повтори кроки 3-6. Лінт-помилки від `bun run lint` тут **не виправляй** — вони на скіл `/n-lint`.
|