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.
@@ -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",
@@ -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));
@@ -1,43 +1,9 @@
1
- # Agent Guidelines
1
+ # AGENTS
2
2
 
3
- This repo uses mdkg for tasks, decisions, and context packs.
3
+ Read `AGENT_START.md` first.
4
4
 
5
- ## Quickstart
6
-
7
- - `mdkg init --llm`
8
- - `mdkg index`
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
- ## 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.
@@ -1,37 +1,8 @@
1
- # Claude Instructions
1
+ # CLAUDE
2
2
 
3
- This project uses mdkg to manage tasks and context.
3
+ Read `AGENT_START.md` first.
4
4
 
5
- ## Quickstart
6
-
7
- - `mdkg init --llm`
8
- - `mdkg index`
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`
@@ -14,13 +14,15 @@ This repository is initialized for mdkg.
14
14
  ## First Commands
15
15
 
16
16
  ```bash
17
- mdkg index
18
- mdkg new task "..." --status todo --priority 1
19
- mdkg list --status todo
20
- mdkg pack <id> --verbose
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?