@decantr/cli 1.7.6 → 1.7.7

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/README.md CHANGED
@@ -14,12 +14,22 @@ npm install -D @decantr/cli
14
14
  Or run it without installing:
15
15
 
16
16
  ```bash
17
- npx @decantr/cli init --blueprint=agent-marketplace --yes
17
+ npx @decantr/cli new my-app --blueprint=agent-marketplace
18
18
  ```
19
19
 
20
+ Use `decantr new` for a greenfield workspace in a fresh directory.
21
+ Use `decantr analyze` first when you already have an app and want Decantr governance without adopting a blueprint.
22
+ Use `decantr init` to attach Decantr contract/context files to an existing project or to create a contract-only workspace.
23
+
24
+ Current starter adapter availability:
25
+
26
+ - `react-vite` is the runnable bootstrap adapter in this wave
27
+ - other contract targets remain valid Decantr targets, but `decantr new` will keep them in contract-only mode until their adapters land
28
+
20
29
  ## What It Does
21
30
 
22
31
  - scaffolds Decantr projects from blueprints, archetypes, or prompts
32
+ - supports three workflow lanes: greenfield blueprint, brownfield adoption, and hybrid composition
23
33
  - generates execution-pack context files for AI coding assistants
24
34
  - audits projects against Decantr contracts
25
35
  - searches the registry and showcase benchmark corpus
@@ -28,7 +38,10 @@ npx @decantr/cli init --blueprint=agent-marketplace --yes
28
38
  ## Common Commands
29
39
 
30
40
  ```bash
31
- decantr init --blueprint=agent-marketplace
41
+ decantr new my-app --blueprint=agent-marketplace
42
+ decantr analyze
43
+ decantr init --existing --yes
44
+ decantr init --existing --blueprint=agent-marketplace
32
45
  decantr magic "AI-native analytics workspace"
33
46
  decantr audit
34
47
  decantr check
@@ -36,14 +49,49 @@ decantr registry summary --namespace @official --json
36
49
  decantr showcase verification --json
37
50
  ```
38
51
 
52
+ ## Greenfield Certification
53
+
54
+ Use the built-in certification harness before releases when you want to prove that representative blueprints still scaffold into runnable starter projects:
55
+
56
+ ```bash
57
+ pnpm --filter @decantr/cli certify:blueprints
58
+ ```
59
+
60
+ By default it certifies `portfolio`, `producer-studio`, and `agent-marketplace` by:
61
+
62
+ - running `decantr new` in fresh temp directories
63
+ - seeding offline content from `DECANTR_CONTENT_DIR` or a sibling `decantr-content` checkout
64
+ - verifying the starter runtime files and router mode match the generated essence
65
+ - running `npm run build` in each scaffolded project
66
+
67
+ Override the matrix or emit JSON when needed:
68
+
69
+ ```bash
70
+ pnpm --filter @decantr/cli certify:blueprints -- --blueprints=portfolio,legal-research --json
71
+ ```
72
+
39
73
  Offline blueprint scaffolding expects a real local content source:
40
74
 
41
75
  ```bash
42
- DECANTR_CONTENT_DIR=/path/to/decantr-content decantr init --blueprint=agent-marketplace --offline --yes
76
+ DECANTR_CONTENT_DIR=/path/to/decantr-content decantr new my-app --blueprint=agent-marketplace --offline
43
77
  ```
44
78
 
45
79
  If a requested offline blueprint, archetype, or theme cannot be resolved from local cache/custom content or `DECANTR_CONTENT_DIR`, the CLI now stops explicitly instead of silently falling back to the default scaffold.
46
80
 
81
+ ## Workflow Certification
82
+
83
+ The broader workflow matrix now has its own certification entrypoint:
84
+
85
+ ```bash
86
+ pnpm --filter @decantr/cli certify:workflows
87
+ ```
88
+
89
+ It covers:
90
+
91
+ - greenfield blueprint bootstrap
92
+ - brownfield `analyze -> init --existing`
93
+ - hybrid follow-up composition via Decantr mutation commands
94
+
47
95
  ## Generated Context
