@decantr/core 1.0.6 → 2.1.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.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/resolve.ts
2
- import { computeDensity, isSectioned, isSimple, isV3 } from "@decantr/essence-spec";
2
+ import { computeDensity, isV4 } from "@decantr/essence-spec";
3
3
  import { detectWirings, resolvePatternPreset } from "@decantr/registry";
4
4
 
5
5
  // src/utils.ts
@@ -115,15 +115,7 @@ function buildThemeDecoration(theme) {
115
115
  dimensions: shell.dimensions || null
116
116
  };
117
117
  }
118
- function buildTheme(essence, isAddon) {
119
- return {
120
- id: essence.theme.id,
121
- mode: essence.theme.mode,
122
- shape: essence.theme.shape || null,
123
- isAddon
124
- };
125
- }
126
- function buildThemeFromV3(essence, isAddon) {
118
+ function buildThemeFromV4(essence, isAddon) {
127
119
  const dna = essence.dna;
128
120
  return {
129
121
  id: dna.theme.id,
@@ -145,7 +137,7 @@ function blueprintPageToStructurePage(page, defaultShell, sectionId) {
145
137
  function routeIdentity(pageId, sectionId) {
146
138
  return sectionId ? `${sectionId}:${pageId}` : pageId;
147
139
  }
148
- function buildV3Routes(essence, structurePages) {
140
+ function buildV4Routes(essence, structurePages) {
149
141
  const explicitRoutes = /* @__PURE__ */ new Map();
150
142
  for (const [path, entry] of Object.entries(essence.blueprint.routes ?? {})) {
151
143
  if (!entry?.page) continue;
@@ -230,81 +222,14 @@ function resolveVisualEffects(theme, pattern, _slot) {
230
222
  };
231
223
  }
232
224
  async function resolveEssence(essence, resolver) {
233
- if (isV3(essence)) {
234
- return resolveV3Essence(essence, resolver);
235
- }
236
- let simpleEssence;
237
- if (isSimple(essence)) {
238
- simpleEssence = essence;
239
- } else if (isSectioned(essence)) {
240
- const sectioned = essence;
241
- if (sectioned.sections.length > 1) {
242
- throw new Error(
243
- `Sectioned essences with ${sectioned.sections.length} sections are not yet supported. Only single-section sectioned essences can be processed. Consider migrating to v3 format using migrateV2ToV3().`
244
- );
245
- }
246
- const firstSection = sectioned.sections[0];
247
- simpleEssence = {
248
- version: sectioned.version,
249
- archetype: firstSection.archetype,
250
- theme: firstSection.theme,
251
- personality: sectioned.personality,
252
- platform: sectioned.platform,
253
- structure: firstSection.structure,
254
- features: firstSection.features || [],
255
- density: sectioned.density,
256
- guard: sectioned.guard,
257
- target: sectioned.target
258
- };
259
- } else {
260
- throw new Error("Invalid essence format");
261
- }
262
- let registryTheme = null;
263
- const themeResult = await resolver.resolve("theme", simpleEssence.theme.id);
264
- if (themeResult) {
265
- registryTheme = themeResult.item;
225
+ if (!isV4(essence)) {
226
+ throw new Error(
227
+ "Active Decantr V2 workflows require Essence v4.0.0. Run `decantr migrate --to v4` for older essence files."
228
+ );
266
229
  }
267
- const themeSpatial = registryTheme?.spatial;
268
- const density = computeDensity(
269
- simpleEssence.personality,
270
- themeSpatial ? {
271
- density_bias: themeSpatial.density_bias,
272
- content_gap_shift: themeSpatial.content_gap_shift
273
- } : void 0
274
- );
275
- const themeId = simpleEssence.theme.id;
276
- const isAddon = themeId.startsWith("custom:") || !CORE_STYLES.has(themeId);
277
- const theme = buildTheme(simpleEssence, isAddon);
278
- const resolvedPages = await resolvePages(simpleEssence.structure, resolver, registryTheme);
279
- const shellType = simpleEssence.structure[0]?.shell || "sidebar-main";
280
- const brand = pascalCase(simpleEssence.archetype);
281
- const nav = buildNavItems(simpleEssence.structure);
282
- const decoration = registryTheme ? buildThemeDecoration(registryTheme) : null;
283
- const shell = {
284
- type: shellType,
285
- brand,
286
- nav,
287
- inset: false,
288
- decoration
289
- };
290
- const routes = simpleEssence.structure.map((page, i) => ({
291
- path: routePath(page.id, i),
292
- pageId: page.id,
293
- shell: page.shell
294
- }));
295
- return {
296
- essence,
297
- pages: resolvedPages,
298
- registryTheme,
299
- density: { gap: density.content_gap, level: density.level },
300
- theme,
301
- shell,
302
- routes,
303
- features: simpleEssence.features ?? [],
304
- isV3Source: false
305
- };
230
+ return resolveV4Essence(essence, resolver);
306
231
  }
307
- async function resolveV3Essence(essence, resolver) {
232
+ async function resolveV4Essence(essence, resolver) {
308
233
  const { dna, blueprint, meta } = essence;
309
234
  let registryTheme = null;
310
235
  const themeResult = await resolver.resolve("theme", dna.theme.id);
@@ -325,22 +250,17 @@ async function resolveV3Essence(essence, resolver) {
325
250
  };
326
251
  const themeId = dna.theme.id;
327
252
  const isAddon = themeId.startsWith("custom:") || !CORE_STYLES.has(themeId);
328
- const theme = buildThemeFromV3(essence, isAddon);
329
- const defaultShell = blueprint.shell ?? blueprint.sections?.[0]?.shell ?? "sidebar-main";
330
- const structurePages = blueprint.pages ? blueprint.pages.map((page) => blueprintPageToStructurePage(page, defaultShell)) : blueprint.sections ? blueprint.sections.flatMap(
253
+ const theme = buildThemeFromV4(essence, isAddon);
254
+ const defaultShell = blueprint.shell ?? blueprint.sections[0]?.shell ?? "sidebar-main";
255
+ const structurePages = blueprint.sections.flatMap(
331
256
  (section) => section.pages.map(
332
257
  (page) => blueprintPageToStructurePage(page, section.shell ?? defaultShell, section.id)
333
258
  )
334
- ) : [
335
- blueprintPageToStructurePage(
336
- { id: "home", layout: ["hero"] },
337
- defaultShell
338
- )
339
- ];
259
+ );
340
260
  const resolvedPages = await resolvePages(structurePages, resolver, registryTheme);
341
261
  const shellType = defaultShell;
342
262
  const brand = pascalCase(meta.archetype);
343
- const routes = buildV3Routes(essence, structurePages);
263
+ const routes = buildV4Routes(essence, structurePages);
344
264
  const nav = buildNavItems(structurePages, routes);
345
265
  const decoration = registryTheme ? buildThemeDecoration(registryTheme) : null;
346
266
  const shell = {
@@ -359,7 +279,7 @@ async function resolveV3Essence(essence, resolver) {
359
279
  shell,
360
280
  routes,
361
281
  features: blueprint.features ?? [],
362
- isV3Source: true
282
+ isBlueprintSource: true
363
283
  };
364
284
  }
365
285
  async function resolvePages(pages, resolver, registryTheme) {
@@ -558,23 +478,19 @@ function validateIR(root) {
558
478
  }
559
479
 
560
480
  // src/packs.ts
561
- import { isV3 as isV33, migrateV2ToV3 as migrateV2ToV32 } from "@decantr/essence-spec";
481
+ import { isV4 as isV42 } from "@decantr/essence-spec";
562
482
 
563
483
  // src/pipeline.ts
564
- import { isV3 as isV32, migrateV2ToV3, validateEssence } from "@decantr/essence-spec";
484
+ import { validateEssence } from "@decantr/essence-spec";
565
485
  import { createResolver } from "@decantr/registry";
566
486
  function extractRouting(essence) {
567
- if (isV32(essence)) {
568
- return essence.meta.platform.routing || "history";
569
- }
570
- return essence.platform?.routing || "history";
487
+ return essence.meta.platform.routing || "history";
571
488
  }
572
489
  async function runPipeline(essence, options) {
573
490
  const validation = validateEssence(essence);
574
491
  if (!validation.valid) {
575
492
  throw new Error(`Invalid essence: ${validation.errors.join(", ")}`);
576
493
  }
577
- const effectiveEssence = isV32(essence) ? essence : migrateV2ToV3(essence);
578
494
  const resolver = options.resolver ?? (() => {
579
495
  if (!options.contentRoot) {
580
496
  throw new Error("Pipeline options must include either a contentRoot or a resolver.");
@@ -584,8 +500,8 @@ async function runPipeline(essence, options) {
584
500
  overridePaths: options.overridePaths
585
501
  });
586
502
  })();
587
- const resolved = await resolveEssence(effectiveEssence, resolver);
588
- const layer = resolved.isV3Source ? "blueprint" : void 0;
503
+ const resolved = await resolveEssence(essence, resolver);
504
+ const layer = "blueprint";
589
505
  const pageNodes = [];
590
506
  for (const rp of resolved.pages) {
591
507
  const pageIR = buildPageIR(
@@ -779,13 +695,13 @@ var DEFAULT_REVIEW_ANTI_PATTERNS = [
779
695
  }
780
696
  ];
781
697
  function collectPatternIds(page) {
782
- const patternIds = [];
698
+ const patternIds2 = [];
783
699
  walkIR(page, (node) => {
784
700
  if (node.type !== "pattern") return;
785
701
  const patternNode = node;
786
- patternIds.push(patternNode.pattern.patternId);
702
+ patternIds2.push(patternNode.pattern.patternId);
787
703
  });
788
- return [...new Set(patternIds)];
704
+ return [...new Set(patternIds2)];
789
705
  }
790
706
  function pageIdentity(pageId, sectionId) {
791
707
  return sectionId ? `${sectionId}/${pageId}` : pageId;
@@ -882,6 +798,16 @@ function routingImplementationHint(routing) {
882
798
  }
883
799
  function renderExecutionPackMarkdown(pack) {
884
800
  const lines = [];
801
+ const escapeMarkdownCell = (value) => {
802
+ let escaped = "";
803
+ for (const char of value) {
804
+ if (char === "\\") escaped += "\\\\";
805
+ else if (char === "|") escaped += "\\|";
806
+ else if (char === "\n" || char === "\r") escaped += "<br>";
807
+ else escaped += char;
808
+ }
809
+ return escaped;
810
+ };
885
811
  lines.push(`# ${pack.packType.charAt(0).toUpperCase()}${pack.packType.slice(1)} Pack`);
886
812
  lines.push("");
887
813
  lines.push(`**Objective:** ${pack.objective}`);
@@ -960,7 +886,6 @@ function renderExecutionPackMarkdown(pack) {
960
886
  }
961
887
  lines.push("");
962
888
  if (scaffoldPack.data.themeDecorators && scaffoldPack.data.themeDecorators.length > 0) {
963
- const escScaffoldCell = (s) => s.replace(/\|/g, "\\|");
964
889
  lines.push(`## Required Theme Decorators (${scaffoldPack.data.theme.id})`);
965
890
  lines.push("");
966
891
  lines.push(
@@ -971,7 +896,7 @@ function renderExecutionPackMarkdown(pack) {
971
896
  lines.push("|-------|--------|----------|");
972
897
  for (const entry of scaffoldPack.data.themeDecorators) {
973
898
  lines.push(
974
- `| \`.${entry.class}\` | ${escScaffoldCell(entry.intent)} | ${escScaffoldCell(entry.applyTo)} |`
899
+ `| \`.${entry.class}\` | ${escapeMarkdownCell(entry.intent)} | ${escapeMarkdownCell(entry.applyTo)} |`
975
900
  );
976
901
  }
977
902
  lines.push("");
@@ -1029,7 +954,6 @@ function renderExecutionPackMarkdown(pack) {
1029
954
  lines.push("");
1030
955
  }
1031
956
  if (sectionPack.data.themeDecorators && sectionPack.data.themeDecorators.length > 0) {
1032
- const escCell = (s) => s.replace(/\|/g, "\\|");
1033
957
  lines.push(`## Required Theme Decorators (${sectionPack.data.theme.id})`);
1034
958
  lines.push("");
1035
959
  lines.push(
@@ -1040,7 +964,7 @@ function renderExecutionPackMarkdown(pack) {
1040
964
  lines.push("|-------|--------|----------|");
1041
965
  for (const entry of sectionPack.data.themeDecorators) {
1042
966
  lines.push(
1043
- `| \`.${entry.class}\` | ${escCell(entry.intent)} | ${escCell(entry.applyTo)} |`
967
+ `| \`.${entry.class}\` | ${escapeMarkdownCell(entry.intent)} | ${escapeMarkdownCell(entry.applyTo)} |`
1044
968
  );
1045
969
  }
1046
970
  lines.push("");
@@ -1080,7 +1004,9 @@ function renderExecutionPackMarkdown(pack) {
1080
1004
  lines.push(` > ${pattern.presetDescription}`);
1081
1005
  }
1082
1006
  if (pattern.interactions && pattern.interactions.length > 0) {
1083
- lines.push(` **Interactions (MUST implement each \u2014 see DECANTR.md "Interaction Requirements"):**`);
1007
+ lines.push(
1008
+ ` **Interactions (MUST implement each \u2014 see DECANTR.md "Interaction Requirements"):**`
1009
+ );
1084
1010
  for (const interaction of pattern.interactions) {
1085
1011
  lines.push(` - [ ] ${interaction}`);
1086
1012
  }
@@ -1216,79 +1142,57 @@ function renderExecutionPackMarkdown(pack) {
1216
1142
  return lines.join("\n").trimEnd() + "\n";
1217
1143
  }
1218
1144
  function resolvePackAdapter(target, platformType) {
1145
+ if (target === "html" || target === "vanilla" || target === "javascript" || target === "js") {
1146
+ return "vanilla-vite";
1147
+ }
1219
1148
  if (target === "react" && platformType === "spa") return "react-vite";
1220
1149
  if (target === "react") return "react-web";
1221
1150
  if (target === "vue" && platformType === "spa") return "vue-vite";
1222
1151
  if (target === "svelte" && platformType === "spa") return "sveltekit";
1152
+ if (target === "sveltekit") return "sveltekit";
1153
+ if (target === "angular") return "angular";
1154
+ if (target === "solid" || target === "solidjs") return "solid-vite";
1223
1155
  if (target) return target;
1224
1156
  return "generic-web";
1225
1157
  }
1226
1158
  function listPackSections(essence) {
1227
1159
  const declaredSections = essence.blueprint.sections;
1228
- if (declaredSections && declaredSections.length > 0) {
1229
- const routedSectionPages = new Set(
1230
- Object.values(essence.blueprint.routes ?? {}).map(
1231
- (entry) => `${entry.section}:${entry.page}`
1232
- )
1233
- );
1234
- return declaredSections.map((section) => {
1235
- const pageIds = section.pages.filter(
1236
- (page) => routedSectionPages.size === 0 || routedSectionPages.has(`${section.id}:${page.id}`)
1237
- ).map((page) => page.id);
1238
- return {
1239
- id: section.id,
1240
- role: section.role,
1241
- shell: section.shell,
1242
- description: section.description,
1243
- features: section.features,
1244
- pageIds,
1245
- ...Array.isArray(section.navigation_items) && section.navigation_items.length > 0 ? { navigationItems: section.navigation_items } : {},
1246
- ...Array.isArray(section.directives) && section.directives.length > 0 ? { directives: section.directives } : {}
1247
- };
1248
- }).filter((section) => section.pageIds.length > 0);
1249
- }
1250
- const pages = essence.blueprint.pages ?? [{ id: "home", layout: ["hero"] }];
1251
- return [
1252
- {
1253
- id: essence.meta.archetype || "default",
1254
- role: "primary",
1255
- shell: essence.blueprint.shell ?? "sidebar-main",
1256
- description: `${essence.meta.archetype || "Application"} section`,
1257
- features: essence.blueprint.features || [],
1258
- pageIds: pages.map((page) => page.id)
1259
- }
1260
- ];
1160
+ const routedSectionPages = new Set(
1161
+ Object.values(essence.blueprint.routes ?? {}).map((entry) => `${entry.section}:${entry.page}`)
1162
+ );
1163
+ return declaredSections.map((section) => {
1164
+ const pageIds = section.pages.filter(
1165
+ (page) => routedSectionPages.size === 0 || routedSectionPages.has(`${section.id}:${page.id}`)
1166
+ ).map((page) => page.id);
1167
+ return {
1168
+ id: section.id,
1169
+ role: section.role,
1170
+ shell: section.shell,
1171
+ description: section.description,
1172
+ features: section.features,
1173
+ pageIds,
1174
+ ...Array.isArray(section.navigation_items) && section.navigation_items.length > 0 ? { navigationItems: section.navigation_items } : {},
1175
+ ...Array.isArray(section.directives) && section.directives.length > 0 ? { directives: section.directives } : {}
1176
+ };
1177
+ }).filter((section) => section.pageIds.length > 0);
1261
1178
  }
1262
1179
  function listPackPages(essence) {
1263
1180
  const declaredSections = essence.blueprint.sections;
1264
- if (declaredSections && declaredSections.length > 0) {
1265
- const routedSectionPages = new Set(
1266
- Object.values(essence.blueprint.routes ?? {}).map(
1267
- (entry) => `${entry.section}:${entry.page}`
1268
- )
1269
- );
1270
- return declaredSections.flatMap(
1271
- (section) => section.pages.map((page) => ({
1272
- pageId: page.id,
1273
- shell: page.shell_override ?? section.shell,
1274
- sectionId: section.id,
1275
- sectionRole: section.role,
1276
- features: section.features,
1277
- ...Array.isArray(page.directives) && page.directives.length > 0 ? { directives: page.directives } : {}
1278
- })).filter(
1279
- (page) => routedSectionPages.size === 0 || routedSectionPages.has(`${page.sectionId}:${page.pageId}`)
1280
- )
1281
- );
1282
- }
1283
- const pages = essence.blueprint.pages ?? [{ id: "home", layout: ["hero"] }];
1284
- const defaultShell = essence.blueprint.shell ?? "sidebar-main";
1285
- return pages.map((page) => ({
1286
- pageId: page.id,
1287
- shell: page.shell_override ?? defaultShell,
1288
- sectionId: essence.meta.archetype || "default",
1289
- sectionRole: "primary",
1290
- features: essence.blueprint.features || []
1291
- }));
1181
+ const routedSectionPages = new Set(
1182
+ Object.values(essence.blueprint.routes ?? {}).map((entry) => `${entry.section}:${entry.page}`)
1183
+ );
1184
+ return declaredSections.flatMap(
1185
+ (section) => section.pages.map((page) => ({
1186
+ pageId: page.id,
1187
+ shell: page.shell_override ?? section.shell,
1188
+ sectionId: section.id,
1189
+ sectionRole: section.role,
1190
+ features: section.features,
1191
+ ...Array.isArray(page.directives) && page.directives.length > 0 ? { directives: page.directives } : {}
1192
+ })).filter(
1193
+ (page) => routedSectionPages.size === 0 || routedSectionPages.has(`${page.sectionId}:${page.pageId}`)
1194
+ )
1195
+ );
1292
1196
  }
1293
1197
  function buildPageManifestEntries(pages) {
1294
1198
  const counts = /* @__PURE__ */ new Map();
@@ -1618,19 +1522,23 @@ function buildReviewPack(appNode, options = {}) {
1618
1522
  return pack;
1619
1523
  }
1620
1524
  async function compileExecutionPackBundle(essence, options = {}) {
1621
- const effectiveEssence = isV33(essence) ? essence : migrateV2ToV32(essence);
1525
+ if (!isV42(essence)) {
1526
+ throw new Error(
1527
+ "Active Decantr V2 workflows require Essence v4.0.0. Run `decantr migrate --to v4` for older essence files."
1528
+ );
1529
+ }
1622
1530
  const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
1623
1531
  const sharedTarget = {
1624
- framework: effectiveEssence.meta.target || null,
1625
- runtime: effectiveEssence.meta.platform.type || null,
1626
- adapter: resolvePackAdapter(effectiveEssence.meta.target, effectiveEssence.meta.platform.type)
1532
+ framework: essence.meta.target || null,
1533
+ runtime: essence.meta.platform.type || null,
1534
+ adapter: resolvePackAdapter(essence.meta.target, essence.meta.platform.type)
1627
1535
  };
1628
1536
  const pipeline = await runPipeline(essence, {
1629
1537
  contentRoot: options.contentRoot,
1630
1538
  overridePaths: options.overridePaths,
1631
1539
  resolver: options.resolver
1632
1540
  });
1633
- const navMeta = effectiveEssence.meta.navigation;
1541
+ const navMeta = essence.meta.navigation;
1634
1542
  const commandPaletteValue = typeof navMeta?.command_palette === "object" && navMeta.command_palette !== null ? navMeta.command_palette : Boolean(navMeta?.command_palette);
1635
1543
  const themeDecorators = (() => {
1636
1544
  const defs = pipeline.registryTheme?.decorator_definitions;
@@ -1665,8 +1573,8 @@ async function compileExecutionPackBundle(essence, options = {}) {
1665
1573
  const review = buildReviewPack(pipeline.ir, {
1666
1574
  target: sharedTarget
1667
1575
  });
1668
- const sectionInputs = listPackSections(effectiveEssence);
1669
- const pageInputs = listPackPages(effectiveEssence);
1576
+ const sectionInputs = listPackSections(essence);
1577
+ const pageInputs = listPackPages(essence);
1670
1578
  const sections = sectionInputs.map(
1671
1579
  (section) => buildSectionPack(pipeline.ir, section, {
1672
1580
  target: sharedTarget
@@ -1773,6 +1681,114 @@ async function compileSelectedExecutionPack(essence, selector, options = {}) {
1773
1681
  const bundle = await compileExecutionPackBundle(essence, options);
1774
1682
  return selectExecutionPackFromBundle(bundle, selector);
1775
1683
  }
1684
+
1685
+ // src/realization.ts
1686
+ import { isV4 as isV43 } from "@decantr/essence-spec";
1687
+ var CERTIFIED_REALIZATION_ADAPTERS = /* @__PURE__ */ new Set([
1688
+ "react-vite",
1689
+ "next-app",
1690
+ "vanilla-vite",
1691
+ "vue-vite",
1692
+ "sveltekit",
1693
+ "angular",
1694
+ "solid-vite"
1695
+ ]);
1696
+ function routePath2(page, fallbackIndex) {
1697
+ if (page.route) return page.route;
1698
+ if (page.id === "home" || fallbackIndex === 0) return "/";
1699
+ return `/${page.id}`;
1700
+ }
1701
+ function patternIds(layout) {
1702
+ const ids = /* @__PURE__ */ new Set();
1703
+ for (const item of layout) {
1704
+ if (typeof item === "string") {
1705
+ ids.add(item);
1706
+ } else if ("pattern" in item) {
1707
+ ids.add(item.pattern);
1708
+ } else if ("cols" in item) {
1709
+ for (const col of item.cols) {
1710
+ ids.add(typeof col === "string" ? col : col.pattern);
1711
+ }
1712
+ }
1713
+ }
1714
+ return [...ids];
1715
+ }
1716
+ function compileRealizationPlan(essence) {
1717
+ if (!isV43(essence)) {
1718
+ throw new Error(
1719
+ "Active Decantr V2 workflows require Essence v4.0.0. Run `decantr migrate --to v4` for older essence files."
1720
+ );
1721
+ }
1722
+ const packAdapter = resolvePackAdapter(essence.meta.target, essence.meta.platform.type);
1723
+ const adapter = essence.meta.target === "nextjs" ? "next-app" : packAdapter;
1724
+ const canRealizeFrameworkCode = CERTIFIED_REALIZATION_ADAPTERS.has(adapter);
1725
+ const routes = [];
1726
+ for (const section of essence.blueprint.sections) {
1727
+ section.pages.forEach((page, pageIndex) => {
1728
+ routes.push({
1729
+ path: routePath2(page, routes.length + pageIndex),
1730
+ sectionId: section.id,
1731
+ sectionRole: section.role,
1732
+ pageId: page.id,
1733
+ shell: page.shell_override ?? section.shell,
1734
+ patterns: patternIds(page.layout),
1735
+ states: ["empty", "loading", "error"]
1736
+ });
1737
+ });
1738
+ }
1739
+ const mockData = [
1740
+ ...essence.blueprint.features.map((feature) => ({
1741
+ id: feature,
1742
+ source: "feature",
1743
+ shape: { enabled: true, status: "mocked" }
1744
+ })),
1745
+ ...routes.map((route) => ({
1746
+ id: route.pageId,
1747
+ source: "route",
1748
+ shape: { title: route.pageId, items: [] }
1749
+ }))
1750
+ ];
1751
+ const navigation = essence.meta.navigation;
1752
+ const interactions = [
1753
+ {
1754
+ id: "auth-mock",
1755
+ kind: "auth-mock",
1756
+ label: "Authenticated user/session placeholder"
1757
+ }
1758
+ ];
1759
+ if (navigation?.command_palette) {
1760
+ interactions.push({
1761
+ id: "command-palette",
1762
+ kind: "command-palette",
1763
+ label: "Command palette placeholder"
1764
+ });
1765
+ }
1766
+ for (const hotkey of navigation?.hotkeys ?? []) {
1767
+ interactions.push({
1768
+ id: `hotkey-${hotkey.key}`,
1769
+ kind: "hotkey",
1770
+ route: hotkey.route,
1771
+ label: hotkey.label
1772
+ });
1773
+ }
1774
+ return {
1775
+ version: "1.0.0",
1776
+ sourceEssenceVersion: "4.0.0",
1777
+ adapter,
1778
+ canRealizeFrameworkCode,
1779
+ routes,
1780
+ shell: {
1781
+ id: essence.blueprint.shell ?? essence.blueprint.sections[0]?.shell ?? "sidebar-main",
1782
+ theme: essence.dna.theme.id,
1783
+ mode: essence.dna.theme.mode
1784
+ },
1785
+ mockData,
1786
+ interactions,
1787
+ ...canRealizeFrameworkCode ? {} : {
1788
+ unsupportedReason: "No certified realization adapter is available for this target yet. Use the V4 contract, execution packs, prompts, and Project Health without generated framework code."
1789
+ }
1790
+ };
1791
+ }
1776
1792
  export {
1777
1793
  EXECUTION_PACK_BUNDLE_SCHEMA_URL,
1778
1794
  EXECUTION_PACK_SCHEMA_URLS,
@@ -1785,6 +1801,7 @@ export {
1785
1801
  buildScaffoldPack,
1786
1802
  buildSectionPack,
1787
1803
  compileExecutionPackBundle,
1804
+ compileRealizationPlan,
1788
1805
  compileSelectedExecutionPack,
1789
1806
  countPatterns,
1790
1807
  findNodes,