mdkg 0.0.9 → 0.1.1

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 CHANGED
@@ -4,6 +4,35 @@ 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
+ ## 0.1.1 - 2026-05-12
8
+
9
+ ### Added
10
+
11
+ - Added bundled template schema fallback so older workspaces can keep using graph inspection while missing newly introduced built-in templates.
12
+ - Added `safe_to_apply`, `will_write_paths`, `preserved_customizations`, `blocking_conflicts`, and `apply_side_effects` fields to `mdkg upgrade --json`.
13
+
14
+ ### Changed
15
+
16
+ - `mdkg new <built-in-type>` can use the installed package template when the workspace has not yet vendored that local template.
17
+ - `mdkg doctor` and `mdkg validate` warn, rather than fail, when packaged fallback schemas cover missing local built-in templates.
18
+ - `mdkg upgrade` human output now states whether the receipt is safe to apply and what paths would be written.
19
+ - `mdkg upgrade` skips ignored event logs and points users to `mdkg event enable` instead of creating ignored `.mdkg/work/events/events.jsonl` files.
20
+
21
+ ## 0.1.0 - 2026-05-12
22
+
23
+ ### Added
24
+
25
+ - Added conservative `mdkg upgrade` for existing workspaces.
26
+ - Added `.mdkg/init-manifest.json` ownership tracking for managed init assets.
27
+ - Added v0.0.9 seed fingerprints so clean older workspaces can safely adopt current init docs, templates, and default skills.
28
+ - Added `npm run smoke:upgrade` for packed-package upgrade verification in temporary workspaces.
29
+
30
+ ### Changed
31
+
32
+ - `mdkg upgrade` defaults to dry-run; `mdkg upgrade --apply` is the only mutating upgrade path.
33
+ - Agent-enabled workspaces can receive safe managed default skill upgrades and mirror refreshes during upgrade.
34
+ - Publish readiness now checks packaged init manifests and runs upgrade smoke before publish.
35
+
7
36
  ## 0.0.9 - 2026-05-12
8
37
 
9
38
  ### Added
package/README.md CHANGED
@@ -13,7 +13,7 @@ mdkg stays deliberately boring:
13
13
  - zero runtime dependencies
14
14
  - no sqlite, daemon, hosted index, or vector DB
15
15
 
16
- Current package version in source: `0.0.9`
16
+ Current package version in source: `0.1.1`
17
17
 
18
18
  ## The product shape
19
19
 
@@ -57,6 +57,23 @@ mdkg init --agent
57
57
 
58
58
  This adds strict-node `SOUL.md` / `HUMAN.md`, seeds the three default mdkg usage skills, creates `events.jsonl`, updates the skill registry, adds core pin updates, and creates mirrored skill folders under `.agents/skills/` and `.claude/skills/`.
59
59
 
60
+ Preview safe scaffold upgrades in an existing mdkg workspace:
61
+
62
+ ```bash
63
+ mdkg upgrade
64
+ mdkg upgrade --json
65
+ ```
66
+
67
+ Apply only after reviewing the receipt:
68
+
69
+ ```bash
70
+ mdkg upgrade --apply
71
+ ```
72
+
73
+ Upgrade is intentionally conservative. It creates missing managed startup docs and templates, updates unchanged mdkg seed assets, and preserves customized docs, templates, skills, and core files as reported preserved customizations. Review `safe_to_apply`, `will_write_paths`, and `apply_side_effects` in the JSON receipt before applying. Agent-enabled workspaces can receive safe default skill upgrades and skill mirror refreshes; ignored event logs are skipped with guidance to run `mdkg event enable` if provenance should be restored.
74
+
75
+ Older workspaces can continue to inspect and validate current graph nodes before applying an upgrade. When local templates are missing for newly introduced built-in mdkg types, mdkg uses the installed package's bundled templates as a read-only schema fallback and warns that `mdkg upgrade --apply` can vendor the missing templates.
76
+
60
77
  Create a task:
61
78
 