48
96
 
49
97
  Scaffolded projects include compiled execution packs under `.decantr/context/`, including:
package/dist/bin.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import "./chunk-KAEQTVAM.js";
3
- import "./chunk-H4H3IQJK.js";
2
+ import "./chunk-OHQXL7EJ.js";
3
+ import "./chunk-4D5V6GQU.js";
4
4
  import "./chunk-KUDAVJOR.js";
@@ -6,8 +6,9 @@ import { computeSpatialTokens } from "@decantr/essence-spec";
6
6
  import { compileExecutionPackBundle } from "@decantr/core";
7
7
 
8
8
  // src/treatments.ts
9
- function generateTreatmentCSS(spatialTokens, treatmentOverrides, themeDecorators, themeName) {
9
+ function generateTreatmentCSS(spatialTokens, treatmentOverrides, themeDecorators, themeName, themeDecoratorDefinitions) {
10
10
  const lines = [];
11
+ const decoratorAnimationNames = /* @__PURE__ */ new Set();
11
12
  lines.push("/* Generated by @decantr/cli \u2014 Visual Treatment System */");
12
13
  lines.push("");
13
14
  lines.push("@layer treatments {");
@@ -195,9 +196,9 @@ ${themeBody}
195
196
  ["font-size", "0.75rem"],
196
197
  ["font-weight", "500"],
197
198
  ["padding", "0.125rem 0.5rem"],
198
- ["margin-top", "calc(var(--d-annotation-mt) * var(--d-density-scale, 1))"],
199
199
  ["border-radius", "var(--d-radius-full)"],
200
- ["background", "var(--d-surface)"],
200
+ ["background", "color-mix(in srgb, var(--d-surface-raised) 88%, transparent)"],
201
+ ["border", "1px solid color-mix(in srgb, var(--d-border) 72%, transparent)"],
201
202
  ["color", "var(--d-text-muted)"],
202
203
  ["white-space", "nowrap"]
203
204
  ]);
@@ -247,10 +248,47 @@ ${themeBody}
247
248
  lines.push("}");
248
249
  lines.push("");
249
250
  lines.push("} /* end @layer treatments */");
251
+ const decoratorRules = [];
252
+ if (themeDecoratorDefinitions) {
253
+ for (const [className, definition] of Object.entries(themeDecoratorDefinitions)) {
254
+ const props = definition?.suggested_properties ?? {};
255
+ const entries = Object.entries(props);
256
+ if (entries.length === 0) continue;
257
+ decoratorRules.push(`.${className} {`);
258
+ for (const [prop, value] of entries) {
259
+ decoratorRules.push(` ${prop}: ${value};`);
260
+ if (prop === "animation") {
261
+ const animationName = value.split(/\s+/)[0]?.trim();
262
+ if (animationName) decoratorAnimationNames.add(animationName);
263
+ }
264
+ }
265
+ decoratorRules.push("}");
266
+ decoratorRules.push("");
267
+ }
268
+ }
269
+ const decoratorKeyframes = [];
270
+ if (decoratorAnimationNames.has("carbon-fade-slide")) {
271
+ decoratorKeyframes.push("@keyframes carbon-fade-slide {");
272
+ decoratorKeyframes.push(" from { opacity: 0; transform: translateY(12px); }");
273
+ decoratorKeyframes.push(" to { opacity: 1; transform: translateY(0); }");
274
+ decoratorKeyframes.push("}");
275
+ decoratorKeyframes.push("");
276
+ }
277
+ if (decoratorAnimationNames.has("pulse")) {
278
+ decoratorKeyframes.push("@keyframes pulse {");
279
+ decoratorKeyframes.push(" 0%, 100% { opacity: 1; }");
280
+ decoratorKeyframes.push(" 50% { opacity: 0.5; }");
281
+ decoratorKeyframes.push("}");
282
+ decoratorKeyframes.push("");
283
+ }
284
+ const decoratorComments = themeDecorators ? Object.entries(themeDecorators).map(([name, description]) => ` /* .${name}: ${description} */`).join("\n") : " /* No theme decorators available. */";
285
+ const decoratorBody = decoratorRules.length > 0 ? `${decoratorRules.join("\n")}${decoratorKeyframes.length > 0 ? `
286
+ ${decoratorKeyframes.join("\n")}` : ""}${decoratorComments ? `
287
+ ${decoratorComments}` : ""}` : `${decoratorComments}
288
+ /* Canonical decorator CSS should be derived from theme decorator definitions when available. */`;
250
289
  const decoratorBlock = `
251
290
  @layer decorators {
252
- /* Decorator CSS is AI-generated from structured definitions in section context files. */
253
- /* See .decantr/context/section-*.md for intent, suggested properties, and usage guidance. */
291
+ ${decoratorBody}
254
292
  }
255
293
  `;
