@contentrain/mcp 3.1.7 → 3.2.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 (56) hide show
  1. package/dist/{apply-manager-DsNq7Zhm.mjs → apply-manager-eZ6zA99Y.mjs} +7 -9
  2. package/dist/apply-manager-eZ6zA99Y.mjs.map +1 -0
  3. package/dist/{content-manager-Bx94DXSF.d.mts → content-manager-9yUO24W2.d.mts} +9 -1
  4. package/dist/content-manager-9yUO24W2.d.mts.map +1 -0
  5. package/dist/{context-CxpTATh4.mjs → context-BHfO4WBv.mjs} +2 -2
  6. package/dist/{context-CxpTATh4.mjs.map → context-BHfO4WBv.mjs.map} +1 -1
  7. package/dist/core/apply-manager.mjs +5 -5
  8. package/dist/core/content-manager.d.mts +1 -1
  9. package/dist/core/content-manager.mjs +2 -2
  10. package/dist/core/context.mjs +3 -3
  11. package/dist/core/doctor.mjs +3 -3
  12. package/dist/core/meta-manager.d.mts +18 -2
  13. package/dist/core/meta-manager.d.mts.map +1 -1
  14. package/dist/core/meta-manager.mjs +1 -1
  15. package/dist/core/model-manager.d.mts +56 -5
  16. package/dist/core/model-manager.d.mts.map +1 -1
  17. package/dist/core/model-manager.mjs +3 -3
  18. package/dist/core/ops/index.d.mts +1 -1
  19. package/dist/core/ops/index.mjs +6 -6
  20. package/dist/core/validator/index.d.mts.map +1 -1
  21. package/dist/core/validator/index.mjs +3 -3
  22. package/dist/{doctor-B7G0oFxO.mjs → doctor-VnOzDTbk.mjs} +2 -2
  23. package/dist/{doctor-B7G0oFxO.mjs.map → doctor-VnOzDTbk.mjs.map} +1 -1
  24. package/dist/git/reconcile.mjs +7 -7
  25. package/dist/git/transaction.mjs +4 -4
  26. package/dist/index-_HJVkDJa.d.mts.map +1 -1
  27. package/dist/index.mjs +12 -12
  28. package/dist/{local-bnn6yrG7.mjs → local-DbPlR0Br.mjs} +4 -4
  29. package/dist/{local-bnn6yrG7.mjs.map → local-DbPlR0Br.mjs.map} +1 -1
  30. package/dist/{meta-manager-g3shoZES.mjs → meta-manager-Cd6AfuGS.mjs} +12 -4
  31. package/dist/meta-manager-Cd6AfuGS.mjs.map +1 -0
  32. package/dist/{model-manager-DqwL8ptm.mjs → model-manager-CfwJWvz7.mjs} +121 -29
  33. package/dist/model-manager-CfwJWvz7.mjs.map +1 -0
  34. package/dist/{ops-BfrdZ6GK.mjs → ops-B2P11b8v.mjs} +8 -8
  35. package/dist/ops-B2P11b8v.mjs.map +1 -0
  36. package/dist/providers/local/index.mjs +8 -8
  37. package/dist/{reconcile-M7KBZtdn.mjs → reconcile-EANDIp_T.mjs} +3 -3
  38. package/dist/{reconcile-M7KBZtdn.mjs.map → reconcile-EANDIp_T.mjs.map} +1 -1
  39. package/dist/{reconcile-D5FTVW5z.mjs → reconcile-TyPQKjme.mjs} +27 -4
  40. package/dist/{reconcile-D5FTVW5z.mjs.map → reconcile-TyPQKjme.mjs.map} +1 -1
  41. package/dist/server/http/index.mjs +12 -12
  42. package/dist/{server-BRkKIO3r.mjs → server-ChpsLHlF.mjs} +70 -32
  43. package/dist/server-ChpsLHlF.mjs.map +1 -0
  44. package/dist/server.mjs +12 -12
  45. package/dist/{transaction-BxDiiakv.mjs → transaction-BR2jg4uj.mjs} +2 -2
  46. package/dist/{transaction-BxDiiakv.mjs.map → transaction-BR2jg4uj.mjs.map} +1 -1
  47. package/dist/{validator-B2GhPM3L.mjs → validator-CLugFhHw.mjs} +47 -4
  48. package/dist/validator-CLugFhHw.mjs.map +1 -0
  49. package/package.json +2 -2
  50. package/dist/apply-manager-DsNq7Zhm.mjs.map +0 -1
  51. package/dist/content-manager-Bx94DXSF.d.mts.map +0 -1
  52. package/dist/meta-manager-g3shoZES.mjs.map +0 -1
  53. package/dist/model-manager-DqwL8ptm.mjs.map +0 -1
  54. package/dist/ops-BfrdZ6GK.mjs.map +0 -1
  55. package/dist/server-BRkKIO3r.mjs.map +0 -1
  56. package/dist/validator-B2GhPM3L.mjs.map +0 -1
