mdkg 0.1.2 → 0.1.4
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 +51 -0
- package/README.md +31 -15
- package/dist/cli.js +182 -85
- package/dist/commands/archive.js +20 -8
- package/dist/commands/bundle.js +7 -7
- package/dist/commands/capability.js +118 -4
- package/dist/commands/checkpoint.js +31 -5
- package/dist/commands/doctor.js +61 -24
- package/dist/commands/index.js +12 -23
- package/dist/commands/init.js +7 -1
- package/dist/commands/list.js +1 -1
- package/dist/commands/new.js +33 -7
- package/dist/commands/next.js +1 -1
- package/dist/commands/node_card.js +1 -1
- package/dist/commands/pack.js +1 -1
- package/dist/commands/search.js +1 -1
- package/dist/commands/show.js +1 -1
- package/dist/commands/subgraph.js +312 -0
- package/dist/commands/task.js +21 -7
- package/dist/commands/upgrade.js +51 -4
- package/dist/commands/validate.js +12 -6
- package/dist/commands/work.js +44 -12
- package/dist/core/config.js +110 -39
- package/dist/graph/capabilities_index_cache.js +2 -2
- package/dist/graph/index_cache.js +14 -14
- package/dist/graph/indexer.js +1 -1
- package/dist/graph/reindex.js +46 -0
- package/dist/graph/skills_index_cache.js +2 -2
- package/dist/graph/sqlite_index.js +293 -0
- package/dist/graph/{bundle_imports.js → subgraphs.js} +216 -142
- package/dist/graph/visibility.js +3 -3
- package/dist/init/AGENT_START.md +5 -1
- package/dist/init/CLI_COMMAND_MATRIX.md +21 -7
- package/dist/init/README.md +20 -10
- package/dist/init/config.json +6 -2
- package/dist/init/core/rule-1-mdkg-conventions.md +2 -1
- package/dist/init/core/rule-3-cli-contract.md +32 -24
- package/dist/init/core/rule-4-repo-safety-and-ignores.md +28 -12
- package/dist/init/core/rule-5-release-and-versioning.md +4 -3
- package/dist/init/init-manifest.json +10 -10
- package/dist/init/skills/default/verify-close-and-checkpoint/SKILL.md +1 -1
- package/dist/util/argparse.js +2 -0
- package/dist/util/atomic.js +44 -0
- package/dist/util/lock.js +72 -0
- package/package.json +13 -9
- package/dist/commands/bundle_import.js +0 -243
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,57 @@ All notable changes to mdkg are documented here.
|
|
|
4
4
|
|
|
5
5
|
This project follows a pragmatic changelog style inspired by Keep a Changelog. Versions use npm package versions.
|
|
6
6
|
|
|
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
|
+
|
|
9
|
+
## 0.1.4 - Unreleased
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Added `mdkg subgraph add/list/show/rm/enable/disable/verify/refresh` as the public read-only child graph orchestration command family.
|
|
14
|
+
- Added `subgraphs` config with multi-source bundle transport, advisory visibility, read permissions, source metadata, and a default 60 minute freshness policy.
|
|
15
|
+
- Added `.mdkg/index/subgraphs.json` as the derived subgraph projection and health cache.
|
|
16
|
+
- Added `mdkg capability resolve [query] [--requires <capability>] [--fresh-only] [--json]` for deterministic local plus subgraph capability ranking.
|
|
17
|
+
- Added packed-package `smoke:subgraph` coverage for root, child, and grandchild orchestration flows.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- Replaced the public `mdkg bundle import ...` surface with `mdkg subgraph ...`; legacy calls now exit with migration guidance.
|
|
22
|
+
- `mdkg upgrade --apply` migrates legacy `bundle_imports` config into `subgraphs`.
|
|
23
|
+
- Read commands, `pack`, and capability discovery now project enabled child bundles as read-only subgraph qids such as `child_repo:work.example`.
|
|
24
|
+
- `mdkg index`, SQLite cache rebuilds, `doctor`, and `validate` now use subgraph naming and metadata instead of bundle-import naming.
|
|
25
|
+
- Stale subgraphs remain usable for planning reads with warnings, fail `mdkg subgraph verify`, and are excluded from `capability resolve --fresh-only`.
|
|
26
|
+
- Public/internal subgraphs require public bundle profiles and public bundle creation fails closed on private/internal subgraph references.
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- Mutation commands now reject subgraph qids with explicit guidance to update the source workspace for the owning subgraph.
|
|
31
|
+
- Seeded init docs, command matrix, and release skills now teach `subgraph` and `capability resolve` instead of onboarding users through `bundle import`.
|
|
32
|
+
|
|
33
|
+
## 0.1.3 - 2026-05-20
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
|
|
37
|
+
- Added first-class SQLite access cache support using Node's built-in `node:sqlite`; no third-party SQLite package is introduced.
|
|
38
|
+
- Added `.mdkg/index/mdkg.sqlite` as a rebuildable derived cache for nodes, edges, skills, capabilities, archives, bundle imports, source hashes, and schema metadata when `index.backend` is `sqlite`.
|
|
39
|
+
- Added fresh init defaults for `index.backend: sqlite`, `index.sqlite_path`, `index.sqlite_commit_warning_bytes`, and `index.lock_timeout_ms`.
|
|
40
|
+
- Added a shared mutation lock plus atomic writes for mdkg mutations and index writes.
|
|
41
|
+
- Added SQLite transactional id reservation for numeric node/checkpoint ids in SQLite mode.
|
|
42
|
+
- Added `npm run smoke:sqlite` and `npm run smoke:parallel` packed/temp-repo coverage.
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
|
|
46
|
+
- Raised the required Node runtime to `>=24.15.0`.
|
|
47
|
+
- Existing workspaces that are migrated from older configs remain on `index.backend: json` until they explicitly opt in to SQLite.
|
|
48
|
+
- Init ignore policy now keeps JSON indexes, temp files, lock directories, WAL, SHM, and journal files ignored while allowing `.mdkg/index/mdkg.sqlite` to be committed by intentional repo policy.
|
|
49
|
+
- `mdkg index` continues to write JSON compatibility indexes and also rebuilds SQLite when enabled.
|
|
50
|
+
- `mdkg doctor` and `mdkg validate` now report SQLite cache health when SQLite mode is enabled.
|
|
51
|
+
- README and seeded docs now state that mdkg is pre-v1 public alpha software and cache/DAL contracts may churn before v1.
|
|
52
|
+
|
|
53
|
+
### Fixed
|
|
54
|
+
|
|
55
|
+
- Removed the accidental self-dependency on `mdkg` from package metadata.
|
|
56
|
+
- Hardened parallel `mdkg new`, checkpoint, task, work, archive, bundle import config, and index writes against naming conflicts and partial cache writes.
|
|
57
|
+
|
|
7
58
|
## 0.1.2 - 2026-05-19
|
|
8
59
|
|
|
9
60
|
### Added
|
package/README.md
CHANGED
|
@@ -9,11 +9,14 @@ It is built for:
|
|
|
9
9
|
|
|
10
10
|
mdkg stays deliberately boring:
|
|
11
11
|
- repo-native under `.mdkg/`
|
|
12
|
-
- TypeScript + Node.js
|
|
13
|
-
- zero runtime dependencies
|
|
14
|
-
-
|
|
12
|
+
- TypeScript + Node.js `>=24.15.0`
|
|
13
|
+
- zero third-party runtime dependencies
|
|
14
|
+
- first-class rebuildable SQLite cache through built-in `node:sqlite`
|
|
15
|
+
- no daemon, hosted index, or vector DB
|
|
15
16
|
|
|
16
|
-
Current package version in source: `0.1.
|
|
17
|
+
Current package version in source: `0.1.4`
|
|
18
|
+
|
|
19
|
+
mdkg is still pre-v1 public alpha software. The public package is usable, but graph, cache, bundle, and DAL contracts may continue to change quickly while the project converges on a stable v1 surface.
|
|
17
20
|
|
|
18
21
|
## The product shape
|
|
19
22
|
|
|
@@ -107,20 +110,21 @@ mdkg bundle verify .mdkg/bundles/private/all.mdkg.zip
|
|
|
107
110
|
mdkg bundle list --json
|
|
108
111
|
```
|
|
109
112
|
|
|
110
|
-
Bundles are explicit graph transport artifacts, separate from task context packs. Before a commit in repos that track archives or bundles, refresh compressed archive caches first, then create the private bundle so the committed graph state is self-consistent. Private bundles are the default and may be committed in private repos when configured. Public bundles require at least one selected workspace with `visibility: public` and include only public workspace content and public archive sidecars; bundle creation fails if public content points at private graph, archive, or
|
|
113
|
+
Bundles are explicit graph transport artifacts, separate from task context packs. Before a commit in repos that track archives or bundles, refresh compressed archive caches first, then create the private bundle so the committed graph state is self-consistent. Private bundles are the default and may be committed in private repos when configured. Public bundles require at least one selected workspace with `visibility: public` and include only public workspace content and public archive sidecars; bundle creation fails if public content points at private graph, archive, or subgraph records.
|
|
111
114
|
|
|
112
|
-
|
|
115
|
+
Register a child repo bundle as a read-only subgraph planning view:
|
|
113
116
|
|
|
114
117
|
```bash
|
|
115
|
-
mdkg
|
|
116
|
-
mdkg
|
|
118
|
+
mdkg subgraph add child_repo child-repo/.mdkg/bundles/private/all.mdkg.zip --source-path child-repo
|
|
119
|
+
mdkg subgraph list --json
|
|
117
120
|
mdkg search "child capability"
|
|
118
121
|
mdkg show child_repo:work.example
|
|
119
122
|
mdkg pack child_repo:work.example --dry-run --stats
|
|
120
|
-
mdkg
|
|
123
|
+
mdkg capability resolve "child capability" --json
|
|
124
|
+
mdkg subgraph verify child_repo --json
|
|
121
125
|
```
|
|
122
126
|
|
|
123
|
-
|
|
127
|
+
Subgraph nodes are projected under the subgraph alias, for example `child_repo:task-1`. They are available to `list`, `search`, `show`, `pack`, capability discovery, and `capability resolve`, but remain read-only; mutate the child repo and refresh its bundle to change subgraph content. Stale subgraphs warn during planning reads and fail `mdkg subgraph verify`. Public or internal subgraphs must be backed by public bundle profiles; private subgraphs stay private planning context.
|
|
124
128
|
|
|
125
129
|
Validate before handoff or commit:
|
|
126
130
|
|
|
@@ -155,7 +159,7 @@ mdkg work artifact add receipt.generate-image-1 ./outputs/image.png --id archive
|
|
|
155
159
|
```
|
|
156
160
|
|
|
157
161
|
Receipt statuses are `recorded`, `verified`, `rejected`, and `superseded`.
|
|
158
|
-
Update and artifact commands accept local ids or local qids;
|
|
162
|
+
Update and artifact commands accept local ids or local qids; subgraph qids are read-only and must be changed in their source workspace.
|
|
159
163
|
|
|
160
164
|
Update structured task state and evidence while keeping body and narrative edits in markdown:
|
|
161
165
|
|
|
@@ -202,10 +206,11 @@ mdkg lives under a hidden root directory:
|
|
|
202
206
|
- `.mdkg/skills/` Agent Skills packages
|
|
203
207
|
- `.mdkg/archive/` sidecar metadata plus deterministic compressed source/artifact caches
|
|
204
208
|
- `.mdkg/bundles/` optional committed full graph snapshot bundles
|
|
205
|
-
- `.mdkg/index/
|
|
209
|
+
- `.mdkg/index/mdkg.sqlite` optional committed, rebuildable SQLite access cache
|
|
210
|
+
- `.mdkg/index/subgraphs.json` generated read-only subgraph projection cache
|
|
206
211
|
- `.agents/skills/` Codex/OpenAI-facing mirrored skills
|
|
207
212
|
- `.claude/skills/` Claude-facing mirrored skills
|
|
208
|
-
- `.mdkg/index
|
|
213
|
+
- `.mdkg/index/*.json` generated JSON compatibility cache files
|
|
209
214
|
|
|
210
215
|
## Primary commands
|
|
211
216
|
|
|
@@ -292,6 +297,14 @@ The capability cache is not the full graph and is not source of truth. Normal ta
|
|
|
292
297
|
|
|
293
298
|
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.
|
|
294
299
|
|
|
300
|
+
## Index backends and parallel safety
|
|
301
|
+
|
|
302
|
+
Fresh `mdkg init` workspaces default to `index.backend: sqlite`, which writes `.mdkg/index/mdkg.sqlite` as a rebuildable access cache using Node's built-in `node:sqlite`. Existing workspaces that are migrated from older configs default to `index.backend: json` until they opt in. Markdown files, archive sidecars, bundle manifests, and config remain source of truth in both modes.
|
|
303
|
+
|
|
304
|
+
`mdkg index` still writes JSON compatibility caches (`global.json`, `skills.json`, `capabilities.json`, and subgraph projections when configured). In SQLite mode it also rebuilds the SQLite cache with nodes, edges, skills, capabilities, archive metadata, subgraphs, source hashes, and schema metadata. Deleting the SQLite file is recoverable with `mdkg index`.
|
|
305
|
+
|
|
306
|
+
Mutating commands use a workspace mutation lock plus atomic writes. SQLite mode additionally reserves numeric ids in a SQLite transaction before writing Markdown so parallel `mdkg new` and checkpoint calls avoid naming conflicts. Skipped ids after failed writes are acceptable because Markdown remains canonical.
|
|
307
|
+
|
|
295
308
|
## Agent workflow files
|
|
296
309
|
|
|
297
310
|
mdkg recognizes a small set of canonical agent workflow documents:
|
|
@@ -323,10 +336,12 @@ By default, init/upgrade ignore generated raw archive source copies with `.mdkg/
|
|
|
323
336
|
|
|
324
337
|
This release includes:
|
|
325
338
|
- `init --agent`
|
|
326
|
-
- default ignore updates with `--no-update-ignores` for
|
|
339
|
+
- default ignore updates with `--no-update-ignores` for generated JSON index/temp/lock files, `.mdkg/pack/`, and raw archive source copies
|
|
327
340
|
- root-only published init seed config
|
|
328
341
|
- skills indexing and search/show/list support
|
|
329
342
|
- JSON capability cache for skills, `SPEC.md`, `WORK.md`, core docs, and design docs
|
|
343
|
+
- SQLite index backend for fresh workspaces using built-in `node:sqlite`
|
|
344
|
+
- mutation locking and atomic writes for parallel mdkg calls
|
|
330
345
|
- optional `skills: [...]` on work items
|
|
331
346
|
- pack-time skill inclusion
|
|
332
347
|
- latest-checkpoint resolver + index hint
|
|
@@ -360,7 +375,8 @@ Design and decision records live in the internal graph under `.mdkg/design/`.
|
|
|
360
375
|
mdkg is not a secret store.
|
|
361
376
|
|
|
362
377
|
Use these defaults:
|
|
363
|
-
- keep `.mdkg/index
|
|
378
|
+
- keep generated `.mdkg/index/*.json`, temp, lock, WAL, SHM, and journal files gitignored
|
|
379
|
+
- commit `.mdkg/index/mdkg.sqlite` only when the repo intentionally tracks a reasonably sized rebuildable access cache
|
|
364
380
|
- keep `.mdkg/pack/` gitignored
|
|
365
381
|
- keep `.mdkg/archive/**/source/` gitignored unless a repo intentionally commits raw local copies
|
|
366
382
|
- commit archive sidecar `.md` metadata and deterministic `.zip` caches when they are needed for reviewable evidence
|
package/dist/cli.js
CHANGED
|
@@ -21,7 +21,7 @@ const doctor_1 = require("./commands/doctor");
|
|
|
21
21
|
const capability_1 = require("./commands/capability");
|
|
22
22
|
const archive_1 = require("./commands/archive");
|
|
23
23
|
const bundle_1 = require("./commands/bundle");
|
|
24
|
-
const
|
|
24
|
+
const subgraph_1 = require("./commands/subgraph");
|
|
25
25
|
const checkpoint_1 = require("./commands/checkpoint");
|
|
26
26
|
const init_1 = require("./commands/init");
|
|
27
27
|
const new_1 = require("./commands/new");
|
|
@@ -60,9 +60,10 @@ function printUsage(log) {
|
|
|
60
60
|
log(" search Search nodes by query");
|
|
61
61
|
log(" pack Generate a context pack");
|
|
62
62
|
log(" skill Create, list, show, search, and validate skills");
|
|
63
|
-
log(" capability List, search, and
|
|
63
|
+
log(" capability List, search, show, and resolve cached capability surfaces");
|
|
64
64
|
log(" archive Add, list, show, verify, and compress archive sidecars");
|
|
65
65
|
log(" bundle Create, list, show, and verify full graph snapshot bundles");
|
|
66
|
+
log(" subgraph Register and verify read-only child graph snapshots");
|
|
66
67
|
log(" work Create and update work contracts, orders, receipts, and artifacts");
|
|
67
68
|
log(" task Start, update, and complete task-like nodes");
|
|
68
69
|
log(" next Suggest the next work item");
|
|
@@ -171,6 +172,8 @@ function printIndexHelp(log) {
|
|
|
171
172
|
log(" - .mdkg/index/global.json");
|
|
172
173
|
log(" - .mdkg/index/skills.json");
|
|
173
174
|
log(" - .mdkg/index/capabilities.json");
|
|
175
|
+
log(" - .mdkg/index/subgraphs.json when subgraphs are configured");
|
|
176
|
+
log(" - .mdkg/index/mdkg.sqlite when index.backend is sqlite");
|
|
174
177
|
printGlobalOptions(log);
|
|
175
178
|
}
|
|
176
179
|
function printShowHelp(log) {
|
|
@@ -320,14 +323,23 @@ function printCapabilityHelp(log, subcommand) {
|
|
|
320
323
|
log(" mdkg capability show <id-or-qid-or-slug> [--json]");
|
|
321
324
|
printGlobalOptions(log);
|
|
322
325
|
return;
|
|
326
|
+
case "resolve":
|
|
327
|
+
log("Usage:");
|
|
328
|
+
log(' mdkg capability resolve [query] [--requires <capability>] [--fresh-only] [--json]');
|
|
329
|
+
log("\nNotes:");
|
|
330
|
+
log(" Resolves local and subgraph capabilities with deterministic ranking.");
|
|
331
|
+
printGlobalOptions(log);
|
|
332
|
+
return;
|
|
323
333
|
default:
|
|
324
334
|
log("Usage:");
|
|
325
335
|
log(" mdkg capability list [--kind <kind>] [--visibility <level>] [--json]");
|
|
326
336
|
log(' mdkg capability search "<query>" [--kind <kind>] [--visibility <level>] [--json]');
|
|
327
337
|
log(" mdkg capability show <id-or-qid-or-slug> [--json]");
|
|
338
|
+
log(' mdkg capability resolve [query] [--requires <capability>] [--fresh-only] [--json]');
|
|
328
339
|
log("\nNotes:");
|
|
329
340
|
log(" Capability records are deterministic cache projections from Markdown.");
|
|
330
341
|
log(" Cached kinds: skill, spec, work, core, design.");
|
|
342
|
+
log(" Resolve includes read-only subgraph capability records when configured.");
|
|
331
343
|
printGlobalOptions(log);
|
|
332
344
|
}
|
|
333
345
|
}
|
|
@@ -373,12 +385,8 @@ function printBundleHelp(log, subcommand) {
|
|
|
373
385
|
switch ((subcommand ?? "").toLowerCase()) {
|
|
374
386
|
case "import":
|
|
375
387
|
log("Usage:");
|
|
376
|
-
log(" mdkg
|
|
377
|
-
log("
|
|
378
|
-
log(" mdkg bundle import rm <alias> [--json]");
|
|
379
|
-
log(" mdkg bundle import enable <alias> [--json]");
|
|
380
|
-
log(" mdkg bundle import disable <alias> [--json]");
|
|
381
|
-
log(" mdkg bundle import verify [alias|--all] [--json]");
|
|
388
|
+
log(" mdkg subgraph add/list/show/rm/enable/disable/verify/refresh ...");
|
|
389
|
+
log("\n`mdkg bundle import` has been replaced by `mdkg subgraph`.");
|
|
382
390
|
break;
|
|
383
391
|
case "create":
|
|
384
392
|
log("Usage:");
|
|
@@ -402,15 +410,66 @@ function printBundleHelp(log, subcommand) {
|
|
|
402
410
|
log(" mdkg bundle verify [bundle-path] [--json]");
|
|
403
411
|
log(" mdkg bundle show <bundle-path> [--json]");
|
|
404
412
|
log(" mdkg bundle list [--json]");
|
|
405
|
-
log(" mdkg bundle import add/list/rm/enable/disable/verify ...");
|
|
406
413
|
log("\nNotes:");
|
|
407
414
|
log(" - bundles are explicit full .mdkg graph snapshots, not task context packs");
|
|
408
|
-
log(" - bundle
|
|
415
|
+
log(" - use `mdkg subgraph ...` to register bundle snapshots as read-only planning views");
|
|
409
416
|
log(" - private is the default profile; public bundles fail closed on private refs");
|
|
410
417
|
log(" - .mdkg/bundles/ is commit-eligible when your repo tracks snapshot bundles");
|
|
411
418
|
}
|
|
412
419
|
printGlobalOptions(log);
|
|
413
420
|
}
|
|
421
|
+
function printSubgraphHelp(log, subcommand) {
|
|
422
|
+
switch ((subcommand ?? "").toLowerCase()) {
|
|
423
|
+
case "add":
|
|
424
|
+
log("Usage:");
|
|
425
|
+
log(" mdkg subgraph add <alias> <bundle-path> [--visibility private|internal|public] [--profile private|public] [--source-path <path>] [--source-repo <ref>] [--max-stale-seconds <seconds>] [--json]");
|
|
426
|
+
break;
|
|
427
|
+
case "list":
|
|
428
|
+
log("Usage:");
|
|
429
|
+
log(" mdkg subgraph list [--json]");
|
|
430
|
+
break;
|
|
431
|
+
case "show":
|
|
432
|
+
log("Usage:");
|
|
433
|
+
log(" mdkg subgraph show <alias> [--json]");
|
|
434
|
+
break;
|
|
435
|
+
case "rm":
|
|
436
|
+
case "remove":
|
|
437
|
+
log("Usage:");
|
|
438
|
+
log(" mdkg subgraph rm <alias> [--json]");
|
|
439
|
+
break;
|
|
440
|
+
case "enable":
|
|
441
|
+
log("Usage:");
|
|
442
|
+
log(" mdkg subgraph enable <alias> [--json]");
|
|
443
|
+
break;
|
|
444
|
+
case "disable":
|
|
445
|
+
log("Usage:");
|
|
446
|
+
log(" mdkg subgraph disable <alias> [--json]");
|
|
447
|
+
break;
|
|
448
|
+
case "verify":
|
|
449
|
+
log("Usage:");
|
|
450
|
+
log(" mdkg subgraph verify [alias|--all] [--json]");
|
|
451
|
+
break;
|
|
452
|
+
case "refresh":
|
|
453
|
+
log("Usage:");
|
|
454
|
+
log(" mdkg subgraph refresh [alias|--all] [--json]");
|
|
455
|
+
break;
|
|
456
|
+
default:
|
|
457
|
+
log("Usage:");
|
|
458
|
+
log(" mdkg subgraph add <alias> <bundle-path> [--visibility private|internal|public] [--profile private|public] [--source-path <path>] [--source-repo <ref>] [--max-stale-seconds <seconds>] [--json]");
|
|
459
|
+
log(" mdkg subgraph list [--json]");
|
|
460
|
+
log(" mdkg subgraph show <alias> [--json]");
|
|
461
|
+
log(" mdkg subgraph rm <alias> [--json]");
|
|
462
|
+
log(" mdkg subgraph enable <alias> [--json]");
|
|
463
|
+
log(" mdkg subgraph disable <alias> [--json]");
|
|
464
|
+
log(" mdkg subgraph verify [alias|--all] [--json]");
|
|
465
|
+
log(" mdkg subgraph refresh [alias|--all] [--json]");
|
|
466
|
+
log("\nNotes:");
|
|
467
|
+
log(" - subgraphs are read-only graph views backed by explicit bundle snapshots");
|
|
468
|
+
log(" - default permissions are read-only and default freshness is 3600 seconds");
|
|
469
|
+
log(" - refresh reloads configured bundle sources only; it does not build child bundles");
|
|
470
|
+
}
|
|
471
|
+
printGlobalOptions(log);
|
|
472
|
+
}
|
|
414
473
|
function printWorkHelp(log, subcommand) {
|
|
415
474
|
switch ((subcommand ?? "").toLowerCase()) {
|
|
416
475
|
case "contract":
|
|
@@ -442,7 +501,7 @@ function printWorkHelp(log, subcommand) {
|
|
|
442
501
|
log(" - production order, receipt, feedback, dispute, payment, ledger, marketplace inventory, fulfillment, and execution state remains canonical outside mdkg");
|
|
443
502
|
log(" - do not store raw secrets, credentials, live payment state, ledger mutations, or canonical marketplace state in work mirrors");
|
|
444
503
|
log(" - artifact:// refs identify external/runtime-managed artifacts; archive:// refs identify committed mdkg archive sidecars");
|
|
445
|
-
log(" - update and artifact commands accept local ids or local qids;
|
|
504
|
+
log(" - update and artifact commands accept local ids or local qids; subgraph qids are read-only");
|
|
446
505
|
}
|
|
447
506
|
printGlobalOptions(log);
|
|
448
507
|
}
|
|
@@ -544,6 +603,7 @@ function printDoctorHelp(log) {
|
|
|
544
603
|
log(" - Bundle import health and staleness");
|
|
545
604
|
log(" - Index load/rebuild health");
|
|
546
605
|
log(" - Capability cache load/rebuild health");
|
|
606
|
+
log(" - SQLite cache health when enabled");
|
|
547
607
|
log("\nOptions:");
|
|
548
608
|
log(" --json Emit machine-readable JSON output");
|
|
549
609
|
printGlobalOptions(log);
|
|
@@ -596,6 +656,9 @@ function printCommandHelp(log, command, subcommand) {
|
|
|
596
656
|
case "bundle":
|
|
597
657
|
printBundleHelp(log, subcommand);
|
|
598
658
|
return;
|
|
659
|
+
case "subgraph":
|
|
660
|
+
printSubgraphHelp(log, subcommand);
|
|
661
|
+
return;
|
|
599
662
|
case "work":
|
|
600
663
|
printWorkHelp(log, subcommand);
|
|
601
664
|
return;
|
|
@@ -868,8 +931,20 @@ function runCapabilitySubcommand(parsed, root) {
|
|
|
868
931
|
(0, capability_1.runCapabilityShowCommand)({ root, id, json, noCache, noReindex });
|
|
869
932
|
return 0;
|
|
870
933
|
}
|
|
934
|
+
case "resolve": {
|
|
935
|
+
const query = parsed.positionals.slice(2).join(" ") || undefined;
|
|
936
|
+
const kind = requireFlagValue("--kind", parsed.flags["--kind"]);
|
|
937
|
+
const visibility = requireFlagValue("--visibility", parsed.flags["--visibility"]);
|
|
938
|
+
const requires = requireFlagValue("--requires", parsed.flags["--requires"]);
|
|
939
|
+
const freshOnly = parseBooleanFlag("--fresh-only", parsed.flags["--fresh-only"]);
|
|
940
|
+
const json = parseBooleanFlag("--json", parsed.flags["--json"]);
|
|
941
|
+
const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
|
|
942
|
+
const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
|
|
943
|
+
(0, capability_1.runCapabilityResolveCommand)({ root, query, kind, visibility, requires, freshOnly, json, noCache, noReindex });
|
|
944
|
+
return 0;
|
|
945
|
+
}
|
|
871
946
|
default:
|
|
872
|
-
throw new errors_1.UsageError("capability requires list/search/show");
|
|
947
|
+
throw new errors_1.UsageError("capability requires list/search/show/resolve");
|
|
873
948
|
}
|
|
874
949
|
}
|
|
875
950
|
function runArchiveSubcommand(parsed, root) {
|
|
@@ -941,78 +1016,7 @@ function runBundleSubcommand(parsed, root) {
|
|
|
941
1016
|
const subcommand = (parsed.positionals[1] ?? "").toLowerCase();
|
|
942
1017
|
switch (subcommand) {
|
|
943
1018
|
case "import": {
|
|
944
|
-
|
|
945
|
-
const json = parseBooleanFlag("--json", parsed.flags["--json"]);
|
|
946
|
-
switch (action) {
|
|
947
|
-
case "add": {
|
|
948
|
-
const alias = parsed.positionals[3];
|
|
949
|
-
const bundlePath = parsed.positionals[4];
|
|
950
|
-
if (!alias || !bundlePath || parsed.positionals.length > 5) {
|
|
951
|
-
throw new errors_1.UsageError("bundle import add requires <alias> <bundle-path>");
|
|
952
|
-
}
|
|
953
|
-
const visibility = requireFlagValue("--visibility", parsed.flags["--visibility"]);
|
|
954
|
-
const profile = requireFlagValue("--profile", parsed.flags["--pack-profile"]);
|
|
955
|
-
const sourcePath = requireFlagValue("--source-path", parsed.flags["--source-path"]);
|
|
956
|
-
const sourceRepo = requireFlagValue("--source-repo", parsed.flags["--source-repo"]);
|
|
957
|
-
const maxStaleRaw = requireFlagValue("--max-stale-seconds", parsed.flags["--max-stale-seconds"]);
|
|
958
|
-
const maxStaleSeconds = maxStaleRaw === undefined ? undefined : Number.parseInt(maxStaleRaw, 10);
|
|
959
|
-
(0, bundle_import_1.runBundleImportAddCommand)({
|
|
960
|
-
root,
|
|
961
|
-
alias,
|
|
962
|
-
bundlePath,
|
|
963
|
-
visibility,
|
|
964
|
-
profile,
|
|
965
|
-
sourcePath,
|
|
966
|
-
sourceRepo,
|
|
967
|
-
maxStaleSeconds,
|
|
968
|
-
json,
|
|
969
|
-
});
|
|
970
|
-
return 0;
|
|
971
|
-
}
|
|
972
|
-
case "list": {
|
|
973
|
-
if (parsed.positionals.length > 3) {
|
|
974
|
-
throw new errors_1.UsageError("bundle import list does not accept positional arguments");
|
|
975
|
-
}
|
|
976
|
-
(0, bundle_import_1.runBundleImportListCommand)({ root, json });
|
|
977
|
-
return 0;
|
|
978
|
-
}
|
|
979
|
-
case "rm":
|
|
980
|
-
case "remove": {
|
|
981
|
-
const alias = parsed.positionals[3];
|
|
982
|
-
if (!alias || parsed.positionals.length > 4) {
|
|
983
|
-
throw new errors_1.UsageError("bundle import rm requires <alias>");
|
|
984
|
-
}
|
|
985
|
-
(0, bundle_import_1.runBundleImportRemoveCommand)({ root, alias, json });
|
|
986
|
-
return 0;
|
|
987
|
-
}
|
|
988
|
-
case "enable": {
|
|
989
|
-
const alias = parsed.positionals[3];
|
|
990
|
-
if (!alias || parsed.positionals.length > 4) {
|
|
991
|
-
throw new errors_1.UsageError("bundle import enable requires <alias>");
|
|
992
|
-
}
|
|
993
|
-
(0, bundle_import_1.runBundleImportEnableCommand)({ root, alias, json });
|
|
994
|
-
return 0;
|
|
995
|
-
}
|
|
996
|
-
case "disable": {
|
|
997
|
-
const alias = parsed.positionals[3];
|
|
998
|
-
if (!alias || parsed.positionals.length > 4) {
|
|
999
|
-
throw new errors_1.UsageError("bundle import disable requires <alias>");
|
|
1000
|
-
}
|
|
1001
|
-
(0, bundle_import_1.runBundleImportDisableCommand)({ root, alias, json });
|
|
1002
|
-
return 0;
|
|
1003
|
-
}
|
|
1004
|
-
case "verify": {
|
|
1005
|
-
if (parsed.positionals.length > 4) {
|
|
1006
|
-
throw new errors_1.UsageError("bundle import verify accepts at most one alias");
|
|
1007
|
-
}
|
|
1008
|
-
const alias = parsed.positionals[3];
|
|
1009
|
-
const all = parseBooleanFlag("--all", parsed.flags["--all"]);
|
|
1010
|
-
(0, bundle_import_1.runBundleImportVerifyCommand)({ root, alias, all, json });
|
|
1011
|
-
return 0;
|
|
1012
|
-
}
|
|
1013
|
-
default:
|
|
1014
|
-
throw new errors_1.UsageError("bundle import requires add/list/rm/enable/disable/verify");
|
|
1015
|
-
}
|
|
1019
|
+
throw new errors_1.UsageError("mdkg bundle import has been replaced by mdkg subgraph; run `mdkg upgrade --apply` to migrate legacy bundle_imports config");
|
|
1016
1020
|
}
|
|
1017
1021
|
case "create": {
|
|
1018
1022
|
if (parsed.positionals.length > 2) {
|
|
@@ -1052,7 +1056,98 @@ function runBundleSubcommand(parsed, root) {
|
|
|
1052
1056
|
return 0;
|
|
1053
1057
|
}
|
|
1054
1058
|
default:
|
|
1055
|
-
throw new errors_1.UsageError("bundle requires create/list/show/verify
|
|
1059
|
+
throw new errors_1.UsageError("bundle requires create/list/show/verify");
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
function runSubgraphSubcommand(parsed, root) {
|
|
1063
|
+
const subcommand = (parsed.positionals[1] ?? "").toLowerCase();
|
|
1064
|
+
const json = parseBooleanFlag("--json", parsed.flags["--json"]);
|
|
1065
|
+
switch (subcommand) {
|
|
1066
|
+
case "add": {
|
|
1067
|
+
const alias = parsed.positionals[2];
|
|
1068
|
+
const bundlePath = parsed.positionals[3];
|
|
1069
|
+
if (!alias || !bundlePath || parsed.positionals.length > 4) {
|
|
1070
|
+
throw new errors_1.UsageError("subgraph add requires <alias> <bundle-path>");
|
|
1071
|
+
}
|
|
1072
|
+
const visibility = requireFlagValue("--visibility", parsed.flags["--visibility"]);
|
|
1073
|
+
const profile = requireFlagValue("--profile", parsed.flags["--pack-profile"]);
|
|
1074
|
+
const sourcePath = requireFlagValue("--source-path", parsed.flags["--source-path"]);
|
|
1075
|
+
const sourceRepo = requireFlagValue("--source-repo", parsed.flags["--source-repo"]);
|
|
1076
|
+
const maxStaleRaw = requireFlagValue("--max-stale-seconds", parsed.flags["--max-stale-seconds"]);
|
|
1077
|
+
const maxStaleSeconds = maxStaleRaw === undefined ? undefined : Number.parseInt(maxStaleRaw, 10);
|
|
1078
|
+
(0, subgraph_1.runSubgraphAddCommand)({
|
|
1079
|
+
root,
|
|
1080
|
+
alias,
|
|
1081
|
+
bundlePath,
|
|
1082
|
+
visibility,
|
|
1083
|
+
profile,
|
|
1084
|
+
sourcePath,
|
|
1085
|
+
sourceRepo,
|
|
1086
|
+
maxStaleSeconds,
|
|
1087
|
+
json,
|
|
1088
|
+
});
|
|
1089
|
+
return 0;
|
|
1090
|
+
}
|
|
1091
|
+
case "list": {
|
|
1092
|
+
if (parsed.positionals.length > 2) {
|
|
1093
|
+
throw new errors_1.UsageError("subgraph list does not accept positional arguments");
|
|
1094
|
+
}
|
|
1095
|
+
(0, subgraph_1.runSubgraphListCommand)({ root, json });
|
|
1096
|
+
return 0;
|
|
1097
|
+
}
|
|
1098
|
+
case "show": {
|
|
1099
|
+
const alias = parsed.positionals[2];
|
|
1100
|
+
if (!alias || parsed.positionals.length > 3) {
|
|
1101
|
+
throw new errors_1.UsageError("subgraph show requires <alias>");
|
|
1102
|
+
}
|
|
1103
|
+
(0, subgraph_1.runSubgraphShowCommand)({ root, alias, json });
|
|
1104
|
+
return 0;
|
|
1105
|
+
}
|
|
1106
|
+
case "rm":
|
|
1107
|
+
case "remove": {
|
|
1108
|
+
const alias = parsed.positionals[2];
|
|
1109
|
+
if (!alias || parsed.positionals.length > 3) {
|
|
1110
|
+
throw new errors_1.UsageError("subgraph rm requires <alias>");
|
|
1111
|
+
}
|
|
1112
|
+
(0, subgraph_1.runSubgraphRemoveCommand)({ root, alias, json });
|
|
1113
|
+
return 0;
|
|
1114
|
+
}
|
|
1115
|
+
case "enable": {
|
|
1116
|
+
const alias = parsed.positionals[2];
|
|
1117
|
+
if (!alias || parsed.positionals.length > 3) {
|
|
1118
|
+
throw new errors_1.UsageError("subgraph enable requires <alias>");
|
|
1119
|
+
}
|
|
1120
|
+
(0, subgraph_1.runSubgraphEnableCommand)({ root, alias, json });
|
|
1121
|
+
return 0;
|
|
1122
|
+
}
|
|
1123
|
+
case "disable": {
|
|
1124
|
+
const alias = parsed.positionals[2];
|
|
1125
|
+
if (!alias || parsed.positionals.length > 3) {
|
|
1126
|
+
throw new errors_1.UsageError("subgraph disable requires <alias>");
|
|
1127
|
+
}
|
|
1128
|
+
(0, subgraph_1.runSubgraphDisableCommand)({ root, alias, json });
|
|
1129
|
+
return 0;
|
|
1130
|
+
}
|
|
1131
|
+
case "verify": {
|
|
1132
|
+
if (parsed.positionals.length > 3) {
|
|
1133
|
+
throw new errors_1.UsageError("subgraph verify accepts at most one alias");
|
|
1134
|
+
}
|
|
1135
|
+
const alias = parsed.positionals[2];
|
|
1136
|
+
const all = parseBooleanFlag("--all", parsed.flags["--all"]);
|
|
1137
|
+
(0, subgraph_1.runSubgraphVerifyCommand)({ root, alias, all, json });
|
|
1138
|
+
return 0;
|
|
1139
|
+
}
|
|
1140
|
+
case "refresh": {
|
|
1141
|
+
if (parsed.positionals.length > 3) {
|
|
1142
|
+
throw new errors_1.UsageError("subgraph refresh accepts at most one alias");
|
|
1143
|
+
}
|
|
1144
|
+
const alias = parsed.positionals[2];
|
|
1145
|
+
const all = parseBooleanFlag("--all", parsed.flags["--all"]);
|
|
1146
|
+
(0, subgraph_1.runSubgraphRefreshCommand)({ root, alias, all, json });
|
|
1147
|
+
return 0;
|
|
1148
|
+
}
|
|
1149
|
+
default:
|
|
1150
|
+
throw new errors_1.UsageError("subgraph requires add/list/show/rm/enable/disable/verify/refresh");
|
|
1056
1151
|
}
|
|
1057
1152
|
}
|
|
1058
1153
|
function runWorkSubcommand(parsed, root) {
|
|
@@ -1564,6 +1659,8 @@ function runCommand(parsed, root, runtime) {
|
|
|
1564
1659
|
return runArchiveSubcommand(parsed, root);
|
|
1565
1660
|
case "bundle":
|
|
1566
1661
|
return runBundleSubcommand(parsed, root);
|
|
1662
|
+
case "subgraph":
|
|
1663
|
+
return runSubgraphSubcommand(parsed, root);
|
|
1567
1664
|
case "work":
|
|
1568
1665
|
return runWorkSubcommand(parsed, root);
|
|
1569
1666
|
case "task":
|
package/dist/commands/archive.js
CHANGED
|
@@ -3,10 +3,10 @@ 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.runArchiveAddCommand = runArchiveAddCommand;
|
|
7
6
|
exports.runArchiveListCommand = runArchiveListCommand;
|
|
8
7
|
exports.runArchiveShowCommand = runArchiveShowCommand;
|
|
9
8
|
exports.runArchiveVerifyCommand = runArchiveVerifyCommand;
|
|
9
|
+
exports.runArchiveAddCommand = runArchiveAddCommand;
|
|
10
10
|
exports.runArchiveCompressCommand = runArchiveCompressCommand;
|
|
11
11
|
const fs_1 = __importDefault(require("fs"));
|
|
12
12
|
const path_1 = __importDefault(require("path"));
|
|
@@ -15,11 +15,14 @@ const frontmatter_1 = require("../graph/frontmatter");
|
|
|
15
15
|
const archive_integrity_1 = require("../graph/archive_integrity");
|
|
16
16
|
const indexer_1 = require("../graph/indexer");
|
|
17
17
|
const index_cache_1 = require("../graph/index_cache");
|
|
18
|
+
const reindex_1 = require("../graph/reindex");
|
|
18
19
|
const visibility_1 = require("../graph/visibility");
|
|
19
20
|
const date_1 = require("../util/date");
|
|
20
21
|
const errors_1 = require("../util/errors");
|
|
21
22
|
const id_1 = require("../util/id");
|
|
22
23
|
const refs_1 = require("../util/refs");
|
|
24
|
+
const atomic_1 = require("../util/atomic");
|
|
25
|
+
const lock_1 = require("../util/lock");
|
|
23
26
|
const zip_1 = require("../util/zip");
|
|
24
27
|
const event_support_1 = require("./event_support");
|
|
25
28
|
const ARCHIVE_KINDS = new Set(["source", "artifact"]);
|
|
@@ -124,8 +127,7 @@ function maybeReindex(root) {
|
|
|
124
127
|
if (!config.index.auto_reindex) {
|
|
125
128
|
return;
|
|
126
129
|
}
|
|
127
|
-
|
|
128
|
-
(0, index_cache_1.writeIndex)(outputPath, (0, indexer_1.buildIndex)(root, config, { tolerant: config.index.tolerant }));
|
|
130
|
+
(0, reindex_1.writeDerivedIndexes)(root, config, (0, indexer_1.buildIndex)(root, config, { tolerant: config.index.tolerant }));
|
|
129
131
|
}
|
|
130
132
|
function resolveArchiveNode(root, id, ws) {
|
|
131
133
|
const config = (0, config_1.loadConfig)(root);
|
|
@@ -174,7 +176,7 @@ function stringAttribute(value) {
|
|
|
174
176
|
function writeArchiveSidecar(sidecarPath, frontmatter, body) {
|
|
175
177
|
const lines = (0, frontmatter_1.formatFrontmatter)(frontmatter);
|
|
176
178
|
const content = ["---", ...lines, "---", body.trimStart()].join("\n");
|
|
177
|
-
|
|
179
|
+
(0, atomic_1.atomicWriteFile)(sidecarPath, content.endsWith("\n") ? content : `${content}\n`);
|
|
178
180
|
}
|
|
179
181
|
function verifyArchiveSidecar(root, ws, sidecarPath) {
|
|
180
182
|
const relativePath = toPosixPath(path_1.default.relative(root, sidecarPath));
|
|
@@ -276,7 +278,7 @@ function loadArchiveVerifyResults(options) {
|
|
|
276
278
|
}
|
|
277
279
|
return results;
|
|
278
280
|
}
|
|
279
|
-
function
|
|
281
|
+
function runArchiveAddCommandLocked(options) {
|
|
280
282
|
const config = (0, config_1.loadConfig)(options.root);
|
|
281
283
|
const ws = normalizeWorkspace(options.ws);
|
|
282
284
|
const workspace = config.workspaces[ws];
|
|
@@ -311,7 +313,7 @@ function runArchiveAddCommand(options) {
|
|
|
311
313
|
fs_1.default.copyFileSync(sourcePath, rawPath);
|
|
312
314
|
const rawData = fs_1.default.readFileSync(rawPath);
|
|
313
315
|
const zipData = (0, zip_1.createDeterministicZip)(basename, rawData);
|
|
314
|
-
|
|
316
|
+
(0, atomic_1.atomicWriteFile)(zipPath, zipData);
|
|
315
317
|
const frontmatter = {
|
|
316
318
|
id,
|
|
317
319
|
type: "archive",
|
|
@@ -423,7 +425,7 @@ function runArchiveVerifyCommand(options) {
|
|
|
423
425
|
throw new errors_1.ValidationError("archive verification failed");
|
|
424
426
|
}
|
|
425
427
|
}
|
|
426
|
-
function
|
|
428
|
+
function runArchiveCompressCommandLocked(options) {
|
|
427
429
|
if (!options.all && !options.id) {
|
|
428
430
|
throw new errors_1.UsageError("archive compress requires <id-or-archive-uri> or --all");
|
|
429
431
|
}
|
|
@@ -441,7 +443,7 @@ function runArchiveCompressCommand(options) {
|
|
|
441
443
|
}
|
|
442
444
|
const rawData = fs_1.default.readFileSync(rawPath);
|
|
443
445
|
const zipData = (0, zip_1.createDeterministicZip)(path_1.default.basename(rawPath), rawData);
|
|
444
|
-
|
|
446
|
+
(0, atomic_1.atomicWriteFile)(zipPath, zipData);
|
|
445
447
|
const parsed = (0, frontmatter_1.parseFrontmatter)(fs_1.default.readFileSync(sidecarPath, "utf8"), sidecarPath);
|
|
446
448
|
const nextFrontmatter = {
|
|
447
449
|
...parsed.frontmatter,
|
|
@@ -472,3 +474,13 @@ function runArchiveCompressCommand(options) {
|
|
|
472
474
|
}
|
|
473
475
|
console.log(`archive compressed: ${updated.length}`);
|
|
474
476
|
}
|
|
477
|
+
function withArchiveLock(root, fn) {
|
|
478
|
+
const config = (0, config_1.loadConfig)(root);
|
|
479
|
+
return (0, lock_1.withMutationLock)(root, config.index.lock_timeout_ms, fn);
|
|
480
|
+
}
|
|
481
|
+
function runArchiveAddCommand(options) {
|
|
482
|
+
return withArchiveLock(options.root, () => runArchiveAddCommandLocked(options));
|
|
483
|
+
}
|
|
484
|
+
function runArchiveCompressCommand(options) {
|
|
485
|
+
return withArchiveLock(options.root, () => runArchiveCompressCommandLocked(options));
|
|
486
|
+
}
|