blume 0.6.0 → 0.6.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/dist/cli/index.js CHANGED
@@ -513,11 +513,11 @@ Next steps:
513
513
  });
514
514
 
515
515
  // src/cli/commands/build.ts
516
- import { existsSync as existsSync14 } from "node:fs";
516
+ import { existsSync as existsSync15 } from "node:fs";
517
517
  import { readdir, stat, writeFile as writeFile7 } from "node:fs/promises";
518
518
  import { build } from "astro";
519
519
  import { defineCommand as defineCommand2 } from "citty";
520
- import { join as join23 } from "pathe";
520
+ import { join as join24 } from "pathe";
521
521
 
522
522
  // src/deploy/xml.ts
523
523
  var escapeXml = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&apos;");
@@ -844,6 +844,42 @@ var serverFeatures = (config) => {
844
844
  return features;
845
845
  };
846
846
 
847
+ // src/deploy/adapter-output.ts
848
+ import { existsSync as existsSync4 } from "node:fs";
849
+ import { cp, mkdir as mkdir2, rm } from "node:fs/promises";
850
+ import { dirname as dirname4, join as join6 } from "pathe";
851
+ var ADAPTER_OUTPUT_PATHS = {
852
+ netlify: ".netlify",
853
+ vercel: ".vercel/output"
854
+ };
855
+ var deployStaticDir = (config, context) => {
856
+ const { adapter, output } = config.deployment;
857
+ if (output === "server" && adapter === "vercel") {
858
+ return join6(context.root, ".vercel", "output", "static");
859
+ }
860
+ return context.distDir ?? join6(context.root, "dist");
861
+ };
862
+ var surfaceAdapterOutput = async (config, context) => {
863
+ const { adapter, output } = config.deployment;
864
+ if (output !== "server" || !adapter) {
865
+ return { moved: false };
866
+ }
867
+ const rel = ADAPTER_OUTPUT_PATHS[adapter];
868
+ if (!rel) {
869
+ return { moved: false };
870
+ }
871
+ const from = join6(context.outDir, rel);
872
+ const to = join6(context.root, rel);
873
+ if (!existsSync4(from)) {
874
+ return { moved: false };
875
+ }
876
+ await mkdir2(dirname4(to), { recursive: true });
877
+ await rm(to, { force: true, recursive: true });
878
+ await cp(from, to, { recursive: true });
879
+ await rm(from, { force: true, recursive: true });
880
+ return { from, ignore: `${rel.split("/")[0]}/`, moved: true, to };
881
+ };
882
+
847
883
  // src/deploy/redirects.ts
848
884
  var buildNetlifyRedirects = (redirects) => `${redirects.map((redirect) => `${redirect.from} ${redirect.to} ${redirect.status}`).join(`
849
885
  `)}
@@ -920,7 +956,7 @@ ${urls.join(`
920
956
  };
921
957
 
922
958
  // src/search/build.ts
923
- import { join as join6 } from "pathe";
959
+ import { join as join7 } from "pathe";
924
960
  var buildSearchIndex = async (outDir) => {
925
961
  const pagefind = await import("pagefind");
926
962
  const { index } = await pagefind.createIndex({});
@@ -928,7 +964,7 @@ var buildSearchIndex = async (outDir) => {
928
964
  throw new Error("Failed to create Pagefind index.");
929
965
  }
930
966
  const result = await index.addDirectory({ path: outDir });
931
- await index.writeFiles({ outputPath: join6(outDir, "pagefind") });
967
+ await index.writeFiles({ outputPath: join7(outDir, "pagefind") });
932
968
  await pagefind.close();
933
969
  return result.page_count;
934
970
  };
