@yojahny/wp-design-library 0.6.0 → 1.0.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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/cli/serve.mjs +25 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yojahny/wp-design-library",
3
- "version": "0.6.0",
3
+ "version": "1.0.0",
4
4
  "description": "Design reference corpus and MCP server for claude-wp-builder",
5
5
  "repository": {
6
6
  "type": "git",
package/src/cli/serve.mjs CHANGED
@@ -11,8 +11,20 @@ async function syncSeed(p) {
11
11
  if (p.seed !== p.entries && fs.existsSync(p.seed)) {
12
12
  const path = await import('node:path');
13
13
  fs.mkdirSync(p.entries, { recursive: true });
14
+ // Healing missing files is not enough when the file that changed is one the volume already
15
+ // has. 0.6.0 rewrote every entry.md — artifacts became {key, bytes, sha256} records — and
16
+ // because the volume's copies existed, none were replaced: all 31 entries failed validation
17
+ // and the gallery served nothing but drafts. Copy-if-absent can only ever fix an entry that
18
+ // is incomplete, never one that is stale, so a schema change breaks the corpus permanently.
19
+ // The stamp closes that: when the image's version differs from the one this volume was last
20
+ // seeded at, entry.md is re-copied for the slugs the seed ships.
21
+ const stamp = path.join(p.data, '.seed-version');
22
+ let seeded;
23
+ try { seeded = fs.readFileSync(stamp, 'utf8').trim(); } catch { seeded = null; }
24
+ const upgraded = seeded !== p.version;
14
25
  let copied = 0;
15
26
  let healed = 0;
27
+ let refreshed = 0;
16
28
  for (const d of fs.readdirSync(p.seed, { withFileTypes: true })) {
17
29
  if (!d.isDirectory() || !fs.existsSync(path.join(p.seed, d.name, 'entry.md'))) continue;
18
30
  const src = path.join(p.seed, d.name);
@@ -31,9 +43,22 @@ async function syncSeed(p) {
31
43
  return true;
32
44
  },
33
45
  });
46
+ // Only entry.md, and only on an upgrade. Everything else the seed ships is inert next to
47
+ // an artifact record, and a hosted ingest never lands on a slug the image also ships — so
48
+ // what this can overwrite is an operator's hand-edit of a seeded entry, which an image
49
+ // upgrade was always going to supersede. Serving a corpus that validates beats preserving
50
+ // an edit that only exists until the next deploy.
51
+ if (!upgraded) continue;
52
+ const from = path.join(src, 'entry.md');
53
+ const to = path.join(dest, 'entry.md');
54
+ if (fs.readFileSync(from, 'utf8') === fs.readFileSync(to, 'utf8')) continue;
55
+ fs.copyFileSync(from, to);
56
+ refreshed++;
34
57
  }
58
+ fs.writeFileSync(stamp, p.version);
35
59
  process.stderr.write(`seed: copied ${copied} new entries into ${p.entries}\n`);
36
60
  process.stderr.write(`seed: healed ${healed} missing files into existing entries\n`);
61
+ process.stderr.write(`seed: refreshed ${refreshed} stale entry.md (volume seeded at ${seeded ?? 'unknown'}, image is ${p.version})\n`);
37
62
  }
38
63
  }
39
64