@nitra/cursor 12.2.0 → 12.3.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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## [12.3.0] - 2026-06-19
4
+
5
+ ### Added
6
+
7
+ - lint --full: резюме викликів моделей у stdout (локальна / cloud-min / cloud-avg) через reportRunStats/summarizeCalls
8
+
3
9
  ## [12.2.0] - 2026-06-19
4
10
 
5
11
  ### Changed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nitra/cursor",
3
- "version": "12.2.0",
3
+ "version": "12.3.0",
4
4
  "description": "CLI для завантаження cursor-правил (префікс n-) у локальний репозиторій",
5
5
  "keywords": [
6
6
  "cli",
@@ -3,7 +3,7 @@ type: JS Module
3
3
  title: orchestrate.mjs
4
4
  resource: npm/rules/lint/js/orchestrate.mjs
5
5
  docgen:
6
- crc: f4eb439d
6
+ crc: 0f1d717c
7
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
8
  score: 100
9
9
  ---
@@ -16,7 +16,7 @@ docgen:
16
16
  selectLintRules вибирає і сортує ідентифікатори правил на основі їхнього обсягу дії (`per-file` або `full`) та прапорця `--full`.
17
17
  runLint запускає оркестрацію лінтування: або виконує перевірку конформності для заданих правил, або ітерує по алфавітно відсортованих правилах (`runPerFileRules`), запускаючи лінтер для змінених файлів (за замовчуванням), або виконує перевірку конформності всього репозиторію при використанні прапорця `--full`.
18
18
  **Fail-fast — лише в `--read-only`** (CI/детект): перший ненульовий код спиняє. У fix-режимі (default) ненульовий код per-file правила НЕ спиняє — проганяються всі правила й виконується крок виправлення (конформність-драбина), а повертається найгірший код.
19
- У режимі `--full` без `--read-only` після конформність-фази (`runFullConformancePhase`) викликається escalation-аналітика (`analyze-escalation.mjs`): фіксує зсув escalation-логу до фази, після — аналізує записи саме цього прогону. Аналіз не впливає на exit-код lint.
19
+ У режимі `--full` без `--read-only` після конформність-фази (`runFullConformancePhase`) друкується резюме викликів моделей за прогін (`reportRunStats`: локальна / cloud-min / cloud-avg) і викликається escalation-аналітика (`analyze-escalation.mjs`): фіксує зсув escalation-логу до фази, після — аналізує записи саме цього прогону. Жодне з цього не впливає на exit-код lint.
20
20
 
21
21
  ## Публічний API
22
22
 
@@ -122,10 +122,15 @@ async function runPerFileRules(ids, ctx) {
122
122
  * @returns {Promise<number>} код конформності
123
123
  */
124
124
  async function runFullConformancePhase(cwd, readOnly, log) {
125
- const { escalationLogSize, maybeAnalyzeEscalation } = await import('../../../scripts/lib/fix/analyze-escalation.mjs')
125
+ const { escalationLogSize, maybeAnalyzeEscalation, reportRunStats } = await import(
126
+ '../../../scripts/lib/fix/analyze-escalation.mjs'
127
+ )
126
128
  const escOffset = readOnly ? 0 : escalationLogSize()
127
129
  const conformanceCode = await runConformance(cwd, readOnly, log)
128
- if (!readOnly) maybeAnalyzeEscalation(cwd, escOffset, log)
130
+ if (!readOnly) {
131
+ reportRunStats(escOffset, log) // резюме викликів моделей (локальна / cloud-min / cloud-avg)
132
+ maybeAnalyzeEscalation(cwd, escOffset, log)
133
+ }
129
134
  return conformanceCode
130
135
  }
131
136
 
@@ -107,6 +107,41 @@ export function readEscalationRecords(path, sinceOffset = 0) {
107
107
  return out
108
108
  }
109
109
 
110
+ /** Маркер skip-запису avg-рунга (кеп вичерпано) — НЕ фактичний виклик моделі. */
111
+ const AVG_SKIP_MARKER = 'cloud-avg cap reached'
112
+
113
+ /**
114
+ * Рахує фактичні виклики моделей за тирами (skip-записи avg-кепу не рахуються).
115
+ * @param {object[]} records записи рунгів
116
+ * @returns {{ local: number, cloudMin: number, cloudAvg: number }} лічильники викликів
117
+ */
118
+ export function summarizeCalls(records) {
119
+ const stats = { local: 0, cloudMin: 0, cloudAvg: 0 }
120
+ for (const r of records) {
121
+ if (r.callError === AVG_SKIP_MARKER) continue
122
+ if (r.tier === 'cloud-avg') stats.cloudAvg++
123
+ else if (r.tier === 'cloud-min') stats.cloudMin++
124
+ else if (typeof r.tier === 'string' && r.tier.startsWith('local')) stats.local++
125
+ }
126
+ return stats
127
+ }
128
+
129
+ /**
130
+ * Друкує резюме викликів моделей за цей прогін (локальна / cloud-min / cloud-avg).
131
+ * No-op, якщо викликів не було. Читає записи від `sinceOffset`.
132
+ * @param {number} sinceOffset байтовий зсув логу перед прогоном
133
+ * @param {(s: string) => void} log логер
134
+ * @returns {void}
135
+ */
136
+ export function reportRunStats(sinceOffset, log) {
137
+ const { local, cloudMin, cloudAvg } = summarizeCalls(readEscalationRecords(escalationLogPath(), sinceOffset))
138
+ if (local + cloudMin + cloudAvg === 0) return
139
+ log(
140
+ `\n📊 LLM-виклики fix-конформності (цей прогін): ` +
141
+ `локальна ${local} · cloud-min ${cloudMin} · cloud-avg ${cloudAvg}\n`
142
+ )
143
+ }
144
+
110
145
  /**
111
146
  * Стискає запис до полів, важливих для аналізу (без ts/ms-шуму).
112
147
  * @param {object} r сирий запис рунга
@@ -3,7 +3,7 @@ type: JS Module
3
3
  title: analyze-escalation.mjs
4
4
  resource: npm/scripts/lib/fix/analyze-escalation.mjs
5
5
  docgen:
6
- crc: f802e47f
6
+ crc: 5a586df6
7
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
8
  score: 100
9
9
  ---
@@ -16,6 +16,8 @@ docgen:
16
16
 
17
17
  ## Публічний API
18
18
 
19
+ - `summarizeCalls(records)` — лічильники фактичних викликів за тирами `{ local, cloudMin, cloudAvg }` (skip-записи avg-кепу не рахуються).
20
+ - `reportRunStats(sinceOffset, log)` — друкує резюме викликів моделей за прогін (no-op, якщо викликів не було).
19
21
  - `analysisEnabled()` — чи дозволено авто-аналіз (kill-switch `N_CURSOR_FIX_ANALYZE`).
20
22
  - `escalationLogSize(path?)` — розмір логу в байтах (since-offset).
21
23
  - `readEscalationRecords(path, sinceOffset?)` — записи від зсуву.