@decantr/cli 1.5.4 → 1.5.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 CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import "./chunk-D3W3MYKT.js";
3
- import "./chunk-T7CQSJGV.js";
2
+ import "./chunk-4KKFOXBB.js";
3
+ import "./chunk-MU3657R7.js";
@@ -9,7 +9,7 @@ import {
9
9
  scaffoldMinimal,
10
10
  scaffoldProject,
11
11
  syncRegistry
12
- } from "./chunk-T7CQSJGV.js";
12
+ } from "./chunk-MU3657R7.js";
13
13
 
14
14
  // src/index.ts
15
15
  import { readFileSync as readFileSync15, existsSync as existsSync23, readdirSync as readdirSync6 } from "fs";
@@ -4256,7 +4256,7 @@ async function main() {
4256
4256
  break;
4257
4257
  }
4258
4258
  case "upgrade": {
4259
- const { cmdUpgrade } = await import("./upgrade-TXVD2WIN.js");
4259
+ const { cmdUpgrade } = await import("./upgrade-T3FNFFIH.js");
4260
4260
  const applyFlag = args.includes("--apply");
4261
4261
  await cmdUpgrade(process.cwd(), { apply: applyFlag });
4262
4262
  break;
@@ -93,6 +93,9 @@ function generateTreatmentCSS(spatialTokens, treatmentOverrides, themeDecorators
93
93
  ["box-shadow", "var(--d-shadow-lg)"],
94
94
  ["z-index", "50"]
95
95
  ]);
96
+ emitRule(".d-surface[data-interactive]", [
97
+ ["cursor", "pointer"]
98
+ ]);
96
99
  emitRule(".d-surface[data-interactive]:hover", [
97
100
  ["border-color", "var(--d-primary-hover, var(--d-border))"],
98
101
  ["box-shadow", "var(--d-shadow-md)"],
@@ -154,7 +157,13 @@ function generateTreatmentCSS(spatialTokens, treatmentOverrides, themeDecorators
154
157
  ["padding", "var(--d-section-py) 0"]
155
158
  ]);
156
159
  lines.push(".d-section + .d-section {");
157
- lines.push(" border-top: 1px solid var(--d-border);");
160
+ lines.push(" border-top: 1px solid transparent;");
161
+ lines.push(" border-image: linear-gradient(to right, transparent, var(--d-border), transparent) 1;");
162
+ lines.push(" margin-top: var(--d-gap-2);");
163
+ lines.push("}");
164
+ lines.push("");
165
+ lines.push('.d-section[data-density="compact"] {');
166
+ lines.push(" padding: calc(var(--d-section-py) * 0.5) 0;");
158
167
  lines.push("}");
159
168
  lines.push("");
160
169
  emitRule(".d-annotation", [
@@ -185,6 +194,14 @@ function generateTreatmentCSS(spatialTokens, treatmentOverrides, themeDecorators
185
194
  ["background", "color-mix(in srgb, var(--d-info) 15%, transparent)"],
186
195
  ["color", "var(--d-info)"]
187
196
  ]);
197
+ emitRule(".d-label", [
198
+ ["font-size", "0.7rem"],
199
+ ["font-weight", "600"],
200
+ ["text-transform", "uppercase"],
201
+ ["letter-spacing", "0.08em"],
202
+ ["color", "var(--d-text-muted)"],
203
+ ["font-family", "var(--d-font-mono, ui-monospace, monospace)"]
204
+ ]);
188
205
  if (themeDecorators && Object.keys(themeDecorators).length > 0) {
189
206
  const label = themeName ? ` (${themeName})` : "";
190
207
  lines.push(`/* \u2500\u2500 Layer 3: Theme Decorators${label} \u2500\u2500 */`);
@@ -208,6 +225,35 @@ function generateTreatmentCSS(spatialTokens, treatmentOverrides, themeDecorators
208
225
  lines.push("}");
209
226
  return lines.join("\n");
210
227
  }
228
+ function generatePersonalityCSS(personality, themeData) {
229
+ const text = personality.join(" ").toLowerCase();
230
+ const rules = [];
231
+ if (text.includes("neon") || text.includes("glow")) {
232
+ const glowColor = "var(--d-accent-glow, rgba(0, 212, 255, 0.3))";
233
+ rules.push(`.neon-glow { box-shadow: 0 0 20px ${glowColor}; }`);
234
+ rules.push(`.neon-glow-hover:hover { box-shadow: 0 0 24px ${glowColor}; transition: box-shadow var(--d-duration-hover, 0.15s) var(--d-easing, ease); }`);
235
+ rules.push(`.neon-text-glow { text-shadow: 0 0 12px ${glowColor}; }`);
236
+ rules.push(`.neon-border-glow { border-color: var(--d-accent); box-shadow: 0 0 8px ${glowColor}; }`);
237
+ }
238
+ if (text.includes("monospace") || text.includes("mono")) {
239
+ rules.push(`.mono-data { font-family: var(--d-font-mono, ui-monospace, monospace); font-variant-numeric: tabular-nums; }`);
240
+ }
241
+ if (text.includes("pulse") || text.includes("ring") || text.includes("status")) {
242
+ rules.push(`.status-ring { width: 48px; height: 48px; border-radius: 50%; border: 2px solid var(--d-border); display: flex; align-items: center; justify-content: center; position: relative; transition: border-color 0.2s ease, box-shadow 0.2s ease; }`);
243
+ rules.push(`.status-ring[data-status="active"] { border-color: var(--d-success); }`);
244
+ 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); }`);
245
+ rules.push(`.status-ring[data-status="warning"] { border-color: var(--d-warning); }`);
246
+ rules.push(`.status-ring[data-status="idle"] { border-color: var(--d-text-muted); }`);
247
+ rules.push(`@keyframes pulse-ring { 0% { opacity: 0.6; transform: scale(1); } 100% { opacity: 0; transform: scale(1.3); } }`);
248
+ 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; }`);
249
+ }
250
+ if (themeData.motion?.entrance) {
251
+ rules.push(`.entrance-fade { animation: decantr-entrance var(--d-duration-entrance, 0.2s) var(--d-easing, ease-out); }`);
252
+ rules.push(`@keyframes decantr-entrance { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }`);
253
+ }
254
+ if (rules.length === 0) return "";
255
+ return "\n/* \u2500\u2500 Personality-Derived Utilities \u2500\u2500 */\n\n" + rules.join("\n\n") + "\n";
256
+ }
211
257
 