256
294
  lines.push(decoratorBlock);
@@ -598,6 +636,7 @@ function mapRegistryThemeToThemeData(theme) {
598
636
  typography: theme.typography,
599
637
  motion: theme.motion,
600
638
  decorators: theme.decorators,
639
+ decorator_definitions: theme.decorator_definitions,
601
640
  treatments: theme.treatments,
602
641
  spatial: theme.spatial,
603
642
  radius: theme.radius,
@@ -777,11 +816,15 @@ body {
777
816
  transform: translateY(0);
778
817
  }
779
818
 
780
- img, picture, video, canvas, svg {
819
+ img, picture, video, canvas {
781
820
  display: block;
782
821
  max-width: 100%;
783
822
  }
784
823
 
824
+ svg {
825
+ max-width: 100%;
826
+ }
827
+
785
828
  input, button, textarea, select {
786
829
  font: inherit;
787
830
  color: inherit;
@@ -1009,10 +1052,14 @@ import './styles/global.css'; // Resets
1009
1052
  ### Runtime Rules
1010
1053
 
1011
1054
  - Use the real \`@decantr/css\` runtime for atoms. If \`package.json\` does not already depend on \`@decantr/css\`, add it before building.
1055
+ - If \`package.json\`, app entry files, or router/runtime files are absent, create them explicitly for the declared target instead of assuming a hidden starter already exists.
1012
1056
  - Do **not** create local atom-runtime substitutes such as \`src/lib/css.js\`, \`src/lib/css.ts\`, or hand-written \`src/styles/atoms.css\` files unless the task explicitly asks for a fallback runtime.
1013
1057
  - Keep atoms in \`css(...)\`, treatments as semantic classes, and theme decorators as additive classes. Do not blur those roles together.
1058
+ - Do **not** use inline visual style values or component-scoped \`<style>\` tags as the primary styling path. Colors, spacing, borders, shadows, gradients, and transitions should come from atoms, treatments, decorators, or CSS variables. Inline styles are only acceptable for truly dynamic geometry that cannot be expressed through the contract.
1014
1059
  - Use \`d-control\` as the default semantic treatment for inputs, selects, and textareas. Theme decorators such as \`carbon-input\` are additive and should only layer on when the section or theme contract explicitly calls for them.
1015
1060
  - Use loading decorators such as \`carbon-skeleton\` as optional enhancement on top of a structurally correct loading state \u2014 they do not replace the need for a real loading/skeleton branch.
1061
+ - Shells own spacing, centering, and scroll containers. Pages should not duplicate shell responsibilities with extra full-height wrappers, max-width wrappers, or page-local padding unless the route contract explicitly requires it.
1062
+ - If a required decorator class is referenced in the generated contract but missing from generated CSS, report that contract gap instead of inventing a parallel visual system.
1016
1063
 
1017
1064
  ### Visual Treatments
1018
1065
 
@@ -1044,12 +1091,19 @@ Atoms + treatment + theme decorator:
1044
1091
 
1045
1092
  \`\`\`tsx
1046
1093
  // Responsive prefix \u2014 applies at breakpoint and above:
1047
- css('_col sm:_row')
1094
+ css('_col _sm:row')
1048
1095
 
1049
1096
  // Pseudo prefix:
1050
- css('hover:_opacity80')
1097
+ css('_bgprimary _h:bgprimary/80')
1051
1098
  \`\`\`
1052
1099
 
1100
+ ### Prefix and Arbitrary Value Syntax
1101
+
1102
+ - Responsive prefixes are part of the atom token itself: \`_sm:gc2\`, \`_md:flex\`, \`_lg:row\`.
1103
+ - Pseudo prefixes are also token-prefixed: \`_h:bgprimary/80\`, \`_f:borderprimary\`, \`_fv:shadowmd\`.
1104
+ - Arbitrary values use square brackets when the standard scale is not enough: \`_w[512px]\`, \`_h[100vh]\`, \`_p[clamp(1rem,3vw,2rem)]\`, \`_z[40]\`.
1105
+ - When you see bracket atoms in shell or page contracts, treat them as first-class Decantr syntax, not as an error or a cue to fall back to inline styles.
1106
+
1053
1107
  ### Atom Reference
1054
1108
 
1055
1109
  #### Display
@@ -1226,7 +1280,7 @@ css('hover:_opacity80')
1226
1280
  | \`_trans\` | \`transition:all 0.15s ease\` |
1227
1281
  | \`_visible\`, \`_invisible\` | visibility |
1228
1282
 
1229
- Responsive prefixes: \`_sm:\`, \`_md:\`, \`_lg:\` (e.g. \`_md:gc2\`, \`_lg:gc4\`, \`_sm:flex\`).
1283
+ Responsive prefixes: \`_sm:\`, \`_md:\`, \`_lg:\`, \`_xl:\` (e.g. \`_sm:gc2\`, \`_md:flex\`, \`_lg:row\`).
1230
1284
 
1231
1285
  ### Section Labels
1232
1286
 
@@ -1245,6 +1299,7 @@ If the theme provides motion tokens, apply the \`entrance-fade\` class to page c
1245
1299
  ### Navigation Shortcuts
1246
1300
 
1247
1301
  If the essence defines hotkeys or command_palette, implement as keyboard event listeners (useEffect + keydown) \u2014 not as visible UI text.
1302
+ Missing declared navigation features are contract drift, not optional polish.
1248
1303
 
1249
1304
  ### Design Tokens
1250
1305
 
@@ -2141,7 +2196,8 @@ async function refreshDerivedFiles(projectRoot, essence, registry, prefetchedThe
2141
2196
  spatialTokens,
2142
2197
  themeData?.treatments,
2143
2198
  themeData?.decorators,
2144
- themeName
2199
+ themeName,
2200
+ themeData?.decorator_definitions
2145
2201
  );
2146
2202
  const personalityCSS = generatePersonalityCSS(personality || [], themeData || {});
2147
2203
  treatmentCSS += personalityCSS;
@@ -3112,9 +3168,18 @@ function generateScaffoldContext(input) {
3112
3168
  lines.push("");
3113
3169
  if (navigation.command_palette) {
3114
3170
  lines.push("- Command palette: enabled");
3171
+ lines.push("- Requirement: implement a real keyboard-triggered command palette, not just placeholder UI text.");
3115
3172
  }
3116
3173
  if (navigation.hotkeys && navigation.hotkeys.length > 0) {
3117
3174
  lines.push(`- Hotkeys: ${navigation.hotkeys.length} configured`);
3175
+ for (const hotkey of navigation.hotkeys) {
3176
+ if (typeof hotkey === "object" && hotkey !== null && typeof hotkey.key === "string") {
3177
+ const target = [hotkey.label, hotkey.route || hotkey.action].filter(Boolean).join(" \u2014 ");
3178
+ lines.push(` - \`${hotkey.key}\`${target ? `: ${target}` : ""}`);
3179
+ }
3180
+ }
3181
+ lines.push("- Requirement: implement these bindings as real keyboard shortcuts, not as decorative text.");
3182
+ lines.push("- Presentation rule: do not append hotkey text to persistent nav labels, breadcrumbs, or page titles unless the shell or route contract explicitly requests visible shortcut hints.");
3118
3183
  }
3119
3184
  lines.push("");
3120
3185
  }