@decantr/cli 1.6.2 → 1.6.4
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 +2 -2
- package/dist/{chunk-7QOXORFL.js → chunk-AFX57QLI.js} +103 -26
- package/dist/{chunk-TL5VMEPJ.js → chunk-NH3YWDNG.js} +2 -2
- package/dist/index.js +2 -2
- package/dist/{upgrade-PKKLUMFJ.js → upgrade-74OUB65K.js} +1 -1
- package/package.json +1 -1
- package/src/templates/task-modify.md.template +3 -4
package/dist/bin.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "./chunk-
|
|
3
|
-
import "./chunk-
|
|
2
|
+
import "./chunk-NH3YWDNG.js";
|
|
3
|
+
import "./chunk-AFX57QLI.js";
|
|
@@ -13,6 +13,8 @@ function generateTreatmentCSS(spatialTokens, treatmentOverrides, themeDecorators
|
|
|
13
13
|
lines.push("");
|
|
14
14
|
lines.push("/* \u2500\u2500 Layer 1: Base Treatments \u2500\u2500 */");
|
|
15
15
|
lines.push("");
|
|
16
|
+
const THEME_ONLY_PROPS = /* @__PURE__ */ new Set(["backdrop-filter", "-webkit-backdrop-filter"]);
|
|
17
|
+
const themeOverrideRules = [];
|
|
16
18
|
function emitRule(selector, props) {
|
|
17
19
|
const treatmentName = selector.replace(/^\./, "").replace(/[:[\s].+$/, "");
|
|
18
20
|
const overrides = treatmentOverrides?.[treatmentName];
|
|
@@ -21,8 +23,20 @@ function generateTreatmentCSS(spatialTokens, treatmentOverrides, themeDecorators
|
|
|
21
23
|
merged.set(prop, val);
|
|
22
24
|
}
|
|
23
25
|
if (overrides && selector === `.${treatmentName}`) {
|
|
26
|
+
const themeProps = [];
|
|
24
27
|
for (const [prop, val] of Object.entries(overrides)) {
|
|
25
|
-
|
|
28
|
+
if (THEME_ONLY_PROPS.has(prop)) {
|
|
29
|
+
themeProps.push([prop, val]);
|
|
30
|
+
} else {
|
|
31
|
+
merged.set(prop, val);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (themeProps.length > 0 && themeName) {
|
|
35
|
+
const themeSelector = `[data-theme="${themeName}"] ${selector}`;
|
|
36
|
+
const themeBody = themeProps.map(([p, v]) => ` ${p}: ${v};`).join("\n");
|
|
37
|
+
themeOverrideRules.push(`${themeSelector} {
|
|
38
|
+
${themeBody}
|
|
39
|
+
}`);
|
|
26
40
|
}
|
|
27
41
|
}
|
|
28
42
|
const body = Array.from(merged.entries()).map(([p, v]) => ` ${p}: ${v};`).join("\n");
|
|
@@ -204,13 +218,16 @@ function generateTreatmentCSS(spatialTokens, treatmentOverrides, themeDecorators
|
|
|
204
218
|
["color", "var(--d-text-muted)"],
|
|
205
219
|
["font-family", "var(--d-font-mono, ui-monospace, monospace)"]
|
|
206
220
|
]);
|
|
221
|
+
if (themeOverrideRules.length > 0) {
|
|
222
|
+
lines.push("/* \u2500\u2500 Theme-scoped Treatment Overrides \u2500\u2500 */");
|
|
223
|
+
lines.push("");
|
|
224
|
+
for (const rule of themeOverrideRules) {
|
|
225
|
+
lines.push(rule);
|
|
226
|
+
lines.push("");
|
|
227
|
+
}
|
|
228
|
+
}
|
|
207
229
|
lines.push("/* \u2500\u2500 Keyframes \u2500\u2500 */");
|
|
208
230
|
lines.push("");
|
|
209
|
-
lines.push("@keyframes decantr-fade-in {");
|
|
210
|
-
lines.push(" from { opacity: 0; transform: translateY(4px); }");
|
|
211
|
-
lines.push(" to { opacity: 1; transform: translateY(0); }");
|
|
212
|
-
lines.push("}");
|
|
213
|
-
lines.push("");
|
|
214
231
|
lines.push("@keyframes decantr-pulse {");
|
|
215
232
|
lines.push(" 0%, 100% { opacity: 1; }");
|
|
216
233
|
lines.push(" 50% { opacity: 0.5; }");
|
|
@@ -245,6 +262,7 @@ function generatePersonalityCSS(personality, themeData) {
|
|
|
245
262
|
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); }`);
|
|
246
263
|
rules.push(`.status-ring[data-status="warning"] { border-color: var(--d-warning); }`);
|
|
247
264
|
rules.push(`.status-ring[data-status="idle"] { border-color: var(--d-text-muted); }`);
|
|
265
|
+
rules.push(`.status-ring[data-status="processing"] { border-color: var(--d-primary); }`);
|
|
248
266
|
rules.push(`@keyframes pulse-ring { 0% { opacity: 0.6; transform: scale(1); } 100% { opacity: 0; transform: scale(1.3); } }`);
|
|
249
267
|
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; }`);
|
|
250
268
|
}
|
|
@@ -474,14 +492,15 @@ function generateTopologySection(data, personality) {
|
|
|
474
492
|
lines.push("");
|
|
475
493
|
lines.push("### Zones");
|
|
476
494
|
lines.push("");
|
|
495
|
+
if (personality.length > 0) {
|
|
496
|
+
lines.push(`**Personality:** ${personality.join(", ")}`);
|
|
497
|
+
lines.push("");
|
|
498
|
+
}
|
|
477
499
|
for (const zone of data.zones) {
|
|
478
500
|
const label = ZONE_LABELS[zone.role] || zone.role;
|
|
479
501
|
lines.push(`**${label}** \u2014 ${zone.shell} shell`);
|
|
480
502
|
lines.push(` Archetypes: ${zone.archetypes.join(", ")}`);
|
|
481
503
|
lines.push(` Purpose: ${zone.descriptions.join(" ")}`);
|
|
482
|
-
if (personality.length > 0) {
|
|
483
|
-
lines.push(` Tone: ${personality.join(", ")}`);
|
|
484
|
-
}
|
|
485
504
|
if (zone.features.length > 0) {
|
|
486
505
|
lines.push(` Features: ${zone.features.join(", ")}`);
|
|
487
506
|
}
|
|
@@ -532,7 +551,7 @@ function generateTokensCSS(themeData, mode, spatialTokens) {
|
|
|
532
551
|
return {
|
|
533
552
|
// Seed colors
|
|
534
553
|
"--d-primary": seed.primary || "#6366f1",
|
|
535
|
-
"--d-secondary": seed.secondary || "#
|
|
554
|
+
"--d-secondary": palette.secondary?.[tokenMode] || palette.secondary?.dark || seed.secondary || "#A1A1AA",
|
|
536
555
|
"--d-accent": seed.accent || "#f59e0b",
|
|
537
556
|
// Palette colors (mode-aware)
|
|
538
557
|
"--d-bg": palette.background?.[tokenMode] || "#18181b",
|
|
@@ -1127,10 +1146,8 @@ function generateDecantrMdV31(params) {
|
|
|
1127
1146
|
briefLines.push("## Project Brief");
|
|
1128
1147
|
briefLines.push("");
|
|
1129
1148
|
briefLines.push(`- **Blueprint:** ${params.blueprintId || "custom"}`);
|
|
1130
|
-
const
|
|
1131
|
-
|
|
1132
|
-
if (params.themeShape) themeParts.push(params.themeShape);
|
|
1133
|
-
briefLines.push(`- **Theme:** ${themeParts.join(" (").replace(/ \($/, "") + (themeParts.length > 1 ? ")" : "")}`);
|
|
1149
|
+
const themeDesc = `${params.themeName || "default"} (${params.themeMode || "dark"} mode${params.themeShape ? `, ${params.themeShape} shape` : ""})`;
|
|
1150
|
+
briefLines.push(`- **Theme:** ${themeDesc}`);
|
|
1134
1151
|
if (params.personality && params.personality.length > 0) {
|
|
1135
1152
|
briefLines.push(`- **Personality:** ${params.personality.join(". ")}`);
|
|
1136
1153
|
}
|
|
@@ -1197,6 +1214,9 @@ function generateProjectJson(detected, options, registrySource) {
|
|
|
1197
1214
|
flags: buildFlagsString(options)
|
|
1198
1215
|
}
|
|
1199
1216
|
};
|
|
1217
|
+
if (options.blueprint) {
|
|
1218
|
+
data.blueprintId = options.blueprint;
|
|
1219
|
+
}
|
|
1200
1220
|
return JSON.stringify(data, null, 2);
|
|
1201
1221
|
}
|
|
1202
1222
|
function buildFlagsString(options) {
|
|
@@ -1209,13 +1229,21 @@ function buildFlagsString(options) {
|
|
|
1209
1229
|
}
|
|
1210
1230
|
function generateTaskContextV3(templateName, essence) {
|
|
1211
1231
|
const template = loadTemplate(templateName);
|
|
1212
|
-
const
|
|
1213
|
-
const
|
|
1232
|
+
const sections = essence.blueprint.sections && essence.blueprint.sections.length > 0 ? essence.blueprint.sections : [];
|
|
1233
|
+
const pages = sections.length > 0 ? sections.flatMap((s) => s.pages) : essence.blueprint.pages || [];
|
|
1234
|
+
const defaultShell = sections[0]?.shell || essence.blueprint.shell || "sidebar-main";
|
|
1214
1235
|
const layout = pages[0]?.layout?.map(serializeLayoutItem).join(", ") || "none";
|
|
1236
|
+
const pageShellMap = /* @__PURE__ */ new Map();
|
|
1237
|
+
for (const s of sections) {
|
|
1238
|
+
for (const p of s.pages) {
|
|
1239
|
+
pageShellMap.set(p.id, s.shell);
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1215
1242
|
const scaffoldStructure = pages.map((p) => {
|
|
1243
|
+
const shell = pageShellMap.get(p.id) || defaultShell;
|
|
1216
1244
|
const patterns = p.layout.length > 0 ? `
|
|
1217
1245
|
- Patterns: ${p.layout.map(serializeLayoutItem).join(", ")}` : "";
|
|
1218
|
-
return `- **${p.id}** (${
|
|
1246
|
+
return `- **${p.id}** (${shell})${patterns}`;
|
|
1219
1247
|
}).join("\n");
|
|
1220
1248
|
const densityLevel = essence.dna.spacing?.density || "comfortable";
|
|
1221
1249
|
const contentGap = essence.dna.spacing?.content_gap || "_gap4";
|
|
@@ -1307,7 +1335,12 @@ async function scaffoldProject(projectRoot, options, detected, registry, archety
|
|
|
1307
1335
|
const essencePath = join(projectRoot, "decantr.essence.json");
|
|
1308
1336
|
writeFileSync(essencePath, JSON.stringify(essenceV3, null, 2) + "\n");
|
|
1309
1337
|
const projectJsonPath = join(decantrDir, "project.json");
|
|
1310
|
-
|
|
1338
|
+
const projectJsonStr = generateProjectJson(detected, options, registrySource);
|
|
1339
|
+
const projectJsonObj = JSON.parse(projectJsonStr);
|
|
1340
|
+
if (blueprintData?.voice) {
|
|
1341
|
+
projectJsonObj.voice = blueprintData.voice;
|
|
1342
|
+
}
|
|
1343
|
+
writeFileSync(projectJsonPath, JSON.stringify(projectJsonObj, null, 2));
|
|
1311
1344
|
const contextFiles = [];
|
|
1312
1345
|
const scaffoldPath = join(contextDir, "task-scaffold.md");
|
|
1313
1346
|
writeFileSync(scaffoldPath, generateTaskContextV3("task-scaffold.md.template", essenceV3));
|
|
@@ -1599,6 +1632,32 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
|
|
|
1599
1632
|
const decantrDir = join(projectRoot, ".decantr");
|
|
1600
1633
|
const contextDir = join(decantrDir, "context");
|
|
1601
1634
|
mkdirSync(contextDir, { recursive: true });
|
|
1635
|
+
let storedBlueprintId;
|
|
1636
|
+
let storedVoice;
|
|
1637
|
+
const projectJsonFilePath = join(decantrDir, "project.json");
|
|
1638
|
+
let projectJsonData = {};
|
|
1639
|
+
if (existsSync(projectJsonFilePath)) {
|
|
1640
|
+
try {
|
|
1641
|
+
projectJsonData = JSON.parse(readFileSync(projectJsonFilePath, "utf-8"));
|
|
1642
|
+
if (projectJsonData.blueprintId) storedBlueprintId = projectJsonData.blueprintId;
|
|
1643
|
+
if (projectJsonData.voice) storedVoice = projectJsonData.voice;
|
|
1644
|
+
} catch {
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
if (!storedVoice && storedBlueprintId) {
|
|
1648
|
+
try {
|
|
1649
|
+
const bpResult = await registry.fetchBlueprint(storedBlueprintId);
|
|
1650
|
+
if (bpResult?.data) {
|
|
1651
|
+
const bpData = bpResult.data;
|
|
1652
|
+
if (bpData.voice) {
|
|
1653
|
+
storedVoice = bpData.voice;
|
|
1654
|
+
projectJsonData.voice = bpData.voice;
|
|
1655
|
+
writeFileSync(projectJsonFilePath, JSON.stringify(projectJsonData, null, 2));
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
} catch {
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1602
1661
|
const themeName = essence.dna.theme.id || essence.dna.theme.style || "default";
|
|
1603
1662
|
const mode = essence.dna.theme.mode;
|
|
1604
1663
|
const guardMode = essence.meta.guard.mode;
|
|
@@ -1716,7 +1775,7 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
|
|
|
1716
1775
|
writeFileSync(decantrMdPath, generateDecantrMdV31({
|
|
1717
1776
|
guardMode,
|
|
1718
1777
|
cssApproach: CSS_APPROACH_CONTENT,
|
|
1719
|
-
blueprintId: essence.meta.blueprint || void 0,
|
|
1778
|
+
blueprintId: storedBlueprintId || essence.meta.blueprint || void 0,
|
|
1720
1779
|
themeName,
|
|
1721
1780
|
themeMode: mode,
|
|
1722
1781
|
themeShape: essence.dna.theme.shape || void 0,
|
|
@@ -1865,7 +1924,7 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
|
|
|
1865
1924
|
const routes = blueprint.routes || {};
|
|
1866
1925
|
const scaffoldContent = generateScaffoldContext({
|
|
1867
1926
|
appName: essence.meta.archetype || "Application",
|
|
1868
|
-
blueprintId: "",
|
|
1927
|
+
blueprintId: storedBlueprintId || essence.meta.blueprint || "",
|
|
1869
1928
|
themeName,
|
|
1870
1929
|
personality,
|
|
1871
1930
|
topologyMarkdown,
|
|
@@ -1873,7 +1932,8 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
|
|
|
1873
1932
|
routes,
|
|
1874
1933
|
constraints: essence.dna.constraints,
|
|
1875
1934
|
seo: essence.meta.seo,
|
|
1876
|
-
navigation: essence.meta.navigation
|
|
1935
|
+
navigation: essence.meta.navigation,
|
|
1936
|
+
voice: storedVoice
|
|
1877
1937
|
});
|
|
1878
1938
|
const scaffoldMdPath = join(contextDir, "scaffold.md");
|
|
1879
1939
|
writeFileSync(scaffoldMdPath, scaffoldContent);
|
|
@@ -2086,18 +2146,31 @@ function generateSectionContext(input) {
|
|
|
2086
2146
|
text: "Body text, headings, primary content",
|
|
2087
2147
|
"text-muted": "Secondary text, placeholders, labels",
|
|
2088
2148
|
primary: "Brand color, key interactive, selected states",
|
|
2089
|
-
"primary-hover": "Hover state for primary elements"
|
|
2149
|
+
"primary-hover": "Hover state for primary elements",
|
|
2150
|
+
secondary: "Secondary brand color, supporting elements"
|
|
2090
2151
|
};
|
|
2152
|
+
const addedTokens = /* @__PURE__ */ new Set();
|
|
2091
2153
|
if (input.themeData?.palette) {
|
|
2092
2154
|
const modeKey = input.themeMode || "dark";
|
|
2093
2155
|
for (const [name, values] of Object.entries(input.themeData.palette)) {
|
|
2094
|
-
|
|
2095
|
-
|
|
2156
|
+
if (!addedTokens.has(name)) {
|
|
2157
|
+
addedTokens.add(name);
|
|
2158
|
+
const val = values[modeKey] || values.dark || values.light || Object.values(values)[0];
|
|
2159
|
+
lines.push(`| \`--d-${name}\` | \`${val}\` | ${semanticRoles[name] || ""} |`);
|
|
2160
|
+
}
|
|
2096
2161
|
}
|
|
2097
2162
|
}
|
|
2098
|
-
if (input.themeData?.seed?.accent) {
|
|
2163
|
+
if (input.themeData?.seed?.accent && !addedTokens.has("accent")) {
|
|
2164
|
+
addedTokens.add("accent");
|
|
2099
2165
|
lines.push(`| \`--d-accent\` | \`${input.themeData.seed.accent}\` | CTAs, links, active states, glow effects |`);
|
|
2100
2166
|
}
|
|
2167
|
+
if (!addedTokens.has("accent-glow")) {
|
|
2168
|
+
const accentGlowVal = input.themeData?.palette?.["accent-glow"]?.[input.themeMode || "dark"] || input.themeData?.tokens?.base?.["accent-glow"];
|
|
2169
|
+
if (accentGlowVal) {
|
|
2170
|
+
addedTokens.add("accent-glow");
|
|
2171
|
+
lines.push(`| \`--d-accent-glow\` | \`${accentGlowVal}\` | Ambient glow effect around accent elements |`);
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2101
2174
|
lines.push("");
|
|
2102
2175
|
lines.push("Full token set: `src/styles/tokens.css`");
|
|
2103
2176
|
lines.push("");
|
|
@@ -2137,7 +2210,11 @@ function generateSectionContext(input) {
|
|
|
2137
2210
|
}
|
|
2138
2211
|
if (themeHints) {
|
|
2139
2212
|
if (themeHints.preferred && themeHints.preferred.length > 0) {
|
|
2140
|
-
|
|
2213
|
+
const sectionPatterns = new Set(section.pages.flatMap((p) => p.layout.map((l) => typeof l === "string" ? l : l.pattern)));
|
|
2214
|
+
const relevant = themeHints.preferred.filter((p) => sectionPatterns.has(p));
|
|
2215
|
+
if (relevant.length > 0) {
|
|
2216
|
+
lines.push(`**Preferred:** ${relevant.join(", ")}`);
|
|
2217
|
+
}
|
|
2141
2218
|
}
|
|
2142
2219
|
if (themeHints.compositions) {
|
|
2143
2220
|
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-AFX57QLI.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-74OUB65K.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-NH3YWDNG.js";
|
|
2
|
+
import "./chunk-AFX57QLI.js";
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**Enforcement Tier: Strict**
|
|
4
4
|
|
|
5
|
-
You are modifying existing code in a Decantr project. ALL
|
|
5
|
+
You are modifying existing code in a Decantr project. ALL 7 guard rules are enforced exactly.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -16,7 +16,7 @@ You are modifying existing code in a Decantr project. ALL 8 guard rules are enfo
|
|
|
16
16
|
| 4 | DNA | **Theme-mode** | STRICT | ERROR — Code rejected |
|
|
17
17
|
| 5 | Blueprint | **Structure** | STRICT | ERROR — Code rejected |
|
|
18
18
|
| 6 | Blueprint | **Layout** | STRICT | ERROR — Pattern order must match exactly |
|
|
19
|
-
|
|
|
19
|
+
| 7 | Blueprint | **Pattern-exists** | STRICT | ERROR — Code rejected |
|
|
20
20
|
|
|
21
21
|
## Violation Response Protocol
|
|
22
22
|
|
|
@@ -90,9 +90,8 @@ Before writing code:
|
|
|
90
90
|
Before modifying:
|
|
91
91
|
|
|
92
92
|
- [ ] Page exists in essence structure
|
|
93
|
-
- [ ] I know the
|
|
93
|
+
- [ ] I know the layout order for the target page (check `blueprint.pages[]` or `blueprint.sections[]`)
|
|
94
94
|
- [ ] I will use theme: `{{THEME_STYLE}}`
|
|
95
|
-
- [ ] I will use theme: `{{THEME_RECIPE}}`
|
|
96
95
|
- [ ] I will follow density: `{{DENSITY}}`
|
|
97
96
|
|
|
98
97
|
During modification:
|