mdkg 0.4.1 → 0.5.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.
Files changed (71) hide show
  1. package/CHANGELOG.md +103 -15
  2. package/CLI_COMMAND_MATRIX.md +109 -2
  3. package/README.md +40 -2
  4. package/dist/cli.js +262 -2
  5. package/dist/command-contract.json +1902 -524
  6. package/dist/commands/archive.js +31 -14
  7. package/dist/commands/bundle.js +180 -44
  8. package/dist/commands/capability.js +1 -0
  9. package/dist/commands/checkpoint.js +6 -5
  10. package/dist/commands/event_support.js +16 -7
  11. package/dist/commands/fix.js +11 -8
  12. package/dist/commands/git.js +624 -0
  13. package/dist/commands/goal.js +23 -23
  14. package/dist/commands/graph.js +64 -10
  15. package/dist/commands/handoff.js +4 -2
  16. package/dist/commands/init.js +28 -23
  17. package/dist/commands/loop.js +1668 -0
  18. package/dist/commands/loop_descriptors.js +219 -0
  19. package/dist/commands/mcp.js +101 -11
  20. package/dist/commands/new.js +49 -3
  21. package/dist/commands/pack.js +14 -7
  22. package/dist/commands/search.js +10 -1
  23. package/dist/commands/skill.js +12 -9
  24. package/dist/commands/skill_mirror.js +39 -31
  25. package/dist/commands/subgraph.js +59 -26
  26. package/dist/commands/task.js +77 -4
  27. package/dist/commands/upgrade.js +13 -15
  28. package/dist/commands/validate.js +20 -7
  29. package/dist/commands/work.js +44 -26
  30. package/dist/commands/workspace.js +10 -4
  31. package/dist/core/config.js +45 -17
  32. package/dist/core/filesystem_authority.js +281 -0
  33. package/dist/core/project_db_events.js +4 -0
  34. package/dist/core/project_db_materializer.js +2 -0
  35. package/dist/core/project_db_migrations.js +238 -181
  36. package/dist/core/project_db_snapshot.js +64 -14
  37. package/dist/core/workspace_path.js +7 -0
  38. package/dist/graph/archive_integrity.js +1 -1
  39. package/dist/graph/capabilities_index_cache.js +4 -1
  40. package/dist/graph/frontmatter.js +38 -0
  41. package/dist/graph/goal_scope.js +4 -1
  42. package/dist/graph/index_cache.js +37 -7
  43. package/dist/graph/loop_bindings.js +39 -0
  44. package/dist/graph/node.js +209 -1
  45. package/dist/graph/node_body.js +52 -6
  46. package/dist/graph/skills_index_cache.js +41 -6
  47. package/dist/graph/skills_indexer.js +5 -2
  48. package/dist/graph/sqlite_index.js +118 -105
  49. package/dist/graph/subgraphs.js +142 -5
  50. package/dist/graph/validate_graph.js +109 -13
  51. package/dist/graph/workspace_files.js +39 -9
  52. package/dist/init/AGENT_START.md +16 -0
  53. package/dist/init/CLI_COMMAND_MATRIX.md +14 -0
  54. package/dist/init/config.json +7 -1
  55. package/dist/init/init-manifest.json +49 -4
  56. package/dist/init/skills/default/pursue-mdkg-loop/SKILL.md +150 -0
  57. package/dist/init/templates/default/loop.md +160 -0
  58. package/dist/init/templates/loops/backend-api-cli-bloat-audit.loop.md +117 -0
  59. package/dist/init/templates/loops/design-frontend-ux-audit.loop.md +117 -0
  60. package/dist/init/templates/loops/duplicate-code-and-linting-audit.loop.md +114 -0
  61. package/dist/init/templates/loops/security-audit.loop.md +140 -0
  62. package/dist/init/templates/loops/tech-stack-best-practices-audit.loop.md +116 -0
  63. package/dist/init/templates/loops/test-ci-skill-infrastructure-audit.loop.md +116 -0
  64. package/dist/init/templates/loops/user-story-audit-and-recommendations.loop.md +116 -0
  65. package/dist/pack/order.js +3 -1
  66. package/dist/pack/pack.js +139 -6
  67. package/dist/templates/loader.js +9 -3
  68. package/dist/util/argparse.js +5 -0
  69. package/dist/util/lock.js +10 -9
  70. package/dist/util/zip.js +163 -9
  71. package/package.json +8 -4
