@7n/rules 1.44.0 → 1.44.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
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.44.1] - 2026-07-23
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- worktree-only скіли (n-lint/n-taze/n-adr-normalize): preflight і ensureRunningInWorktree визнають .claude/worktrees/ (harness Claude Code) як вже ізольований worktree — не пропонують створювати вкладене .worktrees/ дерево
|
|
8
|
+
|
|
3
9
|
## [1.44.0] - 2026-07-22
|
|
4
10
|
|
|
5
11
|
### Added
|
package/package.json
CHANGED
|
@@ -28,7 +28,9 @@ async function defaultConfirm(message) {
|
|
|
28
28
|
* Гарантує, що подальші кроки виконуються в ізольованому worktree
|
|
29
29
|
* (`main.json.worktree: true`-контракт), навіть коли викликач — детермінований
|
|
30
30
|
* JS-код, що не годує SKILL.md жодному LLM-агенту (тож агентський preflight-блок
|
|
31
|
-
* з `worktree-notice.mjs` нікому виконувати). Якщо `cwd` вже під `.worktrees/`
|
|
31
|
+
* з `worktree-notice.mjs` нікому виконувати). Якщо `cwd` вже під `.worktrees/`
|
|
32
|
+
* (репо-конвенція) або `.claude/worktrees/` (worktree харнесу Claude Code,
|
|
33
|
+
* куди `npx \@7n/mt worktree create` класти заборонено — `n-worktree.mdc`) —
|
|
32
34
|
* повертає його без змін. Інакше сам створює `.worktrees/<branch>-<suffix>`
|
|
33
35
|
* (`npx \@7n/mt worktree create`) і ставить залежності (`bun install`).
|
|
34
36
|
*
|
|
@@ -62,8 +64,12 @@ export async function ensureRunningInWorktree(
|
|
|
62
64
|
) {
|
|
63
65
|
const toplevelResult = spawnFn('git', ['rev-parse', '--show-toplevel'], { cwd, encoding: 'utf8' })
|
|
64
66
|
const toplevel = toplevelResult.status === 0 ? toplevelResult.stdout.trim() : ''
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
+
const pathSegments = toplevel.replaceAll('\\', '/').split('/')
|
|
68
|
+
const segments = new Set(pathSegments)
|
|
69
|
+
const isClaudeHarnessWorktree = pathSegments.some(
|
|
70
|
+
(seg, i) => seg === '.claude' && pathSegments[i + 1] === 'worktrees'
|
|
71
|
+
)
|
|
72
|
+
if (segments.has('.worktrees') || isClaudeHarnessWorktree) return { cwd, autoCreated: false, branchArg: null }
|
|
67
73
|
|
|
68
74
|
const branchResult = spawnFn('git', ['branch', '--show-current'], { cwd, encoding: 'utf8' })
|
|
69
75
|
const currentBranch = branchResult.status === 0 ? branchResult.stdout.trim() : ''
|
|
@@ -3,28 +3,66 @@ type: JS Module
|
|
|
3
3
|
title: auto-worktree.mjs
|
|
4
4
|
resource: npm/scripts/lib/auto-worktree.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
7
|
-
model:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
judgeModel: openai-codex/gpt-5.4-mini
|
|
6
|
+
crc: 2a9e7bfd
|
|
7
|
+
model: omlx/gemma-4-e2b-it-4bit
|
|
8
|
+
tier: local-min-retry
|
|
9
|
+
score: 90
|
|
11
10
|
---
|
|
12
11
|
|
|
13
12
|
## Огляд
|
|
14
13
|
|
|
15
|
-
|
|
14
|
+
Функції забезпечують ізоляцію роботи з кодом у worktree, перенесення змін між робочими середовищами та керування життєвим циклом створеного worktree. ensureRunningInWorktree гарантує роботу в ізольованому середовищі, bringChangesBackToOriginal переносить модифікації з worktree назад до основного репозиторію, використовуючи механізм копіювання, а не git merge, removeAutoCreatedWorktree забезпечує прибирання, видаляючи сам worktree після завершення операції.
|
|
16
15
|
|
|
17
16
|
## Поведінка
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
- `bringChangesBackToOriginal` — переносить зміни з автоствореного worktree назад у вихідне дерево як untracked/незакомічені правки, включно з додаванням, оновленням і видаленням файлів; перейменування переносить лише в нову назву.
|
|
21
|
-
- `removeAutoCreatedWorktree` — прибирає автостворений worktree разом із його ефемерною гілкою після перенесення змін назад, а у разі збою лише повідомляє про ручне прибирання.
|
|
18
|
+
Поведінка: Функції взаємодіють для ізоляції роботи з кодом у worktree, перенесенні змін між робочими середовищами та керування життєвим циклом створюваного worktree. `ensureRunningInWorktree` гарантує роботу в ізольованому середовищі, тоді як `bringChangesBackToOriginal` переносить модифікації з worktree назад до основного репозиторію, використовуючи механізм копіювання, а не git merge. `removeAutoCreatedWorktree` забезпечує прибирання, видаляючи сам worktree, що виконується лише після завершення операції з `bringChangesBackToOriginal`.
|
|
22
19
|
|
|
23
20
|
## Публічний API
|
|
24
21
|
|
|
25
|
-
- ensureRunningInWorktree —
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
- ensureRunningInWorktree — Гарантує, що подальші кроки виконуються в ізольованому worktree
|
|
23
|
+
(`main.json.worktree: true`-контракт), навіть коли викликач — детермінований
|
|
24
|
+
JS-код, що не годує SKILL.md жодному LLM-агенту (тож агентський preflight-блок
|
|
25
|
+
з `worktree-notice.mjs` нікому виконувати). Якщо `cwd` вже під `.worktrees/`
|
|
26
|
+
(репо-конвенція) або `.claude/worktrees/` (worktree харнесу Claude Code,
|
|
27
|
+
куди `npx \@7n/mt worktree create` класти заборонено — `n-worktree.mdc`) —
|
|
28
|
+
повертає його без змін. Інакше сам створює `.worktrees/<branch>-<suffix>`
|
|
29
|
+
(`npx \@7n/mt worktree create`) і ставить залежності (`bun install`).
|
|
30
|
+
|
|
31
|
+
**Гейт на чисте дерево.** Auto-create читає стан і потім переносить зміни
|
|
32
|
+
назад копіюванням файлів (`bringChangesBackToOriginal`) — а не git merge.
|
|
33
|
+
Якщо у вихідному `cwd` вже є незакомічені зміни, вони НЕ потраплять у щойно
|
|
34
|
+
створений worktree (той — checkout HEAD), і перенесення назад мовчки
|
|
35
|
+
затерло б їх версією з worktree. Тому за замовчуванням (`requireCleanTree:
|
|
36
|
+
true`) на брудному дереві auto-create питає в терміналі (`deps.confirm`,
|
|
37
|
+
дефолт — y/N через stdin; поза TTY одразу "ні") дозвіл закомить і
|
|
38
|
+
запушити зараз через `npx \@7n/n push` (сквош усього робочого дерева в один
|
|
39
|
+
коміт + push у origin — сама команда підтвердження не питає, тому питаємо
|
|
40
|
+
ми, ДО виклику). На "ні"/поза TTY — кидає, як і раніше. Викликач, що
|
|
41
|
+
гарантує чистоту дерева сам (наприклад taze — SKILL.md вимагає цього як
|
|
42
|
+
передумову ще ДО виклику), може передати `requireCleanTree: false`, щоб не
|
|
43
|
+
платити за зайву git-команду і не питати підтвердження.
|
|
44
|
+
- bringChangesBackToOriginal — Переносить зміни з автоствореного worktree назад у вихідне дерево як
|
|
45
|
+
**untracked/незакомічені** правки (просте копіювання файлів, без git
|
|
46
|
+
merge/cherry-pick). Джерело істини — `git status --porcelain` у worktree:
|
|
47
|
+
для кожного шляху копіює файл, якщо він існує (модифікація/додавання), або
|
|
48
|
+
видаляє його у вихідному дереві, якщо existsSync каже, що в worktree його
|
|
49
|
+
вже нема (видалення). Перейменування (`old -> new` у porcelain) переносять
|
|
50
|
+
лише нову назву — стара лишається як була, прийнятний компроміс для
|
|
51
|
+
інструментів, що самі файли не перейменовують (ефект можливий лише як
|
|
52
|
+
побічний результат LLM-рефакторингу чи форматера).
|
|
53
|
+
|
|
54
|
+
**Untracked-директорія цілком.** Git схлопує щойно створену untracked
|
|
55
|
+
директорію в один porcelain-рядок із `/` на кінці (якщо в ній нема жодного
|
|
56
|
+
файлу, вже відомого git) — `copyFile` на такий шлях впав би (`EISDIR`/`ENOENT`)
|
|
57
|
+
і обривав би цикл, гублячи все, що йшло по порядку ітерації ДАЛІ. Такий
|
|
58
|
+
рядок (суфікс `/` або реальний каталог на диску) копіюється рекурсивно
|
|
59
|
+
(`copyDirectoryRecursive`) — весь вміст, а не один `copyFile`.
|
|
60
|
+
- removeAutoCreatedWorktree — Прибирає автостворений worktree разом з його ефемерною git-гілкою
|
|
61
|
+
(`npx \@7n/mt worktree remove <branch>`) — викликати лише ПІСЛЯ
|
|
62
|
+
`bringChangesBackToOriginal`, інакше зміни згорять разом з деревом.
|
|
63
|
+
Не кидає при провалі — це прибирання, а не крок, від якого залежить
|
|
64
|
+
результат прогону; провал лише логується, worktree лишається для
|
|
65
|
+
ручного розбору.
|
|
28
66
|
|
|
29
67
|
## Гарантії поведінки
|
|
30
68
|
|
|
@@ -3,25 +3,80 @@ type: JS Module
|
|
|
3
3
|
title: worktree-notice.mjs
|
|
4
4
|
resource: npm/scripts/lib/worktree-notice.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
7
|
-
model: omlx/gemma-4-
|
|
6
|
+
crc: 4feb8b6c
|
|
7
|
+
model: omlx/gemma-4-e2b-it-4bit
|
|
8
|
+
tier: local-min-retry
|
|
8
9
|
score: 100
|
|
9
10
|
---
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
## Огляд
|
|
13
|
+
|
|
14
|
+
Цей файл містить інструкції для вбудовування вказівки про використання worktree-гілки в синкнутий текст `SKILL.md`. Він забезпечує ідемпотентне заміщення або видалення цього блоку залежно від значення `main.json.worktree`, забезпечуючи зв'язок з інструкціями щодо роботи з окремими Git-репозиторіями та інструментами для управління залежностями та бінарними викликами.
|
|
15
|
+
|
|
16
|
+
## Behavior
|
|
17
|
+
Транслітерує кирилицю в ASCII для короткого suffix
|
|
18
|
+
@param {string} value вхідний текст
|
|
19
|
+
@returns {string} транслітерований текст
|
|
20
|
+
|
|
21
|
+
### deriveSuffix
|
|
22
|
+
Робить короткий безпечний suffix для worktree-гілки з назви скіла
|
|
23
|
+
@param {string} content вміст `SKILL.md`
|
|
24
|
+
@returns {string} suffix до 10 символів
|
|
25
|
+
викликає: transliterate
|
|
26
|
+
|
|
27
|
+
### buildNoticeBody
|
|
28
|
+
Тіло worktree-інструкції з конкретним суфіксом, щоб агент не питав назву гілки
|
|
29
|
+
@param {string} suffix короткий suffix задачі
|
|
30
|
+
@returns {string} markdown-блок без маркерів
|
|
31
|
+
|
|
32
|
+
### buildBlock
|
|
33
|
+
Канонічний блок worktree-інструкції
|
|
34
|
+
@param {string} content вміст `SKILL.md`
|
|
35
|
+
@returns {string} текст блоку від START до END
|
|
36
|
+
викликає: buildNoticeBody
|
|
37
|
+
|
|
38
|
+
### injectWorktreeNotice
|
|
39
|
+
Вставляє / оновлює / видаляє worktree-блок у вмісті `SKILL.md`
|
|
40
|
+
@param {string} content вміст `SKILL.md`
|
|
41
|
+
@param {boolean} enabled чи має бути блок значення `main.json.worktree`
|
|
42
|
+
@returns {string} оновлений вміст ідемпотентно
|
|
12
43
|
|
|
13
44
|
## Поведінка
|
|
14
45
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
46
|
+
Транслітерує кирилицю в ASCII для короткого suffix
|
|
47
|
+
@param {string} value вхідний текст
|
|
48
|
+
@returns {string} транслітерований текст
|
|
49
|
+
|
|
50
|
+
### deriveSuffix
|
|
51
|
+
Робить короткий безпечний suffix для worktree-гілки з назви скіла
|
|
52
|
+
@param {string} content вміст `SKILL.md`
|
|
53
|
+
@returns {string} suffix до 10 символів
|
|
54
|
+
викликає: transliterate
|
|
55
|
+
|
|
56
|
+
### buildNoticeBody
|
|
57
|
+
Тіло worktree-інструкції з конкретним суфіксом, щоб агент не питав назву гілки
|
|
58
|
+
@param {string} suffix короткий suffix задачі
|
|
59
|
+
@returns {string} markdown-блок без маркерів
|
|
60
|
+
|
|
61
|
+
### buildBlock
|
|
62
|
+
Канонічний блок worktree-інструкції
|
|
63
|
+
@param {string} content вміст `SKILL.md`
|
|
64
|
+
@returns {string} текст блоку від START до END
|
|
65
|
+
викликає: buildNoticeBody, deriveSuffix
|
|
66
|
+
|
|
67
|
+
### injectWorktreeNotice
|
|
68
|
+
Вставляє / оновлює / видаляє worktree-блок у вмісті `SKILL.md`
|
|
69
|
+
@param {string} content вміст `SKILL.md`
|
|
70
|
+
@param {boolean} enabled чи має бути блок значення `main.json.worktree`
|
|
71
|
+
@returns {string} оновлений вміст ідемпотентно
|
|
72
|
+
викликає: buildBlock
|
|
18
73
|
|
|
19
74
|
## Публічний API
|
|
20
75
|
|
|
21
|
-
WORKTREE_START —
|
|
22
|
-
WORKTREE_END —
|
|
23
|
-
injectWorktreeNotice —
|
|
76
|
+
- WORKTREE_START — Маркер початку worktree-блоку (стабільний, не залежить від тексту всередині).
|
|
77
|
+
- WORKTREE_END — Маркер кінця worktree-блоку.
|
|
78
|
+
- injectWorktreeNotice — Вставляє / оновлює / видаляє worktree-блок у вмісті `SKILL.md`.
|
|
24
79
|
|
|
25
80
|
## Гарантії поведінки
|
|
26
81
|
|
|
27
|
-
-
|
|
82
|
+
- Власних операцій запису (ФС/БД) у файлі немає; виклики імпортованих модулів можуть писати.
|
|
@@ -133,7 +133,9 @@ git branch --show-current
|
|
|
133
133
|
|
|
134
134
|
**Root-assert.** Якщо \`pwd\` **не** збігається з виводом \`git rev-parse --show-toplevel\` — ти в **піддиректорії** робочого дерева (worktree-шляхи нижче відносні до кореня репо). Спершу перейди в корінь: \`cd <toplevel>\` (literal-шлях із виводу), і лише тоді продовжуй preflight. Не створюй worktree з піддиректорії — \`cd .worktrees/<…>\` звідти впаде.
|
|
135
135
|
|
|
136
|
-
Якщо \`git rev-parse --show-toplevel\`
|
|
136
|
+
**Вже ізольований — нічого не створюй.** Якщо \`git rev-parse --show-toplevel\` містить сегмент \`.worktrees/<…>\` (репо-конвенція) **або** \`.claude/worktrees/<…>\` (worktree харнесу Claude Code — туди \`npx @7n/mt worktree create\` класти заборонено, \`n-worktree.mdc\`) — ти вже виконуєшся в окремому git-worktree. Preflight пройдено: нічого не створюй, нікого не питай про назву гілки — переходь одразу до Кроку 0.1.
|
|
137
|
+
|
|
138
|
+
Інакше, якщо toplevel не містить жодного з цих сегментів, візьми вивід \`git branch --show-current\` як \`<current-branch>\` і виконай **literal-команди без shell expansion** (без command substitution, variable expansion чи backticks). Наприклад, якщо поточна гілка \`feature/x\`:
|
|
137
139
|
|
|
138
140
|
\`\`\`bash
|
|
139
141
|
npx @7n/mt worktree create "feature/x-${suffix}" "n-${suffix}: worktree-only skill"
|
|
@@ -142,10 +144,10 @@ cd ".worktrees/feature-x-${suffix}"
|
|
|
142
144
|
|
|
143
145
|
Тобто branch-argument лишає slash як у git-гілці, а шлях для \`cd\` бере sanitized форму: slash → \`-\`.
|
|
144
146
|
|
|
145
|
-
**Крок 0.1 — bootstrap
|
|
147
|
+
**Крок 0.1 — bootstrap (якщо в дереві ще нема \`node_modules\`).** Свіжостворений worktree (Крок 0) точно без \`node_modules\`; вже ізольований harness-worktree може мати їх або ні — постав локально, тоді \`npx @7n/rules <cmd>\` бере локальну копію без походу в реєстр:
|
|
146
148
|
|
|
147
149
|
\`\`\`bash
|
|
148
|
-
bun install
|
|
150
|
+
test -d node_modules || bun install
|
|
149
151
|
\`\`\``
|
|
150
152
|
}
|
|
151
153
|
|