212
258
  // src/scaffold.ts
213
259
  var __dirname = dirname(fileURLToPath(import.meta.url));
@@ -627,35 +673,6 @@ input, button, textarea, select {
627
673
  }
628
674
  `;
629
675
  }
630
- function generateTreatmentsContext(themeData, themeName) {
631
- const lines = [];
632
- lines.push(`# Visual Treatments: ${themeName}`);
633
- lines.push("");
634
- lines.push("## Base Treatments");
635
- lines.push("");
636
- lines.push("d-interactive, d-surface, d-data, d-control, d-section, d-annotation \u2014 see DECANTR.md for usage.");
637
- lines.push("");
638
- if (themeData?.decorators && Object.keys(themeData.decorators).length > 0) {
639
- lines.push(`## Theme Decorators (${themeName}-specific)`);
640
- lines.push("");
641
- lines.push("| Class | Use for |");
642
- lines.push("|-------|---------|");
643
- for (const [name, description] of Object.entries(themeData.decorators)) {
644
- const useFor = description.split(".")[0].trim();
645
- lines.push(`| ${name} | ${useFor} |`);
646
- }
647
- lines.push("");
648
- }
649
- lines.push("## Composition");
650
- lines.push("");
651
- lines.push("Atoms + treatment + theme decorator:");
652
- lines.push("```tsx");
653
- lines.push(`css('_flex _col _gap4') + ' d-surface'`);
654
- lines.push("```");
655
- lines.push("");
656
- lines.push("Atoms use `css()` function. Treatments and theme decorators are plain class strings.");
657
- return lines.join("\n");
658
- }
659
676
  function generateDecoratorRule(name, description) {
660
677
  const rules = [];
661
678
  const descLower = description.toLowerCase();
@@ -1067,19 +1084,38 @@ Atoms + treatment + theme decorator:
1067
1084
  ### Atoms Quick Reference
1068
1085
 
1069
1086
  | Category | Examples | Purpose |
1070
- |----------|----------|---------|
1087
+ |----------|---------|---------|
1071
1088
  | Layout | \`_flex\`, \`_col\`, \`_row\`, \`_wrap\`, \`_grid\` | Flex/grid containers |
1072
1089
  | Spacing | \`_gap4\`, \`_p4\`, \`_px4\`, \`_py2\`, \`_m0\` | Gaps, padding, margin |
1073
- | Sizing | \`_w100\`, \`_h100\`, \`_minw0\`, \`_maxwfull\` | Width, height |
1074
- | Text | \`_textlg\`, \`_text2xl\`, \`_fontbold\`, \`_textc\` | Typography |
1090
+ | Sizing | \`_w100\`, \`_h100\`, \`_mw640\`, \`_mw480\` | Width, height, max-width |
1091
+ | Text | \`_textlg\`, \`_text2xl\`, \`_fontbold\`, \`_fontmono\` | Typography |
1092
+ | Color | \`_fgaccent\`, \`_fgmuted\`, \`_fgsuccess\`, \`_bgsurf\` | Foreground/background |
1075
1093
  | Alignment | \`_aic\`, \`_jcc\`, \`_jcsb\`, \`_pic\` | Flex/grid alignment |
1076
1094
  | Position | \`_rel\`, \`_abs\`, \`_sticky\`, \`_z10\` | Positioning |
1077
1095
  | Visual | \`_rounded\`, \`_shadow\`, \`_trans\`, \`_op50\` | Decoration |
1078
- | Color | \`_bgprimary\`, \`_fgtext\`, \`_fgmuted\`, \`_bcborder\` | Theme colors |
1079
1096
  | Responsive | \`_md:gc2\`, \`_lg:gc4\`, \`_sm:flex\` | Breakpoint prefixes |
1097
+ | Cursor | \`_pointer\` | Interaction hints |
1080
1098
 
1081
1099
  Scale: 0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24. Example: \`_gap4\` = \`gap:1rem\`.
1082
1100
 
1101
+ ### Section Labels
1102
+
1103
+ Use the d-label class for uppercase section headings.
1104
+ Anchor with a left accent border: \`border-left: 2px solid var(--d-accent); padding-left: 0.5rem\`.
1105
+
1106
+ ### Empty States
1107
+
1108
+ Every data-driven section should handle zero-data gracefully.
1109
+ Pattern: centered 48px muted icon + descriptive message + optional CTA button.
1110
+
1111
+ ### Page Transitions
1112
+
1113
+ If the theme provides motion tokens, apply the \`entrance-fade\` class to page content containers for smooth page-to-page transitions.
1114
+
1115
+ ### Navigation Shortcuts
1116
+
1117
+ If the essence defines hotkeys or command_palette, implement as keyboard event listeners (useEffect + keydown) \u2014 not as visible UI text.
1118
+
1083
1119
  ### Design Tokens
1084
1120
 
1085
1121
  | Token | Purpose | Use for |
@@ -1583,23 +1619,24 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
1583
1619
  writeFileSync(tokensPath, generateTokensCSS(themeData, mode, spatialTokens));
1584
1620
  }
1585
1621
  const treatmentsPath = join(stylesDir, "treatments.css");
1586
- writeFileSync(treatmentsPath, generateTreatmentCSS(
1622
+ let treatmentCSS = generateTreatmentCSS(
1587
1623
  spatialTokens,
1588
1624
  themeData?.treatments,
1589
1625
  themeData?.decorators,
1590
1626
  themeName
1591
- ));
1627
+ );
1628
+ const personalityCSS = generatePersonalityCSS(personality || [], themeData || {});
1629
+ treatmentCSS += personalityCSS;
1630
+ writeFileSync(treatmentsPath, treatmentCSS);
1592
1631
  const globalPath = join(stylesDir, "global.css");
1593
1632
  if (!existsSync(globalPath)) {
1594
1633
  writeFileSync(globalPath, generateGlobalCSS(personality));
1595
1634
  }
1596
1635
  const cssFiles = [tokensPath, treatmentsPath, globalPath];
1597
- const treatmentsMdPath = join(contextDir, "treatments.md");
1598
- writeFileSync(treatmentsMdPath, generateTreatmentsContext(themeData, themeName));
1599
1636
  const decantrMdPath = join(projectRoot, "DECANTR.md");
1600
1637
  writeFileSync(decantrMdPath, generateDecantrMdV31(guardMode, CSS_APPROACH_CONTENT));
1601
1638
  const hasSections = essence.blueprint.sections && essence.blueprint.sections.length > 0;
1602
- const contextFiles = [treatmentsMdPath];
1639
+ const contextFiles = [];
1603
1640
  if (!hasSections) {
1604
1641
  const summaryPath = join(contextDir, "essence-summary.md");
1605
1642
  writeFileSync(summaryPath, generateEssenceSummaryV3(essence));
@@ -1729,7 +1766,8 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
1729
1766
  shellInfoCache[shellId] = {
1730
1767
  description: inner.description || "",
1731
1768
  regions: inner.config?.regions || [],
1732
- layout: inner.layout || void 0
1769
+ layout: inner.layout || void 0,
1770
+ guidance: inner.guidance || void 0
1733
1771
  };
1734
1772
  }
1735
1773
  } catch {
@@ -1881,7 +1919,8 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
1881
1919
  v30ShellInfo = {
1882
1920
  description: inner.description || "",
1883
1921
  regions: inner.config?.regions || [],
1884
- layout: inner.layout || void 0
1922
+ layout: inner.layout || void 0,
1923
+ guidance: inner.guidance || void 0
1885
1924
  };
1886
1925
  }
1887
1926
  } catch {
@@ -2015,6 +2054,15 @@ function generateSectionContext(input) {
2015
2054
  }
2016
2055
  }
2017
2056
  lines.push("");
2057
+ if (shellInfo?.guidance && Object.keys(shellInfo.guidance).length > 0) {
2058
+ lines.push(`## Shell Notes (${section.shell})`);
2059
+ lines.push("");
2060
+ for (const [key, value] of Object.entries(shellInfo.guidance)) {
2061
+ const label = key.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
2062
+ lines.push(`- **${label}:** ${value}`);
2063
+ }
2064
+ lines.push("");
2065
+ }
2018
2066
  lines.push("---");