package/dist/cli.js CHANGED
@@ -29,12 +29,15 @@ const spec_1 = require("./commands/spec");
29
29
  const archive_1 = require("./commands/archive");
30
30
  const bundle_1 = require("./commands/bundle");
31
31
  const graph_1 = require("./commands/graph");
32
+ const git_1 = require("./commands/git");
32
33
  const subgraph_1 = require("./commands/subgraph");
33
34
  const checkpoint_1 = require("./commands/checkpoint");
34
35
  const init_1 = require("./commands/init");
35
36
  const new_1 = require("./commands/new");
36
37
  const guide_1 = require("./commands/guide");
37
38
  const upgrade_1 = require("./commands/upgrade");
39
+ const loop_1 = require("./commands/loop");
40
+ const loop_descriptors_1 = require("./commands/loop_descriptors");
38
41
  const goal_1 = require("./commands/goal");
39
42
  const event_1 = require("./commands/event");
40
43
  const skill_1 = require("./commands/skill");
@@ -76,8 +79,10 @@ function printUsage(log) {
76
79
  log(" archive Add, list, show, verify, and compress archive sidecars");
77
80
  log(" bundle Create, list, show, and verify full graph snapshot bundles");
78
81
  log(" graph Clone, fork, import, and inspect mdkg graph references");
82
+ log(" git Clone, fetch, inspect, close out, and push Git-backed mdkg projects");
79
83
  log(" subgraph Register, audit, plan, sync, materialize, and verify read-only child graph snapshots");
80
84
  log(" work Create and update work contracts, orders, receipts, and artifacts");
85
+ log(" loop List, show, fork, plan, and inspect first-class loop nodes");
81
86
  log(" goal Inspect and advance recursive goal nodes");
82
87
  log(" task Start, update, and complete task-like nodes");
83
88
  log(" next Suggest the next work item");
@@ -144,7 +149,7 @@ function printNewHelp(log) {
144
149
  log("Usage:");
145
150
  log(' mdkg new <type> "<title>" [options] [--json]');
146
151
  log("\nTypes:");
147
- log(" rule prd edd dec prop goal epic feat task bug spike checkpoint test");
152
+ log(" rule prd edd dec prop loop goal epic feat task bug spike checkpoint test");
148
153
  log("\nAgent workflow file types:");
149
154
  log(" manifest work work_order receipt feedback dispute proposal");
150
155
  log(" spec is a legacy alias for manifest and emits MANIFEST.md during the compatibility bridge.");
@@ -177,6 +182,34 @@ function printNewHelp(log) {
177
182
  log(" spikes do not run web search, create follow-up nodes, generate SKILL.md, or expose `mdkg spike ...`.");
178
183
  printGlobalOptions(log);
179
184
  }
185
+ function printLoopHelp(log, subcommand) {
186
+ printLoopDescriptorHelp(log, (0, loop_descriptors_1.loopDescriptorForSubcommand)(subcommand));
187
+ }
188
+ function printLoopDescriptorHelp(log, descriptor) {
189
+ log("Usage:");
190
+ for (const usage of descriptor.usage) {
191
+ log(` ${usage}`);
192
+ }
193
+ if (descriptor.key === "loop fork") {
194
+ log("\nMaterialization modes:");
195
+ log(" default_children planning_only manual");
196
+ }
197
+ const commandFlags = descriptor.flags.filter((flag) => flag.name !== "--root");
198
+ if (commandFlags.length > 0) {
199
+ log("\nOptions:");
200
+ for (const flag of commandFlags) {
201
+ const syntax = flag.value ? `${flag.name} ${flag.value}` : flag.name;
202
+ log(` ${syntax.padEnd(28)} ${flag.description}`);
203
+ }
204
+ }
205
+ if (descriptor.notes.length > 0) {
206
+ log("\nNotes:");
207
+ for (const note of descriptor.notes) {
208
+ log(` ${note}`);
209
+ }
210
+ }
211
+ printGlobalOptions(log);
212
+ }
180
213
  function printGuideHelp(log) {
181
214
  log("Usage:");
182
215
  log(" mdkg guide");
@@ -316,9 +349,10 @@ function printListHelp(log) {
316
349
  function printSearchHelp(log) {
317
350
  log("Usage:");
318
351
  log(' mdkg search "<query>" [--type <type>] [--status <status>] [--ws <alias>]');
319
- log(" [--tags <tag,tag,...>] [--tags-mode any|all] [--json|--xml|--toon|--md]");
352
+ log(" [--tags <tag,tag,...>] [--tags-mode any|all] [--limit <n>] [--json|--xml|--toon|--md]");
320
353
  log("\nWhen to use:");
321
354
  log(" Search mdkg nodes by metadata. Use `mdkg skill search` for skills.");
355
+ log(" Structured output defaults to a bounded page and reports count, returned_count, limit, and truncated.");
322
356
  printGlobalOptions(log);
323
357
  }
324
358
  function printPackHelp(log) {
@@ -653,6 +687,70 @@ function printGraphHelp(log, subcommand) {
653
687
  }
654
688
  printGlobalOptions(log);
655
689
  }
690
+ function printGitHelp(log, subcommand) {
691
+ switch ((subcommand ?? "").toLowerCase()) {
692
+ case "inspect":
693
+ log("Usage:");
694
+ log(" mdkg git inspect [--json]");
695
+ log("\nNotes:");
696
+ log(" - read-only Git worktree, remote, branch, status, descriptor, and accepted-revision receipt");
697
+ log(" - remote URLs are redacted when userinfo is present");
698
+ break;
699
+ case "clone":
700
+ log("Usage:");
701
+ log(" mdkg git clone <repository-ref> --target <path> [--branch <name>] [--json]");
702
+ log("\nNotes:");
703
+ log(" - uses the system Git CLI and external Git auth");
704
+ log(" - --target must be empty or absent and stay inside the current repo");
705
+ log(" - repository refs must not embed credentials");
706
+ break;
707
+ case "fetch":
708
+ log("Usage:");
709
+ log(" mdkg git fetch [--remote <name>] [--branch <name>] [--json]");
710
+ log("\nNotes:");
711
+ log(" - defaults to remote origin");
712
+ log(" - auth stays external through Git credential helpers, SSH, gh, CI env, or shell state");
713
+ break;
714
+ case "closeout":
715
+ log("Usage:");
716
+ log(" mdkg git closeout [--queue-policy drain|paused] [--output <path>] [--json]");
717
+ log("\nNotes:");
718
+ log(" - validates mdkg state before writing closeout receipts");
719
+ log(" - when the project DB participated, seals SQLite state and writes a deterministic dump");
720
+ log(" - writes static JSON and Markdown receipts under .mdkg/git/closeouts by default");
721
+ break;
722
+ case "push-ready":
723
+ log("Usage:");
724
+ log(" mdkg git push-ready --remote <name> --branch <name> [--json]");
725
+ log("\nNotes:");
726
+ log(" - read-only high-bar preflight for explicit Git remote/branch push");
727
+ log(" - requires clean worktree, valid mdkg graph, external auth boundary, and valid DB snapshot when DB state participated");
728
+ break;
729
+ case "push":
730
+ log("Usage:");
731
+ log(" mdkg git push --remote <name> --branch <name> [--json]");
732
+ log(" mdkg git push --remote <name> --branch <name> --stage-all --message <text> [--queue-policy drain|paused] [--json]");
733
+ log("\nNotes:");
734
+ log(" - real Git push via system Git; requires explicit remote and branch");
735
+ log(" - --stage-all writes closeout evidence, stages all changes, commits with --message, then runs push-ready before pushing");
736
+ log(" - no raw credentials, tokens, SSH keys, prompts, payloads, or provider auth are stored in receipts");
737
+ break;
738
+ default:
739
+ log("Usage:");
740
+ log(" mdkg git inspect [--json]");
741
+ log(" mdkg git clone <repository-ref> --target <path> [--branch <name>] [--json]");
742
+ log(" mdkg git fetch [--remote <name>] [--branch <name>] [--json]");
743
+ log(" mdkg git closeout [--queue-policy drain|paused] [--output <path>] [--json]");
744
+ log(" mdkg git push-ready --remote <name> --branch <name> [--json]");
745
+ log(" mdkg git push --remote <name> --branch <name> [--stage-all --message <text>] [--json]");
746
+ log("\nBoundaries:");
747
+ log(" - mdkg git is a low-level Git lifecycle surface, not project-memory semantic search");
748
+ log(" - system Git is the v1 execution backend");
749
+ log(" - authentication stays external; mdkg records only refs, hashes, policy names, and receipts");
750
+ log(" - real push operations require explicit remote and branch and should be approval-gated by the caller");
751
+ }
752
+ printGlobalOptions(log);
753
+ }
656
754
  function printSubgraphHelp(log, subcommand) {
657
755
  switch ((subcommand ?? "").toLowerCase()) {
658
756
  case "add":
@@ -1179,12 +1277,18 @@ function printCommandHelp(log, command, subcommand) {
1179
1277
  case "graph":
1180
1278
  printGraphHelp(log, subcommand);
1181
1279
  return;
1280
+ case "git":
1281
+ printGitHelp(log, subcommand);
1282
+ return;
1182
1283
  case "subgraph":
1183
1284
  printSubgraphHelp(log, subcommand);
1184
1285
  return;
1185
1286
  case "work":
1186
1287
  printWorkHelp(log, subcommand);
1187
1288
  return;
1289
+ case "loop":
1290
+ printLoopHelp(log, subcommand);
1291
+ return;
1188
1292
  case "task":
1189
1293
  printTaskHelp(log, subcommand);
1190
1294
  return;
@@ -1911,6 +2015,73 @@ function runGraphSubcommand(parsed, root) {
1911
2015
  throw new errors_1.UsageError("graph requires clone/fork/import-template/refs");
1912
2016
  }
1913
2017
  }
2018
+ function runGitSubcommand(parsed, root) {
2019
+ const subcommand = (parsed.positionals[1] ?? "").toLowerCase();
2020
+ const json = parseBooleanFlag("--json", parsed.flags["--json"]);
2021
+ switch (subcommand) {
2022
+ case "inspect": {
2023
+ if (parsed.positionals.length > 2) {
2024
+ throw new errors_1.UsageError("git inspect does not accept positional arguments");
2025
+ }
2026
+ (0, git_1.runGitInspectCommand)({ root, json });
2027
+ return 0;
2028
+ }
2029
+ case "clone": {
2030
+ const repository = parsed.positionals[2];
2031
+ if (!repository || parsed.positionals.length > 3) {
2032
+ throw new errors_1.UsageError("git clone requires <repository-ref>");
2033
+ }
2034
+ const target = requireFlagValue("--target", parsed.flags["--target"]);
2035
+ if (!target) {
2036
+ throw new errors_1.UsageError("git clone requires --target <path>");
2037
+ }
2038
+ const branch = requireFlagValue("--branch", parsed.flags["--branch"]);
2039
+ (0, git_1.runGitCloneCommand)({ root, repository, target, branch, json });
2040
+ return 0;
2041
+ }
2042
+ case "fetch": {
2043
+ if (parsed.positionals.length > 2) {
2044
+ throw new errors_1.UsageError("git fetch does not accept positional arguments");
2045
+ }
2046
+ const remote = requireFlagValue("--remote", parsed.flags["--remote"]);
2047
+ const branch = requireFlagValue("--branch", parsed.flags["--branch"]);
2048
+ (0, git_1.runGitFetchCommand)({ root, remote, branch, json });
2049
+ return 0;
2050
+ }
2051
+ case "closeout": {
2052
+ if (parsed.positionals.length > 2) {
2053
+ throw new errors_1.UsageError("git closeout does not accept positional arguments");
2054
+ }
2055
+ const queuePolicy = parseQueuePolicyFlag(parsed.flags["--queue-policy"]);
2056
+ const output = requireFlagValue("--output", parsed.flags["--out"]);
2057
+ (0, git_1.runGitCloseoutCommand)({ root, queuePolicy, output, json });
2058
+ return 0;
2059
+ }
2060
+ case "push-ready": {
2061
+ if (parsed.positionals.length > 2) {
2062
+ throw new errors_1.UsageError("git push-ready does not accept positional arguments");
2063
+ }
2064
+ const remote = requireFlagValue("--remote", parsed.flags["--remote"]);
2065
+ const branch = requireFlagValue("--branch", parsed.flags["--branch"]);
2066
+ (0, git_1.runGitPushReadyCommand)({ root, remote, branch, json });
2067
+ return 0;
2068
+ }
2069
+ case "push": {
2070
+ if (parsed.positionals.length > 2) {
2071
+ throw new errors_1.UsageError("git push does not accept positional arguments");
2072
+ }
2073
+ const remote = requireFlagValue("--remote", parsed.flags["--remote"]);
2074
+ const branch = requireFlagValue("--branch", parsed.flags["--branch"]);
2075
+ const message = requireFlagValue("--message", parsed.flags["--message"]);
2076
+ const stageAll = parseBooleanFlag("--stage-all", parsed.flags["--stage-all"]);
2077
+ const queuePolicy = parseQueuePolicyFlag(parsed.flags["--queue-policy"]);
2078
+ (0, git_1.runGitPushCommand)({ root, remote, branch, message, stageAll, queuePolicy, json });
2079
+ return 0;
2080
+ }
2081
+ default:
2082
+ throw new errors_1.UsageError("git requires inspect/clone/fetch/closeout/push-ready/push");
2083
+ }
2084
+ }
1914
2085
  function runSubgraphSubcommand(parsed, root) {
1915
2086
  const subcommand = (parsed.positionals[1] ?? "").toLowerCase();
1916
2087
  const json = parseBooleanFlag("--json", parsed.flags["--json"]);
@@ -2372,6 +2543,89 @@ function runSkillSubcommand(parsed, root) {
2372
2543
  throw new errors_1.UsageError("skill requires new/list/show/search/validate/sync");
2373
2544
  }
2374
2545
  }
2546
+ function runLoopSubcommand(parsed, root) {
2547
+ const subcommand = (parsed.positionals[1] ?? "").toLowerCase();
2548
+ const ws = requireFlagValue("--ws", parsed.flags["--ws"]);
2549
+ const json = parseBooleanFlag("--json", parsed.flags["--json"]);
2550
+ const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
2551
+ const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
2552
+ switch (subcommand) {
2553
+ case "list": {
2554
+ if (parsed.positionals.length > 2) {
2555
+ throw new errors_1.UsageError("loop list does not accept positional arguments");
2556
+ }
2557
+ (0, loop_1.runLoopListCommand)({ root, ws, json, noCache, noReindex });
2558
+ return 0;
2559
+ }
2560
+ case "show": {
2561
+ const id = parsed.positionals[2];
2562
+ if (!id || parsed.positionals.length > 3) {
2563
+ throw new errors_1.UsageError("loop show requires <loop-or-template>");
2564
+ }
2565
+ const metaOnly = parseBooleanFlag("--meta", parsed.flags["--meta"]);
2566
+ (0, loop_1.runLoopShowCommand)({ root, id, ws, metaOnly, json, noCache, noReindex });
2567
+ return 0;
2568
+ }
2569
+ case "fork": {
2570
+ const template = parsed.positionals[2];
2571
+ if (!template || parsed.positionals.length > 3) {
2572
+ throw new errors_1.UsageError("loop fork requires <template>");
2573
+ }
2574
+ const scope = requireFlagValue("--scope", parsed.flags["--scope"]);
2575
+ if (!scope) {
2576
+ throw new errors_1.UsageError("loop fork requires --scope");
2577
+ }
2578
+ const title = requireFlagValue("--title", parsed.flags["--title"]);
2579
+ const materializationMode = requireFlagValue("--materialization", parsed.flags["--materialization"]);
2580
+ const planningOnly = parseBooleanFlag("--planning-only", parsed.flags["--planning-only"]);
2581
+ const noChildren = parseBooleanFlag("--no-children", parsed.flags["--no-children"]);
2582
+ const dryRun = parseBooleanFlag("--dry-run", parsed.flags["--dry-run"]);
2583
+ const runId = requireFlagValue("--run-id", parsed.flags["--run-id"]);
2584
+ (0, loop_1.runLoopForkCommand)({
2585
+ root,
2586
+ template,
2587
+ scope,
2588
+ title,
2589
+ ws,
2590
+ materializationMode: materializationMode,
2591
+ planningOnly,
2592
+ noChildren,
2593
+ dryRun,
2594
+ runId,
2595
+ json,
2596
+ noCache,
2597
+ noReindex,
2598
+ });
2599
+ return 0;
2600
+ }
2601
+ case "plan": {
2602
+ const id = parsed.positionals[2];
2603
+ if (!id || parsed.positionals.length > 3) {
2604
+ throw new errors_1.UsageError("loop plan requires <loop>");
2605
+ }
2606
+ (0, loop_1.runLoopPlanCommand)({ root, id, ws, json, noCache, noReindex });
2607
+ return 0;
2608
+ }
2609
+ case "next": {
2610
+ const id = parsed.positionals[2];
2611
+ if (!id || parsed.positionals.length > 3) {
2612
+ throw new errors_1.UsageError("loop next requires <loop>");
2613
+ }
2614
+ (0, loop_1.runLoopNextCommand)({ root, id, ws, json, noCache, noReindex });
2615
+ return 0;
2616
+ }
2617
+ case "runs": {
2618
+ const id = parsed.positionals[2];
2619
+ if (!id || parsed.positionals.length > 3) {
2620
+ throw new errors_1.UsageError("loop runs requires <loop>");
2621
+ }
2622
+ (0, loop_1.runLoopRunsCommand)({ root, id, ws, json, noCache, noReindex });
2623
+ return 0;
2624
+ }
2625
+ default:
2626
+ throw new errors_1.UsageError("loop requires list/show/fork/plan/next/runs");
2627
+ }
2628
+ }
2375
2629
  function runGoalSubcommand(parsed, root) {
2376
2630
  const subcommand = (parsed.positionals[1] ?? "").toLowerCase();
2377
2631
  const ws = requireFlagValue("--ws", parsed.flags["--ws"]);
@@ -2747,10 +3001,14 @@ function runCommand(parsed, root, runtime) {
2747
3001
  return runBundleSubcommand(parsed, root);
2748
3002
  case "graph":
2749
3003
  return runGraphSubcommand(parsed, root);
3004
+ case "git":
3005
+ return runGitSubcommand(parsed, root);
2750
3006
  case "subgraph":
2751
3007
  return runSubgraphSubcommand(parsed, root);
2752
3008
  case "work":
2753
3009
  return runWorkSubcommand(parsed, root);
3010
+ case "loop":
3011
+ return runLoopSubcommand(parsed, root);
2754
3012
  case "goal":
2755
3013
  return runGoalSubcommand(parsed, root);
2756
3014
  case "task":
@@ -2819,6 +3077,7 @@ function runCommand(parsed, root, runtime) {
2819
3077
  const status = requireFlagValue("--status", parsed.flags["--status"]);
2820
3078
  const tags = parseCsvFlag("--tags", parsed.flags["--tags"]);
2821
3079
  const tagsMode = parseTagsModeFlag(parsed.flags["--tags-mode"]);
3080
+ const limit = parseNumberFlag("--limit", parsed.flags["--limit"]);
2822
3081
  const format = parseQueryOutputFormat(parsed);
2823
3082
  const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
2824
3083
  const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
@@ -2830,6 +3089,7 @@ function runCommand(parsed, root, runtime) {
2830
3089
  status,
2831
3090
  tags,
2832
3091
  tagsMode,
3092
+ limit,
2833
3093
  format,
2834
3094
  noCache,
2835
3095
  noReindex,