@decantr/cli 1.6.7 → 1.7.1

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-3ZYYVKWA.js";
3
- import "./chunk-XUX3ZLCK.js";
2
+ import "./chunk-4KL2DCYC.js";
3
+ import "./chunk-X4RHL7WQ.js";
@@ -9,7 +9,7 @@ import {
9
9
  scaffoldMinimal,
10
10
  scaffoldProject,
11
11
  syncRegistry
12
- } from "./chunk-XUX3ZLCK.js";
12
+ } from "./chunk-X4RHL7WQ.js";
13
13
 
14
14
  // src/index.ts
15
15
  import { readFileSync as readFileSync15, existsSync as existsSync23, readdirSync as readdirSync6 } from "fs";
@@ -3299,48 +3299,16 @@ function extractPatternName(item) {
3299
3299
  }
3300
3300
  function generateCuratedPrompt(ctx) {
3301
3301
  const lines = [];
3302
- lines.push(`I'm building a ${ctx.archetype} application using ${ctx.target}.`);
3302
+ lines.push("Build this application using the Decantr design system.");
3303
3303
  lines.push("");
3304
- if (ctx.blueprint) {
3305
- lines.push(`Blueprint: ${ctx.blueprint}`);
3306
- }
3307
- lines.push(`Theme: ${ctx.theme} (${ctx.mode} mode)`);
3308
- lines.push(`Personality: ${ctx.personality.join(", ")}`);
3309
- lines.push(`Guard mode: ${ctx.guard}`);
3310
- lines.push("");
3311
- lines.push("Pages to build:");
3312
- for (const page of ctx.pages) {
3313
- const patternNames = page.layout.map(extractPatternName);
3314
- const patterns = patternNames.length > 0 ? patternNames.join(", ") : "custom";
3315
- lines.push(` - ${page.id}: ${page.shell} shell with ${patterns}`);
3316
- }
3317
- if (ctx.features.length > 0) {
3318
- lines.push("");
3319
- lines.push(`Features: ${ctx.features.join(", ")}`);
3320
- }
3304
+ lines.push("Read DECANTR.md for the design spec, CSS approach, and guard rules.");
3305
+ lines.push("Read .decantr/context/scaffold.md for the app overview, topology, routes, and voice guidance.");
3306
+ lines.push("Read each .decantr/context/section-*.md file before building that section's pages.");
3307
+ lines.push("Import src/styles/global.css, src/styles/tokens.css, and src/styles/treatments.css.");
3321
3308
  lines.push("");
3322
- lines.push("Please read DECANTR.md for the full design spec and methodology.");
3323
- lines.push("Follow the guard rules and use the patterns from decantr.essence.json.");
3309
+ lines.push("Start with the shell layouts, then build each section's pages.");
3324
3310
  return lines.join("\n");
3325
3311
  }