2019
2067
  lines.push("");
2020
2068
  lines.push(`**Guard:** ${guardConfig.mode} mode | DNA violations = ${guardConfig.dna_enforcement} | Blueprint violations = ${guardConfig.blueprint_enforcement}`);
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import "./chunk-D3W3MYKT.js";
2
- import "./chunk-T7CQSJGV.js";
1
+ import "./chunk-4KKFOXBB.js";
2
+ import "./chunk-MU3657R7.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  RegistryClient,
3
3
  refreshDerivedFiles
4
- } from "./chunk-T7CQSJGV.js";
4
+ } from "./chunk-MU3657R7.js";
5
5
 
6
6
  // src/commands/upgrade.ts
7
7
  import { readFileSync, writeFileSync, existsSync } from "fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decantr/cli",
3
- "version": "1.5.4",
3
+ "version": "1.5.5",
4
4
  "description": "Decantr CLI — search the registry, validate essence files, and access design intelligence from the terminal",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -1,66 +1,12 @@
1
1
  # Task Context: Scaffolding
2
2
 
3
- **Enforcement Tier: Creative**
4
-
5
- You are scaffolding a new Decantr project. Guard rules are advisory only during initial scaffolding.
6
-
7
- ---
8
-
9
- ## Your Task
10
-
11
- Generate the initial project structure based on the essence specification.
12
-
13
- ## Rules (Advisory)
14
-
15
- During scaffolding, the following rules are recommendations, not requirements:
16
-
17
- | # | Layer | Rule | Status | Guidance |
18
- |---|-------|------|--------|----------|
19
- | 1 | DNA | Style | Advisory | Use the theme from essence, but creative variations are acceptable |
20
- | 2 | DNA | Density | Advisory | Follow spacing guidelines loosely |
21
- | 4 | DNA | Accessibility | Advisory | Meet WCAG level from essence where possible |
22
- | 5 | DNA | Theme-mode | Advisory | Use the specified theme/mode combination |
23
- | 6 | Blueprint | Structure | Advisory | Follow the page structure, add placeholder content |
24
- | 7 | Blueprint | Layout | Advisory | Use suggested patterns, order can be adjusted |
25
- | 8 | Blueprint | Pattern-exists | Advisory | Use patterns that exist in the registry |
26
-
27
- ## Checklist
28
-
29
- Before scaffolding:
30
-
31
- - [ ] Read `decantr.essence.json`
32
- - [ ] Understand the target framework ({{TARGET}})
33
- - [ ] Know the theme ({{THEME_STYLE}}) and mode ({{THEME_MODE}})
34
- - [ ] Review the page structure
35
-
36
- During scaffolding:
37
-
38
- - [ ] Create the shell layout ({{DEFAULT_SHELL}})
39
- - [ ] Generate pages from `blueprint.pages[]`
40
- - [ ] Add pattern placeholders for each page's `layout[]`
41
- - [ ] Apply theme colors and typography
42
- - [ ] Set up routing based on page IDs
43
-
44
- After scaffolding:
45
-
46
- - [ ] Run `npx @decantr/cli validate` to check the essence
47
- - [ ] Verify each page renders correctly
48
- - [ ] Check theme consistency across pages
3
+ **Enforcement Tier: Creative** — Guard rules are advisory during initial scaffolding.
49
4
 
50
5
  ## What to Generate
51
6
 
52
7
  {{SCAFFOLD_STRUCTURE}}
53
8
 
54
- ## Next Steps
55
-
56
- After scaffolding is complete:
57
-
58
- 1. Run the development server
59
- 2. Verify all pages load
60
- 3. Check theme consistency
61
- 4. Run `npx @decantr/cli validate`
62
-
63
- Once verified, subsequent changes will use **{{GUARD_MODE}}** enforcement mode.
9
+ Post-scaffold enforcement mode: **{{GUARD_MODE}}**.
64
10
 
65
11
  ---
66
12