@k0t0vich/meta-agents-template 0.1.8 → 0.1.9
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 +9 -0
- package/README.md +5 -5
- package/package.json +1 -1
- package/src/cli.mjs +20 -6
- package/src/init.mjs +41 -3
- package/template/.meta-agents/scripts/task-branch-router.mjs +16 -5
- package/template/README.md +2 -2
- package/template/agents.md +2 -2
- package/template/tracker-command-template.md +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this package are documented in this file.
|
|
4
4
|
|
|
5
|
+
## 0.1.9 - 2026-03-20
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- `meta-agents init` now creates `AGENTS.md` by default for new projects, so agent runtimes that expect uppercase bootstrap filename can load rules reliably.
|
|
9
|
+
- Existing projects with pre-created `agents.md` remain non-destructive: init still updates only managed links block instead of replacing full file.
|
|
10
|
+
- Bootstrap block now includes explicit required instruction to read canonical rules from npm-linked template files.
|
|
11
|
+
- Branch context protection for `meta:task-start` now checks `AGENTS.md` with fallback to `agents.md`.
|
|
12
|
+
- Local smoke now validates `AGENTS.md` presence and required bootstrap instruction in empty-folder install scenario.
|
|
13
|
+
|
|
5
14
|
## 0.1.8 - 2026-03-20
|
|
6
15
|
|
|
7
16
|
### Changed
|
package/README.md
CHANGED
|
@@ -31,7 +31,7 @@ npx -y @k0t0vich/meta-agents-template init . --yes --tracker github
|
|
|
31
31
|
Важно:
|
|
32
32
|
- если пользователь дал URL `https://www.npmjs.com/package/@k0t0vich/meta-agents-template`, извлекай имя пакета `@k0t0vich/meta-agents-template` и ставь именно его;
|
|
33
33
|
- не запускай `npm i -D ...` в папке без `package.json`, иначе npm может установить пакет в родительский проект.
|
|
34
|
-
- `meta-agents init` по умолчанию работает non-destructive: в корне создаёт/обновляет только project-specific конфиги `.meta-agents/config/project-context.yaml` (имя проекта + tracker) и `.meta-agents/config/trackers.yaml`, аккуратно merge-ит `meta:*` scripts в `package.json` и
|
|
34
|
+
- `meta-agents init` по умолчанию работает non-destructive: в корне создаёт/обновляет только project-specific конфиги `.meta-agents/config/project-context.yaml` (имя проекта + tracker) и `.meta-agents/config/trackers.yaml`, аккуратно merge-ит `meta:*` scripts в `package.json` и добавляет/обновляет bootstrap-блок в `AGENTS.md` (или в уже существующий `agents.md`) вместо полной перезаписи.
|
|
35
35
|
- `--force` нужен только если надо перезаписать уже существующие project-specific конфиги (`project-context.yaml`, `trackers.yaml`) и мигрировать legacy `meta:*` scripts.
|
|
36
36
|
|
|
37
37
|
## One-line для агентного запуска
|
|
@@ -48,7 +48,7 @@ mkdir -p my-project && cd my-project && npm init -y && npm i -D @k0t0vich/meta-a
|
|
|
48
48
|
Проверка, что шаблон и правила действительно развернуты:
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
|
-
test -f agents.md && test -f .meta-agents/config/project-context.yaml && test -f node_modules/@k0t0vich/meta-agents-template/template/agents.md && echo "meta-agents template ready"
|
|
51
|
+
(test -f AGENTS.md || test -f agents.md) && test -f .meta-agents/config/project-context.yaml && test -f node_modules/@k0t0vich/meta-agents-template/template/agents.md && echo "meta-agents template ready"
|
|
52
52
|
```
|
|
53
53
|
|
|
54
54
|
## Диалог при `init`
|
|
@@ -64,7 +64,7 @@ test -f agents.md && test -f .meta-agents/config/project-context.yaml && test -f
|
|
|
64
64
|
my-project/
|
|
65
65
|
package.json
|
|
66
66
|
package-lock.json
|
|
67
|
-
agents.md
|
|
67
|
+
AGENTS.md # или agents.md, если файл уже существовал
|
|
68
68
|
.meta-agents/
|
|
69
69
|
config/
|
|
70
70
|
project-context.yaml
|
|
@@ -76,7 +76,7 @@ my-project/
|
|
|
76
76
|
template/.meta-agents/scripts/*.mjs
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
`
|
|
79
|
+
Файл `AGENTS.md` (или уже существующий `agents.md`) не перезаписывается целиком: `init` добавляет/обновляет в нём только managed bootstrap-блок со ссылками на canonical rules из npm-пакета.
|
|
80
80
|
|
|
81
81
|
## Канонические команды
|
|
82
82
|
0. `VERIFY_GOVERNANCE_GATE`
|
|
@@ -153,7 +153,7 @@ npm run meta:status
|
|
|
153
153
|
`meta:ops` принудительно проверяет tracker provider lock и блокирует выполнение, если переданный `--tracker` не совпадает с зафиксированным provider проекта.
|
|
154
154
|
`meta:branch` валидирует ветку по Git Flow Lite (`main`, `develop`, `feature/*`, `release/*`, `hotfix/*`).
|
|
155
155
|
`meta:task-start` делает branch-routing preflight: сравнивает задачу с текущей веткой, показывает dirty/ahead блокеры и готовит маршрут (`stay_on_current_branch` или `create_new_branch`).
|
|
156
|
-
`meta:task-start` также делает context-protection check для `agents.md` между текущей и базовой веткой и требует явного подтверждения при diff.
|
|
156
|
+
`meta:task-start` также делает context-protection check для `AGENTS.md` (fallback: `agents.md`) между текущей и базовой веткой и требует явного подтверждения при diff.
|
|
157
157
|
Именование branch task ref: использовать GitHub issue ref в формате `issue-<number>`.
|
|
158
158
|
`meta:mr-review` формирует сводный pre-merge отчёт по MR/PR, `meta:mr-review-approve` фиксирует финальный PASS после подтверждения пользователя.
|
|
159
159
|
`meta:status` отдаёт единый статус-срез: trackers used, current sprint, current task, current branch context, git uncommitted и summary.
|
package/package.json
CHANGED
package/src/cli.mjs
CHANGED
|
@@ -279,12 +279,26 @@ export async function main(argv) {
|
|
|
279
279
|
if (result.config.skipped.length > 0) {
|
|
280
280
|
console.log(`Config files kept: ${result.config.skipped.join(", ")}`);
|
|
281
281
|
}
|
|
282
|
-
if (result.agents.created) {
|
|
283
|
-
console.log(
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
282
|
+
if (result.agents.created.length > 0) {
|
|
283
|
+
console.log(
|
|
284
|
+
`Agent bootstrap created: ${result.agents.created
|
|
285
|
+
.map((item) => path.basename(item))
|
|
286
|
+
.join(", ")}`,
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
if (result.agents.updated.length > 0) {
|
|
290
|
+
console.log(
|
|
291
|
+
`Agent bootstrap updated: ${result.agents.updated
|
|
292
|
+
.map((item) => path.basename(item))
|
|
293
|
+
.join(", ")}`,
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
if (result.agents.created.length === 0 && result.agents.updated.length === 0) {
|
|
297
|
+
console.log(
|
|
298
|
+
`Agent bootstrap already up to date: ${result.agents.unchanged
|
|
299
|
+
.map((item) => path.basename(item))
|
|
300
|
+
.join(", ")}`,
|
|
301
|
+
);
|
|
288
302
|
}
|
|
289
303
|
if (result.git.actions.length > 0) {
|
|
290
304
|
console.log(`Git actions: ${result.git.actions.join("; ")}`);
|
package/src/init.mjs
CHANGED
|
@@ -13,6 +13,7 @@ const TEXT_EXTENSIONS = new Set([
|
|
|
13
13
|
".js",
|
|
14
14
|
]);
|
|
15
15
|
const ROOT_CONFIG_FILES = ["project-context.yaml", "trackers.yaml"];
|
|
16
|
+
const DEFAULT_AGENTS_FILENAME = "AGENTS.md";
|
|
16
17
|
|
|
17
18
|
const AGENTS_LINK_BLOCK_START = "<!-- meta-agents-template:links:start -->";
|
|
18
19
|
const AGENTS_LINK_BLOCK_END = "<!-- meta-agents-template:links:end -->";
|
|
@@ -219,6 +220,8 @@ function buildAgentsLinkBlock(packageName) {
|
|
|
219
220
|
const lines = [
|
|
220
221
|
AGENTS_LINK_BLOCK_START,
|
|
221
222
|
"## Meta Agents Template (npm-linked)",
|
|
223
|
+
"ОБЯЗАТЕЛЬНО: перед выполнением любой команды сначала прочитай canonical rules по ссылкам ниже.",
|
|
224
|
+
"При конфликте локального текста и шаблона приоритет у canonical files из node_modules.",
|
|
222
225
|
"Базовые правила шаблона:",
|
|
223
226
|
`- [Template agents.md](${packageRoot}/template/agents.md)`,
|
|
224
227
|
`- [Template tracker-command-template.md](${packageRoot}/template/tracker-command-template.md)`,
|
|
@@ -230,12 +233,22 @@ function buildAgentsLinkBlock(packageName) {
|
|
|
230
233
|
return `${lines.join("\n")}\n`;
|
|
231
234
|
}
|
|
232
235
|
|
|
233
|
-
|
|
234
|
-
|
|
236
|
+
function buildAgentsBootstrapContent(fileName, block) {
|
|
237
|
+
return [
|
|
238
|
+
`# ${fileName}`,
|
|
239
|
+
"",
|
|
240
|
+
"Bootstrap file for agent runtime.",
|
|
241
|
+
"Before any task, read canonical rules from the npm-linked files in the block below.",
|
|
242
|
+
"",
|
|
243
|
+
block,
|
|
244
|
+
].join("\n");
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
async function upsertAgentsLinksInFile(agentsPath, packageName) {
|
|
235
248
|
const block = buildAgentsLinkBlock(packageName);
|
|
236
249
|
|
|
237
250
|
if (!(await pathExists(agentsPath))) {
|
|
238
|
-
const content =
|
|
251
|
+
const content = buildAgentsBootstrapContent(path.basename(agentsPath), block);
|
|
239
252
|
await fs.writeFile(agentsPath, content, "utf8");
|
|
240
253
|
return { created: true, updated: false, path: agentsPath };
|
|
241
254
|
}
|
|
@@ -265,6 +278,31 @@ async function upsertAgentsLinks(targetDir, packageName) {
|
|
|
265
278
|
return { created: false, updated, path: agentsPath };
|
|
266
279
|
}
|
|
267
280
|
|
|
281
|
+
async function detectAgentsFilePath(targetDir) {
|
|
282
|
+
try {
|
|
283
|
+
const entries = await fs.readdir(targetDir, { withFileTypes: true });
|
|
284
|
+
const match = entries.find(
|
|
285
|
+
(entry) => entry.isFile() && entry.name.toLowerCase() === "agents.md",
|
|
286
|
+
);
|
|
287
|
+
if (match) {
|
|
288
|
+
return path.join(targetDir, match.name);
|
|
289
|
+
}
|
|
290
|
+
} catch {
|
|
291
|
+
// target directory may not exist yet
|
|
292
|
+
}
|
|
293
|
+
return path.join(targetDir, DEFAULT_AGENTS_FILENAME);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
async function upsertAgentsLinks(targetDir, packageName) {
|
|
297
|
+
const agentsPath = await detectAgentsFilePath(targetDir);
|
|
298
|
+
const result = await upsertAgentsLinksInFile(agentsPath, packageName);
|
|
299
|
+
return {
|
|
300
|
+
created: result.created ? [result.path] : [],
|
|
301
|
+
updated: result.updated ? [result.path] : [],
|
|
302
|
+
unchanged: !result.created && !result.updated ? [result.path] : [],
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
|
|
268
306
|
async function syncConfigFiles({ templateRoot, targetDir, values, force }) {
|
|
269
307
|
const sourceConfigRoot = path.join(templateRoot, ".meta-agents", "config");
|
|
270
308
|
const targetConfigRoot = path.join(targetDir, ".meta-agents", "config");
|
|
@@ -15,6 +15,7 @@ const TASK_KIND_MAP = {
|
|
|
15
15
|
release: "release",
|
|
16
16
|
hotfix: "hotfix",
|
|
17
17
|
};
|
|
18
|
+
const GOVERNANCE_CONTEXT_FILES = ["AGENTS.md", "agents.md"];
|
|
18
19
|
|
|
19
20
|
function git(args, allowFailure = false) {
|
|
20
21
|
try {
|
|
@@ -266,6 +267,16 @@ function readFileAtRef(ref, filePath) {
|
|
|
266
267
|
return git(["show", `${ref}:${filePath}`], true);
|
|
267
268
|
}
|
|
268
269
|
|
|
270
|
+
function readGovernanceContextAtRef(ref) {
|
|
271
|
+
for (const filePath of GOVERNANCE_CONTEXT_FILES) {
|
|
272
|
+
const content = readFileAtRef(ref, filePath);
|
|
273
|
+
if (content) {
|
|
274
|
+
return { filePath, content };
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
|
|
269
280
|
function getContextWarnings(baseBranch) {
|
|
270
281
|
const warnings = [];
|
|
271
282
|
if (!baseBranch) {
|
|
@@ -280,19 +291,19 @@ function getContextWarnings(baseBranch) {
|
|
|
280
291
|
return warnings;
|
|
281
292
|
}
|
|
282
293
|
|
|
283
|
-
const currentAgents =
|
|
284
|
-
const baseAgents =
|
|
294
|
+
const currentAgents = readGovernanceContextAtRef("HEAD");
|
|
295
|
+
const baseAgents = readGovernanceContextAtRef(baseBranch);
|
|
285
296
|
|
|
286
297
|
if (!currentAgents || !baseAgents) {
|
|
287
298
|
warnings.push(
|
|
288
|
-
"Cannot compare governance context file 'agents.md' between current and base branch (missing in one of refs).",
|
|
299
|
+
"Cannot compare governance context file 'AGENTS.md/agents.md' between current and base branch (missing in one of refs).",
|
|
289
300
|
);
|
|
290
301
|
return warnings;
|
|
291
302
|
}
|
|
292
303
|
|
|
293
|
-
if (currentAgents !== baseAgents) {
|
|
304
|
+
if (currentAgents.content !== baseAgents.content) {
|
|
294
305
|
warnings.push(
|
|
295
|
-
`Governance context differs: '
|
|
306
|
+
`Governance context differs: '${currentAgents.filePath}' in current branch is not equal to '${baseBranch}:${baseAgents.filePath}'. Confirm switch before apply.`,
|
|
296
307
|
);
|
|
297
308
|
}
|
|
298
309
|
|
package/template/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Проект инициализирован шаблоном `meta-agents-template`.
|
|
4
4
|
|
|
5
5
|
## Что уже подключено
|
|
6
|
-
- `agents.md
|
|
6
|
+
- `AGENTS.md` (или существующий `agents.md`): локальный bootstrap-файл с ссылками на canonical правила в npm-пакете;
|
|
7
7
|
- `.meta-agents/config/project-context.yaml`: project name + выбранный tracker provider;
|
|
8
8
|
- `.meta-agents/config/trackers.yaml`: lock tracker provider и доступные providers;
|
|
9
9
|
- `meta:*` npm scripts, которые запускают canonical tooling из `node_modules/@k0t0vich/meta-agents-template/template/.meta-agents/scripts/*`.
|
|
@@ -64,7 +64,7 @@ npm run meta:status
|
|
|
64
64
|
Если передать `--tracker`, он обязан совпадать с зафиксированным provider проекта, иначе команда блокируется.
|
|
65
65
|
`meta:branch` валидирует ветку по Git Flow Lite (`main`, `develop`, `feature/*`, `release/*`, `hotfix/*`).
|
|
66
66
|
`meta:task-start` делает branch-routing preflight: сравнивает задачу с текущей веткой, показывает dirty/ahead блокеры и готовит маршрут (`stay_on_current_branch` или `create_new_branch`).
|
|
67
|
-
`meta:task-start` также делает context-protection check для `agents.md` между текущей и базовой веткой и требует явного подтверждения при diff.
|
|
67
|
+
`meta:task-start` также делает context-protection check для `AGENTS.md` (fallback: `agents.md`) между текущей и базовой веткой и требует явного подтверждения при diff.
|
|
68
68
|
Именование branch task ref: использовать GitHub issue ref в формате `issue-<number>`.
|
|
69
69
|
`meta:mr-review` формирует сводный pre-merge отчёт по MR/PR, `meta:mr-review-approve` фиксирует финальный PASS после подтверждения пользователя.
|
|
70
70
|
|
package/template/agents.md
CHANGED
|
@@ -172,7 +172,7 @@ Name: <agent role>
|
|
|
172
172
|
6. Согласовать с пользователем способ обработки (`commit/stash/discard/push`).
|
|
173
173
|
7. Переключиться на базовую ветку (`develop` или `main`) и обновить её.
|
|
174
174
|
8. Создать новую рабочую ветку по Git Flow Lite.
|
|
175
|
-
9. Перед переключением проверить консистентность `agents.md` между текущей и базовой веткой; при отличиях показать явное предупреждение и запросить подтверждение пользователя.
|
|
175
|
+
9. Перед переключением проверить консистентность `AGENTS.md` (fallback: `agents.md`) между текущей и базовой веткой; при отличиях показать явное предупреждение и запросить подтверждение пользователя.
|
|
176
176
|
|
|
177
177
|
Без этого preflight выполнение реализации запрещено.
|
|
178
178
|
|
|
@@ -201,7 +201,7 @@ Name: <agent role>
|
|
|
201
201
|
21. Для релиза обновлён публичный `CHANGELOG.md`.
|
|
202
202
|
22. Коммит следует формату `#issue-number <summary>` (issue ref в начале сообщения).
|
|
203
203
|
23. Для branch routing собран e2e evidence по двум сценариям: `same feature` и `different feature`.
|
|
204
|
-
24. Перед `--apply` подтверждена консистентность контекста `agents.md`
|
|
204
|
+
24. Перед `--apply` подтверждена консистентность контекста `AGENTS.md` (fallback: `agents.md`) или явно подтверждён осознанный switch при diff.
|
|
205
205
|
|
|
206
206
|
Если хотя бы один критерий не выполнен, задача не принимается.
|
|
207
207
|
|
|
@@ -67,7 +67,7 @@ result PASS
|
|
|
67
67
|
- branch naming policy: использовать только GitHub issue ref в формате `issue-<number>`;
|
|
68
68
|
- если задача атомарная и относится к текущей feature-ветке, допускается выполнение в текущей ветке после явного подтверждения пользователя;
|
|
69
69
|
- если задача не относится к текущей ветке, требуется: проверить dirty/ahead, согласовать действие с пользователем, перейти на `develop` (или `main` для hotfix), обновить и создать новую ветку;
|
|
70
|
-
- перед `--apply` обязателен контекстный check: сравнить `agents.md` текущей и базовой ветки, при diff запросить явное подтверждение пользователя;
|
|
70
|
+
- перед `--apply` обязателен контекстный check: сравнить `AGENTS.md` (fallback: `agents.md`) текущей и базовой ветки, при diff запросить явное подтверждение пользователя;
|
|
71
71
|
- сообщение коммита обязательно следует формату `#issue-number <summary>` (issue ref в начале).
|
|
72
72
|
|
|
73
73
|
Для GitHub трекера статус issue задаётся label-ом (одновременно только один статус из набора):
|
|
@@ -187,7 +187,7 @@ tracker __DEFAULT_TRACKER__,
|
|
|
187
187
|
task "#12",
|
|
188
188
|
task kind "atomic",
|
|
189
189
|
command "npm run meta:task-start -- --task #12 --slug api-redirect",
|
|
190
|
-
user dialogue "confirm branch context + dirty/ahead handling +
|
|
190
|
+
user dialogue "confirm branch context + dirty/ahead handling + AGENTS.md context warning + switch decision"
|
|
191
191
|
```
|
|
192
192
|
|
|
193
193
|
### SET_STATUS -> REVIEW (обязателен перед review gate)
|