62
79
  ```bash
@@ -142,6 +159,7 @@ mdkg lives under a hidden root directory:
142
159
 
143
160
  These are the commands new users and agents should learn first:
144
161
  - `mdkg init`
162
+ - `mdkg upgrade`
145
163
  - `mdkg new`
146
164
  - `mdkg search`
147
165
  - `mdkg show`
@@ -204,7 +222,7 @@ This repo now dogfoods three internal skills:
204
222
  - `build-pack-and-execute-task`
205
223
  - `verify-close-and-checkpoint`
206
224
 
207
- Optional skill metadata with prefixes such as `ochatr_*` is treated as vendor extension data. Structured skill output exposes it under `extensions.ochatr` while keeping the top-level `ochatr` field as a 0.0.9 compatibility alias. ochatr.ai is a pioneering adopter of this extension pattern, not the name of the base mdkg standard.
225
+ Optional skill metadata with prefixes such as `ochatr_*` is treated as vendor extension data. Structured skill output exposes it under `extensions.ochatr` while keeping the top-level `ochatr` field as a compatibility alias introduced in 0.0.9. ochatr.ai is a pioneering adopter of this extension pattern, not the name of the base mdkg standard.
208
226
 
209
227
  ## Agent workflow files
210
228
 
package/dist/cli.js CHANGED
@@ -22,6 +22,7 @@ const checkpoint_1 = require("./commands/checkpoint");
22
22
  const init_1 = require("./commands/init");
23
23
  const new_1 = require("./commands/new");
24
24
  const guide_1 = require("./commands/guide");
25
+ const upgrade_1 = require("./commands/upgrade");
25
26
  const event_1 = require("./commands/event");
26
27
  const skill_1 = require("./commands/skill");
27
28
  const task_1 = require("./commands/task");
@@ -47,6 +48,7 @@ function printUsage(log) {
47
48
  log(" mdkg <command> [options]");
48
49
  log("\nPrimary commands:");
49
50
  log(" init Initialize .mdkg scaffolding");
51
+ log(" upgrade Conservatively upgrade mdkg scaffolding");
50
52
  log(" new Create a node from templates");
51
53
  log(" show Show a node by id or qid");
52
54
  log(" list List nodes with filters");
@@ -66,6 +68,8 @@ function printUsage(log) {
66
68
  log(" workspace Manage workspaces (ls/add/rm/enable/disable)");
67
69
  log("\nQuickstart:");
68
70
  log(" mdkg init --llm");
71
+ log(" mdkg upgrade");
72
+ log(" mdkg upgrade --apply");
69
73
  log(' mdkg new task "..." --status todo --priority 1');
70
74
  log(' mdkg search "..."');
71
75
  log(" mdkg show <id>");
@@ -95,6 +99,21 @@ function printInitHelp(log) {
95
99
  log("\nCompatibility flags still supported but not shown in the primary onboarding story.");
96
100
  printGlobalOptions(log);
97
101
  }
102
+ function printUpgradeHelp(log) {
103
+ log("Usage:");
104
+ log(" mdkg upgrade [--dry-run] [--apply] [--json]");
105
+ log("\nOptions:");
106
+ log(" --dry-run Preview upgrade changes without writing files (default)");
107
+ log(" --apply Apply safe managed init asset upgrades");
108
+ log(" --json Emit machine-readable upgrade receipt");
109
+ log("\nNotes:");
110
+ log(" - preserves customized docs, templates, skills, and core files");
111
+ log(" - json receipts include safe_to_apply, will_write_paths, and apply_side_effects");
112
+ log(" - upgrades default mdkg skills only when they match managed seed fingerprints");
113
+ log(" - skips ignored event logs; run mdkg event enable if provenance should be restored");
114
+ log(" - run without flags first, then rerun with --apply when the receipt looks right");
115
+ printGlobalOptions(log);
116
+ }
98
117
  function printNewHelp(log) {
99
118
  log("Usage:");
100
119
  log(' mdkg new <type> "<title>" [options] [--json]');
@@ -371,6 +390,9 @@ function printCommandHelp(log, command, subcommand) {
371
390
  case "init":
372
391
  printInitHelp(log);
373
392
  return;
393
+ case "upgrade":
394
+ printUpgradeHelp(log);
395
+ return;
374
396
  case "guide":
375
397
  printGuideHelp(log);
376
398
  return;
@@ -909,6 +931,19 @@ function runCommand(parsed, root, runtime) {
909
931
  });
910
932
  return 0;
911
933
  }
934
+ case "upgrade": {
935
+ if (parsed.positionals.length > 1) {
936
+ throw new errors_1.UsageError("upgrade does not accept positional arguments");
937
+ }
938
+ const dryRun = parseBooleanFlag("--dry-run", parsed.flags["--dry-run"]);
939
+ const apply = parseBooleanFlag("--apply", parsed.flags["--apply"]);
940
+ if (dryRun && apply) {
941
+ throw new errors_1.UsageError("choose either --dry-run or --apply, not both");
942
+ }
943
+ const json = parseBooleanFlag("--json", parsed.flags["--json"]);
944
+ (0, upgrade_1.runUpgradeCommand)({ root, dryRun, apply, json });
945
+ return 0;
946
+ }
912
947
  case "guide":
913
948
  (0, guide_1.runGuideCommand)({ root });
914
949
  return 0;
@@ -79,12 +79,20 @@ function runDoctorCommand(options) {
79
79
  }
80
80
  if (config) {
81
81
  try {
82
- (0, template_schema_1.loadTemplateSchemas)(options.root, config, node_1.ALLOWED_TYPES);
82
+ const templateSchemaInfo = (0, template_schema_1.loadTemplateSchemasWithInfo)(options.root, config, node_1.ALLOWED_TYPES);
83
83
  results.push({
84
84
  name: "templates",
85
85
  ok: true,
86
86
  detail: "template schema set loaded",
87
87
  });
88
+ if (templateSchemaInfo.fallbackTypes.length > 0) {
89
+ results.push({
90
+ name: "local-templates",
91
+ ok: true,
92
+ level: "warn",
93
+ detail: `missing local template schema(s) covered by bundled fallback: ${templateSchemaInfo.fallbackTypes.join(", ")}; run \`mdkg upgrade --apply\` to vendor them`,
94
+ });
95
+ }
88
96
  }
