@decantr/cli 1.6.1 → 1.6.3
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/bin.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "./chunk-
|
|
3
|
-
import "./chunk-
|
|
2
|
+
import "./chunk-HWMN432I.js";
|
|
3
|
+
import "./chunk-5MKMLONH.js";
|
|
@@ -217,20 +217,13 @@ function generateTreatmentCSS(spatialTokens, treatmentOverrides, themeDecorators
|
|
|
217
217
|
lines.push("}");
|
|
218
218
|
lines.push("");
|
|
219
219
|
lines.push("} /* end @layer treatments */");
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
for (const [name, description] of Object.entries(themeDecorators)) {
|
|
228
|
-
const rule = generateDecoratorRule(name, description);
|
|
229
|
-
lines.push(rule);
|
|
230
|
-
lines.push("");
|
|
231
|
-
}
|
|
232
|
-
lines.push("} /* end @layer decorators */");
|
|
233
|
-
}
|
|
220
|
+
const decoratorBlock = `
|
|
221
|
+
@layer decorators {
|
|
222
|
+
/* Decorator CSS is AI-generated from structured definitions in section context files. */
|
|
223
|
+
/* See .decantr/context/section-*.md for intent, suggested properties, and usage guidance. */
|
|
224
|
+
}
|
|
225
|
+
`;
|
|
226
|
+
lines.push(decoratorBlock);
|
|
234
227
|
return lines.join("\n");
|
|
235
228
|
}
|
|
236
229
|
function generatePersonalityCSS(personality, themeData) {
|
|
@@ -252,6 +245,7 @@ function generatePersonalityCSS(personality, themeData) {
|
|
|
252
245
|
rules.push(`.status-ring[data-status="error"] { border-color: var(--d-error); box-shadow: 0 0 12px color-mix(in srgb, var(--d-error) 25%, transparent); }`);
|
|
253
246
|
rules.push(`.status-ring[data-status="warning"] { border-color: var(--d-warning); }`);
|
|
254
247
|
rules.push(`.status-ring[data-status="idle"] { border-color: var(--d-text-muted); }`);
|
|
248
|
+
rules.push(`.status-ring[data-status="processing"] { border-color: var(--d-primary); }`);
|
|
255
249
|
rules.push(`@keyframes pulse-ring { 0% { opacity: 0.6; transform: scale(1); } 100% { opacity: 0; transform: scale(1.3); } }`);
|
|
256
250
|
rules.push(`.status-ring[data-status="active"]::after { content: ''; position: absolute; inset: -4px; border-radius: 50%; border: 2px solid var(--d-success); opacity: 0; animation: pulse-ring 2s ease-out infinite; }`);
|
|
257
251
|
}
|
|
@@ -539,7 +533,7 @@ function generateTokensCSS(themeData, mode, spatialTokens) {
|
|
|
539
533
|
return {
|
|
540
534
|
// Seed colors
|
|
541
535
|
"--d-primary": seed.primary || "#6366f1",
|
|
542
|
-
"--d-secondary": seed.secondary || "#
|
|
536
|
+
"--d-secondary": palette.secondary?.[tokenMode] || palette.secondary?.dark || seed.secondary || "#A1A1AA",
|
|
543
537
|
"--d-accent": seed.accent || "#f59e0b",
|
|
544
538
|
// Palette colors (mode-aware)
|
|
545
539
|
"--d-bg": palette.background?.[tokenMode] || "#18181b",
|
|
@@ -693,135 +687,6 @@ input, button, textarea, select {
|
|
|
693
687
|
}
|
|
694
688
|
`;
|
|
695
689
|
}
|
|
696
|
-
function generateDecoratorRule(name, description) {
|
|
697
|
-
const rules = [];
|
|
698
|
-
const descLower = description.toLowerCase();
|
|
699
|
-
const nameLower = name.toLowerCase();
|
|
700
|
-
const isCard = descLower.includes("card") || descLower.includes("panel") || nameLower.includes("card") || nameLower.includes("panel");
|
|
701
|
-
const isInput = descLower.includes("input") || descLower.includes("field") || descLower.includes("textarea") || nameLower.includes("input") || nameLower.includes("textarea");
|
|
702
|
-
const isGlass = descLower.includes("glassmorphic") || descLower.includes("glass") || nameLower.includes("glass");
|
|
703
|
-
const isInteractive = isCard || isInput || isGlass;
|
|
704
|
-
const isNonInteractive = descLower.includes("divider") || descLower.includes("skeleton") || descLower.includes("keyframe") || descLower.includes("canvas") || nameLower.includes("divider") || nameLower.includes("skeleton") || nameLower.includes("canvas");
|
|
705
|
-
if (descLower.includes("monospace") || descLower.includes("mono font")) {
|
|
706
|
-
rules.push("font-family: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono', monospace");
|
|
707
|
-
}
|
|
708
|
-
if (descLower.includes("surface-raised") || descLower.includes("surface raised")) {
|
|
709
|
-
rules.push("background: var(--d-surface-raised)");
|
|
710
|
-
} else if (descLower.includes("surface background") || descLower.includes("surface elevation")) {
|
|
711
|
-
rules.push("background: var(--d-surface)");
|
|
712
|
-
} else if (descLower.includes("background") && descLower.includes("theme")) {
|
|
713
|
-
rules.push("background: var(--d-bg)");
|
|
714
|
-
} else if (descLower.includes("primary-tinted") || descLower.includes("primary background")) {
|
|
715
|
-
rules.push("background: color-mix(in srgb, var(--d-primary) 15%, var(--d-surface))");
|
|
716
|
-
}
|
|
717
|
-
if (isInput) {
|
|
718
|
-
if (!rules.some((r) => r.startsWith("background"))) {
|
|
719
|
-
rules.push("background: var(--d-surface)");
|
|
720
|
-
}
|
|
721
|
-
rules.push("color: var(--d-text)");
|
|
722
|
-
rules.push("padding: 0.5rem 0.75rem");
|
|
723
|
-
rules.push("border-radius: var(--d-radius)");
|
|
724
|
-
rules.push("width: 100%");
|
|
725
|
-
rules.push("outline: none");
|
|
726
|
-
}
|
|
727
|
-
const leftBorderMatch = descLower.match(/(\d+)px\s+left\s+border/);
|
|
728
|
-
if (leftBorderMatch) {
|
|
729
|
-
rules.push(`border-left: ${leftBorderMatch[1]}px solid var(--d-primary)`);
|
|
730
|
-
} else if (descLower.includes("left border")) {
|
|
731
|
-
rules.push("border-left: 3px solid var(--d-primary)");
|
|
732
|
-
} else if (descLower.includes("1px border") || descLower.includes("subtle border")) {
|
|
733
|
-
rules.push("border: 1px solid var(--d-border)");
|
|
734
|
-
} else if (descLower.includes("border") && !descLower.includes("radius")) {
|
|
735
|
-
rules.push("border: 1px solid var(--d-border)");
|
|
736
|
-
}
|
|
737
|
-
const radiusMatch = descLower.match(/(\d+)px radius/);
|
|
738
|
-
if (radiusMatch) {
|
|
739
|
-
rules.push(`border-radius: ${radiusMatch[1]}px`);
|
|
740
|
-
} else if ((descLower.includes("radius") || descLower.includes("rounded")) && !isInput) {
|
|
741
|
-
rules.push("border-radius: var(--d-radius)");
|
|
742
|
-
}
|
|
743
|
-
if (descLower.includes("elevation") || descLower.includes("shadow")) {
|
|
744
|
-
rules.push("box-shadow: var(--d-shadow)");
|
|
745
|
-
}
|
|
746
|
-
if (isInteractive && !isNonInteractive) {
|
|
747
|
-
rules.push("transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease");
|
|
748
|
-
}
|
|
749
|
-
if (descLower.includes("entrance animation") || descLower.includes("fade")) {
|
|
750
|
-
rules.push("animation: decantr-fade-in 0.2s ease-out");
|
|
751
|
-
}
|
|
752
|
-
if (descLower.includes("pulse animation") || descLower.includes("skeleton")) {
|
|
753
|
-
rules.push("animation: decantr-pulse 1.5s ease-in-out infinite");
|
|
754
|
-
}
|
|
755
|
-
const blurMatch = descLower.match(/blur\((\d+)px\)/);
|
|
756
|
-
if (blurMatch) {
|
|
757
|
-
rules.push(`backdrop-filter: blur(${blurMatch[1]}px)`);
|
|
758
|
-
rules.push(`-webkit-backdrop-filter: blur(${blurMatch[1]}px)`);
|
|
759
|
-
} else if (isGlass) {
|
|
760
|
-
rules.push("backdrop-filter: blur(12px)");
|
|
761
|
-
rules.push("-webkit-backdrop-filter: blur(12px)");
|
|
762
|
-
} else if (descLower.includes("blur")) {
|
|
763
|
-
rules.push("backdrop-filter: blur(8px)");
|
|
764
|
-
rules.push("-webkit-backdrop-filter: blur(8px)");
|
|
765
|
-
}
|
|
766
|
-
if (descLower.includes("semi-transparent") || descLower.includes("glassmorphic")) {
|
|
767
|
-
const bgIdx = rules.findIndex((r) => r.startsWith("background:"));
|
|
768
|
-
const rgbaBg = "background: rgba(31, 31, 35, 0.8)";
|
|
769
|
-
if (bgIdx !== -1) {
|
|
770
|
-
rules[bgIdx] = rgbaBg;
|
|
771
|
-
} else {
|
|
772
|
-
rules.push(rgbaBg);
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
if (descLower.includes("right-aligned")) {
|
|
776
|
-
rules.push("margin-left: auto");
|
|
777
|
-
} else if (descLower.includes("left-aligned")) {
|
|
778
|
-
rules.push("margin-right: auto");
|
|
779
|
-
}
|
|
780
|
-
if (descLower.includes("message bubble") || descLower.includes("bubble")) {
|
|
781
|
-
rules.push("padding: var(--d-gap-3) var(--d-gap-4)");
|
|
782
|
-
rules.push("border-radius: var(--d-radius-lg)");
|
|
783
|
-
rules.push("max-width: 80%");
|
|
784
|
-
}
|
|
785
|
-
if (descLower.includes("monospace") || descLower.includes("code")) {
|
|
786
|
-
if (!rules.some((r) => r.startsWith("padding"))) {
|
|
787
|
-
rules.push("padding: 0.75rem 1rem");
|
|
788
|
-
}
|
|
789
|
-
if (!rules.some((r) => r.startsWith("border-radius"))) {
|
|
790
|
-
rules.push("border-radius: var(--d-radius-sm)");
|
|
791
|
-
}
|
|
792
|
-
rules.push("overflow-x: auto");
|
|
793
|
-
}
|
|
794
|
-
if (rules.length === 0) {
|
|
795
|
-
return `/* .${name}: ${description} */`;
|
|
796
|
-
}
|
|
797
|
-
let css = `.${name} {
|
|
798
|
-
${rules.join(";\n ")};
|
|
799
|
-
}`;
|
|
800
|
-
if (isInteractive && !isNonInteractive) {
|
|
801
|
-
const stateRules = [];
|
|
802
|
-
if (isCard || isGlass) {
|
|
803
|
-
stateRules.push(`.${name}:hover {
|
|
804
|
-
border-color: var(--d-primary-hover, var(--d-border));
|
|
805
|
-
box-shadow: var(--d-shadow-md);
|
|
806
|
-
}`);
|
|
807
|
-
}
|
|
808
|
-
if (isInput) {
|
|
809
|
-
stateRules.push(`.${name}:focus {
|
|
810
|
-
border-color: var(--d-primary);
|
|
811
|
-
box-shadow: 0 0 0 3px color-mix(in srgb, var(--d-primary) 25%, transparent);
|
|
812
|
-
}`);
|
|
813
|
-
stateRules.push(`.${name}::placeholder {
|
|
814
|
-
color: var(--d-text-muted);
|
|
815
|
-
}`);
|
|
816
|
-
stateRules.push(`.${name}:disabled {
|
|
817
|
-
opacity: 0.5;
|
|
818
|
-
cursor: not-allowed;
|
|
819
|
-
}`);
|
|
820
|
-
}
|
|
821
|
-
css += "\n\n" + stateRules.join("\n\n");
|
|
822
|
-
}
|
|
823
|
-
return css;
|
|
824
|
-
}
|
|
825
690
|
function serializeLayoutItem(item) {
|
|
826
691
|
if (typeof item === "string") {
|
|
827
692
|
return item;
|
|
@@ -897,64 +762,6 @@ function resolvePatternAlias(item, patterns) {
|
|
|
897
762
|
}
|
|
898
763
|
return item;
|
|
899
764
|
}
|
|
900
|
-
function buildEssence(options, archetypeData) {
|
|
901
|
-
let structure = [
|
|
902
|
-
{ id: "home", shell: options.shell, layout: ["hero"] }
|
|
903
|
-
];
|
|
904
|
-
let features = options.features;
|
|
905
|
-
if (archetypeData?.pages) {
|
|
906
|
-
structure = archetypeData.pages.map((p) => {
|
|
907
|
-
const resolvedLayout = (p.default_layout?.length ? p.default_layout : ["hero"]).map((item) => resolvePatternAlias(item, p.patterns));
|
|
908
|
-
return {
|
|
909
|
-
id: p.id,
|
|
910
|
-
shell: p.shell || options.shell,
|
|
911
|
-
layout: resolvedLayout
|
|
912
|
-
};
|
|
913
|
-
});
|
|
914
|
-
}
|
|
915
|
-
if (archetypeData?.features) {
|
|
916
|
-
features = [.../* @__PURE__ */ new Set([...features, ...archetypeData.features])];
|
|
917
|
-
}
|
|
918
|
-
const contentGapMap = {
|
|
919
|
-
compact: "_gap2",
|
|
920
|
-
comfortable: "_gap4",
|
|
921
|
-
spacious: "_gap6"
|
|
922
|
-
};
|
|
923
|
-
const archetype = options.archetype || "custom";
|
|
924
|
-
const essence = {
|
|
925
|
-
version: "2.0.0",
|
|
926
|
-
archetype,
|
|
927
|
-
theme: {
|
|
928
|
-
style: options.theme,
|
|
929
|
-
mode: options.mode,
|
|
930
|
-
recipe: options.theme,
|
|
931
|
-
// Legacy v2 field — kept for backward compatibility
|
|
932
|
-
shape: options.shape
|
|
933
|
-
},
|
|
934
|
-
personality: options.personality,
|
|
935
|
-
platform: {
|
|
936
|
-
type: "spa",
|
|
937
|
-
routing: "hash"
|
|
938
|
-
},
|
|
939
|
-
structure,
|
|
940
|
-
features,
|
|
941
|
-
guard: {
|
|
942
|
-
enforce_style: true,
|
|
943
|
-
enforce_recipe: true,
|
|
944
|
-
// Legacy v2 field — kept for backward compatibility
|
|
945
|
-
mode: options.guard
|
|
946
|
-
},
|
|
947
|
-
density: {
|
|
948
|
-
level: options.density,
|
|
949
|
-
content_gap: contentGapMap[options.density] || "_gap4"
|
|
950
|
-
},
|
|
951
|
-
target: options.target
|
|
952
|
-
};
|
|
953
|
-
if (options.accessibility) {
|
|
954
|
-
essence.accessibility = options.accessibility;
|
|
955
|
-
}
|
|
956
|
-
return essence;
|
|
957
|
-
}
|
|
958
765
|
function buildEssenceV3(options, archetypeData, themeHints) {
|
|
959
766
|
let pages = [
|
|
960
767
|
{ id: "home", layout: ["hero"] }
|
|
@@ -1321,10 +1128,8 @@ function generateDecantrMdV31(params) {
|
|
|
1321
1128
|
briefLines.push("## Project Brief");
|
|
1322
1129
|
briefLines.push("");
|
|
1323
1130
|
briefLines.push(`- **Blueprint:** ${params.blueprintId || "custom"}`);
|
|
1324
|
-
const
|
|
1325
|
-
|
|
1326
|
-
if (params.themeShape) themeParts.push(params.themeShape);
|
|
1327
|
-
briefLines.push(`- **Theme:** ${themeParts.join(" (").replace(/ \($/, "") + (themeParts.length > 1 ? ")" : "")}`);
|
|
1131
|
+
const themeDesc = `${params.themeName || "default"} (${params.themeMode || "dark"} mode${params.themeShape ? `, ${params.themeShape} shape` : ""})`;
|
|
1132
|
+
briefLines.push(`- **Theme:** ${themeDesc}`);
|
|
1328
1133
|
if (params.personality && params.personality.length > 0) {
|
|
1329
1134
|
briefLines.push(`- **Personality:** ${params.personality.join(". ")}`);
|
|
1330
1135
|
}
|
|
@@ -1337,7 +1142,17 @@ function generateDecantrMdV31(params) {
|
|
|
1337
1142
|
}
|
|
1338
1143
|
briefLines.push(`- **Guard mode:** ${params.guardMode}`);
|
|
1339
1144
|
briefLines.push("");
|
|
1340
|
-
if (params.
|
|
1145
|
+
if (params.decoratorDefinitions && Object.keys(params.decoratorDefinitions).length > 0) {
|
|
1146
|
+
briefLines.push("### Decorator Quick Reference");
|
|
1147
|
+
briefLines.push("| Class | Intent | Key CSS |");
|
|
1148
|
+
briefLines.push("|-------|--------|---------|");
|
|
1149
|
+
for (const [name, def] of Object.entries(params.decoratorDefinitions)) {
|
|
1150
|
+
const intent = def.intent || "";
|
|
1151
|
+
const cssProps = def.css ? Object.entries(def.css).map(([p, v]) => `${p}: ${v}`).join("; ") : "";
|
|
1152
|
+
briefLines.push(`| \`.${name}\` | ${intent} | ${cssProps} |`);
|
|
1153
|
+
}
|
|
1154
|
+
briefLines.push("");
|
|
1155
|
+
} else if (params.decorators && params.decorators.length > 0) {
|
|
1341
1156
|
briefLines.push("### Decorator Quick Reference");
|
|
1342
1157
|
briefLines.push("| Class | Purpose |");
|
|
1343
1158
|
briefLines.push("|-------|---------|");
|
|
@@ -1381,6 +1196,9 @@ function generateProjectJson(detected, options, registrySource) {
|
|
|
1381
1196
|
flags: buildFlagsString(options)
|
|
1382
1197
|
}
|
|
1383
1198
|
};
|
|
1199
|
+
if (options.blueprint) {
|
|
1200
|
+
data.blueprintId = options.blueprint;
|
|
1201
|
+
}
|
|
1384
1202
|
return JSON.stringify(data, null, 2);
|
|
1385
1203
|
}
|
|
1386
1204
|
function buildFlagsString(options) {
|
|
@@ -1391,38 +1209,23 @@ function buildFlagsString(options) {
|
|
|
1391
1209
|
if (options.guard) flags.push(`--guard=${options.guard}`);
|
|
1392
1210
|
return flags.join(" ");
|
|
1393
1211
|
}
|
|
1394
|
-
function generateTaskContext(templateName, essence) {
|
|
1395
|
-
const template = loadTemplate(templateName);
|
|
1396
|
-
const defaultShell = essence.structure[0]?.shell || "sidebar-main";
|
|
1397
|
-
const layout = essence.structure[0]?.layout.map(serializeLayoutItem).join(", ") || "none";
|
|
1398
|
-
const scaffoldStructure = essence.structure.map((p) => {
|
|
1399
|
-
const patterns = p.layout.length > 0 ? `
|
|
1400
|
-
- Patterns: ${p.layout.map(serializeLayoutItem).join(", ")}` : "";
|
|
1401
|
-
return `- **${p.id}** (${p.shell})${patterns}`;
|
|
1402
|
-
}).join("\n");
|
|
1403
|
-
const vars = {
|
|
1404
|
-
TARGET: essence.target,
|
|
1405
|
-
THEME_STYLE: essence.theme.style,
|
|
1406
|
-
THEME_MODE: essence.theme.mode,
|
|
1407
|
-
THEME_RECIPE: essence.theme.style,
|
|
1408
|
-
DEFAULT_SHELL: defaultShell,
|
|
1409
|
-
GUARD_MODE: essence.guard.mode,
|
|
1410
|
-
LAYOUT: layout,
|
|
1411
|
-
DENSITY: essence.density.level,
|
|
1412
|
-
CONTENT_GAP: essence.density.content_gap,
|
|
1413
|
-
SCAFFOLD_STRUCTURE: scaffoldStructure
|
|
1414
|
-
};
|
|
1415
|
-
return renderTemplate(template, vars);
|
|
1416
|
-
}
|
|
1417
1212
|
function generateTaskContextV3(templateName, essence) {
|
|
1418
1213
|
const template = loadTemplate(templateName);
|
|
1419
|
-
const
|
|
1420
|
-
const
|
|
1214
|
+
const sections = essence.blueprint.sections && essence.blueprint.sections.length > 0 ? essence.blueprint.sections : [];
|
|
1215
|
+
const pages = sections.length > 0 ? sections.flatMap((s) => s.pages) : essence.blueprint.pages || [];
|
|
1216
|
+
const defaultShell = sections[0]?.shell || essence.blueprint.shell || "sidebar-main";
|
|
1421
1217
|
const layout = pages[0]?.layout?.map(serializeLayoutItem).join(", ") || "none";
|
|
1218
|
+
const pageShellMap = /* @__PURE__ */ new Map();
|
|
1219
|
+
for (const s of sections) {
|
|
1220
|
+
for (const p of s.pages) {
|
|
1221
|
+
pageShellMap.set(p.id, s.shell);
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1422
1224
|
const scaffoldStructure = pages.map((p) => {
|
|
1225
|
+
const shell = pageShellMap.get(p.id) || defaultShell;
|
|
1423
1226
|
const patterns = p.layout.length > 0 ? `
|
|
1424
1227
|
- Patterns: ${p.layout.map(serializeLayoutItem).join(", ")}` : "";
|
|
1425
|
-
return `- **${p.id}** (${
|
|
1228
|
+
return `- **${p.id}** (${shell})${patterns}`;
|
|
1426
1229
|
}).join("\n");
|
|
1427
1230
|
const densityLevel = essence.dna.spacing?.density || "comfortable";
|
|
1428
1231
|
const contentGap = essence.dna.spacing?.content_gap || "_gap4";
|
|
@@ -1506,7 +1309,6 @@ ${cacheEntry}
|
|
|
1506
1309
|
}
|
|
1507
1310
|
async function scaffoldProject(projectRoot, options, detected, registry, archetypeData, registrySource = "cache", themeData, topologyMarkdown, composedSections, routeMap, patternSpecs, blueprintData) {
|
|
1508
1311
|
const essenceV3 = buildEssenceV3(options, archetypeData, themeData);
|
|
1509
|
-
const essence = buildEssence(options, archetypeData);
|
|
1510
1312
|
const decantrDir = join(projectRoot, ".decantr");
|
|
1511
1313
|
const contextDir = join(decantrDir, "context");
|
|
1512
1314
|
const cacheDir = join(decantrDir, "cache");
|
|
@@ -1515,10 +1317,15 @@ async function scaffoldProject(projectRoot, options, detected, registry, archety
|
|
|
1515
1317
|
const essencePath = join(projectRoot, "decantr.essence.json");
|
|
1516
1318
|
writeFileSync(essencePath, JSON.stringify(essenceV3, null, 2) + "\n");
|
|
1517
1319
|
const projectJsonPath = join(decantrDir, "project.json");
|
|
1518
|
-
|
|
1320
|
+
const projectJsonStr = generateProjectJson(detected, options, registrySource);
|
|
1321
|
+
const projectJsonObj = JSON.parse(projectJsonStr);
|
|
1322
|
+
if (blueprintData?.voice) {
|
|
1323
|
+
projectJsonObj.voice = blueprintData.voice;
|
|
1324
|
+
}
|
|
1325
|
+
writeFileSync(projectJsonPath, JSON.stringify(projectJsonObj, null, 2));
|
|
1519
1326
|
const contextFiles = [];
|
|
1520
1327
|
const scaffoldPath = join(contextDir, "task-scaffold.md");
|
|
1521
|
-
writeFileSync(scaffoldPath,
|
|
1328
|
+
writeFileSync(scaffoldPath, generateTaskContextV3("task-scaffold.md.template", essenceV3));
|
|
1522
1329
|
contextFiles.push(scaffoldPath);
|
|
1523
1330
|
if (composedSections) {
|
|
1524
1331
|
essenceV3.version = "3.1.0";
|
|
@@ -1541,7 +1348,7 @@ async function scaffoldProject(projectRoot, options, detected, registry, archety
|
|
|
1541
1348
|
}
|
|
1542
1349
|
writeFileSync(essencePath, JSON.stringify(essenceV3, null, 2) + "\n");
|
|
1543
1350
|
}
|
|
1544
|
-
const refreshResult = await refreshDerivedFiles(projectRoot, essenceV3, registry, themeData, { isInitialScaffold: true });
|
|
1351
|
+
const refreshResult = await refreshDerivedFiles(projectRoot, essenceV3, registry, themeData, { isInitialScaffold: true, patternSpecs });
|
|
1545
1352
|
contextFiles.push(...refreshResult.contextFiles);
|
|
1546
1353
|
const gitignoreUpdated = updateGitignore(projectRoot);
|
|
1547
1354
|
return {
|
|
@@ -1741,10 +1548,81 @@ When available, use these tools:
|
|
|
1741
1548
|
gitignoreUpdated
|
|
1742
1549
|
};
|
|
1743
1550
|
}
|
|
1551
|
+
async function resolvePatternSpec(name, registry, prefetched, includeExtendedFields = true) {
|
|
1552
|
+
if (prefetched && (prefetched.layout_hints || prefetched.visual_brief || !includeExtendedFields)) {
|
|
1553
|
+
if (!prefetched.components || prefetched.components.length === 0) {
|
|
1554
|
+
const syntheticComps2 = generateSyntheticComponents(name, prefetched.description);
|
|
1555
|
+
if (syntheticComps2.length > 0) prefetched.components = syntheticComps2;
|
|
1556
|
+
}
|
|
1557
|
+
if (!prefetched.slots || Object.keys(prefetched.slots).length === 0) {
|
|
1558
|
+
const synthetic = generateSyntheticSlots(name, prefetched.description);
|
|
1559
|
+
if (Object.keys(synthetic).length > 0) prefetched.slots = synthetic;
|
|
1560
|
+
}
|
|
1561
|
+
return prefetched;
|
|
1562
|
+
}
|
|
1563
|
+
try {
|
|
1564
|
+
const patResult = await registry.fetchPattern(name);
|
|
1565
|
+
if (patResult?.data) {
|
|
1566
|
+
const inner = patResult.data;
|
|
1567
|
+
const defaultPreset = inner.default_preset || "standard";
|
|
1568
|
+
const preset = inner.presets?.[defaultPreset];
|
|
1569
|
+
let slots = preset?.layout?.slots || {};
|
|
1570
|
+
if (Object.keys(slots).length === 0) {
|
|
1571
|
+
const synthetic = generateSyntheticSlots(name, inner.description || "");
|
|
1572
|
+
if (Object.keys(synthetic).length > 0) slots = synthetic;
|
|
1573
|
+
}
|
|
1574
|
+
const spec = {
|
|
1575
|
+
description: inner.description || prefetched?.description || "",
|
|
1576
|
+
components: inner.components || prefetched?.components || [],
|
|
1577
|
+
slots,
|
|
1578
|
+
layout_hints: inner.layout_hints,
|
|
1579
|
+
...includeExtendedFields ? {
|
|
1580
|
+
visual_brief: inner.visual_brief,
|
|
1581
|
+
composition: inner.composition,
|
|
1582
|
+
motion: inner.motion,
|
|
1583
|
+
responsive: inner.responsive,
|
|
1584
|
+
accessibility: inner.accessibility
|
|
1585
|
+
} : {}
|
|
1586
|
+
};
|
|
1587
|
+
if (!spec.components || spec.components.length === 0) {
|
|
1588
|
+
const syntheticComps2 = generateSyntheticComponents(name, spec.description);
|
|
1589
|
+
if (syntheticComps2.length > 0) spec.components = syntheticComps2;
|
|
1590
|
+
}
|
|
1591
|
+
return spec;
|
|
1592
|
+
}
|
|
1593
|
+
} catch {
|
|
1594
|
+
}
|
|
1595
|
+
if (prefetched) {
|
|
1596
|
+
if (!prefetched.components || prefetched.components.length === 0) {
|
|
1597
|
+
const syntheticComps2 = generateSyntheticComponents(name, prefetched.description);
|
|
1598
|
+
if (syntheticComps2.length > 0) prefetched.components = syntheticComps2;
|
|
1599
|
+
}
|
|
1600
|
+
if (!prefetched.slots || Object.keys(prefetched.slots).length === 0) {
|
|
1601
|
+
const synthetic = generateSyntheticSlots(name, prefetched.description);
|
|
1602
|
+
if (Object.keys(synthetic).length > 0) prefetched.slots = synthetic;
|
|
1603
|
+
}
|
|
1604
|
+
return prefetched;
|
|
1605
|
+
}
|
|
1606
|
+
const syntheticSlots = generateSyntheticSlots(name, "");
|
|
1607
|
+
const syntheticComps = generateSyntheticComponents(name, "");
|
|
1608
|
+
if (Object.keys(syntheticSlots).length > 0 || syntheticComps.length > 0) {
|
|
1609
|
+
return { description: "", components: syntheticComps, slots: syntheticSlots };
|
|
1610
|
+
}
|
|
1611
|
+
return null;
|
|
1612
|
+
}
|
|
1744
1613
|
async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThemeData, options) {
|
|
1745
1614
|
const decantrDir = join(projectRoot, ".decantr");
|
|
1746
1615
|
const contextDir = join(decantrDir, "context");
|
|
1747
1616
|
mkdirSync(contextDir, { recursive: true });
|
|
1617
|
+
let storedBlueprintId;
|
|
1618
|
+
const projectJsonFilePath = join(decantrDir, "project.json");
|
|
1619
|
+
if (existsSync(projectJsonFilePath)) {
|
|
1620
|
+
try {
|
|
1621
|
+
const projData = JSON.parse(readFileSync(projectJsonFilePath, "utf-8"));
|
|
1622
|
+
if (projData.blueprintId) storedBlueprintId = projData.blueprintId;
|
|
1623
|
+
} catch {
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1748
1626
|
const themeName = essence.dna.theme.id || essence.dna.theme.style || "default";
|
|
1749
1627
|
const mode = essence.dna.theme.mode;
|
|
1750
1628
|
const guardMode = essence.meta.guard.mode;
|
|
@@ -1862,14 +1740,15 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
|
|
|
1862
1740
|
writeFileSync(decantrMdPath, generateDecantrMdV31({
|
|
1863
1741
|
guardMode,
|
|
1864
1742
|
cssApproach: CSS_APPROACH_CONTENT,
|
|
1865
|
-
blueprintId: essence.meta.blueprint || void 0,
|
|
1743
|
+
blueprintId: storedBlueprintId || essence.meta.blueprint || void 0,
|
|
1866
1744
|
themeName,
|
|
1867
1745
|
themeMode: mode,
|
|
1868
1746
|
themeShape: essence.dna.theme.shape || void 0,
|
|
1869
1747
|
personality,
|
|
1870
1748
|
sections: sectionSummaries.length > 0 ? sectionSummaries : void 0,
|
|
1871
1749
|
features: allFeatures.length > 0 ? allFeatures : void 0,
|
|
1872
|
-
decorators: earlyDecoratorList.length > 0 ? earlyDecoratorList : void 0
|
|
1750
|
+
decorators: earlyDecoratorList.length > 0 ? earlyDecoratorList : void 0,
|
|
1751
|
+
decoratorDefinitions: themeData?.decorator_definitions
|
|
1873
1752
|
}));
|
|
1874
1753
|
const hasSections = essence.blueprint.sections && essence.blueprint.sections.length > 0;
|
|
1875
1754
|
const contextFiles = [];
|
|
@@ -1895,6 +1774,7 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
|
|
|
1895
1774
|
section.shell = primarySectionShell;
|
|
1896
1775
|
}
|
|
1897
1776
|
}
|
|
1777
|
+
const prefetchedSpecs = options?.patternSpecs;
|
|
1898
1778
|
const patternSpecs = {};
|
|
1899
1779
|
const seenPatterns = /* @__PURE__ */ new Set();
|
|
1900
1780
|
for (const section of sections) {
|
|
@@ -1904,49 +1784,8 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
|
|
|
1904
1784
|
for (const name of names) {
|
|
1905
1785
|
if (!seenPatterns.has(name)) {
|
|
1906
1786
|
seenPatterns.add(name);
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
if (patResult?.data) {
|
|
1910
|
-
const inner = patResult.data;
|
|
1911
|
-
const defaultPreset = inner.default_preset || "standard";
|
|
1912
|
-
const preset = inner.presets?.[defaultPreset];
|
|
1913
|
-
let slots = preset?.layout?.slots || {};
|
|
1914
|
-
if (Object.keys(slots).length === 0) {
|
|
1915
|
-
const synthetic = generateSyntheticSlots(name, inner.description || "");
|
|
1916
|
-
if (Object.keys(synthetic).length > 0) {
|
|
1917
|
-
slots = synthetic;
|
|
1918
|
-
}
|
|
1919
|
-
}
|
|
1920
|
-
const spec = {
|
|
1921
|
-
description: inner.description || "",
|
|
1922
|
-
components: inner.components || [],
|
|
1923
|
-
slots,
|
|
1924
|
-
layout_hints: inner.layout_hints,
|
|
1925
|
-
visual_brief: inner.visual_brief,
|
|
1926
|
-
composition: inner.composition,
|
|
1927
|
-
motion: inner.motion,
|
|
1928
|
-
responsive: inner.responsive,
|
|
1929
|
-
accessibility: inner.accessibility
|
|
1930
|
-
};
|
|
1931
|
-
if (!spec.components || spec.components.length === 0) {
|
|
1932
|
-
const syntheticComps = generateSyntheticComponents(name, spec.description);
|
|
1933
|
-
if (syntheticComps.length > 0) spec.components = syntheticComps;
|
|
1934
|
-
}
|
|
1935
|
-
patternSpecs[name] = spec;
|
|
1936
|
-
} else {
|
|
1937
|
-
const synthetic = generateSyntheticSlots(name, "");
|
|
1938
|
-
const syntheticComps = generateSyntheticComponents(name, "");
|
|
1939
|
-
if (Object.keys(synthetic).length > 0 || syntheticComps.length > 0) {
|
|
1940
|
-
patternSpecs[name] = { description: "", components: syntheticComps, slots: synthetic };
|
|
1941
|
-
}
|
|
1942
|
-
}
|
|
1943
|
-
} catch {
|
|
1944
|
-
const synthetic = generateSyntheticSlots(name, "");
|
|
1945
|
-
const syntheticComps = generateSyntheticComponents(name, "");
|
|
1946
|
-
if (Object.keys(synthetic).length > 0 || syntheticComps.length > 0) {
|
|
1947
|
-
patternSpecs[name] = { description: "", components: syntheticComps, slots: synthetic };
|
|
1948
|
-
}
|
|
1949
|
-
}
|
|
1787
|
+
const spec = await resolvePatternSpec(name, registry, prefetchedSpecs?.[name], true);
|
|
1788
|
+
if (spec) patternSpecs[name] = spec;
|
|
1950
1789
|
}
|
|
1951
1790
|
}
|
|
1952
1791
|
}
|
|
@@ -2047,10 +1886,18 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
|
|
|
2047
1886
|
writeFileSync(sectionContextPath, contextContent);
|
|
2048
1887
|
contextFiles.push(sectionContextPath);
|
|
2049
1888
|
}
|
|
1889
|
+
let projectVoice;
|
|
1890
|
+
if (existsSync(projectJsonFilePath)) {
|
|
1891
|
+
try {
|
|
1892
|
+
const projData = JSON.parse(readFileSync(projectJsonFilePath, "utf-8"));
|
|
1893
|
+
if (projData.voice) projectVoice = projData.voice;
|
|
1894
|
+
} catch {
|
|
1895
|
+
}
|
|
1896
|
+
}
|
|
2050
1897
|
const routes = blueprint.routes || {};
|
|
2051
1898
|
const scaffoldContent = generateScaffoldContext({
|
|
2052
1899
|
appName: essence.meta.archetype || "Application",
|
|
2053
|
-
blueprintId: "",
|
|
1900
|
+
blueprintId: storedBlueprintId || essence.meta.blueprint || "",
|
|
2054
1901
|
themeName,
|
|
2055
1902
|
personality,
|
|
2056
1903
|
topologyMarkdown,
|
|
@@ -2058,7 +1905,8 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
|
|
|
2058
1905
|
routes,
|
|
2059
1906
|
constraints: essence.dna.constraints,
|
|
2060
1907
|
seo: essence.meta.seo,
|
|
2061
|
-
navigation: essence.meta.navigation
|
|
1908
|
+
navigation: essence.meta.navigation,
|
|
1909
|
+
voice: projectVoice
|
|
2062
1910
|
});
|
|
2063
1911
|
const scaffoldMdPath = join(contextDir, "scaffold.md");
|
|
2064
1912
|
writeFileSync(scaffoldMdPath, scaffoldContent);
|
|
@@ -2074,6 +1922,7 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
|
|
|
2074
1922
|
description: `${essence.meta.archetype || "Application"} section`,
|
|
2075
1923
|
pages
|
|
2076
1924
|
};
|
|
1925
|
+
const prefetchedSpecs = options?.patternSpecs;
|
|
2077
1926
|
const patternSpecs = {};
|
|
2078
1927
|
const seenPatterns = /* @__PURE__ */ new Set();
|
|
2079
1928
|
for (const page of pages) {
|
|
@@ -2082,44 +1931,8 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
|
|
|
2082
1931
|
for (const name of names) {
|
|
2083
1932
|
if (!seenPatterns.has(name)) {
|
|
2084
1933
|
seenPatterns.add(name);
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
if (patResult?.data) {
|
|
2088
|
-
const inner = patResult.data;
|
|
2089
|
-
const defaultPreset = inner.default_preset || "standard";
|
|
2090
|
-
const preset = inner.presets?.[defaultPreset];
|
|
2091
|
-
let slots = preset?.layout?.slots || {};
|
|
2092
|
-
if (Object.keys(slots).length === 0) {
|
|
2093
|
-
const synthetic = generateSyntheticSlots(name, inner.description || "");
|
|
2094
|
-
if (Object.keys(synthetic).length > 0) {
|
|
2095
|
-
slots = synthetic;
|
|
2096
|
-
}
|
|
2097
|
-
}
|
|
2098
|
-
const spec = {
|
|
2099
|
-
description: inner.description || "",
|
|
2100
|
-
components: inner.components || [],
|
|
2101
|
-
slots,
|
|
2102
|
-
layout_hints: inner.layout_hints
|
|
2103
|
-
};
|
|
2104
|
-
if (!spec.components || spec.components.length === 0) {
|
|
2105
|
-
const syntheticComps = generateSyntheticComponents(name, spec.description);
|
|
2106
|
-
if (syntheticComps.length > 0) spec.components = syntheticComps;
|
|
2107
|
-
}
|
|
2108
|
-
patternSpecs[name] = spec;
|
|
2109
|
-
} else {
|
|
2110
|
-
const synthetic = generateSyntheticSlots(name, "");
|
|
2111
|
-
const syntheticComps = generateSyntheticComponents(name, "");
|
|
2112
|
-
if (Object.keys(synthetic).length > 0 || syntheticComps.length > 0) {
|
|
2113
|
-
patternSpecs[name] = { description: "", components: syntheticComps, slots: synthetic };
|
|
2114
|
-
}
|
|
2115
|
-
}
|
|
2116
|
-
} catch {
|
|
2117
|
-
const synthetic = generateSyntheticSlots(name, "");
|
|
2118
|
-
const syntheticComps = generateSyntheticComponents(name, "");
|
|
2119
|
-
if (Object.keys(synthetic).length > 0 || syntheticComps.length > 0) {
|
|
2120
|
-
patternSpecs[name] = { description: "", components: syntheticComps, slots: synthetic };
|
|
2121
|
-
}
|
|
2122
|
-
}
|
|
1934
|
+
const spec = await resolvePatternSpec(name, registry, prefetchedSpecs?.[name], false);
|
|
1935
|
+
if (spec) patternSpecs[name] = spec;
|
|
2123
1936
|
}
|
|
2124
1937
|
}
|
|
2125
1938
|
}
|
|
@@ -2306,7 +2119,8 @@ function generateSectionContext(input) {
|
|
|
2306
2119
|
text: "Body text, headings, primary content",
|
|
2307
2120
|
"text-muted": "Secondary text, placeholders, labels",
|
|
2308
2121
|
primary: "Brand color, key interactive, selected states",
|
|
2309
|
-
"primary-hover": "Hover state for primary elements"
|
|
2122
|
+
"primary-hover": "Hover state for primary elements",
|
|
2123
|
+
secondary: "Secondary brand color, supporting elements"
|
|
2310
2124
|
};
|
|
2311
2125
|
if (input.themeData?.palette) {
|
|
2312
2126
|
const modeKey = input.themeMode || "dark";
|
|
@@ -2317,12 +2131,36 @@ function generateSectionContext(input) {
|
|
|
2317
2131
|
}
|
|
2318
2132
|
if (input.themeData?.seed?.accent) {
|
|
2319
2133
|
lines.push(`| \`--d-accent\` | \`${input.themeData.seed.accent}\` | CTAs, links, active states, glow effects |`);
|
|
2134
|
+
const accentGlowVal = input.themeData?.palette?.["accent-glow"]?.[input.themeMode || "dark"] || input.themeData?.tokens?.base?.["accent-glow"];
|
|
2135
|
+
if (accentGlowVal) {
|
|
2136
|
+
lines.push(`| \`--d-accent-glow\` | \`${accentGlowVal}\` | Ambient glow effect around accent elements |`);
|
|
2137
|
+
}
|
|
2320
2138
|
}
|
|
2321
2139
|
lines.push("");
|
|
2322
2140
|
lines.push("Full token set: `src/styles/tokens.css`");
|
|
2323
2141
|
lines.push("");
|
|
2324
2142
|
lines.push("**Visual Treatments:** All 6 base treatments available (see DECANTR.md for usage).");
|
|
2325
|
-
|
|
2143
|
+
const decoratorDefs = input.themeData?.decorator_definitions;
|
|
2144
|
+
if (decoratorDefs && Object.keys(decoratorDefs).length > 0) {
|
|
2145
|
+
lines.push("**Theme decorators:**");
|
|
2146
|
+
lines.push("");
|
|
2147
|
+
lines.push("| Class | Intent | Key CSS | Pairs with |");
|
|
2148
|
+
lines.push("|-------|--------|---------|------------|");
|
|
2149
|
+
for (const [name, def] of Object.entries(decoratorDefs)) {
|
|
2150
|
+
const intent = def.intent || "";
|
|
2151
|
+
const cssProps = def.css ? Object.entries(def.css).map(([p, v]) => `${p}: ${v}`).join("; ") : "";
|
|
2152
|
+
const pairsWith = def.pairs_with || "";
|
|
2153
|
+
lines.push(`| \`.${name}\` | ${intent} | ${cssProps} | ${pairsWith} |`);
|
|
2154
|
+
}
|
|
2155
|
+
lines.push("");
|
|
2156
|
+
lines.push("**Decorator usage guide:**");
|
|
2157
|
+
for (const [name, def] of Object.entries(decoratorDefs)) {
|
|
2158
|
+
if (def.usage && def.usage.length > 0) {
|
|
2159
|
+
lines.push(`- \`.${name}\`: ${def.usage.join(", ")}`);
|
|
2160
|
+
}
|
|
2161
|
+
}
|
|
2162
|
+
lines.push("");
|
|
2163
|
+
} else if (decorators.length > 0) {
|
|
2326
2164
|
lines.push("**Theme decorators:**");
|
|
2327
2165
|
lines.push("");
|
|
2328
2166
|
lines.push("| Class | Usage |");
|
|
@@ -2332,12 +2170,16 @@ function generateSectionContext(input) {
|
|
|
2332
2170
|
}
|
|
2333
2171
|
lines.push("");
|
|
2334
2172
|
} else {
|
|
2335
|
-
lines.push("
|
|
2173
|
+
lines.push("No theme decorators defined.");
|
|
2336
2174
|
lines.push("");
|
|
2337
2175
|
}
|
|
2338
2176
|
if (themeHints) {
|
|
2339
2177
|
if (themeHints.preferred && themeHints.preferred.length > 0) {
|
|
2340
|
-
|
|
2178
|
+
const sectionPatterns = new Set(section.pages.flatMap((p) => p.layout.map((l) => typeof l === "string" ? l : l.pattern)));
|
|
2179
|
+
const relevant = themeHints.preferred.filter((p) => sectionPatterns.has(p));
|
|
2180
|
+
if (relevant.length > 0) {
|
|
2181
|
+
lines.push(`**Preferred:** ${relevant.join(", ")}`);
|
|
2182
|
+
}
|
|
2341
2183
|
}
|
|
2342
2184
|
if (themeHints.compositions) {
|
|
2343
2185
|
lines.push(`**Compositions:** ${themeHints.compositions}`);
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
scaffoldMinimal,
|
|
10
10
|
scaffoldProject,
|
|
11
11
|
syncRegistry
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-5MKMLONH.js";
|
|
13
13
|
|
|
14
14
|
// src/index.ts
|
|
15
15
|
import { readFileSync as readFileSync15, existsSync as existsSync23, readdirSync as readdirSync6 } from "fs";
|
|
@@ -4332,7 +4332,7 @@ async function main() {
|
|
|
4332
4332
|
break;
|
|
4333
4333
|
}
|
|
4334
4334
|
case "upgrade": {
|
|
4335
|
-
const { cmdUpgrade } = await import("./upgrade-
|
|
4335
|
+
const { cmdUpgrade } = await import("./upgrade-3AAWHJGG.js");
|
|
4336
4336
|
const applyFlag = args.includes("--apply");
|
|
4337
4337
|
await cmdUpgrade(process.cwd(), { apply: applyFlag });
|
|
4338
4338
|
break;
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import "./chunk-
|
|
2
|
-
import "./chunk-
|
|
1
|
+
import "./chunk-HWMN432I.js";
|
|
2
|
+
import "./chunk-5MKMLONH.js";
|