mdkg 0.3.7 → 0.3.9
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 +50 -0
- package/CLI_COMMAND_MATRIX.md +85 -24
- package/README.md +51 -26
- package/dist/cli.js +72 -35
- package/dist/command-contract.json +354 -9
- package/dist/commands/capability.js +1 -0
- package/dist/commands/doctor.js +7 -7
- package/dist/commands/format.js +40 -1
- package/dist/commands/handoff.js +6 -0
- package/dist/commands/init.js +84 -3
- package/dist/commands/new.js +12 -3
- package/dist/commands/skill.js +1 -1
- package/dist/commands/skill_mirror.js +22 -17
- package/dist/commands/skill_support.js +1 -1
- package/dist/commands/spec.js +76 -17
- package/dist/commands/subgraph.js +7 -4
- package/dist/commands/upgrade.js +137 -30
- package/dist/commands/validate.js +106 -3
- package/dist/commands/work.js +12 -5
- package/dist/core/config.js +132 -0
- package/dist/graph/agent_file_types.js +59 -20
- package/dist/graph/capabilities_indexer.js +45 -3
- package/dist/graph/indexer.js +5 -0
- package/dist/graph/template_schema.js +37 -17
- package/dist/graph/validate_graph.js +11 -5
- package/dist/init/AGENT_START.md +10 -9
- package/dist/init/CLI_COMMAND_MATRIX.md +30 -17
- package/dist/init/README.md +11 -9
- package/dist/init/config.json +15 -0
- package/dist/init/core/COLLABORATION.md +45 -0
- package/dist/init/core/HUMAN.md +7 -1
- package/dist/init/core/core.md +1 -0
- package/dist/init/core/rule-1-mdkg-conventions.md +3 -0
- package/dist/init/core/rule-3-cli-contract.md +5 -5
- package/dist/init/init-manifest.json +78 -13
- package/dist/init/llms.txt +2 -1
- package/dist/init/skills/default/author-mdkg-skill/SKILL.md +211 -0
- package/dist/init/skills/default/pursue-mdkg-goal/SKILL.md +10 -0
- package/dist/init/skills/default/select-work-and-ground-context/SKILL.md +8 -0
- package/dist/init/skills/default/verify-close-and-checkpoint/SKILL.md +73 -9
- package/dist/init/templates/default/manifest.md +45 -0
- package/dist/init/templates/specs/agent.MANIFEST.md +80 -0
- package/dist/init/templates/specs/api.MANIFEST.md +33 -0
- package/dist/init/templates/specs/base.MANIFEST.md +120 -0
- package/dist/init/templates/specs/capability.MANIFEST.md +45 -0
- package/dist/init/templates/specs/integration.MANIFEST.md +25 -0
- package/dist/init/templates/specs/model.MANIFEST.md +21 -0
- package/dist/init/templates/specs/project.MANIFEST.md +39 -0
- package/dist/init/templates/specs/runtime-agent.MANIFEST.md +49 -0
- package/dist/init/templates/specs/runtime-image.MANIFEST.md +21 -0
- package/dist/init/templates/specs/tool.MANIFEST.md +25 -0
- package/dist/util/argparse.js +3 -0
- package/package.json +19 -3
package/dist/core/config.js
CHANGED
|
@@ -3,6 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DEFAULT_SKILL_MIRROR_TARGETS = void 0;
|
|
7
|
+
exports.defaultCustomizationConfig = defaultCustomizationConfig;
|
|
6
8
|
exports.validateConfigSchema = validateConfigSchema;
|
|
7
9
|
exports.loadConfig = loadConfig;
|
|
8
10
|
const fs_1 = __importDefault(require("fs"));
|
|
@@ -30,6 +32,7 @@ const DEFAULT_ARCHIVE_LARGE_CACHE_WARNING_BYTES = 26214400;
|
|
|
30
32
|
const DEFAULT_SQLITE_COMMIT_WARNING_BYTES = 52428800;
|
|
31
33
|
const DEFAULT_LOCK_TIMEOUT_MS = 10000;
|
|
32
34
|
const DEFAULT_SUBGRAPH_MAX_STALE_SECONDS = 3600;
|
|
35
|
+
exports.DEFAULT_SKILL_MIRROR_TARGETS = [".agents/skills", ".claude/skills"];
|
|
33
36
|
const DEFAULT_PROJECT_DB_CONFIG = {
|
|
34
37
|
enabled: false,
|
|
35
38
|
schema_version: project_db_1.PROJECT_DB_CONFIG_SCHEMA_VERSION,
|
|
@@ -41,6 +44,20 @@ const DEFAULT_PROJECT_DB_CONFIG = {
|
|
|
41
44
|
receipts_path: project_db_1.PROJECT_DB_RECEIPTS_DIR,
|
|
42
45
|
migration_table: project_db_1.PROJECT_DB_MIGRATION_TABLE,
|
|
43
46
|
};
|
|
47
|
+
function defaultCustomizationConfig() {
|
|
48
|
+
return {
|
|
49
|
+
standards: {
|
|
50
|
+
profile: "default",
|
|
51
|
+
refs: [],
|
|
52
|
+
},
|
|
53
|
+
core_docs: {
|
|
54
|
+
custom_paths: [],
|
|
55
|
+
},
|
|
56
|
+
skill_mirrors: {
|
|
57
|
+
targets: [...exports.DEFAULT_SKILL_MIRROR_TARGETS],
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
44
61
|
function isObject(value) {
|
|
45
62
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
46
63
|
}
|
|
@@ -171,6 +188,35 @@ function requireKnownLowercaseUniqueStringArray(value, path, allowed, errors, al
|
|
|
171
188
|
}
|
|
172
189
|
return items;
|
|
173
190
|
}
|
|
191
|
+
function requireUniqueStringArray(value, path, errors, allowEmpty = false) {
|
|
192
|
+
const items = requireStringArray(value, path, errors);
|
|
193
|
+
if (items === undefined) {
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
if (items.length === 0) {
|
|
197
|
+
if (!allowEmpty) {
|
|
198
|
+
errors.push(`${path} must not be empty`);
|
|
199
|
+
}
|
|
200
|
+
return items;
|
|
201
|
+
}
|
|
202
|
+
const seen = new Set();
|
|
203
|
+
for (let i = 0; i < items.length; i += 1) {
|
|
204
|
+
const item = items[i];
|
|
205
|
+
if (item.trim().length === 0) {
|
|
206
|
+
errors.push(`${path}[${i}] must not be empty`);
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
if (item !== item.trim()) {
|
|
210
|
+
errors.push(`${path}[${i}] must not include surrounding whitespace`);
|
|
211
|
+
}
|
|
212
|
+
if (seen.has(item)) {
|
|
213
|
+
errors.push(`${path} must not contain duplicate value "${item}"`);
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
seen.add(item);
|
|
217
|
+
}
|
|
218
|
+
return items;
|
|
219
|
+
}
|
|
174
220
|
function requireObject(value, path, errors) {
|
|
175
221
|
if (!isObject(value)) {
|
|
176
222
|
errors.push(`${path} must be an object`);
|
|
@@ -213,6 +259,33 @@ function requireContainedPath(value, path, errors) {
|
|
|
213
259
|
return undefined;
|
|
214
260
|
}
|
|
215
261
|
}
|
|
262
|
+
function requireContainedPathArray(value, path, errors, allowEmpty = true) {
|
|
263
|
+
if (!Array.isArray(value)) {
|
|
264
|
+
errors.push(`${path} must be an array of relative paths`);
|
|
265
|
+
return undefined;
|
|
266
|
+
}
|
|
267
|
+
if (value.length === 0) {
|
|
268
|
+
if (!allowEmpty) {
|
|
269
|
+
errors.push(`${path} must not be empty`);
|
|
270
|
+
}
|
|
271
|
+
return [];
|
|
272
|
+
}
|
|
273
|
+
const items = [];
|
|
274
|
+
const seen = new Set();
|
|
275
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
276
|
+
const normalized = requireContainedPath(value[i], `${path}[${i}]`, errors);
|
|
277
|
+
if (!normalized) {
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
if (seen.has(normalized)) {
|
|
281
|
+
errors.push(`${path} must not contain duplicate path "${normalized}"`);
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
seen.add(normalized);
|
|
285
|
+
items.push(normalized);
|
|
286
|
+
}
|
|
287
|
+
return items;
|
|
288
|
+
}
|
|
216
289
|
function requireSqlIdentifier(value, path, errors) {
|
|
217
290
|
const raw = requireString(value, path, errors);
|
|
218
291
|
if (raw === undefined) {
|
|
@@ -266,6 +339,10 @@ function validateConfigSchema(raw) {
|
|
|
266
339
|
? { output_dir: ".mdkg/bundles", default_profile: "private" }
|
|
267
340
|
: requireObject(raw.bundles, "bundles", errors);
|
|
268
341
|
const dbRaw = raw.db === undefined ? DEFAULT_PROJECT_DB_CONFIG : requireObject(raw.db, "db", errors);
|
|
342
|
+
const customizationDefaults = defaultCustomizationConfig();
|
|
343
|
+
const customizationRaw = raw.customization === undefined
|
|
344
|
+
? customizationDefaults
|
|
345
|
+
: requireObject(raw.customization, "customization", errors);
|
|
269
346
|
if (raw.bundle_imports !== undefined && raw.subgraphs !== undefined) {
|
|
270
347
|
errors.push("config must not define both subgraphs and legacy bundle_imports");
|
|
271
348
|
}
|
|
@@ -370,6 +447,60 @@ function validateConfigSchema(raw) {
|
|
|
370
447
|
};
|
|
371
448
|
}
|
|
372
449
|
}
|
|
450
|
+
let customization;
|
|
451
|
+
if (customizationRaw) {
|
|
452
|
+
const standardsRaw = customizationRaw.standards === undefined
|
|
453
|
+
? customizationDefaults.standards
|
|
454
|
+
: requireObject(customizationRaw.standards, "customization.standards", errors);
|
|
455
|
+
const coreDocsRaw = customizationRaw.core_docs === undefined
|
|
456
|
+
? customizationDefaults.core_docs
|
|
457
|
+
: requireObject(customizationRaw.core_docs, "customization.core_docs", errors);
|
|
458
|
+
const skillMirrorsRaw = customizationRaw.skill_mirrors === undefined
|
|
459
|
+
? customizationDefaults.skill_mirrors
|
|
460
|
+
: requireObject(customizationRaw.skill_mirrors, "customization.skill_mirrors", errors);
|
|
461
|
+
const standardsProfile = standardsRaw
|
|
462
|
+
? standardsRaw.profile === undefined
|
|
463
|
+
? customizationDefaults.standards.profile
|
|
464
|
+
: requireString(standardsRaw.profile, "customization.standards.profile", errors)
|
|
465
|
+
: undefined;
|
|
466
|
+
const standardsRefs = standardsRaw
|
|
467
|
+
? standardsRaw.refs === undefined
|
|
468
|
+
? customizationDefaults.standards.refs
|
|
469
|
+
: requireUniqueStringArray(standardsRaw.refs, "customization.standards.refs", errors, true)
|
|
470
|
+
: undefined;
|
|
471
|
+
const coreDocPaths = coreDocsRaw
|
|
472
|
+
? coreDocsRaw.custom_paths === undefined
|
|
473
|
+
? customizationDefaults.core_docs.custom_paths
|
|
474
|
+
: requireContainedPathArray(coreDocsRaw.custom_paths, "customization.core_docs.custom_paths", errors, true)
|
|
475
|
+
: undefined;
|
|
476
|
+
const mirrorTargets = skillMirrorsRaw
|
|
477
|
+
? skillMirrorsRaw.targets === undefined
|
|
478
|
+
? customizationDefaults.skill_mirrors.targets
|
|
479
|
+
: requireContainedPathArray(skillMirrorsRaw.targets, "customization.skill_mirrors.targets", errors, true)
|
|
480
|
+
: undefined;
|
|
481
|
+
if (standardsProfile !== undefined) {
|
|
482
|
+
if (standardsProfile.trim().length === 0) {
|
|
483
|
+
errors.push("customization.standards.profile must not be empty");
|
|
484
|
+
}
|
|
485
|
+
if (standardsProfile !== standardsProfile.trim()) {
|
|
486
|
+
errors.push("customization.standards.profile must not include surrounding whitespace");
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
if (standardsProfile && standardsRefs && coreDocPaths && mirrorTargets) {
|
|
490
|
+
customization = {
|
|
491
|
+
standards: {
|
|
492
|
+
profile: standardsProfile,
|
|
493
|
+
refs: standardsRefs,
|
|
494
|
+
},
|
|
495
|
+
core_docs: {
|
|
496
|
+
custom_paths: coreDocPaths,
|
|
497
|
+
},
|
|
498
|
+
skill_mirrors: {
|
|
499
|
+
targets: mirrorTargets,
|
|
500
|
+
},
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
}
|
|
373
504
|
const packLimitsRaw = packRaw ? requireObject(packRaw.limits, "pack.limits", errors) : undefined;
|
|
374
505
|
const pack = packRaw
|
|
375
506
|
? {
|
|
@@ -605,6 +736,7 @@ function validateConfigSchema(raw) {
|
|
|
605
736
|
capabilities: capabilities,
|
|
606
737
|
bundles: bundles,
|
|
607
738
|
db: db,
|
|
739
|
+
customization: customization,
|
|
608
740
|
subgraphs,
|
|
609
741
|
pack: pack,
|
|
610
742
|
templates: templates,
|
|
@@ -3,15 +3,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.AGENT_ATTRIBUTE_KEY_ORDER = exports.AGENT_FILE_BASENAMES = exports.AGENT_FILE_TYPES = void 0;
|
|
6
|
+
exports.AGENT_ATTRIBUTE_KEY_ORDER = exports.AGENT_FILE_BASENAMES = exports.AGENT_FILE_TYPES = exports.LEGACY_SPEC_BASENAME = exports.CANONICAL_MANIFEST_BASENAME = void 0;
|
|
7
7
|
exports.isAgentFileType = isAgentFileType;
|
|
8
|
+
exports.isManifestSemanticType = isManifestSemanticType;
|
|
9
|
+
exports.collectManifestSiblingConflicts = collectManifestSiblingConflicts;
|
|
8
10
|
exports.validateAgentFileName = validateAgentFileName;
|
|
9
11
|
exports.validateAgentFrontmatter = validateAgentFrontmatter;
|
|
10
12
|
exports.extractAgentAttributes = extractAgentAttributes;
|
|
11
13
|
const path_1 = __importDefault(require("path"));
|
|
12
14
|
const id_1 = require("../util/id");
|
|
13
15
|
const refs_1 = require("../util/refs");
|
|
16
|
+
exports.CANONICAL_MANIFEST_BASENAME = "MANIFEST.md";
|
|
17
|
+
exports.LEGACY_SPEC_BASENAME = "SPEC.md";
|
|
14
18
|
exports.AGENT_FILE_TYPES = [
|
|
19
|
+
"manifest",
|
|
15
20
|
"spec",
|
|
16
21
|
"work",
|
|
17
22
|
"work_order",
|
|
@@ -21,7 +26,8 @@ exports.AGENT_FILE_TYPES = [
|
|
|
21
26
|
"proposal",
|
|
22
27
|
];
|
|
23
28
|
exports.AGENT_FILE_BASENAMES = {
|
|
24
|
-
|
|
29
|
+
manifest: exports.CANONICAL_MANIFEST_BASENAME,
|
|
30
|
+
spec: exports.LEGACY_SPEC_BASENAME,
|
|
25
31
|
work: "WORK.md",
|
|
26
32
|
work_order: "WORK_ORDER.md",
|
|
27
33
|
receipt: "RECEIPT.md",
|
|
@@ -29,23 +35,25 @@ exports.AGENT_FILE_BASENAMES = {
|
|
|
29
35
|
dispute: "DISPUTE.md",
|
|
30
36
|
proposal: "PROPOSAL.md",
|
|
31
37
|
};
|
|
38
|
+
const MANIFEST_ATTRIBUTE_KEYS = [
|
|
39
|
+
"version",
|
|
40
|
+
"spec_kind",
|
|
41
|
+
"role",
|
|
42
|
+
"runtime_mode",
|
|
43
|
+
"work_contracts",
|
|
44
|
+
"requested_capabilities",
|
|
45
|
+
"skill_refs",
|
|
46
|
+
"tool_refs",
|
|
47
|
+
"model_refs",
|
|
48
|
+
"wasm_component_refs",
|
|
49
|
+
"runtime_image_refs",
|
|
50
|
+
"subagent_refs",
|
|
51
|
+
"resource_profile",
|
|
52
|
+
"update_policy",
|
|
53
|
+
];
|
|
32
54
|
exports.AGENT_ATTRIBUTE_KEY_ORDER = {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"spec_kind",
|
|
36
|
-
"role",
|
|
37
|
-
"runtime_mode",
|
|
38
|
-
"work_contracts",
|
|
39
|
-
"requested_capabilities",
|
|
40
|
-
"skill_refs",
|
|
41
|
-
"tool_refs",
|
|
42
|
-
"model_refs",
|
|
43
|
-
"wasm_component_refs",
|
|
44
|
-
"runtime_image_refs",
|
|
45
|
-
"subagent_refs",
|
|
46
|
-
"resource_profile",
|
|
47
|
-
"update_policy",
|
|
48
|
-
],
|
|
55
|
+
manifest: MANIFEST_ATTRIBUTE_KEYS,
|
|
56
|
+
spec: MANIFEST_ATTRIBUTE_KEYS,
|
|
49
57
|
work: [
|
|
50
58
|
"version",
|
|
51
59
|
"agent_id",
|
|
@@ -207,9 +215,39 @@ function formatError(filePath, message) {
|
|
|
207
215
|
function isAgentFileType(type) {
|
|
208
216
|
return exports.AGENT_FILE_TYPES.includes(type);
|
|
209
217
|
}
|
|
218
|
+
function isManifestSemanticType(type) {
|
|
219
|
+
return type === "manifest" || type === "spec";
|
|
220
|
+
}
|
|
221
|
+
function collectManifestSiblingConflicts(filePaths, formatDir) {
|
|
222
|
+
const basenamesByDir = new Map();
|
|
223
|
+
for (const filePath of filePaths) {
|
|
224
|
+
const basename = path_1.default.basename(filePath);
|
|
225
|
+
if (basename !== exports.CANONICAL_MANIFEST_BASENAME && basename !== exports.LEGACY_SPEC_BASENAME) {
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
const dirPath = path_1.default.dirname(filePath);
|
|
229
|
+
const basenames = basenamesByDir.get(dirPath) ?? new Set();
|
|
230
|
+
basenames.add(basename);
|
|
231
|
+
basenamesByDir.set(dirPath, basenames);
|
|
232
|
+
}
|
|
233
|
+
const conflicts = [];
|
|
234
|
+
for (const [dirPath, basenames] of Array.from(basenamesByDir.entries()).sort()) {
|
|
235
|
+
if (basenames.has(exports.CANONICAL_MANIFEST_BASENAME) && basenames.has(exports.LEGACY_SPEC_BASENAME)) {
|
|
236
|
+
conflicts.push(`${formatDir(dirPath)}: MANIFEST.md and SPEC.md cannot both exist in the same logical Omni unit; keep MANIFEST.md and remove the legacy SPEC.md alias`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return conflicts;
|
|
240
|
+
}
|
|
210
241
|
function validateAgentFileName(type, filePath) {
|
|
242
|
+
const basename = path_1.default.basename(filePath);
|
|
243
|
+
if (type === "spec" && basename === exports.CANONICAL_MANIFEST_BASENAME) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
211
246
|
const expected = exports.AGENT_FILE_BASENAMES[type];
|
|
212
|
-
if (
|
|
247
|
+
if (basename !== expected) {
|
|
248
|
+
if (isManifestSemanticType(type)) {
|
|
249
|
+
throw formatError(filePath, `manifest files must be named MANIFEST.md (canonical) or SPEC.md (legacy alias); ${type} files must be named ${expected}`);
|
|
250
|
+
}
|
|
213
251
|
throw formatError(filePath, `${type} files must be named ${expected}`);
|
|
214
252
|
}
|
|
215
253
|
}
|
|
@@ -303,7 +341,7 @@ function validateSpecKind(value, filePath) {
|
|
|
303
341
|
}
|
|
304
342
|
const route = DOCUMENTATION_ONLY_SPEC_KIND_ROUTES[value];
|
|
305
343
|
if (route) {
|
|
306
|
-
throw formatError(filePath, `spec_kind ${value} is documentation-only; ${route}.
|
|
344
|
+
throw formatError(filePath, `spec_kind ${value} is documentation-only; ${route}. MANIFEST.md must define a reusable invocable capability surface; legacy SPEC.md follows the same contract.`);
|
|
307
345
|
}
|
|
308
346
|
throw formatError(filePath, `spec_kind must be one of ${Array.from(SPEC_KIND_VALUES).join(", ")}; documentation-only records belong in normal mdkg nodes such as task, test, epic, goal, checkpoint, EDD, PRD, DEC, bug, feedback, dispute, or proposal.`);
|
|
309
347
|
}
|
|
@@ -398,6 +436,7 @@ function validateAgentFrontmatter(type, frontmatter, filePath) {
|
|
|
398
436
|
const version = expectString(frontmatter, "version", filePath);
|
|
399
437
|
requireSemver(version, "version", filePath);
|
|
400
438
|
switch (type) {
|
|
439
|
+
case "manifest":
|
|
401
440
|
case "spec": {
|
|
402
441
|
const specKind = optionalString(frontmatter, "spec_kind", filePath);
|
|
403
442
|
if (specKind) {
|
|
@@ -10,6 +10,7 @@ const crypto_1 = __importDefault(require("crypto"));
|
|
|
10
10
|
const fs_1 = __importDefault(require("fs"));
|
|
11
11
|
const path_1 = __importDefault(require("path"));
|
|
12
12
|
const indexer_1 = require("./indexer");
|
|
13
|
+
const agent_file_types_1 = require("./agent_file_types");
|
|
13
14
|
const skills_indexer_1 = require("./skills_indexer");
|
|
14
15
|
exports.CAPABILITIES_INDEX_RELATIVE_PATH = ".mdkg/index/capabilities.json";
|
|
15
16
|
exports.CAPABILITY_KINDS = ["skill", "spec", "work", "core", "design"];
|
|
@@ -41,7 +42,7 @@ function workspaceMdkgPrefix(entry) {
|
|
|
41
42
|
return `${wsPath}${mdkgDir}/`;
|
|
42
43
|
}
|
|
43
44
|
function classifyNodeCapability(node, config) {
|
|
44
|
-
if (node.type
|
|
45
|
+
if ((0, agent_file_types_1.isManifestSemanticType)(node.type)) {
|
|
45
46
|
return "spec";
|
|
46
47
|
}
|
|
47
48
|
if (node.type === "work") {
|
|
@@ -115,7 +116,7 @@ function resolveWorkSpecs(index, workNode) {
|
|
|
115
116
|
const candidates = new Map();
|
|
116
117
|
const workRefs = nodeRefSet(workNode);
|
|
117
118
|
for (const node of Object.values(index.nodes)) {
|
|
118
|
-
if (node.type
|
|
119
|
+
if (!(0, agent_file_types_1.isManifestSemanticType)(node.type) || node.ws !== workNode.ws) {
|
|
119
120
|
continue;
|
|
120
121
|
}
|
|
121
122
|
const agentId = typeof workNode.attributes.agent_id === "string" ? workNode.attributes.agent_id : undefined;
|
|
@@ -159,9 +160,49 @@ function buildCapabilityLinkage(index, node, kind) {
|
|
|
159
160
|
receipt_qids: receipts.map((receiptNode) => receiptNode.qid),
|
|
160
161
|
};
|
|
161
162
|
}
|
|
163
|
+
function manifestCapabilityMetadata(node) {
|
|
164
|
+
if (!(0, agent_file_types_1.isManifestSemanticType)(node.type)) {
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
const sourceBasename = path_1.default.posix.basename(node.path);
|
|
168
|
+
const compatibilityMode = sourceBasename === agent_file_types_1.LEGACY_SPEC_BASENAME
|
|
169
|
+
? "legacy"
|
|
170
|
+
: node.type === "spec"
|
|
171
|
+
? "transitional"
|
|
172
|
+
: "canonical";
|
|
173
|
+
return {
|
|
174
|
+
semantic_kind: "manifest",
|
|
175
|
+
source_basename: sourceBasename,
|
|
176
|
+
source_type: node.type,
|
|
177
|
+
canonical_basename: agent_file_types_1.CANONICAL_MANIFEST_BASENAME,
|
|
178
|
+
legacy_basename: agent_file_types_1.LEGACY_SPEC_BASENAME,
|
|
179
|
+
compatibility_mode: compatibilityMode,
|
|
180
|
+
legacy: compatibilityMode !== "canonical",
|
|
181
|
+
deprecated: compatibilityMode !== "canonical",
|
|
182
|
+
command_family: "manifest",
|
|
183
|
+
legacy_command_family: "spec",
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function manifestSearchAliases(metadata) {
|
|
187
|
+
if (!metadata) {
|
|
188
|
+
return [];
|
|
189
|
+
}
|
|
190
|
+
return [
|
|
191
|
+
"manifest",
|
|
192
|
+
"manifest.md",
|
|
193
|
+
"MANIFEST.md",
|
|
194
|
+
"manifest capability",
|
|
195
|
+
"MANIFEST.md legacy SPEC.md",
|
|
196
|
+
"spec.md compatibility alias",
|
|
197
|
+
"legacy spec.md",
|
|
198
|
+
metadata.compatibility_mode,
|
|
199
|
+
metadata.source_basename,
|
|
200
|
+
];
|
|
201
|
+
}
|
|
162
202
|
function nodeCapabilityRecord(root, config, index, node, kind, indexedAt) {
|
|
163
203
|
const absolutePath = path_1.default.resolve(root, node.path);
|
|
164
204
|
const content = fs_1.default.readFileSync(absolutePath, "utf8");
|
|
205
|
+
const manifest = kind === "spec" ? manifestCapabilityMetadata(node) : undefined;
|
|
165
206
|
const record = {
|
|
166
207
|
kind,
|
|
167
208
|
workspace: node.ws,
|
|
@@ -172,7 +213,7 @@ function nodeCapabilityRecord(root, config, index, node, kind, indexedAt) {
|
|
|
172
213
|
title: node.title,
|
|
173
214
|
tags: [...node.tags],
|
|
174
215
|
refs: [...node.refs],
|
|
175
|
-
aliases: [...node.aliases],
|
|
216
|
+
aliases: Array.from(new Set([...node.aliases, ...manifestSearchAliases(manifest)])),
|
|
176
217
|
links: [...node.links],
|
|
177
218
|
artifacts: [...node.artifacts],
|
|
178
219
|
updated: node.updated,
|
|
@@ -182,6 +223,7 @@ function nodeCapabilityRecord(root, config, index, node, kind, indexedAt) {
|
|
|
182
223
|
node_type: node.type,
|
|
183
224
|
};
|
|
184
225
|
if (kind === "spec") {
|
|
226
|
+
record.manifest = manifest;
|
|
185
227
|
record.spec = pickAttributes(node.attributes, [
|
|
186
228
|
"version",
|
|
187
229
|
"spec_kind",
|
package/dist/graph/indexer.js
CHANGED
|
@@ -10,6 +10,7 @@ const node_1 = require("./node");
|
|
|
10
10
|
const workspace_files_1 = require("./workspace_files");
|
|
11
11
|
const validate_graph_1 = require("./validate_graph");
|
|
12
12
|
const template_schema_1 = require("./template_schema");
|
|
13
|
+
const agent_file_types_1 = require("./agent_file_types");
|
|
13
14
|
function normalizeEdgeTarget(value, ws) {
|
|
14
15
|
if (value.includes(":")) {
|
|
15
16
|
return value;
|
|
@@ -48,6 +49,10 @@ function buildIndex(root, config, options = {}) {
|
|
|
48
49
|
for (const alias of workspaceAliases) {
|
|
49
50
|
idsByWorkspace[alias] = new Set();
|
|
50
51
|
const files = docFilesByAlias[alias];
|
|
52
|
+
const manifestConflicts = (0, agent_file_types_1.collectManifestSiblingConflicts)(files, (dirPath) => path_1.default.relative(root, dirPath).split(path_1.default.sep).join("/") || ".");
|
|
53
|
+
if (manifestConflicts.length > 0 && !tolerant) {
|
|
54
|
+
throw new Error(manifestConflicts[0]);
|
|
55
|
+
}
|
|
51
56
|
for (const filePath of files) {
|
|
52
57
|
if (path_1.default.basename(filePath) === "core.md" && path_1.default.basename(path_1.default.dirname(filePath)) === "core") {
|
|
53
58
|
continue;
|
|
@@ -9,6 +9,9 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
10
10
|
const frontmatter_1 = require("./frontmatter");
|
|
11
11
|
const builtin_1 = require("../templates/builtin");
|
|
12
|
+
const TEMPLATE_SCHEMA_ALIASES = {
|
|
13
|
+
spec: "manifest",
|
|
14
|
+
};
|
|
12
15
|
function listMarkdownFiles(dir) {
|
|
13
16
|
if (!fs_1.default.existsSync(dir)) {
|
|
14
17
|
return [];
|
|
@@ -46,6 +49,34 @@ function addKeyToSchema(schema, key, kind, filePath) {
|
|
|
46
49
|
schema.listKeys.add(key);
|
|
47
50
|
}
|
|
48
51
|
}
|
|
52
|
+
function cloneSchema(schema, type) {
|
|
53
|
+
return {
|
|
54
|
+
type,
|
|
55
|
+
allowedKeys: new Set(schema.allowedKeys),
|
|
56
|
+
keyKinds: { ...schema.keyKinds },
|
|
57
|
+
listKeys: new Set(schema.listKeys),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function loadBundledSchema(type) {
|
|
61
|
+
const bundledPath = (0, builtin_1.requireBundledTemplatePath)(type);
|
|
62
|
+
const content = fs_1.default.readFileSync(bundledPath, "utf8");
|
|
63
|
+
const { frontmatter } = (0, frontmatter_1.parseFrontmatter)(content, bundledPath);
|
|
64
|
+
const typeValue = frontmatter.type;
|
|
65
|
+
if (typeValue !== type) {
|
|
66
|
+
throw new Error(`bundled template fallback type mismatch for ${type}: ${bundledPath}`);
|
|
67
|
+
}
|
|
68
|
+
const schema = {
|
|
69
|
+
type,
|
|
70
|
+
allowedKeys: new Set(),
|
|
71
|
+
keyKinds: {},
|
|
72
|
+
listKeys: new Set(),
|
|
73
|
+
};
|
|
74
|
+
for (const [key, value] of Object.entries(frontmatter)) {
|
|
75
|
+
const kind = getValueKind(value);
|
|
76
|
+
addKeyToSchema(schema, key, kind, bundledPath);
|
|
77
|
+
}
|
|
78
|
+
return schema;
|
|
79
|
+
}
|
|
49
80
|
function loadTemplateSchemas(root, config, requiredTypes) {
|
|
50
81
|
return loadTemplateSchemasWithInfo(root, config, requiredTypes).schemas;
|
|
51
82
|
}
|
|
@@ -84,24 +115,13 @@ function loadTemplateSchemasWithInfo(root, config, requiredTypes) {
|
|
|
84
115
|
if (requiredTypes) {
|
|
85
116
|
const required = Array.from(requiredTypes, (value) => value.toLowerCase());
|
|
86
117
|
for (const missingType of required.filter((value) => !schemas[value])) {
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
throw new Error(`bundled template fallback type mismatch for ${missingType}: ${bundledPath}`);
|
|
93
|
-
}
|
|
94
|
-
const schema = {
|
|
95
|
-
type: missingType,
|
|
96
|
-
allowedKeys: new Set(),
|
|
97
|
-
keyKinds: {},
|
|
98
|
-
listKeys: new Set(),
|
|
99
|
-
};
|
|
100
|
-
schemas[missingType] = schema;
|
|
101
|
-
for (const [key, value] of Object.entries(frontmatter)) {
|
|
102
|
-
const kind = getValueKind(value);
|
|
103
|
-
addKeyToSchema(schema, key, kind, bundledPath);
|
|
118
|
+
const aliasType = TEMPLATE_SCHEMA_ALIASES[missingType];
|
|
119
|
+
if (aliasType) {
|
|
120
|
+
const aliasSchema = schemas[aliasType] ?? loadBundledSchema(aliasType);
|
|
121
|
+
schemas[missingType] = cloneSchema(aliasSchema, missingType);
|
|
122
|
+
continue;
|
|
104
123
|
}
|
|
124
|
+
schemas[missingType] = loadBundledSchema(missingType);
|
|
105
125
|
fallbackTypes.push(missingType);
|
|
106
126
|
}
|
|
107
127
|
}
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.collectGraphErrors = collectGraphErrors;
|
|
4
4
|
exports.validateGraph = validateGraph;
|
|
5
|
+
const agent_file_types_1 = require("./agent_file_types");
|
|
5
6
|
const refs_1 = require("../util/refs");
|
|
7
|
+
const qid_1 = require("../util/qid");
|
|
6
8
|
const goal_scope_1 = require("./goal_scope");
|
|
7
9
|
function pushError(errors, message) {
|
|
8
10
|
if (errors) {
|
|
@@ -147,7 +149,7 @@ function validateAgentWorkflowSpecWorkContracts(index, allowMissing, errors) {
|
|
|
147
149
|
});
|
|
148
150
|
}
|
|
149
151
|
for (const [qid, node] of Object.entries(index.nodes)) {
|
|
150
|
-
if (node.type
|
|
152
|
+
if (!(0, agent_file_types_1.isManifestSemanticType)(node.type)) {
|
|
151
153
|
continue;
|
|
152
154
|
}
|
|
153
155
|
const workContracts = node.attributes.work_contracts;
|
|
@@ -233,7 +235,7 @@ function validateAgentWorkflowReceiptWorkOrderRefs(index, allowMissing, external
|
|
|
233
235
|
function buildSpecRolesByWorkspace(index) {
|
|
234
236
|
const specRolesByWorkspace = {};
|
|
235
237
|
for (const node of Object.values(index.nodes)) {
|
|
236
|
-
if (node.type
|
|
238
|
+
if (!(0, agent_file_types_1.isManifestSemanticType)(node.type)) {
|
|
237
239
|
continue;
|
|
238
240
|
}
|
|
239
241
|
if (!specRolesByWorkspace[node.ws]) {
|
|
@@ -247,8 +249,12 @@ function buildSpecRolesByWorkspace(index) {
|
|
|
247
249
|
return specRolesByWorkspace;
|
|
248
250
|
}
|
|
249
251
|
function resolveSpecRole(index, ws, value) {
|
|
250
|
-
const
|
|
251
|
-
if (
|
|
252
|
+
const resolved = (0, qid_1.resolveQid)(index, value, ws);
|
|
253
|
+
if (resolved.status !== "ok") {
|
|
254
|
+
return undefined;
|
|
255
|
+
}
|
|
256
|
+
const node = index.nodes[resolved.qid];
|
|
257
|
+
if (!node || !(0, agent_file_types_1.isManifestSemanticType)(node.type)) {
|
|
252
258
|
return undefined;
|
|
253
259
|
}
|
|
254
260
|
return {
|
|
@@ -259,7 +265,7 @@ function resolveSpecRole(index, ws, value) {
|
|
|
259
265
|
function validateAgentWorkflowSubagentRefs(index, allowMissing, externalWorkspaces, errors) {
|
|
260
266
|
const specRolesByWorkspace = buildSpecRolesByWorkspace(index);
|
|
261
267
|
for (const [qid, node] of Object.entries(index.nodes)) {
|
|
262
|
-
if (node.type
|
|
268
|
+
if (!(0, agent_file_types_1.isManifestSemanticType)(node.type) && node.type !== "work") {
|
|
263
269
|
continue;
|
|
264
270
|
}
|
|
265
271
|
const subagentRefs = node.attributes.subagent_refs;
|
package/dist/init/AGENT_START.md
CHANGED
|
@@ -6,14 +6,15 @@ mdkg is pre-v1 public alpha software. Treat generated graph, cache, bundle, and
|
|
|
6
6
|
|
|
7
7
|
Read these files in order:
|
|
8
8
|
1. `.mdkg/core/SOUL.md` if it exists
|
|
9
|
-
2. `.mdkg/core/
|
|
10
|
-
3. `.mdkg/
|
|
11
|
-
4.
|
|
9
|
+
2. `.mdkg/core/COLLABORATION.md` if it exists
|
|
10
|
+
3. `.mdkg/core/HUMAN.md` if it exists as a legacy alias
|
|
11
|
+
4. `.mdkg/README.md`
|
|
12
|
+
5. `CLI_COMMAND_MATRIX.md`
|
|
12
13
|
|
|
13
14
|
Trust order:
|
|
14
15
|
- source code
|
|
15
16
|
- mdkg rules, design docs, decisions, and work nodes
|
|
16
|
-
- SOUL/HUMAN
|
|
17
|
+
- SOUL/COLLABORATION anchors and legacy HUMAN notes
|
|
17
18
|
- relevant skills
|
|
18
19
|
- chat history
|
|
19
20
|
|
|
@@ -29,8 +30,8 @@ Agent operating prompt:
|
|
|
29
30
|
- Treat goal `required_checks` as report-only guidance from mdkg. Run commands yourself, then record evidence in the goal or active work item.
|
|
30
31
|
- Record skill improvement candidates during normal goal execution; edit `SKILL.md` only when the active node is explicit skill-maintenance work.
|
|
31
32
|
- Use `mdkg skill list`, `mdkg skill search`, and `mdkg skill show <slug>` for skill discovery.
|
|
32
|
-
- Use `mdkg capability list/search/show` for deterministic skills, `SPEC.md`, `WORK.md`, core-doc, and design-doc capability discovery.
|
|
33
|
-
- Use `mdkg
|
|
33
|
+
- Use `mdkg capability list/search/show` for deterministic skills, `MANIFEST.md` / legacy `SPEC.md`, `WORK.md`, core-doc, and design-doc capability discovery.
|
|
34
|
+
- Use `mdkg manifest list/show/validate` for focused optional `MANIFEST.md` capability records; `mdkg spec ...` remains a legacy alias for one compatibility release.
|
|
34
35
|
- Use `mdkg index` to refresh JSON compatibility caches and `.mdkg/index/mdkg.sqlite` when SQLite mode is enabled.
|
|
35
36
|
- Treat `.mdkg/db` as project application state; use `mdkg db init` to create
|
|
36
37
|
the generic scaffold and enable `db.enabled` without creating an active
|
|
@@ -111,9 +112,9 @@ Capability discovery:
|
|
|
111
112
|
- `mdkg capability list --kind skill --json`
|
|
112
113
|
- `mdkg capability search "<query>" --kind spec --json`
|
|
113
114
|
- `mdkg capability search "<query>" --kind work --json`
|
|
114
|
-
- `mdkg
|
|
115
|
-
- `mdkg
|
|
116
|
-
- `mdkg
|
|
115
|
+
- `mdkg manifest list --json`
|
|
116
|
+
- `mdkg manifest show <id-or-qid-or-alias> --json`
|
|
117
|
+
- `mdkg manifest validate <id-or-qid-or-alias> --json`
|
|
117
118
|
|
|
118
119
|
Conventions:
|
|
119
120
|
- `AGENTS.md` is the Codex/OpenAI-oriented wrapper doc.
|