89
97
  catch (err) {
90
98
  const message = err instanceof Error ? err.message : String(err);
@@ -143,7 +151,7 @@ function runDoctorCommand(options) {
143
151
  }
144
152
  else {
145
153
  for (const result of results) {
146
- const prefix = result.ok ? "ok" : "fail";
154
+ const prefix = result.ok ? result.level ?? "ok" : "fail";
147
155
  console.log(`${prefix}: ${result.name} - ${result.detail}`);
148
156
  }
149
157
  }
@@ -9,6 +9,8 @@ const path_1 = __importDefault(require("path"));
9
9
  const config_1 = require("../core/config");
10
10
  const errors_1 = require("../util/errors");
11
11
  const date_1 = require("../util/date");
12
+ const version_1 = require("../core/version");
13
+ const init_manifest_1 = require("./init_manifest");
12
14
  const skill_support_1 = require("./skill_support");
13
15
  const skill_mirror_1 = require("./skill_mirror");
14
16
  const DEFAULT_SEED_SUBDIR = path_1.default.resolve(__dirname, "..", "init");
@@ -236,6 +238,7 @@ function runInitCommand(options) {
236
238
  const seedCliMatrix = path_1.default.join(seedRoot, "CLI_COMMAND_MATRIX.md");
237
239
  const seedReadme = path_1.default.join(seedRoot, "README.md");
238
240
  const seedDefaultSkills = path_1.default.join(seedRoot, "skills", "default");
241
+ const seedManifest = (0, init_manifest_1.createInitManifest)(seedRoot, (0, version_1.readPackageVersion)());
239
242
  if (!fs_1.default.existsSync(seedConfig) || !fs_1.default.existsSync(seedCore) || !fs_1.default.existsSync(seedTemplates)) {
240
243
  throw new errors_1.NotFoundError(`init assets not found at ${seedRoot} (try reinstalling mdkg)`);
241
244
  }
@@ -304,6 +307,7 @@ function runInitCommand(options) {
304
307
  (0, skill_support_1.refreshSkillsRegistry)(root, config);
305
308
  (0, skill_mirror_1.syncSkillMirrors)({ root, config, createRoots: true, force });
306
309
  }
310
+ (0, init_manifest_1.writeInitManifest)(path_1.default.join(mdkgDir, init_manifest_1.INIT_MANIFEST_FILE), seedManifest);
307
311
  const noUpdateIgnores = Boolean(options.noUpdateIgnores);
308
312
  const shouldUpdateGitignore = Boolean(options.updateGitignore || !noUpdateIgnores);
309
313
  const shouldUpdateNpmignore = Boolean(options.updateNpmignore || !noUpdateIgnores);
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.INIT_MANIFEST_SCHEMA_VERSION = exports.INIT_MANIFEST_FILE = void 0;
7
+ exports.sha256File = sha256File;
8
+ exports.seedSourcePath = seedSourcePath;
9
+ exports.createInitManifest = createInitManifest;
10
+ exports.writeInitManifest = writeInitManifest;
11
+ exports.readInitManifest = readInitManifest;
12
+ exports.loadLegacyInitManifests = loadLegacyInitManifests;
13
+ const crypto_1 = __importDefault(require("crypto"));
14
+ const fs_1 = __importDefault(require("fs"));
15
+ const path_1 = __importDefault(require("path"));
16
+ exports.INIT_MANIFEST_FILE = "init-manifest.json";
17
+ exports.INIT_MANIFEST_SCHEMA_VERSION = 1;
18
+ const STARTUP_DOCS = ["llms.txt", "AGENT_START.md", "CLI_COMMAND_MATRIX.md"];
19
+ const AGENT_DOCS = ["AGENTS.md", "CLAUDE.md"];
20
+ function toPosixPath(value) {
21
+ return value.split(path_1.default.sep).join("/");
22
+ }
23
+ function sha256Buffer(value) {
24
+ return crypto_1.default.createHash("sha256").update(value).digest("hex");
25
+ }
26
+ function sha256File(filePath) {
27
+ return sha256Buffer(fs_1.default.readFileSync(filePath));
28
+ }
29
+ function listFiles(dirPath) {
30
+ if (!fs_1.default.existsSync(dirPath)) {
31
+ return [];
32
+ }
33
+ const files = [];
34
+ const entries = fs_1.default.readdirSync(dirPath, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
35
+ for (const entry of entries) {
36
+ const fullPath = path_1.default.join(dirPath, entry.name);
37
+ if (entry.isDirectory()) {
38
+ files.push(...listFiles(fullPath));
39
+ }
40
+ else if (entry.isFile()) {
41
+ files.push(fullPath);
42
+ }
43
+ }
44
+ return files;
45
+ }
46
+ function addSeedFile(files, seedRoot, seedRelativePath, targetPath, category) {
47
+ const sourcePath = path_1.default.join(seedRoot, seedRelativePath);
48
+ if (!fs_1.default.existsSync(sourcePath) || !fs_1.default.statSync(sourcePath).isFile()) {
49
+ return;
50
+ }
51
+ files.push({
52
+ path: toPosixPath(targetPath),
53
+ category,
54
+ sha256: sha256File(sourcePath),
55
+ });
56
+ }
57
+ function addSeedDir(files, seedRoot, seedRelativeDir, targetDir, category) {
58
+ const sourceDir = path_1.default.join(seedRoot, seedRelativeDir);
59
+ for (const sourcePath of listFiles(sourceDir)) {
60
+ const relPath = toPosixPath(path_1.default.relative(sourceDir, sourcePath));
61
+ files.push({
62
+ path: path_1.default.posix.join(targetDir, relPath),
63
+ category,
64
+ sha256: sha256File(sourcePath),
65
+ });
66
+ }
67
+ }
68
+ function seedSourcePath(seedRoot, file) {
69
+ if (file.path === ".mdkg/config.json") {
70
+ return path_1.default.join(seedRoot, "config.json");
71
+ }
72
+ if (file.path === ".mdkg/README.md") {
73
+ return path_1.default.join(seedRoot, "README.md");
74
+ }
75
+ if (file.path.startsWith(".mdkg/core/")) {
76
+ return path_1.default.join(seedRoot, "core", file.path.slice(".mdkg/core/".length));
77
+ }
78
+ if (file.path.startsWith(".mdkg/templates/")) {
79
+ return path_1.default.join(seedRoot, "templates", file.path.slice(".mdkg/templates/".length));
80
+ }
81
+ if (file.path.startsWith(".mdkg/skills/")) {
82
+ return path_1.default.join(seedRoot, "skills", "default", file.path.slice(".mdkg/skills/".length));
83
+ }
84
+ return path_1.default.join(seedRoot, file.path);
85
+ }
86
+ function createInitManifest(seedRoot, mdkgVersion) {
87
+ const files = [];
88
+ addSeedFile(files, seedRoot, "config.json", ".mdkg/config.json", "config");
89
+ addSeedFile(files, seedRoot, "README.md", ".mdkg/README.md", "mdkg_doc");
90
+ addSeedDir(files, seedRoot, "core", ".mdkg/core", "core");
91
+ addSeedDir(files, seedRoot, "templates", ".mdkg/templates", "template");
92
+ for (const doc of AGENT_DOCS) {
93
+ addSeedFile(files, seedRoot, doc, doc, "agent_doc");
94
+ }
95
+ for (const doc of STARTUP_DOCS) {
96
+ addSeedFile(files, seedRoot, doc, doc, "startup_doc");
97
+ }
98
+ addSeedDir(files, seedRoot, path_1.default.join("skills", "default"), ".mdkg/skills", "default_skill");
99
+ return {
100
+ schema_version: exports.INIT_MANIFEST_SCHEMA_VERSION,
101
+ tool: "mdkg",
102
+ mdkg_version: mdkgVersion,
103
+ files: files.sort((a, b) => a.path.localeCompare(b.path)),
104
+ };
105
+ }
106
+ function writeInitManifest(filePath, manifest) {
107
+ fs_1.default.mkdirSync(path_1.default.dirname(filePath), { recursive: true });
108
+ fs_1.default.writeFileSync(filePath, `${JSON.stringify(manifest, null, 2)}\n`, "utf8");
109
+ }
110
+ function readInitManifest(filePath) {
111
+ if (!fs_1.default.existsSync(filePath)) {
112
+ return undefined;
113
+ }
114
+ const parsed = JSON.parse(fs_1.default.readFileSync(filePath, "utf8"));
115
+ if (parsed.schema_version !== exports.INIT_MANIFEST_SCHEMA_VERSION || parsed.tool !== "mdkg" || !Array.isArray(parsed.files)) {
116
+ throw new Error(`${filePath}: invalid mdkg init manifest`);
117
+ }
118
+ return parsed;
119
+ }
120
+ function loadLegacyInitManifests(seedRoot) {
121
+ const legacyDir = path_1.default.join(seedRoot, "legacy");
122
+ if (!fs_1.default.existsSync(legacyDir)) {
123
+ return [];
124
+ }
125
+ return fs_1.default
126
+ .readdirSync(legacyDir, { withFileTypes: true })
127
+ .filter((entry) => entry.isFile() && entry.name.endsWith(".json"))
128
+ .sort((a, b) => a.name.localeCompare(b.name))
129
+ .map((entry) => readInitManifest(path_1.default.join(legacyDir, entry.name)))
130
+ .filter((manifest) => manifest !== undefined);
131
+ }
@@ -286,6 +286,9 @@ function runNewCommand(options) {
286
286
  }
287
287
  const today = (0, date_1.formatDate)(options.now ?? new Date());
288
288
  const template = (0, loader_1.loadTemplate)(options.root, config, type, options.template);
289
+ if (template.source === "bundled") {
290
+ console.error(`warning: using bundled template fallback for ${type}; run \`mdkg upgrade --apply\` to vendor missing local templates`);
291
+ }
289
292
  const content = (0, loader_1.renderTemplate)(template, {
290
293
  id,
291
294
  type,