mdkg 0.0.4 → 0.0.6
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 +25 -14
- package/dist/cli.js +34 -13
- package/dist/commands/event.js +1 -2
- package/dist/commands/event_support.js +2 -30
- package/dist/commands/init.js +35 -4
- package/dist/commands/skill.js +15 -0
- package/dist/commands/skill_mirror.js +323 -0
- package/dist/commands/skill_support.js +1 -0
- package/dist/commands/task.js +8 -0
- package/dist/commands/validate.js +2 -0
- package/dist/init/AGENTS.md +7 -41
- package/dist/init/AGENT_START.md +47 -0
- package/dist/init/CLAUDE.md +6 -35
- package/dist/init/CLI_COMMAND_MATRIX.md +29 -0
- package/dist/init/README.md +6 -4
- package/dist/init/core/HUMAN.md +36 -0
- package/dist/init/core/SOUL.md +257 -0
- package/dist/init/core/core.md +3 -1
- package/dist/init/core/rule-3-cli-contract.md +16 -4
- package/dist/init/core/rule-4-repo-safety-and-ignores.md +2 -3
- package/dist/init/llms.txt +17 -0
- package/dist/init/skills/default/build-pack-and-execute-task/SKILL.md +57 -0
- package/dist/init/skills/default/select-work-and-ground-context/SKILL.md +55 -0
- package/dist/init/skills/default/verify-close-and-checkpoint/SKILL.md +62 -0
- package/dist/util/argparse.js +12 -7
- package/package.json +1 -1
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.syncSkillMirrors = syncSkillMirrors;
|
|
7
|
+
exports.shouldMaintainSkillMirrors = shouldMaintainSkillMirrors;
|
|
8
|
+
exports.auditSkillMirrors = auditSkillMirrors;
|
|
9
|
+
exports.scaffoldMirrorRoots = scaffoldMirrorRoots;
|
|
10
|
+
const fs_1 = __importDefault(require("fs"));
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const skills_indexer_1 = require("../graph/skills_indexer");
|
|
13
|
+
const errors_1 = require("../util/errors");
|
|
14
|
+
const MIRROR_PRODUCTS = ["agents", "claude"];
|
|
15
|
+
const MANIFEST_FILE = ".mdkg-managed.json";
|
|
16
|
+
const MANAGED_ROOT_MARKERS = [
|
|
17
|
+
path_1.default.join(".mdkg", "core", "SOUL.md"),
|
|
18
|
+
path_1.default.join(".mdkg", "core", "HUMAN.md"),
|
|
19
|
+
];
|
|
20
|
+
const ALLOWED_ROOT_ENTRIES = ["SKILL.md", "references", "assets", "scripts"];
|
|
21
|
+
function resolveMirrorTargets(root) {
|
|
22
|
+
return MIRROR_PRODUCTS.map((product) => {
|
|
23
|
+
const rootDir = path_1.default.join(root, `.${product}`);
|
|
24
|
+
const skillsRoot = path_1.default.join(rootDir, "skills");
|
|
25
|
+
return {
|
|
26
|
+
product,
|
|
27
|
+
rootDir,
|
|
28
|
+
skillsRoot,
|
|
29
|
+
manifestPath: path_1.default.join(skillsRoot, MANIFEST_FILE),
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function readManifest(target) {
|
|
34
|
+
if (!fs_1.default.existsSync(target.manifestPath)) {
|
|
35
|
+
return new Set();
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const parsed = JSON.parse(fs_1.default.readFileSync(target.manifestPath, "utf8"));
|
|
39
|
+
if (!Array.isArray(parsed.managed_slugs)) {
|
|
40
|
+
return new Set();
|
|
41
|
+
}
|
|
42
|
+
return new Set(parsed.managed_slugs
|
|
43
|
+
.map((value) => String(value).trim().toLowerCase())
|
|
44
|
+
.filter(Boolean));
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return new Set();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function writeManifest(target, managed) {
|
|
51
|
+
const payload = {
|
|
52
|
+
managed_slugs: Array.from(new Set(Array.from(managed).map((value) => value.toLowerCase()))).sort(),
|
|
53
|
+
};
|
|
54
|
+
fs_1.default.mkdirSync(target.skillsRoot, { recursive: true });
|
|
55
|
+
fs_1.default.writeFileSync(target.manifestPath, `${JSON.stringify(payload, null, 2)}\n`, "utf8");
|
|
56
|
+
}
|
|
57
|
+
function shouldCreateMirrorRoots(root) {
|
|
58
|
+
if (MANAGED_ROOT_MARKERS.some((relPath) => fs_1.default.existsSync(path_1.default.join(root, relPath)))) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
return resolveMirrorTargets(root).some((target) => fs_1.default.existsSync(target.rootDir) || fs_1.default.existsSync(target.skillsRoot));
|
|
62
|
+
}
|
|
63
|
+
function listAllowedEntries(dirPath) {
|
|
64
|
+
if (!fs_1.default.existsSync(dirPath)) {
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
const entries = [];
|
|
68
|
+
const queue = [dirPath];
|
|
69
|
+
while (queue.length > 0) {
|
|
70
|
+
const current = queue.shift();
|
|
71
|
+
const dirEntries = fs_1.default.readdirSync(current, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
72
|
+
for (const entry of dirEntries) {
|
|
73
|
+
const fullPath = path_1.default.join(current, entry.name);
|
|
74
|
+
const relPath = path_1.default.relative(dirPath, fullPath).replace(/\\/g, "/");
|
|
75
|
+
if (entry.isDirectory()) {
|
|
76
|
+
entries.push(`${relPath}/`);
|
|
77
|
+
queue.push(fullPath);
|
|
78
|
+
}
|
|
79
|
+
else if (entry.isFile()) {
|
|
80
|
+
entries.push(relPath);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return entries.sort();
|
|
85
|
+
}
|
|
86
|
+
function resolveSkillDocPath(skillDir) {
|
|
87
|
+
const canonicalPath = path_1.default.join(skillDir, "SKILL.md");
|
|
88
|
+
const compatPath = path_1.default.join(skillDir, "SKILLS.md");
|
|
89
|
+
if (fs_1.default.existsSync(canonicalPath) && fs_1.default.existsSync(compatPath)) {
|
|
90
|
+
throw new errors_1.UsageError(`${skillDir}: both SKILL.md and SKILLS.md exist; fix the canonical skill first`);
|
|
91
|
+
}
|
|
92
|
+
if (fs_1.default.existsSync(canonicalPath)) {
|
|
93
|
+
return canonicalPath;
|
|
94
|
+
}
|
|
95
|
+
if (fs_1.default.existsSync(compatPath)) {
|
|
96
|
+
return compatPath;
|
|
97
|
+
}
|
|
98
|
+
throw new errors_1.UsageError(`${skillDir}: missing SKILL.md or SKILLS.md`);
|
|
99
|
+
}
|
|
100
|
+
function loadCanonicalSources(root, config) {
|
|
101
|
+
const index = (0, skills_indexer_1.buildSkillsIndex)(root, config);
|
|
102
|
+
return Object.values(index.skills)
|
|
103
|
+
.sort((a, b) => a.slug.localeCompare(b.slug))
|
|
104
|
+
.map((entry) => {
|
|
105
|
+
const docPath = path_1.default.resolve(root, entry.path);
|
|
106
|
+
return {
|
|
107
|
+
slug: entry.slug,
|
|
108
|
+
sourceDir: path_1.default.dirname(docPath),
|
|
109
|
+
docPath,
|
|
110
|
+
};
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
function writeFileIfChanged(srcPath, destPath) {
|
|
114
|
+
const next = fs_1.default.readFileSync(srcPath);
|
|
115
|
+
if (fs_1.default.existsSync(destPath) && fs_1.default.statSync(destPath).isFile()) {
|
|
116
|
+
const current = fs_1.default.readFileSync(destPath);
|
|
117
|
+
if (current.equals(next)) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
fs_1.default.mkdirSync(path_1.default.dirname(destPath), { recursive: true });
|
|
122
|
+
fs_1.default.writeFileSync(destPath, next);
|
|
123
|
+
}
|
|
124
|
+
function syncDir(srcDir, destDir) {
|
|
125
|
+
fs_1.default.mkdirSync(destDir, { recursive: true });
|
|
126
|
+
const sourceEntries = fs_1.default.readdirSync(srcDir, { withFileTypes: true });
|
|
127
|
+
const sourceNames = new Set(sourceEntries.map((entry) => entry.name));
|
|
128
|
+
if (fs_1.default.existsSync(destDir)) {
|
|
129
|
+
for (const existing of fs_1.default.readdirSync(destDir)) {
|
|
130
|
+
if (!sourceNames.has(existing)) {
|
|
131
|
+
fs_1.default.rmSync(path_1.default.join(destDir, existing), { recursive: true, force: true });
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
for (const entry of sourceEntries) {
|
|
136
|
+
const srcPath = path_1.default.join(srcDir, entry.name);
|
|
137
|
+
const destPath = path_1.default.join(destDir, entry.name);
|
|
138
|
+
if (entry.isDirectory()) {
|
|
139
|
+
syncDir(srcPath, destPath);
|
|
140
|
+
}
|
|
141
|
+
else if (entry.isFile()) {
|
|
142
|
+
writeFileIfChanged(srcPath, destPath);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function materializeSkillMirror(source, destDir) {
|
|
147
|
+
fs_1.default.mkdirSync(destDir, { recursive: true });
|
|
148
|
+
const expectedRootEntries = new Set(["SKILL.md"]);
|
|
149
|
+
for (const entry of ["references", "assets", "scripts"]) {
|
|
150
|
+
const srcPath = path_1.default.join(source.sourceDir, entry);
|
|
151
|
+
if (fs_1.default.existsSync(srcPath) && fs_1.default.statSync(srcPath).isDirectory()) {
|
|
152
|
+
expectedRootEntries.add(entry);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
for (const existing of fs_1.default.readdirSync(destDir)) {
|
|
156
|
+
if (!expectedRootEntries.has(existing)) {
|
|
157
|
+
fs_1.default.rmSync(path_1.default.join(destDir, existing), { recursive: true, force: true });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
writeFileIfChanged(source.docPath, path_1.default.join(destDir, "SKILL.md"));
|
|
161
|
+
for (const entry of ["references", "assets", "scripts"]) {
|
|
162
|
+
const srcPath = path_1.default.join(source.sourceDir, entry);
|
|
163
|
+
const destPath = path_1.default.join(destDir, entry);
|
|
164
|
+
if (fs_1.default.existsSync(srcPath) && fs_1.default.statSync(srcPath).isDirectory()) {
|
|
165
|
+
syncDir(srcPath, destPath);
|
|
166
|
+
}
|
|
167
|
+
else if (fs_1.default.existsSync(destPath)) {
|
|
168
|
+
fs_1.default.rmSync(destPath, { recursive: true, force: true });
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function collectExpectedSkillTree(source) {
|
|
173
|
+
const expected = new Map();
|
|
174
|
+
expected.set("SKILL.md", fs_1.default.readFileSync(source.docPath, "utf8"));
|
|
175
|
+
for (const entry of ["references", "assets", "scripts"]) {
|
|
176
|
+
const srcPath = path_1.default.join(source.sourceDir, entry);
|
|
177
|
+
if (!fs_1.default.existsSync(srcPath) || !fs_1.default.statSync(srcPath).isDirectory()) {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
expected.set(`${entry}/`, "dir");
|
|
181
|
+
for (const relPath of listAllowedEntries(srcPath)) {
|
|
182
|
+
const absolute = path_1.default.join(srcPath, relPath.replace(/\/$/, ""));
|
|
183
|
+
expected.set(`${entry}/${relPath}`, relPath.endsWith("/") ? "dir" : fs_1.default.readFileSync(absolute, "utf8"));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return expected;
|
|
187
|
+
}
|
|
188
|
+
function collectActualSkillTree(destDir) {
|
|
189
|
+
const entries = new Map();
|
|
190
|
+
if (!fs_1.default.existsSync(destDir)) {
|
|
191
|
+
return { entries, hasUnexpectedRootEntry: false };
|
|
192
|
+
}
|
|
193
|
+
const rootEntries = fs_1.default.readdirSync(destDir, { withFileTypes: true });
|
|
194
|
+
let hasUnexpectedRootEntry = false;
|
|
195
|
+
for (const entry of rootEntries) {
|
|
196
|
+
if (!ALLOWED_ROOT_ENTRIES.includes(entry.name)) {
|
|
197
|
+
hasUnexpectedRootEntry = true;
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
const fullPath = path_1.default.join(destDir, entry.name);
|
|
201
|
+
if (entry.isFile()) {
|
|
202
|
+
entries.set(entry.name, fs_1.default.readFileSync(fullPath, "utf8"));
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
if (!entry.isDirectory()) {
|
|
206
|
+
hasUnexpectedRootEntry = true;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
entries.set(`${entry.name}/`, "dir");
|
|
210
|
+
for (const relPath of listAllowedEntries(fullPath)) {
|
|
211
|
+
const absolute = path_1.default.join(fullPath, relPath.replace(/\/$/, ""));
|
|
212
|
+
entries.set(`${entry.name}/${relPath}`, relPath.endsWith("/") ? "dir" : fs_1.default.readFileSync(absolute, "utf8"));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return { entries, hasUnexpectedRootEntry };
|
|
216
|
+
}
|
|
217
|
+
function isManagedSkillTreeInSync(source, destDir) {
|
|
218
|
+
const expected = collectExpectedSkillTree(source);
|
|
219
|
+
const actual = collectActualSkillTree(destDir);
|
|
220
|
+
if (actual.hasUnexpectedRootEntry) {
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
if (expected.size !== actual.entries.size) {
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
for (const [relPath, content] of expected.entries()) {
|
|
227
|
+
if (!actual.entries.has(relPath) || actual.entries.get(relPath) !== content) {
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return true;
|
|
232
|
+
}
|
|
233
|
+
function syncSkillMirrors(options) {
|
|
234
|
+
const sources = loadCanonicalSources(options.root, options.config);
|
|
235
|
+
const createRoots = Boolean(options.createRoots);
|
|
236
|
+
const force = Boolean(options.force);
|
|
237
|
+
const targets = resolveMirrorTargets(options.root);
|
|
238
|
+
let synced = 0;
|
|
239
|
+
let pruned = 0;
|
|
240
|
+
let touchedTargets = 0;
|
|
241
|
+
for (const target of targets) {
|
|
242
|
+
const shouldManageTarget = createRoots || fs_1.default.existsSync(target.skillsRoot) || fs_1.default.existsSync(target.rootDir);
|
|
243
|
+
if (!shouldManageTarget) {
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
touchedTargets += 1;
|
|
247
|
+
fs_1.default.mkdirSync(target.skillsRoot, { recursive: true });
|
|
248
|
+
const managed = readManifest(target);
|
|
249
|
+
for (const source of sources) {
|
|
250
|
+
const destDir = path_1.default.join(target.skillsRoot, source.slug);
|
|
251
|
+
const exists = fs_1.default.existsSync(destDir);
|
|
252
|
+
if (exists && !managed.has(source.slug) && !force) {
|
|
253
|
+
throw new errors_1.UsageError(`${path_1.default.relative(options.root, destDir)} already exists and is not mdkg-managed; rerun \`mdkg skill sync --force\` to replace it`);
|
|
254
|
+
}
|
|
255
|
+
materializeSkillMirror(source, destDir);
|
|
256
|
+
managed.add(source.slug);
|
|
257
|
+
synced += 1;
|
|
258
|
+
}
|
|
259
|
+
for (const slug of Array.from(managed)) {
|
|
260
|
+
if (sources.some((source) => source.slug === slug)) {
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
const destDir = path_1.default.join(target.skillsRoot, slug);
|
|
264
|
+
if (fs_1.default.existsSync(destDir)) {
|
|
265
|
+
fs_1.default.rmSync(destDir, { recursive: true, force: true });
|
|
266
|
+
pruned += 1;
|
|
267
|
+
}
|
|
268
|
+
managed.delete(slug);
|
|
269
|
+
}
|
|
270
|
+
writeManifest(target, managed);
|
|
271
|
+
}
|
|
272
|
+
return { synced, pruned, targets: touchedTargets };
|
|
273
|
+
}
|
|
274
|
+
function shouldMaintainSkillMirrors(root) {
|
|
275
|
+
return shouldCreateMirrorRoots(root);
|
|
276
|
+
}
|
|
277
|
+
function auditSkillMirrors(root, config) {
|
|
278
|
+
const shouldAudit = shouldCreateMirrorRoots(root);
|
|
279
|
+
if (!shouldAudit) {
|
|
280
|
+
return [];
|
|
281
|
+
}
|
|
282
|
+
const warnings = [];
|
|
283
|
+
const sources = loadCanonicalSources(root, config);
|
|
284
|
+
const sourceBySlug = new Map(sources.map((source) => [source.slug, source]));
|
|
285
|
+
for (const target of resolveMirrorTargets(root)) {
|
|
286
|
+
if (!fs_1.default.existsSync(target.skillsRoot)) {
|
|
287
|
+
warnings.push(`${path_1.default.relative(root, target.skillsRoot)}: mirror root missing; run \`mdkg skill sync\``);
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
const managed = readManifest(target);
|
|
291
|
+
if (!fs_1.default.existsSync(target.manifestPath)) {
|
|
292
|
+
warnings.push(`${path_1.default.relative(root, target.manifestPath)}: mirror manifest missing; run \`mdkg skill sync\``);
|
|
293
|
+
}
|
|
294
|
+
for (const source of sources) {
|
|
295
|
+
const destDir = path_1.default.join(target.skillsRoot, source.slug);
|
|
296
|
+
if (!fs_1.default.existsSync(destDir)) {
|
|
297
|
+
warnings.push(`${path_1.default.relative(root, destDir)}: missing mirrored skill; run \`mdkg skill sync\``);
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
if (!managed.has(source.slug)) {
|
|
301
|
+
warnings.push(`${path_1.default.relative(root, destDir)}: conflicting unmanaged mirror; rerun \`mdkg skill sync --force\` to replace it`);
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
if (!isManagedSkillTreeInSync(source, destDir)) {
|
|
305
|
+
warnings.push(`${path_1.default.relative(root, destDir)}: mirrored skill drift detected; run \`mdkg skill sync\``);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
for (const slug of managed) {
|
|
309
|
+
if (!sourceBySlug.has(slug)) {
|
|
310
|
+
warnings.push(`${path_1.default.relative(root, path_1.default.join(target.skillsRoot, slug))}: stale mirrored skill; run \`mdkg skill sync\``);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return warnings;
|
|
315
|
+
}
|
|
316
|
+
function scaffoldMirrorRoots(root) {
|
|
317
|
+
for (const target of resolveMirrorTargets(root)) {
|
|
318
|
+
fs_1.default.mkdirSync(target.skillsRoot, { recursive: true });
|
|
319
|
+
if (!fs_1.default.existsSync(target.manifestPath)) {
|
|
320
|
+
writeManifest(target, []);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
@@ -51,6 +51,7 @@ function registryTemplate() {
|
|
|
51
51
|
"This directory stores Agent Skills packages used by mdkg tooling and orchestrators.",
|
|
52
52
|
"",
|
|
53
53
|
"Use `mdkg skill new <slug> \"<name>\" --description \"...\"` to scaffold a new skill from the built-in Anthropic-aligned template.",
|
|
54
|
+
"Use `mdkg skill sync` to mirror canonical skills into `.agents/skills/` and `.claude/skills/` when agent bootstrap is enabled.",
|
|
54
55
|
"Use `CLI_COMMAND_MATRIX.md` as the canonical command and flag reference when updating skill procedures.",
|
|
55
56
|
"",
|
|
56
57
|
"## Conventions",
|
package/dist/commands/task.js
CHANGED
|
@@ -169,6 +169,12 @@ function ensureSkillsExist(root, node, slugs) {
|
|
|
169
169
|
function updateUpdatedDate(frontmatter, now) {
|
|
170
170
|
frontmatter.updated = (0, date_1.formatDate)(now);
|
|
171
171
|
}
|
|
172
|
+
function maybeWarnEventsDisabled(root, config, ws) {
|
|
173
|
+
if ((0, event_support_1.isEventLoggingEnabled)(root, config, ws)) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
console.error(`note: events.jsonl is missing for workspace ${ws}; run mdkg event enable --ws ${ws} to restore JSONL provenance`);
|
|
177
|
+
}
|
|
172
178
|
function runTaskStartCommand(options) {
|
|
173
179
|
const loaded = loadMutableTaskNode(options.root, options.id, options.ws);
|
|
174
180
|
const now = options.now ?? new Date();
|
|
@@ -186,6 +192,7 @@ function runTaskStartCommand(options) {
|
|
|
186
192
|
runId: options.runId,
|
|
187
193
|
now,
|
|
188
194
|
});
|
|
195
|
+
maybeWarnEventsDisabled(options.root, loaded.config, loaded.ws);
|
|
189
196
|
console.log(`task started: ${loaded.qid}`);
|
|
190
197
|
}
|
|
191
198
|
function runTaskUpdateCommand(options) {
|
|
@@ -266,5 +273,6 @@ function runTaskDoneCommand(options) {
|
|
|
266
273
|
});
|
|
267
274
|
}
|
|
268
275
|
maybeReindex(options.root, loaded.config);
|
|
276
|
+
maybeWarnEventsDisabled(options.root, loaded.config, loaded.ws);
|
|
269
277
|
console.log(`task done: ${loaded.qid}`);
|
|
270
278
|
}
|
|
@@ -13,6 +13,7 @@ const skills_indexer_1 = require("../graph/skills_indexer");
|
|
|
13
13
|
const workspace_files_1 = require("../graph/workspace_files");
|
|
14
14
|
const validate_graph_1 = require("../graph/validate_graph");
|
|
15
15
|
const errors_1 = require("../util/errors");
|
|
16
|
+
const skill_mirror_1 = require("./skill_mirror");
|
|
16
17
|
const RECOMMENDED_HEADINGS = {
|
|
17
18
|
task: [
|
|
18
19
|
"Overview",
|
|
@@ -290,6 +291,7 @@ function runValidateCommand(options) {
|
|
|
290
291
|
warnings.push(`${path_1.default.relative(options.root, compatPath)}: using legacy SKILLS.md compatibility file`);
|
|
291
292
|
}
|
|
292
293
|
}
|
|
294
|
+
warnings.push(...(0, skill_mirror_1.auditSkillMirrors)(options.root, config));
|
|
293
295
|
validateEventsJsonl(options.root, config, errors);
|
|
294
296
|
const uniqueWarnings = Array.from(new Set(warnings));
|
|
295
297
|
const uniqueErrors = Array.from(new Set(errors));
|
package/dist/init/AGENTS.md
CHANGED
|
@@ -1,43 +1,9 @@
|
|
|
1
|
-
#
|
|
1
|
+
# AGENTS
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Read `AGENT_START.md` first.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
-
|
|
8
|
-
- `mdkg
|
|
9
|
-
- `mdkg
|
|
10
|
-
- `mdkg list --status todo`
|
|
11
|
-
- `mdkg pack <id> --verbose`
|
|
12
|
-
- `mdkg validate`
|
|
13
|
-
|
|
14
|
-
## Core commands
|
|
15
|
-
|
|
16
|
-
- `mdkg init` (scaffold .mdkg and optional agent docs)
|
|
17
|
-
- `mdkg guide` (print the repo guide)
|
|
18
|
-
- `mdkg new <type> "<title>"` (create nodes)
|
|
19
|
-
- `mdkg list` / `mdkg show` / `mdkg search`
|
|
20
|
-
- `mdkg pack` (context bundles)
|
|
21
|
-
- `mdkg next` (priority/chain)
|
|
22
|
-
- `mdkg validate` / `mdkg format`
|
|
23
|
-
|
|
24
|
-
## Getting context
|
|
25
|
-
|
|
26
|
-
- Run `mdkg list --status todo` to find work items.
|
|
27
|
-
- Before coding, run `mdkg pack <task-id> --verbose`.
|
|
28
|
-
- Read linked rules and decisions in the pack.
|
|
29
|
-
|
|
30
|
-
## Editing rules
|
|
31
|
-
|
|
32
|
-
- Keep frontmatter valid and lowercase.
|
|
33
|
-
- Update `updated: YYYY-MM-DD` when you make changes.
|
|
34
|
-
- Use `links:` and `artifacts:` for anything you want searchable.
|
|
35
|
-
|
|
36
|
-
## Validation
|
|
37
|
-
|
|
38
|
-
- Run `mdkg validate` after edits.
|
|
39
|
-
- Run `mdkg format` if frontmatter drifts.
|
|
40
|
-
|
|
41
|
-
## Project-specific notes
|
|
42
|
-
|
|
43
|
-
Add repo-specific build/test commands and conventions here.
|
|
5
|
+
Codex/OpenAI conventions for this repo:
|
|
6
|
+
- use `AGENT_START.md` as the startup contract
|
|
7
|
+
- use `.agents/skills/` for product-facing mirrored skills when present
|
|
8
|
+
- use `mdkg skill ...` as the canonical skill command family
|
|
9
|
+
- use `mdkg task ...` for structured task fields and markdown edits for narrative/body changes
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# AGENT_START
|
|
2
|
+
|
|
3
|
+
This repository uses mdkg for deterministic project memory.
|
|
4
|
+
|
|
5
|
+
Read these files in order:
|
|
6
|
+
1. `.mdkg/core/SOUL.md` if it exists
|
|
7
|
+
2. `.mdkg/core/HUMAN.md` if it exists
|
|
8
|
+
3. `.mdkg/README.md`
|
|
9
|
+
4. `CLI_COMMAND_MATRIX.md`
|
|
10
|
+
|
|
11
|
+
Trust order:
|
|
12
|
+
- source code
|
|
13
|
+
- mdkg rules, design docs, decisions, and work nodes
|
|
14
|
+
- SOUL/HUMAN collaboration anchors
|
|
15
|
+
- relevant skills
|
|
16
|
+
- chat history
|
|
17
|
+
|
|
18
|
+
If the active task is known:
|
|
19
|
+
- `mdkg pack <id>`
|
|
20
|
+
- `mdkg task start <id>` when durable work begins
|
|
21
|
+
- `mdkg task update <id> ...` as evidence accumulates
|
|
22
|
+
- `mdkg task done <id>` when work is complete
|
|
23
|
+
- `mdkg validate`
|
|
24
|
+
|
|
25
|
+
If no task is known:
|
|
26
|
+
- `mdkg search "..."`
|
|
27
|
+
- `mdkg show <id>`
|
|
28
|
+
- `mdkg next`
|
|
29
|
+
- then use `mdkg pack <id>`
|
|
30
|
+
|
|
31
|
+
Skill discovery:
|
|
32
|
+
- `mdkg skill list --tags stage:plan --json`
|
|
33
|
+
- `mdkg skill list --tags stage:execute --json`
|
|
34
|
+
- `mdkg skill list --tags stage:review --json`
|
|
35
|
+
- `mdkg skill show select-work-and-ground-context`
|
|
36
|
+
|
|
37
|
+
Conventions:
|
|
38
|
+
- `AGENTS.md` is the Codex/OpenAI-oriented wrapper doc.
|
|
39
|
+
- `CLAUDE.md` is the Claude-oriented wrapper doc.
|
|
40
|
+
- `.agents/skills/` and `.claude/skills/` mirror canonical skills from `.mdkg/skills/` when agent bootstrap is enabled.
|
|
41
|
+
- mdkg does not execute skill scripts; runtimes decide when and whether to do that.
|
|
42
|
+
- Prefer packs over ad-hoc file lists.
|
|
43
|
+
- Prefer task/event commands for structured work-state changes and use markdown edits for narrative/body updates.
|
|
44
|
+
- Use `mdkg task done <id> --checkpoint "<title>"` for milestone compression, not every routine task completion.
|
|
45
|
+
- Prefer checkpoints for feat/epic closeout summaries; parent status edits remain manual.
|
|
46
|
+
- If `events.jsonl` is missing, `mdkg task start` and `mdkg task done` will remind you how to recreate it.
|
|
47
|
+
- Files outside mdkg-managed skill mirrors, such as local tool permission files, are not managed by mdkg unless documented explicitly.
|
package/dist/init/CLAUDE.md
CHANGED
|
@@ -1,37 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# CLAUDE
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Read `AGENT_START.md` first.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
-
|
|
8
|
-
- `mdkg
|
|
9
|
-
- `mdkg new task "..." --status todo --priority 1`
|
|
10
|
-
- `mdkg list --status todo`
|
|
11
|
-
- `mdkg pack <id> --verbose`
|
|
12
|
-
- `mdkg validate`
|
|
13
|
-
|
|
14
|
-
## Core commands
|
|
15
|
-
|
|
16
|
-
- `mdkg init` (scaffold .mdkg and optional agent docs)
|
|
17
|
-
- `mdkg guide` (print the repo guide)
|
|
18
|
-
- `mdkg new <type> "<title>"` (create nodes)
|
|
19
|
-
- `mdkg list` / `mdkg show` / `mdkg search`
|
|
20
|
-
- `mdkg pack` (context bundles)
|
|
21
|
-
- `mdkg next` (priority/chain)
|
|
22
|
-
- `mdkg validate` / `mdkg format`
|
|
23
|
-
|
|
24
|
-
## Before making changes
|
|
25
|
-
|
|
26
|
-
- Run `mdkg pack <task-id> --verbose`.
|
|
27
|
-
- Follow linked rules and decisions.
|
|
28
|
-
|
|
29
|
-
## After making changes
|
|
30
|
-
|
|
31
|
-
- Update frontmatter fields and `updated: YYYY-MM-DD`.
|
|
32
|
-
- Run `mdkg validate` and fix any errors.
|
|
33
|
-
- If frontmatter is inconsistent, run `mdkg format`.
|
|
34
|
-
|
|
35
|
-
## Repo-specific notes
|
|
36
|
-
|
|
37
|
-
Add build, test, and release instructions here.
|
|
5
|
+
Claude conventions for this repo:
|
|
6
|
+
- use `AGENT_START.md` as the startup contract
|
|
7
|
+
- use `.claude/skills/` for product-facing mirrored skills when present
|
|
8
|
+
- use `mdkg skill ...` as the canonical skill command family
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# CLI Command Matrix
|
|
2
|
+
|
|
3
|
+
This file is the canonical command reference for mdkg in this repository.
|
|
4
|
+
|
|
5
|
+
Verify live help with:
|
|
6
|
+
- `mdkg --help`
|
|
7
|
+
- `mdkg help <command>`
|
|
8
|
+
|
|
9
|
+
Primary commands:
|
|
10
|
+
- `mdkg init`
|
|
11
|
+
- `mdkg new`
|
|
12
|
+
- `mdkg show`
|
|
13
|
+
- `mdkg list`
|
|
14
|
+
- `mdkg search`
|
|
15
|
+
- `mdkg pack`
|
|
16
|
+
- `mdkg skill`
|
|
17
|
+
- `mdkg task`
|
|
18
|
+
- `mdkg validate`
|
|
19
|
+
|
|
20
|
+
Agent bootstrap:
|
|
21
|
+
- `mdkg init --llm`
|
|
22
|
+
- `mdkg init --agent`
|
|
23
|
+
- `mdkg init --llm --agent`
|
|
24
|
+
|
|
25
|
+
Skill discovery:
|
|
26
|
+
- `mdkg skill list --tags stage:plan --json`
|
|
27
|
+
- `mdkg skill search "<query>" --json`
|
|
28
|
+
- `mdkg skill show <slug> --json`
|
|
29
|
+
- `mdkg skill sync`
|
package/dist/init/README.md
CHANGED
|
@@ -14,13 +14,15 @@ This repository is initialized for mdkg.
|
|
|
14
14
|
## First Commands
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
mdkg
|
|
18
|
-
mdkg
|
|
19
|
-
mdkg
|
|
20
|
-
mdkg pack <id>
|
|
17
|
+
mdkg init --llm --agent
|
|
18
|
+
mdkg search "..."
|
|
19
|
+
mdkg show <id>
|
|
20
|
+
mdkg pack <id>
|
|
21
21
|
mdkg validate
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
+
Read `AGENT_START.md` first when this repo includes it.
|
|
25
|
+
|
|
24
26
|
## Pack Profiles
|
|
25
27
|
|
|
26
28
|
- `--pack-profile standard`: full body (current default behavior)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: rule-human
|
|
3
|
+
type: rule
|
|
4
|
+
title: human working profile and collaboration preferences
|
|
5
|
+
tags: [human, collaboration, preferences]
|
|
6
|
+
owners: []
|
|
7
|
+
links: []
|
|
8
|
+
artifacts: []
|
|
9
|
+
relates: []
|
|
10
|
+
refs: []
|
|
11
|
+
aliases: [human]
|
|
12
|
+
created: 2026-03-10
|
|
13
|
+
updated: 2026-03-10
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Purpose
|
|
17
|
+
|
|
18
|
+
Capture stable collaboration preferences and boundaries so agents can work with less ambiguity.
|
|
19
|
+
|
|
20
|
+
# Scope
|
|
21
|
+
|
|
22
|
+
Applies to planning, implementation, and review interactions in this repository.
|
|
23
|
+
|
|
24
|
+
# Requirements
|
|
25
|
+
|
|
26
|
+
- Keep top goals, boundaries, and style preferences current.
|
|
27
|
+
- Include ask-before-doing constraints for risky or high-impact actions.
|
|
28
|
+
- Record preferred environment assumptions and validation commands.
|
|
29
|
+
|
|
30
|
+
# Notes
|
|
31
|
+
|
|
32
|
+
Suggested prompts:
|
|
33
|
+
- What are your top 3 goals in this repo right now?
|
|
34
|
+
- What should never happen without confirmation?
|
|
35
|
+
- What coding/review style should the agent prefer?
|
|
36
|
+
- What OS/runtime/test commands should be assumed?
|