@bossmissing/agent-meta 0.1.0 → 0.2.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 +46 -2
- package/assets/skills/ironbank/ironbank-citations/SKILL.md +195 -0
- package/assets/skills/ironbank/ironbank-docs-research/SKILL.md +205 -0
- package/assets/skills/ironbank/ironbank-mcp-reference/SKILL.md +413 -0
- package/dist/cli.js +72 -1
- package/dist/commands/config.d.ts +5 -0
- package/dist/commands/config.js +50 -0
- package/dist/commands/doctor.d.ts +14 -0
- package/dist/commands/doctor.js +187 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +39 -1
- package/dist/commands/new-change.d.ts +12 -0
- package/dist/commands/new-change.js +125 -0
- package/dist/commands/new-domain.js +2 -0
- package/dist/commands/preflight.d.ts +14 -0
- package/dist/commands/preflight.js +103 -0
- package/dist/commands/review.d.ts +18 -0
- package/dist/commands/review.js +102 -0
- package/dist/core/checklist.d.ts +31 -0
- package/dist/core/checklist.js +43 -0
- package/dist/core/doc-scopes.d.ts +18 -0
- package/dist/core/doc-scopes.js +55 -0
- package/dist/core/frontmatter.d.ts +7 -0
- package/dist/core/frontmatter.js +35 -0
- package/dist/core/mcp-packs.d.ts +26 -0
- package/dist/core/mcp-packs.js +83 -0
- package/dist/generators/hook-generator.d.ts +14 -0
- package/dist/generators/hook-generator.js +55 -0
- package/dist/generators/mcp-generator.d.ts +9 -0
- package/dist/generators/mcp-generator.js +68 -0
- package/dist/templates/index.d.ts +7 -2
- package/dist/templates/index.js +125 -9
- package/dist/validators/domain-validator.js +30 -1
- package/dist/validators/openspec-validator.js +33 -4
- package/package.json +9 -15
package/dist/templates/index.js
CHANGED
|
@@ -25,19 +25,25 @@ const AGENTS_MD = `# AGENTS.md
|
|
|
25
25
|
|
|
26
26
|
- Read the nearest applicable \`AGENTS.md\` before modifying files.
|
|
27
27
|
- Read related domain documentation before changing business behavior.
|
|
28
|
+
- Do not modify third-party or vendored code (\`node_modules/\`, \`vendor/\`, \`third_party/\`, \`patches/\`). Wrap or extend it instead; if patching is unavoidable, record an ADR first.
|
|
29
|
+
- Do not use user-level (global) skills, plugins, or MCP tools unless the human explicitly asks for them. Prefer tools, scripts, and skills defined inside this repository.
|
|
30
|
+
- Never violate declared hard constraints (\`docs/domain/*/rules.md\` 硬限制 sections and \`docs/engineering/constraints.md\`). If a limit is not declared, ask the human instead of assuming it is negotiable.
|
|
31
|
+
- If you are guessing, fabricating, or cannot verify a conclusion, stop and ask the human.
|
|
28
32
|
- Do not duplicate domain rules in this file.
|
|
29
33
|
- Update OpenSpec specs when externally observable behavior changes.
|
|
30
34
|
- Add or update tests for behavior changes.
|
|
31
35
|
- Do not mix unrelated refactors into a feature change.
|
|
32
|
-
|
|
36
|
+
{{extra_rules}}
|
|
33
37
|
## High-Risk Areas
|
|
34
38
|
|
|
35
|
-
Before changing payment, order, commission, settlement, withdrawal, permissions, webhooks, inventory, or audit logging, read the applicable documentation under \`docs/domain/\`.
|
|
39
|
+
Before changing payment, order, commission, settlement, withdrawal, permissions, webhooks, inventory, or audit logging, read the applicable documentation under \`docs/domain/\`. Hard constraints for these areas are declared in each domain's \`rules.md\` under 硬限制(不可违反).
|
|
36
40
|
|
|
37
41
|
## Definition of Done
|
|
38
42
|
|
|
39
43
|
- Relevant tests pass.
|
|
40
44
|
- Type checking and lint pass where configured.
|
|
45
|
+
- A human has reviewed the change.
|
|
46
|
+
- All declared hard constraints hold.
|
|
41
47
|
- Behavior changes include documentation or specification updates where applicable.
|
|
42
48
|
- High-risk changes include rollback and failure-path consideration.
|
|
43
49
|
`;
|
|
@@ -98,14 +104,21 @@ applies_to: []
|
|
|
98
104
|
|
|
99
105
|
<!-- 仅列出该领域特有术语;通用术语应放到 docs/domain/glossary.md。 -->
|
|
100
106
|
|
|
101
|
-
##
|
|
107
|
+
## 硬限制(不可违反)
|
|
102
108
|
|
|
103
|
-
<!--
|
|
109
|
+
<!-- 安全、数据一致性、API 契约、性能预算、兼容性、合规。 -->
|
|
110
|
+
<!-- 没写在这里的限制,AI 会当成可协商的。 -->
|
|
104
111
|
|
|
105
112
|
-
|
|
106
113
|
-
|
|
107
114
|
-
|
|
108
115
|
|
|
116
|
+
## 软限制(可权衡)
|
|
117
|
+
|
|
118
|
+
<!-- 代码风格偏好、非关键路径的实现细节、可后续优化的部分。 -->
|
|
119
|
+
|
|
120
|
+
-
|
|
121
|
+
|
|
109
122
|
## 权限规则
|
|
110
123
|
|
|
111
124
|
| 角色 | 可执行操作 | 限制 |
|
|
@@ -119,11 +132,6 @@ applies_to: []
|
|
|
119
132
|
## 审计与追踪
|
|
120
133
|
|
|
121
134
|
<!-- 是否需要审计日志、操作人、时间、状态变更原因等。 -->
|
|
122
|
-
|
|
123
|
-
## 禁止行为
|
|
124
|
-
|
|
125
|
-
-
|
|
126
|
-
-
|
|
127
135
|
`;
|
|
128
136
|
const DOMAIN_STATE_MACHINE = `---
|
|
129
137
|
title: {{domain_title}}状态机
|
|
@@ -413,6 +421,109 @@ applies_to: []
|
|
|
413
421
|
|
|
414
422
|
## 工具与命令
|
|
415
423
|
`;
|
|
424
|
+
const CHANGE_PROPOSAL = `# {{change_title}}
|
|
425
|
+
|
|
426
|
+
## Why
|
|
427
|
+
|
|
428
|
+
<!-- 为什么要做这个变更?解决什么问题? -->
|
|
429
|
+
|
|
430
|
+
## What Changes
|
|
431
|
+
|
|
432
|
+
<!-- 变更内容概述:新增/修改/移除哪些能力。 -->
|
|
433
|
+
|
|
434
|
+
## Impact
|
|
435
|
+
|
|
436
|
+
- Affected domains: {{domain}}
|
|
437
|
+
- Affected specs:
|
|
438
|
+
- Affected code:
|
|
439
|
+
`;
|
|
440
|
+
const CHANGE_DESIGN = `# {{change_title}} — Design
|
|
441
|
+
|
|
442
|
+
## Context
|
|
443
|
+
|
|
444
|
+
<!-- 现状与约束。 -->
|
|
445
|
+
|
|
446
|
+
## Goals / Non-Goals
|
|
447
|
+
|
|
448
|
+
- Goals:
|
|
449
|
+
- Non-Goals:
|
|
450
|
+
|
|
451
|
+
## Decisions
|
|
452
|
+
|
|
453
|
+
<!-- 关键技术决策;长期决策请沉淀为 ADR(meta new-adr)。 -->
|
|
454
|
+
|
|
455
|
+
## Hard Constraints(硬限制核对)
|
|
456
|
+
|
|
457
|
+
<!-- 列出本变更涉及的已声明硬限制与核对结论。 -->
|
|
458
|
+
<!-- 来源:docs/domain/<domain>/rules.md 硬限制章节、docs/engineering/constraints.md。 -->
|
|
459
|
+
|
|
460
|
+
| 硬限制 | 来源 | 核对结论 |
|
|
461
|
+
|---|---|---|
|
|
462
|
+
| | | |
|
|
463
|
+
|
|
464
|
+
## Risks / Trade-offs
|
|
465
|
+
|
|
466
|
+
<!-- 风险与权衡。 -->
|
|
467
|
+
`;
|
|
468
|
+
const CHANGE_TASKS = `# {{change_title}} — Tasks
|
|
469
|
+
|
|
470
|
+
## 1. Implementation
|
|
471
|
+
|
|
472
|
+
- [ ] 1.1
|
|
473
|
+
- [ ] 1.2
|
|
474
|
+
|
|
475
|
+
## 2. Validation
|
|
476
|
+
|
|
477
|
+
- [ ] 2.1 Tests updated
|
|
478
|
+
- [ ] 2.2 \`meta check\` passes
|
|
479
|
+
`;
|
|
480
|
+
const CHANGE_RISK_REVIEW = `# {{change_title}} — Risk Review
|
|
481
|
+
|
|
482
|
+
- Related domain: {{domain}}
|
|
483
|
+
- Date: {{date}}
|
|
484
|
+
|
|
485
|
+
## Checklist
|
|
486
|
+
|
|
487
|
+
- [ ] Money representation(金额表示与精度)
|
|
488
|
+
- [ ] Idempotency(幂等)
|
|
489
|
+
- [ ] Retry behavior(重试行为)
|
|
490
|
+
- [ ] Callback deduplication(回调去重)
|
|
491
|
+
- [ ] Audit logging(审计日志)
|
|
492
|
+
- [ ] Permission boundaries(权限边界)
|
|
493
|
+
- [ ] Rollback plan(回滚方案)
|
|
494
|
+
- [ ] Declared hard constraints checked(已声明的硬限制全部核对)
|
|
495
|
+
|
|
496
|
+
## Notes
|
|
497
|
+
|
|
498
|
+
<!-- 每项勾选前写清结论或“不适用”的原因。 -->
|
|
499
|
+
`;
|
|
500
|
+
const ENGINEERING_CONSTRAINTS = `---
|
|
501
|
+
title: 项目级硬限制
|
|
502
|
+
status: draft
|
|
503
|
+
owner: {{owner}}
|
|
504
|
+
last_reviewed: {{date}}
|
|
505
|
+
source_of_truth: true
|
|
506
|
+
applies_to: []
|
|
507
|
+
---
|
|
508
|
+
|
|
509
|
+
# 项目级硬限制
|
|
510
|
+
|
|
511
|
+
<!-- 跨领域的硬限制放这里;单个领域的硬限制放 docs/domain/<domain>/rules.md。 -->
|
|
512
|
+
|
|
513
|
+
## 硬限制(不可违反)
|
|
514
|
+
|
|
515
|
+
<!-- 类别参考:安全、数据一致性、API 契约、性能预算、兼容性、合规。 -->
|
|
516
|
+
<!-- 没写在这里的限制,AI 会当成可协商的。 -->
|
|
517
|
+
|
|
518
|
+
-
|
|
519
|
+
-
|
|
520
|
+
|
|
521
|
+
## 软限制(可权衡)
|
|
522
|
+
|
|
523
|
+
<!-- 代码风格偏好、非关键路径的实现细节、可后续优化的部分。 -->
|
|
524
|
+
|
|
525
|
+
-
|
|
526
|
+
`;
|
|
416
527
|
const RUNBOOKS_README = `---
|
|
417
528
|
title: Runbooks
|
|
418
529
|
status: draft
|
|
@@ -441,5 +552,10 @@ export const BUILTIN_TEMPLATES = {
|
|
|
441
552
|
"system-overview.md": SYSTEM_OVERVIEW,
|
|
442
553
|
"api-conventions.md": API_CONVENTIONS,
|
|
443
554
|
"engineering-testing.md": ENGINEERING_TESTING,
|
|
555
|
+
"engineering-constraints.md": ENGINEERING_CONSTRAINTS,
|
|
444
556
|
"runbooks-readme.md": RUNBOOKS_README,
|
|
557
|
+
"change-proposal.md": CHANGE_PROPOSAL,
|
|
558
|
+
"change-design.md": CHANGE_DESIGN,
|
|
559
|
+
"change-tasks.md": CHANGE_TASKS,
|
|
560
|
+
"change-risk-review.md": CHANGE_RISK_REVIEW,
|
|
445
561
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { parseDocFile, hasSection } from "../core/frontmatter.js";
|
|
3
|
+
import { parseDocFile, hasSection, sectionHasContent, HARD_CONSTRAINT_HEADINGS, } from "../core/frontmatter.js";
|
|
4
4
|
import { matchRiskKeywords } from "../core/risk.js";
|
|
5
5
|
export function listDomainDirs(root, domainDocs) {
|
|
6
6
|
const abs = path.join(root, domainDocs);
|
|
@@ -99,6 +99,20 @@ export function validateDomains(ctx) {
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
if (riskHits.length > 0) {
|
|
102
|
+
// Hard constraints must be declared; undeclared limits get treated as
|
|
103
|
+
// negotiable by AI agents.
|
|
104
|
+
if (fs.existsSync(rulesAbs)) {
|
|
105
|
+
const rules = parseDocFile(rulesAbs);
|
|
106
|
+
if (!sectionHasContent(rules.content, HARD_CONSTRAINT_HEADINGS)) {
|
|
107
|
+
issues.push({
|
|
108
|
+
code: "HIGH_RISK_DOMAIN_MISSING_HARD_CONSTRAINTS",
|
|
109
|
+
severity: "warning",
|
|
110
|
+
file: path.join(relDir, "rules.md"),
|
|
111
|
+
message: `High-risk domain '${domain}' declares no hard constraints`,
|
|
112
|
+
suggestion: 'Fill the "## 硬限制(不可违反)" section in rules.md (security, data consistency, API contracts, performance budgets, compatibility, compliance).',
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
102
116
|
if (!fs.existsSync(rulesAbs)) {
|
|
103
117
|
issues.push({
|
|
104
118
|
code: "HIGH_RISK_DOMAIN_MISSING_RULES",
|
|
@@ -126,6 +140,21 @@ export function validateDomains(ctx) {
|
|
|
126
140
|
suggestion: `Run \`meta new-domain ${domain} --force --with-state-machine\`.`,
|
|
127
141
|
});
|
|
128
142
|
}
|
|
143
|
+
// High-risk domains should link the ADRs backing their key decisions.
|
|
144
|
+
const docs = [readmeAbs, rulesAbs].filter((abs) => fs.existsSync(abs));
|
|
145
|
+
const referencesAdr = docs.some((abs) => {
|
|
146
|
+
const body = fs.readFileSync(abs, "utf8").replace(/<!--[\s\S]*?-->/g, "");
|
|
147
|
+
return /adr\//i.test(body) || /ADR-\d/.test(body);
|
|
148
|
+
});
|
|
149
|
+
if (docs.length > 0 && !referencesAdr) {
|
|
150
|
+
issues.push({
|
|
151
|
+
code: "DOMAIN_NO_ADR_REFERENCE",
|
|
152
|
+
severity: "warning",
|
|
153
|
+
file: relDir,
|
|
154
|
+
message: `High-risk domain '${domain}' does not reference any ADR`,
|
|
155
|
+
suggestion: `Record key decisions with \`meta new-adr ${domain}-idempotency\` and link them from the domain README.`,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
129
158
|
}
|
|
130
159
|
}
|
|
131
160
|
return { issues, checkedFiles };
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { matchRiskKeywords } from "../core/risk.js";
|
|
4
|
+
import { listDomainDirs } from "./domain-validator.js";
|
|
3
5
|
export function validateOpenSpec(ctx) {
|
|
4
6
|
const issues = [];
|
|
5
7
|
const { root, config } = ctx;
|
|
@@ -53,24 +55,51 @@ export function validateOpenSpec(ctx) {
|
|
|
53
55
|
});
|
|
54
56
|
}
|
|
55
57
|
}
|
|
56
|
-
// Each change directory
|
|
58
|
+
// Each change directory must contain the core change files.
|
|
57
59
|
const changesAbs = path.join(openspecAbs, "changes");
|
|
58
60
|
if (fs.existsSync(changesAbs)) {
|
|
59
61
|
for (const entry of fs.readdirSync(changesAbs, { withFileTypes: true })) {
|
|
60
62
|
if (!entry.isDirectory())
|
|
61
63
|
continue;
|
|
64
|
+
// OpenSpec keeps completed changes under changes/archive/.
|
|
65
|
+
if (entry.name === "archive")
|
|
66
|
+
continue;
|
|
62
67
|
checkedFiles++;
|
|
63
68
|
const changeDir = path.join(changesAbs, entry.name);
|
|
64
|
-
const
|
|
65
|
-
if (
|
|
69
|
+
const missing = ["proposal.md", "tasks.md"].filter((f) => !fs.existsSync(path.join(changeDir, f)));
|
|
70
|
+
if (missing.length > 0) {
|
|
66
71
|
issues.push({
|
|
67
72
|
code: "OPENSPEC_CHANGE_INCOMPLETE",
|
|
68
73
|
severity: "warning",
|
|
69
74
|
file: path.join(openspecRel, "changes", entry.name),
|
|
70
|
-
message:
|
|
75
|
+
message: `Change directory is missing: ${missing.join(", ")}`,
|
|
76
|
+
suggestion: `Run \`meta new-change ${entry.name}\` to create the missing files.`,
|
|
71
77
|
});
|
|
72
78
|
}
|
|
73
79
|
}
|
|
74
80
|
}
|
|
81
|
+
// High-risk domain docs should reference OpenSpec specs or changes.
|
|
82
|
+
for (const domain of listDomainDirs(root, config.paths.domain_docs)) {
|
|
83
|
+
const riskHits = matchRiskKeywords(domain, config.risk_keywords);
|
|
84
|
+
if (riskHits.length === 0)
|
|
85
|
+
continue;
|
|
86
|
+
const domainRel = path.join(config.paths.domain_docs, domain);
|
|
87
|
+
const docs = ["README.md", "rules.md"]
|
|
88
|
+
.map((f) => path.join(root, domainRel, f))
|
|
89
|
+
.filter((abs) => fs.existsSync(abs));
|
|
90
|
+
if (docs.length === 0)
|
|
91
|
+
continue;
|
|
92
|
+
checkedFiles += docs.length;
|
|
93
|
+
const referencesOpenspec = docs.some((abs) => /openspec/i.test(fs.readFileSync(abs, "utf8").replace(/<!--[\s\S]*?-->/g, "")));
|
|
94
|
+
if (!referencesOpenspec) {
|
|
95
|
+
issues.push({
|
|
96
|
+
code: "HIGH_RISK_DOMAIN_NO_OPENSPEC_REFERENCE",
|
|
97
|
+
severity: "warning",
|
|
98
|
+
file: domainRel,
|
|
99
|
+
message: `High-risk domain '${domain}' does not reference any OpenSpec specs or changes`,
|
|
100
|
+
suggestion: `Link the relevant openspec/specs/ or openspec/changes/ entries from ${domainRel}/README.md.`,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
75
104
|
return { issues, checkedFiles };
|
|
76
105
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bossmissing/agent-meta",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Agent Meta CLI - manage AI agent collaboration metadata (AGENTS.md, domain docs, ADRs, frontmatter checks)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"types": "./dist/index.d.ts",
|
|
23
23
|
"files": [
|
|
24
24
|
"dist",
|
|
25
|
+
"assets",
|
|
25
26
|
"README.md",
|
|
26
27
|
"LICENSE"
|
|
27
28
|
],
|
|
@@ -32,14 +33,6 @@
|
|
|
32
33
|
"engines": {
|
|
33
34
|
"node": ">=20"
|
|
34
35
|
},
|
|
35
|
-
"scripts": {
|
|
36
|
-
"build": "tsc -p tsconfig.build.json",
|
|
37
|
-
"dev": "tsx src/cli.ts",
|
|
38
|
-
"test": "vitest run",
|
|
39
|
-
"test:watch": "vitest",
|
|
40
|
-
"typecheck": "tsc --noEmit",
|
|
41
|
-
"prepublishOnly": "pnpm build"
|
|
42
|
-
},
|
|
43
36
|
"dependencies": {
|
|
44
37
|
"@inquirer/prompts": "^7.0.0",
|
|
45
38
|
"commander": "^12.1.0",
|
|
@@ -55,10 +48,11 @@
|
|
|
55
48
|
"typescript": "^5.5.0",
|
|
56
49
|
"vitest": "^2.1.0"
|
|
57
50
|
},
|
|
58
|
-
"
|
|
59
|
-
|
|
60
|
-
"
|
|
61
|
-
|
|
62
|
-
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "tsc -p tsconfig.build.json",
|
|
53
|
+
"dev": "tsx src/cli.ts",
|
|
54
|
+
"test": "vitest run",
|
|
55
|
+
"test:watch": "vitest",
|
|
56
|
+
"typecheck": "tsc --noEmit"
|
|
63
57
|
}
|
|
64
|
-
}
|
|
58
|
+
}
|