@rt-tools/agent-kit 0.23.0 → 0.24.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/README.md +8 -2
- package/assets/checks/board.github.mjs +1 -1
- package/assets/checks/check-board.github.mjs +14 -0
- package/assets/checks/check-doc-paths.mjs +24 -5
- package/assets/checks/check-file-size.mjs +8 -2
- package/assets/checks/check-prose-style.mjs +10 -1
- package/assets/defaults/gate-map.sh +13 -0
- package/assets/defaults/project.sh +10 -0
- package/assets/defaults/shell.sh +18 -3
- package/assets/hooks/browser-guard-device-id.sh +42 -12
- package/assets/hooks/dispatch.sh +40 -9
- package/assets/hooks/docs-guard.sh +10 -0
- package/assets/hooks/exam-guard.sh +66 -16
- package/assets/hooks/git-guard-delivery-draft.sh +78 -0
- package/assets/hooks/git-guard-delivery.sh +49 -111
- package/assets/hooks/git-guard-main.sh +39 -4
- package/assets/hooks/git-guard-push-tests.sh +49 -3
- package/assets/hooks/hook-input.sh +17 -6
- package/assets/hooks/rule-source-guard.sh +11 -0
- package/assets/hooks/stand-login-guard.sh +101 -0
- package/assets/hooks/write-targets.sh +37 -4
- package/assets/laws/verifiability.md +12 -2
- package/assets/laws/work-conduct.md +59 -65
- package/assets/patterns/browser-verification-measure.md +41 -1
- package/assets/patterns/browser-verification-stand.md +56 -15
- package/assets/patterns/doc-style-human.md +75 -0
- package/assets/patterns/git-workflow-commit.azure.md +12 -0
- package/assets/patterns/git-workflow-commit.github.md +16 -3
- package/assets/patterns/git-workflow-commit.gitlab.md +12 -0
- package/assets/patterns/git-workflow-merge.md +8 -0
- package/assets/patterns/task-flow-start.md +1 -1
- package/assets/patterns/testing-e2e.md +18 -8
- package/assets/pitfalls/task-flow.md +40 -40
- package/assets/rules/browser-verification.md +29 -3
- package/assets/rules/doc-style.md +36 -0
- package/assets/rules/git-workflow.github.md +20 -23
- package/assets/rules/reuse-first.md +8 -2
- package/assets/rules/styling-bem.md +8 -1
- package/assets/rules/task-flow.md +73 -73
- package/assets/rules/testing.md +21 -0
- package/assets/skills/agent-kit.md +60 -70
- package/lib/commands.d.ts.map +1 -1
- package/lib/commands.js +63 -2
- package/lib/commands.js.map +1 -1
- package/lib/enroll.d.ts.map +1 -1
- package/lib/enroll.js +1 -1
- package/lib/enroll.js.map +1 -1
- package/lib/observations.d.ts +10 -1
- package/lib/observations.d.ts.map +1 -1
- package/lib/observations.js +1 -0
- package/lib/observations.js.map +1 -1
- package/lib/override-marks.d.ts +24 -0
- package/lib/override-marks.d.ts.map +1 -0
- package/lib/override-marks.js +98 -0
- package/lib/override-marks.js.map +1 -0
- package/lib/shipment.d.ts.map +1 -1
- package/lib/shipment.js +1 -1
- package/lib/shipment.js.map +1 -1
- package/package.json +1 -1
- package/rt-tools-agent-kit-0.24.0.tgz +0 -0
- package/rt-tools-agent-kit-0.23.0.tgz +0 -0
package/assets/rules/testing.md
CHANGED
|
@@ -120,6 +120,14 @@ flowchart TD
|
|
|
120
120
|
каталог, любая своя ошибка — гард выходит нулём и пропускает: сломанная проверка не имеет права
|
|
121
121
|
заклинить работу. Объявляется это строкой `FAIL-OPEN` в шапке самого гарда, рядом с
|
|
122
122
|
перечислением случаев, и туда же дописывается новый случай, когда он находится.
|
|
123
|
+
- **Гард, не узнавший вызов, молчит так же, как исправный.** Нулевой выход бывает двух родов: гард
|
|
124
|
+
сломался и отпустил намеренно — это объявлено в его шапке, — либо он не признал в команде своего
|
|
125
|
+
дела и до проверки не дошёл вовсе. Снаружи они неотличимы, а второй не объявлен нигде и не
|
|
126
|
+
оставляет следа. Отсюда два следствия. Признак вызова обязан ошибаться в сторону лишнего
|
|
127
|
+
срабатывания: сработавший на лишнем виден сразу и правится, не узнавший — не виден никогда. И
|
|
128
|
+
принятый в дереве способ звать команду — полным путём, через обёртку, с подстановкой переменных —
|
|
129
|
+
входит в признак наравне с голым именем: обход, которым команду зовут каждый день, ровно там гард
|
|
130
|
+
и слепнет.
|
|
123
131
|
- **Список известного у проверки именной и объясняет себя сам.** Первым полем перечня стоит имя
|
|
124
132
|
проверки и слово о том, что перечисленное отказом не считается. Дальше либо два ключа — принятое
|
|
125
133
|
остаётся навсегда, долг накоплен к заведению проверки и только сокращается, — либо столько
|
|
@@ -186,6 +194,19 @@ flowchart TD
|
|
|
186
194
|
по-прежнему, и плывущее значение внутри него двигает соседей мимо маски. Там, где размер узла
|
|
187
195
|
считается по содержимому — ячейка таблицы, надпись, растягивающая кнопку, — плывущее лечится в
|
|
188
196
|
данных стенда постоянным значением, и тогда маска не нужна вовсе.
|
|
197
|
+
- **Постоянным делается не только время, но и всё, что приложение из него вывело.** Приложение
|
|
198
|
+
считает от своих часов и производное — ключ месяца, срок, признак свежести, — и считает его в
|
|
199
|
+
минуту записи. Правка времён, идущая после записи, производного не двигает: оно посчитано раньше
|
|
200
|
+
и лежит в соседней колонке. Расхождения при этом не наступает месяцами, а потом набор краснеет в
|
|
201
|
+
день, когда в дерево не внесли ни строки. Признак у промаха свой и виден сравнением двух колонок:
|
|
202
|
+
производное перестало сходиться с тем, из чего его обязаны были вывести.
|
|
203
|
+
- **Засев проверяет себя сам, а не полагается на кадр.** Кадр говорит «стало другим» и молчит о
|
|
204
|
+
том, почему; отказ засева называет причину словами и приходит до того, как снят хоть один кадр.
|
|
205
|
+
Признак берётся верный в любой день прогона: данные стенда — прошлое, поэтому значение времени,
|
|
206
|
+
попавшее на день прогона или позже, посчитано часами машины, а засевом не закреплено. Нарочно
|
|
207
|
+
будущее отделяется границей и называется отдельно. Судятся при этом временные колонки всех
|
|
208
|
+
таблиц, которые читают экраны, а не только показанные сегодня: столбец выводят на экран одной
|
|
209
|
+
строкой разметки, и вспомнить при этом про засев некому.
|
|
189
210
|
|
|
190
211
|
## Чего из закона здесь нет
|
|
191
212
|
|
|
@@ -53,24 +53,21 @@ description: Переносимый слой правил агента — за
|
|
|
53
53
|
**Подъём версии пакета и раскладка едут одним изменением.** Сверка раскладки стоит в гейте
|
|
54
54
|
пуша: редакция, поднятая без раскладки, красит главную ветку и запирает дерево целиком.
|
|
55
55
|
|
|
56
|
-
**Объявление хука раскладка кладёт вместе с самим хуком.**
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
деревом не возвращается, а настройку, которую не разобрать как JSON, пакет не трогает вовсе —
|
|
62
|
-
там печатается готовый кусок и запись идёт рукой, как прежде.
|
|
56
|
+
**Объявление хука раскладка кладёт вместе с самим хуком.** Хук вызывается по записи в настройке
|
|
57
|
+
агента, и разложенный без неё снаружи неотличим от работающего. Раскладка дописывает запись на
|
|
58
|
+
каждое событие, которого в настройке нет, и сообщает об этом. Правка только добавляет: записи не
|
|
59
|
+
переписываются и не снимаются, снятое деревом не возвращается, а настройку, которую не разобрать
|
|
60
|
+
как JSON, пакет не трогает — печатает готовый кусок для записи рукой.
|
|
63
61
|
|
|
64
62
|
**Держит это гард места правки, а не память.** Правку файла с шапкой раскладки он отбивает в
|
|
65
63
|
минуту правки и называет адрес: источник, если дерево его держит, иначе надстройку. Правит копию
|
|
66
|
-
не только рука: форматтер
|
|
67
|
-
|
|
68
|
-
раскладка кладёт заново, и так эту поломку и чинят.
|
|
64
|
+
не только рука: форматтер дерева переписывает разложенный файл по-своему, и раскладка читает это
|
|
65
|
+
ровно как правку руками. Снятие копии гард пропускает — снятый файл раскладка кладёт заново.
|
|
69
66
|
|
|
70
67
|
**Надстройка правится по разделу, а не кладётся целиком.** Разделы в неё дописывают разные ветки
|
|
71
|
-
и разные заходы, и положенная целиком она уносит все, которых эта правка не
|
|
72
|
-
|
|
73
|
-
|
|
68
|
+
и разные заходы, и положенная целиком она уносит все, которых эта правка не касалась. Держит это
|
|
69
|
+
второй гард — он отбивает запись поверх непустой надстройки и называет размер того, что затрут.
|
|
70
|
+
Дописывание в конец и правка по месту проходят.
|
|
74
71
|
|
|
75
72
|
## Команды
|
|
76
73
|
|
|
@@ -85,8 +82,7 @@ npx agent-kit adopt [файлы] # отдать пакету свой файл,
|
|
|
85
82
|
```
|
|
86
83
|
|
|
87
84
|
Отдача откладывает прежнее содержимое рядом, с пометкой `.before-rt-kit`, и освобождает путь под
|
|
88
|
-
раскладку; без имён отдаются все чужие файлы разом.
|
|
89
|
-
находят по тексту отказа раскладки — то есть в ту минуту, когда работа уже встала.
|
|
85
|
+
раскладку; без имён отдаются все чужие файлы разом.
|
|
90
86
|
|
|
91
87
|
Часть команд слоя исполняет агент, а не программа: `/feedback` кладёт слово о правилах блоком в
|
|
92
88
|
файл предложений, `/skill-curator` разбирает закрытую задачу, `/next-session` закрывает заход.
|
|
@@ -108,11 +104,10 @@ npx agent-kit adopt [файлы] # отдать пакету свой файл,
|
|
|
108
104
|
cp -r node_modules/@rt-tools/agent-kit/assets /tmp/agent-kit-assets-<прежняя версия>
|
|
109
105
|
```
|
|
110
106
|
|
|
111
|
-
2. **Установка и раскладка.** Обычным порядком. Раскладка кладёт ту редакцию, которая
|
|
112
|
-
а не ту, что объявило дерево:
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
зависимости и повторить вызов.
|
|
107
|
+
2. **Установка и раскладка.** Обычным порядком. Раскладка кладёт ту редакцию, которая
|
|
108
|
+
**установлена**, а не ту, что объявило дерево: установленная остаётся от соседней ветки и
|
|
109
|
+
ложится целиком, молча, с тем же успешным выходом. Расхождение точного номера раскладка
|
|
110
|
+
отбивает сама; починка — поставить зависимости и повторить вызов.
|
|
116
111
|
3. **Сверка замещённых разделов по снимку.** Какие разделы замещены, называет `doctor` — строкой
|
|
117
112
|
«замещено надстройками разделов» и перечнем «ресурс · заголовок». Каждый из них читается в
|
|
118
113
|
снимке и в новой редакции: что пакет дописал, дописывается в надстройку руками.
|
|
@@ -123,8 +118,7 @@ npx agent-kit adopt [файлы] # отдать пакету свой файл,
|
|
|
123
118
|
этим раздел замещён. Готовая пара команд — в холодной части рядом.
|
|
124
119
|
|
|
125
120
|
Дальше решение обычное: раздел, ради которого надстройка заводилась, остаётся замещённым, а
|
|
126
|
-
раздел, чья причина ушла с исправленной редакцией,
|
|
127
|
-
предложения.
|
|
121
|
+
раздел, чья причина ушла с исправленной редакцией, снимается.
|
|
128
122
|
|
|
129
123
|
## Что пакет везёт, а что остаётся дереву
|
|
130
124
|
|
|
@@ -164,18 +158,16 @@ npx agent-kit adopt [файлы] # отдать пакету свой файл,
|
|
|
164
158
|
и не загружено ни разу**: правило, которого никто не открыл, ничем себя не выдаёт.
|
|
165
159
|
|
|
166
160
|
**Цена** — `agent-kit cost`. Сводка говорит, чем пользовались; цена — сколько это стоило: вес
|
|
167
|
-
входа в работу, вес одного правила и вес всего слоя. Считается не файл, а то, что заход
|
|
168
|
-
|
|
169
|
-
той же командой.
|
|
161
|
+
входа в работу, вес одного правила и вес всего слоя. Считается не файл, а то, что заход получает.
|
|
162
|
+
Число сравнимо только со снятым той же командой.
|
|
170
163
|
|
|
171
164
|
**Предложения** приходят двумя путями: разбор закрытой задачи — командой `/skill-curator` —
|
|
172
165
|
приносит их пачкой, а слово, сказанное посреди работы, кладёт командой `/feedback` сам агент. Оба
|
|
173
166
|
пишут в один файл дня и в одной форме; в сеть не ходит ни один — увозит их отправка.
|
|
174
167
|
|
|
175
168
|
Каждая запись несёт четыре строки: **место** — куда правка встаёт в ресурсе, **повод** — что
|
|
176
|
-
пошло не так без неё, **ближайшее** — точная цитата
|
|
177
|
-
|
|
178
|
-
снимаются, когда правка приедет редакцией пакета.
|
|
169
|
+
пошло не так без неё, **ближайшее** — точная цитата строки ресурса, к которой это ближе всего, и
|
|
170
|
+
**чем закрывается** — какие надстройки дерева снимаются, когда правка приедет редакцией пакета.
|
|
179
171
|
|
|
180
172
|
Третья строка — единственная, которую проверяет машина: цитата ищется в ресурсе, и ненайденная
|
|
181
173
|
отбивает блок. Ближайшего нет вовсе — так и пишется: «нет». Отбитый блок остаётся лежать с
|
|
@@ -185,46 +177,51 @@ npx agent-kit adopt [файлы] # отдать пакету свой файл,
|
|
|
185
177
|
без неё она замещает уже исправленный раздел навсегда. Снимать нечего — так и пишется; пустой
|
|
186
178
|
четвёртая строка не бывает.
|
|
187
179
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
180
|
+
Та же связь ставится и на саму надстройку — комментарием разметки в её разделе:
|
|
181
|
+
|
|
182
|
+
<!-- rt-proposed: rules/task-flow.md · «статья целиком, как в предложении» · 2026-09-03 -->
|
|
183
|
+
|
|
184
|
+
Записи предложений в день обновления никто не открывает: на них ничто не указывает. Пометка не
|
|
185
|
+
видна в собранном тексте, переживает слияние по заголовкам и читается машиной: раскладка
|
|
186
|
+
перечисляет разделы, чья статья в новой редакции уже есть. Снимает их человек — в раздел могли
|
|
187
|
+
дописать и другое. Раздел без пометки считается постоянным.
|
|
188
|
+
|
|
189
|
+
Каждому предложению ставится адрес: «пакет», «компаньон» или «дерево». Выгружаются они файлом в
|
|
190
|
+
`.claude/rt-kit/proposals/` (форма — шаблон `proposal.md`), а `agent-kit propose` увозит в приём
|
|
191
|
+
те, что адресованы пакету, вместе со сводкой и разборами происшествий. Адрес дерева в сводке или
|
|
192
|
+
в тексте предложения отбивает отправку целиком.
|
|
192
193
|
|
|
193
194
|
Приём — закрытая служба: сводка говорит о рабочих привычках команды, и в открытой очереди работ
|
|
194
195
|
это выложено всему свету. Адрес приёма объявляется ключом `intake` в конфиге дерева, токен —
|
|
195
196
|
ключом `token`, и лежит он вне дерева.
|
|
196
197
|
|
|
197
|
-
Оба значения приходят от владельца приёма, а не придумываются потребителем: адрес он называет, а
|
|
198
|
-
одноразовым кодом приглашения — код заводит дерево в приёме и кладёт токен в файл
|
|
199
|
-
|
|
198
|
+
Оба значения приходят от владельца приёма, а не придумываются потребителем: адрес он называет, а
|
|
199
|
+
токен выдаёт одноразовым кодом приглашения — код заводит дерево в приёме и кладёт токен в файл
|
|
200
|
+
ключа `token`. До приглашения отправка отказывает по устройству, а не по недонастройке.
|
|
200
201
|
|
|
201
202
|
**Признак дерева считает отправитель, а не человек.** Он выводится из адреса репозитория, и
|
|
202
|
-
запись в приёме заводится именно им: дерево, заведённое своим словом, приёмник не
|
|
203
|
-
|
|
204
|
-
единственный способ узнать признак до заведения записи.
|
|
203
|
+
запись в приёме заводится именно им: дерево, заведённое своим словом, приёмник не узнаёт. Что
|
|
204
|
+
уедет и под каким признаком, печатает прогон вхолостую.
|
|
205
205
|
|
|
206
|
-
**Отметка об отправке — след для человека, а не хранилище
|
|
207
|
-
|
|
208
|
-
груз в приёме уже лежал, а не что отправка не сработала.
|
|
206
|
+
**Отметка об отправке — след для человека, а не хранилище состояния.** Чистое дерево после
|
|
207
|
+
отправки значит, что весь груз в приёме уже лежал, а не что отправка не сработала.
|
|
209
208
|
|
|
210
209
|
Разбирают их там, где лежат правимые ресурсы и видно всех потребителей сразу, — а сюда
|
|
211
210
|
приезжает ответ приёма о том, сколько записей легло.
|
|
212
211
|
|
|
213
212
|
**Имя файла предложения в текстах дерева не называется.** Читателю чужого дерева оно не даёт
|
|
214
|
-
ничего, а
|
|
215
|
-
|
|
216
|
-
при этом называть можно — он в истории есть.
|
|
213
|
+
ничего, а ссылка на каталог с машины автора ведёт в пустоту и красит проверку путей. Текст
|
|
214
|
+
репозитория говорит, кому предложение отправлено и о чём оно; ресурс пакета называть можно.
|
|
217
215
|
|
|
218
216
|
Предложение работу не выправляет. Оно лежит текстом, читается глазами и в контекст сам собой не
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
требование и не считают дырку закрытой.
|
|
217
|
+
приходит. Закрытым оно считается, только войдя в ресурс пакета: до этого на него не ссылаются как
|
|
218
|
+
на действующее требование и не считают дырку закрытой.
|
|
222
219
|
|
|
223
220
|
**Слово владельца о предложении — «отправь», «заведи», «напиши пропозал» и любая другая форма
|
|
224
|
-
того же — исполняется отправкой в тот же ход.** Сухой прогон отправкой не
|
|
225
|
-
показывает, что
|
|
226
|
-
|
|
227
|
-
|
|
221
|
+
того же — исполняется отправкой в тот же ход.** Сухой прогон отправкой не считается: он
|
|
222
|
+
показывает, что было бы отправлено, и следа наружу не оставляет. Отметки, которые отправка
|
|
223
|
+
оставляет в дереве, ложатся вторым коммитом в ту же ветку. Это проверяет гард предложения на
|
|
224
|
+
завершении хода.
|
|
228
225
|
|
|
229
226
|
## Установка туда, где уже всё своё
|
|
230
227
|
|
|
@@ -276,23 +273,16 @@ npx agent-kit adopt [файлы] # отдать пакету свой файл,
|
|
|
276
273
|
целиком, до первой реплики, и оттого он выглядит обычным документом дерева; шапка у него есть,
|
|
277
274
|
но читается служебной строкой. Новое слово идёт в надстройку словаря, своим разделом.
|
|
278
275
|
|
|
279
|
-
- **Запись файла командой оболочки
|
|
280
|
-
пути из текста
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
исходников и снимок долга приезжают модулем настройки проверок. Второе такое же заводится без
|
|
289
|
-
сигнала: повтора не видит ни сверка раскладки — файл не разложен, — ни проверка повторов,
|
|
290
|
-
которая ищет совпадение текста. Признак один, и он читается: до того как в своей проверке
|
|
291
|
-
заводится разбор списка, чтение настройки или сравнение с накопленным, смотрят, что
|
|
292
|
-
экспортирует модуль настройки проверок.
|
|
276
|
+
- **Запись файла командой оболочки проверяется по всем путям, названным в её теле.** Гейт
|
|
277
|
+
вынимает пути из текста команды и читает тело документа целиком, если в команде есть имя
|
|
278
|
+
интерпретатора; строка импорта разложенного модуля тогда требует второе правило, а требуется
|
|
279
|
+
за раз одно — два отказа подряд, и каждый теряет написанное тело. Инструмент правки
|
|
280
|
+
проверяется одним своим путём; перенаправление оболочки — для того, что файлом дерева не станет.
|
|
281
|
+
- **Своё, стоящее рядом с разложенным, повторяет его механику молча.** Разбор списка известного,
|
|
282
|
+
корни исходников и снимок долга даёт модуль настройки проверок; второй такой же разбор в своей
|
|
283
|
+
проверке не видит ни сверка раскладки, ни проверка повторов. Перед тем как завести своё, смотрят,
|
|
284
|
+
что экспортирует модуль настройки проверок.
|
|
293
285
|
- **Правило, загруженное инструментом, бывает показано не целиком, и обрыв ничем не помечен.**
|
|
294
|
-
Длинный файл
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
в конец. Отсюда порядок: решение о порядке работы принимается после того, как показанные строки
|
|
298
|
-
сверены с длиной файла одной командой, а расходятся они — файл дочитывается чтением.
|
|
286
|
+
Длинный файл приходит в контекст обрезанным по строке, а обрыв приходится на хвост — туда, где
|
|
287
|
+
разделы надстройки дописаны в конец. Показанные строки сверяются с длиной файла одной командой;
|
|
288
|
+
расходятся — файл дочитывается чтением.
|
package/lib/commands.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../projects/agent-kit/src/lib/commands.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../projects/agent-kit/src/lib/commands.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAwB7C,MAAM,WAAW,iBAAiB;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,2FAA2F;AAC3F,MAAM,WAAW,YAAY;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACpC;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CAC1B;AA2DD,+DAA+D;AAC/D,eAAO,MAAM,WAAW,EAAE,MAAyB,CAAC;AA+apD;;;;GAIG;AACH,wBAAgB,IAAI,CAChB,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,SAAS,MAAM,EAAO,EAC5B,QAAQ,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM,EAC/C,SAAS,GAAE,MAAW,GACvB,iBAAiB,CAgCnB;AA0LD,wBAAgB,IAAI,CAAC,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,GAAG,iBAAiB,CA+DzE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,iBAAiB,CA+CpF;AAQD,0EAA0E;AAC1E,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8FAA8F;IAC9F,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CAC1B;AAoLD;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,aAAa,GAAG,iBAAiB,CA6DlF;AA0BD,wBAAgB,MAAM,CAAC,GAAG,EAAE,YAAY,GAAG,iBAAiB,CAkF3D;AAED;;;;;GAKG;AACH,wBAAgB,IAAI,CAAC,GAAG,EAAE,YAAY,GAAG,iBAAiB,CA2DzD"}
|
package/lib/commands.js
CHANGED
|
@@ -14,6 +14,7 @@ import { CONFIG_PATH, DEFAULT_LAYOUT, KINDS, OVERRIDES_DIR, PROFILE_FILE, readCo
|
|
|
14
14
|
import { hooksSection, SETTINGS_PATH } from './hooks-map.js';
|
|
15
15
|
import { DEFAULT_DAYS, KEEP_DAYS, OBSERVATIONS_DIR, readObservations, summarize, } from './observations.js';
|
|
16
16
|
import { isRefusal } from './plan.js';
|
|
17
|
+
import { staleOverrides } from './override-marks.js';
|
|
17
18
|
import { pushGateLines } from './push-gate.js';
|
|
18
19
|
import { laidOutSkills, treeSnapshot } from './snapshot.js';
|
|
19
20
|
import { mergedBody, pendingOf, planSync, runSync } from './sync.js';
|
|
@@ -186,6 +187,25 @@ const holes = (result) => [...result.missing].map(([asset, names]) => {
|
|
|
186
187
|
const written = names.map(holeOf).join(', ');
|
|
187
188
|
return ` ${asset}: нет значений для ${written}`;
|
|
188
189
|
});
|
|
190
|
+
/**
|
|
191
|
+
* Незаполненная дырка — состояние дерева, а не расхождение с пакетом.
|
|
192
|
+
*
|
|
193
|
+
* Расхождение говорит, что разложенное разошлось с редакцией; дырка без значения — что дерево
|
|
194
|
+
* ещё не описало своего: порты стенда, префикс компонентов, имя главной ветки. Один код возврата
|
|
195
|
+
* на оба состояния ставит дерево перед выбором между красным гейтом пуша и выдуманными числами в
|
|
196
|
+
* настройке, после чего подстановки теряют смысл.
|
|
197
|
+
*
|
|
198
|
+
* Раскладки это не касается: файл с дыркой на диск не кладётся, и `sync` отказывает по-прежнему —
|
|
199
|
+
* разложенное правило с `{{имя}}` посреди строки агент прочтёт как имя.
|
|
200
|
+
*/
|
|
201
|
+
const holeWarningLines = (result) => result.missing.size
|
|
202
|
+
? [
|
|
203
|
+
`дерево ещё не описало своего: ресурсов с незаполненными дырками ${result.missing.size}`,
|
|
204
|
+
...holes(result),
|
|
205
|
+
' — это описание дерева, а не расхождение с пакетом: значения идут ключом `vars` в `.claude/rt-kit.json`',
|
|
206
|
+
' — до них ресурс не раскладывается, и на диске его нет',
|
|
207
|
+
]
|
|
208
|
+
: [];
|
|
189
209
|
const unfilled = (result) => result.companions.filter(isUnfilled);
|
|
190
210
|
/**
|
|
191
211
|
* Строка про компаньон, которому нечего сказать.
|
|
@@ -387,6 +407,7 @@ const strayLines = (result) => result.strayOverrides.length
|
|
|
387
407
|
* всплывали бы только там, где и без них уже красно.
|
|
388
408
|
*/
|
|
389
409
|
const warnings = (result) => [
|
|
410
|
+
...holeWarningLines(result),
|
|
390
411
|
...brokenLines(result),
|
|
391
412
|
...idleLines(result),
|
|
392
413
|
...namedCutLines(result),
|
|
@@ -396,7 +417,6 @@ const warnings = (result) => [
|
|
|
396
417
|
...strayLines(result),
|
|
397
418
|
];
|
|
398
419
|
const describe = (result) => [
|
|
399
|
-
...holes(result),
|
|
400
420
|
...gapLines(result),
|
|
401
421
|
...unboundLines(result),
|
|
402
422
|
...driftedLines(result),
|
|
@@ -570,6 +590,24 @@ function refusalBeforeSync(env, config) {
|
|
|
570
590
|
}
|
|
571
591
|
return null;
|
|
572
592
|
}
|
|
593
|
+
/**
|
|
594
|
+
* Надстройки, чья статья в новой редакции уже есть.
|
|
595
|
+
*
|
|
596
|
+
* Пометка без читателя ничего не меняет: тот, кто ставит новую версию, видит число разложенных
|
|
597
|
+
* файлов и не видит, что часть надстроек стала лишней. Раскладка их называет, снимает человек:
|
|
598
|
+
* пометка держит одну статью, а в раздел могли дописать и другое.
|
|
599
|
+
*/
|
|
600
|
+
function staleOverrideLines(root, assetsDir) {
|
|
601
|
+
const stale = staleOverrides(root, assetsDir);
|
|
602
|
+
if (!stale.length) {
|
|
603
|
+
return [];
|
|
604
|
+
}
|
|
605
|
+
return [
|
|
606
|
+
`надстройки, чья статья в пакете уже есть: ${stale.length}`,
|
|
607
|
+
...stale.map((mark) => ` ${mark.file} · раздел «${mark.heading}» · отправлено ${mark.day}`),
|
|
608
|
+
' — раздел снимается, и дерево возвращается к пакетной формулировке',
|
|
609
|
+
];
|
|
610
|
+
}
|
|
573
611
|
/** Ответ `sync --check`: расхождения считаются, на диск не пишется ничего. */
|
|
574
612
|
function syncCheck(config, root, version, assetsDir) {
|
|
575
613
|
{
|
|
@@ -587,7 +625,10 @@ function syncCheck(config, root, version, assetsDir) {
|
|
|
587
625
|
// Гард, подписанный не на то, что объявляет, идёт в счёт по той же причине и с большим
|
|
588
626
|
// основанием: неподключённый хотя бы не притворяется — этот выглядит работающим, и ветка
|
|
589
627
|
// его тела, ради которой всё писалось, не исполняется ни разу.
|
|
590
|
-
|
|
628
|
+
// Незаполненная дырка в счёт не входит: она говорит о том, чего дерево ещё не описало о
|
|
629
|
+
// себе, а не о расхождении разложенного с редакцией. Она печатается предупреждением —
|
|
630
|
+
// и на сошедшемся дереве тоже.
|
|
631
|
+
const count = result.gaps.length + pending.length + empty.length + result.unbound.length + result.drifted.length;
|
|
591
632
|
if (!count) {
|
|
592
633
|
return { code: 0, lines: [`sync --check: разложенное сходится с пакетом v${version}`, ...warnings(result)] };
|
|
593
634
|
}
|
|
@@ -646,6 +687,7 @@ export function sync(env, check) {
|
|
|
646
687
|
...boundLines(result),
|
|
647
688
|
...(result.bound?.unreadable === false ? [] : unboundLines(result)),
|
|
648
689
|
...driftedLines(result),
|
|
690
|
+
...staleOverrideLines(root, assetsDir),
|
|
649
691
|
...debtLines(config, root, assetsDir),
|
|
650
692
|
...warnings(result),
|
|
651
693
|
],
|
|
@@ -787,6 +829,24 @@ function offFileLines(summary) {
|
|
|
787
829
|
}
|
|
788
830
|
return [` не на правке файла: ${summary.denialsOffFile} из ${total} — ${Math.round((summary.denialsOffFile / total) * 100)}%`];
|
|
789
831
|
}
|
|
832
|
+
/**
|
|
833
|
+
* Исходы гейта пуша. Молчит, когда гейт не отработал ни разу за отрезок.
|
|
834
|
+
*
|
|
835
|
+
* Вынесено из сводки отдельной функцией не ради имени: та собирает строки одним выражением, и
|
|
836
|
+
* каждая новая развилка в нём растит её сложность, за которой следит линтер.
|
|
837
|
+
*/
|
|
838
|
+
function pushGateOutcomeLines(summary) {
|
|
839
|
+
if (!summary.pushGate.length) {
|
|
840
|
+
return [];
|
|
841
|
+
}
|
|
842
|
+
const total = summary.pushGate.reduce((found, entry) => found + entry.count, 0);
|
|
843
|
+
return [
|
|
844
|
+
'',
|
|
845
|
+
`гейт пуша прогонял набор: ${total}`,
|
|
846
|
+
...countLines(summary.pushGate),
|
|
847
|
+
' — green зелёный набор, red красный, no-checks проверок в дереве не нашлось',
|
|
848
|
+
];
|
|
849
|
+
}
|
|
790
850
|
/** Сводка строками: загруженное, незагруженное, отбивки гейта и отказы гардов. */
|
|
791
851
|
function statsLines(summary, swept, days, version, laidOut) {
|
|
792
852
|
return [
|
|
@@ -834,6 +894,7 @@ function statsLines(summary, swept, days, version, laidOut) {
|
|
|
834
894
|
...countLines(summary.guards),
|
|
835
895
|
]
|
|
836
896
|
: []),
|
|
897
|
+
...pushGateOutcomeLines(summary),
|
|
837
898
|
...(summary.silentGuards.length
|
|
838
899
|
? [
|
|
839
900
|
'',
|