@@ -2976,17 +3012,17 @@ var syncSearchProvider = async (project, reporter) => {
2976
3012
 
2977
3013
  // src/cli/dev-lock.ts
2978
3014
  import {
2979
- existsSync as existsSync5,
3015
+ existsSync as existsSync6,
2980
3016
  mkdirSync,
2981
3017
  readFileSync as readFileSync2,
2982
3018
  rmSync,
2983
3019
  writeFileSync
2984
3020
  } from "node:fs";
2985
- import { join as join8 } from "pathe";
3021
+ import { join as join9 } from "pathe";
2986
3022
 
2987
3023
  // src/core/project.ts
2988
- import { existsSync as existsSync4 } from "node:fs";
2989
- import { isAbsolute, join as join7, resolve as resolve2 } from "pathe";
3024
+ import { existsSync as existsSync5 } from "node:fs";
3025
+ import { isAbsolute, join as join8, resolve as resolve2 } from "pathe";
2990
3026
  var CONFIG_FILENAMES = [
2991
3027
  "blume.config.ts",
2992
3028
  "blume.config.mjs",
@@ -2996,22 +3032,22 @@ var THEME_FILENAMES = ["theme.css"];
2996
3032
  var COMPONENTS_FILENAMES = ["components.tsx", "components.ts"];
2997
3033
  var firstExisting = (root, names) => {
2998
3034
  for (const name of names) {
2999
- const candidate = join7(root, name);
3000
- if (existsSync4(candidate)) {
3035
+ const candidate = join8(root, name);
3036
+ if (existsSync5(candidate)) {
3001
3037
  return candidate;
3002
3038
  }
3003
3039
  }
3004
3040
  return null;
3005
3041
  };
3006
3042
  var findConfigFile = (root) => firstExisting(root, CONFIG_FILENAMES);
3007
- var resolveRuntimeDir = (root, runtimeDir = ".blume") => isAbsolute(runtimeDir) ? runtimeDir : join7(resolve2(root), runtimeDir);
3043
+ var resolveRuntimeDir = (root, runtimeDir = ".blume") => isAbsolute(runtimeDir) ? runtimeDir : join8(resolve2(root), runtimeDir);
3008
3044
  var resolveProjectContext = (root, config, options) => {
3009
3045
  const absoluteRoot = resolve2(root);
3010
- const contentRoot = isAbsolute(config.content.root) ? config.content.root : join7(absoluteRoot, config.content.root);
3011
- const pagesPath = join7(absoluteRoot, config.content.pages);
3012
- const pagesRoot = existsSync4(pagesPath) ? pagesPath : null;
3046
+ const contentRoot = isAbsolute(config.content.root) ? config.content.root : join8(absoluteRoot, config.content.root);
3047
+ const pagesPath = join8(absoluteRoot, config.content.pages);
3048
+ const pagesRoot = existsSync5(pagesPath) ? pagesPath : null;
3013
3049
  const outDir = resolveRuntimeDir(absoluteRoot, options?.runtimeDir);
3014
- const distDir = options?.runtimeDir ? join7(outDir, "dist") : join7(absoluteRoot, "dist");
3050
+ const distDir = options?.runtimeDir ? join8(outDir, "dist") : join8(absoluteRoot, "dist");
3015
3051
  return {
3016
3052
  componentsFile: firstExisting(absoluteRoot, COMPONENTS_FILENAMES),
3017
3053
  configFile: findConfigFile(absoluteRoot),
@@ -3025,7 +3061,7 @@ var resolveProjectContext = (root, config, options) => {
3025
3061
  };
3026
3062
 
3027
3063
  // src/cli/dev-lock.ts
3028
- var lockPath = (outDir) => join8(outDir, "dev.lock");
3064
+ var lockPath = (outDir) => join9(outDir, "dev.lock");
3029
3065
  var isValidPid = (pid) => typeof pid === "number" && Number.isInteger(pid) && pid > 0;
3030
3066
  var parseLock = (raw) => {
3031
3067
  let data;
@@ -3055,7 +3091,7 @@ var isProcessAlive = (pid) => {
3055
3091
  };
3056
3092
  var readDevLock = (outDir) => {
3057
3093
  const path = lockPath(outDir);
3058
- if (!existsSync5(path)) {
3094
+ if (!existsSync6(path)) {
3059
3095
  return null;
3060
3096
  }
3061
3097
  const lock = parseLock(readFileSync2(path, "utf-8"));
@@ -3069,7 +3105,7 @@ var writeLock = (outDir, port) => {
3069
3105
  };
3070
3106
  var ownsLock = (outDir) => {
3071
3107
  const path = lockPath(outDir);
3072
- if (!existsSync5(path)) {
3108
+ if (!existsSync6(path)) {
3073
3109
  return false;
3074
3110
  }
3075
3111
  try {
@@ -3109,19 +3145,19 @@ var refuseIfDevRunning = (root, action, runtimeDir) => {
3109
3145
  };
3110
3146
 
3111
3147
  // src/astro/generate.ts
3112
- import { existsSync as existsSync9, readFileSync as readFileSync6, realpathSync } from "node:fs";
3148
+ import { existsSync as existsSync10, readFileSync as readFileSync6, realpathSync } from "node:fs";
3113
3149
  import {
3114
3150
  lstat,
3115
- mkdir as mkdir4,
3151
+ mkdir as mkdir5,
3116
3152
  readFile as readFile10,
3117
3153
  rename,
3118
- rm,
3154
+ rm as rm2,
3119
3155
  symlink,
3120
3156
  writeFile as writeFile5
3121
3157
  } from "node:fs/promises";
3122
3158
  import { createRequire as createRequire5 } from "node:module";
3123
3159
  import { pathToFileURL as pathToFileURL2 } from "node:url";
3124
- import { basename as basename2, dirname as dirname7, join as join16, normalize as normalize3, relative as relative7 } from "pathe";
3160
+ import { basename as basename2, dirname as dirname8, join as join17, normalize as normalize3, relative as relative7 } from "pathe";
3125
3161
  import { glob as glob4 } from "tinyglobby";
3126
3162
 
3127
3163
  // src/ai/ask-data.ts
@@ -3360,8 +3396,8 @@ var validateUsedComponents = (pages, extraTags, registryNames) => {
3360
3396
  };
3361
3397
 
3362
3398
  // src/core/component-overrides.ts
3363
- import { existsSync as existsSync6 } from "node:fs";
3364
- import { dirname as dirname4, extname, isAbsolute as isAbsolute2, resolve as resolve3 } from "pathe";
3399
+ import { existsSync as existsSync7 } from "node:fs";
3400
+ import { dirname as dirname5, extname, isAbsolute as isAbsolute2, resolve as resolve3 } from "pathe";
3365
3401
  import ts from "typescript";
3366
3402
  var GROUPS = ["mdx", "layout", "islands"];
3367
3403
  var FRAMEWORK_BY_EXT = {
@@ -3449,7 +3485,7 @@ var findDefaultExportObject = (sourceFile) => {
3449
3485
  var probeExtension = (base) => {
3450
3486
  for (const extension of COMPONENT_EXTS) {
3451
3487
  const candidate = `${base}.${extension}`;
3452
- if (existsSync6(candidate)) {
3488
+ if (existsSync7(candidate)) {
3453
3489
  return candidate;
3454
3490
  }
3455
3491
  }
@@ -3596,7 +3632,7 @@ var analyzeComponentOverrides = (source, filePath) => {
3596
3632
  return result;
3597
3633
  }
3598
3634
  const imports = collectImports(sourceFile);
3599
- const dir = dirname4(filePath);
3635
+ const dir = dirname5(filePath);
3600
3636
  for (const property of object.properties) {
3601
3637
  if (!ts.isPropertyAssignment(property)) {
3602
3638
  continue;
@@ -3891,10 +3927,10 @@ var validateNavStructure = (navigation, pages) => [
3891
3927
  ];
3892
3928
 
3893
3929
  // src/core/tsconfig-aliases.ts
3894
- import { existsSync as existsSync7, readFileSync as readFileSync3, statSync } from "node:fs";
3930
+ import { existsSync as existsSync8, readFileSync as readFileSync3, statSync } from "node:fs";
3895
3931
  import { createRequire as createRequire3 } from "node:module";
3896
3932
  import { pathToFileURL } from "node:url";
3897
- import { dirname as dirname5, isAbsolute as isAbsolute3, join as join9, resolve as resolve4 } from "pathe";
3933
+ import { dirname as dirname6, isAbsolute as isAbsolute3, join as join10, resolve as resolve4 } from "pathe";
3898
3934
  var stripJsonComments = (text) => {
3899
3935
  let out = "";
3900
3936
  let inString = false;
@@ -3957,7 +3993,7 @@ var resolveExtends = (spec, fromDir) => {
3957
3993
  return candidates.find(isFile) ?? null;
3958
3994
  }
3959
3995
  try {
3960
- const require_ = createRequire3(pathToFileURL(join9(fromDir, "_.js")).href);
3996
+ const require_ = createRequire3(pathToFileURL(join10(fromDir, "_.js")).href);
3961
3997
  for (const sub of [`${spec}/tsconfig.json`, spec]) {
3962
3998
  try {
3963
3999
  return require_.resolve(sub);
@@ -3967,7 +4003,7 @@ var resolveExtends = (spec, fromDir) => {
3967
4003
  return null;
3968
4004
  };
3969
4005
  var loadPaths = (file, seen) => {
3970
- if (seen.has(file) || !existsSync7(file)) {
4006
+ if (seen.has(file) || !existsSync8(file)) {
3971
4007
  return null;
3972
4008
  }
3973
4009
  seen.add(file);
@@ -3979,7 +4015,7 @@ var loadPaths = (file, seen) => {
3979
4015
  if (options.paths && typeof options.paths === "object") {
3980
4016
  const baseUrl = typeof options.baseUrl === "string" ? options.baseUrl : ".";
3981
4017
  return {
3982
- baseDir: resolve4(dirname5(file), baseUrl),
4018
+ baseDir: resolve4(dirname6(file), baseUrl),
3983
4019
  paths: options.paths
3984
4020
  };
3985
4021
  }
@@ -3988,7 +4024,7 @@ var loadPaths = (file, seen) => {
3988
4024
  if (typeof base !== "string") {
3989
4025
  continue;
3990
4026
  }
3991
- const resolved = resolveExtends(base, dirname5(file));
4027
+ const resolved = resolveExtends(base, dirname6(file));
3992
4028
  const found = resolved ? loadPaths(resolved, seen) : null;
3993
4029
  if (found) {
3994
4030
  return found;
@@ -4009,7 +4045,7 @@ var toAlias = (key, value, baseDir) => {
4009
4045
  return { find, replacement: resolve4(baseDir, target) };
4010
4046
  };
4011
4047
  var resolveTsconfigAliases = (root) => {
4012
- const entry = ["tsconfig.json", "jsconfig.json"].map((name) => join9(root, name)).find((file) => existsSync7(file));
4048
+ const entry = ["tsconfig.json", "jsconfig.json"].map((name) => join10(root, name)).find((file) => existsSync8(file));
4013
4049
  if (!entry) {
4014
4050
  return {};
4015
4051
  }
@@ -4107,11 +4143,11 @@ var hasScalarReferences = (config) => resolveReferences(config).some((ref) => re
4107
4143
 
4108
4144
  // src/openapi/scalar.ts
4109
4145
  import { readFile as readFile5 } from "node:fs/promises";
4110
- import { isAbsolute as isAbsolute5, join as join11 } from "pathe";
4146
+ import { isAbsolute as isAbsolute5, join as join12 } from "pathe";
4111
4147
 
4112
4148
  // src/astro/templates.ts
4113
- import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
4114
- import { dirname as dirname6, isAbsolute as isAbsolute4, join as join10, relative as relative4 } from "pathe";
4149
+ import { existsSync as existsSync9, readFileSync as readFileSync4 } from "node:fs";
4150
+ import { dirname as dirname7, isAbsolute as isAbsolute4, join as join11, relative as relative4 } from "pathe";
4115
4151
 
4116
4152
  // src/core/sources/watch.ts
4117
4153
  var BLUME_IGNORE_DIRS = [
@@ -4293,7 +4329,7 @@ var WORKSPACE_MARKERS = [
4293
4329
  "yarn.lock"
4294
4330
  ];
4295
4331
  var hasWorkspacesField = (pkgPath) => {
4296
- if (!existsSync8(pkgPath)) {
4332
+ if (!existsSync9(pkgPath)) {
4297
4333
  return false;
4298
4334
  }
4299
4335
  try {
@@ -4303,14 +4339,14 @@ var hasWorkspacesField = (pkgPath) => {
4303
4339
  return false;
4304
4340
  }
4305
4341
  };
4306
- var hasWorkspaceMarker = (dir) => hasWorkspacesField(join10(dir, "package.json")) || WORKSPACE_MARKERS.some((marker) => existsSync8(join10(dir, marker)));
4342
+ var hasWorkspaceMarker = (dir) => hasWorkspacesField(join11(dir, "package.json")) || WORKSPACE_MARKERS.some((marker) => existsSync9(join11(dir, marker)));
4307
4343
  var findWorkspaceRoot = (start) => {
4308
4344
  let dir = start;
4309
4345
  for (;; ) {
4310
4346
  if (hasWorkspaceMarker(dir)) {
4311
4347
  return dir;
4312
4348
  }
4313
- const parent = dirname6(dir);
4349
+ const parent = dirname7(dir);
4314
4350
  if (parent === dir) {
4315
4351
  return start;
4316
4352
  }
@@ -4425,9 +4461,7 @@ var astroConfigTemplate = (options) => {
4425
4461
  const twoslashTransformer = "transformerTwoslash({ explicitTrigger: true }), ";
4426
4462
  const integrations = [
4427
4463
  `mdx({ processor: blumeMdxProcessor(${JSON.stringify({
4428
- headingAnchors: config.markdown.headingAnchors,
4429
- inline: config.markdown.code.inline,
4430
- math: config.markdown.math
4464
+ headingAnchors: config.markdown.headingAnchors
4431
4465
  })}) })`
4432
4466
  ];
4433
4467
  if (needsReact) {
@@ -4455,8 +4489,7 @@ export default defineConfig({
4455
4489
  integrations: [${integrations.join(", ")}],
4456
4490
  markdown: {
4457
4491
  processor: blumeMarkdownProcessor(${JSON.stringify({
4458
- headingAnchors: config.markdown.headingAnchors,
4459
- inline: config.markdown.code.inline
4492
+ headingAnchors: config.markdown.headingAnchors
4460
4493
  })}),
4461
4494
  shikiConfig: {
4462
4495
  themes: {
@@ -4506,14 +4539,14 @@ export default defineConfig({
4506
4539
  // self-hosted fonts) -- pure noise the loader logs as "No entry type
4507
4540
  // found". Vite appends this to its default ignores.
4508
4541
  watch: {
4509
- ignored: ${JSON.stringify([join10(context.outDir, ".astro", "**")])},
4542
+ ignored: ${JSON.stringify([join11(context.outDir, ".astro", "**")])},
4510
4543
  },
4511
4544
  },
4512
4545
  },
4513
4546
  });
4514
4547
  `;
4515
4548
  };
4516
- var stagedContentDir = (outDir) => join10(outDir, "content");
4549
+ var stagedContentDir = (outDir) => join11(outDir, "content");
4517
4550
  var contentConfigTemplate = (options) => {
4518
4551
  const { context, config } = options;
4519
4552
  const stagedBase = options.stagedBase ?? stagedContentDir(context.outDir);
@@ -5203,6 +5236,20 @@ const slugify = (text) =>
5203
5236
  text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") ||
5204
5237
  "update";
5205
5238
 
5239
+ // The major of a version's embedded semver (\`1.2.3\` -> 1, \`pkg@2.0.0\` -> 2), or
5240
+ // null when there is no full major.minor.patch to key on. Drives the changelog's
5241
+ // group-by-major pagination, so it tolerates the scoped tags monorepos publish.
5242
+ const majorVersion = (version) => {
5243
+ const match = /(\\d+)\\.\\d+\\.\\d+/.exec(String(version ?? ""));
5244
+ return match ? Number(match[1]) : null;
5245
+ };
5246
+
5247
+ // Map each entry to its own generated page so the timeline heading can deep-link
5248
+ // to it. The collection entry id matches the route manifest's \`entryId\`.
5249
+ const routeByEntry = new Map(
5250
+ data.routes.map((route) => [route.entryId, route.path])
5251
+ );
5252
+
5206
5253
  const changelogEntries = [
5207
5254
  ...(await getCollection("docs")),${stagedSpread}
5208
5255
  ]
@@ -5224,8 +5271,10 @@ const items = await Promise.all(
5224
5271
  return {
5225
5272
  Content: (await render(entry)).Content,
5226
5273
  date: formatDate(entryDate(entry)),
5274
+ href: routeByEntry.get(entry.id) ?? null,
5227
5275
  id: slugify(label),
5228
5276
  label,
5277
+ major: majorVersion(entry.data.changelog?.version),
5229
5278
  tags: entry.data.changelog?.category
5230
5279
  ? [entry.data.changelog.category]
5231
5280
  : [],
@@ -5233,6 +5282,19 @@ const items = await Promise.all(
5233
5282
  })
5234
5283
  );
5235
5284
 
5285
+ // A changelog is semver-paginated only when every visible release parses as
5286
+ // semver and they span more than one major line. Older majors then collapse
5287
+ // into groups the reader reveals one at a time; otherwise the timeline is flat.
5288
+ const majors = items.every((item) => item.major !== null)
5289
+ ? [...new Set(items.map((item) => item.major))].toSorted((a, b) => b - a)
5290
+ : [];
5291
+ const paginate = majors.length > 1;
5292
+ const majorGroups = majors.map((major) => ({
5293
+ items: items.filter((item) => item.major === major),
5294
+ label: major + ".x",
5295
+ major,
5296
+ }));
5297
+
5236
5298
  const headings = items.map((item) => ({
5237
5299
  depth: 2,
5238
5300
  slug: item.id,
@@ -5264,6 +5326,7 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
5264
5326
  }}
5265
5327
  headings={headings}
5266
5328
  toc={data.config.toc}
5329
+ contentLayout="bare"
5267
5330
  themeMode={data.config.theme.mode}
5268
5331
  fontCssVars={data.fontCssVars}
5269
5332
  searchEnabled={data.config.search.enabled}
@@ -5282,16 +5345,50 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
5282
5345
  {
5283
5346
  items.length === 0 ? (
5284
5347
  <p>No changelog entries yet.</p>
5348
+ ) : paginate ? (
5349
+ <blume-changelog class="not-prose mt-8 block">
5350
+ {majorGroups[0].items.map(({ Content, href, id, label, date, tags }) => (
5351
+ <Update description={date} href={href} id={id} label={label} tags={tags}>
5352
+ <Content />
5353
+ </Update>
5354
+ ))}
5355
+ {majorGroups.slice(1).map((group) => (
5356
+ <section
5357
+ aria-label={group.label + " releases"}
5358
+ data-changelog-label={group.label}
5359
+ data-changelog-major={group.major}
5360
+ >
5361
+ {group.items.map(({ Content, href, id, label, date, tags }) => (
5362
+ <Update description={date} href={href} id={id} label={label} tags={tags}>
5363
+ <Content />
5364
+ </Update>
5365
+ ))}
5366
+ </section>
5367
+ ))}
5368
+ <div class="mt-10 flex justify-center">
5369
+ <button
5370
+ class="inline-flex items-center gap-2 rounded-full border border-border bg-background px-4 py-2 font-medium text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground"
5371
+ data-changelog-more
5372
+ hidden
5373
+ type="button"
5374
+ >
5375
+ Show older releases
5376
+ </button>
5377
+ </div>
5378
+ </blume-changelog>
5285
5379
  ) : (
5286
5380
  <div class="not-prose mt-8">
5287
- {items.map(({ Content, id, label, date, tags }) => (
5288
- <Update description={date} id={id} label={label} tags={tags}>
5381
+ {items.map(({ Content, href, id, label, date, tags }) => (
5382
+ <Update description={date} href={href} id={id} label={label} tags={tags}>
5289
5383
  <Content />
5290
5384
  </Update>
5291
5385
  ))}
5292
5386
  </div>
5293
5387
  )
5294
5388
  }
5389
+ <script>
5390
+ import "blume/components/content/changelog-element.ts";
5391
+ </script>
5295
5392
  </LayoutComponent>
5296
5393
  `;
5297
5394
  };
@@ -5525,7 +5622,7 @@ var specConfiguration = async (spec, root) => {
5525
5622
  if (URL_SPEC.test(spec)) {
5526
5623
  return { config: { url: spec } };
5527
5624
  }
5528
- const absolute = isAbsolute5(spec) ? spec : join11(root, spec);
5625
+ const absolute = isAbsolute5(spec) ? spec : join12(root, spec);
5529
5626
  try {
5530
5627
  return { config: { content: await readFile5(absolute, "utf-8") } };
5531
5628
  } catch {
@@ -5583,8 +5680,8 @@ var buildReferenceFiles = async (options) => {
5583
5680
  };
5584
5681
 
5585
5682
  // src/core/sources/cache.ts
5586
- import { mkdir as mkdir2, readFile as readFile6, writeFile as writeFile3 } from "node:fs/promises";
5587
- import { join as join12 } from "pathe";
5683
+ import { mkdir as mkdir3, readFile as readFile6, writeFile as writeFile3 } from "node:fs/promises";
5684
+ import { join as join13 } from "pathe";
5588
5685
  var hashText = (text) => {
5589
5686
  let hash = 5381;
5590
5687
  for (let i = 0;i < text.length; i += 1) {
@@ -5611,7 +5708,7 @@ var pollingWatch = (load2, intervalSeconds) => (onChange) => {
5611
5708
  return () => clearInterval(timer);
5612
5709
  };
5613
5710
  var snapshotCache = (cacheDir) => {
5614
- const file = join12(cacheDir, "entries.json");
5711
+ const file = join13(cacheDir, "entries.json");
5615
5712
  return {
5616
5713
  read: async () => {
5617
5714
  try {
@@ -5622,7 +5719,7 @@ var snapshotCache = (cacheDir) => {
5622
5719
  },
5623
5720
  write: async (entries) => {
5624
5721
  try {
5625
- await mkdir2(cacheDir, { recursive: true });
5722
+ await mkdir3(cacheDir, { recursive: true });
5626
5723
  await writeFile3(file, `${JSON.stringify(entries)}
5627
5724
  `, "utf-8");
5628
5725
  } catch {}
@@ -5726,10 +5823,10 @@ var extractOperations = (document, baseRoute) => {
5726
5823
  };
5727
5824
 
5728
5825
  // src/openapi/parse.ts
5729
- import { mkdir as mkdir3, readFile as readFile7, writeFile as writeFile4 } from "node:fs/promises";
5826
+ import { mkdir as mkdir4, readFile as readFile7, writeFile as writeFile4 } from "node:fs/promises";
5730
5827
  import { setTimeout as sleep } from "node:timers/promises";
5731
5828
  import { normalize as normalize2, upgrade } from "@scalar/openapi-parser";
5732
- import { isAbsolute as isAbsolute6, join as join13 } from "pathe";
5829
+ import { isAbsolute as isAbsolute6, join as join14 } from "pathe";
5733
5830
  var URL_SPEC2 = /^https?:\/\//u;
5734
5831
  var FETCH_TIMEOUT_MS = 15000;
5735
5832
  var MAX_ATTEMPTS = 3;
@@ -5804,7 +5901,7 @@ var fetchSpecText = async (spec) => {
5804
5901
  }
5805
5902
  throw last.error;
5806
5903
  };
5807
- var cacheFileFor = (cacheDir, spec) => join13(cacheDir, `spec-${hashText(spec)}.cache`);
5904
+ var cacheFileFor = (cacheDir, spec) => join14(cacheDir, `spec-${hashText(spec)}.cache`);
5808
5905
  var readCache = async (file) => {
5809
5906
  try {
5810
5907
  return await readFile7(file, "utf-8");
@@ -5814,13 +5911,13 @@ var readCache = async (file) => {
5814
5911
  };
5815
5912
  var writeCache = async (dir, file, text) => {
5816
5913
  try {
5817
- await mkdir3(dir, { recursive: true });
5914
+ await mkdir4(dir, { recursive: true });
5818
5915
  await writeFile4(file, text, "utf-8");
5819
5916
  } catch {}
5820
5917
  };
5821
5918
  var readSpecText = async (spec, root, options) => {
5822
5919
  if (!URL_SPEC2.test(spec)) {
5823
- const absolute = isAbsolute6(spec) ? spec : join13(root, spec);
5920
+ const absolute = isAbsolute6(spec) ? spec : join14(root, spec);
5824
5921
  return { text: await readFile7(absolute, "utf-8"), warnings: [] };
5825
5922
  }
5826
5923
  const cacheFile = options.cacheDir ? cacheFileFor(options.cacheDir, spec) : undefined;
@@ -6422,6 +6519,10 @@ blume-diff {
6422
6519
  font-size: 0.8125rem;
6423
6520
  }
6424
6521
 
6522
+ .prose :where(td, th) :not(pre) > code {
6523
+ white-space: nowrap;
6524
+ }
6525
+
6425
6526
  blume-tabs pre,
6426
6527
  .not-prose > div > pre {
6427
6528
  background: var(--blume-code-background);
@@ -6597,9 +6698,9 @@ pre:has(.line.focused):hover .line:not(.focused) {
6597
6698
  content: none;
6598
6699
  }
6599
6700
 
6600
- /* Inline code highlighting (markdown.code.inline): Shiki colors the tokens of a
6601
- \`code\`{:lang} snippet via the same dual-theme CSS variables as fenced blocks,
6602
- keeping the inline pill background. */
6701
+ /* Inline code highlighting: Shiki colors the tokens of a \`code\`{:lang} snippet
6702
+ via the same dual-theme CSS variables as fenced blocks, keeping the inline
6703
+ pill background. Always on — it only fires on the trailing {:lang} marker. */
6603
6704
  .prose code.blume-inline-code span {
6604
6705
  color: var(--shiki-light);
6605
6706
  }
@@ -6823,12 +6924,12 @@ export const layoutOverrides = { ...(overrides.layout ?? {})${layoutEntries.leng
6823
6924
 
6824
6925
  // src/astro/examples.ts
6825
6926
  import { readFile as readFile9 } from "node:fs/promises";
6826
- import { join as join15, relative as relative5 } from "pathe";
6927
+ import { join as join16, relative as relative5 } from "pathe";
6827
6928
  import { glob as glob2 } from "tinyglobby";
6828
6929
 
6829
6930
  // src/astro/islands.ts
6830
6931
  import { readFile as readFile8 } from "node:fs/promises";
6831
- import { basename, join as join14 } from "pathe";
6932
+ import { basename, join as join15 } from "pathe";
6832
6933
  import { glob } from "tinyglobby";
6833
6934
  var DEFAULT_CLIENT = "visible";
6834
6935
  var VALID_MODES = new Set([
@@ -6857,7 +6958,7 @@ var readClientMode = (source, file, warnings) => {
6857
6958
  return mode;
6858
6959
  };
6859
6960
  var discoverIslands = async (root) => {
6860
- const dir = join14(root, "islands");
6961
+ const dir = join15(root, "islands");
6861
6962
  const matches = await glob(["**/*.{jsx,svelte,tsx,vue}"], {
6862
6963
  absolute: true,
6863
6964
  cwd: dir,
@@ -6920,7 +7021,7 @@ var splitGlobBase = (pattern) => {
6920
7021
  };
6921
7022
  var discoverExamples = async (root, pattern = "examples") => {
6922
7023
  const { base, rest } = GLOB_MAGIC.test(pattern) ? splitGlobBase(pattern) : { base: pattern, rest: DEFAULT_EXAMPLE_GLOB };
6923
- const dir = join15(root, base);
7024
+ const dir = join16(root, base);
6924
7025
  const matches = await glob2([rest], {
6925
7026
  absolute: true,
6926
7027
  cwd: dir,
@@ -7001,10 +7102,10 @@ var customOgRoutes = (pages, siteTitle) => {
7001
7102
  };
7002
7103
 
7003
7104
  // src/astro/generate.ts
7004
- var BLUME_SRC = join16(packageRoot(), "src");
7105
+ var BLUME_SRC = join17(packageRoot(), "src");
7005
7106
  var canResolveFrom = (fromDir, spec) => {
7006
7107
  try {
7007
- createRequire5(pathToFileURL2(join16(fromDir, "_.js")).href).resolve(spec);
7108
+ createRequire5(pathToFileURL2(join17(fromDir, "_.js")).href).resolve(spec);
7008
7109
  return true;
7009
7110
  } catch {
7010
7111
  return false;
@@ -7012,15 +7113,15 @@ var canResolveFrom = (fromDir, spec) => {
7012
7113
  };
7013
7114
  var resolvedAstroPath = (fromDir) => {
7014
7115
  try {
7015
- const pkg = createRequire5(pathToFileURL2(join16(fromDir, "_.js")).href).resolve("astro/package.json");
7116
+ const pkg = createRequire5(pathToFileURL2(join17(fromDir, "_.js")).href).resolve("astro/package.json");
7016
7117
  return realpathSync(pkg);
7017
7118
  } catch {
7018
7119
  return null;
7019
7120
  }
7020
7121
  };
7021
7122
  var blumeDepsDir = (pkgDir = packageRoot()) => {
7022
- const candidates = [join16(pkgDir, "node_modules"), dirname7(pkgDir)];
7023
- return candidates.find((dir) => existsSync9(join16(dir, "astro"))) ?? null;
7123
+ const candidates = [join17(pkgDir, "node_modules"), dirname8(pkgDir)];
7124
+ return candidates.find((dir) => existsSync10(join17(dir, "astro"))) ?? null;
7024
7125
  };
7025
7126
  var linkDepsJunction = async (link, depsDir) => {
7026
7127
  const existing = await lstat(link).catch(() => null);
@@ -7028,9 +7129,9 @@ var linkDepsJunction = async (link, depsDir) => {
7028
7129
  if (!existing.isSymbolicLink()) {
7029
7130
  return;
7030
7131
  }
7031
- await rm(link, { force: true });
7132
+ await rm2(link, { force: true });
7032
7133
  }
7033
- await mkdir4(dirname7(link), { recursive: true });
7134
+ await mkdir5(dirname8(link), { recursive: true });
7034
7135
  await symlink(depsDir, link, "junction");
7035
7136
  };
7036
7137
  var readPkgVersion = (pkgJsonPath) => {
@@ -7060,8 +7161,8 @@ var ensureDepsLink = async (outDir, pkgDir = packageRoot()) => {
7060
7161
  if (blumeAstro && outDirAstro === blumeAstro) {
7061
7162
  return null;
7062
7163
  }
7063
- if (existsSync9(join16(depsDir, "@astrojs", "mdx"))) {
7064
- await linkDepsJunction(join16(outDir, "node_modules"), depsDir);
7164
+ if (existsSync10(join17(depsDir, "@astrojs", "mdx"))) {
7165
+ await linkDepsJunction(join17(outDir, "node_modules"), depsDir);
7065
7166
  return null;
7066
7167
  }
7067
7168
  return astroConflictWarning(blumeAstro, outDirAstro);
@@ -7098,6 +7199,15 @@ var detectNeedsReact = async (root) => {
7098
7199
  });
7099
7200
  return matches.length > 0;
7100
7201
  };
7202
+ var detectUsesMath = async (root) => {
7203
+ const files = await glob4(["**/*.mdx"], {
7204
+ cwd: root,
7205
+ ignore: ["**/node_modules/**", "**/.blume/**", "**/dist/**"],
7206
+ onlyFiles: true
7207
+ });
7208
+ const contents = await Promise.all(files.map((file) => readOptional(join17(root, file))));
7209
+ return contents.some((content) => content.includes("$$"));
7210
+ };
7101
7211
  var writeIfChanged = async (path, content) => {
7102
7212
  let existing = null;
7103
7213
  try {
@@ -7108,13 +7218,13 @@ var writeIfChanged = async (path, content) => {
7108
7218
  if (existing === content) {
7109
7219
  return false;
7110
7220
  }
7111
- await mkdir4(dirname7(path), { recursive: true });
7221
+ await mkdir5(dirname8(path), { recursive: true });
7112
7222
  const tmp = `${path}.${process.pid}.tmp`;
7113
7223
  await writeFile5(tmp, content, "utf-8");
7114
7224
  try {
7115
7225
  await rename(tmp, path);
7116
7226
  } catch (error) {
7117
- await rm(tmp, { force: true });
7227
+ await rm2(tmp, { force: true });
7118
7228
  throw error;
7119
7229
  }
7120
7230
  return true;
@@ -7125,7 +7235,7 @@ var pruneOrphans = async (srcDir, written) => {
7125
7235
  cwd: srcDir,
7126
7236
  onlyFiles: true
7127
7237
  });
7128
- await Promise.all(existing.map((path) => normalize3(path)).filter((path) => !written.has(path)).map((path) => rm(path, { force: true })));
7238
+ await Promise.all(existing.map((path) => normalize3(path)).filter((path) => !written.has(path)).map((path) => rm2(path, { force: true })));
7129
7239
  };
7130
7240
  var collectStaged = (project) => {
7131
7241
  const staged = new Map;
@@ -7140,11 +7250,11 @@ var writeStagedContent = async (out, staged) => {
7140
7250
  const contentDir = stagedContentDir(out);
7141
7251
  const written = new Set;
7142
7252
  await Promise.all([...staged].map(async ([entryId, text]) => {
7143
- const path = join16(contentDir, entryId);
7253
+ const path = join17(contentDir, entryId);
7144
7254
  written.add(normalize3(path));
7145
7255
  await writeIfChanged(path, text);
7146
7256
  }));
7147
- if (existsSync9(contentDir)) {
7257
+ if (existsSync10(contentDir)) {
7148
7258
  await pruneOrphans(contentDir, written);
7149
7259
  }
7150
7260
  };
@@ -7163,9 +7273,9 @@ var resolveLogo = (project) => {
7163
7273
  if (light && light === dark && light.toLowerCase().endsWith(".svg")) {
7164
7274
  const rel = light.replace(/^\//u, "");
7165
7275
  const file = [
7166
- join16(project.context.root, "public", rel),
7167
- join16(project.context.root, rel)
7168
- ].find((path) => existsSync9(path));
7276
+ join17(project.context.root, "public", rel),
7277
+ join17(project.context.root, rel)
7278
+ ].find((path) => existsSync10(path));
7169
7279
  if (file) {
7170
7280
  return { alt, href: brandHref, svg: readFileSync6(file, "utf-8"), text };
7171
7281
  }
@@ -7193,7 +7303,7 @@ var faviconType = (name) => {
7193
7303
  };
7194
7304
  var inlineDataUri = (file, type) => `data:${type};base64,${readFileSync6(file).toString("base64")}`;
7195
7305
  var defaultFavicon = () => ({
7196
- href: inlineDataUri(join16(BLUME_SRC, "assets", "icon.png"), "image/png"),
7306
+ href: inlineDataUri(join17(BLUME_SRC, "assets", "icon.png"), "image/png"),
7197
7307
  type: "image/png"
7198
7308
  });
7199
7309
  var APPLE_ICON_CANDIDATES = [
@@ -7205,13 +7315,13 @@ var APPLE_ICON_CANDIDATES = [
7205
7315
  var resolveIconFile = (project, candidates) => {
7206
7316
  const { root } = project.context;
7207
7317
  for (const name of candidates) {
7208
- if (existsSync9(join16(root, "public", name))) {
7318
+ if (existsSync10(join17(root, "public", name))) {
7209
7319
  return { href: `/${name}`, type: faviconType(name) };
7210
7320
  }
7211
7321
  }
7212
7322
  for (const name of candidates) {
7213
- const file = join16(root, name);
7214
- if (existsSync9(file)) {
7323
+ const file = join17(root, name);
7324
+ if (existsSync10(file)) {
7215
7325
  const type = faviconType(name);
7216
7326
  return { href: inlineDataUri(file, type ?? "image/x-icon"), type };
7217
7327
  }
@@ -7339,7 +7449,7 @@ var buildRuntimeData = (project) => {
7339
7449
  var planMcp = (project, srcDir) => {
7340
7450
  const { config } = project;
7341
7451
  const { route } = config.mcp;
7342
- const dir = join16(srcDir, "blume-mcp");
7452
+ const dir = join17(srcDir, "blume-mcp");
7343
7453
  const base = {
7344
7454
  dir,
7345
7455
  discoveryPages: [],
@@ -7363,11 +7473,11 @@ var planMcp = (project, srcDir) => {
7363
7473
  ...base,
7364
7474
  discoveryPages: [
7365
7475
  {
7366
- entrypoint: join16(dir, "discovery.ts"),
7476
+ entrypoint: join17(dir, "discovery.ts"),
7367
7477
  pattern: "/.well-known/mcp.json"
7368
7478
  },
7369
7479
  {
7370
- entrypoint: join16(dir, "server-card.ts"),
7480
+ entrypoint: join17(dir, "server-card.ts"),
7371
7481
  pattern: "/.well-known/mcp/server-card.json"
7372
7482
  }
7373
7483
  ],
@@ -7386,11 +7496,11 @@ var writeMcpFiles = async (project, plan, write) => {
7386
7496
  version: data.version
7387
7497
  };
7388
7498
  await Promise.all([
7389
- write(join16(plan.srcDir, "generated", "mcp-data.json"), `${JSON.stringify(data)}
7499
+ write(join17(plan.srcDir, "generated", "mcp-data.json"), `${JSON.stringify(data)}
7390
7500
  `),
7391
- write(join16(plan.srcDir, "pages", mcpPageFile(plan.route)), mcpEndpointTemplate(plan.route)),
7392
- write(join16(plan.dir, "discovery.ts"), staticJsonEndpointTemplate(buildMcpDiscovery(discoveryInput))),
7393
- write(join16(plan.dir, "server-card.ts"), staticJsonEndpointTemplate(buildMcpServerCard(discoveryInput)))
7501
+ write(join17(plan.srcDir, "pages", mcpPageFile(plan.route)), mcpEndpointTemplate(plan.route)),
7502
+ write(join17(plan.dir, "discovery.ts"), staticJsonEndpointTemplate(buildMcpDiscovery(discoveryInput))),
7503
+ write(join17(plan.dir, "server-card.ts"), staticJsonEndpointTemplate(buildMcpServerCard(discoveryInput)))
7394
7504
  ]);
7395
7505
  };
7396
7506
  var writeAskFiles = async (project, srcDir, write) => {
@@ -7400,16 +7510,16 @@ var writeAskFiles = async (project, srcDir, write) => {
7400
7510
  }
7401
7511
  const grounded = ask.provider !== "inkeep";
7402
7512
  if (grounded) {
7403
- await write(join16(srcDir, "generated", "ask-data.json"), `${JSON.stringify(await buildAskData(project))}
7513
+ await write(join17(srcDir, "generated", "ask-data.json"), `${JSON.stringify(await buildAskData(project))}
7404
7514
  `);
7405
7515
  }
7406
- await write(join16(srcDir, "pages", "api", "ask.ts"), askEndpointTemplate(resolveAskBackend(ask), grounded));
7516
+ await write(join17(srcDir, "pages", "api", "ask.ts"), askEndpointTemplate(resolveAskBackend(ask), grounded));
7407
7517
  };
7408
7518
  var writeNotFoundPage = async (write, srcDir, pages, contentPages) => {
7409
7519
  if (routeIsTaken(pages, contentPages, "/404")) {
7410
7520
  return;
7411
7521
  }
7412
- await write(join16(srcDir, "pages", "404.astro"), notFoundPageTemplate());
7522
+ await write(join17(srcDir, "pages", "404.astro"), notFoundPageTemplate());
7413
7523
  };
7414
7524
  var shouldGenerateChangelog = (project) => {
7415
7525
  const hasChangelog = project.graph.pages.some((page) => page.contentType === "changelog" && !(page.meta.draft || page.meta.sidebar.hidden));
@@ -7428,12 +7538,12 @@ var buildComponentSlots = async (componentsFile) => {
7428
7538
  var generateRuntime = async (project) => {
7429
7539
  const { context, config } = project;
7430
7540
  const out = context.outDir;
7431
- const srcDir = join16(out, "src");
7432
- const dataPath = join16(srcDir, "generated", "data.json");
7433
- const themePath = join16(srcDir, "generated", "app.css");
7434
- const searchClientPath = join16(srcDir, "generated", "search-client.ts");
7435
- const examplesPath = join16(srcDir, "generated", "examples.ts");
7436
- const openapiPath = join16(srcDir, "generated", "openapi.json");
7541
+ const srcDir = join17(out, "src");
7542
+ const dataPath = join17(srcDir, "generated", "data.json");
7543
+ const themePath = join17(srcDir, "generated", "app.css");
7544
+ const searchClientPath = join17(srcDir, "generated", "search-client.ts");
7545
+ const examplesPath = join17(srcDir, "generated", "examples.ts");
7546
+ const openapiPath = join17(srcDir, "generated", "openapi.json");
7437
7547
  const written = new Set;
7438
7548
  const write = (path, content) => {
7439
7549
  written.add(normalize3(path));
@@ -7443,9 +7553,17 @@ var generateRuntime = async (project) => {
7443
7553
  const askEnabled = config.ai.ask?.enabled ?? false;
7444
7554
  const exportPdf = config.export.pdf;
7445
7555
  const exportEpub = config.export.epub;
7446
- const [pages, detectedReact, userTheme, islandDiscovery, exampleDiscovery] = await Promise.all([
7556
+ const [
7557
+ pages,
7558
+ detectedReact,
7559
+ usesMath,
7560
+ userTheme,
7561
+ islandDiscovery,
7562
+ exampleDiscovery
7563
+ ] = await Promise.all([
7447
7564
  context.pagesRoot ? discoverPages(context.pagesRoot) : Promise.resolve([]),
7448
7565
  detectNeedsReact(context.root),
7566
+ detectUsesMath(context.root),
7449
7567
  readOptional(context.themeFile),
7450
7568
  discoverIslands(context.root),
7451
7569
  discoverExamples(context.root, config.examples)
@@ -7470,7 +7588,7 @@ var generateRuntime = async (project) => {
7470
7588
  const hasStaged = staged.size > 0;
7471
7589
  const hasFilesystemSource = project.sources.some((source) => !source.staged);
7472
7590
  const structural = await Promise.all([
7473
- write(join16(out, "astro.config.mjs"), astroConfigTemplate({
7591
+ write(join17(out, "astro.config.mjs"), astroConfigTemplate({
7474
7592
  aliases: resolveTsconfigAliases(context.root),
7475
7593
  config,
7476
7594
  contentRoutes: project.manifest.routes.map((route) => route.path),
@@ -7485,25 +7603,25 @@ var generateRuntime = async (project) => {
7485
7603
  searchClientPath,
7486
7604
  themePath
7487
7605
  })),
7488
- write(join16(out, "package.json"), runtimePackageTemplate(runtimeDependencies({ config, needsReact, needsSvelte, needsVue }))),
7489
- write(join16(out, "tsconfig.json"), runtimeTsconfigTemplate()),
7490
- write(join16(srcDir, "env.d.ts"), envTemplate()),
7491
- write(join16(srcDir, "content.config.ts"), contentConfigTemplate({
7606
+ write(join17(out, "package.json"), runtimePackageTemplate(runtimeDependencies({ config, needsReact, needsSvelte, needsVue }))),
7607
+ write(join17(out, "tsconfig.json"), runtimeTsconfigTemplate()),
7608
+ write(join17(srcDir, "env.d.ts"), envTemplate()),
7609
+ write(join17(srcDir, "content.config.ts"), contentConfigTemplate({
7492
7610
  config,
7493
7611
  context,
7494
7612
  filesystem: hasFilesystemSource,
7495
7613
  staged: hasStaged
7496
7614
  })),
7497
- write(join16(srcDir, "pages", "[...slug].astro"), catchAllPageTemplate({
7615
+ write(join17(srcDir, "pages", "[...slug].astro"), catchAllPageTemplate({
7498
7616
  askEnabled,
7499
7617
  exportEpub,
7500
7618
  exportPdf,
7501
- mathEnabled: config.markdown.math,
7619
+ mathEnabled: usesMath,
7502
7620
  needsReact
7503
7621
  })),
7504
- write(join16(srcDir, "generated", "components.ts"), slotPlan.module),
7505
- write(join16(srcDir, "generated", "islands.ts"), islandMapTemplate(islandDiscovery.islands)),
7506
- write(join16(srcDir, "generated", "examples.ts"), exampleMapTemplate(exampleDiscovery.examples)),
7622
+ write(join17(srcDir, "generated", "components.ts"), slotPlan.module),
7623
+ write(join17(srcDir, "generated", "islands.ts"), islandMapTemplate(islandDiscovery.islands)),
7624
+ write(join17(srcDir, "generated", "examples.ts"), exampleMapTemplate(exampleDiscovery.examples)),
7507
7625
  write(themePath, tailwindEntryTemplate({
7508
7626
  configTokens: `${buildThemeCss(config.theme)}${buildFontsCss(config.theme.fonts)}`,
7509
7627
  sources: [
@@ -7514,16 +7632,16 @@ var generateRuntime = async (project) => {
7514
7632
  userTheme
7515
7633
  }))
7516
7634
  ]);
7517
- await Promise.all(islandDiscovery.islands.map((island) => write(join16(srcDir, "generated", "islands", `${island.name}.astro`), islandWrapperTemplate(island))));
7518
- await Promise.all(slotPlan.wrappers.map((wrapper) => write(join16(srcDir, "generated", "component-slots", `${wrapper.name}.astro`), wrapper.content)));
7519
- await Promise.all(exampleDiscovery.examples.map((example) => write(join16(srcDir, "generated", "examples", `${exampleSlug(example.path)}.astro`), exampleWrapperTemplate(example))));
7635
+ await Promise.all(islandDiscovery.islands.map((island) => write(join17(srcDir, "generated", "islands", `${island.name}.astro`), islandWrapperTemplate(island))));
7636
+ await Promise.all(slotPlan.wrappers.map((wrapper) => write(join17(srcDir, "generated", "component-slots", `${wrapper.name}.astro`), wrapper.content)));
7637
+ await Promise.all(exampleDiscovery.examples.map((example) => write(join17(srcDir, "generated", "examples", `${exampleSlug(example.path)}.astro`), exampleWrapperTemplate(example))));
7520
7638
  await writeAskFiles(project, srcDir, write);
7521
7639
  await writeMcpFiles(project, mcp, write);
7522
7640
  if (config.seo.og.enabled) {
7523
- await write(join16(srcDir, "pages", "og", "[...slug].png.ts"), ogEndpointTemplate(ogRoutes));
7641
+ await write(join17(srcDir, "pages", "og", "[...slug].png.ts"), ogEndpointTemplate(ogRoutes));
7524
7642
  }
7525
7643
  if (shouldGenerateChangelog(project)) {
7526
- await write(join16(srcDir, "pages", "changelog.astro"), changelogIndexTemplate({
7644
+ await write(join17(srcDir, "pages", "changelog.astro"), changelogIndexTemplate({
7527
7645
  askEnabled,
7528
7646
  exportEpub,
7529
7647
  exportPdf,
@@ -7535,27 +7653,27 @@ var generateRuntime = async (project) => {
7535
7653
  await write(searchClientPath, searchClientTemplate(config));
7536
7654
  if (servesStaticIndex(config.search.provider)) {
7537
7655
  const documents = await buildSearchDocuments(project);
7538
- await write(join16(srcDir, "generated", "search.json"), `${JSON.stringify(documents)}
7656
+ await write(join17(srcDir, "generated", "search.json"), `${JSON.stringify(documents)}
7539
7657
  `);
7540
- await write(join16(srcDir, "pages", "blume-search.json.ts"), searchEndpointTemplate());
7658
+ await write(join17(srcDir, "pages", "blume-search.json.ts"), searchEndpointTemplate());
7541
7659
  }
7542
7660
  if (config.search.provider === "mixedbread") {
7543
- await write(join16(srcDir, "pages", "api", "search.ts"), mixedbreadSearchEndpointTemplate(config.search.mixedbread?.storeId ?? ""));
7661
+ await write(join17(srcDir, "pages", "api", "search.ts"), mixedbreadSearchEndpointTemplate(config.search.mixedbread?.storeId ?? ""));
7544
7662
  }
7545
7663
  const rawMarkdown = await buildRawMarkdown(project);
7546
7664
  await Promise.all([
7547
- write(join16(srcDir, "generated", "raw-markdown.json"), `${JSON.stringify(rawMarkdown)}
7665
+ write(join17(srcDir, "generated", "raw-markdown.json"), `${JSON.stringify(rawMarkdown)}
7548
7666
  `),
7549
- write(join16(srcDir, "pages", "[...slug].md.ts"), rawMarkdownEndpointTemplate()),
7550
- write(join16(srcDir, "pages", "[...slug].mdx.ts"), rawMarkdownEndpointTemplate())
7667
+ write(join17(srcDir, "pages", "[...slug].md.ts"), rawMarkdownEndpointTemplate()),
7668
+ write(join17(srcDir, "pages", "[...slug].mdx.ts"), rawMarkdownEndpointTemplate())
7551
7669
  ]);
7552
7670
  const feeds = buildRssFeeds(project);
7553
7671
  if (feeds.length > 0) {
7554
7672
  const feedXml = Object.fromEntries(feeds.map((feed) => [feed.type, renderRssFeed(feed)]));
7555
7673
  await Promise.all([
7556
- write(join16(srcDir, "generated", "rss.json"), `${JSON.stringify(feedXml)}
7674
+ write(join17(srcDir, "generated", "rss.json"), `${JSON.stringify(feedXml)}
7557
7675
  `),
7558
- write(join16(srcDir, "pages", "[section]", "rss.xml.ts"), rssEndpointTemplate())
7676
+ write(join17(srcDir, "pages", "[section]", "rss.xml.ts"), rssEndpointTemplate())
7559
7677
  ]);
7560
7678
  }
7561
7679
  const warnings = [
@@ -7592,13 +7710,13 @@ var generateRuntime = async (project) => {
7592
7710
  root: context.root
7593
7711
  });
7594
7712
  warnings.push(...references.warnings);
7595
- await Promise.all(references.files.map((file) => write(join16(srcDir, "pages", file.pagePath), file.content)));
7713
+ await Promise.all(references.files.map((file) => write(join17(srcDir, "pages", file.pagePath), file.content)));
7596
7714
  }
7597
- await write(join16(srcDir, "generated", "data.json"), buildRuntimeData(project));
7715
+ await write(join17(srcDir, "generated", "data.json"), buildRuntimeData(project));
7598
7716
  const openApiSource2 = project.sources.find(isOpenApiSource);
7599
7717
  await write(openapiPath, `${JSON.stringify(openApiSource2 ? openApiSource2.openApiData() : {})}
7600
7718
  `);
7601
- await write(join16(out, "blume.manifest.json"), `${JSON.stringify(project.manifest, null, 2)}
7719
+ await write(join17(out, "blume.manifest.json"), `${JSON.stringify(project.manifest, null, 2)}
7602
7720
  `);
7603
7721
  await writeStagedContent(out, staged);
7604
7722
  await pruneOrphans(srcDir, written);
@@ -7606,7 +7724,7 @@ var generateRuntime = async (project) => {
7606
7724
  };
7607
7725
 
7608
7726
  // src/core/config.ts
7609
- import { existsSync as existsSync10, readFileSync as readFileSync7 } from "node:fs";
7727
+ import { existsSync as existsSync11, readFileSync as readFileSync7 } from "node:fs";
7610
7728
 
7611
7729
  // src/core/deployment-env.ts
7612
7730
  var toUrl = (value) => {
@@ -8113,15 +8231,13 @@ var lastModifiedConfigSchema = z2.union([
8113
8231
  ]);
8114
8232
  var codeConfigSchema = z2.object({
8115
8233
  icons: z2.boolean().default(true),
8116
- inline: z2.boolean().default(false),
8117
8234
  wrap: z2.boolean().default(false)
8118
8235
  }).strict();
8119
8236
  var markdownConfigSchema = z2.object({
8120
8237
  code: codeConfigSchema.default({}),
8121
8238
  codeBlocks: codeBlocksConfigSchema.default({}),
8122
8239
  headingAnchors: z2.boolean().default(true),
8123
- imageZoom: z2.boolean().default(true),
8124
- math: z2.boolean().default(false)
8240
+ imageZoom: z2.boolean().default(true)
8125
8241
  }).strict();
8126
8242
  var openapiSourceSchema = z2.object({
8127
8243
  label: z2.string().optional(),
@@ -8207,7 +8323,7 @@ var loadConfig = async (root, options = {}) => {
8207
8323
  }
8208
8324
  const parsed = blumeConfigSchema.safeParse(raw ?? {});
8209
8325
  if (!parsed.success) {
8210
- const source = configFile && existsSync10(configFile) ? readFileSync7(configFile, "utf-8") : undefined;
8326
+ const source = configFile && existsSync11(configFile) ? readFileSync7(configFile, "utf-8") : undefined;
8211
8327
  const diagnostics = diagnosticsFromZod(parsed.error, {
8212
8328
  code: "BLUME_CONFIG_INVALID",
8213
8329
  file: configFile ?? undefined,
@@ -8641,7 +8757,7 @@ var gitLastModifiedTimes = (root, contentRoot, sourcePaths) => {
8641
8757
  };
8642
8758
 
8643
8759
  // src/core/meta.ts
8644
- import { basename as basename3, dirname as dirname8, relative as relative9 } from "pathe";
8760
+ import { basename as basename3, dirname as dirname9, relative as relative9 } from "pathe";
8645
8761
  import { glob as glob5 } from "tinyglobby";
8646
8762
  var META_FILES = [
8647
8763
  "**/meta.ts",
@@ -8671,7 +8787,7 @@ var discoverFolderMeta = async (contentRoot) => {
8671
8787
  const shared = new Map;
8672
8788
  const diagnostics = [];
8673
8789
  for (const entry of loaded) {
8674
- const dir = relative9(contentRoot, dirname8(entry.file));
8790
+ const dir = relative9(contentRoot, dirname9(entry.file));
8675
8791
  if (!entry.ok) {
8676
8792
  diagnostics.push({
8677
8793
  code: "BLUME_META_LOAD_FAILED",
@@ -8696,7 +8812,7 @@ var discoverFolderMeta = async (contentRoot) => {
8696
8812
  };
8697
8813
 
8698
8814
  // src/core/sources/normalize.ts
8699
- import { existsSync as existsSync11, readFileSync as readFileSync8 } from "node:fs";
8815
+ import { existsSync as existsSync12, readFileSync as readFileSync8 } from "node:fs";
8700
8816
  import GithubSlugger from "github-slugger";
8701
8817
  import { extname as extname4 } from "pathe";
8702
8818
  var NUMERIC_PREFIX2 = /^\d+[-_.]/u;
@@ -8830,7 +8946,7 @@ var normalizeEntry2 = (entry, ctx) => {
8830
8946
  const ext = format === "mdx" ? ".mdx" : ".md";
8831
8947
  const result = pageMetaSchema.safeParse(entry.data);
8832
8948
  if (!result.success) {
8833
- const source = entry.raw ?? (entry.sourcePath && existsSync11(entry.sourcePath) ? readFileSync8(entry.sourcePath, "utf-8") : undefined);
8949
+ const source = entry.raw ?? (entry.sourcePath && existsSync12(entry.sourcePath) ? readFileSync8(entry.sourcePath, "utf-8") : undefined);
8834
8950
  return {
8835
8951
  diagnostics: diagnosticsFromZod(result.error, {
8836
8952
  code: "BLUME_FRONTMATTER_INVALID",
@@ -8881,15 +8997,15 @@ var normalizeEntry2 = (entry, ctx) => {
8881
8997
  };
8882
8998
 
8883
8999
  // src/core/sources/resolve.ts
8884
- import { join as join21 } from "pathe";
9000
+ import { join as join22 } from "pathe";
8885
9001
 
8886
9002
  // src/core/sources/filesystem.ts
8887
- import { existsSync as existsSync12, watch as fsWatch } from "node:fs";
9003
+ import { existsSync as existsSync13, watch as fsWatch } from "node:fs";
8888
9004
  import { readFile as readFile11 } from "node:fs/promises";
8889
- import { extname as extname5, isAbsolute as isAbsolute7, join as join17, relative as relative10, resolve as resolve5 } from "pathe";
9005
+ import { extname as extname5, isAbsolute as isAbsolute7, join as join18, relative as relative10, resolve as resolve5 } from "pathe";
8890
9006
  import { glob as glob6 } from "tinyglobby";
8891
9007
  var filesystemSource = (options) => {
8892
- const contentRoot = isAbsolute7(options.root) ? options.root : join17(resolve5(options.projectRoot), options.root);
9008
+ const contentRoot = isAbsolute7(options.root) ? options.root : join18(resolve5(options.projectRoot), options.root);
8893
9009
  const load2 = async () => {
8894
9010
  const files = await glob6(options.include, {
8895
9011
  absolute: true,
@@ -8913,7 +9029,7 @@ var filesystemSource = (options) => {
8913
9029
  return { diagnostics: [], entries };
8914
9030
  };
8915
9031
  const validate = () => {
8916
- if (!existsSync12(contentRoot)) {
9032
+ if (!existsSync13(contentRoot)) {
8917
9033
  throw new BlumeError({
8918
9034
  code: options.missingCode ?? "BLUME_CONTENT_ROOT_MISSING",
8919
9035
  file: contentRoot,
@@ -8928,7 +9044,7 @@ var filesystemSource = (options) => {
8928
9044
  ...excludeDirSegments(options.exclude)
8929
9045
  ]);
8930
9046
  const watch = (onChange) => {
8931
- if (!existsSync12(contentRoot)) {
9047
+ if (!existsSync13(contentRoot)) {
8932
9048
  return () => {};
8933
9049
  }
8934
9050
  const watcher = fsWatch(contentRoot, { recursive: true }, ignoringWatchListener(onChange, watchIgnoreDirs));
@@ -8939,7 +9055,7 @@ var filesystemSource = (options) => {
8939
9055
  load: load2,
8940
9056
  name: options.name,
8941
9057
  prefix: options.prefix,
8942
- read: (ref) => readFile11(join17(contentRoot, ref), "utf-8"),
9058
+ read: (ref) => readFile11(join18(contentRoot, ref), "utf-8"),
8943
9059
  staged: false,
8944
9060
  validate,
8945
9061
  watch
@@ -9229,11 +9345,11 @@ var mdxRemoteSource = (options, ctx) => {
9229
9345
 
9230
9346
  // src/core/sources/notion.ts
9231
9347
  import { setTimeout as sleep2 } from "node:timers/promises";
9232
- import { join as join19 } from "pathe";
9348
+ import { join as join20 } from "pathe";
9233
9349
 
9234
9350
  // src/core/sources/assets.ts
9235
- import { mkdir as mkdir5, writeFile as writeFile6 } from "node:fs/promises";
9236
- import { extname as extname6, join as join18 } from "pathe";
9351
+ import { mkdir as mkdir6, writeFile as writeFile6 } from "node:fs/promises";
9352
+ import { extname as extname6, join as join19 } from "pathe";
9237
9353
  var MD_IMAGE = /!\[(?<alt>[^\]]*)\]\((?<url>[^)\s]+)\)/gu;
9238
9354
  var REMOTE = /^https?:\/\//u;
9239
9355
  var SAFE_EXT = /^\.[a-z0-9]+$/iu;
@@ -9261,8 +9377,8 @@ var materializeAssets = async (markdown, ctx) => {
9261
9377
  }
9262
9378
  const bytes = new Uint8Array(await res.arrayBuffer());
9263
9379
  const file = `${hashText(url)}${extFor(url)}`;
9264
- await mkdir5(ctx.assetsDir, { recursive: true });
9265
- await writeFile6(join18(ctx.assetsDir, file), bytes);
9380
+ await mkdir6(ctx.assetsDir, { recursive: true });
9381
+ await writeFile6(join19(ctx.assetsDir, file), bytes);
9266
9382
  rewrites.set(url, `${ctx.assetsBaseUrl}/${file}`);
9267
9383
  } catch (error) {
9268
9384
  diagnostics.push({
@@ -9378,8 +9494,8 @@ ${text}
9378
9494
  };
9379
9495
  var notionSource = (options, ctx) => {
9380
9496
  const props = options.properties ?? {};
9381
- const cache = snapshotCache(ctx?.cacheDir ?? join19(".blume", "cache", options.name));
9382
- const assetsDir = ctx?.assetsDir ?? join19(".blume", "public", "blume-assets", options.name);
9497
+ const cache = snapshotCache(ctx?.cacheDir ?? join20(".blume", "cache", options.name));
9498
+ const assetsDir = ctx?.assetsDir ?? join20(".blume", "public", "blume-assets", options.name);
9383
9499
  const assetsBaseUrl = ctx?.assetsBaseUrl ?? `/blume-assets/${options.name}`;
9384
9500
  let snapshot = new Map;
9385
9501
  const resolveClient = async () => {
@@ -9547,7 +9663,7 @@ ${rendered.join(`
9547
9663
  };
9548
9664
 
9549
9665
  // src/core/sources/sanity.ts
9550
- import { join as join20 } from "pathe";
9666
+ import { join as join21 } from "pathe";
9551
9667
 
9552
9668
  // src/core/sources/portable-text.ts
9553
9669
  var HEADING_STYLES = {
@@ -9686,7 +9802,7 @@ var resolveClient = async (options, preview) => {
9686
9802
  };
9687
9803
  var sanitySource = (options, ctx) => {
9688
9804
  const fields = options.fields ?? {};
9689
- const cache = snapshotCache(ctx?.cacheDir ?? join20(".blume", "cache", options.name));
9805
+ const cache = snapshotCache(ctx?.cacheDir ?? join21(".blume", "cache", options.name));
9690
9806
  let snapshot = new Map;
9691
9807
  const toEntry2 = (doc) => {
9692
9808
  const slugValue = asString(getPath(doc, fields.slug ?? "slug.current")) ?? asString(doc._id) ?? "untitled";
@@ -9761,8 +9877,8 @@ var uniqueNamer = () => {
9761
9877
  };
9762
9878
  var sourceContext = (context, name, runtime) => ({
9763
9879
  assetsBaseUrl: `/blume-assets/${name}`,
9764
- assetsDir: join21(context.outDir, "public", "blume-assets", name),
9765
- cacheDir: join21(context.outDir, "cache", name),
9880
+ assetsDir: join22(context.outDir, "public", "blume-assets", name),
9881
+ cacheDir: join22(context.outDir, "cache", name),
9766
9882
  mode: runtime.mode,
9767
9883
  preview: runtime.preview,
9768
9884
  projectRoot: context.root,
@@ -9952,8 +10068,8 @@ var scanProject = async (root, options = {}) => {
9952
10068
  };
9953
10069
 
9954
10070
  // src/cli/env.ts
9955
- import { existsSync as existsSync13, readFileSync as readFileSync9 } from "node:fs";
9956
- import { dirname as dirname9, join as join22, resolve as resolve6 } from "pathe";
10071
+ import { existsSync as existsSync14, readFileSync as readFileSync9 } from "node:fs";
10072
+ import { dirname as dirname10, join as join23, resolve as resolve6 } from "pathe";
9957
10073
  var ENV_LINE = /^\s*(?:export\s+)?(?<key>[A-Za-z_][A-Za-z0-9_]*)\s*=\s*(?<value>.*?)\s*$/u;
9958
10074
  var DOUBLE_QUOTED2 = /^"(?<body>[\s\S]*)"$/u;
9959
10075
  var SINGLE_QUOTED = /^'(?<body>[\s\S]*)'$/u;
@@ -9991,7 +10107,7 @@ var applyEnv = (parsed) => {
9991
10107
  };
9992
10108
  var loadFile = (path) => {
9993
10109
  try {
9994
- if (existsSync13(path)) {
10110
+ if (existsSync14(path)) {
9995
10111
  applyEnv(parseEnv(readFileSync9(path, "utf-8")));
9996
10112
  }
9997
10113
  } catch {}
@@ -10000,10 +10116,10 @@ var loadEnvFiles = (startDir) => {
10000
10116
  let dir = resolve6(startDir);
10001
10117
  let done = false;
10002
10118
  while (!done) {
10003
- loadFile(join22(dir, ".env.local"));
10004
- loadFile(join22(dir, ".env"));
10005
- const parent = dirname9(dir);
10006
- done = existsSync13(join22(dir, ".git")) || parent === dir;
10119
+ loadFile(join23(dir, ".env.local"));
10120
+ loadFile(join23(dir, ".env"));
10121
+ const parent = dirname10(dir);
10122
+ done = existsSync14(join23(dir, ".git")) || parent === dir;
10007
10123
  dir = parent;
10008
10124
  }
10009
10125
  };
@@ -10133,24 +10249,24 @@ var emitRedirectFiles = async (config, distDir) => {
10133
10249
  if (redirects.length === 0 || config.deployment.output !== "static") {
10134
10250
  return;
10135
10251
  }
10136
- await writeFile7(join23(distDir, "blume-redirects.json"), buildRedirectManifest(redirects), "utf-8");
10252
+ await writeFile7(join24(distDir, "blume-redirects.json"), buildRedirectManifest(redirects), "utf-8");
10137
10253
  const platformFiles = [
10138
10254
  { content: buildNetlifyRedirects(redirects), name: "_redirects" },
10139
10255
  { content: buildVercelConfig(redirects), name: "vercel.json" }
10140
10256
  ];
10141
- await Promise.all(platformFiles.map((file) => existsSync14(join23(distDir, file.name)) ? Promise.resolve() : writeFile7(join23(distDir, file.name), file.content, "utf-8")));
10257
+ await Promise.all(platformFiles.map((file) => existsSync15(join24(distDir, file.name)) ? Promise.resolve() : writeFile7(join24(distDir, file.name), file.content, "utf-8")));
10142
10258
  logger.success(`Emitted redirect files for ${redirects.length} redirect(s)`);
10143
10259
  };
10144
10260
  var formatBytes = (bytes) => bytes < 1024 ? `${bytes} B` : `${(bytes / 1024).toFixed(bytes < 1024 * 100 ? 1 : 0)} kB`;
10145
10261
  var astroAssets = async (distDir, ext) => {
10146
- const astroDir = join23(distDir, "_astro");
10147
- if (!existsSync14(astroDir)) {
10262
+ const astroDir = join24(distDir, "_astro");
10263
+ if (!existsSync15(astroDir)) {
10148
10264
  return [];
10149
10265
  }
10150
10266
  const entries = await readdir(astroDir);
10151
10267
  const files = entries.filter((name) => name.endsWith(`.${ext}`));
10152
10268
  const sized = await Promise.all(files.map(async (name) => {
10153
- const info = await stat(join23(astroDir, name));
10269
+ const info = await stat(join24(astroDir, name));
10154
10270
  return { name, size: info.size };
10155
10271
  }));
10156
10272
  return sized.toSorted((a, b) => b.size - a.size);
@@ -10206,24 +10322,24 @@ var publishBuildArtifacts = async (project, distDir, args) => {
10206
10322
  if (project.config.ai.llmsTxt) {
10207
10323
  const { index, full } = await buildLlmsFiles(project);
10208
10324
  await Promise.all([
10209
- writeFile7(join23(distDir, "llms.txt"), index, "utf-8"),
10210
- writeFile7(join23(distDir, "llms-full.txt"), full, "utf-8")
10325
+ writeFile7(join24(distDir, "llms.txt"), index, "utf-8"),
10326
+ writeFile7(join24(distDir, "llms-full.txt"), full, "utf-8")
10211
10327
  ]);
10212
10328
  logger.success("Generated llms.txt and llms-full.txt");
10213
10329
  }
10214
10330
  const sitemap = buildSitemap(project);
10215
- if (sitemap && !existsSync14(join23(distDir, "sitemap.xml"))) {
10216
- await writeFile7(join23(distDir, "sitemap.xml"), sitemap, "utf-8");
10331
+ if (sitemap && !existsSync15(join24(distDir, "sitemap.xml"))) {
10332
+ await writeFile7(join24(distDir, "sitemap.xml"), sitemap, "utf-8");
10217
10333
  logger.success("Generated sitemap.xml");
10218
10334
  }
10219
10335
  const robots = buildRobots(project);
10220
- if (robots && !existsSync14(join23(distDir, "robots.txt"))) {
10221
- await writeFile7(join23(distDir, "robots.txt"), robots, "utf-8");
10336
+ if (robots && !existsSync15(join24(distDir, "robots.txt"))) {
10337
+ await writeFile7(join24(distDir, "robots.txt"), robots, "utf-8");
10222
10338
  logger.success("Generated robots.txt");
10223
10339
  }
10224
10340
  const agentReadability = buildAgentReadability(project);
10225
- if (agentReadability && !existsSync14(join23(distDir, "agent-readability.json"))) {
10226
- await writeFile7(join23(distDir, "agent-readability.json"), `${JSON.stringify(agentReadability, null, 2)}
10341
+ if (agentReadability && !existsSync15(join24(distDir, "agent-readability.json"))) {
10342
+ await writeFile7(join24(distDir, "agent-readability.json"), `${JSON.stringify(agentReadability, null, 2)}
10227
10343
  `, "utf-8");
10228
10344
  logger.success("Generated agent-readability.json");
10229
10345
  }
@@ -10324,21 +10440,26 @@ var buildCommand = defineCommand2({
10324
10440
  logLevel: "info",
10325
10441
  root: project.context.outDir
10326
10442
  });
10327
- const distDir = project.context.distDir ?? join23(root, "dist");
10443
+ const distDir = project.context.distDir ?? join24(root, "dist");
10328
10444
  if (runtimeDir) {
10329
10445
  logger.success(`Isolated build OK — output at ${distDir} (not published).`);
10330
10446
  return;
10331
10447
  }
10332
- await publishBuildArtifacts(project, distDir, args);
10448
+ const surfaced = await surfaceAdapterOutput(project.config, project.context);
10449
+ if (surfaced.moved) {
10450
+ logger.success(`Surfaced ${project.config.deployment.adapter} output to ${surfaced.to}`);
10451
+ await ensureGitignore(root, [surfaced.ignore]);
10452
+ }
10453
+ await publishBuildArtifacts(project, deployStaticDir(project.config, project.context), args);
10333
10454
  }
10334
10455
  });
10335
10456
 
10336
10457
  // src/cli/commands/check.ts
10337
- import { existsSync as existsSync15 } from "node:fs";
10458
+ import { existsSync as existsSync16 } from "node:fs";
10338
10459
  import { check } from "@astrojs/check";
10339
10460
  import { sync } from "astro";
10340
10461
  import { defineCommand as defineCommand3 } from "citty";
10341
- import { join as join24 } from "pathe";
10462
+ import { join as join25 } from "pathe";
10342
10463
  var checkCommand = defineCommand3({
10343
10464
  args: {
10344
10465
  isolated: {
@@ -10374,13 +10495,13 @@ var checkCommand = defineCommand3({
10374
10495
  });
10375
10496
  const { outDir } = project.context;
10376
10497
  await sync({ logLevel: "warn", root: outDir });
10377
- const tsconfig = join24(root, "tsconfig.json");
10498
+ const tsconfig = join25(root, "tsconfig.json");
10378
10499
  logger.start(`Type-checking ${project.graph.pages.length} page(s)`);
10379
10500
  const failed = await check({
10380
10501
  minimumFailingSeverity: "error",
10381
10502
  minimumSeverity: "hint",
10382
10503
  root: outDir,
10383
- tsconfig: existsSync15(tsconfig) ? tsconfig : undefined,
10504
+ tsconfig: existsSync16(tsconfig) ? tsconfig : undefined,
10384
10505
  watch: false
10385
10506
  });
10386
10507
  if (failed) {
@@ -10652,12 +10773,12 @@ var doctorCommand = defineCommand5({
10652
10773
  // src/cli/commands/eject.ts
10653
10774
  import { readFile as readFile13, writeFile as writeFile9 } from "node:fs/promises";
10654
10775
  import { defineCommand as defineCommand6 } from "citty";
10655
- import { join as join26, relative as relative12 } from "pathe";
10776
+ import { join as join27, relative as relative12 } from "pathe";
10656
10777
 
10657
10778
  // src/registry/eject.ts
10658
- import { existsSync as existsSync16 } from "node:fs";
10659
- import { cp, mkdir as mkdir6, readFile as readFile12, rm as rm2, writeFile as writeFile8 } from "node:fs/promises";
10660
- import { join as join25, relative as relative11 } from "pathe";
10779
+ import { existsSync as existsSync17 } from "node:fs";
10780
+ import { cp as cp2, mkdir as mkdir7, readFile as readFile12, rm as rm3, writeFile as writeFile8 } from "node:fs/promises";
10781
+ import { join as join26, relative as relative11 } from "pathe";
10661
10782
  var POSIX = (path) => path.split("\\").join("/");
10662
10783
  var ejectOpenApiData = (project) => {
10663
10784
  const source = project.sources.find(isOpenApiSource);
@@ -10672,14 +10793,14 @@ var askFiles = async (project, srcDir, genDir) => {
10672
10793
  const files = [
10673
10794
  {
10674
10795
  content: askEndpointTemplate(resolveAskBackend(ask), grounded),
10675
- path: join25(srcDir, "pages", "api", "ask.ts")
10796
+ path: join26(srcDir, "pages", "api", "ask.ts")
10676
10797
  }
10677
10798
  ];
10678
10799
  if (grounded) {
10679
10800
  files.push({
10680
10801
  content: `${JSON.stringify(await buildAskData(project))}
10681
10802
  `,
10682
- path: join25(genDir, "ask-data.json")
10803
+ path: join26(genDir, "ask-data.json")
10683
10804
  });
10684
10805
  }
10685
10806
  return files;
@@ -10687,14 +10808,23 @@ var askFiles = async (project, srcDir, genDir) => {
10687
10808
  var eject = async (root) => {
10688
10809
  const project = await scanProject(root, { mode: "build" });
10689
10810
  const { context, config } = project;
10690
- const srcDir = join25(root, "src");
10691
- const genDir = join25(srcDir, "generated");
10811
+ const srcDir = join26(root, "src");
10812
+ const genDir = join26(srcDir, "generated");
10692
10813
  const askEnabled = config.ai.ask?.enabled ?? false;
10693
10814
  const exportPdf = config.export.pdf;
10694
10815
  const exportEpub = config.export.epub;
10695
- const [pages, needsReactRaw, userTheme, rawMarkdown, islands, examples] = await Promise.all([
10816
+ const [
10817
+ pages,
10818
+ needsReactRaw,
10819
+ usesMath,
10820
+ userTheme,
10821
+ rawMarkdown,
10822
+ islands,
10823
+ examples
10824
+ ] = await Promise.all([
10696
10825
  context.pagesRoot ? discoverPages(context.pagesRoot) : Promise.resolve([]),
10697
10826
  detectNeedsReact(root),
10827
+ detectUsesMath(root),
10698
10828
  context.themeFile ? readFile12(context.themeFile, "utf-8") : Promise.resolve(""),
10699
10829
  buildRawMarkdown(project),
10700
10830
  discoverIslands(root),
@@ -10737,14 +10867,14 @@ var eject = async (root) => {
10737
10867
  searchClientPath: "./src/generated/search-client.ts",
10738
10868
  themePath: "./src/generated/app.css"
10739
10869
  }),
10740
- path: join25(root, "astro.config.mjs")
10870
+ path: join26(root, "astro.config.mjs")
10741
10871
  },
10742
10872
  {
10743
10873
  content: runtimeTsconfigTemplate(),
10744
- path: join25(root, "tsconfig.json"),
10874
+ path: join26(root, "tsconfig.json"),
10745
10875
  skipIfExists: true
10746
10876
  },
10747
- { content: envTemplate(), path: join25(srcDir, "env.d.ts") },
10877
+ { content: envTemplate(), path: join26(srcDir, "env.d.ts") },
10748
10878
  {
10749
10879
  content: contentConfigTemplate({
10750
10880
  config,
@@ -10752,29 +10882,29 @@ var eject = async (root) => {
10752
10882
  staged: hasStaged,
10753
10883
  stagedBase: stagedDir
10754
10884
  }),
10755
- path: join25(srcDir, "content.config.ts")
10885
+ path: join26(srcDir, "content.config.ts")
10756
10886
  },
10757
10887
  {
10758
10888
  content: catchAllPageTemplate({
10759
10889
  askEnabled,
10760
10890
  exportEpub,
10761
10891
  exportPdf,
10762
- mathEnabled: config.markdown.math,
10892
+ mathEnabled: usesMath,
10763
10893
  needsReact
10764
10894
  }),
10765
- path: join25(srcDir, "pages", "[...slug].astro")
10895
+ path: join26(srcDir, "pages", "[...slug].astro")
10766
10896
  },
10767
10897
  {
10768
10898
  content: planComponentSlots(componentsImport, null).module,
10769
- path: join25(genDir, "components.ts")
10899
+ path: join26(genDir, "components.ts")
10770
10900
  },
10771
10901
  {
10772
10902
  content: islandMapTemplate(islands.islands),
10773
- path: join25(genDir, "islands.ts")
10903
+ path: join26(genDir, "islands.ts")
10774
10904
  },
10775
10905
  {
10776
10906
  content: exampleMapTemplate(examples.examples),
10777
- path: join25(genDir, "examples.ts")
10907
+ path: join26(genDir, "examples.ts")
10778
10908
  },
10779
10909
  {
10780
10910
  content: tailwindEntryTemplate({
@@ -10786,26 +10916,26 @@ var eject = async (root) => {
10786
10916
  twoslashCss: twoslashCss(),
10787
10917
  userTheme
10788
10918
  }),
10789
- path: join25(genDir, "app.css")
10919
+ path: join26(genDir, "app.css")
10790
10920
  },
10791
- { content: buildRuntimeData(project), path: join25(genDir, "data.json") },
10921
+ { content: buildRuntimeData(project), path: join26(genDir, "data.json") },
10792
10922
  {
10793
10923
  content: `${JSON.stringify(ejectOpenApiData(project))}
10794
10924
  `,
10795
- path: join25(genDir, "openapi.json")
10925
+ path: join26(genDir, "openapi.json")
10796
10926
  },
10797
10927
  {
10798
10928
  content: `${JSON.stringify(rawMarkdown)}
10799
10929
  `,
10800
- path: join25(genDir, "raw-markdown.json")
10930
+ path: join26(genDir, "raw-markdown.json")
10801
10931
  },
10802
10932
  {
10803
10933
  content: rawMarkdownEndpointTemplate(),
10804
- path: join25(srcDir, "pages", "[...slug].md.ts")
10934
+ path: join26(srcDir, "pages", "[...slug].md.ts")
10805
10935
  },
10806
10936
  {
10807
10937
  content: rawMarkdownEndpointTemplate(),
10808
- path: join25(srcDir, "pages", "[...slug].mdx.ts")
10938
+ path: join26(srcDir, "pages", "[...slug].mdx.ts")
10809
10939
  }
10810
10940
  ];
10811
10941
  if (askEnabled) {
@@ -10814,34 +10944,34 @@ var eject = async (root) => {
10814
10944
  if (config.seo.og.enabled) {
10815
10945
  files.push({
10816
10946
  content: ogEndpointTemplate(customOgRoutes(pages, config.title)),
10817
- path: join25(srcDir, "pages", "og", "[...slug].png.ts")
10947
+ path: join26(srcDir, "pages", "og", "[...slug].png.ts")
10818
10948
  });
10819
10949
  }
10820
10950
  if (!routeIsTaken(pages, project.graph.pages, "/404")) {
10821
10951
  files.push({
10822
10952
  content: notFoundPageTemplate(),
10823
- path: join25(srcDir, "pages", "404.astro")
10953
+ path: join26(srcDir, "pages", "404.astro")
10824
10954
  });
10825
10955
  }
10826
10956
  files.push({
10827
10957
  content: searchClientTemplate(config),
10828
- path: join25(genDir, "search-client.ts")
10958
+ path: join26(genDir, "search-client.ts")
10829
10959
  });
10830
10960
  if (servesStaticIndex(config.search.provider)) {
10831
10961
  const documents = await buildSearchDocuments(project);
10832
10962
  files.push({
10833
10963
  content: `${JSON.stringify(documents)}
10834
10964
  `,
10835
- path: join25(genDir, "search.json")
10965
+ path: join26(genDir, "search.json")
10836
10966
  }, {
10837
10967
  content: searchEndpointTemplate(),
10838
- path: join25(srcDir, "pages", "blume-search.json.ts")
10968
+ path: join26(srcDir, "pages", "blume-search.json.ts")
10839
10969
  });
10840
10970
  }
10841
10971
  if (config.search.provider === "mixedbread") {
10842
10972
  files.push({
10843
10973
  content: mixedbreadSearchEndpointTemplate(config.search.mixedbread?.storeId ?? ""),
10844
- path: join25(srcDir, "pages", "api", "search.ts")
10974
+ path: join26(srcDir, "pages", "api", "search.ts")
10845
10975
  });
10846
10976
  }
10847
10977
  const feeds = buildRssFeeds(project);
@@ -10850,10 +10980,10 @@ var eject = async (root) => {
10850
10980
  files.push({
10851
10981
  content: `${JSON.stringify(feedXml)}
10852
10982
  `,
10853
- path: join25(genDir, "rss.json")
10983
+ path: join26(genDir, "rss.json")
10854
10984
  }, {
10855
10985
  content: rssEndpointTemplate(),
10856
- path: join25(srcDir, "pages", "[section]", "rss.xml.ts")
10986
+ path: join26(srcDir, "pages", "[section]", "rss.xml.ts")
10857
10987
  });
10858
10988
  }
10859
10989
  if (hasScalarReferences(config)) {
@@ -10865,38 +10995,38 @@ var eject = async (root) => {
10865
10995
  for (const file of references.files) {
10866
10996
  files.push({
10867
10997
  content: file.content,
10868
- path: join25(srcDir, "pages", file.pagePath)
10998
+ path: join26(srcDir, "pages", file.pagePath)
10869
10999
  });
10870
11000
  }
10871
11001
  }
10872
11002
  files.push(...islands.islands.map((island) => ({
10873
11003
  content: islandWrapperTemplate(island),
10874
- path: join25(genDir, "islands", `${island.name}.astro`)
11004
+ path: join26(genDir, "islands", `${island.name}.astro`)
10875
11005
  })), ...examples.examples.map((example) => ({
10876
11006
  content: exampleWrapperTemplate(example),
10877
- path: join25(genDir, "examples", `${exampleSlug(example.path)}.astro`)
11007
+ path: join26(genDir, "examples", `${exampleSlug(example.path)}.astro`)
10878
11008
  })));
10879
11009
  for (const [entryId, content] of staged) {
10880
- files.push({ content, path: join25(root, stagedDir, entryId) });
11010
+ files.push({ content, path: join26(root, stagedDir, entryId) });
10881
11011
  }
10882
- const written = files.filter((file) => !(file.skipIfExists && existsSync16(file.path)));
11012
+ const written = files.filter((file) => !(file.skipIfExists && existsSync17(file.path)));
10883
11013
  await Promise.all(written.map(async (file) => {
10884
- await mkdir6(join25(file.path, ".."), { recursive: true });
11014
+ await mkdir7(join26(file.path, ".."), { recursive: true });
10885
11015
  await writeFile8(file.path, file.content, "utf-8");
10886
11016
  }));
10887
- const assetsSrc = join25(context.outDir, "public", "blume-assets");
10888
- if (existsSync16(assetsSrc)) {
10889
- await cp(assetsSrc, join25(root, "public", "blume-assets"), {
11017
+ const assetsSrc = join26(context.outDir, "public", "blume-assets");
11018
+ if (existsSync17(assetsSrc)) {
11019
+ await cp2(assetsSrc, join26(root, "public", "blume-assets"), {
10890
11020
  recursive: true
10891
11021
  });
10892
11022
  }
10893
- await rm2(context.outDir, { force: true, recursive: true });
11023
+ await rm3(context.outDir, { force: true, recursive: true });
10894
11024
  return written.map((file) => file.path);
10895
11025
  };
10896
11026
 
10897
11027
  // src/cli/commands/eject.ts
10898
11028
  var updatePackageScripts = async (root) => {
10899
- const pkgPath = join26(root, "package.json");
11029
+ const pkgPath = join27(root, "package.json");
10900
11030
  let pkg;
10901
11031
  try {
10902
11032
  pkg = JSON.parse(await readFile13(pkgPath, "utf-8"));
@@ -10946,10 +11076,10 @@ The blume package remains importable.`);
10946
11076
  });
10947
11077
 
10948
11078
  // src/cli/commands/init.ts
10949
- import { existsSync as existsSync17 } from "node:fs";
10950
- import { mkdir as mkdir7, writeFile as writeFile10 } from "node:fs/promises";
11079
+ import { existsSync as existsSync18 } from "node:fs";
11080
+ import { mkdir as mkdir8, writeFile as writeFile10 } from "node:fs/promises";
10951
11081
  import { defineCommand as defineCommand7 } from "citty";
10952
- import { basename as basename4, dirname as dirname10, isAbsolute as isAbsolute8, join as join27, relative as relative13 } from "pathe";
11082
+ import { basename as basename4, dirname as dirname11, isAbsolute as isAbsolute8, join as join28, relative as relative13 } from "pathe";
10953
11083
 
10954
11084
  // src/core/package-json.ts
10955
11085
  var toPackageName = (raw) => raw.toLowerCase().replaceAll(/[^a-z0-9._-]+/gu, "-").replaceAll(/^[-_.]+|[-_.]+$/gu, "") || "docs";
@@ -11001,7 +11131,7 @@ var STARTERS = {
11001
11131
  files: (dir) => [
11002
11132
  {
11003
11133
  content: page("API Reference", "Explore the API.", "# API Reference\n\nYour OpenAPI spec renders at [`/api`](/api). Point `openapi.sources` at your own spec in `blume.config.ts`."),
11004
- path: join27(dir, "index.mdx")
11134
+ path: join28(dir, "index.mdx")
11005
11135
  }
11006
11136
  ]
11007
11137
  },
@@ -11016,7 +11146,7 @@ var STARTERS = {
11016
11146
  files: (dir) => [
11017
11147
  {
11018
11148
  content: page("Introduction", "Welcome to your new Blume docs.", "# Introduction\n\nWrite your docs here, and log releases under `changelog/`."),
11019
- path: join27(dir, "index.mdx")
11149
+ path: join28(dir, "index.mdx")
11020
11150
  },
11021
11151
  {
11022
11152
  content: `---
@@ -11027,7 +11157,7 @@ date: 2026-01-01
11027
11157
 
11028
11158
  The first release. Edit \`${dir}/changelog/v1-0-0.mdx\` or add new entries beside it.
11029
11159
  `,
11030
- path: join27(dir, "changelog", "v1-0-0.mdx")
11160
+ path: join28(dir, "changelog", "v1-0-0.mdx")
11031
11161
  }
11032
11162
  ]
11033
11163
  },
@@ -11040,7 +11170,7 @@ The first release. Edit \`${dir}/changelog/v1-0-0.mdx\` or add new entries besid
11040
11170
  Welcome to **Blume** — markdown-first docs powered by Astro and Vite.
11041
11171
 
11042
11172
  Edit \`${dir}/index.mdx\` to get started, then run \`blume dev\`.`),
11043
- path: join27(dir, "index.mdx")
11173
+ path: join28(dir, "index.mdx")
11044
11174
  }
11045
11175
  ]
11046
11176
  },
@@ -11051,11 +11181,11 @@ Edit \`${dir}/index.mdx\` to get started, then run \`blume dev\`.`),
11051
11181
  content: page("Introduction", "Get started with the SDK.", `# Introduction
11052
11182
 
11053
11183
  Install the SDK and make your first call. See [Installation](/installation).`),
11054
- path: join27(dir, "index.mdx")
11184
+ path: join28(dir, "index.mdx")
11055
11185
  },
11056
11186
  {
11057
11187
  content: page("Installation", "Install the SDK.", "# Installation\n\n```package-install\nyour-sdk\n```"),
11058
- path: join27(dir, "installation.mdx")
11188
+ path: join28(dir, "installation.mdx")
11059
11189
  }
11060
11190
  ]
11061
11191
  }
@@ -11065,11 +11195,11 @@ var commandsFor = (pm) => ({
11065
11195
  install: `${pm} install`
11066
11196
  });
11067
11197
  var writeFileSafe = async (path, content) => {
11068
- if (existsSync17(path)) {
11198
+ if (existsSync18(path)) {
11069
11199
  logger.info(`Skipped existing ${path}`);
11070
11200
  return false;
11071
11201
  }
11072
- await mkdir7(dirname10(path), { recursive: true });
11202
+ await mkdir8(dirname11(path), { recursive: true });
11073
11203
  await writeFile10(path, content, "utf-8");
11074
11204
  logger.success(`Created ${path}`);
11075
11205
  return true;
@@ -11102,7 +11232,7 @@ var initCommand = defineCommand7({
11102
11232
  async run({ args }) {
11103
11233
  const root = process.cwd();
11104
11234
  const contentDir = args["content-dir"] ?? "docs";
11105
- if (isAbsolute8(contentDir) || relative13(root, join27(root, contentDir)).startsWith("..")) {
11235
+ if (isAbsolute8(contentDir) || relative13(root, join28(root, contentDir)).startsWith("..")) {
11106
11236
  logger.error(`Invalid --content-dir "${contentDir}" (must be a path inside the project).`);
11107
11237
  process.exit(1);
11108
11238
  }
@@ -11117,9 +11247,9 @@ var initCommand = defineCommand7({
11117
11247
  process.exit(1);
11118
11248
  }
11119
11249
  const starter = STARTERS[template];
11120
- const createdPackage = await writeFileSafe(join27(root, "package.json"), blumePackageJson(toPackageName(basename4(root))));
11121
- await writeFileSafe(join27(root, "blume.config.ts"), starter.config);
11122
- await Promise.all(starter.files(contentDir).map((file) => writeFileSafe(join27(root, file.path), file.content)));
11250
+ const createdPackage = await writeFileSafe(join28(root, "package.json"), blumePackageJson(toPackageName(basename4(root))));
11251
+ await writeFileSafe(join28(root, "blume.config.ts"), starter.config);
11252
+ await Promise.all(starter.files(contentDir).map((file) => writeFileSafe(join28(root, file.path), file.content)));
11123
11253
  const ignored = await ensureGitignore(root, [".blume/", "dist/"]);
11124
11254
  if (ignored.length > 0) {
11125
11255
  logger.success(`Added ${ignored.join(", ")} to .gitignore`);
@@ -11157,10 +11287,10 @@ var initCommand = defineCommand7({
11157
11287
  });
11158
11288
 
11159
11289
  // src/cli/commands/preview.ts
11160
- import { existsSync as existsSync18 } from "node:fs";
11290
+ import { existsSync as existsSync19 } from "node:fs";
11161
11291
  import { preview } from "astro";
11162
11292
  import { defineCommand as defineCommand8 } from "citty";
11163
- import { join as join28 } from "pathe";
11293
+ import { join as join29 } from "pathe";
11164
11294
  var previewCommand = defineCommand8({
11165
11295
  args: {
11166
11296
  host: { description: "Network host to bind.", type: "string" },
@@ -11174,7 +11304,7 @@ var previewCommand = defineCommand8({
11174
11304
  const root = process.cwd();
11175
11305
  const { config } = await loadConfig(root);
11176
11306
  const context = resolveProjectContext(root, config);
11177
- if (!existsSync18(join28(context.outDir, "astro.config.mjs"))) {
11307
+ if (!existsSync19(join29(context.outDir, "astro.config.mjs"))) {
11178
11308
  logger.error("No build found. Run `blume build` first.");
11179
11309
  process.exit(1);
11180
11310
  }
@@ -11190,9 +11320,9 @@ var previewCommand = defineCommand8({
11190
11320
  });
11191
11321
 
11192
11322
  // src/cli/commands/sync.ts
11193
- import { rm as rm3 } from "node:fs/promises";
11323
+ import { rm as rm4 } from "node:fs/promises";
11194
11324
  import { defineCommand as defineCommand9 } from "citty";
11195
- import { join as join29 } from "pathe";
11325
+ import { join as join30 } from "pathe";
11196
11326
  var syncCommand = defineCommand9({
11197
11327
  args: {
11198
11328
  force: {
@@ -11214,7 +11344,7 @@ var syncCommand = defineCommand9({
11214
11344
  if (args.force) {
11215
11345
  const { config } = await loadConfig(root);
11216
11346
  const context = resolveProjectContext(root, config);
11217
- await rm3(join29(context.outDir, "cache"), { force: true, recursive: true });
11347
+ await rm4(join30(context.outDir, "cache"), { force: true, recursive: true });
11218
11348
  logger.info("Cleared source cache.");
11219
11349
  }
11220
11350
  await prepareProject({
@@ -11229,13 +11359,13 @@ var syncCommand = defineCommand9({
11229
11359
  });
11230
11360
 
11231
11361
  // src/cli/commands/validate.ts
11232
- import { existsSync as existsSync20 } from "node:fs";
11362
+ import { existsSync as existsSync21 } from "node:fs";
11233
11363
  import { defineCommand as defineCommand10 } from "citty";
11234
- import { join as join31 } from "pathe";
11364
+ import { join as join32 } from "pathe";
11235
11365
 
11236
11366
  // src/core/links.ts
11237
- import { existsSync as existsSync19 } from "node:fs";
11238
- import { basename as basename5, join as join30 } from "pathe";
11367
+ import { existsSync as existsSync20 } from "node:fs";
11368
+ import { basename as basename5, join as join31 } from "pathe";
11239
11369
  var HTTP = /^https?:\/\//iu;
11240
11370
  var PROTOCOL_RELATIVE = /^\/\//u;
11241
11371
  var SCHEME = /^[a-z][a-z0-9+.-]*:/iu;
@@ -11247,7 +11377,7 @@ var STATUS_NOT_FOUND = 404;
11247
11377
  var STATUS_GONE = 410;
11248
11378
  var STATUS_METHOD_NOT_ALLOWED = 405;
11249
11379
  var STATUS_NOT_IMPLEMENTED = 501;
11250
- var assetIsPresent = (resolved, ctx) => ctx.publicDir !== null && existsSync19(join30(ctx.publicDir, resolved));
11380
+ var assetIsPresent = (resolved, ctx) => ctx.publicDir !== null && existsSync20(join31(ctx.publicDir, resolved));
11251
11381
  var isIndexPage = (page2) => {
11252
11382
  const ref = page2.source?.ref ?? page2.sourcePath ?? "";
11253
11383
  return /^index\.(?:md|mdx)$/iu.test(basename5(ref));
@@ -11490,10 +11620,10 @@ var validateCommand = defineCommand10({
11490
11620
  try {
11491
11621
  const project = await scanProject(root, { mode: "build" });
11492
11622
  diagnostics.push(...project.diagnostics);
11493
- const publicDir = join31(root, "public");
11623
+ const publicDir = join32(root, "public");
11494
11624
  diagnostics.push(...await validateLinks(project.graph, {
11495
11625
  checkExternal: Boolean(args.external),
11496
- publicDir: existsSync20(publicDir) ? publicDir : null,
11626
+ publicDir: existsSync21(publicDir) ? publicDir : null,
11497
11627
  redirects: project.config.redirects
11498
11628
  }));
11499
11629
  } catch (error) {
@@ -11553,5 +11683,5 @@ process.on("unhandledRejection", (error) => {
11553
11683
  });
11554
11684
  runMain(main);
11555
11685
 
11556
- //# debugId=0E9EF5D2749C00F464756E2164756E21
11686
+ //# debugId=0628D18D87A2023564756E2164756E21
11557
11687
  //# sourceMappingURL=index.js.map