@@ -1,25 +1,25 @@
1
- import { n as readContext } from "./context-CxpTATh4.mjs";
2
- import { D as contentDirPath, O as contentFilePath, T as writeContent, _ as resolveContentDir, b as resolveMdFilePath, c as listModels, d as validateModelDefinition, f as writeModel, i as countEntries, l as readModel, m as listContent, o as fieldDefZodSchema, p as deleteContent, r as checkReferences, v as resolveJsonFilePath, y as resolveLocaleStrategy } from "./model-manager-DqwL8ptm.mjs";
3
- import { a as planModelDelete, i as planModelSave, n as planVocabularySave, o as planContentSave, s as planContentDelete, t as planVocabularyDelete } from "./ops-BfrdZ6GK.mjs";
1
+ import { n as readContext } from "./context-BHfO4WBv.mjs";
2
+ import { A as contentDirPath, C as resolveMdFilePath, O as writeContent, S as resolveLocaleStrategy, _ as listContent, a as countEntries, b as resolveContentDir, d as readModel, g as deleteContent, h as writeModel, i as collectFieldPaths, j as contentFilePath, m as validateModelDefinition, r as checkReferences, s as fieldDefZodSchema, u as listModels, x as resolveJsonFilePath } from "./model-manager-CfwJWvz7.mjs";
3
+ import { a as planModelDelete, i as planModelSave, n as planVocabularySave, o as planContentSave, s as planContentDelete, t as planVocabularyDelete } from "./ops-B2P11b8v.mjs";
4
4
  import { a as readJson, n as ensureDir, r as pathExists, s as writeJson, t as contentrainDir } from "./fs-DJv5G8uL.mjs";
5
- import { a as writeMeta, i as readMeta, o as writeMetaEntries, r as mergeEntryMeta, t as applyStatusChange } from "./meta-manager-g3shoZES.mjs";
5
+ import { a as writeMeta, i as readMeta, o as writeMetaEntries, r as mergeEntryMeta, t as applyStatusChange } from "./meta-manager-Cd6AfuGS.mjs";
6
6
  import { t as OverlayReader } from "./overlay-reader-Bx1YxGXq.mjs";
7
7
  import { n as readVocabulary, t as readConfig } from "./config-B8a4JBT1.mjs";
8
- import { t as validateProject } from "./validator-B2GhPM3L.mjs";
8
+ import { t as validateProject } from "./validator-CLugFhHw.mjs";
9
9
  import { r as createGit } from "./identity-CxAB9Qb8.mjs";
10
10
  import { a as contentBranchRelation, c as listRemoteCrBranches, i as cleanupMergedBranches, n as checkBranchHealth, o as deleteRemoteBranch, u as pruneMergedRemoteBranches } from "./branch-lifecycle-DUOoyNWn.mjs";
11
- import { i as ensureContentBranch, n as buildBranchName, o as mergeBranch, r as createTransaction } from "./transaction-BxDiiakv.mjs";
12
- import { n as isMerged, t as LocalProvider } from "./local-bnn6yrG7.mjs";
11
+ import { i as ensureContentBranch, n as buildBranchName, o as mergeBranch, r as createTransaction } from "./transaction-BR2jg4uj.mjs";
12
+ import { n as isMerged, t as LocalProvider } from "./local-DbPlR0Br.mjs";
13
13
  import { n as isToolAvailable, t as TOOL_REQUIREMENTS } from "./availability-DYHNoP0_.mjs";
14
14
  import { t as detectStack } from "./detect-CI32ynpq.mjs";
