@7n/rules 1.49.19 → 1.49.21

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,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.49.21] - 2026-07-27
4
+
5
+ ### Fixed
6
+
7
+ - v8r: validate VS Code extension recommendations with the local catalog
8
+
9
+ ## [1.49.20] - 2026-07-27
10
+
11
+ ### Fixed
12
+
13
+ - Allow committed branch changes and keep empty PR check rollups fail-closed
14
+
3
15
  ## [1.49.19] - 2026-07-27
4
16
 
5
17
  ### Fixed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@7n/rules",
3
- "version": "1.49.19",
3
+ "version": "1.49.21",
4
4
  "description": "CLI еталонних правил і skills (префікс n-): синк у репозиторій, дельта-lint, конформність",
5
5
  "keywords": [
6
6
  "cli",
@@ -15,13 +15,15 @@
15
15
  },
16
16
  {
17
17
  "name": "any.json",
18
- "description": "Заглушка-схема (приймає будь-який JSON) — bespoke tool-конфіги й one-off артефакти без офіційної схеми",
18
+ "description": "Заглушка-схема (приймає будь-який JSON) — bespoke tool-конфіги, VS Code extension recommendations і one-off артефакти без офіційної схеми",
19
19
  "url": "any.json",
20
20
  "fileMatch": [
21
21
  ".licensee.json",
22
22
  "**/.licensee.json",
23
23
  ".kubescape-exceptions.json",
24
24
  "**/.kubescape-exceptions.json",
25
+ ".vscode/extensions.json",
26
+ "**/.vscode/extensions.json",
25
27
  "docs/specs/**/*.json",
26
28
  "docs/plans/**/*.json",
27
29
  "any.json",
@@ -3,7 +3,7 @@ type: JS Module
3
3
  title: orchestrate.mjs
4
4
  resource: npm/skills/git-reconcile/js/orchestrate.mjs
5
5
  docgen:
6
- crc: e28dcd28
6
+ crc: f87f22fc
7
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
8
  score: 100
9
9
  ---
@@ -22,6 +22,8 @@ docgen:
22
22
 
23
23
  `runAsync` запускає install, tests, lint і PR checks без блокування event loop. Після push та `gh pr create` функція `verifyPullRequestReadiness` очікує terminal checks і передає набори PR/base checks у `classifyPullRequestChecks`. Успішний outcome `pr-created` повертається лише для `ready`; regression, baseline-red, pending, timeout або unreadable checks зберігають branch, URL і worktree та блокують cleanup.
24
24
 
25
+ `commitPendingChanges` створює додатковий commit лише для staged remediation. Чистий index після перенесення branch-source є валідним, коли корисні commits уже присутні в `HEAD`. Порожній PR check rollup вважається непідтвердженим, а не успішним.
26
+
25
27
  `cleanupSource` видаляє лише точний доказово безпечний branch/stash. Cleanup review-source дозволений після `drop` або коли всі його групи завершились `pr-created` чи `patch-equivalent`; `failed` і всі `pr-checks-*` outcomes лишають source та forensic worktree.
26
28
 
27
29
  ## Публічний API
@@ -33,6 +35,7 @@ docgen:
33
35
  - `callRunner`, `callWithValidatedFallback` — викликають runner за схемою `min → validation → max`.
34
36
  - `captureBehaviorBaseline`, `captureCachedBehaviorBaseline` — фіксують і кешують test baseline.
35
37
  - `validateBehaviorState`, `validateFinalProjectGates`, `remediateBehaviorState` — виконують behavioral та canonical gates.
38
+ - `commitPendingChanges` — комітить лише staged remediation, не вимагаючи порожнього commit для вже перенесених commits.
36
39
  - `classifyPullRequestChecks`, `verifyPullRequestReadiness` — класифікують CI відносно base commit.
37
40
  - `formatOutcomeCounts`, `formatReport` — формують точний deterministic summary.
38
41
  - `cleanupSource`, `runGitReconcileOrchestrator` — виконують безпечний cleanup і координують повний flow.
@@ -43,6 +46,7 @@ docgen:
43
46
  - Baseline test Promise дедуплікується між concurrent PR-групами одного base OID.
44
47
  - Canonical fixers охоплюють code/non-code scope, після чого gates повторюються без fix.
45
48
  - PR вважається створеним успішно лише після terminal green checks.
49
+ - Порожній PR check rollup fail-closed зберігає forensic worktree.
46
50
  - CI regression, baseline-red або непідтверджений стан завершують orchestration non-zero і зберігають forensic refs/worktree.
47
51
  - Cleanup не видаляє protected, open-PR, kept, failed або `pr-checks-*` sources.
48
52
  - `spawnSync.error`, зокрема `ENOENT`, зберігається в command diagnostics.
@@ -1420,6 +1420,12 @@ function normalizeGitHubCheck(check) {
1420
1420
  * @returns {{status:'ready'|'pr-checks-regressed'|'pr-checks-baseline-red'|'pr-checks-unverified',error?:string}} класифікація
1421
1421
  */
1422
1422
  export function classifyPullRequestChecks(prChecks, baseChecks) {
1423
+ if (prChecks.length === 0) {
1424
+ return {
1425
+ status: 'pr-checks-unverified',
1426
+ error: 'PR check rollup порожній: GitHub checks ще не зареєстровані'
1427
+ }
1428
+ }
1423
1429
  const normalizedPr = prChecks.map(check => normalizeGitHubCheck(check))
1424
1430
  const pending = normalizedPr.filter(check => check.state === 'pending')
1425
1431
  if (pending.length > 0) {
@@ -1526,6 +1532,26 @@ async function passFinalProjectGates(args) {
1526
1532
  return finalGates
1527
1533
  }
1528
1534
 
1535
+ /**
1536
+ * Комітить лише зміни, які лишилися в index після final gates. Branch sources
1537
+ * можуть уже мати готові commits після cherry-pick, тому чистий index є
1538
+ * валідним станом і не потребує порожнього commit.
1539
+ * @param {string} cwd worktree
1540
+ * @param {string} title commit message
1541
+ * @param {typeof spawnSync} spawnFn інжект
1542
+ * @returns {boolean} чи створено commit
1543
+ */
1544
+ export function commitPendingChanges(cwd, title, spawnFn = spawnSync) {
1545
+ git(['add', '-A'], cwd, spawnFn)
1546
+ const staged =
1547
+ git(['diff', '--cached', '--quiet'], cwd, spawnFn, {
1548
+ allowFailure: true
1549
+ }).status !== 0
1550
+ if (!staged) return false
1551
+ git(['commit', '-m', title], cwd, spawnFn)
1552
+ return true
1553
+ }
1554
+
1529
1555
  /**
1530
1556
  * Створює один готовий PR. При будь-якому провалі worktree лишається для
1531
1557
  * ручного відновлення; прибирається тільки після успішних CI checks.
@@ -1594,11 +1620,6 @@ async function createPullRequest(args) {
1594
1620
  if (unresolved.length > 0) throw new Error(`Нерозв'язані конфлікти: ${unresolved.join(', ')}`)
1595
1621
  git(['diff', '--check'], worktree.cwd, spawnFn)
1596
1622
  git(['add', '-A'], worktree.cwd, spawnFn)
1597
- const staged =
1598
- git(['diff', '--cached', '--quiet'], worktree.cwd, spawnFn, {
1599
- allowFailure: true
1600
- }).status !== 0
1601
- if (!staged) throw new Error('Після Git validation немає staged змін')
1602
1623
  if (!hasChangesFromBase(worktree.cwd, spawnFn)) {
1603
1624
  onProgress('remove no-op worktree')
1604
1625
  removeReconcileWorktree(worktree, rootCwd, spawnFn)
@@ -1612,8 +1633,7 @@ async function createPullRequest(args) {
1612
1633
  onProgress
1613
1634
  })
1614
1635
  if (!finalGates.ok) throw new Error(finalGates.error)
1615
- git(['add', '-A'], worktree.cwd, spawnFn)
1616
- git(['commit', '-m', group.title], worktree.cwd, spawnFn)
1636
+ commitPendingChanges(worktree.cwd, group.title, spawnFn)
1617
1637
  const baseRef = policyBaseRef(worktree.cwd)
1618
1638
  const baseBranch = readGitPolicy(worktree.cwd).baseBranch
1619
1639
  git(['diff', '--check', `${baseRef}...HEAD`], worktree.cwd, spawnFn)