@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/README.md +13 -1
- package/dist/index.d.ts +48 -10
- package/dist/index.js +197 -180
- package/dist/index.js.map +1 -1
- package/package.json +14 -3
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/resolve.ts
|
|
2
|
-
import { computeDensity,
|
|
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
|
|
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
|
|
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 (
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
329
|
-
const defaultShell = blueprint.shell ?? blueprint.sections
|
|
330
|
-
const structurePages = blueprint.
|
|
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 =
|
|
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
|
-
|
|
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 {
|
|
481
|
+
import { isV4 as isV42 } from "@decantr/essence-spec";
|
|
562
482
|
|
|
563
483
|
// src/pipeline.ts
|
|
564
|
-
import {
|
|
484
|
+
import { validateEssence } from "@decantr/essence-spec";
|
|
565
485
|
import { createResolver } from "@decantr/registry";
|
|
566
486
|
function extractRouting(essence) {
|
|
567
|
-
|
|
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(
|
|
588
|
-
const layer =
|
|
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
|
|
698
|
+
const patternIds2 = [];
|
|
783
699
|
walkIR(page, (node) => {
|
|
784
700
|
if (node.type !== "pattern") return;
|
|
785
701
|
const patternNode = node;
|
|
786
|
-
|
|
702
|
+
patternIds2.push(patternNode.pattern.patternId);
|
|
787
703
|
});
|
|
788
|
-
return [...new Set(
|
|
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}\` | ${
|
|
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}\` | ${
|
|
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(
|
|
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
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
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
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
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
|
-
|
|
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:
|
|
1625
|
-
runtime:
|
|
1626
|
-
adapter: resolvePackAdapter(
|
|
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 =
|
|
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(
|
|
1669
|
-
const pageInputs = listPackPages(
|
|
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,
|