@wizzlethorpe/vaults 0.14.0 → 0.15.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 (67) hide show
  1. package/README.md +2 -2
  2. package/dist/asset-refs.js +18 -10
  3. package/dist/asset-refs.js.map +1 -1
  4. package/dist/build.js +159 -70
  5. package/dist/build.js.map +1 -1
  6. package/dist/commands/build.js +1 -54
  7. package/dist/commands/build.js.map +1 -1
  8. package/dist/config.js.map +1 -1
  9. package/dist/escape.js +20 -0
  10. package/dist/escape.js.map +1 -1
  11. package/dist/foundry-adventure.js +86 -0
  12. package/dist/foundry-adventure.js.map +1 -0
  13. package/dist/foundry-defaults.js +65 -0
  14. package/dist/foundry-defaults.js.map +1 -0
  15. package/dist/foundry-grafts.js +610 -0
  16. package/dist/foundry-grafts.js.map +1 -0
  17. package/dist/foundry-html.js +196 -0
  18. package/dist/foundry-html.js.map +1 -0
  19. package/dist/foundry-importer.bundle.js +39 -3
  20. package/dist/foundry-meta.js +15 -243
  21. package/dist/foundry-meta.js.map +1 -1
  22. package/dist/foundry-module-journal.js +24 -3
  23. package/dist/foundry-module-journal.js.map +1 -1
  24. package/dist/foundry-module.js +19 -12
  25. package/dist/foundry-module.js.map +1 -1
  26. package/dist/foundry-types.js +28 -0
  27. package/dist/foundry-types.js.map +1 -0
  28. package/dist/foundry-version.js +30 -0
  29. package/dist/foundry-version.js.map +1 -0
  30. package/dist/frontmatter-defaults.js +1 -1
  31. package/dist/frontmatter-defaults.js.map +1 -1
  32. package/dist/index.js +0 -4
  33. package/dist/index.js.map +1 -1
  34. package/dist/manifest.js +1 -1
  35. package/dist/manifest.js.map +1 -1
  36. package/dist/migrate/0.15-foundry-patch-keys.js +51 -0
  37. package/dist/migrate/0.15-foundry-patch-keys.js.map +1 -0
  38. package/dist/migrate/0.15-foundry-pinned-id.js +68 -0
  39. package/dist/migrate/0.15-foundry-pinned-id.js.map +1 -0
  40. package/dist/migrate/files.js +66 -0
  41. package/dist/migrate/files.js.map +1 -0
  42. package/dist/migrate/registry.js +4 -0
  43. package/dist/migrate/registry.js.map +1 -1
  44. package/dist/migrate/run.js +36 -2
  45. package/dist/migrate/run.js.map +1 -1
  46. package/dist/render/auth-template.js +9 -8
  47. package/dist/render/auth-template.js.map +1 -1
  48. package/dist/render/handlers/assets.js +5 -34
  49. package/dist/render/handlers/assets.js.map +1 -1
  50. package/dist/render/handlers/builtin/battlemap.js +4 -1
  51. package/dist/render/handlers/builtin/battlemap.js.map +1 -1
  52. package/dist/render/handlers/builtin/fm-code.js +2 -2
  53. package/dist/render/handlers/builtin/fm-code.js.map +1 -1
  54. package/dist/render/handlers/builtin/fvtt-link.js +39 -0
  55. package/dist/render/handlers/builtin/fvtt-link.js.map +1 -0
  56. package/dist/render/handlers/builtin/index.js +2 -1
  57. package/dist/render/handlers/builtin/index.js.map +1 -1
  58. package/dist/render/handlers/builtin/statblock.js +0 -4
  59. package/dist/render/handlers/builtin/statblock.js.map +1 -1
  60. package/dist/render/handlers/types.js.map +1 -1
  61. package/dist/scan.js +0 -8
  62. package/dist/scan.js.map +1 -1
  63. package/dist/settings.js +57 -28
  64. package/dist/settings.js.map +1 -1
  65. package/dist/zip.js +78 -0
  66. package/dist/zip.js.map +1 -0
  67. package/package.json +3 -3
package/README.md CHANGED
@@ -45,7 +45,7 @@ Cloudflare Pages ← per-user, your account
45
45
  - **Per-tier deploys.** A page tagged `role: dm` in its frontmatter only includes to the dm variant. Public visitors *cannot* fetch it; the file structurally doesn't exist in their variant.
46
46
  - **Inline gating with callouts.** Drop a `> [!dm]` callout in an otherwise public page; the entire block is stripped from the public deploy. Same for any other configured role.
