mdkg 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +79 -0
- package/README.md +105 -14
- package/dist/cli.js +564 -15
- package/dist/commands/archive.js +474 -0
- package/dist/commands/bundle.js +743 -0
- package/dist/commands/bundle_import.js +243 -0
- package/dist/commands/capability.js +162 -0
- package/dist/commands/doctor.js +223 -0
- package/dist/commands/format.js +38 -9
- package/dist/commands/index.js +11 -0
- package/dist/commands/init.js +188 -63
- package/dist/commands/init_manifest.js +19 -6
- package/dist/commands/list.js +5 -2
- package/dist/commands/new.js +3 -0
- package/dist/commands/next.js +7 -0
- package/dist/commands/node_card.js +4 -1
- package/dist/commands/pack.js +62 -2
- package/dist/commands/query_output.js +1 -0
- package/dist/commands/search.js +5 -2
- package/dist/commands/show.js +7 -14
- package/dist/commands/skill_mirror.js +22 -0
- package/dist/commands/task.js +3 -0
- package/dist/commands/upgrade.js +24 -1
- package/dist/commands/validate.js +14 -1
- package/dist/commands/work.js +365 -0
- package/dist/commands/workspace.js +12 -2
- package/dist/core/config.js +100 -1
- package/dist/graph/agent_file_types.js +78 -5
- package/dist/graph/archive_file.js +125 -0
- package/dist/graph/archive_integrity.js +66 -0
- package/dist/graph/bundle_imports.js +418 -0
- package/dist/graph/capabilities_index_cache.js +103 -0
- package/dist/graph/capabilities_indexer.js +231 -0
- package/dist/graph/frontmatter.js +19 -0
- package/dist/graph/index_cache.js +21 -4
- package/dist/graph/indexer.js +4 -1
- package/dist/graph/node.js +23 -4
- package/dist/graph/node_body.js +37 -0
- package/dist/graph/skills_indexer.js +8 -3
- package/dist/graph/validate_graph.js +83 -7
- package/dist/graph/visibility.js +214 -0
- package/dist/graph/workspace_files.js +22 -0
- package/dist/init/AGENT_START.md +21 -0
- package/dist/init/CLI_COMMAND_MATRIX.md +56 -3
- package/dist/init/README.md +59 -2
- package/dist/init/config.json +13 -1
- package/dist/init/core/guide.md +6 -2
- package/dist/init/core/rule-3-cli-contract.md +71 -4
- package/dist/init/core/rule-4-repo-safety-and-ignores.md +20 -0
- package/dist/init/core/rule-6-templates-and-schemas.md +7 -0
- package/dist/init/init-manifest.json +19 -14
- package/dist/init/skills/default/build-pack-and-execute-task/SKILL.md +2 -1
- package/dist/init/skills/default/verify-close-and-checkpoint/SKILL.md +26 -0
- package/dist/init/templates/default/archive.md +33 -0
- package/dist/init/templates/default/receipt.md +15 -1
- package/dist/init/templates/default/work.md +6 -1
- package/dist/init/templates/default/work_order.md +15 -1
- package/dist/pack/export_md.js +3 -0
- package/dist/pack/export_xml.js +3 -0
- package/dist/pack/order.js +1 -0
- package/dist/pack/pack.js +3 -13
- package/dist/util/argparse.js +30 -0
- package/dist/util/refs.js +40 -0
- package/dist/util/zip.js +153 -0
- package/package.json +8 -2
package/dist/commands/format.js
CHANGED
|
@@ -10,16 +10,34 @@ const config_1 = require("../core/config");
|
|
|
10
10
|
const frontmatter_1 = require("../graph/frontmatter");
|
|
11
11
|
const template_schema_1 = require("../graph/template_schema");
|
|
12
12
|
const node_1 = require("../graph/node");
|
|
13
|
+
const agent_file_types_1 = require("../graph/agent_file_types");
|
|
14
|
+
const archive_file_1 = require("../graph/archive_file");
|
|
13
15
|
const workspace_files_1 = require("../graph/workspace_files");
|
|
14
16
|
const errors_1 = require("../util/errors");
|
|
15
17
|
const date_1 = require("../util/date");
|
|
16
18
|
const id_1 = require("../util/id");
|
|
19
|
+
const refs_1 = require("../util/refs");
|
|
17
20
|
const DEC_ID_RE = /^dec-[0-9]+$/;
|
|
18
21
|
const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
19
22
|
const ID_LIST_KEYS = new Set(["refs", "scope"]);
|
|
20
23
|
const ID_REF_LIST_KEYS = new Set(["relates", "blocked_by", "blocks"]);
|
|
21
24
|
const ID_REF_SCALAR_KEYS = new Set(["epic", "parent", "prev", "next"]);
|
|
22
|
-
const PRESERVE_CASE_LIST_KEYS = new Set([
|
|
25
|
+
const PRESERVE_CASE_LIST_KEYS = new Set([
|
|
26
|
+
"links",
|
|
27
|
+
"artifacts",
|
|
28
|
+
"work_contracts",
|
|
29
|
+
"input_refs",
|
|
30
|
+
"constraint_refs",
|
|
31
|
+
"proof_refs",
|
|
32
|
+
"attestation_refs",
|
|
33
|
+
]);
|
|
34
|
+
const EXTERNAL_REF_LIST_KEYS = new Set([
|
|
35
|
+
"input_refs",
|
|
36
|
+
"constraint_refs",
|
|
37
|
+
"proof_refs",
|
|
38
|
+
"attestation_refs",
|
|
39
|
+
]);
|
|
40
|
+
const HASH_REF_LIST_KEYS = new Set(["input_hashes", "output_hashes"]);
|
|
23
41
|
function isValidId(value) {
|
|
24
42
|
return (0, id_1.isCanonicalId)(value);
|
|
25
43
|
}
|
|
@@ -48,7 +66,7 @@ function sortList(values) {
|
|
|
48
66
|
return 0;
|
|
49
67
|
});
|
|
50
68
|
}
|
|
51
|
-
function normalizeList(values, key, errors, filePath) {
|
|
69
|
+
function normalizeList(values, key, errors, filePath, allowPortableRefs = false) {
|
|
52
70
|
const trimmed = values.map((value) => normalizeScalar(value));
|
|
53
71
|
const shouldLowercase = !PRESERVE_CASE_LIST_KEYS.has(key);
|
|
54
72
|
const normalized = shouldLowercase ? trimmed.map((value) => value.toLowerCase()) : trimmed;
|
|
@@ -57,12 +75,18 @@ function normalizeList(values, key, errors, filePath) {
|
|
|
57
75
|
errors.push(`${filePath}: ${key} entries must be non-empty`);
|
|
58
76
|
continue;
|
|
59
77
|
}
|
|
60
|
-
if (ID_LIST_KEYS.has(key) && !isValidId(entry)) {
|
|
78
|
+
if (ID_LIST_KEYS.has(key) && !(allowPortableRefs ? (0, id_1.isPortableId)(entry) : isValidId(entry))) {
|
|
61
79
|
errors.push(`${filePath}: ${key} entries must match <prefix>-<number> or reserved id`);
|
|
62
80
|
}
|
|
63
|
-
if (ID_REF_LIST_KEYS.has(key) && !(0, id_1.isCanonicalIdRef)(entry)) {
|
|
81
|
+
if (ID_REF_LIST_KEYS.has(key) && !(allowPortableRefs ? (0, id_1.isPortableIdRef)(entry) : (0, id_1.isCanonicalIdRef)(entry))) {
|
|
64
82
|
errors.push(`${filePath}: ${key} entries must be valid id references`);
|
|
65
83
|
}
|
|
84
|
+
if (EXTERNAL_REF_LIST_KEYS.has(key) && !(0, refs_1.validatePortableOrUriRef)(entry)) {
|
|
85
|
+
errors.push(`${filePath}: ${key} entries must be portable ids or URI refs`);
|
|
86
|
+
}
|
|
87
|
+
if (HASH_REF_LIST_KEYS.has(key) && !(0, refs_1.isSha256Ref)(entry)) {
|
|
88
|
+
errors.push(`${filePath}: ${key} entries must be sha256:<64 lowercase hex chars>`);
|
|
89
|
+
}
|
|
66
90
|
}
|
|
67
91
|
return sortList(normalized);
|
|
68
92
|
}
|
|
@@ -73,14 +97,15 @@ function normalizeIdRef(value, key, errors, filePath) {
|
|
|
73
97
|
}
|
|
74
98
|
return normalized;
|
|
75
99
|
}
|
|
76
|
-
function normalizeFrontmatterValue(key, value, schema, errors, filePath) {
|
|
100
|
+
function normalizeFrontmatterValue(key, value, schema, errors, filePath, type) {
|
|
77
101
|
const expected = schema.keyKinds[key];
|
|
78
102
|
if (expected === "list") {
|
|
79
103
|
if (!Array.isArray(value)) {
|
|
80
104
|
errors.push(`${filePath}: ${key} must be a list`);
|
|
81
105
|
return [];
|
|
82
106
|
}
|
|
83
|
-
|
|
107
|
+
const allowPortableRefs = (0, agent_file_types_1.isAgentFileType)(type) || (0, archive_file_1.isArchiveType)(type);
|
|
108
|
+
return normalizeList(value, key, errors, filePath, allowPortableRefs);
|
|
84
109
|
}
|
|
85
110
|
if (expected === "boolean") {
|
|
86
111
|
if (typeof value !== "boolean") {
|
|
@@ -111,7 +136,7 @@ function normalizeFrontmatter(frontmatter, schema, type, workStatusEnum, priorit
|
|
|
111
136
|
}
|
|
112
137
|
continue;
|
|
113
138
|
}
|
|
114
|
-
const normalizedValue = normalizeFrontmatterValue(key, value, schema, errors, filePath);
|
|
139
|
+
const normalizedValue = normalizeFrontmatterValue(key, value, schema, errors, filePath, type);
|
|
115
140
|
if (normalizedValue !== undefined) {
|
|
116
141
|
normalized[key] = normalizedValue;
|
|
117
142
|
}
|
|
@@ -122,8 +147,12 @@ function normalizeFrontmatter(frontmatter, schema, type, workStatusEnum, priorit
|
|
|
122
147
|
}
|
|
123
148
|
else {
|
|
124
149
|
const normalizedId = idValue.toLowerCase();
|
|
125
|
-
|
|
126
|
-
|
|
150
|
+
const allowPortableId = (0, agent_file_types_1.isAgentFileType)(type) || (0, archive_file_1.isArchiveType)(type);
|
|
151
|
+
if (!(allowPortableId ? (0, id_1.isPortableId)(normalizedId) : isValidId(normalizedId))) {
|
|
152
|
+
const requirement = allowPortableId
|
|
153
|
+
? "<prefix>-<number>, reserved id, or allowed portable id"
|
|
154
|
+
: "<prefix>-<number> or reserved id";
|
|
155
|
+
errors.push(`${filePath}: id must match ${requirement}`);
|
|
127
156
|
}
|
|
128
157
|
normalized.id = normalizedId;
|
|
129
158
|
}
|
package/dist/commands/index.js
CHANGED
|
@@ -10,14 +10,25 @@ const indexer_1 = require("../graph/indexer");
|
|
|
10
10
|
const index_cache_1 = require("../graph/index_cache");
|
|
11
11
|
const skills_index_cache_1 = require("../graph/skills_index_cache");
|
|
12
12
|
const skills_indexer_1 = require("../graph/skills_indexer");
|
|
13
|
+
const capabilities_indexer_1 = require("../graph/capabilities_indexer");
|
|
14
|
+
const capabilities_index_cache_1 = require("../graph/capabilities_index_cache");
|
|
15
|
+
const bundle_imports_1 = require("../graph/bundle_imports");
|
|
13
16
|
function runIndexCommand(options) {
|
|
14
17
|
const config = (0, config_1.loadConfig)(options.root);
|
|
15
18
|
const nodeIndex = (0, indexer_1.buildIndex)(options.root, config, { tolerant: options.tolerant });
|
|
16
19
|
const skillsIndex = (0, skills_indexer_1.buildSkillsIndex)(options.root, config);
|
|
20
|
+
const capabilitiesIndex = (0, capabilities_indexer_1.buildCapabilitiesIndex)(options.root, config, nodeIndex);
|
|
21
|
+
const importsIndex = (0, bundle_imports_1.buildBundleImportsIndex)(options.root, config);
|
|
17
22
|
const nodesOutputPath = path_1.default.resolve(options.root, config.index.global_index_path);
|
|
18
23
|
const skillsOutputPath = (0, skills_indexer_1.resolveSkillsIndexPath)(options.root);
|
|
24
|
+
const capabilitiesOutputPath = (0, capabilities_indexer_1.resolveCapabilitiesIndexPath)(options.root, config);
|
|
25
|
+
const importsOutputPath = (0, bundle_imports_1.resolveBundleImportsIndexPath)(options.root);
|
|
19
26
|
(0, index_cache_1.writeIndex)(nodesOutputPath, nodeIndex);
|
|
20
27
|
(0, skills_index_cache_1.writeSkillsIndex)(skillsOutputPath, skillsIndex);
|
|
28
|
+
(0, capabilities_index_cache_1.writeCapabilitiesIndex)(capabilitiesOutputPath, capabilitiesIndex);
|
|
29
|
+
(0, bundle_imports_1.writeBundleImportsIndex)(importsOutputPath, importsIndex.index);
|
|
21
30
|
console.log(`index written: ${path_1.default.relative(options.root, nodesOutputPath)}`);
|
|
22
31
|
console.log(`skills index written: ${path_1.default.relative(options.root, skillsOutputPath)}`);
|
|
32
|
+
console.log(`capabilities index written: ${path_1.default.relative(options.root, capabilitiesOutputPath)}`);
|
|
33
|
+
console.log(`bundle imports index written: ${path_1.default.relative(options.root, importsOutputPath)}`);
|
|
23
34
|
}
|
package/dist/commands/init.js
CHANGED
|
@@ -7,6 +7,7 @@ exports.runInitCommand = runInitCommand;
|
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const config_1 = require("../core/config");
|
|
10
|
+
const migrate_1 = require("../core/migrate");
|
|
10
11
|
const errors_1 = require("../util/errors");
|
|
11
12
|
const date_1 = require("../util/date");
|
|
12
13
|
const version_1 = require("../core/version");
|
|
@@ -39,16 +40,28 @@ function listFiles(dir) {
|
|
|
39
40
|
}
|
|
40
41
|
return files;
|
|
41
42
|
}
|
|
42
|
-
function
|
|
43
|
+
function displayPath(root, filePath) {
|
|
44
|
+
const relPath = path_1.default.relative(root, filePath).split(path_1.default.sep).join("/");
|
|
45
|
+
return relPath.length > 0 ? relPath : ".";
|
|
46
|
+
}
|
|
47
|
+
function recordCreated(root, dest, stats) {
|
|
48
|
+
stats.created += 1;
|
|
49
|
+
stats.createdPaths.push(displayPath(root, dest));
|
|
50
|
+
}
|
|
51
|
+
function recordSkipped(root, dest, stats) {
|
|
52
|
+
stats.skipped += 1;
|
|
53
|
+
stats.skippedPaths.push(displayPath(root, dest));
|
|
54
|
+
}
|
|
55
|
+
function copySeedFile(root, src, dest, force, stats) {
|
|
43
56
|
if (fs_1.default.existsSync(dest) && !force) {
|
|
44
|
-
|
|
57
|
+
recordSkipped(root, dest, stats);
|
|
45
58
|
return;
|
|
46
59
|
}
|
|
47
60
|
fs_1.default.mkdirSync(path_1.default.dirname(dest), { recursive: true });
|
|
48
61
|
fs_1.default.copyFileSync(src, dest);
|
|
49
|
-
|
|
62
|
+
recordCreated(root, dest, stats);
|
|
50
63
|
}
|
|
51
|
-
function copySeedDir(srcDir, destDir, force, stats) {
|
|
64
|
+
function copySeedDir(root, srcDir, destDir, force, stats) {
|
|
52
65
|
if (!fs_1.default.existsSync(srcDir)) {
|
|
53
66
|
return;
|
|
54
67
|
}
|
|
@@ -56,7 +69,7 @@ function copySeedDir(srcDir, destDir, force, stats) {
|
|
|
56
69
|
for (const filePath of files) {
|
|
57
70
|
const relPath = path_1.default.relative(srcDir, filePath);
|
|
58
71
|
const destPath = path_1.default.join(destDir, relPath);
|
|
59
|
-
copySeedFile(filePath, destPath, force, stats);
|
|
72
|
+
copySeedFile(root, filePath, destPath, force, stats);
|
|
60
73
|
}
|
|
61
74
|
}
|
|
62
75
|
function appendIgnoreEntries(filePath, entries) {
|
|
@@ -73,14 +86,14 @@ function appendIgnoreEntries(filePath, entries) {
|
|
|
73
86
|
fs_1.default.writeFileSync(filePath, updated, "utf8");
|
|
74
87
|
return true;
|
|
75
88
|
}
|
|
76
|
-
function writeFileIfMissing(filePath, content, force, stats) {
|
|
89
|
+
function writeFileIfMissing(root, filePath, content, force, stats) {
|
|
77
90
|
if (fs_1.default.existsSync(filePath) && !force) {
|
|
78
|
-
|
|
91
|
+
recordSkipped(root, filePath, stats);
|
|
79
92
|
return;
|
|
80
93
|
}
|
|
81
94
|
fs_1.default.mkdirSync(path_1.default.dirname(filePath), { recursive: true });
|
|
82
95
|
fs_1.default.writeFileSync(filePath, content, "utf8");
|
|
83
|
-
|
|
96
|
+
recordCreated(root, filePath, stats);
|
|
84
97
|
}
|
|
85
98
|
function soulTemplate(created) {
|
|
86
99
|
return [
|
|
@@ -176,6 +189,48 @@ function seededInitEvent(nowIso) {
|
|
|
176
189
|
};
|
|
177
190
|
return `${JSON.stringify(event)}\n`;
|
|
178
191
|
}
|
|
192
|
+
function listSeedSkillSlugs(seedDefaultSkills) {
|
|
193
|
+
if (!fs_1.default.existsSync(seedDefaultSkills)) {
|
|
194
|
+
return [];
|
|
195
|
+
}
|
|
196
|
+
return fs_1.default
|
|
197
|
+
.readdirSync(seedDefaultSkills, { withFileTypes: true })
|
|
198
|
+
.filter((entry) => entry.isDirectory() && fs_1.default.existsSync(path_1.default.join(seedDefaultSkills, entry.name, "SKILL.md")))
|
|
199
|
+
.map((entry) => entry.name.toLowerCase())
|
|
200
|
+
.sort();
|
|
201
|
+
}
|
|
202
|
+
function listExistingCanonicalSkillSlugs(root) {
|
|
203
|
+
const skillsDir = path_1.default.join(root, ".mdkg", "skills");
|
|
204
|
+
if (!fs_1.default.existsSync(skillsDir)) {
|
|
205
|
+
return [];
|
|
206
|
+
}
|
|
207
|
+
return fs_1.default
|
|
208
|
+
.readdirSync(skillsDir, { withFileTypes: true })
|
|
209
|
+
.filter((entry) => entry.isDirectory() && fs_1.default.existsSync(path_1.default.join(skillsDir, entry.name, "SKILL.md")))
|
|
210
|
+
.map((entry) => entry.name.toLowerCase())
|
|
211
|
+
.sort();
|
|
212
|
+
}
|
|
213
|
+
function preflightSeedConfig(seedConfig) {
|
|
214
|
+
const raw = JSON.parse(fs_1.default.readFileSync(seedConfig, "utf8"));
|
|
215
|
+
(0, config_1.validateConfigSchema)((0, migrate_1.migrateConfig)(raw).config);
|
|
216
|
+
}
|
|
217
|
+
function emitPartialInitFailure(root, stats, err) {
|
|
218
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
219
|
+
console.error("mdkg init failed after partial writes");
|
|
220
|
+
console.error(`error: ${message}`);
|
|
221
|
+
console.error(`created: ${stats.created}`);
|
|
222
|
+
for (const created of stats.createdPaths) {
|
|
223
|
+
console.error(` created: ${created}`);
|
|
224
|
+
}
|
|
225
|
+
console.error(`skipped: ${stats.skipped}`);
|
|
226
|
+
for (const skipped of stats.skippedPaths) {
|
|
227
|
+
console.error(` skipped: ${skipped}`);
|
|
228
|
+
}
|
|
229
|
+
console.error("recovery:");
|
|
230
|
+
console.error(" inspect the created paths above");
|
|
231
|
+
console.error(" rerun `mdkg init --agent` after resolving the reported error");
|
|
232
|
+
console.error(` root: ${root}`);
|
|
233
|
+
}
|
|
179
234
|
function parseCoreList(raw) {
|
|
180
235
|
const lines = raw.split(/\r?\n/);
|
|
181
236
|
const header = [];
|
|
@@ -224,9 +279,9 @@ function ensureCorePins(coreListPath, requiredPins) {
|
|
|
224
279
|
function runInitCommand(options) {
|
|
225
280
|
const root = path_1.default.resolve(options.root);
|
|
226
281
|
const seedRoot = options.seedRoot ? path_1.default.resolve(options.seedRoot) : DEFAULT_SEED_SUBDIR;
|
|
227
|
-
const createAgents = Boolean(options.
|
|
228
|
-
const createClaude = Boolean(options.
|
|
229
|
-
const createStartupDocs = Boolean(options.
|
|
282
|
+
const createAgents = Boolean(options.agent);
|
|
283
|
+
const createClaude = Boolean(options.agent);
|
|
284
|
+
const createStartupDocs = Boolean(options.agent);
|
|
230
285
|
const force = Boolean(options.force);
|
|
231
286
|
const seedConfig = path_1.default.join(seedRoot, "config.json");
|
|
232
287
|
const seedCore = path_1.default.join(seedRoot, "core");
|
|
@@ -238,7 +293,13 @@ function runInitCommand(options) {
|
|
|
238
293
|
const seedCliMatrix = path_1.default.join(seedRoot, "CLI_COMMAND_MATRIX.md");
|
|
239
294
|
const seedReadme = path_1.default.join(seedRoot, "README.md");
|
|
240
295
|
const seedDefaultSkills = path_1.default.join(seedRoot, "skills", "default");
|
|
241
|
-
const
|
|
296
|
+
const seedSoul = path_1.default.join(seedCore, "SOUL.md");
|
|
297
|
+
const seedHuman = path_1.default.join(seedCore, "HUMAN.md");
|
|
298
|
+
const seedManifest = (0, init_manifest_1.createInitManifest)(seedRoot, (0, version_1.readPackageVersion)(), {
|
|
299
|
+
includeAgentDocs: Boolean(options.agent),
|
|
300
|
+
includeStartupDocs: Boolean(options.agent),
|
|
301
|
+
includeDefaultSkills: Boolean(options.agent),
|
|
302
|
+
});
|
|
242
303
|
if (!fs_1.default.existsSync(seedConfig) || !fs_1.default.existsSync(seedCore) || !fs_1.default.existsSync(seedTemplates)) {
|
|
243
304
|
throw new errors_1.NotFoundError(`init assets not found at ${seedRoot} (try reinstalling mdkg)`);
|
|
244
305
|
}
|
|
@@ -263,67 +324,131 @@ function runInitCommand(options) {
|
|
|
263
324
|
if (options.agent && !fs_1.default.existsSync(seedDefaultSkills)) {
|
|
264
325
|
throw new errors_1.NotFoundError(`init assets missing default skills at ${seedRoot}`);
|
|
265
326
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
copySeedDir(seedCore, path_1.default.join(mdkgDir, "core"), force, stats);
|
|
274
|
-
copySeedDir(seedTemplates, path_1.default.join(mdkgDir, "templates"), force, stats);
|
|
275
|
-
if (createAgents) {
|
|
276
|
-
copySeedFile(seedAgents, path_1.default.join(root, "AGENTS.md"), force, stats);
|
|
277
|
-
}
|
|
278
|
-
if (createClaude) {
|
|
279
|
-
copySeedFile(seedClaude, path_1.default.join(root, "CLAUDE.md"), force, stats);
|
|
327
|
+
preflightSeedConfig(seedConfig);
|
|
328
|
+
if (options.agent) {
|
|
329
|
+
(0, skill_mirror_1.preflightSkillMirrorTargets)({
|
|
330
|
+
root,
|
|
331
|
+
slugs: [...listSeedSkillSlugs(seedDefaultSkills), ...listExistingCanonicalSkillSlugs(root)],
|
|
332
|
+
force,
|
|
333
|
+
});
|
|
280
334
|
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
335
|
+
const stats = {
|
|
336
|
+
created: 0,
|
|
337
|
+
skipped: 0,
|
|
338
|
+
createdPaths: [],
|
|
339
|
+
skippedPaths: [],
|
|
340
|
+
ignoreFilesUpdated: [],
|
|
341
|
+
manifestWritten: false,
|
|
342
|
+
registryRefreshed: false,
|
|
343
|
+
mirrorTargets: 0,
|
|
344
|
+
mirroredSkills: 0,
|
|
345
|
+
};
|
|
346
|
+
const mdkgDir = path_1.default.join(root, ".mdkg");
|
|
347
|
+
try {
|
|
348
|
+
fs_1.default.mkdirSync(mdkgDir, { recursive: true });
|
|
349
|
+
fs_1.default.mkdirSync(path_1.default.join(mdkgDir, "work"), { recursive: true });
|
|
350
|
+
fs_1.default.mkdirSync(path_1.default.join(mdkgDir, "design"), { recursive: true });
|
|
351
|
+
copySeedFile(root, seedConfig, path_1.default.join(mdkgDir, "config.json"), force, stats);
|
|
352
|
+
copySeedFile(root, seedReadme, path_1.default.join(mdkgDir, "README.md"), force, stats);
|
|
353
|
+
copySeedDir(root, seedCore, path_1.default.join(mdkgDir, "core"), force, stats);
|
|
354
|
+
copySeedDir(root, seedTemplates, path_1.default.join(mdkgDir, "templates"), force, stats);
|
|
355
|
+
if (createAgents) {
|
|
356
|
+
copySeedFile(root, seedAgents, path_1.default.join(root, "AGENTS.md"), force, stats);
|
|
357
|
+
}
|
|
358
|
+
if (createClaude) {
|
|
359
|
+
copySeedFile(root, seedClaude, path_1.default.join(root, "CLAUDE.md"), force, stats);
|
|
360
|
+
}
|
|
361
|
+
if (createStartupDocs) {
|
|
362
|
+
copySeedFile(root, seedLlms, path_1.default.join(root, "llms.txt"), force, stats);
|
|
363
|
+
copySeedFile(root, seedAgentStart, path_1.default.join(root, "AGENT_START.md"), force, stats);
|
|
364
|
+
copySeedFile(root, seedCliMatrix, path_1.default.join(root, "CLI_COMMAND_MATRIX.md"), force, stats);
|
|
365
|
+
}
|
|
366
|
+
if (options.agent) {
|
|
367
|
+
const today = (0, date_1.formatDate)(new Date());
|
|
368
|
+
const soulPath = path_1.default.join(mdkgDir, "core", "SOUL.md");
|
|
369
|
+
const humanPath = path_1.default.join(mdkgDir, "core", "HUMAN.md");
|
|
370
|
+
const skillsDir = path_1.default.join(mdkgDir, "skills");
|
|
371
|
+
const registryPath = path_1.default.join(skillsDir, "registry.md");
|
|
372
|
+
const eventsDir = path_1.default.join(mdkgDir, "work", "events");
|
|
373
|
+
const eventsPath = path_1.default.join(eventsDir, "events.jsonl");
|
|
374
|
+
fs_1.default.mkdirSync(skillsDir, { recursive: true });
|
|
375
|
+
fs_1.default.mkdirSync(eventsDir, { recursive: true });
|
|
376
|
+
copySeedDir(root, seedDefaultSkills, skillsDir, force, stats);
|
|
377
|
+
if (!fs_1.default.existsSync(seedSoul)) {
|
|
378
|
+
writeFileIfMissing(root, soulPath, soulTemplate(today), force, stats);
|
|
379
|
+
}
|
|
380
|
+
if (!fs_1.default.existsSync(seedHuman)) {
|
|
381
|
+
writeFileIfMissing(root, humanPath, humanTemplate(today), force, stats);
|
|
382
|
+
}
|
|
383
|
+
writeFileIfMissing(root, registryPath, (0, skill_support_1.registryTemplate)(), force, stats);
|
|
384
|
+
if (!fs_1.default.existsSync(eventsPath) || force) {
|
|
385
|
+
writeFileIfMissing(root, eventsPath, seededInitEvent(new Date().toISOString()), force, stats);
|
|
386
|
+
}
|
|
387
|
+
const coreListPath = path_1.default.join(mdkgDir, "core", "core.md");
|
|
388
|
+
ensureCorePins(coreListPath, [SOUL_PIN_ID, HUMAN_PIN_ID]);
|
|
389
|
+
(0, skill_mirror_1.scaffoldMirrorRoots)(root);
|
|
390
|
+
const config = (0, config_1.loadConfig)(root);
|
|
391
|
+
(0, skill_support_1.refreshSkillsRegistry)(root, config);
|
|
392
|
+
stats.registryRefreshed = true;
|
|
393
|
+
const mirrorResult = (0, skill_mirror_1.syncSkillMirrors)({ root, config, createRoots: true, force });
|
|
394
|
+
stats.mirrorTargets = mirrorResult.targets;
|
|
395
|
+
stats.mirroredSkills = mirrorResult.synced;
|
|
396
|
+
}
|
|
397
|
+
(0, init_manifest_1.writeInitManifest)(path_1.default.join(mdkgDir, init_manifest_1.INIT_MANIFEST_FILE), seedManifest);
|
|
398
|
+
stats.manifestWritten = true;
|
|
285
399
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
const humanPath = path_1.default.join(mdkgDir, "core", "HUMAN.md");
|
|
290
|
-
const skillsDir = path_1.default.join(mdkgDir, "skills");
|
|
291
|
-
const registryPath = path_1.default.join(skillsDir, "registry.md");
|
|
292
|
-
const eventsDir = path_1.default.join(mdkgDir, "work", "events");
|
|
293
|
-
const eventsPath = path_1.default.join(eventsDir, "events.jsonl");
|
|
294
|
-
fs_1.default.mkdirSync(skillsDir, { recursive: true });
|
|
295
|
-
fs_1.default.mkdirSync(eventsDir, { recursive: true });
|
|
296
|
-
copySeedDir(seedDefaultSkills, skillsDir, force, stats);
|
|
297
|
-
writeFileIfMissing(soulPath, soulTemplate(today), force, stats);
|
|
298
|
-
writeFileIfMissing(humanPath, humanTemplate(today), force, stats);
|
|
299
|
-
writeFileIfMissing(registryPath, (0, skill_support_1.registryTemplate)(), force, stats);
|
|
300
|
-
if (!fs_1.default.existsSync(eventsPath) || force) {
|
|
301
|
-
writeFileIfMissing(eventsPath, seededInitEvent(new Date().toISOString()), force, stats);
|
|
400
|
+
catch (err) {
|
|
401
|
+
if (stats.created > 0 || stats.skipped > 0) {
|
|
402
|
+
emitPartialInitFailure(root, stats, err);
|
|
302
403
|
}
|
|
303
|
-
|
|
304
|
-
ensureCorePins(coreListPath, [SOUL_PIN_ID, HUMAN_PIN_ID]);
|
|
305
|
-
(0, skill_mirror_1.scaffoldMirrorRoots)(root);
|
|
306
|
-
const config = (0, config_1.loadConfig)(root);
|
|
307
|
-
(0, skill_support_1.refreshSkillsRegistry)(root, config);
|
|
308
|
-
(0, skill_mirror_1.syncSkillMirrors)({ root, config, createRoots: true, force });
|
|
404
|
+
throw err;
|
|
309
405
|
}
|
|
310
|
-
(0, init_manifest_1.writeInitManifest)(path_1.default.join(mdkgDir, init_manifest_1.INIT_MANIFEST_FILE), seedManifest);
|
|
311
406
|
const noUpdateIgnores = Boolean(options.noUpdateIgnores);
|
|
312
407
|
const shouldUpdateGitignore = Boolean(options.updateGitignore || !noUpdateIgnores);
|
|
313
408
|
const shouldUpdateNpmignore = Boolean(options.updateNpmignore || !noUpdateIgnores);
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
".
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
409
|
+
try {
|
|
410
|
+
if (shouldUpdateGitignore) {
|
|
411
|
+
if (appendIgnoreEntries(path_1.default.join(root, ".gitignore"), [
|
|
412
|
+
".mdkg/index/",
|
|
413
|
+
".mdkg/pack/",
|
|
414
|
+
".mdkg/archive/**/source/",
|
|
415
|
+
])) {
|
|
416
|
+
stats.ignoreFilesUpdated.push(".gitignore");
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
if (shouldUpdateNpmignore) {
|
|
420
|
+
if (appendIgnoreEntries(path_1.default.join(root, ".npmignore"), [".mdkg/", ".mdkg/index/", ".mdkg/pack/"])) {
|
|
421
|
+
stats.ignoreFilesUpdated.push(".npmignore");
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
if (options.updateDockerignore) {
|
|
425
|
+
if (appendIgnoreEntries(path_1.default.join(root, ".dockerignore"), [".mdkg/"])) {
|
|
426
|
+
stats.ignoreFilesUpdated.push(".dockerignore");
|
|
427
|
+
}
|
|
428
|
+
}
|
|
322
429
|
}
|
|
323
|
-
|
|
324
|
-
|
|
430
|
+
catch (err) {
|
|
431
|
+
if (stats.created > 0 || stats.skipped > 0) {
|
|
432
|
+
emitPartialInitFailure(root, stats, err);
|
|
433
|
+
}
|
|
434
|
+
throw err;
|
|
325
435
|
}
|
|
326
436
|
console.log(`mdkg init complete: ${stats.created} file(s) created, ${stats.skipped} skipped`);
|
|
437
|
+
if (stats.manifestWritten) {
|
|
438
|
+
console.log("managed manifest: .mdkg/init-manifest.json");
|
|
439
|
+
}
|
|
440
|
+
if (stats.ignoreFilesUpdated.length > 0) {
|
|
441
|
+
console.log(`ignore files updated: ${stats.ignoreFilesUpdated.join(", ")}`);
|
|
442
|
+
}
|
|
443
|
+
if (options.agent) {
|
|
444
|
+
console.log("agent bootstrap: AGENT_START.md, AGENTS.md, CLAUDE.md, llms.txt, CLI_COMMAND_MATRIX.md");
|
|
445
|
+
console.log("agent core pins: rule-soul, rule-human");
|
|
446
|
+
console.log("agent event log: .mdkg/work/events/events.jsonl");
|
|
447
|
+
console.log(`skill mirrors: ${stats.mirroredSkills} sync operation(s) across ${stats.mirrorTargets} target(s)`);
|
|
448
|
+
if (stats.registryRefreshed) {
|
|
449
|
+
console.log("skill registry: .mdkg/skills/registry.md");
|
|
450
|
+
}
|
|
451
|
+
}
|
|
327
452
|
console.log("next:");
|
|
328
453
|
if (createStartupDocs) {
|
|
329
454
|
console.log(" read AGENT_START.md");
|
|
@@ -83,19 +83,32 @@ function seedSourcePath(seedRoot, file) {
|
|
|
83
83
|
}
|
|
84
84
|
return path_1.default.join(seedRoot, file.path);
|
|
85
85
|
}
|
|
86
|
-
function createInitManifest(seedRoot, mdkgVersion
|
|
86
|
+
function createInitManifest(seedRoot, mdkgVersion, options = {
|
|
87
|
+
includeAgentDocs: true,
|
|
88
|
+
includeStartupDocs: true,
|
|
89
|
+
includeDefaultSkills: true,
|
|
90
|
+
}) {
|
|
91
|
+
const includeAgentDocs = Boolean(options.includeAgentDocs);
|
|
92
|
+
const includeStartupDocs = Boolean(options.includeStartupDocs);
|
|
93
|
+
const includeDefaultSkills = Boolean(options.includeDefaultSkills);
|
|
87
94
|
const files = [];
|
|
88
95
|
addSeedFile(files, seedRoot, "config.json", ".mdkg/config.json", "config");
|
|
89
96
|
addSeedFile(files, seedRoot, "README.md", ".mdkg/README.md", "mdkg_doc");
|
|
90
97
|
addSeedDir(files, seedRoot, "core", ".mdkg/core", "core");
|
|
91
98
|
addSeedDir(files, seedRoot, "templates", ".mdkg/templates", "template");
|
|
92
|
-
|
|
93
|
-
|
|
99
|
+
if (includeAgentDocs) {
|
|
100
|
+
for (const doc of AGENT_DOCS) {
|
|
101
|
+
addSeedFile(files, seedRoot, doc, doc, "agent_doc");
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (includeStartupDocs) {
|
|
105
|
+
for (const doc of STARTUP_DOCS) {
|
|
106
|
+
addSeedFile(files, seedRoot, doc, doc, "startup_doc");
|
|
107
|
+
}
|
|
94
108
|
}
|
|
95
|
-
|
|
96
|
-
|
|
109
|
+
if (includeDefaultSkills) {
|
|
110
|
+
addSeedDir(files, seedRoot, path_1.default.join("skills", "default"), ".mdkg/skills", "default_skill");
|
|
97
111
|
}
|
|
98
|
-
addSeedDir(files, seedRoot, path_1.default.join("skills", "default"), ".mdkg/skills", "default_skill");
|
|
99
112
|
return {
|
|
100
113
|
schema_version: exports.INIT_MANIFEST_SCHEMA_VERSION,
|
|
101
114
|
tool: "mdkg",
|
package/dist/commands/list.js
CHANGED
|
@@ -18,14 +18,14 @@ function normalizeWorkspace(value) {
|
|
|
18
18
|
function runListCommand(options) {
|
|
19
19
|
const config = (0, config_1.loadConfig)(options.root);
|
|
20
20
|
const ws = normalizeWorkspace(options.ws);
|
|
21
|
-
if (ws && !config.workspaces[ws]) {
|
|
21
|
+
if (ws && !config.workspaces[ws] && !config.bundle_imports[ws]) {
|
|
22
22
|
throw new errors_1.NotFoundError(`workspace not found: ${ws}`);
|
|
23
23
|
}
|
|
24
24
|
const normalizedType = options.type?.toLowerCase();
|
|
25
25
|
if (normalizedType === "skill") {
|
|
26
26
|
throw new errors_1.UsageError("--type skill is no longer supported here; use `mdkg skill list`");
|
|
27
27
|
}
|
|
28
|
-
const { index, rebuilt, stale } = (0, index_cache_1.loadIndex)({
|
|
28
|
+
const { index, rebuilt, stale, warnings } = (0, index_cache_1.loadIndex)({
|
|
29
29
|
root: options.root,
|
|
30
30
|
config,
|
|
31
31
|
useCache: !options.noCache,
|
|
@@ -34,6 +34,9 @@ function runListCommand(options) {
|
|
|
34
34
|
if (stale && !rebuilt && !options.noCache) {
|
|
35
35
|
console.error("warning: index is stale; run mdkg index to refresh");
|
|
36
36
|
}
|
|
37
|
+
for (const warning of warnings) {
|
|
38
|
+
console.error(`warning: ${warning}`);
|
|
39
|
+
}
|
|
37
40
|
let epicQid;
|
|
38
41
|
if (options.epic) {
|
|
39
42
|
const resolved = (0, qid_1.resolveQid)(index, options.epic, ws);
|
package/dist/commands/new.js
CHANGED
|
@@ -156,6 +156,9 @@ function runNewCommand(options) {
|
|
|
156
156
|
throw new errors_1.UsageError("title cannot be empty");
|
|
157
157
|
}
|
|
158
158
|
const type = options.type.toLowerCase();
|
|
159
|
+
if (type === "archive") {
|
|
160
|
+
throw new errors_1.UsageError("use `mdkg archive add <file>` to create archive sidecars");
|
|
161
|
+
}
|
|
159
162
|
if (!node_1.ALLOWED_TYPES.has(type)) {
|
|
160
163
|
throw new errors_1.UsageError(`type must be one of ${Array.from(node_1.ALLOWED_TYPES).join(", ")}`);
|
|
161
164
|
}
|
package/dist/commands/next.js
CHANGED
|
@@ -21,6 +21,9 @@ function selectNextByPriority(index, ws, statusPreference, priorityMax) {
|
|
|
21
21
|
if (ws && node.ws !== ws) {
|
|
22
22
|
return false;
|
|
23
23
|
}
|
|
24
|
+
if (node.source?.imported) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
24
27
|
if (!NEXT_TYPES.has(node.type)) {
|
|
25
28
|
return false;
|
|
26
29
|
}
|
|
@@ -59,6 +62,10 @@ function runNextCommand(options) {
|
|
|
59
62
|
throw new errors_1.NotFoundError((0, qid_1.formatResolveError)("id", options.id, resolved, ws));
|
|
60
63
|
}
|
|
61
64
|
const node = index.nodes[resolved.qid];
|
|
65
|
+
if (node.source?.imported) {
|
|
66
|
+
console.error("no local next item: imported bundle nodes are read-only planning context");
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
62
69
|
const nextQid = node.edges.next;
|
|
63
70
|
if (nextQid && index.nodes[nextQid]) {
|
|
64
71
|
console.log((0, node_card_1.formatNodeCard)(index.nodes[nextQid]));
|
|
@@ -7,11 +7,14 @@ function formatStatusPriority(node) {
|
|
|
7
7
|
return `${status}/${priority}`;
|
|
8
8
|
}
|
|
9
9
|
function formatNodeCard(node) {
|
|
10
|
+
const sourceLabel = node.source?.imported
|
|
11
|
+
? ` | import:${node.source.import_alias}${node.source.stale ? ":stale" : ""} | read-only`
|
|
12
|
+
: "";
|
|
10
13
|
return [
|
|
11
14
|
node.qid,
|
|
12
15
|
node.type,
|
|
13
16
|
formatStatusPriority(node),
|
|
14
17
|
node.title,
|
|
15
18
|
node.path,
|
|
16
|
-
].join(" | ");
|
|
19
|
+
].join(" | ") + sourceLabel;
|
|
17
20
|
}
|