3326
- function boxedPrompt(content, title) {
3327
- const lines = content.split("\n");
3328
- const maxLen = Math.max(...lines.map((l) => l.length), title.length + 4);
3329
- const width = maxLen + 4;
3330
- const top = `\u250C${"\u2500".repeat(width - 2)}\u2510`;
3331
- const titleLine = `\u2502 ${BOLD6}${title}${RESET13}${" ".repeat(width - title.length - 4)} \u2502`;
3332
- const sep2 = `\u251C${"\u2500".repeat(width - 2)}\u2524`;
3333
- const bottom = `\u2514${"\u2500".repeat(width - 2)}\u2518`;
3334
- const body = lines.map((line) => {
3335
- const padding = " ".repeat(width - line.length - 4);
3336
- return `\u2502 ${line}${padding} \u2502`;
3337
- }).join("\n");
3338
- return `${top}
3339
- ${titleLine}
3340
- ${sep2}
3341
- ${body}
3342
- ${bottom}`;
3343
- }
3344
3312
  function getAPIClient() {
3345
3313
  return new RegistryAPIClient3({
3346
3314
  baseUrl: process.env.DECANTR_API_URL || void 0,
@@ -3895,7 +3863,13 @@ Validation warnings: ${validation.errors.join(", ")}`));
3895
3863
  guard: options.guard
3896
3864
  };
3897
3865
  const curatedPrompt = generateCuratedPrompt(promptCtx);
3898
- console.log(boxedPrompt(curatedPrompt, "Copy this prompt for your AI assistant"));
3866
+ console.log("");
3867
+ console.log(`${BOLD6}Prompt for your AI assistant:${RESET13}`);
3868
+ console.log(dim3("\u2500".repeat(50)));
3869
+ console.log("");
3870
+ console.log(curatedPrompt);
3871
+ console.log("");
3872
+ console.log(dim3("\u2500".repeat(50)));
3899
3873
  console.log("");
3900
3874
  if (registrySource === "cache") {
3901
3875
  console.log(dim3('Run "decantr sync" when online to get the latest registry content.'));
@@ -4332,7 +4306,7 @@ async function main() {
4332
4306
  break;
4333
4307
  }
4334
4308
  case "upgrade": {
4335
- const { cmdUpgrade } = await import("./upgrade-QPHY2ER6.js");
4309
+ const { cmdUpgrade } = await import("./upgrade-2KX7BKEK.js");
4336
4310
  const applyFlag = args.includes("--apply");
4337
4311
  await cmdUpgrade(process.cwd(), { apply: applyFlag });
4338
4312
  break;
@@ -922,6 +922,14 @@ Atoms + treatment + theme decorator:
922
922
  - **Theme decorators:** \`carbon-glass\`, \`carbon-code\` \u2014 theme-specific decoration from treatments.css
923
923
  - **Combined:** \`css('_flex _col') + ' d-surface carbon-card'\`
924
924
 
925
+ \`\`\`tsx
926
+ // Responsive prefix \u2014 applies at breakpoint and above:
927
+ css('_col sm:_row')
928
+
929
+ // Pseudo prefix:
930
+ css('hover:_opacity80')
931
+ \`\`\`
932
+
925
933
  ### Atom Reference
926
934
 
927
935
  #### Display
@@ -1131,7 +1139,15 @@ Check \`decantr.essence.json\` \u2192 \`meta.platform.routing\` for the routing
1131
1139
  - \`"hash"\` \u2192 use \`HashRouter\` (e.g., for static hosting, GitHub Pages)
1132
1140
  - \`"history"\` \u2192 use \`BrowserRouter\` (e.g., for server-rendered apps)
1133
1141
 
1134
- Routes are defined in \`decantr.essence.json\` \u2192 \`blueprint.routes\` and listed in \`.decantr/context/scaffold.md\`.`;
1142
+ Routes are defined in \`decantr.essence.json\` \u2192 \`blueprint.routes\` and listed in \`.decantr/context/scaffold.md\`.
1143
+
1144
+ ### Layout Rules
1145
+
1146
+ 1. **Never nest d-surface inside d-surface.** Inner sections use plain containers with padding atoms.
1147
+ 2. **Shell regions are frames, not surfaces.** Sidebar and header use var(--d-surface) or var(--d-bg) directly. Apply d-surface only to content cards within the body region.
1148
+ 3. **One scroll container per region.** Body has overflow-y-auto. Sidebar nav has its own overflow-y-auto. Never nest additional scrollable wrappers.
1149
+ 4. **d-section spacing is self-contained.** Each d-section owns its padding. The d-section + d-section rule adds a separator. Do NOT add extra margin between adjacent sections.
1150
+ 5. **Responsive nav rules.** Hamburger menus appear ONLY below the shell collapse breakpoint. Full nav shows above it.`;
1135
1151
  function generateDecantrMdV31(params) {
1136
1152
  const template = loadTemplate("DECANTR.md.template");
1137
1153
  const body = renderTemplate(template, {
@@ -1867,7 +1883,10 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
1867
1883
  description: inner.description || "",
1868
1884
  regions: inner.config?.regions || [],
1869
1885
  layout: inner.layout || void 0,
1870
- guidance: inner.guidance || void 0
1886
+ guidance: inner.guidance || void 0,
1887
+ atoms: inner.atoms || void 0,
1888
+ config: inner.config || void 0,
1889
+ internal_layout: inner.internal_layout || void 0
1871
1890
  };
1872
1891
  }
1873
1892
  } catch {
@@ -1914,7 +1933,8 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
1914
1933
  constraints: essence.dna.constraints,
1915
1934
  shellInfo: shellInfoCache[section.shell],
1916
1935
  themeData,
1917
- themeMode: mode
1936
+ themeMode: mode,
1937
+ voiceTone: storedVoice?.tone ? storedVoice.tone.split(".")[0] + "." : void 0
1918
1938
  });
1919
1939
  const sectionContextPath = join(contextDir, `section-${section.id}.md`);
1920
1940
  writeFileSync(sectionContextPath, contextContent);
@@ -1979,7 +1999,10 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
1979
1999
  description: inner.description || "",
1980
2000
  regions: inner.config?.regions || [],
1981
2001
  layout: inner.layout || void 0,
1982
- guidance: inner.guidance || void 0
2002
+ guidance: inner.guidance || void 0,
2003
+ atoms: inner.atoms || void 0,
2004
+ config: inner.config || void 0,
2005
+ internal_layout: inner.internal_layout || void 0
1983
2006
  };
1984
2007
  }
