@nitra/cursor 3.14.2 → 3.15.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 +6 -0
- package/package.json +1 -1
- package/scripts/lib/mirror-parity.mjs +60 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.15.0] - 2026-06-02
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- parity-гард дзеркала правил: тест перевіряє, що .cursor/rules/n-<id>.mdc == канонічний npm/rules/<id>/<id>.mdc з inlined-шаблонами (хелпер mirror-parity.mjs), ловлячи дрейф рано. Разово регенеровано наявний дрейф (changelog/flow/ga/npm-module/test).
|
|
8
|
+
|
|
3
9
|
## [3.14.2] - 2026-06-02
|
|
4
10
|
|
|
5
11
|
### Fixed
|
package/package.json
CHANGED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parity дзеркала правил: `.cursor/rules/n-<id>.mdc` має дорівнювати канонічному
|
|
3
|
+
* `npm/rules/<id>/<id>.mdc` з inlined-шаблонами — тим самим трансформом, що його
|
|
4
|
+
* застосовує синк (`readBundledRuleContent` → `inlineTemplateLinks`). Дрейф виникає,
|
|
5
|
+
* коли канонічний `.mdc` змінюють, не регенерувавши дзеркало (беклог адаптації flow #10).
|
|
6
|
+
*
|
|
7
|
+
* Використовується і тестом-гардом (drift === []), і разовою регенерацією.
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs'
|
|
10
|
+
import { dirname, join } from 'node:path'
|
|
11
|
+
|
|
12
|
+
import { inlineTemplateLinks } from './inline-template-links.mjs'
|
|
13
|
+
|
|
14
|
+
const MIRROR_PREFIX = 'n-'
|
|
15
|
+
const MDC_EXT = '.mdc'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Керовані дзеркала `.cursor/rules/n-<id>.mdc`, що мають канонічне джерело
|
|
19
|
+
* `npm/rules/<id>/<id>.mdc`. Дзеркала без канону (зовнішні) пропускаються.
|
|
20
|
+
* @param {string} repoRoot корінь репо
|
|
21
|
+
* @returns {{ id: string, mirrorPath: string, canonicalPath: string }[]} список
|
|
22
|
+
*/
|
|
23
|
+
export function listManagedMirrors(repoRoot) {
|
|
24
|
+
const rulesDir = join(repoRoot, '.cursor/rules')
|
|
25
|
+
if (!existsSync(rulesDir)) return []
|
|
26
|
+
return readdirSync(rulesDir)
|
|
27
|
+
.filter(f => f.startsWith(MIRROR_PREFIX) && f.endsWith(MDC_EXT))
|
|
28
|
+
.map(f => {
|
|
29
|
+
const id = f.slice(MIRROR_PREFIX.length, -MDC_EXT.length)
|
|
30
|
+
return {
|
|
31
|
+
id,
|
|
32
|
+
mirrorPath: join(rulesDir, f),
|
|
33
|
+
canonicalPath: join(repoRoot, 'npm/rules', id, `${id}${MDC_EXT}`)
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
.filter(m => existsSync(m.canonicalPath))
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Очікуваний вміст дзеркала = канон з inlined-шаблонами (трансформ синку).
|
|
41
|
+
* @param {string} canonicalPath абсолютний шлях `npm/rules/<id>/<id>.mdc`
|
|
42
|
+
* @returns {Promise<string>} очікуваний текст дзеркала
|
|
43
|
+
*/
|
|
44
|
+
export function expectedMirrorContent(canonicalPath) {
|
|
45
|
+
return inlineTemplateLinks(readFileSync(canonicalPath, 'utf8'), dirname(canonicalPath))
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Id дзеркал, що розійшлися з каноном (actual ≠ expected).
|
|
50
|
+
* @param {string} repoRoot корінь репо
|
|
51
|
+
* @returns {Promise<string[]>} відсортовані id дрейфу
|
|
52
|
+
*/
|
|
53
|
+
export async function findMirrorDrift(repoRoot) {
|
|
54
|
+
const drift = []
|
|
55
|
+
for (const m of listManagedMirrors(repoRoot)) {
|
|
56
|
+
const expected = await expectedMirrorContent(m.canonicalPath)
|
|
57
|
+
if (readFileSync(m.mirrorPath, 'utf8') !== expected) drift.push(m.id)
|
|
58
|
+
}
|
|
59
|
+
return drift.sort()
|
|
60
|
+
}
|