mdkg 0.1.10 → 0.3.0
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 +69 -0
- package/README.md +40 -15
- package/dist/cli.js +293 -13
- package/dist/commands/capability.js +13 -8
- package/dist/commands/db.js +185 -1
- package/dist/commands/format.js +1 -1
- package/dist/commands/spec.js +101 -0
- package/dist/commands/work.js +569 -20
- package/dist/core/project_db_migrations.js +24 -0
- package/dist/core/project_db_queue.js +186 -0
- package/dist/core/project_db_snapshot.js +28 -3
- package/dist/graph/agent_file_types.js +95 -7
- package/dist/graph/capabilities_indexer.js +89 -2
- package/dist/graph/frontmatter.js +6 -0
- package/dist/graph/node.js +8 -2
- package/dist/init/AGENT_START.md +15 -9
- package/dist/init/CLI_COMMAND_MATRIX.md +33 -5
- package/dist/init/README.md +36 -11
- package/dist/init/init-manifest.json +64 -9
- package/dist/init/skills/default/verify-close-and-checkpoint/SKILL.md +8 -7
- package/dist/init/templates/default/receipt.md +12 -1
- package/dist/init/templates/default/spec.md +8 -6
- package/dist/init/templates/default/work.md +5 -1
- package/dist/init/templates/default/work_order.md +11 -0
- package/dist/init/templates/skills/base.SKILL.md +66 -0
- package/dist/init/templates/specs/agent.SPEC.md +80 -0
- package/dist/init/templates/specs/api.SPEC.md +33 -0
- package/dist/init/templates/specs/base.SPEC.md +120 -0
- package/dist/init/templates/specs/capability.SPEC.md +45 -0
- package/dist/init/templates/specs/integration.SPEC.md +25 -0
- package/dist/init/templates/specs/model.SPEC.md +21 -0
- package/dist/init/templates/specs/project.SPEC.md +39 -0
- package/dist/init/templates/specs/runtime-agent.SPEC.md +49 -0
- package/dist/init/templates/specs/runtime-image.SPEC.md +21 -0
- package/dist/init/templates/specs/tool.SPEC.md +25 -0
- package/dist/util/argparse.js +8 -0
- package/package.json +5 -2
package/dist/commands/db.js
CHANGED
|
@@ -8,6 +8,18 @@ exports.runDbInitCommand = runDbInitCommand;
|
|
|
8
8
|
exports.runDbMigrateCommand = runDbMigrateCommand;
|
|
9
9
|
exports.runDbVerifyCommand = runDbVerifyCommand;
|
|
10
10
|
exports.runDbStatsCommand = runDbStatsCommand;
|
|
11
|
+
exports.runDbQueueCreateCommand = runDbQueueCreateCommand;
|
|
12
|
+
exports.runDbQueuePauseCommand = runDbQueuePauseCommand;
|
|
13
|
+
exports.runDbQueueResumeCommand = runDbQueueResumeCommand;
|
|
14
|
+
exports.runDbQueueEnqueueCommand = runDbQueueEnqueueCommand;
|
|
15
|
+
exports.runDbQueueClaimCommand = runDbQueueClaimCommand;
|
|
16
|
+
exports.runDbQueueAckCommand = runDbQueueAckCommand;
|
|
17
|
+
exports.runDbQueueFailCommand = runDbQueueFailCommand;
|
|
18
|
+
exports.runDbQueueDeadLetterCommand = runDbQueueDeadLetterCommand;
|
|
19
|
+
exports.runDbQueueReleaseExpiredCommand = runDbQueueReleaseExpiredCommand;
|
|
20
|
+
exports.runDbQueueStatsCommand = runDbQueueStatsCommand;
|
|
21
|
+
exports.runDbQueueListCommand = runDbQueueListCommand;
|
|
22
|
+
exports.runDbQueueShowCommand = runDbQueueShowCommand;
|
|
11
23
|
exports.runDbSnapshotSealCommand = runDbSnapshotSealCommand;
|
|
12
24
|
exports.runDbSnapshotVerifyCommand = runDbSnapshotVerifyCommand;
|
|
13
25
|
exports.runDbSnapshotStatusCommand = runDbSnapshotStatusCommand;
|
|
@@ -23,6 +35,7 @@ const paths_1 = require("../core/paths");
|
|
|
23
35
|
const project_db_1 = require("../core/project_db");
|
|
24
36
|
const project_db_migrations_1 = require("../core/project_db_migrations");
|
|
25
37
|
const project_db_snapshot_1 = require("../core/project_db_snapshot");
|
|
38
|
+
const project_db_queue_1 = require("../core/project_db_queue");
|
|
26
39
|
const version_1 = require("../core/version");
|
|
27
40
|
const index_1 = require("./index");
|
|
28
41
|
const capabilities_indexer_1 = require("../graph/capabilities_indexer");
|
|
@@ -449,6 +462,177 @@ function runDbStatsCommand(options) {
|
|
|
449
462
|
}
|
|
450
463
|
}
|
|
451
464
|
}
|
|
465
|
+
function requireQueueName(options) {
|
|
466
|
+
if (!options.queueName) {
|
|
467
|
+
throw new errors_1.UsageError("queue name is required");
|
|
468
|
+
}
|
|
469
|
+
return options.queueName;
|
|
470
|
+
}
|
|
471
|
+
function requireMessageId(options) {
|
|
472
|
+
if (!options.messageId) {
|
|
473
|
+
throw new errors_1.UsageError("message id is required");
|
|
474
|
+
}
|
|
475
|
+
return options.messageId;
|
|
476
|
+
}
|
|
477
|
+
function requireLeaseOwner(options) {
|
|
478
|
+
if (!options.leaseOwner) {
|
|
479
|
+
throw new errors_1.UsageError("--lease-owner is required");
|
|
480
|
+
}
|
|
481
|
+
return options.leaseOwner;
|
|
482
|
+
}
|
|
483
|
+
function requireLeaseMs(options) {
|
|
484
|
+
if (options.leaseMs === undefined) {
|
|
485
|
+
throw new errors_1.UsageError("--lease-ms is required");
|
|
486
|
+
}
|
|
487
|
+
return options.leaseMs;
|
|
488
|
+
}
|
|
489
|
+
function loadQueueDatabasePath(root) {
|
|
490
|
+
const config = (0, config_1.loadConfig)(root);
|
|
491
|
+
const verification = (0, project_db_migrations_1.verifyProjectDb)(root, config);
|
|
492
|
+
if (!verification.ok) {
|
|
493
|
+
throw new errors_1.ValidationError(`db queue requires a valid project DB; run mdkg db verify`);
|
|
494
|
+
}
|
|
495
|
+
return (0, project_db_1.resolveConfiguredProjectDbLayout)(root, config.db).runtimeFile;
|
|
496
|
+
}
|
|
497
|
+
function parseQueuePayload(options) {
|
|
498
|
+
const hasPayloadJson = options.payloadJson !== undefined;
|
|
499
|
+
const hasPayloadFile = options.payloadFile !== undefined;
|
|
500
|
+
if (hasPayloadJson === hasPayloadFile) {
|
|
501
|
+
throw new errors_1.UsageError("mdkg db queue enqueue requires exactly one of --payload-json or --payload-file");
|
|
502
|
+
}
|
|
503
|
+
const raw = hasPayloadJson
|
|
504
|
+
? options.payloadJson
|
|
505
|
+
: fs_1.default.readFileSync(path_1.default.resolve(options.root, String(options.payloadFile)), "utf8");
|
|
506
|
+
try {
|
|
507
|
+
return JSON.parse(String(raw));
|
|
508
|
+
}
|
|
509
|
+
catch (err) {
|
|
510
|
+
throw new errors_1.UsageError(`queue payload must be valid JSON: ${err instanceof Error ? err.message : String(err)}`);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
function writeQueueJsonOrText(action, payload, json) {
|
|
514
|
+
if (json) {
|
|
515
|
+
console.log(JSON.stringify({ action, ok: true, ...payload }, null, 2));
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
console.log(action);
|
|
519
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
520
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null) {
|
|
521
|
+
console.log(`${key}: ${value}`);
|
|
522
|
+
}
|
|
523
|
+
else {
|
|
524
|
+
console.log(`${key}: ${JSON.stringify(value)}`);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
function runQueueMutation(options, fn, action) {
|
|
529
|
+
const config = (0, config_1.loadConfig)(options.root);
|
|
530
|
+
(0, lock_1.withMutationLock)(options.root, config.index.lock_timeout_ms, () => {
|
|
531
|
+
const databasePath = loadQueueDatabasePath(options.root);
|
|
532
|
+
writeQueueJsonOrText(action, fn(databasePath), options.json);
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
function runDbQueueCreateCommand(options) {
|
|
536
|
+
runQueueMutation(options, (databasePath) => (0, project_db_queue_1.createProjectQueue)(databasePath, {
|
|
537
|
+
queue_name: requireQueueName(options),
|
|
538
|
+
paused: options.paused,
|
|
539
|
+
reason: options.reason,
|
|
540
|
+
}), "db-queue-create");
|
|
541
|
+
}
|
|
542
|
+
function runDbQueuePauseCommand(options) {
|
|
543
|
+
runQueueMutation(options, (databasePath) => ({ queue: (0, project_db_queue_1.pauseProjectQueue)(databasePath, { queue_name: requireQueueName(options), reason: options.reason }) }), "db-queue-pause");
|
|
544
|
+
}
|
|
545
|
+
function runDbQueueResumeCommand(options) {
|
|
546
|
+
runQueueMutation(options, (databasePath) => ({ queue: (0, project_db_queue_1.resumeProjectQueue)(databasePath, { queue_name: requireQueueName(options) }) }), "db-queue-resume");
|
|
547
|
+
}
|
|
548
|
+
function runDbQueueEnqueueCommand(options) {
|
|
549
|
+
runQueueMutation(options, (databasePath) => (0, project_db_queue_1.enqueueProjectQueueMessage)(databasePath, {
|
|
550
|
+
queue_name: requireQueueName(options),
|
|
551
|
+
message_id: requireMessageId(options),
|
|
552
|
+
dedupe_key: options.dedupeKey,
|
|
553
|
+
payload: parseQueuePayload(options),
|
|
554
|
+
available_at_ms: options.availableAtMs,
|
|
555
|
+
max_attempts: options.maxAttempts,
|
|
556
|
+
}), "db-queue-enqueue");
|
|
557
|
+
}
|
|
558
|
+
function runDbQueueClaimCommand(options) {
|
|
559
|
+
runQueueMutation(options, (databasePath) => ({
|
|
560
|
+
message: (0, project_db_queue_1.claimProjectQueueMessage)(databasePath, {
|
|
561
|
+
queue_name: requireQueueName(options),
|
|
562
|
+
lease_owner: requireLeaseOwner(options),
|
|
563
|
+
lease_ms: requireLeaseMs(options),
|
|
564
|
+
}),
|
|
565
|
+
}), "db-queue-claim");
|
|
566
|
+
}
|
|
567
|
+
function runDbQueueAckCommand(options) {
|
|
568
|
+
runQueueMutation(options, (databasePath) => ({
|
|
569
|
+
message: (0, project_db_queue_1.ackProjectQueueMessage)(databasePath, {
|
|
570
|
+
queue_name: requireQueueName(options),
|
|
571
|
+
message_id: requireMessageId(options),
|
|
572
|
+
lease_owner: requireLeaseOwner(options),
|
|
573
|
+
}),
|
|
574
|
+
}), "db-queue-ack");
|
|
575
|
+
}
|
|
576
|
+
function runDbQueueFailCommand(options) {
|
|
577
|
+
if (!options.error) {
|
|
578
|
+
throw new errors_1.UsageError("--error is required");
|
|
579
|
+
}
|
|
580
|
+
runQueueMutation(options, (databasePath) => ({
|
|
581
|
+
message: (0, project_db_queue_1.failProjectQueueMessage)(databasePath, {
|
|
582
|
+
queue_name: requireQueueName(options),
|
|
583
|
+
message_id: requireMessageId(options),
|
|
584
|
+
lease_owner: requireLeaseOwner(options),
|
|
585
|
+
error: String(options.error),
|
|
586
|
+
retry_after_ms: options.retryAfterMs,
|
|
587
|
+
}),
|
|
588
|
+
}), "db-queue-fail");
|
|
589
|
+
}
|
|
590
|
+
function runDbQueueDeadLetterCommand(options) {
|
|
591
|
+
if (!options.error) {
|
|
592
|
+
throw new errors_1.UsageError("--error is required");
|
|
593
|
+
}
|
|
594
|
+
runQueueMutation(options, (databasePath) => ({
|
|
595
|
+
message: (0, project_db_queue_1.deadLetterProjectQueueMessage)(databasePath, {
|
|
596
|
+
queue_name: requireQueueName(options),
|
|
597
|
+
message_id: requireMessageId(options),
|
|
598
|
+
lease_owner: requireLeaseOwner(options),
|
|
599
|
+
error: String(options.error),
|
|
600
|
+
}),
|
|
601
|
+
}), "db-queue-dead-letter");
|
|
602
|
+
}
|
|
603
|
+
function runDbQueueReleaseExpiredCommand(options) {
|
|
604
|
+
runQueueMutation(options, (databasePath) => (0, project_db_queue_1.releaseExpiredProjectQueueLeases)(databasePath, { queue_name: options.queueName }), "db-queue-release-expired");
|
|
605
|
+
}
|
|
606
|
+
function runDbQueueStatsCommand(options) {
|
|
607
|
+
const databasePath = loadQueueDatabasePath(options.root);
|
|
608
|
+
const stats = (0, project_db_queue_1.readProjectQueueStats)(databasePath, { queue_name: options.queueName });
|
|
609
|
+
const queue = options.queueName ? (0, project_db_queue_1.readProjectQueue)(databasePath, options.queueName) : null;
|
|
610
|
+
writeQueueJsonOrText("db-queue-stats", {
|
|
611
|
+
queue,
|
|
612
|
+
stats,
|
|
613
|
+
queues: options.queueName ? undefined : (0, project_db_queue_1.listProjectQueues)(databasePath),
|
|
614
|
+
snapshot_summary: (0, project_db_queue_1.readProjectQueueSnapshotSummary)(databasePath),
|
|
615
|
+
}, options.json);
|
|
616
|
+
}
|
|
617
|
+
function runDbQueueListCommand(options) {
|
|
618
|
+
const databasePath = loadQueueDatabasePath(options.root);
|
|
619
|
+
const messages = (0, project_db_queue_1.listProjectQueueMessages)(databasePath, {
|
|
620
|
+
queue_name: requireQueueName(options),
|
|
621
|
+
status: (options.status ?? "all"),
|
|
622
|
+
limit: options.limit,
|
|
623
|
+
});
|
|
624
|
+
writeQueueJsonOrText("db-queue-list", { queue_name: requireQueueName(options), count: messages.length, messages }, options.json);
|
|
625
|
+
}
|
|
626
|
+
function runDbQueueShowCommand(options) {
|
|
627
|
+
const databasePath = loadQueueDatabasePath(options.root);
|
|
628
|
+
const queueName = requireQueueName(options);
|
|
629
|
+
const messageId = requireMessageId(options);
|
|
630
|
+
const message = (0, project_db_queue_1.readProjectQueueMessage)(databasePath, queueName, messageId);
|
|
631
|
+
if (!message) {
|
|
632
|
+
throw new errors_1.NotFoundError(`queue message not found: ${queueName}/${messageId}`);
|
|
633
|
+
}
|
|
634
|
+
writeQueueJsonOrText("db-queue-show", { message }, options.json);
|
|
635
|
+
}
|
|
452
636
|
function printSnapshotChecks(payload) {
|
|
453
637
|
for (const check of payload.checks) {
|
|
454
638
|
const location = check.path ? ` (${path_1.default.isAbsolute(check.path) ? rel(process.cwd(), check.path) : check.path})` : "";
|
|
@@ -457,7 +641,7 @@ function printSnapshotChecks(payload) {
|
|
|
457
641
|
}
|
|
458
642
|
function runDbSnapshotSealCommandLocked(options) {
|
|
459
643
|
const config = (0, config_1.loadConfig)(options.root);
|
|
460
|
-
const payload = (0, project_db_snapshot_1.sealProjectDbSnapshot)(options.root, config);
|
|
644
|
+
const payload = (0, project_db_snapshot_1.sealProjectDbSnapshot)(options.root, config, options.queuePolicy ?? "drain");
|
|
461
645
|
if (options.json) {
|
|
462
646
|
console.log(JSON.stringify(payload, null, 2));
|
|
463
647
|
return;
|
package/dist/commands/format.js
CHANGED
|
@@ -37,7 +37,7 @@ const EXTERNAL_REF_LIST_KEYS = new Set([
|
|
|
37
37
|
"proof_refs",
|
|
38
38
|
"attestation_refs",
|
|
39
39
|
]);
|
|
40
|
-
const HASH_REF_LIST_KEYS = new Set(["input_hashes", "output_hashes"]);
|
|
40
|
+
const HASH_REF_LIST_KEYS = new Set(["evidence_hashes", "input_hashes", "output_hashes"]);
|
|
41
41
|
function isValidId(value) {
|
|
42
42
|
return (0, id_1.isCanonicalId)(value);
|
|
43
43
|
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runSpecListCommand = runSpecListCommand;
|
|
4
|
+
exports.runSpecShowCommand = runSpecShowCommand;
|
|
5
|
+
exports.runSpecValidateCommand = runSpecValidateCommand;
|
|
6
|
+
const capability_1 = require("./capability");
|
|
7
|
+
const validate_1 = require("./validate");
|
|
8
|
+
const errors_1 = require("../util/errors");
|
|
9
|
+
function sortSpecRecords(records) {
|
|
10
|
+
return [...records].sort((a, b) => {
|
|
11
|
+
const qidDelta = a.qid.localeCompare(b.qid);
|
|
12
|
+
if (qidDelta !== 0) {
|
|
13
|
+
return qidDelta;
|
|
14
|
+
}
|
|
15
|
+
return a.path.localeCompare(b.path);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
function loadSpecRecords(options) {
|
|
19
|
+
const listOptions = {
|
|
20
|
+
root: options.root,
|
|
21
|
+
kind: "spec",
|
|
22
|
+
noCache: options.noCache,
|
|
23
|
+
noReindex: options.noReindex,
|
|
24
|
+
};
|
|
25
|
+
return sortSpecRecords((0, capability_1.filterCapabilityRecords)((0, capability_1.loadCapabilityRecords)(listOptions), listOptions));
|
|
26
|
+
}
|
|
27
|
+
function matchesSpecRef(record, id) {
|
|
28
|
+
const normalized = id.toLowerCase();
|
|
29
|
+
return (record.id === id ||
|
|
30
|
+
record.qid === id ||
|
|
31
|
+
record.path === id ||
|
|
32
|
+
record.id.toLowerCase() === normalized ||
|
|
33
|
+
record.qid.toLowerCase() === normalized ||
|
|
34
|
+
record.path.toLowerCase() === normalized ||
|
|
35
|
+
record.aliases.some((alias) => alias.toLowerCase() === normalized));
|
|
36
|
+
}
|
|
37
|
+
function resolveSpecRecord(records, id) {
|
|
38
|
+
const matches = records.filter((record) => matchesSpecRef(record, id));
|
|
39
|
+
if (matches.length === 1) {
|
|
40
|
+
return matches[0];
|
|
41
|
+
}
|
|
42
|
+
if (matches.length > 1) {
|
|
43
|
+
throw new errors_1.UsageError(`SPEC reference is ambiguous: ${id}`);
|
|
44
|
+
}
|
|
45
|
+
throw new errors_1.NotFoundError(`SPEC not found: ${id}`);
|
|
46
|
+
}
|
|
47
|
+
function stringValue(value) {
|
|
48
|
+
return typeof value === "string" ? value : undefined;
|
|
49
|
+
}
|
|
50
|
+
function stringArrayValue(value) {
|
|
51
|
+
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
52
|
+
}
|
|
53
|
+
function printSpecList(records, json) {
|
|
54
|
+
if (json) {
|
|
55
|
+
console.log(JSON.stringify({
|
|
56
|
+
kind: "spec",
|
|
57
|
+
count: records.length,
|
|
58
|
+
items: records,
|
|
59
|
+
}, null, 2));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (records.length === 0) {
|
|
63
|
+
console.log("no SPEC.md capabilities found");
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
console.log(`SPEC.md capabilities: ${records.length}`);
|
|
67
|
+
for (const record of records) {
|
|
68
|
+
const kind = stringValue(record.spec?.spec_kind);
|
|
69
|
+
const kindLabel = kind ? ` | ${kind}` : "";
|
|
70
|
+
console.log(`${record.qid} | ${record.visibility}${kindLabel} | ${record.title}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function printSpec(record, json) {
|
|
74
|
+
if (json) {
|
|
75
|
+
console.log(JSON.stringify({ kind: "spec", item: record }, null, 2));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
console.log(`${record.qid} | ${record.visibility}`);
|
|
79
|
+
console.log(`title: ${record.title}`);
|
|
80
|
+
const specKind = stringValue(record.spec?.spec_kind);
|
|
81
|
+
if (specKind) {
|
|
82
|
+
console.log(`spec_kind: ${specKind}`);
|
|
83
|
+
}
|
|
84
|
+
console.log(`path: ${record.path}`);
|
|
85
|
+
const requestedCapabilities = stringArrayValue(record.spec?.requested_capabilities);
|
|
86
|
+
if (requestedCapabilities.length > 0) {
|
|
87
|
+
console.log(`requested_capabilities: ${requestedCapabilities.join(", ")}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function runSpecListCommand(options) {
|
|
91
|
+
printSpecList(loadSpecRecords(options), options.json);
|
|
92
|
+
}
|
|
93
|
+
function runSpecShowCommand(options) {
|
|
94
|
+
printSpec(resolveSpecRecord(loadSpecRecords(options), options.id), options.json);
|
|
95
|
+
}
|
|
96
|
+
function runSpecValidateCommand(options) {
|
|
97
|
+
if (options.id) {
|
|
98
|
+
resolveSpecRecord(loadSpecRecords(options), options.id);
|
|
99
|
+
}
|
|
100
|
+
(0, validate_1.runValidateCommand)({ root: options.root, json: options.json });
|
|
101
|
+
}
|