15
15
  import { t as TOOL_ANNOTATIONS } from "./annotations-CXHPnS-M.mjs";
16
16
  import { n as listTemplates, t as getTemplate } from "./templates-BZbohJc8.mjs";
17
17
  import { t as normalizeOperationError } from "./errors-BmLE-JSC.mjs";
18
- import { t as reconcileBranches } from "./reconcile-M7KBZtdn.mjs";
18
+ import { t as reconcileBranches } from "./reconcile-EANDIp_T.mjs";
19
19
  import { t as buildGraph } from "./graph-builder-C9NS7y-a.mjs";
20
20
  import { n as scanSummary, t as scanCandidates } from "./scanner-CEiT8Tgx.mjs";
21
- import { n as applyExtract, r as applyReuse } from "./apply-manager-DsNq7Zhm.mjs";
22
- import { t as runDoctor } from "./doctor-B7G0oFxO.mjs";
21
+ import { n as applyExtract, r as applyReuse } from "./apply-manager-eZ6zA99Y.mjs";
22
+ import { t as runDoctor } from "./doctor-VnOzDTbk.mjs";
23
23
  import { join } from "node:path";
24
24
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
25
25
  import { CONTENTRAIN_BRANCH } from "@contentrain/types";
@@ -243,8 +243,8 @@ function registerContextTools(server, provider, projectRoot) {
243
243
  updated_by: "Author identifier string",
244
244
  approved_by: "Optional: approver identifier",
245
245
  version: "Optional: version string",
246
- publish_at: "Optional: ISO 8601 date for scheduled publishing",
247
- expire_at: "Optional: ISO 8601 date for scheduled expiry (must be after publish_at)"
246
+ publish_at: "Optional: ISO 8601 date for scheduled publishing. A delivery gate on top of status \"published\" — it never changes status, so a draft with a past publish_at stays a draft. Meta only; never written to the content file.",
247
+ expire_at: "Optional: ISO 8601 date for scheduled expiry (must be after publish_at). Same gate semantics as publish_at."
248
248
  }
249
249
  },
250
250
  locale_strategies: {
@@ -902,7 +902,7 @@ function registerModelTools(server, provider, projectRoot) {
902
902
  }],
903
903
  isError: true
904
904
  };
905
- const { errors, warnings: schemaWarnings } = validateModel(input);
905
+ const { errors, warnings: schemaWarnings } = validateModel(input, { existingFieldPaths: collectFieldPaths((await readModel(provider, input.id))?.fields) });
906
906
  if (errors.length > 0) return {
907
907
  content: [{
908
908
  type: "text",
@@ -1110,8 +1110,8 @@ function registerContentTools(server, provider, projectRoot) {
1110
1110
  slug: z.string().optional().describe("Slug (document only)"),
1111
1111
  locale: z.string().optional().describe("Locale code (defaults to config default)"),
1112
1112
  data: z.record(z.string(), z.unknown()).describe("Content data. For documents, include \"body\" key for markdown content."),
1113
- publish_at: z.string().optional().describe("ISO 8601 date for scheduled publishing (stored in meta)"),
1114
- expire_at: z.string().optional().describe("ISO 8601 date for scheduled expiry (stored in meta, must be after publish_at)")
1113
+ publish_at: z.string().nullable().optional().describe("Scheduled publish date, ISO 8601. Stored in meta only — never in the content file — and it does NOT change status: a draft stays a draft, and a published entry is delivered only once this date has passed. Publish with contentrain_bulk update_status. Pass null to clear a previously set date; omit to leave it unchanged."),
1114
+ expire_at: z.string().nullable().optional().describe("Scheduled expiry, ISO 8601, must be after publish_at. Same rules as publish_at: meta only, never changes status, null clears, omit leaves unchanged.")
1115
1115
  })).describe("Content entries to save")
1116
1116
  }, TOOL_ANNOTATIONS["contentrain_content_save"], async (input) => {
1117
1117
  const config = await readConfig(provider);
@@ -1138,7 +1138,7 @@ function registerContentTools(server, provider, projectRoot) {
1138
1138
  }],
1139
1139
  isError: true
1140
1140
  };