1985
2008
  } catch {
@@ -2001,7 +2024,8 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
2001
2024
  constraints: essence.dna.constraints,
2002
2025
  shellInfo: v30ShellInfo,
2003
2026
  themeData,
2004
- themeMode: mode
2027
+ themeMode: mode,
2028
+ voiceTone: storedVoice?.tone ? storedVoice.tone.split(".")[0] + "." : void 0
2005
2029
  });
2006
2030
  const sectionContextPath = join(contextDir, `section-${syntheticSection.id}.md`);
2007
2031
  writeFileSync(sectionContextPath, contextContent);
@@ -2100,6 +2124,136 @@ function generateSyntheticComponents(patternId, description) {
2100
2124
  if (patternId.includes("empty") || patternId.includes("new")) syntheticComponents.push("Icon", "Text", "Button");
2101
2125
  return [...new Set(syntheticComponents)];
2102
2126
  }
2127
+ function generateShellImplementation(shellId, shellInfo) {
2128
+ const lines = [];
2129
+ lines.push(`## Shell Implementation (${shellId})`);
2130
+ lines.push("");
2131
+ if (shellInfo.internal_layout && Object.keys(shellInfo.internal_layout).length > 0) {
2132
+ for (const [region, props] of Object.entries(shellInfo.internal_layout)) {
2133
+ lines.push(`### ${region}`);
2134
+ lines.push("");
2135
+ if (typeof props === "object" && props !== null) {
2136
+ for (const [key, value] of Object.entries(props)) {
2137
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
2138
+ lines.push(`- **${key}:**`);
2139
+ for (const [subKey, subValue] of Object.entries(value)) {
2140
+ lines.push(` - ${subKey}: ${subValue}`);
2141
+ }
2142
+ } else {
2143
+ lines.push(`- **${key}:** ${value}`);
2144
+ }
2145
+ }
2146
+ } else {
2147
+ lines.push(`- ${props}`);
2148
+ }
2149
+ lines.push("");
2150
+ }
2151
+ lines.push("### Anti-patterns");
2152
+ lines.push("");
2153
+ lines.push("- Do NOT nest `overflow-y-auto` inside another `overflow-y-auto` \u2014 one scroll container per region.");
2154
+ lines.push("- Do NOT apply `d-surface` to shell frame regions (sidebar, header). Use `var(--d-surface)` or `var(--d-bg)` directly.");
2155
+ lines.push("- Do NOT add wrapper `<div>` elements around shell regions \u2014 the grid areas handle placement.");
2156
+ lines.push("");
2157
+ } else {
2158
+ if (shellInfo.layout) {
2159
+ lines.push(`**Layout:** ${shellInfo.layout}`);
2160
+ lines.push("");
2161
+ }
2162
+ if (shellInfo.atoms) {
2163
+ lines.push(`**Atoms:** \`${shellInfo.atoms}\``);
2164
+ lines.push("");
2165
+ }
2166
+ if (shellInfo.config) {
2167
+ const cfg = shellInfo.config;
2168
+ if (cfg.nav) {
2169
+ const navParts = [];
2170
+ if (cfg.nav.position) navParts.push(`position: ${cfg.nav.position}`);
2171
+ if (cfg.nav.width) navParts.push(`width: ${cfg.nav.width}`);
2172
+ if (cfg.nav.collapseTo) navParts.push(`collapses to: ${cfg.nav.collapseTo}`);
2173
+ if (cfg.nav.collapseBelow) navParts.push(`below: ${cfg.nav.collapseBelow}`);
2174
+ if (navParts.length > 0) lines.push(`**Nav:** ${navParts.join(", ")}`);
2175
+ }
2176
+ if (cfg.header) {
2177
+ const headerParts = [];
2178
+ if (cfg.header.height) headerParts.push(`height: ${cfg.header.height}`);
2179
+ if (cfg.header.sticky) headerParts.push("sticky");
2180
+ if (headerParts.length > 0) lines.push(`**Header:** ${headerParts.join(", ")}`);
2181
+ }
2182
+ if (cfg.body) {
2183
+ const bodyParts = [];
2184
+ if (cfg.body.scroll) bodyParts.push("overflow-y: auto");
2185
+ if (cfg.body.inputAnchored) bodyParts.push("input anchored to bottom");
2186
+ if (bodyParts.length > 0) lines.push(`**Body:** ${bodyParts.join(", ")}`);
2187
+ }
2188
+ if (cfg.footer) {
2189
+ const footerParts = [];
2190
+ if (cfg.footer.height) footerParts.push(`height: ${cfg.footer.height}`);
2191
+ if (cfg.footer.sticky) footerParts.push("sticky");
2192
+ if (footerParts.length > 0) lines.push(`**Footer:** ${footerParts.join(", ")}`);
2193
+ }
2194
+ lines.push("");
2195
+ }
2196
+ }
2197
+ return lines;
2198
+ }
2199
+ function generateQuickStart(input) {
2200
+ const { section, shellInfo, decorators, personality, voiceTone } = input;
2201
+ const lines = [];
2202
+ lines.push("## Quick Start");
2203
+ lines.push("");
2204
+ const shellDesc = shellInfo?.description || `${section.shell} shell`;
2205
+ const dims = [];
2206
+ if (shellInfo?.config?.nav?.width) dims.push(`nav: ${shellInfo.config.nav.width}`);
2207
+ if (shellInfo?.config?.header?.height) dims.push(`header: ${shellInfo.config.header.height}`);
2208
+ lines.push(`**Shell:** ${shellDesc}${dims.length > 0 ? ` (${dims.join(", ")})` : ""}`);
2209
+ const pageNames = section.pages.map((p) => p.id);
2210
+ lines.push(`**Pages:** ${section.pages.length} (${pageNames.join(", ")})`);
2211
+ const patternLabels = [];
2212
+ const specEntries = Object.entries(input.patternSpecs);
2213
+ for (const [name, spec] of specEntries) {
2214
+ const count = spec.components.length;
2215
+ if (count >= 8) patternLabels.push(`${name} [complex]`);
2216
+ else if (count >= 4) patternLabels.push(`${name} [moderate]`);
2217
+ else patternLabels.push(name);
2218
+ }
2219
+ if (patternLabels.length > 0) {
2220
+ lines.push(`**Key patterns:** ${patternLabels.join(", ")}`);
2221
+ }
2222
+ const cssClasses = [];
2223
+ const topDecorators = decorators.slice(0, 3).map((d) => d.name);
2224
+ cssClasses.push(...topDecorators);
2225
+ const pLower = personality.join(" ").toLowerCase();
2226
+ if (pLower.includes("neon") || pLower.includes("glow")) cssClasses.push("neon-glow");
2227
+ if (pLower.includes("mono") || pLower.includes("monospace")) cssClasses.push("mono-data");
2228
+ if (cssClasses.length > 0) {
2229
+ lines.push(`**CSS classes:** ${cssClasses.map((c) => `\`.${c}\``).join(", ")}`);
2230
+ }
2231
+ const density = section.dna_overrides?.density || "comfortable";
2232
+ lines.push(`**Density:** ${density}`);
2233
+ if (voiceTone) {
2234
+ lines.push(`**Voice:** ${voiceTone}`);
2235
+ }
2236
+ lines.push("");
2237
+ return lines;
2238
+ }
2239
+ function generateSpacingGuide(density) {
2240
+ const lines = [];
2241
+ const level = density === "compact" || density === "spacious" ? density : "comfortable";
2242
+ const tokens = computeSpatialTokens(level);
2243
+ lines.push("## Spacing Guide");
2244
+ lines.push("");
2245
+ lines.push("| Context | Token | Value | Usage |");
2246
+ lines.push("|---------|-------|-------|-------|");
2247
+ lines.push(`| Content gap | \`--d-content-gap\` | \`${tokens["--d-content-gap"]}\` | Gap between sibling elements |`);
2248
+ lines.push(`| Section padding | \`--d-section-py\` | \`${tokens["--d-section-py"]}\` | Vertical padding on d-section |`);
2249
+ lines.push(`| Surface padding | \`--d-surface-p\` | \`${tokens["--d-surface-p"]}\` | Inner padding for d-surface |`);
2250
+ lines.push(`| Interactive V | \`--d-interactive-py\` | \`${tokens["--d-interactive-py"]}\` | Vertical padding on buttons |`);
2251
+ lines.push(`| Interactive H | \`--d-interactive-px\` | \`${tokens["--d-interactive-px"]}\` | Horizontal padding on buttons |`);
2252
+ lines.push(`| Control | \`--d-control-py\` | \`${tokens["--d-control-py"]}\` | Vertical padding on inputs |`);
2253
+ lines.push(`| Data row | \`--d-data-py\` | \`${tokens["--d-data-py"]}\` | Vertical padding on table rows |`);
2254
+ lines.push("");
2255
+ return lines;
2256
+ }
2103
2257
  function generateSectionContext(input) {
2104
2258
  const { section, decorators, guardConfig, personality, themeName, zoneContext, patternSpecs, themeHints, constraints, shellInfo } = input;
2105
2259
  const lines = [];
@@ -2107,10 +2261,6 @@ function generateSectionContext(input) {
2107
2261
  lines.push("");
2108
2262
  lines.push(`**Role:** ${section.role} | **Shell:** ${section.shell} | **Archetype:** ${section.id}`);
2109
2263
  lines.push(`**Description:** ${section.description}`);
2110
- if (shellInfo) {
2111
- lines.push(`**Shell structure:** ${shellInfo.description}`);
2112
- lines.push(`**Regions:** ${shellInfo.regions.join(", ")}`);
2113
- }
2114
2264
  if (section.dna_overrides) {
2115
2265
  const parts = [];
2116
2266
  if (section.dna_overrides.density) parts.push(`density: ${section.dna_overrides.density}`);
@@ -2120,6 +2270,10 @@ function generateSectionContext(input) {
2120
2270
  }
2121
2271
  }
2122
2272
  lines.push("");
2273
+ lines.push(...generateQuickStart(input));
2274
+ if (shellInfo) {
2275
+ lines.push(...generateShellImplementation(section.shell, shellInfo));
2276
+ }
2123
2277
  if (shellInfo?.guidance && Object.keys(shellInfo.guidance).length > 0) {
2124
2278
  lines.push(`## Shell Notes (${section.shell})`);
2125
2279
  lines.push("");
@@ -2129,6 +2283,8 @@ function generateSectionContext(input) {
2129
2283
  }
2130
2284
  lines.push("");
2131
2285
  }
2286
+ const density = section.dna_overrides?.density || "comfortable";
2287
+ lines.push(...generateSpacingGuide(density));
2132
2288
  lines.push("---");
2133
2289
  lines.push("");
2134
2290
  lines.push(`**Guard:** ${guardConfig.mode} mode | DNA violations = ${guardConfig.dna_enforcement} | Blueprint violations = ${guardConfig.blueprint_enforcement}`);
@@ -2401,8 +2557,6 @@ function generateScaffoldContext(input) {
2401
2557
  if (input.voice.metrics_format) lines.push(`**Metrics format:** ${input.voice.metrics_format}`);
2402
2558
  lines.push("");
2403
2559
  }
2404
- lines.push("## App Topology");
2405
- lines.push("");
2406
2560
  lines.push(topologyMarkdown);
2407
2561
  lines.push("");
2408
2562
  lines.push("## Sections Overview");
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import "./chunk-3ZYYVKWA.js";
2
- import "./chunk-XUX3ZLCK.js";
1
+ import "./chunk-4KL2DCYC.js";
2
+ import "./chunk-X4RHL7WQ.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  RegistryClient,
3
3
  refreshDerivedFiles
4
- } from "./chunk-XUX3ZLCK.js";
4
+ } from "./chunk-X4RHL7WQ.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.6.7",
3
+ "version": "1.7.1",
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": {
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "dependencies": {
26
26
  "@decantr/essence-spec": "1.0.0-beta.11",
27
- "@decantr/registry": "1.0.0-beta.11"
27
+ "@decantr/registry": "1.0.0-beta.12"
28
28
  },
29
29
  "scripts": {
30
30
  "build": "tsup",