mdkg 0.2.0 → 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 +44 -1
- package/README.md +26 -4
- package/dist/cli.js +146 -7
- package/dist/commands/capability.js +13 -8
- package/dist/commands/format.js +1 -1
- package/dist/commands/spec.js +101 -0
- package/dist/commands/work.js +569 -20
- 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 +5 -1
- package/dist/init/CLI_COMMAND_MATRIX.md +23 -0
- package/dist/init/README.md +25 -2
- package/dist/init/init-manifest.json +20 -20
- 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/specs/agent.SPEC.md +45 -4
- package/dist/init/templates/specs/api.SPEC.md +1 -0
- package/dist/init/templates/specs/base.SPEC.md +45 -12
- package/dist/init/templates/specs/capability.SPEC.md +16 -3
- package/dist/init/templates/specs/integration.SPEC.md +1 -0
- package/dist/init/templates/specs/model.SPEC.md +1 -0
- package/dist/init/templates/specs/project.SPEC.md +14 -1
- package/dist/init/templates/specs/{omniruntime-agent.SPEC.md → runtime-agent.SPEC.md} +13 -3
- package/dist/init/templates/specs/runtime-image.SPEC.md +1 -0
- package/dist/init/templates/specs/tool.SPEC.md +1 -0
- package/dist/util/argparse.js +8 -0
- package/package.json +4 -2
package/CHANGELOG.md
CHANGED
|
@@ -6,7 +6,50 @@ This project follows a pragmatic changelog style inspired by Keep a Changelog. V
|
|
|
6
6
|
|
|
7
7
|
mdkg is pre-v1 public alpha software. Command, graph, cache, bundle, and DAL contracts may change quickly while the project converges on a stable v1 surface.
|
|
8
8
|
|
|
9
|
-
## 0.
|
|
9
|
+
## 0.3.0 - Unreleased
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Added optional `SPEC.md` reusable capability records with strict validation
|
|
14
|
+
for supported `spec_kind` values and diagnostics that reject documentation-only
|
|
15
|
+
misuse while keeping repos without SPEC files valid.
|
|
16
|
+
- Added focused `mdkg spec list/show/validate` commands for optional SPEC
|
|
17
|
+
capability discovery alongside the broader `mdkg capability ...` surface.
|
|
18
|
+
- Added a dogfood mdkg CLI `SPEC.md` and linked `WORK.md` contract so the CLI's
|
|
19
|
+
graph, project DB, skill, and tool capabilities are discoverable through the
|
|
20
|
+
same capability index used by downstream repos.
|
|
21
|
+
- Added deterministic `mdkg work trigger`, `mdkg work order status`, and
|
|
22
|
+
`mdkg work receipt verify` helpers for creating submitted work-order mirrors,
|
|
23
|
+
reviewing order/receipt linkage, and validating receipt evidence without
|
|
24
|
+
executing work.
|
|
25
|
+
- Added optional `mdkg work trigger --enqueue <queue>` delivery bridging to the
|
|
26
|
+
public local project DB queue surface. The bridge requires an initialized,
|
|
27
|
+
migrated, verified DB and an explicitly created active queue, records
|
|
28
|
+
delivery refs, and still does not execute work.
|
|
29
|
+
- Added read-only SPEC/WORK capability linkage arrays for related specs, work
|
|
30
|
+
contracts, work orders, and receipts.
|
|
31
|
+
- Added packed `smoke:work-invocation` coverage for trigger-to-order-to-receipt
|
|
32
|
+
verification plus queue bridge delivery from an installed tarball.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- Hardened default SPEC, WORK, WORK_ORDER, and RECEIPT templates with capability
|
|
37
|
+
metadata, payload hashes, queue refs, evidence hashes, redaction policies, and
|
|
38
|
+
explicit semantic-mirror boundaries.
|
|
39
|
+
- Updated README, command matrix, help snapshots, init assets, and upgrade
|
|
40
|
+
smokes for optional SPEC adoption, work invocation helpers, queue bridge
|
|
41
|
+
behavior, capability linkage, and no-SPEC backward compatibility.
|
|
42
|
+
- Strengthened init and upgrade smokes so fresh workspaces can remain SPEC-free
|
|
43
|
+
while optional SPEC/WORK templates can be created and validated on demand.
|
|
44
|
+
|
|
45
|
+
### Security
|
|
46
|
+
|
|
47
|
+
- Audited templates, docs, dogfood mirrors, and work invocation command paths for
|
|
48
|
+
no-secret and semantic-mirror boundaries before the 0.3.0 release metadata
|
|
49
|
+
bump. No raw secret, credential, payment, ledger, or canonical production
|
|
50
|
+
state values were identified.
|
|
51
|
+
|
|
52
|
+
## 0.2.0 - 2026-06-06
|
|
10
53
|
|
|
11
54
|
Release numbering note: future project DB materializer/profile release planning
|
|
12
55
|
should follow `0.1.9 -> 0.2.0` rather than continuing the line as `0.1.10`
|
package/README.md
CHANGED
|
@@ -167,8 +167,16 @@ mdkg index
|
|
|
167
167
|
mdkg capability list --kind skill --json
|
|
168
168
|
mdkg capability search "image worker" --kind work --json
|
|
169
169
|
mdkg capability show <id-or-qid-or-slug> --json
|
|
170
|
+
mdkg spec list --json
|
|
171
|
+
mdkg spec show <id-or-qid-or-alias> --json
|
|
170
172
|
```
|
|
171
173
|
|
|
174
|
+
`SPEC.md` is optional. Repos with no SPEC files still validate; when present,
|
|
175
|
+
SPEC records describe reusable capability surfaces rather than general planning
|
|
176
|
+
notes. `mdkg spec list/show/validate` is the focused SPEC command family, while
|
|
177
|
+
`mdkg capability ...` remains the broader read-only discovery surface for
|
|
178
|
+
skills, SPECs, WORK contracts, core docs, and design docs.
|
|
179
|
+
|
|
172
180
|
Register source and artifact files as committed archive sidecars:
|
|
173
181
|
|
|
174
182
|
```bash
|
|
@@ -181,11 +189,20 @@ Create semantic mirror work contracts, orders, receipts, and artifacts:
|
|
|
181
189
|
|
|
182
190
|
```bash
|
|
183
191
|
mdkg work contract new "generate image" --id work.generate-image --agent-id agent.image-worker --kind image_generation --inputs prompt:text:required --outputs image_url:url:required
|
|
184
|
-
mdkg work
|
|
192
|
+
mdkg work trigger work.generate-image --id order.generate-image-1 --requester user://example
|
|
193
|
+
mdkg work order status order.generate-image-1 --json
|
|
185
194
|
mdkg work receipt new "generate image receipt" --id receipt.generate-image-1 --work-order-id order.generate-image-1 --outcome success --receipt-status recorded
|
|
195
|
+
mdkg work receipt verify receipt.generate-image-1 --json
|
|
186
196
|
mdkg work artifact add receipt.generate-image-1 ./outputs/image.png --id archive.generated-image --kind artifact
|
|
187
197
|
```
|
|
188
198
|
|
|
199
|
+
Create a manual order instead of a trigger-created order when you need to supply
|
|
200
|
+
input refs at order creation time:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
mdkg work order new "generate image request" --id order.generate-image-manual --work-id work.generate-image --requester user://example --input-refs archive://archive.key-input-doc
|
|
204
|
+
```
|
|
205
|
+
|
|
189
206
|
Receipt statuses are `recorded`, `verified`, `rejected`, and `superseded`.
|
|
190
207
|
Update and artifact commands accept local ids or local qids; subgraph qids are read-only and must be changed in their source workspace.
|
|
191
208
|
|
|
@@ -254,6 +271,7 @@ These are the commands new users and agents should learn first:
|
|
|
254
271
|
- `mdkg pack`
|
|
255
272
|
- `mdkg skill`
|
|
256
273
|
- `mdkg capability`
|
|
274
|
+
- `mdkg spec`
|
|
257
275
|
- `mdkg archive`
|
|
258
276
|
- `mdkg work`
|
|
259
277
|
- `mdkg goal`
|
|
@@ -326,7 +344,7 @@ mdkg maintains `.mdkg/index/capabilities.json` as a derived access cache for det
|
|
|
326
344
|
|
|
327
345
|
The capability cache is not the full graph and is not source of truth. Normal tasks, epics, bugs, tests, feats, and checkpoints remain in the standard graph index. Markdown remains authoritative; deleting the cache is recoverable with `mdkg index` or by running a capability command when auto-reindex is enabled.
|
|
328
346
|
|
|
329
|
-
Capability records aggregate enabled registered workspaces and include deterministic source metadata such as `workspace`, `visibility`, `kind`, `id`, `qid`, `path`, headings, refs, source hash, and `indexed_at`. Workspace `visibility` also feeds mdkg's export safety checks for public/internal packs and public bundles. This is a CLI safety layer, not secret scanning, body redaction, or a replacement for private git hosting.
|
|
347
|
+
Capability records aggregate enabled registered workspaces and include deterministic source metadata such as `workspace`, `visibility`, `kind`, `id`, `qid`, `path`, headings, refs, source hash, and `indexed_at`. SPEC and WORK records also expose read-only `linkage` arrays when related work contracts, work orders, and receipts exist, so an orchestrator can discover a capability from reusable surface to invocation evidence without loading the full graph. Workspace `visibility` also feeds mdkg's export safety checks for public/internal packs and public bundles. This is a CLI safety layer, not secret scanning, body redaction, or a replacement for private git hosting.
|
|
330
348
|
|
|
331
349
|
## Index backends and parallel safety
|
|
332
350
|
|
|
@@ -360,6 +378,9 @@ rows are durable local project DB history; receipts, reducers, writer leases,
|
|
|
360
378
|
and materializers remain internal helper surfaces in this release, with no
|
|
361
379
|
public `mdkg db event`, `mdkg db reducer`, `mdkg db lease`, or
|
|
362
380
|
`mdkg db materializer` CLI yet.
|
|
381
|
+
`mdkg work trigger --enqueue <queue>` can bridge a submitted work order mirror
|
|
382
|
+
into an explicitly created active project DB queue; it writes local delivery
|
|
383
|
+
state only and never executes work.
|
|
363
384
|
Use `mdkg db verify` for non-mutating health checks over config, layout,
|
|
364
385
|
runtime SQLite integrity, migration metadata, and transient runtime files. Use
|
|
365
386
|
`mdkg db stats` for deterministic table counts, DB size, migration state,
|
|
@@ -401,7 +422,7 @@ Use `mdkg new spec|work|work_order|receipt|feedback|dispute|proposal "<title>"`
|
|
|
401
422
|
|
|
402
423
|
Relational templates contain editable placeholder refs. `spec` and `work` scaffold as validation-clean standalone docs; `work_order`, `receipt`, `feedback`, `dispute`, and `proposal` need real refs before strict `mdkg validate` passes.
|
|
403
424
|
|
|
404
|
-
For executable or purchasable capability mirrors, prefer the lifecycle helpers under `mdkg work ...`. They create and update `WORK.md`, `WORK_ORDER.md`, and `RECEIPT.md` semantic mirror files only. Production order state, receipt state, feedback, disputes, payments, ledgers, marketplace inventory, fulfillment records, and execution state remain canonical outside mdkg, such as in Postgres or another application database. Do not store raw secrets, credentials, live payment state, ledger mutations, canonical marketplace state, or bulky raw payloads in these mirrors.
|
|
425
|
+
For executable or purchasable capability mirrors, prefer the lifecycle helpers under `mdkg work ...`. They create and update `WORK.md`, `WORK_ORDER.md`, and `RECEIPT.md` semantic mirror files only. `mdkg work trigger` creates a deterministic submitted `WORK_ORDER.md` from a WORK contract or a SPEC with exactly one resolvable work contract. `mdkg work order status` and `mdkg work receipt verify` are read-only review helpers for deterministic closeout. `mdkg work trigger --enqueue <queue>` optionally writes a local project DB queue delivery message after the queue has been explicitly created and is active; it still does not execute work. Production order state, receipt state, feedback, disputes, payments, ledgers, marketplace inventory, fulfillment records, and execution state remain canonical outside mdkg, such as in Postgres or another application database. Do not store raw secrets, credentials, live payment state, ledger mutations, canonical marketplace state, or bulky raw payloads in these mirrors.
|
|
405
426
|
|
|
406
427
|
## Archive sidecars
|
|
407
428
|
|
|
@@ -423,6 +444,7 @@ This release includes:
|
|
|
423
444
|
- root-only published init seed config
|
|
424
445
|
- skills indexing and search/show/list support
|
|
425
446
|
- JSON capability cache for skills, `SPEC.md`, `WORK.md`, core docs, and design docs
|
|
447
|
+
- optional `mdkg spec list/show/validate` for reusable SPEC capability records
|
|
426
448
|
- SQLite index backend for fresh workspaces using built-in `node:sqlite`
|
|
427
449
|
- mutation locking and atomic writes for parallel mdkg calls
|
|
428
450
|
- first-class `goal` nodes and `mdkg goal show/next/evaluate/pause/resume/done`
|
|
@@ -436,7 +458,7 @@ This release includes:
|
|
|
436
458
|
- shared `AGENT_START.md` startup guidance
|
|
437
459
|
- conservative `mdkg upgrade` with mode-aware init manifests
|
|
438
460
|
- archive sidecars with deterministic ZIP caches
|
|
439
|
-
- semantic mirror helpers under `mdkg work
|
|
461
|
+
- semantic mirror helpers under `mdkg work ...`, including trigger/order status/receipt verification
|
|
440
462
|
- explicit public/internal/private visibility enforcement for packs, bundles, archives, imports, validation, and doctor diagnostics
|
|
441
463
|
- strict archive ZIP payload integrity checks during validation
|
|
442
464
|
|
package/dist/cli.js
CHANGED
|
@@ -20,6 +20,7 @@ const format_1 = require("./commands/format");
|
|
|
20
20
|
const doctor_1 = require("./commands/doctor");
|
|
21
21
|
const db_1 = require("./commands/db");
|
|
22
22
|
const capability_1 = require("./commands/capability");
|
|
23
|
+
const spec_1 = require("./commands/spec");
|
|
23
24
|
const archive_1 = require("./commands/archive");
|
|
24
25
|
const bundle_1 = require("./commands/bundle");
|
|
25
26
|
const subgraph_1 = require("./commands/subgraph");
|
|
@@ -63,6 +64,7 @@ function printUsage(log) {
|
|
|
63
64
|
log(" pack Generate a context pack");
|
|
64
65
|
log(" skill Create, list, show, search, and validate skills");
|
|
65
66
|
log(" capability List, search, show, and resolve cached capability surfaces");
|
|
67
|
+
log(" spec List, show, and validate optional SPEC.md capability records");
|
|
66
68
|
log(" archive Add, list, show, verify, and compress archive sidecars");
|
|
67
69
|
log(" bundle Create, list, show, and verify full graph snapshot bundles");
|
|
68
70
|
log(" subgraph Register, sync, materialize, and verify read-only child graph snapshots");
|
|
@@ -435,6 +437,41 @@ function printCapabilityHelp(log, subcommand) {
|
|
|
435
437
|
printGlobalOptions(log);
|
|
436
438
|
}
|
|
437
439
|
}
|
|
440
|
+
function printSpecHelp(log, subcommand) {
|
|
441
|
+
switch ((subcommand ?? "").toLowerCase()) {
|
|
442
|
+
case "list":
|
|
443
|
+
log("Usage:");
|
|
444
|
+
log(" mdkg spec list [--json]");
|
|
445
|
+
log("\nNotes:");
|
|
446
|
+
log(" SPEC.md is optional and declares reusable capability surfaces.");
|
|
447
|
+
printGlobalOptions(log);
|
|
448
|
+
return;
|
|
449
|
+
case "show":
|
|
450
|
+
log("Usage:");
|
|
451
|
+
log(" mdkg spec show <id-or-qid-or-alias> [--json]");
|
|
452
|
+
log("\nNotes:");
|
|
453
|
+
log(" Shows one optional SPEC.md capability record from the capability index.");
|
|
454
|
+
printGlobalOptions(log);
|
|
455
|
+
return;
|
|
456
|
+
case "validate":
|
|
457
|
+
log("Usage:");
|
|
458
|
+
log(" mdkg spec validate [<id-or-qid-or-alias>] [--json]");
|
|
459
|
+
log("\nNotes:");
|
|
460
|
+
log(" With no reference, validates the graph and all optional SPEC.md capability records.");
|
|
461
|
+
log(" With a reference, also ensures that specific SPEC.md capability exists.");
|
|
462
|
+
printGlobalOptions(log);
|
|
463
|
+
return;
|
|
464
|
+
default:
|
|
465
|
+
log("Usage:");
|
|
466
|
+
log(" mdkg spec list [--json]");
|
|
467
|
+
log(" mdkg spec show <id-or-qid-or-alias> [--json]");
|
|
468
|
+
log(" mdkg spec validate [<id-or-qid-or-alias>] [--json]");
|
|
469
|
+
log("\nNotes:");
|
|
470
|
+
log(" SPEC.md is optional and reusable-capability oriented.");
|
|
471
|
+
log(" Use `mdkg capability ...` for broader skill, SPEC.md, WORK.md, core-doc, and design-doc discovery.");
|
|
472
|
+
printGlobalOptions(log);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
438
475
|
function printArchiveHelp(log, subcommand) {
|
|
439
476
|
switch ((subcommand ?? "").toLowerCase()) {
|
|
440
477
|
case "add":
|
|
@@ -580,15 +617,31 @@ function printWorkHelp(log, subcommand) {
|
|
|
580
617
|
log("Usage:");
|
|
581
618
|
log(' mdkg work contract new "<title>" --id <work.id> --agent-id <agent.id> --kind <kind> --inputs <...> --outputs <...> [--required-capabilities <...>] [--pricing-model <...>] [--json]');
|
|
582
619
|
break;
|
|
620
|
+
case "trigger":
|
|
621
|
+
log("Usage:");
|
|
622
|
+
log(' mdkg work trigger <work-or-capability-ref> [--id <order.id>] [--title "<title>"] [--requester <ref>] [--enqueue <queue>] [--json]');
|
|
623
|
+
log("\nExample:");
|
|
624
|
+
log(" mdkg work trigger work.example --id order.example-1 --requester user://example --json");
|
|
625
|
+
log("\nNotes:");
|
|
626
|
+
log(" Accepted targets: direct WORK.md ref, or SPEC.md ref with exactly one resolvable work contract.");
|
|
627
|
+
log(" Creates a deterministic WORK_ORDER.md semantic mirror and does not execute work.");
|
|
628
|
+
log(" Queue enqueue requires a valid project DB plus an explicitly created active queue and never executes work.");
|
|
629
|
+
break;
|
|
583
630
|
case "order":
|
|
584
631
|
log("Usage:");
|
|
585
|
-
log(' mdkg work order new "<title>" --id <order.id> --work-id <work.id> --requester <ref> [--request-ref <ref>] [--input-refs <...>] [--requested-outputs <...>] [--json]');
|
|
586
|
-
log(" mdkg work order
|
|
632
|
+
log(' mdkg work order new "<title>" --id <order.id> --work-id <work.id> --requester <ref> [--request-ref <ref>] [--trigger-ref <ref>] [--payload-hash <sha256:...>] [--input-refs <...>] [--queue-refs <...>] [--requested-outputs <...>] [--json]');
|
|
633
|
+
log(" mdkg work order status <id-or-qid> [--json]");
|
|
634
|
+
log(" mdkg work order update <id-or-qid> [--status <status>] [--add-input-refs <...>] [--add-queue-refs <...>] [--add-artifacts <...>] [--json]");
|
|
635
|
+
log("\nNotes:");
|
|
636
|
+
log(" work order status is read-only and reports deterministic JSON order state plus linked receipts.");
|
|
587
637
|
break;
|
|
588
638
|
case "receipt":
|
|
589
639
|
log("Usage:");
|
|
590
|
-
log(' mdkg work receipt new "<title>" --id <receipt.id> --work-order-id <order.id> --outcome success|partial|failure [--receipt-status recorded|verified|rejected|superseded] [--json]');
|
|
591
|
-
log(" mdkg work receipt
|
|
640
|
+
log(' mdkg work receipt new "<title>" --id <receipt.id> --work-order-id <order.id> --outcome success|partial|failure [--receipt-status recorded|verified|rejected|superseded] [--redaction-policy refs_and_hashes_only|redacted_summary|external_private] [--evidence-hashes <sha256:...>] [--json]');
|
|
641
|
+
log(" mdkg work receipt verify <id-or-qid> [--json]");
|
|
642
|
+
log(" mdkg work receipt update <id-or-qid> [--receipt-status <status>] [--add-artifacts <...>] [--add-proof-refs <...>] [--add-attestation-refs <...>] [--add-evidence-hashes <sha256:...>] [--json]");
|
|
643
|
+
log("\nNotes:");
|
|
644
|
+
log(" work receipt verify is read-only and reports deterministic JSON linkage, evidence, hash, outcome, and redaction checks.");
|
|
592
645
|
break;
|
|
593
646
|
case "artifact":
|
|
594
647
|
log("Usage:");
|
|
@@ -597,8 +650,9 @@ function printWorkHelp(log, subcommand) {
|
|
|
597
650
|
default:
|
|
598
651
|
log("Usage:");
|
|
599
652
|
log(" mdkg work contract new ...");
|
|
600
|
-
log(" mdkg work
|
|
601
|
-
log(" mdkg work
|
|
653
|
+
log(" mdkg work trigger <work-or-capability-ref> ...");
|
|
654
|
+
log(" mdkg work order new|status|update ...");
|
|
655
|
+
log(" mdkg work receipt new|verify|update ...");
|
|
602
656
|
log(" mdkg work artifact add ...");
|
|
603
657
|
log("\nNotes:");
|
|
604
658
|
log(" - work commands mutate semantic mirror files only");
|
|
@@ -837,6 +891,9 @@ function printCommandHelp(log, command, subcommand) {
|
|
|
837
891
|
case "capability":
|
|
838
892
|
printCapabilityHelp(log, subcommand);
|
|
839
893
|
return;
|
|
894
|
+
case "spec":
|
|
895
|
+
printSpecHelp(log, subcommand);
|
|
896
|
+
return;
|
|
840
897
|
case "archive":
|
|
841
898
|
printArchiveHelp(log, subcommand);
|
|
842
899
|
return;
|
|
@@ -1353,6 +1410,45 @@ function runCapabilitySubcommand(parsed, root) {
|
|
|
1353
1410
|
throw new errors_1.UsageError("capability requires list/search/show/resolve");
|
|
1354
1411
|
}
|
|
1355
1412
|
}
|
|
1413
|
+
function runSpecSubcommand(parsed, root) {
|
|
1414
|
+
const subcommand = (parsed.positionals[1] ?? "").toLowerCase();
|
|
1415
|
+
switch (subcommand) {
|
|
1416
|
+
case "list": {
|
|
1417
|
+
if (parsed.positionals.length > 2) {
|
|
1418
|
+
throw new errors_1.UsageError("spec list does not accept positional arguments");
|
|
1419
|
+
}
|
|
1420
|
+
const json = parseBooleanFlag("--json", parsed.flags["--json"]);
|
|
1421
|
+
const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
|
|
1422
|
+
const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
|
|
1423
|
+
(0, spec_1.runSpecListCommand)({ root, json, noCache, noReindex });
|
|
1424
|
+
return 0;
|
|
1425
|
+
}
|
|
1426
|
+
case "show": {
|
|
1427
|
+
const id = parsed.positionals[2];
|
|
1428
|
+
if (!id || parsed.positionals.length > 3) {
|
|
1429
|
+
throw new errors_1.UsageError("spec show requires <id-or-qid-or-alias>");
|
|
1430
|
+
}
|
|
1431
|
+
const json = parseBooleanFlag("--json", parsed.flags["--json"]);
|
|
1432
|
+
const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
|
|
1433
|
+
const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
|
|
1434
|
+
(0, spec_1.runSpecShowCommand)({ root, id, json, noCache, noReindex });
|
|
1435
|
+
return 0;
|
|
1436
|
+
}
|
|
1437
|
+
case "validate": {
|
|
1438
|
+
const id = parsed.positionals[2];
|
|
1439
|
+
if (parsed.positionals.length > 3) {
|
|
1440
|
+
throw new errors_1.UsageError("spec validate accepts at most one SPEC reference");
|
|
1441
|
+
}
|
|
1442
|
+
const json = parseBooleanFlag("--json", parsed.flags["--json"]);
|
|
1443
|
+
const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
|
|
1444
|
+
const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
|
|
1445
|
+
(0, spec_1.runSpecValidateCommand)({ root, id, json, noCache, noReindex });
|
|
1446
|
+
return 0;
|
|
1447
|
+
}
|
|
1448
|
+
default:
|
|
1449
|
+
throw new errors_1.UsageError("spec requires list/show/validate");
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1356
1452
|
function runArchiveSubcommand(parsed, root) {
|
|
1357
1453
|
const subcommand = (parsed.positionals[1] ?? "").toLowerCase();
|
|
1358
1454
|
switch (subcommand) {
|
|
@@ -1587,6 +1683,18 @@ function runWorkSubcommand(parsed, root) {
|
|
|
1587
1683
|
const action = (parsed.positionals[2] ?? "").toLowerCase();
|
|
1588
1684
|
const ws = requireFlagValue("--ws", parsed.flags["--ws"]);
|
|
1589
1685
|
const json = parseBooleanFlag("--json", parsed.flags["--json"]);
|
|
1686
|
+
if (domain === "trigger") {
|
|
1687
|
+
const targetRef = parsed.positionals[2];
|
|
1688
|
+
if (!targetRef || parsed.positionals.length > 3) {
|
|
1689
|
+
throw new errors_1.UsageError("work trigger requires <work-or-capability-ref>");
|
|
1690
|
+
}
|
|
1691
|
+
const id = requireFlagValue("--id", parsed.flags["--id"]);
|
|
1692
|
+
const title = requireFlagValue("--title", parsed.flags["--title"]);
|
|
1693
|
+
const requester = requireFlagValue("--requester", parsed.flags["--requester"]);
|
|
1694
|
+
const enqueue = requireFlagValue("--enqueue", parsed.flags["--enqueue"]);
|
|
1695
|
+
(0, work_1.runWorkTriggerCommand)({ root, ws, targetRef, id, title, requester, enqueue, json });
|
|
1696
|
+
return 0;
|
|
1697
|
+
}
|
|
1590
1698
|
if (domain === "contract" && action === "new") {
|
|
1591
1699
|
const title = parsed.positionals.slice(3).join(" ");
|
|
1592
1700
|
const id = requireFlagValue("--id", parsed.flags["--id"]);
|
|
@@ -1623,7 +1731,10 @@ function runWorkSubcommand(parsed, root) {
|
|
|
1623
1731
|
throw new errors_1.UsageError("work order new requires title, --id, --work-id, and --requester");
|
|
1624
1732
|
}
|
|
1625
1733
|
const requestRef = requireFlagValue("--request-ref", parsed.flags["--request-ref"]);
|
|
1734
|
+
const triggerRef = requireFlagValue("--trigger-ref", parsed.flags["--trigger-ref"]);
|
|
1735
|
+
const payloadHash = requireFlagValue("--payload-hash", parsed.flags["--payload-hash"]);
|
|
1626
1736
|
const inputRefs = requireFlagValue("--input-refs", parsed.flags["--input-refs"]);
|
|
1737
|
+
const queueRefs = requireFlagValue("--queue-refs", parsed.flags["--queue-refs"]);
|
|
1627
1738
|
const requestedOutputs = requireFlagValue("--requested-outputs", parsed.flags["--requested-outputs"]);
|
|
1628
1739
|
const constraintRefs = requireFlagValue("--constraint-refs", parsed.flags["--constraint-refs"]);
|
|
1629
1740
|
(0, work_1.runWorkOrderNewCommand)({
|
|
@@ -1634,7 +1745,10 @@ function runWorkSubcommand(parsed, root) {
|
|
|
1634
1745
|
workId,
|
|
1635
1746
|
requester,
|
|
1636
1747
|
requestRef,
|
|
1748
|
+
triggerRef,
|
|
1749
|
+
payloadHash,
|
|
1637
1750
|
inputRefs,
|
|
1751
|
+
queueRefs,
|
|
1638
1752
|
requestedOutputs,
|
|
1639
1753
|
constraintRefs,
|
|
1640
1754
|
json,
|
|
@@ -1648,8 +1762,17 @@ function runWorkSubcommand(parsed, root) {
|
|
|
1648
1762
|
}
|
|
1649
1763
|
const status = requireFlagValue("--status", parsed.flags["--status"]);
|
|
1650
1764
|
const addInputRefs = requireFlagValue("--add-input-refs", parsed.flags["--add-input-refs"]);
|
|
1765
|
+
const addQueueRefs = requireFlagValue("--add-queue-refs", parsed.flags["--add-queue-refs"]);
|
|
1651
1766
|
const addArtifacts = requireFlagValue("--add-artifacts", parsed.flags["--add-artifacts"]);
|
|
1652
|
-
(0, work_1.runWorkOrderUpdateCommand)({ root, ws, id, status, addInputRefs, addArtifacts, json });
|
|
1767
|
+
(0, work_1.runWorkOrderUpdateCommand)({ root, ws, id, status, addInputRefs, addQueueRefs, addArtifacts, json });
|
|
1768
|
+
return 0;
|
|
1769
|
+
}
|
|
1770
|
+
if (domain === "order" && action === "status") {
|
|
1771
|
+
const id = parsed.positionals[3];
|
|
1772
|
+
if (!id || parsed.positionals.length > 4) {
|
|
1773
|
+
throw new errors_1.UsageError("work order status requires <id-or-qid>");
|
|
1774
|
+
}
|
|
1775
|
+
(0, work_1.runWorkOrderStatusCommand)({ root, ws, id, json });
|
|
1653
1776
|
return 0;
|
|
1654
1777
|
}
|
|
1655
1778
|
if (domain === "receipt" && action === "new") {
|
|
@@ -1662,9 +1785,11 @@ function runWorkSubcommand(parsed, root) {
|
|
|
1662
1785
|
}
|
|
1663
1786
|
const receiptStatus = requireFlagValue("--receipt-status", parsed.flags["--receipt-status"]);
|
|
1664
1787
|
const costRef = requireFlagValue("--cost-ref", parsed.flags["--cost-ref"]);
|
|
1788
|
+
const redactionPolicy = requireFlagValue("--redaction-policy", parsed.flags["--redaction-policy"]);
|
|
1665
1789
|
const artifacts = requireFlagValue("--artifacts", parsed.flags["--artifacts"]);
|
|
1666
1790
|
const proofRefs = requireFlagValue("--proof-refs", parsed.flags["--proof-refs"]);
|
|
1667
1791
|
const attestationRefs = requireFlagValue("--attestation-refs", parsed.flags["--attestation-refs"]);
|
|
1792
|
+
const evidenceHashes = requireFlagValue("--evidence-hashes", parsed.flags["--evidence-hashes"]);
|
|
1668
1793
|
const inputHashes = requireFlagValue("--input-hashes", parsed.flags["--input-hashes"]);
|
|
1669
1794
|
const outputHashes = requireFlagValue("--output-hashes", parsed.flags["--output-hashes"]);
|
|
1670
1795
|
(0, work_1.runWorkReceiptNewCommand)({
|
|
@@ -1676,9 +1801,11 @@ function runWorkSubcommand(parsed, root) {
|
|
|
1676
1801
|
outcome,
|
|
1677
1802
|
receiptStatus,
|
|
1678
1803
|
costRef,
|
|
1804
|
+
redactionPolicy,
|
|
1679
1805
|
artifacts,
|
|
1680
1806
|
proofRefs,
|
|
1681
1807
|
attestationRefs,
|
|
1808
|
+
evidenceHashes,
|
|
1682
1809
|
inputHashes,
|
|
1683
1810
|
outputHashes,
|
|
1684
1811
|
json,
|
|
@@ -1694,6 +1821,7 @@ function runWorkSubcommand(parsed, root) {
|
|
|
1694
1821
|
const addArtifacts = requireFlagValue("--add-artifacts", parsed.flags["--add-artifacts"]);
|
|
1695
1822
|
const addProofRefs = requireFlagValue("--add-proof-refs", parsed.flags["--add-proof-refs"]);
|
|
1696
1823
|
const addAttestationRefs = requireFlagValue("--add-attestation-refs", parsed.flags["--add-attestation-refs"]);
|
|
1824
|
+
const addEvidenceHashes = requireFlagValue("--add-evidence-hashes", parsed.flags["--add-evidence-hashes"]);
|
|
1697
1825
|
(0, work_1.runWorkReceiptUpdateCommand)({
|
|
1698
1826
|
root,
|
|
1699
1827
|
ws,
|
|
@@ -1702,10 +1830,19 @@ function runWorkSubcommand(parsed, root) {
|
|
|
1702
1830
|
addArtifacts,
|
|
1703
1831
|
addProofRefs,
|
|
1704
1832
|
addAttestationRefs,
|
|
1833
|
+
addEvidenceHashes,
|
|
1705
1834
|
json,
|
|
1706
1835
|
});
|
|
1707
1836
|
return 0;
|
|
1708
1837
|
}
|
|
1838
|
+
if (domain === "receipt" && action === "verify") {
|
|
1839
|
+
const id = parsed.positionals[3];
|
|
1840
|
+
if (!id || parsed.positionals.length > 4) {
|
|
1841
|
+
throw new errors_1.UsageError("work receipt verify requires <id-or-qid>");
|
|
1842
|
+
}
|
|
1843
|
+
(0, work_1.runWorkReceiptVerifyCommand)({ root, ws, id, json });
|
|
1844
|
+
return 0;
|
|
1845
|
+
}
|
|
1709
1846
|
if (domain === "artifact" && action === "add") {
|
|
1710
1847
|
const targetId = parsed.positionals[3];
|
|
1711
1848
|
const file = parsed.positionals[4];
|
|
@@ -2175,6 +2312,8 @@ function runCommand(parsed, root, runtime) {
|
|
|
2175
2312
|
return runSkillSubcommand(parsed, root);
|
|
2176
2313
|
case "capability":
|
|
2177
2314
|
return runCapabilitySubcommand(parsed, root);
|
|
2315
|
+
case "spec":
|
|
2316
|
+
return runSpecSubcommand(parsed, root);
|
|
2178
2317
|
case "archive":
|
|
2179
2318
|
return runArchiveSubcommand(parsed, root);
|
|
2180
2319
|
case "bundle":
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadCapabilityRecords = loadCapabilityRecords;
|
|
4
|
+
exports.filterCapabilityRecords = filterCapabilityRecords;
|
|
5
|
+
exports.resolveCapabilityRecord = resolveCapabilityRecord;
|
|
3
6
|
exports.runCapabilityListCommand = runCapabilityListCommand;
|
|
4
7
|
exports.runCapabilitySearchCommand = runCapabilitySearchCommand;
|
|
5
8
|
exports.runCapabilityShowCommand = runCapabilityShowCommand;
|
|
@@ -29,7 +32,7 @@ function normalizeVisibility(value) {
|
|
|
29
32
|
}
|
|
30
33
|
throw new errors_1.UsageError(`--visibility must be one of ${capabilities_indexer_1.CAPABILITY_VISIBILITIES.join(", ")}`);
|
|
31
34
|
}
|
|
32
|
-
function
|
|
35
|
+
function loadCapabilityRecords(options) {
|
|
33
36
|
const config = (0, config_1.loadConfig)(options.root);
|
|
34
37
|
const { index, stale, rebuilt } = (0, capabilities_index_cache_1.loadCapabilitiesIndex)({
|
|
35
38
|
root: options.root,
|
|
@@ -46,7 +49,7 @@ function loadRecords(options) {
|
|
|
46
49
|
}
|
|
47
50
|
return [...index.records, ...subgraph.records];
|
|
48
51
|
}
|
|
49
|
-
function
|
|
52
|
+
function filterCapabilityRecords(records, options) {
|
|
50
53
|
const kind = normalizeKind(options.kind);
|
|
51
54
|
const visibility = normalizeVisibility(options.visibility);
|
|
52
55
|
return records.filter((record) => {
|
|
@@ -78,6 +81,7 @@ function capabilitySearchText(record) {
|
|
|
78
81
|
...record.headings.map((heading) => heading.text),
|
|
79
82
|
JSON.stringify(record.spec ?? {}),
|
|
80
83
|
JSON.stringify(record.work ?? {}),
|
|
84
|
+
JSON.stringify(record.linkage ?? {}),
|
|
81
85
|
JSON.stringify(record.skill ?? {}),
|
|
82
86
|
]
|
|
83
87
|
.filter((value) => typeof value === "string" && value.length > 0)
|
|
@@ -117,6 +121,7 @@ function requirementMatch(record, required) {
|
|
|
117
121
|
...record.tags,
|
|
118
122
|
JSON.stringify(record.spec ?? {}),
|
|
119
123
|
JSON.stringify(record.work ?? {}),
|
|
124
|
+
JSON.stringify(record.linkage ?? {}),
|
|
120
125
|
JSON.stringify(record.skill ?? {}),
|
|
121
126
|
]
|
|
122
127
|
.join(" ")
|
|
@@ -199,7 +204,7 @@ function printCapabilityList(records, json, query) {
|
|
|
199
204
|
console.log(`${record.qid} | ${record.kind} | ${record.visibility} | ${label} | ${record.title}`);
|
|
200
205
|
}
|
|
201
206
|
}
|
|
202
|
-
function
|
|
207
|
+
function resolveCapabilityRecord(records, id) {
|
|
203
208
|
const normalized = id.toLowerCase();
|
|
204
209
|
const exact = records.find((record) => record.qid === id || record.id === id);
|
|
205
210
|
if (exact) {
|
|
@@ -233,19 +238,19 @@ function printCapability(record, json) {
|
|
|
233
238
|
console.log(`path: ${record.path}`);
|
|
234
239
|
}
|
|
235
240
|
function runCapabilityListCommand(options) {
|
|
236
|
-
const records =
|
|
241
|
+
const records = filterCapabilityRecords(loadCapabilityRecords(options), options);
|
|
237
242
|
printCapabilityList(records, options.json);
|
|
238
243
|
}
|
|
239
244
|
function runCapabilitySearchCommand(options) {
|
|
240
|
-
const records =
|
|
245
|
+
const records = filterCapabilityRecords(loadCapabilityRecords(options), options).filter((record) => matchesQuery(record, options.query));
|
|
241
246
|
printCapabilityList(records, options.json, options.query);
|
|
242
247
|
}
|
|
243
248
|
function runCapabilityShowCommand(options) {
|
|
244
|
-
const records =
|
|
245
|
-
printCapability(
|
|
249
|
+
const records = loadCapabilityRecords(options);
|
|
250
|
+
printCapability(resolveCapabilityRecord(records, options.id), options.json);
|
|
246
251
|
}
|
|
247
252
|
function runCapabilityResolveCommand(options) {
|
|
248
|
-
const records =
|
|
253
|
+
const records = filterCapabilityRecords(loadCapabilityRecords(options), options);
|
|
249
254
|
const items = resolveCapabilities(records, options).map((record, rank) => ({
|
|
250
255
|
rank: rank + 1,
|
|
251
256
|
score: resolveScore(record, options),
|
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
|
+
}
|