1141
- if (entry.publish_at !== void 0) {
1141
+ if (typeof entry.publish_at === "string") {
1142
1142
  const d = new Date(entry.publish_at);
1143
1143
  if (Number.isNaN(d.getTime())) return {
1144
1144
  content: [{
@@ -1148,7 +1148,7 @@ function registerContentTools(server, provider, projectRoot) {
1148
1148
  isError: true
1149
1149
  };
1150
1150
  }
1151
- if (entry.expire_at !== void 0) {
1151
+ if (typeof entry.expire_at === "string") {
1152
1152
  const d = new Date(entry.expire_at);
1153
1153
  if (Number.isNaN(d.getTime())) return {
1154
1154
  content: [{
@@ -1158,7 +1158,7 @@ function registerContentTools(server, provider, projectRoot) {
1158
1158
  isError: true
1159
1159
  };
1160
1160
  }
1161
- if (entry.publish_at !== void 0 && entry.expire_at !== void 0) {
1161
+ if (typeof entry.publish_at === "string" && typeof entry.expire_at === "string") {
1162
1162
  if (new Date(entry.expire_at) <= new Date(entry.publish_at)) return {
1163
1163
  content: [{
1164
1164
  type: "text",
@@ -1167,9 +1167,8 @@ function registerContentTools(server, provider, projectRoot) {
1167
1167
  isError: true
1168
1168
  };
1169
1169
  }
1170
- if (entry.publish_at !== void 0) entry.data["publish_at"] = entry.publish_at;
1171
- if (entry.expire_at !== void 0) entry.data["expire_at"] = entry.expire_at;
1172
1170
  }
1171
+ const schedulingTouched = input.entries.some((e) => e.publish_at !== void 0 || e.expire_at !== void 0);
1173
1172
  const readiness = await provider.checkWriteReadiness?.();
1174
1173
  if (readiness?.blocked) return {
1175
1174
  content: [{
@@ -1262,6 +1261,7 @@ function registerContentTools(server, provider, projectRoot) {
1262
1261
  advisory_note: "Save succeeded. Review these warnings and consider consolidating duplicate values."
1263
1262
  } : {},
1264
1263
  ...warnings.length > 0 ? { warnings } : {},
1264
+ ...schedulingTouched ? { scheduling_note: "publish_at/expire_at were written to meta only — not to the content file — and status is unchanged: a draft is still a draft. They gate delivery of a *published* entry (served once publish_at has passed, until expire_at). To publish, call contentrain_bulk update_status." } : {},
1265
1265
  validation: {
1266
1266
  valid: true,
1267
1267
  errors: []
@@ -1271,6 +1271,7 @@ function registerContentTools(server, provider, projectRoot) {
1271
1271
  ...divergenceNextSteps(commit),
1272
1272
  ...allAdvisories.length > 0 ? ["ADVISORY: Duplicate values detected — review advisories above"] : [],
1273
1273
  ...warnings.length > 0 ? ["REVIEW: see warnings above — the save was not blocked by them"] : [],
1274
+ ...schedulingTouched ? ["PUBLISH: publish_at did not change status — use contentrain_bulk update_status if this entry should go live"] : [],
1274
1275
  ...model.kind === "collection" ? ["Use contentrain_content_list to verify", "Add more entries or publish"] : ["Use contentrain_content_list to verify"]
1275
1276
  ]
1276
1277
  }, null, 2)
@@ -1661,9 +1662,9 @@ async function resolveMergeBranch(git, input) {
1661
1662
  }))).toSorted((left, right) => right.t - left.t)[0].b };
1662
1663
  }
1663
1664
  function registerWorkflowTools(server, provider, projectRoot) {
1664
- server.tool("contentrain_validate", "Validate project content against model schemas. Detects required field violations, type mismatches, broken relations, secret leaks, i18n parity issues, and more. If fix:true, auto-fixes structural issues (canonical sort, orphan meta, missing locale files, stray non-i18n meta layout) and backfills a missing model title_field — do NOT manually edit .contentrain/ files.", {
1665
+ server.tool("contentrain_validate", "Validate project content against model schemas. Detects required field violations, type mismatches, broken relations, secret leaks, i18n parity issues, and more. If fix:true, auto-fixes structural issues (canonical sort, orphan meta, missing locale files, stray non-i18n meta layout, scheduling keys an older content_save leaked into document frontmatter) and backfills a missing model title_field — do NOT manually edit .contentrain/ files.", {
1665
1666
  model: z.string().optional().describe("Model ID to validate (omit for all models)"),
1666
- fix: z.boolean().optional().describe("Auto-fix structural issues (canonical sort, orphan meta, missing locale files, stray non-i18n meta layout) and backfill a missing model title_field. Each backfilled title_field is reported as a notice naming the rule that chose it. Default: false")
1667
+ fix: z.boolean().optional().describe("Auto-fix structural issues (canonical sort, orphan meta, missing locale files, stray non-i18n meta layout, publish_at/expire_at copies an older content_save left in document frontmatter when meta holds the same key) and backfill a missing model title_field. Each backfilled title_field is reported as a notice naming the rule that chose it. Default: false")
1667
1668
  }, TOOL_ANNOTATIONS["contentrain_validate"], async (input) => {
1668
1669
  if (input.fix && !projectRoot) return capabilityError("contentrain_validate", "localWorktree");
1669
1670
  if (!await readConfig(provider)) return {
@@ -2421,6 +2422,7 @@ function registerBulkTools(server, _provider, projectRoot) {
2421
2422
  source_locale: z.string().optional().describe("Source locale for copy_locale operation"),
2422
2423
  target_locale: z.string().optional().describe("Target locale for copy_locale operation"),
2423
2424
  entry_ids: z.array(z.string()).optional().describe("Entry IDs for update_status (collection models) or delete_entries"),
2425
+ slugs: z.array(z.string()).optional().describe("Document slugs for update_status (document models) — a document is addressed by slug, the same identity contentrain_content_save uses, not by entry ID"),
2424
2426
  locale: z.string().optional().describe("Scope update_status to a single locale (i18n models only; defaults to every supported locale)"),
2425
2427
  status: z.enum([
2426
2428
  "draft",
@@ -2571,22 +2573,39 @@ function registerBulkTools(server, _provider, projectRoot) {
2571
2573
  }],
2572
2574
  isError: true
2573
2575
  };
2574
- if (model.kind === "document") return {
2576
+ const keyedByEntry = model.kind === "collection";
2577
+ const keyedBySlug = model.kind === "document";
2578
+ const hasEntryIds = Boolean(input.entry_ids && input.entry_ids.length > 0);
2579
+ const hasSlugs = Boolean(input.slugs && input.slugs.length > 0);
2580
+ if (keyedBySlug && hasEntryIds) return {
2575
2581
  content: [{
2576
2582
  type: "text",
2577
- text: JSON.stringify({ error: `Model "${input.model}" is a document model. update_status does not support documents yet — their meta is keyed by slug, not entry ID.` })
2583
+ text: JSON.stringify({ error: `Model "${input.model}" is a document model — documents are keyed by slug, not entry ID. Pass slugs instead of entry_ids.` })
2578
2584
  }],
2579
2585
  isError: true
2580
2586
  };
2581
- const keyedByEntry = model.kind === "collection";
2582
- if (keyedByEntry && (!input.entry_ids || input.entry_ids.length === 0)) return {
2587
+ if (keyedBySlug && !hasSlugs) return {
2588
+ content: [{
2589
+ type: "text",
2590
+ text: JSON.stringify({ error: `update_status requires slugs for document model "${input.model}".` })
2591
+ }],
2592
+ isError: true
2593
+ };
2594
+ if (!keyedBySlug && hasSlugs) return {
2595
+ content: [{
2596
+ type: "text",
2597
+ text: JSON.stringify({ error: `slugs only apply to document models — "${input.model}" is a ${model.kind} model. ${keyedByEntry ? "Pass entry_ids." : "Omit both entry_ids and slugs."}` })
2598
+ }],
2599
+ isError: true
2600
+ };
2601
+ if (keyedByEntry && !hasEntryIds) return {
2583
2602
  content: [{
2584
2603
  type: "text",
2585
2604
  text: JSON.stringify({ error: `update_status requires entry_ids for collection model "${input.model}".` })
2586
2605
  }],
2587
2606
  isError: true
2588
2607
  };
2589
- if (!keyedByEntry && input.entry_ids && input.entry_ids.length > 0) return {
2608
+ if (!keyedByEntry && !keyedBySlug && hasEntryIds) return {
2590
2609
  content: [{
2591
2610
  type: "text",
2592
2611
  text: JSON.stringify({ error: `Model "${input.model}" is a ${model.kind} model — it has one meta record per locale, so entry_ids do not apply. Omit entry_ids.` })
@@ -2624,6 +2643,24 @@ function registerBulkTools(server, _provider, projectRoot) {
2624
2643
  defaultLocale: config.locales.default
2625
2644
  }, updates);
2626
2645
  if (written.length > 0) updatedPerLocale[locale] = written;
2646
+ } else if (keyedBySlug) {
2647
+ const written = [];
2648
+ for (const slug of input.slugs) {
2649
+ const existing = await readMeta(wt, model, {
2650
+ locale,
2651
+ slug,
2652
+ defaultLocale: config.locales.default
2653
+ });
2654
+ if (!existing) continue;
2655
+ await writeMeta(wt, model, {
2656
+ locale,
2657
+ slug,
2658
+ defaultLocale: config.locales.default
2659
+ }, applyStatusChange(existing, input.status));
2660
+ written.push(slug);
2661
+ foundIds.add(slug);
2662
+ }
2663
+ if (written.length > 0) updatedPerLocale[locale] = written;
2627
2664
  } else {
2628
2665
  const existing = await readMeta(wt, model, {
2629
2666
  locale,
@@ -2638,14 +2675,15 @@ function registerBulkTools(server, _provider, projectRoot) {
2638
2675
  }
2639
2676
  });
2640
2677
  const updatedCount = Object.values(updatedPerLocale).reduce((n, ids) => n + ids.length, 0);
2641
- const notFound = keyedByEntry ? input.entry_ids.filter((id) => !foundIds.has(id)) : [];
2678
+ const requested = keyedByEntry ? input.entry_ids : keyedBySlug ? input.slugs : [];
2679
+ const notFound = requested.filter((key) => !foundIds.has(key));
2642
2680
  if (updatedCount === 0) {
2643
2681
  await tx.cleanup();
2644
2682
  return {
2645
2683
  content: [{
2646
2684
  type: "text",
2647
2685
  text: JSON.stringify({
2648
- error: keyedByEntry ? `No meta records found for the given entry_ids in model "${input.model}" across locales [${targetLocales.join(", ")}]. Nothing was changed.` : `No meta record found for model "${input.model}" across locales [${targetLocales.join(", ")}]. Nothing was changed.`,
2686
+ error: keyedByEntry ? `No meta records found for the given entry_ids in model "${input.model}" across locales [${targetLocales.join(", ")}]. Nothing was changed.` : keyedBySlug ? `No meta records found for the given slugs in model "${input.model}" across locales [${targetLocales.join(", ")}]. Nothing was changed. Check the slugs with contentrain_content_list.` : `No meta record found for model "${input.model}" across locales [${targetLocales.join(", ")}]. Nothing was changed.`,
2649
2687
  not_found: notFound.length > 0 ? notFound : void 0
2650
2688
  }, null, 2)
2651
2689
  }],
@@ -2655,7 +2693,7 @@ function registerBulkTools(server, _provider, projectRoot) {
2655
2693
  await tx.commit(`[contentrain] bulk: update status → ${input.status} for ${input.model}`, {
2656
2694
  tool: "contentrain_bulk",
2657
2695
  model: input.model,
2658
- ...keyedByEntry ? { entries: input.entry_ids } : {}
2696
+ ...requested.length > 0 ? { entries: requested } : {}
2659
2697
  });
2660
2698
  const gitResult = await tx.complete();
2661
2699
  return { content: [{
@@ -2921,7 +2959,7 @@ function registerMediaTools(server, provider, _projectRoot) {
2921
2959
  }
2922
2960
  //#endregion
2923
2961
  //#region package.json
2924
- var version = "3.1.7";
2962
+ var version = "3.2.0";
2925
2963
  //#endregion
2926
2964
  //#region src/server.ts
2927
2965
  /**
@@ -2996,4 +3034,4 @@ function resolveServerContext(input) {
2996
3034
  //#endregion
2997
3035
  export { createServer as n, DEFAULT_INSTRUCTIONS as t };
2998
3036
 
2999
- //# sourceMappingURL=server-BRkKIO3r.mjs.map
3037
+ //# sourceMappingURL=server-ChpsLHlF.mjs.map