@decantr/cli 1.6.3 → 1.6.5
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-5MKMLONH.js → chunk-GSRPDFXK.js} +61 -25
- package/dist/{chunk-HWMN432I.js → chunk-MEW5X6AP.js} +2 -2
- package/dist/index.js +2 -2
- package/dist/{upgrade-3AAWHJGG.js → upgrade-WPC7QPXX.js} +1 -1
- package/package.json +1 -1
- package/src/templates/task-add-page.md.template +16 -11
- 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-MEW5X6AP.js";
|
|
3
|
+
import "./chunk-GSRPDFXK.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,7 +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); }`);
|
|
248
|
-
rules.push(`.status-ring[data-status="processing"] { border-color: var(--d-primary); }`);
|
|
265
|
+
rules.push(`.status-ring[data-status="processing"] { border-color: var(--d-primary); animation: pulse-ring 2s ease-in-out infinite; }`);
|
|
249
266
|
rules.push(`@keyframes pulse-ring { 0% { opacity: 0.6; transform: scale(1); } 100% { opacity: 0; transform: scale(1.3); } }`);
|
|
250
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; }`);
|
|
251
268
|
}
|
|
@@ -480,9 +497,6 @@ function generateTopologySection(data, personality) {
|
|
|
480
497
|
lines.push(`**${label}** \u2014 ${zone.shell} shell`);
|
|
481
498
|
lines.push(` Archetypes: ${zone.archetypes.join(", ")}`);
|
|
482
499
|
lines.push(` Purpose: ${zone.descriptions.join(" ")}`);
|
|
483
|
-
if (personality.length > 0) {
|
|
484
|
-
lines.push(` Tone: ${personality.join(", ")}`);
|
|
485
|
-
}
|
|
486
500
|
if (zone.features.length > 0) {
|
|
487
501
|
lines.push(` Features: ${zone.features.join(", ")}`);
|
|
488
502
|
}
|
|
@@ -1615,11 +1629,28 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
|
|
|
1615
1629
|
const contextDir = join(decantrDir, "context");
|
|
1616
1630
|
mkdirSync(contextDir, { recursive: true });
|
|
1617
1631
|
let storedBlueprintId;
|
|
1632
|
+
let storedVoice;
|
|
1618
1633
|
const projectJsonFilePath = join(decantrDir, "project.json");
|
|
1634
|
+
let projectJsonData = {};
|
|
1619
1635
|
if (existsSync(projectJsonFilePath)) {
|
|
1620
1636
|
try {
|
|
1621
|
-
|
|
1622
|
-
if (
|
|
1637
|
+
projectJsonData = JSON.parse(readFileSync(projectJsonFilePath, "utf-8"));
|
|
1638
|
+
if (projectJsonData.blueprintId) storedBlueprintId = projectJsonData.blueprintId;
|
|
1639
|
+
if (projectJsonData.voice) storedVoice = projectJsonData.voice;
|
|
1640
|
+
} catch {
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
if (!storedVoice && storedBlueprintId) {
|
|
1644
|
+
try {
|
|
1645
|
+
const bpResult = await registry.fetchBlueprint(storedBlueprintId);
|
|
1646
|
+
if (bpResult?.data) {
|
|
1647
|
+
const bpData = bpResult.data;
|
|
1648
|
+
if (bpData.voice) {
|
|
1649
|
+
storedVoice = bpData.voice;
|
|
1650
|
+
projectJsonData.voice = bpData.voice;
|
|
1651
|
+
writeFileSync(projectJsonFilePath, JSON.stringify(projectJsonData, null, 2));
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1623
1654
|
} catch {
|
|
1624
1655
|
}
|
|
1625
1656
|
}
|
|
@@ -1886,14 +1917,6 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
|
|
|
1886
1917
|
writeFileSync(sectionContextPath, contextContent);
|
|
1887
1918
|
contextFiles.push(sectionContextPath);
|
|
1888
1919
|
}
|
|
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
|
-
}
|
|
1897
1920
|
const routes = blueprint.routes || {};
|
|
1898
1921
|
const scaffoldContent = generateScaffoldContext({
|
|
1899
1922
|
appName: essence.meta.archetype || "Application",
|
|
@@ -1906,7 +1929,7 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
|
|
|
1906
1929
|
constraints: essence.dna.constraints,
|
|
1907
1930
|
seo: essence.meta.seo,
|
|
1908
1931
|
navigation: essence.meta.navigation,
|
|
1909
|
-
voice:
|
|
1932
|
+
voice: storedVoice
|
|
1910
1933
|
});
|
|
1911
1934
|
const scaffoldMdPath = join(contextDir, "scaffold.md");
|
|
1912
1935
|
writeFileSync(scaffoldMdPath, scaffoldContent);
|
|
@@ -2120,19 +2143,32 @@ function generateSectionContext(input) {
|
|
|
2120
2143
|
"text-muted": "Secondary text, placeholders, labels",
|
|
2121
2144
|
primary: "Brand color, key interactive, selected states",
|
|
2122
2145
|
"primary-hover": "Hover state for primary elements",
|
|
2123
|
-
secondary: "Secondary brand color, supporting elements"
|
|
2146
|
+
secondary: "Secondary brand color, supporting elements",
|
|
2147
|
+
"accent-glow": "Ambient glow effect for accent-colored elements"
|
|
2148
|
+
};
|
|
2149
|
+
const paletteToTokenName = {
|
|
2150
|
+
"background": "bg"
|
|
2124
2151
|
};
|
|
2152
|
+
const addedTokens = /* @__PURE__ */ new Set();
|
|
2125
2153
|
if (input.themeData?.palette) {
|
|
2126
2154
|
const modeKey = input.themeMode || "dark";
|
|
2127
2155
|
for (const [name, values] of Object.entries(input.themeData.palette)) {
|
|
2128
|
-
|
|
2129
|
-
|
|
2156
|
+
if (!addedTokens.has(name)) {
|
|
2157
|
+
addedTokens.add(name);
|
|
2158
|
+
const tokenName = paletteToTokenName[name] || name;
|
|
2159
|
+
const val = values[modeKey] || values.dark || values.light || Object.values(values)[0];
|
|
2160
|
+
lines.push(`| \`--d-${tokenName}\` | \`${val}\` | ${semanticRoles[name] || ""} |`);
|
|
2161
|
+
}
|
|
2130
2162
|
}
|
|
2131
2163
|
}
|
|
2132
|
-
if (input.themeData?.seed?.accent) {
|
|
2164
|
+
if (input.themeData?.seed?.accent && !addedTokens.has("accent")) {
|
|
2165
|
+
addedTokens.add("accent");
|
|
2133
2166
|
lines.push(`| \`--d-accent\` | \`${input.themeData.seed.accent}\` | CTAs, links, active states, glow effects |`);
|
|
2167
|
+
}
|
|
2168
|
+
if (!addedTokens.has("accent-glow")) {
|
|
2134
2169
|
const accentGlowVal = input.themeData?.palette?.["accent-glow"]?.[input.themeMode || "dark"] || input.themeData?.tokens?.base?.["accent-glow"];
|
|
2135
2170
|
if (accentGlowVal) {
|
|
2171
|
+
addedTokens.add("accent-glow");
|
|
2136
2172
|
lines.push(`| \`--d-accent-glow\` | \`${accentGlowVal}\` | Ambient glow effect around accent elements |`);
|
|
2137
2173
|
}
|
|
2138
2174
|
}
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
scaffoldMinimal,
|
|
10
10
|
scaffoldProject,
|
|
11
11
|
syncRegistry
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-GSRPDFXK.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-WPC7QPXX.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-MEW5X6AP.js";
|
|
2
|
+
import "./chunk-GSRPDFXK.js";
|
package/package.json
CHANGED
|
@@ -16,23 +16,28 @@ You are adding new pages or features to an existing Decantr project. Guided mode
|
|
|
16
16
|
| 4 | DNA | **Theme-mode** | ENFORCED | Theme/mode combination must be compatible |
|
|
17
17
|
| 5 | Blueprint | **Structure** | ENFORCED | Page MUST exist in essence before generating code |
|
|
18
18
|
| 6 | Blueprint | Layout | advisory | Pattern order is flexible |
|
|
19
|
-
|
|
|
19
|
+
| 7 | Blueprint | **Pattern-exists** | ENFORCED | All patterns must exist in the registry |
|
|
20
20
|
|
|
21
21
|
## Before You Start
|
|
22
22
|
|
|
23
23
|
### 1. Update the Essence
|
|
24
24
|
|
|
25
|
-
Before generating code for a new page, add it to the essence:
|
|
25
|
+
Before generating code for a new page, add it to the relevant section in the essence:
|
|
26
26
|
|
|
27
27
|
```json
|
|
28
28
|
{
|
|
29
29
|
"blueprint": {
|
|
30
|
-
"
|
|
31
|
-
"pages": [
|
|
32
|
-
// ... existing pages ...
|
|
30
|
+
"sections": [
|
|
33
31
|
{
|
|
34
|
-
"id": "
|
|
35
|
-
"
|
|
32
|
+
"id": "section-id",
|
|
33
|
+
"shell": "{{DEFAULT_SHELL}}",
|
|
34
|
+
"pages": [
|
|
35
|
+
// ... existing pages ...
|
|
36
|
+
{
|
|
37
|
+
"id": "new-page-id",
|
|
38
|
+
"layout": ["pattern-1", "pattern-2"]
|
|
39
|
+
}
|
|
40
|
+
]
|
|
36
41
|
}
|
|
37
42
|
]
|
|
38
43
|
}
|
|
@@ -55,8 +60,8 @@ Only after the page exists in the essence should you generate code for it.
|
|
|
55
60
|
|
|
56
61
|
Before adding a page:
|
|
57
62
|
|
|
58
|
-
- [ ] The page ID is added to `blueprint.pages[]` in essence
|
|
59
|
-
- [ ] The
|
|
63
|
+
- [ ] The page ID is added to the target `blueprint.sections[].pages[]` in essence
|
|
64
|
+
- [ ] The section has a `shell` defined
|
|
60
65
|
- [ ] The page has a `layout[]` with pattern IDs
|
|
61
66
|
- [ ] Validation passes (`npx @decantr/cli validate`)
|
|
62
67
|
|
|
@@ -64,7 +69,7 @@ During code generation:
|
|
|
64
69
|
|
|
65
70
|
- [ ] Use theme `{{THEME_STYLE}}` for all styling
|
|
66
71
|
- [ ] Use theme `{{THEME_RECIPE}}` decorators for decoration
|
|
67
|
-
- [ ] Follow the shell structure (
|
|
72
|
+
- [ ] Follow the shell structure for the target section (see section context file for shell notes)
|
|
68
73
|
- [ ] Include patterns from the layout array
|
|
69
74
|
|
|
70
75
|
After generation:
|
|
@@ -95,7 +100,7 @@ Please confirm how you'd like to proceed.
|
|
|
95
100
|
When adding features (auth, search, payments, etc.):
|
|
96
101
|
|
|
97
102
|
1. Add the feature to `features[]` in the essence
|
|
98
|
-
2. Update relevant pages in `blueprint.pages[]`
|
|
103
|
+
2. Update relevant pages in `blueprint.sections[].pages[]`
|
|
99
104
|
3. Then implement the feature
|
|
100
105
|
|
|
101
106
|
## Pattern Selection
|
|
@@ -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:
|