mdkg 0.0.3 → 0.0.5
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 +181 -169
- package/dist/cli.js +1002 -624
- package/dist/commands/checkpoint.js +17 -6
- package/dist/commands/event.js +46 -0
- package/dist/commands/event_support.js +146 -0
- package/dist/commands/format.js +6 -7
- package/dist/commands/index.js +10 -4
- package/dist/commands/init.js +224 -16
- package/dist/commands/list.js +18 -1
- package/dist/commands/new.js +30 -5
- package/dist/commands/pack.js +194 -2
- package/dist/commands/query_output.js +84 -0
- package/dist/commands/search.js +22 -5
- package/dist/commands/show.js +26 -11
- package/dist/commands/skill.js +374 -0
- package/dist/commands/skill_mirror.js +290 -0
- package/dist/commands/skill_support.js +122 -0
- package/dist/commands/task.js +278 -0
- package/dist/commands/validate.js +106 -7
- package/dist/graph/edges.js +2 -2
- package/dist/graph/frontmatter.js +1 -0
- package/dist/graph/indexer.js +21 -0
- package/dist/graph/node.js +20 -4
- package/dist/graph/skills_index_cache.js +94 -0
- package/dist/graph/skills_indexer.js +160 -0
- package/dist/init/AGENTS.md +6 -41
- package/dist/init/AGENT_START.md +46 -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-1-mdkg-conventions.md +9 -2
- package/dist/init/core/rule-3-cli-contract.md +81 -14
- package/dist/init/core/rule-4-repo-safety-and-ignores.md +9 -3
- package/dist/init/core/rule-6-templates-and-schemas.md +6 -2
- package/dist/init/llms.txt +17 -0
- package/dist/init/skills/SKILL.md.example +41 -0
- package/dist/init/templates/default/bug.md +1 -0
- package/dist/init/templates/default/chk.md +1 -0
- package/dist/init/templates/default/epic.md +1 -0
- package/dist/init/templates/default/feat.md +1 -0
- package/dist/init/templates/default/task.md +1 -0
- package/dist/init/templates/default/test.md +1 -0
- package/dist/pack/export_md.js +6 -0
- package/dist/pack/export_xml.js +6 -0
- package/dist/pack/pack.js +35 -0
- package/dist/util/argparse.js +36 -5
- package/dist/util/filter.js +18 -0
- package/dist/util/id.js +23 -0
- package/package.json +5 -2
package/dist/graph/node.js
CHANGED
|
@@ -4,7 +4,7 @@ exports.ALLOWED_TYPES = exports.DEC_TYPES = exports.WORK_TYPES = void 0;
|
|
|
4
4
|
exports.parseNode = parseNode;
|
|
5
5
|
const frontmatter_1 = require("./frontmatter");
|
|
6
6
|
const edges_1 = require("./edges");
|
|
7
|
-
const
|
|
7
|
+
const id_1 = require("../util/id");
|
|
8
8
|
const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
9
9
|
const DEC_ID_RE = /^dec-[0-9]+$/;
|
|
10
10
|
exports.WORK_TYPES = new Set(["epic", "feat", "task", "bug", "checkpoint", "test"]);
|
|
@@ -23,6 +23,7 @@ exports.ALLOWED_TYPES = new Set([
|
|
|
23
23
|
"test",
|
|
24
24
|
]);
|
|
25
25
|
const DEC_STATUS = new Set(["proposed", "accepted", "rejected", "superseded"]);
|
|
26
|
+
const SKILL_SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
26
27
|
function formatError(filePath, message) {
|
|
27
28
|
return new Error(`${filePath}: ${message}`);
|
|
28
29
|
}
|
|
@@ -74,11 +75,11 @@ function requireLowercaseList(values, key, filePath) {
|
|
|
74
75
|
});
|
|
75
76
|
}
|
|
76
77
|
function isValidId(value) {
|
|
77
|
-
return
|
|
78
|
+
return (0, id_1.isCanonicalId)(value);
|
|
78
79
|
}
|
|
79
80
|
function requireIdFormat(value, key, filePath) {
|
|
80
81
|
if (!isValidId(value)) {
|
|
81
|
-
throw formatError(filePath, `${key} must match <prefix>-<number
|
|
82
|
+
throw formatError(filePath, `${key} must match <prefix>-<number> or reserved id`);
|
|
82
83
|
}
|
|
83
84
|
return value;
|
|
84
85
|
}
|
|
@@ -104,11 +105,20 @@ function normalizeIdList(values, key, filePath) {
|
|
|
104
105
|
throw formatError(filePath, `${key} entries must be lowercase`);
|
|
105
106
|
}
|
|
106
107
|
if (!isValidId(value)) {
|
|
107
|
-
throw formatError(filePath, `${key} entries must match <prefix>-<number
|
|
108
|
+
throw formatError(filePath, `${key} entries must match <prefix>-<number> or reserved id`);
|
|
108
109
|
}
|
|
109
110
|
return value;
|
|
110
111
|
});
|
|
111
112
|
}
|
|
113
|
+
function normalizeSkillList(values, filePath) {
|
|
114
|
+
return values.map((value, index) => {
|
|
115
|
+
const normalized = value.toLowerCase();
|
|
116
|
+
if (!SKILL_SLUG_RE.test(normalized)) {
|
|
117
|
+
throw formatError(filePath, `skills[${index}] must be kebab-case`);
|
|
118
|
+
}
|
|
119
|
+
return normalized;
|
|
120
|
+
});
|
|
121
|
+
}
|
|
112
122
|
function requireTemplateSchema(type, templateSchemas, filePath) {
|
|
113
123
|
const schema = templateSchemas[type];
|
|
114
124
|
if (!schema) {
|
|
@@ -192,6 +202,11 @@ function parseNode(content, filePath, options) {
|
|
|
192
202
|
const artifacts = optionalList(frontmatter, "artifacts", filePath);
|
|
193
203
|
const refs = normalizeIdList(optionalList(frontmatter, "refs", filePath), "refs", filePath);
|
|
194
204
|
const aliases = requireLowercaseList(optionalList(frontmatter, "aliases", filePath), "aliases", filePath);
|
|
205
|
+
const skillsRaw = optionalList(frontmatter, "skills", filePath);
|
|
206
|
+
const skills = normalizeSkillList(skillsRaw, filePath);
|
|
207
|
+
if (skills.length > 0 && !exports.WORK_TYPES.has(type)) {
|
|
208
|
+
throw formatError(filePath, "skills is only allowed for work items");
|
|
209
|
+
}
|
|
195
210
|
normalizeIdList(optionalList(frontmatter, "scope", filePath), "scope", filePath);
|
|
196
211
|
const supersedesValue = optionalString(frontmatter, "supersedes", filePath);
|
|
197
212
|
if (supersedesValue !== undefined) {
|
|
@@ -218,6 +233,7 @@ function parseNode(content, filePath, options) {
|
|
|
218
233
|
artifacts,
|
|
219
234
|
refs,
|
|
220
235
|
aliases,
|
|
236
|
+
skills,
|
|
221
237
|
edges,
|
|
222
238
|
body,
|
|
223
239
|
frontmatter,
|
|
@@ -0,0 +1,94 @@
|
|
|
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.writeSkillsIndex = writeSkillsIndex;
|
|
7
|
+
exports.loadSkillsIndex = loadSkillsIndex;
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const paths_1 = require("../core/paths");
|
|
11
|
+
const skills_indexer_1 = require("./skills_indexer");
|
|
12
|
+
function mtimeMs(filePath) {
|
|
13
|
+
return fs_1.default.statSync(filePath).mtimeMs;
|
|
14
|
+
}
|
|
15
|
+
function listFilesAndDirectories(dir) {
|
|
16
|
+
if (!fs_1.default.existsSync(dir)) {
|
|
17
|
+
return [];
|
|
18
|
+
}
|
|
19
|
+
const entries = fs_1.default.readdirSync(dir, { withFileTypes: true });
|
|
20
|
+
const items = [dir];
|
|
21
|
+
for (const entry of entries) {
|
|
22
|
+
const fullPath = path_1.default.join(dir, entry.name);
|
|
23
|
+
if (entry.isDirectory()) {
|
|
24
|
+
items.push(...listFilesAndDirectories(fullPath));
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (entry.isFile()) {
|
|
28
|
+
items.push(fullPath);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return items;
|
|
32
|
+
}
|
|
33
|
+
function isSkillsIndexStale(root, config) {
|
|
34
|
+
const indexPath = (0, skills_indexer_1.resolveSkillsIndexPath)(root);
|
|
35
|
+
if (!fs_1.default.existsSync(indexPath)) {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
const indexMtime = mtimeMs(indexPath);
|
|
39
|
+
const cfgPath = (0, paths_1.configPath)(root);
|
|
40
|
+
if (fs_1.default.existsSync(cfgPath) && mtimeMs(cfgPath) > indexMtime) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
const skillsRoot = (0, skills_indexer_1.resolveSkillsRoot)(root, config);
|
|
44
|
+
for (const item of listFilesAndDirectories(skillsRoot)) {
|
|
45
|
+
if (mtimeMs(item) > indexMtime) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
function readSkillsIndex(indexPath) {
|
|
52
|
+
try {
|
|
53
|
+
const raw = fs_1.default.readFileSync(indexPath, "utf8");
|
|
54
|
+
return JSON.parse(raw);
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
const message = err instanceof Error ? err.message : "unknown error";
|
|
58
|
+
throw new Error(`failed to read skills index: ${message}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function writeSkillsIndex(indexPath, index) {
|
|
62
|
+
const sortedSkills = {};
|
|
63
|
+
for (const slug of Object.keys(index.skills).sort()) {
|
|
64
|
+
sortedSkills[slug] = index.skills[slug];
|
|
65
|
+
}
|
|
66
|
+
const sortedIndex = {
|
|
67
|
+
...index,
|
|
68
|
+
skills: sortedSkills,
|
|
69
|
+
};
|
|
70
|
+
fs_1.default.mkdirSync(path_1.default.dirname(indexPath), { recursive: true });
|
|
71
|
+
fs_1.default.writeFileSync(indexPath, JSON.stringify(sortedIndex, null, 2), "utf8");
|
|
72
|
+
}
|
|
73
|
+
function loadSkillsIndex(options) {
|
|
74
|
+
const useCache = options.useCache ?? true;
|
|
75
|
+
const allowReindex = options.allowReindex ?? options.config.index.auto_reindex;
|
|
76
|
+
const indexPath = (0, skills_indexer_1.resolveSkillsIndexPath)(options.root);
|
|
77
|
+
if (!useCache) {
|
|
78
|
+
const index = (0, skills_indexer_1.buildSkillsIndex)(options.root, options.config);
|
|
79
|
+
return { index, rebuilt: true, stale: false };
|
|
80
|
+
}
|
|
81
|
+
const stale = isSkillsIndexStale(options.root, options.config);
|
|
82
|
+
if (fs_1.default.existsSync(indexPath) && !stale) {
|
|
83
|
+
return { index: readSkillsIndex(indexPath), rebuilt: false, stale: false };
|
|
84
|
+
}
|
|
85
|
+
if (allowReindex) {
|
|
86
|
+
const index = (0, skills_indexer_1.buildSkillsIndex)(options.root, options.config);
|
|
87
|
+
writeSkillsIndex(indexPath, index);
|
|
88
|
+
return { index, rebuilt: true, stale };
|
|
89
|
+
}
|
|
90
|
+
if (fs_1.default.existsSync(indexPath)) {
|
|
91
|
+
return { index: readSkillsIndex(indexPath), rebuilt: false, stale: true };
|
|
92
|
+
}
|
|
93
|
+
throw new Error("skills index missing and auto-reindex is disabled");
|
|
94
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
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.SKILL_SLUG_RE = exports.SKILLS_INDEX_RELATIVE_PATH = void 0;
|
|
7
|
+
exports.resolveSkillsRoot = resolveSkillsRoot;
|
|
8
|
+
exports.resolveSkillsIndexPath = resolveSkillsIndexPath;
|
|
9
|
+
exports.buildSkillIndexEntry = buildSkillIndexEntry;
|
|
10
|
+
exports.buildSkillsIndex = buildSkillsIndex;
|
|
11
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const frontmatter_1 = require("./frontmatter");
|
|
14
|
+
exports.SKILLS_INDEX_RELATIVE_PATH = ".mdkg/index/skills.json";
|
|
15
|
+
exports.SKILL_SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
16
|
+
function listSkillMarkdownFiles(dir) {
|
|
17
|
+
if (!fs_1.default.existsSync(dir)) {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
const entries = fs_1.default.readdirSync(dir, { withFileTypes: true });
|
|
21
|
+
const files = [];
|
|
22
|
+
for (const entry of entries) {
|
|
23
|
+
if (!entry.isDirectory()) {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
const slug = entry.name.toLowerCase();
|
|
27
|
+
const skillDir = path_1.default.join(dir, entry.name);
|
|
28
|
+
const canonicalPath = path_1.default.join(skillDir, "SKILL.md");
|
|
29
|
+
const compatPath = path_1.default.join(skillDir, "SKILLS.md");
|
|
30
|
+
if (fs_1.default.existsSync(canonicalPath) && fs_1.default.existsSync(compatPath)) {
|
|
31
|
+
throw new Error(`${skillDir}: both SKILL.md and SKILLS.md exist`);
|
|
32
|
+
}
|
|
33
|
+
if (fs_1.default.existsSync(canonicalPath)) {
|
|
34
|
+
files.push({ slug, filePath: canonicalPath });
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (fs_1.default.existsSync(compatPath)) {
|
|
38
|
+
files.push({ slug, filePath: compatPath });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
files.sort((a, b) => a.slug.localeCompare(b.slug));
|
|
42
|
+
return files;
|
|
43
|
+
}
|
|
44
|
+
function requireString(frontmatter, key, filePath) {
|
|
45
|
+
const value = frontmatter[key];
|
|
46
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
47
|
+
throw new Error(`${filePath}: ${key} is required and must be a non-empty string`);
|
|
48
|
+
}
|
|
49
|
+
return value;
|
|
50
|
+
}
|
|
51
|
+
function optionalString(frontmatter, key, filePath) {
|
|
52
|
+
const value = frontmatter[key];
|
|
53
|
+
if (value === undefined) {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
57
|
+
throw new Error(`${filePath}: ${key} must be a non-empty string when set`);
|
|
58
|
+
}
|
|
59
|
+
return value;
|
|
60
|
+
}
|
|
61
|
+
function optionalList(frontmatter, key, filePath) {
|
|
62
|
+
const value = frontmatter[key];
|
|
63
|
+
if (value === undefined) {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
if (!Array.isArray(value)) {
|
|
67
|
+
throw new Error(`${filePath}: ${key} must be a list`);
|
|
68
|
+
}
|
|
69
|
+
return value;
|
|
70
|
+
}
|
|
71
|
+
function toLowercaseList(values) {
|
|
72
|
+
return values.map((value) => value.toLowerCase());
|
|
73
|
+
}
|
|
74
|
+
function extractOchatr(frontmatter) {
|
|
75
|
+
const keys = Object.keys(frontmatter)
|
|
76
|
+
.filter((key) => key.startsWith("ochatr_"))
|
|
77
|
+
.sort();
|
|
78
|
+
const extracted = {};
|
|
79
|
+
for (const key of keys) {
|
|
80
|
+
extracted[key] = frontmatter[key];
|
|
81
|
+
}
|
|
82
|
+
return extracted;
|
|
83
|
+
}
|
|
84
|
+
function hasDirectory(dirPath) {
|
|
85
|
+
if (!fs_1.default.existsSync(dirPath)) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
return fs_1.default.statSync(dirPath).isDirectory();
|
|
89
|
+
}
|
|
90
|
+
function rootWorkspaceMdkgPath(root, config) {
|
|
91
|
+
const rootWs = config.workspaces.root;
|
|
92
|
+
if (rootWs && rootWs.enabled) {
|
|
93
|
+
return path_1.default.resolve(root, rootWs.path, rootWs.mdkg_dir);
|
|
94
|
+
}
|
|
95
|
+
return path_1.default.resolve(root, ".mdkg");
|
|
96
|
+
}
|
|
97
|
+
function resolveSkillsRoot(root, config) {
|
|
98
|
+
return path_1.default.join(rootWorkspaceMdkgPath(root, config), "skills");
|
|
99
|
+
}
|
|
100
|
+
function resolveSkillsIndexPath(root) {
|
|
101
|
+
return path_1.default.resolve(root, exports.SKILLS_INDEX_RELATIVE_PATH);
|
|
102
|
+
}
|
|
103
|
+
function buildSkillIndexEntry(root, slug, filePath) {
|
|
104
|
+
if (!exports.SKILL_SLUG_RE.test(slug)) {
|
|
105
|
+
throw new Error(`${filePath}: skill slug must be kebab-case`);
|
|
106
|
+
}
|
|
107
|
+
const content = fs_1.default.readFileSync(filePath, "utf8");
|
|
108
|
+
const { frontmatter } = (0, frontmatter_1.parseFrontmatter)(content, filePath);
|
|
109
|
+
const name = requireString(frontmatter, "name", filePath);
|
|
110
|
+
const description = requireString(frontmatter, "description", filePath);
|
|
111
|
+
const version = optionalString(frontmatter, "version", filePath);
|
|
112
|
+
const tags = toLowercaseList(optionalList(frontmatter, "tags", filePath));
|
|
113
|
+
const authors = toLowercaseList(optionalList(frontmatter, "authors", filePath));
|
|
114
|
+
const links = optionalList(frontmatter, "links", filePath);
|
|
115
|
+
const skillDir = path_1.default.dirname(filePath);
|
|
116
|
+
return {
|
|
117
|
+
slug,
|
|
118
|
+
id: `skill:${slug}`,
|
|
119
|
+
qid: `root:skill:${slug}`,
|
|
120
|
+
ws: "root",
|
|
121
|
+
type: "skill",
|
|
122
|
+
name,
|
|
123
|
+
description,
|
|
124
|
+
tags,
|
|
125
|
+
version,
|
|
126
|
+
authors,
|
|
127
|
+
links,
|
|
128
|
+
path: path_1.default.relative(root, filePath),
|
|
129
|
+
has_scripts: hasDirectory(path_1.default.join(skillDir, "scripts")),
|
|
130
|
+
has_references: hasDirectory(path_1.default.join(skillDir, "references")),
|
|
131
|
+
ochatr: extractOchatr(frontmatter),
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function buildSkillsIndex(root, config) {
|
|
135
|
+
const skillsRoot = resolveSkillsRoot(root, config);
|
|
136
|
+
const files = listSkillMarkdownFiles(skillsRoot);
|
|
137
|
+
const skills = {};
|
|
138
|
+
for (const file of files) {
|
|
139
|
+
const { slug, filePath } = file;
|
|
140
|
+
if (skills[slug]) {
|
|
141
|
+
throw new Error(`${filePath}: duplicate skill slug ${slug}`);
|
|
142
|
+
}
|
|
143
|
+
skills[slug] = buildSkillIndexEntry(root, slug, filePath);
|
|
144
|
+
}
|
|
145
|
+
const sortedSkills = {};
|
|
146
|
+
for (const slug of Object.keys(skills).sort()) {
|
|
147
|
+
sortedSkills[slug] = skills[slug];
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
meta: {
|
|
151
|
+
tool: config.tool,
|
|
152
|
+
schema_version: config.schema_version,
|
|
153
|
+
generated_at: new Date().toISOString(),
|
|
154
|
+
root,
|
|
155
|
+
skills_root: path_1.default.relative(root, skillsRoot),
|
|
156
|
+
skill_count: Object.keys(sortedSkills).length,
|
|
157
|
+
},
|
|
158
|
+
skills: sortedSkills,
|
|
159
|
+
};
|
|
160
|
+
}
|
package/dist/init/AGENTS.md
CHANGED
|
@@ -1,43 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# AGENTS
|
|
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
|
-
## 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
|
|
@@ -0,0 +1,46 @@
|
|
|
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 over hand-editing routine work-state changes.
|
|
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 in 0.0.5.
|
|
46
|
+
- If events are disabled, `mdkg task start` and `mdkg task done` will remind you how to enable JSONL provenance.
|
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?
|