47
47
  - **Images and media are gated too.** Only images, audio, video, PDFs, and EPUBs embedded by visible pages are copied into a given variant. Unknown extensions are skipped by default (toggle `include_unknown_files`).
48
- - **Incremental sync.** External clients (the [Foundry VTT module](https://github.com/wizzlethorpe/vaults)) probe `/_manifest.json` to discover the deploy's name, auth requirements, and role order, then pull `/_batch` (text) and `/_batch-images` (binary) for changed content. Manifest hashes fold in per-page frontmatter, so a role flip or title rename triggers a sync without a body diff.
48
+ - **Foundry integration.** The build compiles each role's pages into `_foundry/grafts.json`, an entry list the [Foundry module](https://github.com/wizzlethorpe/vaults) hands to [graft](https://github.com/wizzlethorpe/graft) to build on the reader's own machine. Bodies and art travel as references and are pulled through `/_batch` (text) and `/_batch-images` (binary) in the reader's own role variant, so a player never receives the GM's rendering of a page.
49
49
  - **Bases support.** `.base` files render as cards / table / list inside the wiki, just like inside Obsidian.
50
50
  - **LaTeX math.** `$inline$` and `$$display$$` math render server-side via KaTeX, matching Obsidian's syntax. The stylesheet and fonts are self-hosted and only ship for vaults that contain math.
51
51
  - **Social meta.** OG / Twitter card tags are auto-generated. Pages without an explicit `image:` frontmatter use the first body embed (toggle with `auto_image`).
@@ -217,7 +217,7 @@ Multi-role deploys include with a small Cloudflare Pages Function (`_middleware.
217
217
  - **Issues bearer tokens** through an OAuth-style `/connect` flow used by the [Foundry module](https://github.com/wizzlethorpe/vaults).
218
218
  - **Handles Patreon login** at `/auth/patreon/start` and `/auth/patreon/callback`, and **OIDC login** at `/auth/oidc/start` and `/auth/oidc/callback`, when configured.
219
219
  - **Exposes** `/_batch` (text) and `/_batch-images` (binary) for bulk content sync.
220
- - **Publishes** `/_manifest.json` with the deploy's name, role order, and auth requirements so external clients can probe the deploy before picking an auth flow.
220
+ - **Publishes** `_foundry/module.json`, `module.zip` and `version.json` ungated, so Foundry can install the vault's module without a credential, while the entry list behind them stays role-gated.
221
221
 
222
222
  Tokens are stateless HMAC-signed JWTs; revocation = rotate `SESSION_SECRET` via `vaults push --rotate-secret`.
223
223
 
@@ -18,7 +18,9 @@ import { foundryManifestPaths } from "./render/handlers/builtin/foundry-manifest
18
18
  import { IMAGE_EXT_RE } from "./render/extensions.js";
19
19
  import { slugify } from "./render/slug.js";
20
20
  import { loadDataJson } from "./foundry-meta.js";
21
- const EMBED_RE = /!\[\[([^\[\]|#\n]+?)(?:\|[^\[\]#\n]*)?\]\]/g;
21
+ // The optional backslash matters: a table cell has to escape the size hint's
22
+ // pipe, and keeping that backslash in the name misses the index silently.
23
+ const EMBED_RE = /!\[\[([^\[\]|#\n]+?)\\?(?:\|[^\[\]#\n]*)?\]\]/g;
22
24
  // A ```gallery code block. Its body lists images by name (one per line,
23
25
  // optional `| caption`), which the gallery handler renders but the source
24
26
  // scanners would otherwise never see — so we read the block here to stage
@@ -29,7 +31,7 @@ const GALLERY_BLOCK_RE = /^```gallery[^\n]*\n([\s\S]*?)^```/gm;
29
31
  // internal page links (e.g. `(href)` without an extension).
30
32
  const MD_LINK_RE = /\[[^\]]*\]\(([^)\s]+\.[a-z0-9]+)(?:\s+["'][^"']*["'])?\)/gi;
31
33
  // `[[file.ext]]` and `![[file.ext]]` — Obsidian-flavoured wikilinks/embeds.
32
- const WIKI_LINK_RE = /!?\[\[([^\[\]|#\n]+\.[a-z0-9]+)(?:\|[^\[\]#\n]*)?(?:#[^\[\]\n]*)?\]\]/gi;
34
+ const WIKI_LINK_RE = /!?\[\[([^\[\]|#\n]+\.[a-z0-9]+)\\?(?:\|[^\[\]#\n]*)?(?:#[^\[\]\n]*)?\]\]/gi;
33
35
  /** Image basenames referenced inside a page's ```gallery blocks. */
34
36
  function galleryImageNames(source) {
35
37
  const names = [];
@@ -108,7 +110,7 @@ export async function copyReferencedImages(visibleSources, visibleMetas, imageIn
108
110
  }
109
111
  });
110
112
  }
111
- // Image refs inside the page's foundry.data_json (Scene backgrounds, tiles).
113
+ // Image refs inside the page's foundry.patch_json (Scene backgrounds, tiles).
112
114
  for (const path of p.foundryAssets ?? []) {
113
115
  if (!IMAGE_EXT_RE.test(path))
114
116
  continue;
@@ -117,12 +119,14 @@ export async function copyReferencedImages(visibleSources, visibleMetas, imageIn
117
119
  refs.add(image.outputPath);
118
120
  }
119
121
  }
122
+ const copied = [];
120
123
  for (const outputPath of refs) {
121
124
  const src = join(stagingDir, outputPath);
122
125
  const dst = join(variantDir, outputPath);
123
126
  await mkdir(dirname(dst), { recursive: true });
124
127
  try {
125
128
  await copyFile(src, dst);
129
+ copied.push(outputPath);
126
130
  }
127
131
  catch (err) {
128
132
  // Source may legitimately be missing if the file is in the index but
@@ -130,9 +134,10 @@ export async function copyReferencedImages(visibleSources, visibleMetas, imageIn
130
134
  console.warn(` warning: could not copy image ${outputPath}: ${err.message}`);
131
135
  }
132
136
  }
137
+ return copied;
133
138
  }
134
139
  /** Collect the `@vault/...` paths a page's foundry block references, from both
135
- * `foundry.data_json` and `foundry.data`. A Scene's bulk asset refs
140
+ * `foundry.patch_json` and `foundry.patch`. A Scene's bulk asset refs
136
141
  * (backgrounds, ambient sounds, tiles) live in that JSON content, and a token's
137
142
  * ring subject lives in the inline `data` overlay; neither appears anywhere the
138
143
  * per-variant asset scanners look, so without this they never ship and Foundry
@@ -148,20 +153,20 @@ export async function collectDataJsonVaultRefs(vaultPath, fm, pagePath) {
148
153
  if (path)
149
154
  out.push(path);
150
155
  });
151
- const rel = block["data_json"];
156
+ const rel = block["patch_json"];
152
157
  if (typeof rel === "string" && rel.trim()) {
153
158
  const parsed = await loadDataJson(vaultPath, rel.trim(), pagePath);
154
159
  if (parsed !== null)
155
160
  collect(parsed);
156
161
  }
157
- collect(block["data"]);
162
+ collect(block["patch"]);
158
163
  return out;
159
164
  }
160
165
  /**
161
166
  * Visit every string value reachable from `value` (object / array / scalar)
162
167
  * and call `fn` once per string. Used to surface `@vault/PATH` references
163
- * inside parsed frontmatter (e.g., a Scene's `foundry.data.background.src`
164
- * or a Playlist's `foundry.data.sounds[N].path`) so the per-variant asset
168
+ * inside parsed frontmatter (e.g., a Scene's `foundry.patch.background.src`
169
+ * or a Playlist's `foundry.patch.sounds[N].path`) so the per-variant asset
165
170
  * scanner can include those files alongside body-referenced ones.
166
171
  */
167
172
  export function forEachString(value, fn) {
@@ -204,7 +209,7 @@ export async function copyReferencedPassthroughs(visibleSources, visibleMetas, p
204
209
  */
205
210
  manifestDownloads = new Map()) {
206
211
  if (passthroughIndex.size === 0)
207
- return;
212
+ return [];
208
213
  const refs = new Set();
209
214
  for (const source of visibleSources.values()) {
210
215
  for (const m of source.matchAll(WIKI_LINK_RE)) {
@@ -252,23 +257,26 @@ manifestDownloads = new Map()) {
252
257
  refs.add(entry.outputPath);
253
258
  }
254
259
  });
255
- // Audio/video/pdf refs inside the page's foundry.data_json (ambient sounds).
260
+ // Audio/video/pdf refs inside the page's foundry.patch_json (ambient sounds).
256
261
  for (const path of p.foundryAssets ?? []) {
257
262
  const entry = passthroughIndex.get(path);
258
263
  if (entry)
259
264
  refs.add(entry.outputPath);
260
265
  }
261
266
  }
267
+ const copied = [];
262
268
  for (const outputPath of refs) {
263
269
  const src = join(stagingDir, outputPath);
264
270
  const dst = join(variantDir, outputPath);
265
271
  await mkdir(dirname(dst), { recursive: true });
266
272
  try {
267
273
  await copyFile(src, dst);
274
+ copied.push(outputPath);
268
275
  }
269
276
  catch (err) {
270
277
  console.warn(` warning: could not copy ${outputPath}: ${err.message}`);
271
278
  }
272
279
  }
280
+ return copied;
273
281
  }
274
282
  //# sourceMappingURL=asset-refs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"asset-refs.js","sourceRoot":"","sources":["../src/asset-refs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"asset-refs.js","sourceRoot":"","sources":["../src/asset-refs.ts"],"names":[],"mappings":"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"}
package/dist/build.js CHANGED
@@ -9,22 +9,20 @@ import { htmlEscape } from "./escape.js";
9
9
  import { collectDataJsonVaultRefs, copyReferencedImages, copyReferencedPassthroughs, } from "./asset-refs.js";
10
10
  import { downloadFilePaths } from "./render/handlers/builtin/download.js";
11
11
  import { foundryManifestPaths, manifestDownloadPath } from "./render/handlers/builtin/foundry-manifest.js";
12
- import { buildManifest } from "./manifest.js";
13
- import { collectBodyMeta, warnFoundryDocCollisions } from "./foundry-meta.js";
12
+ import { warnFoundryDocCollisions } from "./foundry-meta.js";
14
13
  import { compressImage } from "./images.js";
15
14
  import { IMAGE_EXT_RE, PASSTHROUGH_EXT_RE, COMPRESSIBLE_EXT_RE, } from "./render/extensions.js";
16
15
  import { buildFavicon } from "./favicon.js";
17
16
  import { renderMarkdown } from "./render/pipeline.js";
18
17
  import { extractH1 } from "./render/frontmatter.js";
19
18
  import { renderLayout, render404 } from "./render/layout.js";
20
- import { writeFoundryImporter } from "./foundry-importer.js";
21
19
  import { slugify } from "./render/slug.js";
22
20
  import { buildPreview } from "./render/preview.js";
23
21
  import { resolvePageImage } from "./render/cover.js";
24
22
  import { DEFAULT_CSS, renderThemeOverride } from "./render/styles.js";
25
23
  import { loadObsidianSnippets } from "./obsidian.js";
26
24
  import { loadSettings, writeSettings, SETTINGS_FILE } from "./settings.js";
27
- import { loadConfig } from "./config.js";
25
+ import { loadConfig, saveConfig } from "./config.js";
28
26
  import { applyFrontmatterDefaults, compileFrontmatterRules } from "./frontmatter-defaults.js";
29
27
  import matter from "gray-matter";
30
28
  import { renderAuthMiddleware, renderLoginPage } from "./render/auth-template.js";
@@ -36,6 +34,11 @@ import { bundleHandlerAssets } from "./render/handlers/assets.js";
36
34
  import { runMigrations } from "./migrate/run.js";
37
35
  import { cacheDir } from "./paths.js";
38
36
  import { formatDuration, pMap, Progress } from "./util.js";
37
+ import { buildGrafts, contentHash, moduleManifest, moduleGrafts, packsFor, pagesFrom, withFolderIndexes } from "./foundry-grafts.js";
38
+ import { toFoundryHtml, dualVariantBody } from "./foundry-html.js";
39
+ import { zip } from "./zip.js";
40
+ import { moduleVersion } from "./foundry-version.js";
41
+ import { loadDataJson } from "./foundry-meta.js";
39
42
  /**
40
43
  * Output layout when there are multiple roles:
41
44
  *
@@ -368,7 +371,7 @@ export async function buildSite(input) {
368
371
  if (roleErrors.length > 0) {
369
372
  throw new Error(`Unknown frontmatter role on ${roleErrors.length} page(s) (build aborted so gated pages can't leak):\n${roleErrors.join("\n")}`);
370
373
  }
371
- // Stage assets referenced inside each page's foundry.data_json (Scene
374
+ // Stage assets referenced inside each page's foundry.patch_json (Scene
372
375
  // backgrounds / ambient sounds / tile art live in that JSON, not the page
373
376
  // frontmatter, so the asset scanners below consult p.foundryAssets).
374
377
  await Promise.all(allPageMetas.map(async (p) => {
@@ -473,18 +476,8 @@ export async function buildSite(input) {
473
476
  .update(DEFAULT_CSS + themeOverride + userCss + handlerAssets.js + handlerAssets.css + katexVersion)
474
477
  .digest("hex")
475
478
  .slice(0, 10);
476
- // Foundry importer bundle: one ESM file the Foundry module fetches at
477
- // sync time. Skipped entirely when the vault has opted out of the Foundry
478
- // integration — it is ~60KB shipped to every deploy, and a course site or
479
- // research wiki will never fetch it.
480
479
  const foundryEnabled = settings.values.foundry.package !== "none";
481
- if (foundryEnabled)
482
- await writeFoundryImporter(opts.outputDir);
483
- // Foundry-import bundles are written per-variant inside the role loop
484
- // below (instead of at the root) so the middleware role-gates them. A
485
- // public visitor can't fetch the dm-tier handler bundle even if it
486
- // contains different content. The path stays `/_handlers.foundry.{js,css}`
487
- // — the middleware rewrites root requests to the matching variant.
480
+ const foundryPackaging = settings.values.foundry.package === "adventure" ? "adventure" : "compendium";
488
481
  // Favicon; either user-supplied via settings.favicon, or a generated
489
482
  // default with the vault's first letter in accent on the theme background.
490
483
  try {
@@ -526,11 +519,64 @@ export async function buildSite(input) {
526
519
  meta.coverImage = cover;
527
520
  }
528
521
  warnFoundryDocCollisions(allPageMetas);
522
+ // Said once for the vault, not once per role: it is a fact about the
523
+ // settings, and the per-variant emitter would repeat it for each.
524
+ if (foundryEnabled && !settings.values.foundry.core_version
525
+ && allPageMetas.some((p) => p.frontmatter?.["foundry"]?.source)) {
526
+ console.warn(" foundry.core_version is not set, so documents carry no _stats.coreVersion."
527
+ + " Foundry rejects those and builds a degraded copy instead: a Scene loses its levels."
528
+ + " Set it to the full Foundry version your exported JSON came from, e.g. 14.359.");
529
+ }
530
+ // The module is only emitted when there is a URL to fetch the vault from,
531
+ // so without one the deploy carries content Foundry has no way to install.
532
+ if (foundryEnabled && !opts.siteUrl) {
533
+ console.warn(" site_url is not set, so no Foundry module is written."
534
+ + " The vault deploys, but there is nothing to install in Foundry."
535
+ + " Set it to the URL this vault is served from, e.g. https://notes.example.com.");
536
+ }
537
+ // Read each page's `foundry.patch_json` once, before any variant is
538
+ // rendered: the file is the same whoever is reading, and a Scene sidecar is
539
+ // the largest thing in the vault to be re-parsing per role. It stays separate
540
+ // from the page's inline patch, because it is a weaker statement than one —
541
+ // an export carries whatever Foundry had, including its placeholders.
542
+ const foundryPatches = new Map();
543
+ await Promise.all(allPageMetas.map(async (p) => {
544
+ const fo = p.frontmatter?.["foundry"];
545
+ if (!fo || typeof fo !== "object" || Array.isArray(fo))
546
+ return;
547
+ const block = fo;
548
+ const ref = block["patch_json"];
549
+ if (typeof ref !== "string" || !ref.trim())
550
+ return;
551
+ const loaded = await loadDataJson(opts.vaultPath, ref.trim(), p.path);
552
+ if (!loaded || typeof loaded !== "object" || Array.isArray(loaded))
553
+ return;
554
+ foundryPatches.set(p.path, loaded);
555
+ }));
556
+ // A module id from the vault name: stable, lowercase, no spaces. It names
557
+ // the packs too, so changing it orphans what a reader already built.
558
+ const foundryModuleId = opts.vaultName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "")
559
+ || "vault";
529
560
  // ── Per-role variant builds ─────────────────────────────────────────────
530
561
  const perRolePageCount = {};
531
562
  const collapseToRoot = roles.length === 1;
532
563
  let defaultRolePagePaths = [];
533
564
  let katexCopied = false;
565
+ // What the Foundry provider compares a cached file against, so a rebuild
566
+ // re-fetches only what changed. Keyed "<variant>/<path>", and hashed once
567
+ // per asset rather than once per variant: every variant copies the same
568
+ // staged file. Roles run least privileged first, so by the time a variant
569
+ // writes its grafts.json the map holds every variant it can reference.
570
+ const assetHashes = new Map();
571
+ const hashOf = new Map();
572
+ const hashAsset = async (path, dir) => {
573
+ let digest = hashOf.get(path);
574
+ if (!digest) {
575
+ digest = createHash("md5").update(await readFile(join(dir, path))).digest("hex").slice(0, 16);
576
+ hashOf.set(path, digest);
577
+ }
578
+ return digest;
579
+ };
534
580
  for (const role of roles) {
535
581
  const variantDir = collapseToRoot
536
582
  ? opts.outputDir
@@ -572,6 +618,9 @@ export async function buildSite(input) {
572
618
  allWarnings: opts.allWarnings,
573
619
  });
574
620
  perRolePageCount[role] = stats.pageCount;
621
+ for (const path of stats.assetPaths) {
622
+ assetHashes.set(`${role}/${path}`, await hashAsset(path, variantDir));
623
+ }
575
624
  // Only the default (lowest) role feeds the sitemap; see writeSitemap.
576
625
  if (role === roles[0])
577
626
  defaultRolePagePaths = stats.pagePaths;
@@ -584,36 +633,98 @@ export async function buildSite(input) {
584
633
  await copyKatexAssets(join(opts.outputDir, "katex"));
585
634
  katexCopied = true;
586
635
  }
587
- // Foundry-import opt-in bundles, emitted INSIDE the variant directory
588
- // (not at the deploy root) so the auth middleware role-gates them.
589
- // Single-role builds collapse variantDir to outputDir, so the file
590
- // ends up at root automatically. The Foundry module fetches by the
591
- // canonical `/_handlers.foundry.{js,css}` path; the middleware
592
- // rewrites that to the matching `_variants/<role>/...` per the
593
- // requesting bearer token's role.
594
- // Foundry-import subset bundles. The Foundry module fetches these by
595
- // their canonical `/_handlers.foundry.{js,css}` paths; the middleware
596
- // role-gates per the requesting bearer's variant.
597
- if (foundryEnabled && handlerAssets.foundry) {
598
- if (handlerAssets.foundry.js.length > 0) {
599
- await writeFile(join(variantDir, "_handlers.foundry.js"), handlerAssets.foundry.js);
600
- }
601
- if (handlerAssets.foundry.css.length > 0) {
602
- await writeFile(join(variantDir, "_handlers.foundry.css"), handlerAssets.foundry.css);
603
- }
636
+ // The entry list graft builds from, inside the variant directory so the
637
+ // auth middleware gates it: a role only ever receives the pages it may
638
+ // read, and the GM's variant is the one that lists everything.
639
+ if (foundryEnabled) {
640
+ const graftPages = withFolderIndexes(pagesFrom(allPageMetas, visibleRoles, foundryPatches), roles);
641
+ const grafts = buildGrafts(graftPages, {
642
+ vaultId: foundryModuleId,
643
+ roles,
644
+ playerRole: settings.values.foundry.player_role,
645
+ buildRole: role,
646
+ packs: packsFor(foundryModuleId),
647
+ coreVersion: settings.values.foundry.core_version,
648
+ system: settings.values.foundry.system,
649
+ packaging: foundryPackaging,
650
+ title: opts.vaultName,
651
+ assets: Object.fromEntries(assetHashes),
652
+ });
653
+ for (const warning of grafts.warnings)
654
+ console.warn(` warning: ${warning}`);
655
+ // A second body per page, with links resolved to UUIDs and media pointed
656
+ // at markers the provider fills in. Foundry gets this one; the wiki keeps
657
+ // the plain `.body.html`, since the same HTML cannot serve both.
658
+ // A player-visible page's body carries both renders: the GM's inside a
659
+ // secret section, the player's in the open (see dualVariantBody). Roles
660
+ // build lowest first, so the player variant's body is already on disk.
661
+ const playerRole = settings.values.foundry.player_role;
662
+ const ceiling = roles.indexOf(playerRole);
663
+ const playerDir = collapseToRoot
664
+ ? opts.outputDir
665
+ : join(opts.outputDir, "_variants", playerRole);
666
+ // Only bodies an entry references: a page kept out of Foundry, or one
667
+ // whose prose goes nowhere, must not move the hash and prompt a rebuild.
668
+ const referenced = new Set([...JSON.stringify(grafts.file.entries).matchAll(/@vaults\/[^/"]+\/((?:[^"\\]|\\.)+?)\.foundry\.html/g)]
669
+ .map((m) => JSON.parse(`"${m[1]}"`) + ".md"));
670
+ const bodyHashes = new Map();
671
+ await pMap(graftPages.filter((p) => referenced.has(p.path)), concurrency, async (page) => {
672
+ const base = page.path.replace(/\.md$/i, "");
673
+ const body = await readFile(join(variantDir, `${base}.body.html`), "utf8");
674
+ const gm = toFoundryHtml(body, grafts.links, role);
675
+ const observable = ceiling >= 0 && roles.indexOf(page.role) <= ceiling;
676
+ const dual = observable && roles.indexOf(role) > ceiling;
677
+ const out = dual
678
+ ? dualVariantBody(gm, toFoundryHtml(await readFile(join(playerDir, `${base}.body.html`), "utf8"), grafts.links, playerRole))
679
+ : gm;
680
+ await writeFile(join(variantDir, `${base}.foundry.html`), out);
681
+ bodyHashes.set(page.path, createHash("md5").update(out).digest("hex"));
682
+ });
683
+ grafts.file.contentHash = contentHash(grafts.file.entries, grafts.file.assets ?? {}, bodyHashes);
684
+ await mkdir(join(variantDir, "_foundry"), { recursive: true });
685
+ await writeFile(join(variantDir, "_foundry", "grafts.json"), JSON.stringify(grafts.file, null, 2));
686
+ // The freshness signal, apart from the 1MB+ file it describes: the
687
+ // module reads this on world load to ask "anything new since I built?".
688
+ await writeFile(join(variantDir, "_foundry", "version.json"), JSON.stringify({ content: grafts.file.contentHash }));
604
689
  }
605
- // Write a per-variant _manifest.json so external clients (Foundry, MCP,
606
- // etc.) can do an incremental diff. Includes EVERY file that variant
607
- // serves; html, md, images (as relative paths into shared root), css.
608
- // bodyMeta carries per-page Foundry reskin metadata; folded into each
609
- // body row's hash so meta-only changes trigger a re-sync.
610
- const manifest = await buildManifest(opts.outputDir, variantDir, stats.bodyMeta, !collapseToRoot, roles, opts.vaultName, {
611
- hasHandlerJs,
612
- hasHandlerCss,
613
- hasFoundryJs: foundryEnabled && (handlerAssets.foundry?.js.length ?? 0) > 0,
614
- hasFoundryCss: foundryEnabled && (handlerAssets.foundry?.css.length ?? 0) > 0,
615
- }, settings.values.foundry.package, allRoleSet.has(settings.values.foundry.player_role) ? settings.values.foundry.player_role : "");
616
- await writeFile(join(variantDir, "_manifest.json"), JSON.stringify(manifest));
690
+ }
691
+ // The module a reader installs, served by the vault itself: no release, no
692
+ // zip, no registry the GM sends players a link to their own vault. It is
693
+ // generated once and then inert, so pushing content never reinstalls it.
694
+ if (foundryEnabled && opts.siteUrl) {
695
+ const dir = join(opts.outputDir, "_foundry");
696
+ await mkdir(dir, { recursive: true });
697
+ // Versioned from the manifest itself, so it reads as a date and moves only
698
+ // when the module changes. `assetVersion` is a hash of the stylesheet: it
699
+ // cannot be ordered, which is what Foundry needs to offer an update.
700
+ const manifest = moduleManifest({
701
+ moduleId: foundryModuleId,
702
+ title: opts.vaultName,
703
+ vaultUrl: opts.siteUrl,
704
+ systemId: settings.values.foundry.system,
705
+ packaging: foundryPackaging,
706
+ extra: settings.values.foundry.module,
707
+ });
708
+ const stamped = moduleVersion(manifest, cfg.foundryModule);
709
+ manifest["version"] = stamped.version;
710
+ if (stamped.version !== cfg.foundryModule?.version) {
711
+ await saveConfig(input.vaultPath, { ...cfg, foundryModule: stamped });
712
+ }
713
+ await writeFile(join(dir, "module.json"), JSON.stringify(manifest, null, 2));
714
+ // The module itself, which is what Foundry installs from the manifest. It
715
+ // holds no content: a manifest, and the one line naming the vault to read.
716
+ //
717
+ // The marker exists only inside the archive. graft reads a module's entry
718
+ // file from `modules/<id>/grafts.json` — the installed copy — so serving
719
+ // one at the deploy root would be a file nothing fetches, sharing a name
720
+ // with the per-variant entry list the middleware rewrites `/_foundry/` to.
721
+ // Pack directories are absent on purpose: Foundry creates them.
722
+ const manifestJson = await readFile(join(dir, "module.json"));
723
+ const marker = Buffer.from(JSON.stringify(moduleGrafts(opts.siteUrl, !collapseToRoot), null, 2) + "\n");
724
+ await writeFile(join(dir, "module.zip"), zip([
725
+ { name: `${foundryModuleId}/module.json`, data: manifestJson },
726
+ { name: `${foundryModuleId}/grafts.json`, data: marker },
727
+ ]));
617
728
  }
618
729
  // ── Pages Functions ─────────────────────────────────────────────────────
619
730
  // Auth middleware ships only for multi-role builds. Single-role deploys
@@ -796,7 +907,6 @@ async function buildVariant(a) {
796
907
  const previewMode = previewModeOf(a.settings.preview_mode);
797
908
  const previewModeMobile = previewModeOf(a.settings.preview_mode_mobile);
798
909
  const previewsEnabled = previewMode !== "none" || previewModeMobile !== "none";
799
- const bodyMeta = new Map();
800
910
  await pMap(visibleMetas, a.concurrency, async (p) => {
801
911
  const r = rendered.get(p.path);
802
912
  const backlinkPaths = backlinkMap.get(p.path) ?? new Set();
@@ -836,7 +946,6 @@ async function buildVariant(a) {
836
946
  // remark/rehype pipeline land in journals as-is, no client-side render.
837
947
  const bodyPath = outputBase + ".body.html";
838
948
  await writeFile(join(a.variantDir, bodyPath), r.html);
839
- bodyMeta.set(bodyPath, await collectBodyMeta(p, a.vaultPath));
840
949
  // Preview JSON feeds the popover; skip it only when neither device class
841
950
  // shows previews (both modes "none").
842
951
  if (previewsEnabled) {
@@ -885,17 +994,17 @@ async function buildVariant(a) {
885
994
  // under the variants that need them so guessing a DM-only image URL on
886
995
  // the public wiki structurally 404s. coverImage feeds in here too so
887
996
  // images named via `image:` frontmatter (no body embed) still ship.
888
- await copyReferencedImages(visibleSources, visibleMetas, a.imageIndex, a.imageStagingDir, a.variantDir);
997
+ const copiedImages = await copyReferencedImages(visibleSources, visibleMetas, a.imageIndex, a.imageStagingDir, a.variantDir);
889
998
  // Passthrough files (audio/video/pdf/epub) follow the same gating
890
999
  // contract as images: ship only into variants whose visible pages
891
1000
  // reference the file. A DM-only audio cue can't ride along into the
892
1001
  // public deploy because no public-tier source mentions it.
893
- await copyReferencedPassthroughs(visibleSources, visibleMetas, a.passthroughIndex, a.passthroughStagingDir, a.variantDir, a.manifestDownloads);
1002
+ const copiedOther = await copyReferencedPassthroughs(visibleSources, visibleMetas, a.passthroughIndex, a.passthroughStagingDir, a.variantDir, a.manifestDownloads);
894
1003
  return {
895
1004
  pageCount: visibleMetas.length,
896
1005
  pagePaths: visibleMetas.map((m) => m.path),
897
- bodyMeta,
898
1006
  hasMath: hasMathCss,
1007
+ assetPaths: [...copiedImages, ...copiedOther],
899
1008
  };
900
1009
  }
901
1010
  /**
@@ -926,20 +1035,6 @@ async function copyKatexAssets(destDir) {
926
1035
  }
927
1036
  }
928
1037
  }
929
- /**
930
- * Build the per-body manifest meta from a page's frontmatter + resolved
931
- * cover image. `role` always lands so the Foundry side can apply the
932
- * dmRole permission gate; the foundry / image fields are conditional.
933
- *
934
- * Frontmatter shape forwarded to clients:
935
- * foundry:
936
- * base: <UUID> | <Type>[:<subtype>] # required for instantiation
937
- * sync: false # default true; skip Foundry entirely
938
- * journal: false # default true; doc only, no journal page
939
- * link: doc # default journal; link to the doc instead
940
- * embed: false # default true
941
- * data: { … deep-merged into the doc }
942
- */
943
1038
  /** Coerce settings.theme to the layout's narrowed union, defaulting to
944
1039
  * "auto" for any unrecognised value rather than failing the build. */
945
1040
  function themeOf(s) {
@@ -1277,12 +1372,6 @@ function kindLabel(kind) {
1277
1372
  default: return kind;
1278
1373
  }
1279
1374
  }
1280
- /**
1281
- * Per-page extension on .body.html manifest entries, consumed by the Foundry
1282
- * sync. Always carries the page's role (so the Foundry side can map roles to
1283
- * JournalEntry ownership against a per-vault dmRole setting); other fields
1284
- * are present only when the corresponding frontmatter is set.
1285
- */
1286
1375
  /**
1287
1376
  * Strip an HTML body to plain text. Used to feed the search index from
1288
1377
  * the rendered article (post-wikilink, post-callout-redaction) so search