@decantr/cli 2.4.0 → 2.5.0

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,7 +14,7 @@ npm install -D @decantr/cli
14
14
  Or run it without installing:
15
15
 
16
16
  ```bash
17
- npx @decantr/cli new my-app --blueprint=agent-marketplace
17
+ npx @decantr/cli new my-app --blueprint=esports-hq
18
18
  ```
19
19
 
20
20
  Use `decantr new` for a greenfield workspace in a fresh directory. With a blueprint/archetype it uses the runnable adapter and Decantr CSS; without registry content it creates a contract-only workspace unless you explicitly pass `--adoption=decantr-css`.
@@ -68,17 +68,18 @@ Brownfield analysis also writes `.decantr/doctrine-map.json`, a ranked source-pr
68
68
  - produces local Project Health reports, Evidence Bundles, workspace health, and a localhost Studio dashboard for end-user drift triage
69
69
  - audits local registry content repositories with Content Health reports for schema, reference, and quality coverage
70
70
  - searches the registry and showcase benchmark corpus
71
+ - filters blueprints through public portfolio sets: `All`, `Featured`, `Certified`, and opt-in `Labs`
71
72
  - syncs paginated hosted registry content into a full slug-keyed local cache for offline guards and context generation
72
73
  - validates, refreshes, and maintains `decantr.essence.json`
73
74
 
74
75
  ## Common Commands
75
76
 
76
77
  ```bash
77
- decantr new my-app --blueprint=agent-marketplace
78
+ decantr new my-app --blueprint=esports-hq
78
79
  decantr analyze
79
80
  decantr init --existing --accept-proposal
80
81
  decantr check --brownfield
81
- decantr init --existing --blueprint=agent-marketplace
82
+ decantr init --existing --blueprint=esports-hq
82
83
  decantr init --workflow=greenfield --adoption=contract-only
83
84
  decantr rules preview
84
85
  decantr rules apply
@@ -92,6 +93,9 @@ decantr telemetry explain
92
93
  decantr telemetry link --enable --org <org-slug>
93
94
  decantr content-health --ci --fail-on error
94
95
  decantr registry summary --namespace @official --json
96
+ decantr list blueprints --blueprint-set featured
97
+ decantr list blueprints --blueprint-set certified
98
+ decantr search dashboard --type blueprint --blueprint-set labs
95
99
  decantr showcase verification --json
96
100
  ```
97
101
 
@@ -210,7 +214,7 @@ pnpm --filter @decantr/cli certify:blueprints -- --blueprints=portfolio,legal-re
210
214
  Offline blueprint scaffolding expects a real local content source:
211
215
 
212
216
  ```bash
213
- DECANTR_CONTENT_DIR=/path/to/decantr-content decantr new my-app --blueprint=agent-marketplace --offline
217
+ DECANTR_CONTENT_DIR=/path/to/decantr-content decantr new my-app --blueprint=esports-hq --offline
214
218
  ```
215
219
 
216
220
  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.
package/dist/bin.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import "./chunk-H6TIXG5K.js";
3
- import "./chunk-PEGMSXDJ.js";
2
+ import "./chunk-HO3OLDPQ.js";
3
+ import "./chunk-V3XAQWKD.js";
4
4
  import "./chunk-IEW2QFYI.js";
@@ -14,7 +14,7 @@ import {
14
14
  scaffoldProject,
15
15
  syncRegistry,
16
16
  writeExecutionPackBundleArtifacts
17
- } from "./chunk-PEGMSXDJ.js";
17
+ } from "./chunk-V3XAQWKD.js";
18
18
  import {
19
19
  buildGuardRegistryContext,
20
20
  createDoctrineMap,
@@ -39,9 +39,11 @@ import { evaluateGuard, isV4 as isV47, validateEssence as validateEssence2 } fro
39
39
  import {
40
40
  CONTENT_TYPE_TO_API_CONTENT_TYPE as CONTENT_TYPE_TO_API_CONTENT_TYPE3,
41
41
  CONTENT_TYPES as GET_CONTENT_TYPES,
42
+ getBlueprintPortfolioMetadata,
42
43
  isApiContentType,
43
44
  isContentIntelligenceSource,
44
45
  isContentType as isGetContentType,
46
+ isPublicBlueprintSet,
45
47
  API_CONTENT_TYPES as LIST_CONTENT_TYPES,
46
48
  RegistryAPIClient as RegistryAPIClient3
47
49
  } from "@decantr/registry";
@@ -5624,6 +5626,7 @@ function extractPatternName(item) {
5624
5626
  function generateGreenfieldPrompt(ctx) {
5625
5627
  const lines = [];
5626
5628
  const usesDecantrCss = ctx.adoptionMode === "decantr-css" || !ctx.adoptionMode;
5629
+ const hasCompiledPacks = ctx.hasCompiledPacks ?? true;
5627
5630
  lines.push("Build this greenfield application using the Decantr design system.");
5628
5631
  lines.push("");
5629
5632
  if (ctx.blueprint) lines.push(`Blueprint: ${ctx.blueprint}`);
@@ -5640,44 +5643,66 @@ function generateGreenfieldPrompt(ctx) {
5640
5643
  "This workspace is a new Decantr scaffold. Use the contract to create or extend the runtime deliberately, not to reverse-engineer a hidden starter."
5641
5644
  );
5642
5645
  lines.push("");
5643
- lines.push("Treat the compiled execution-pack files as the primary source of truth.");
5644
- lines.push(
5645
- "Use narrative docs only as secondary explanation when the compiled packs are not enough."
5646
- );
5646
+ if (hasCompiledPacks) {
5647
+ lines.push("Treat the compiled execution-pack files as the primary source of truth.");
5648
+ lines.push(
5649
+ "Use narrative docs only as secondary explanation when the compiled packs are not enough."
5650
+ );
5651
+ } else {
5652
+ lines.push(
5653
+ "Compiled execution-pack files are not present in this scaffold. Treat narrative Decantr context as the temporary source of truth and run `decantr refresh` after fixing the reported validation issue."
5654
+ );
5655
+ }
5647
5656
  lines.push(
5648
5657
  "Use only files present in this workspace as the source of truth. If local scaffold files disagree, stop and report the mismatch instead of relying on external Decantr assumptions or prior examples."
5649
5658
  );
5650
5659
  lines.push("");
5651
5660
  lines.push("Read in this order:");
5652
- lines.push(
5653
- "1. .decantr/context/scaffold-pack.md \u2014 the canonical compiled contract. Contains route plan, shell layouts, navigation, Required Theme Decorators, and project-wide execution rules."
5654
- );
5655
- lines.push(
5656
- "2. Before section work, read the matching .decantr/context/section-*-pack.md first, then .decantr/context/section-*.md only for extra slot/layout detail."
5657
- );
5658
- lines.push(
5659
- "3. Before route work, read the matching .decantr/context/page-*-pack.md file. Its pattern layout and interaction checklists are contract."
5660
- );
5661
- lines.push(
5662
- "4. .decantr/context/scaffold.md for broader topology, route map, and voice guidance after the compact packs are understood."
5663
- );
5664
- lines.push(
5665
- "5. DECANTR.md as a lookup reference for atoms, treatments, decorators, interaction implementations, and guard rules. Do not let narrative docs override compiled packs."
5666
- );
5667
- lines.push("");
5668
- lines.push("\u2550\u2550\u2550 INTERACTIONS ARE CONTRACT, NOT GUIDANCE \u2550\u2550\u2550");
5669
- lines.push("");
5670
- lines.push(
5671
- 'Each page pack lists "Interactions (MUST implement each)" per pattern. Implement the actual behavior, not visible text saying it exists. Use DECANTR.md only to look up the canonical implementation shape when needed.'
5672
- );
5673
- lines.push(
5674
- "Examples: pointer handlers for dragging/panning, onWheel for zoom, onKeyDown + tabIndex for keyboard navigation, IntersectionObserver for scroll reveal, state updates for real-time indicators, and d-* motion classes where the contract calls for animation."
5675
- );
5676
- lines.push("");
5677
- lines.push(
5678
- "`decantr check --strict` fails when a declared interaction has no matching implementation."
5679
- );
5680
- lines.push("");
5661
+ if (hasCompiledPacks) {
5662
+ lines.push(
5663
+ "1. .decantr/context/scaffold-pack.md \u2014 the canonical compiled contract. Contains route plan, shell layouts, navigation, Required Theme Decorators, and project-wide execution rules."
5664
+ );
5665
+ lines.push(
5666
+ "2. Before section work, read the matching .decantr/context/section-*-pack.md first, then .decantr/context/section-*.md only for extra slot/layout detail."
5667
+ );
5668
+ lines.push(
5669
+ "3. Before route work, read the matching .decantr/context/page-*-pack.md file. Its pattern layout and interaction checklists are contract."
5670
+ );
5671
+ lines.push(
5672
+ "4. .decantr/context/scaffold.md for broader topology, route map, and voice guidance after the compact packs are understood."
5673
+ );
5674
+ lines.push(
5675
+ "5. DECANTR.md as a lookup reference for atoms, treatments, decorators, interaction implementations, and guard rules. Do not let narrative docs override compiled packs."
5676
+ );
5677
+ lines.push("");
5678
+ lines.push("\u2550\u2550\u2550 INTERACTIONS ARE CONTRACT, NOT GUIDANCE \u2550\u2550\u2550");
5679
+ lines.push("");
5680
+ lines.push(
5681
+ 'Each page pack lists "Interactions (MUST implement each)" per pattern. Implement the actual behavior, not visible text saying it exists. Use DECANTR.md only to look up the canonical implementation shape when needed.'
5682
+ );
5683
+ lines.push(
5684
+ "Examples: pointer handlers for dragging/panning, onWheel for zoom, onKeyDown + tabIndex for keyboard navigation, IntersectionObserver for scroll reveal, state updates for real-time indicators, and d-* motion classes where the contract calls for animation."
5685
+ );
5686
+ lines.push("");
5687
+ lines.push(
5688
+ "`decantr check --strict` fails when a declared interaction has no matching implementation."
5689
+ );
5690
+ lines.push("");
5691
+ } else {
5692
+ lines.push(
5693
+ "1. .decantr/context/scaffold.md for topology, route map, voice, and section inventory."
5694
+ );
5695
+ lines.push(
5696
+ "2. The matching .decantr/context/section-*.md file before implementing each section."
5697
+ );
5698
+ lines.push(
5699
+ "3. DECANTR.md for atoms, treatments, decorators, interaction shapes, and guard rules."
5700
+ );
5701
+ lines.push(
5702
+ "4. Run `decantr refresh` and switch to compiled pack files once validation passes."
5703
+ );
5704
+ lines.push("");
5705
+ }
5681
5706
  lines.push("\u2550\u2550\u2550 STYLING ADOPTION \u2550\u2550\u2550");
5682
5707
  lines.push("");
5683
5708
  if (ctx.adoptionMode === "contract-only") {
@@ -5764,12 +5789,18 @@ function generateGreenfieldPrompt(ctx) {
5764
5789
  lines.push("");
5765
5790
  lines.push("\u2550\u2550\u2550 THEME DECORATOR CONTRACT \u2014 APPLY OR THE THEME DOES NOT LAND \u2550\u2550\u2550");
5766
5791
  lines.push("");
5767
- lines.push(
5768
- 'Each theme ships namespaced decorator classes (`clean-card`, `lum-glass`, `carbon-canvas`, `paper-card`, etc.). Apply the scaffold-pack.md "Required Theme Decorators" as additive classes alongside d-* treatments so the theme lands as more than token colors.'
5769
- );
5770
- lines.push(
5771
- "Section packs may point back to the scaffold-pack table; scaffold-pack.md is authoritative."
5772
- );
5792
+ if (hasCompiledPacks) {
5793
+ lines.push(
5794
+ 'Each theme ships namespaced decorator classes (`clean-card`, `lum-glass`, `carbon-canvas`, `paper-card`, etc.). Apply the scaffold-pack.md "Required Theme Decorators" as additive classes alongside d-* treatments so the theme lands as more than token colors.'
5795
+ );
5796
+ lines.push(
5797
+ "Section packs may point back to the scaffold-pack table; scaffold-pack.md is authoritative."
5798
+ );
5799
+ } else {
5800
+ lines.push(
5801
+ "Each theme ships namespaced decorator classes (`clean-card`, `lum-glass`, `carbon-canvas`, `paper-card`, etc.). Use DECANTR.md and section context to apply the theme, then rerun `decantr refresh` to restore the authoritative decorator table."
5802
+ );
5803
+ }
5773
5804
  lines.push("");
5774
5805
  lines.push("\u2550\u2550\u2550 HARD RULES (NON-NEGOTIABLE) \u2550\u2550\u2550");
5775
5806
  lines.push("");
@@ -5790,7 +5821,7 @@ function generateGreenfieldPrompt(ctx) {
5790
5821
  "- Use lucide-react for ALL iconography (already in package.json). Pick semantic icons (Bot, Activity, Database, Search) over generic ones. Do NOT inline SVGs for icons that have Lucide equivalents."
5791
5822
  );
5792
5823
  lines.push(
5793
- "- Section Directives in section packs are execution rules for layout proportions, treatment stacks, copy conventions, and pattern fitness."
5824
+ hasCompiledPacks ? "- Section Directives in section packs are execution rules for layout proportions, treatment stacks, copy conventions, and pattern fitness." : "- Section context files are execution rules for layout proportions, treatment stacks, copy conventions, and pattern fitness until compiled packs are restored."
5794
5825
  );
5795
5826
  lines.push(
5796
5827
  "- Filter chip rows / tab strips use `d-step-chip[data-step-state]`, not bare `d-interactive` buttons."
@@ -5804,9 +5835,11 @@ function generateGreenfieldPrompt(ctx) {
5804
5835
  lines.push("");
5805
5836
  lines.push("\u2550\u2550\u2550 IMPLEMENTATION RULES \u2550\u2550\u2550");
5806
5837
  lines.push(
5807
- "- Do not invent routes, sections, shells, themes, or features beyond the compiled packs."
5838
+ hasCompiledPacks ? "- Do not invent routes, sections, shells, themes, or features beyond the compiled packs." : "- Do not invent routes, sections, shells, themes, or features beyond decantr.essence.json and generated narrative context."
5839
+ );
5840
+ lines.push(
5841
+ hasCompiledPacks ? "- Prefer scaffold-pack, section-pack, and page-pack guidance over narrative docs." : "- Prefer decantr.essence.json and generated section context over assumptions from prior examples."
5808
5842
  );
5809
- lines.push("- Prefer scaffold-pack, section-pack, and page-pack guidance over narrative docs.");
5810
5843
  lines.push(
5811
5844
  "- Start with the shell layouts and route structure first, then build section pages route by route."
5812
5845
  );
@@ -5850,7 +5883,9 @@ function generateGreenfieldPrompt(ctx) {
5850
5883
  lines.push("");
5851
5884
  lines.push("\u2550\u2550\u2550 EXECUTION FLOW \u2550\u2550\u2550");
5852
5885
  lines.push("- Build the shell and shared layout first.");
5853
- lines.push("- Then implement each section's pages using the matching section and page packs.");
5886
+ lines.push(
5887
+ hasCompiledPacks ? "- Then implement each section's pages using the matching section and page packs." : "- Then implement each section's pages using decantr.essence.json and the matching section context."
5888
+ );
5854
5889
  lines.push(
5855
5890
  "- After implementation, run `decantr check` (primary gate) and `decantr audit` (supplementary diagnostics)."
5856
5891
  );
@@ -6495,7 +6530,41 @@ async function printHostedProjectAudit(namespace, jsonOutput = false, essencePat
6495
6530
  );
6496
6531
  printProjectAuditReport(report);
6497
6532
  }
6498
- async function cmdSearch(query, type, sort, recommended, intelligenceSource) {
6533
+ function formatBlueprintPortfolioSummary(value) {
6534
+ const portfolio = getBlueprintPortfolioMetadata(value);
6535
+ if (!portfolio) return null;
6536
+ const labels = [];
6537
+ if (portfolio.artifact.status === "certified") labels.push("Certified");
6538
+ if (portfolio.visibility === "featured") labels.push("Featured");
6539
+ if (portfolio.visibility === "labs") labels.push("Labs");
6540
+ if (portfolio.visibility === "hidden") labels.push("Folded");
6541
+ if (labels.length === 0) labels.push("All");
6542
+ const alternative = portfolio.recommended_alternative ? `; recommended alternative: ${portfolio.recommended_alternative}` : "";
6543
+ return `Blueprint set: ${labels.join(" + ")}${alternative}`;
6544
+ }
6545
+ function printBlueprintPortfolioNotice(blueprint) {
6546
+ const portfolio = getBlueprintPortfolioMetadata(blueprint);
6547
+ if (!portfolio) return;
6548
+ if (portfolio.visibility === "hidden" || portfolio.maturity === "fold-candidate") {
6549
+ console.log(
6550
+ `${YELLOW9} Warning:${RESET14} blueprint "${blueprint.id}" is folded out of public browsing.`
6551
+ );
6552
+ if (portfolio.recommended_alternative) {
6553
+ console.log(
6554
+ dim3(
6555
+ ` Recommended public alternative: decantr new <name> --blueprint=${portfolio.recommended_alternative}`
6556
+ )
6557
+ );
6558
+ }
6559
+ return;
6560
+ }
6561
+ if (portfolio.visibility === "labs") {
6562
+ console.log(
6563
+ `${YELLOW9} Note:${RESET14} blueprint "${blueprint.id}" is a Labs blueprint; direct scaffolding is supported, but it is not a default recommendation yet.`
6564
+ );
6565
+ }
6566
+ }
6567
+ async function cmdSearch(query, type, sort, recommended, intelligenceSource, blueprintSet) {
6499
6568
  const apiClient = getAPIClient();
6500
6569
  try {
6501
6570
  const response = await apiClient.search({
@@ -6503,7 +6572,8 @@ async function cmdSearch(query, type, sort, recommended, intelligenceSource) {
6503
6572
  type,
6504
6573
  sort,
6505
6574
  recommended,
6506
- intelligenceSource
6575
+ intelligenceSource,
6576
+ blueprintSet
6507
6577
  });
6508
6578
  const results = response.results;
6509
6579
  if (results.length === 0) {
@@ -6518,6 +6588,12 @@ async function cmdSearch(query, type, sort, recommended, intelligenceSource) {
6518
6588
  if (intelligenceSummary) {
6519
6589
  console.log(` ${dim3(intelligenceSummary)}`);
6520
6590
  }
6591
+ const portfolioSummary = formatBlueprintPortfolioSummary(
6592
+ r.blueprint_portfolio
6593
+ );
6594
+ if (portfolioSummary) {
6595
+ console.log(` ${dim3(portfolioSummary)}`);
6596
+ }
6521
6597
  console.log("");
6522
6598
  }
6523
6599
  } catch {
@@ -6657,7 +6733,7 @@ async function cmdValidate(path) {
6657
6733
  } catch {
6658
6734
  }
6659
6735
  }
6660
- async function cmdList(type, sort, recommended, intelligenceSource) {
6736
+ async function cmdList(type, sort, recommended, intelligenceSource, blueprintSet) {
6661
6737
  if (!isApiContentType(type)) {
6662
6738
  console.error(
6663
6739
  error3(`Invalid type "${type}". Must be one of: ${LIST_CONTENT_TYPES.join(", ")}`)
@@ -6673,7 +6749,8 @@ async function cmdList(type, sort, recommended, intelligenceSource) {
6673
6749
  void 0,
6674
6750
  sort,
6675
6751
  recommended,
6676
- intelligenceSource
6752
+ intelligenceSource,
6753
+ blueprintSet
6677
6754
  );
6678
6755
  const items = result.data.items;
6679
6756
  if (items.length === 0) {
@@ -6709,6 +6786,12 @@ async function cmdList(type, sort, recommended, intelligenceSource) {
6709
6786
  if (intelligenceSummary) {
6710
6787
  console.log(` ${dim3(intelligenceSummary)}`);
6711
6788
  }
6789
+ const portfolioSummary = formatBlueprintPortfolioSummary(
6790
+ item.blueprint_portfolio ?? item
6791
+ );
6792
+ if (portfolioSummary) {
6793
+ console.log(` ${dim3(portfolioSummary)}`);
6794
+ }
6712
6795
  }
6713
6796
  }
6714
6797
  }
@@ -7146,6 +7229,7 @@ ${YELLOW9}You're offline. Scaffolding Decantr default.${RESET14}`);
7146
7229
  const blueprintResult = await registryClient.fetchBlueprint(options.blueprint);
7147
7230
  if (blueprintResult) {
7148
7231
  const blueprint = blueprintResult.data;
7232
+ printBlueprintPortfolioNotice(blueprint);
7149
7233
  if (blueprint.theme) {
7150
7234
  if (!userExplicit.theme && blueprint.theme.id) {
7151
7235
  options.theme = blueprint.theme.id;
@@ -7353,19 +7437,34 @@ ${YELLOW9}You're offline. Scaffolding Decantr default.${RESET14}`);
7353
7437
  )
7354
7438
  );
7355
7439
  }
7440
+ const hasCompiledPacks = existsSync26(join27(projectRoot, ".decantr", "context", "scaffold-pack.md"));
7356
7441
  console.log("");
7357
7442
  console.log(" Next steps:");
7358
- console.log(
7359
- " 1. Read .decantr/context/scaffold-pack.md first as the primary compiled contract"
7360
- );
7361
- console.log(
7362
- " 2. Read .decantr/context/scaffold.md for broader topology, route map, and voice guidance"
7363
- );
7364
- console.log(" 3. Read the matching section and page packs before implementing each route");
7365
- console.log(" 4. Use DECANTR.md as a lookup reference for atoms, treatments, and guard rules");
7366
- console.log(" 5. Build the shell and route structure first, then implement the pages");
7367
- console.log(" 6. Run decantr check and decantr audit after implementation");
7368
- console.log(" 7. Explore more at decantr.ai/registry");
7443
+ if (hasCompiledPacks) {
7444
+ console.log(
7445
+ " 1. Read .decantr/context/scaffold-pack.md first as the primary compiled contract"
7446
+ );
7447
+ console.log(
7448
+ " 2. Read .decantr/context/scaffold.md for broader topology, route map, and voice guidance"
7449
+ );
7450
+ console.log(" 3. Read the matching section and page packs before implementing each route");
7451
+ console.log(
7452
+ " 4. Use DECANTR.md as a lookup reference for atoms, treatments, and guard rules"
7453
+ );
7454
+ console.log(" 5. Build the shell and route structure first, then implement the pages");
7455
+ console.log(" 6. Run decantr check and decantr audit after implementation");
7456
+ console.log(" 7. Explore more at decantr.ai/registry");
7457
+ } else {
7458
+ console.log(" 1. Fix the validation issue reported above");
7459
+ console.log(" 2. Run decantr refresh to restore compiled execution packs");
7460
+ console.log(
7461
+ " 3. Until packs exist, read .decantr/context/scaffold.md and section context files"
7462
+ );
7463
+ console.log(
7464
+ " 4. Use DECANTR.md as a lookup reference for atoms, treatments, and guard rules"
7465
+ );
7466
+ console.log(" 5. Run decantr check and decantr audit after implementation");
7467
+ }
7369
7468
  console.log("");
7370
7469
  console.log(" Commands:");
7371
7470
  console.log(` ${cyan3("decantr status")} Project health`);
@@ -7416,7 +7515,8 @@ Validation warnings: ${validation.errors.join(", ")}`));
7416
7515
  pages: promptPages,
7417
7516
  personality: options.personality,
7418
7517
  features: options.features,
7419
- guard: options.guard
7518
+ guard: options.guard,
7519
+ hasCompiledPacks
7420
7520
  };
7421
7521
  const curatedPrompt = generateCuratedPrompt(promptCtx);
7422
7522
  console.log("");
@@ -8178,7 +8278,7 @@ async function main() {
8178
8278
  break;
8179
8279
  }
8180
8280
  case "upgrade": {
8181
- const { cmdUpgrade } = await import("./upgrade-XTTGHFG7.js");
8281
+ const { cmdUpgrade } = await import("./upgrade-U2BTWJJJ.js");
8182
8282
  const applyFlag = args.includes("--apply");
8183
8283
  await cmdUpgrade(process.cwd(), { apply: applyFlag });
8184
8284
  break;
@@ -8287,7 +8387,7 @@ async function main() {
8287
8387
  if (!query) {
8288
8388
  console.error(
8289
8389
  error3(
8290
- "Usage: decantr search <query> [--type <type>] [--sort <recommended|recent|name>] [--source <authored|benchmark|hybrid>]"
8390
+ "Usage: decantr search <query> [--type <type>] [--sort <recommended|recent|name>] [--source <authored|benchmark|hybrid>] [--blueprint-set <all|featured|certified|labs>]"
8291
8391
  )
8292
8392
  );
8293
8393
  process.exitCode = 1;
@@ -8299,6 +8399,18 @@ async function main() {
8299
8399
  const sort = sortIdx !== -1 ? args[sortIdx + 1] : void 0;
8300
8400
  const sourceIdx = args.indexOf("--source");
8301
8401
  const intelligenceSource = sourceIdx !== -1 ? args[sourceIdx + 1] : void 0;
8402
+ const blueprintSetIdx = args.indexOf("--blueprint-set");
8403
+ const rawBlueprintSet = args.includes("--labs") ? "labs" : blueprintSetIdx !== -1 ? args[blueprintSetIdx + 1] : void 0;
8404
+ const blueprintSet = rawBlueprintSet && isPublicBlueprintSet(rawBlueprintSet) ? rawBlueprintSet : void 0;
8405
+ if (rawBlueprintSet && !blueprintSet) {
8406
+ console.error(
8407
+ error3(
8408
+ `Invalid blueprint set "${rawBlueprintSet}". Must be one of: all, featured, certified, labs.`
8409
+ )
8410
+ );
8411
+ process.exitCode = 1;
8412
+ return;
8413
+ }
8302
8414
  if (intelligenceSource && !isContentIntelligenceSource(intelligenceSource)) {
8303
8415
  console.error(
8304
8416
  error3(
@@ -8309,7 +8421,7 @@ async function main() {
8309
8421
  return;
8310
8422
  }
8311
8423
  const recommended = args.includes("--recommended");
8312
- await cmdSearch(query, type, sort, recommended, intelligenceSource);
8424
+ await cmdSearch(query, type, sort, recommended, intelligenceSource, blueprintSet);
8313
8425
  break;
8314
8426
  }
8315
8427
  case "suggest": {
@@ -8340,7 +8452,7 @@ async function main() {
8340
8452
  if (!type) {
8341
8453
  console.error(
8342
8454
  error3(
8343
- "Usage: decantr list <type> [--sort <recommended|recent|name>] [--source <authored|benchmark|hybrid>]"
8455
+ "Usage: decantr list <type> [--sort <recommended|recent|name>] [--source <authored|benchmark|hybrid>] [--blueprint-set <all|featured|certified|labs>]"
8344
8456
  )
8345
8457
  );
8346
8458
  process.exitCode = 1;
@@ -8350,6 +8462,18 @@ async function main() {
8350
8462
  const sort = sortIdx !== -1 ? args[sortIdx + 1] : void 0;
8351
8463
  const sourceIdx = args.indexOf("--source");
8352
8464
  const intelligenceSource = sourceIdx !== -1 ? args[sourceIdx + 1] : void 0;
8465
+ const blueprintSetIdx = args.indexOf("--blueprint-set");
8466
+ const rawBlueprintSet = args.includes("--labs") ? "labs" : blueprintSetIdx !== -1 ? args[blueprintSetIdx + 1] : void 0;
8467
+ const blueprintSet = rawBlueprintSet && isPublicBlueprintSet(rawBlueprintSet) ? rawBlueprintSet : void 0;
8468
+ if (rawBlueprintSet && !blueprintSet) {
8469
+ console.error(
8470
+ error3(
8471
+ `Invalid blueprint set "${rawBlueprintSet}". Must be one of: all, featured, certified, labs.`
8472
+ )
8473
+ );
8474
+ process.exitCode = 1;
8475
+ return;
8476
+ }
8353
8477
  if (intelligenceSource && !isContentIntelligenceSource(intelligenceSource)) {
8354
8478
  console.error(
8355
8479
  error3(
@@ -8360,7 +8484,7 @@ async function main() {
8360
8484
  return;
8361
8485
  }
8362
8486
  const recommended = args.includes("--recommended");
8363
- await cmdList(type, sort, recommended, intelligenceSource);
8487
+ await cmdList(type, sort, recommended, intelligenceSource, blueprintSet);
8364
8488
  break;
8365
8489
  }
8366
8490
  case "showcase": {
@@ -133,7 +133,7 @@ var RegistryClient = class {
133
133
  * Unified fetch for a content list.
134
134
  * Resolution: API -> Cache. Custom items are merged into the list.
135
135
  */
136
- async fetchContentList(contentType, namespace, sort, recommended, intelligenceSource) {
136
+ async fetchContentList(contentType, namespace, sort, recommended, intelligenceSource, blueprintSet, labs) {
137
137
  let apiItems = [];
138
138
  let source = { type: "cache" };
139
139
  if (!this.offline) {
@@ -142,7 +142,9 @@ var RegistryClient = class {
142
142
  namespace,
143
143
  sort,
144
144
  recommended,
145
- intelligenceSource
145
+ intelligenceSource,
146
+ blueprintSet,
147
+ labs
146
148
  });
147
149
  apiItems = apiResult.items;
148
150
  source = { type: "api", url: this.apiUrl };
@@ -3969,6 +3971,44 @@ function buildFlagsString(options) {
3969
3971
  }
3970
3972
  return flags.join(" ");
3971
3973
  }
3974
+ function serializeConstraintValue(value) {
3975
+ if (value === void 0 || value === null) return void 0;
3976
+ if (typeof value === "string") return value;
3977
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
3978
+ try {
3979
+ return JSON.stringify(value);
3980
+ } catch {
3981
+ return String(value);
3982
+ }
3983
+ }
3984
+ function normalizeBlueprintDesignConstraints(designConstraints) {
3985
+ if (!designConstraints || typeof designConstraints !== "object" || Array.isArray(designConstraints)) {
3986
+ return void 0;
3987
+ }
3988
+ const constraints = {};
3989
+ const effects = {};
3990
+ for (const [key, value] of Object.entries(designConstraints)) {
3991
+ if (key === "effects" && value && typeof value === "object" && !Array.isArray(value)) {
3992
+ for (const [effectKey, effectValue] of Object.entries(value)) {
3993
+ const serialized2 = serializeConstraintValue(effectValue);
3994
+ if (serialized2) effects[effectKey] = serialized2;
3995
+ }
3996
+ continue;
3997
+ }
3998
+ const serialized = serializeConstraintValue(value);
3999
+ if (!serialized) continue;
4000
+ if (key === "mode" && typeof value === "string") constraints.mode = value;
4001
+ else if (key === "typography" && typeof value === "string") constraints.typography = value;
4002
+ else if (key === "borders" && typeof value === "string") constraints.borders = value;
4003
+ else if (key === "corners" && typeof value === "string") constraints.corners = value;
4004
+ else if (key === "shadows" && typeof value === "string") constraints.shadows = value;
4005
+ else effects[key] = serialized;
4006
+ }
4007
+ if (Object.keys(effects).length > 0) {
4008
+ constraints.effects = effects;
4009
+ }
4010
+ return Object.keys(constraints).length > 0 ? constraints : void 0;
4011
+ }
3972
4012
  function generateTaskContextV4(templateName, essence) {
3973
4013
  const template = loadTemplate(templateName);
3974
4014
  const sections = essence.blueprint.sections;
@@ -4226,8 +4266,11 @@ async function scaffoldProject(projectRoot, options, detected, registry, archety
4226
4266
  if (blueprintData?.personality?.length) {
4227
4267
  essenceV4.dna.personality = typeof blueprintData.personality === "string" ? [blueprintData.personality] : blueprintData.personality;
4228
4268
  }
4229
- if (blueprintData?.design_constraints) {
4230
- essenceV4.dna.constraints = blueprintData.design_constraints;
4269
+ const normalizedDesignConstraints = normalizeBlueprintDesignConstraints(
4270
+ blueprintData?.design_constraints
4271
+ );
4272
+ if (normalizedDesignConstraints) {
4273
+ essenceV4.dna.constraints = normalizedDesignConstraints;
4231
4274
  }
4232
4275
  if (blueprintData?.seo_hints) {
4233
4276
  essenceV4.meta.seo = blueprintData.seo_hints;
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import "./chunk-H6TIXG5K.js";
2
- import "./chunk-PEGMSXDJ.js";
1
+ import "./chunk-HO3OLDPQ.js";
2
+ import "./chunk-V3XAQWKD.js";
3
3
  import "./chunk-IEW2QFYI.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  RegistryClient,
3
3
  refreshDerivedFiles
4
- } from "./chunk-PEGMSXDJ.js";
4
+ } from "./chunk-V3XAQWKD.js";
5
5
 
6
6
  // src/commands/upgrade.ts
7
7
  import { existsSync, readFileSync, writeFileSync } from "fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decantr/cli",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "description": "Decantr CLI - scaffold, audit, inspect Project Health, and maintain Decantr projects from the terminal",
5
5
  "keywords": [
6
6
  "decantr",
@@ -48,10 +48,10 @@
48
48
  },
49
49
  "dependencies": {
50
50
  "ajv": "^8.20.0",
51
- "@decantr/registry": "2.0.0",
52
51
  "@decantr/essence-spec": "2.0.1",
53
52
  "@decantr/core": "2.1.0",
54
53
  "@decantr/telemetry": "2.2.1",
54
+ "@decantr/registry": "2.1.0",
55
55
  "@decantr/verifier": "2.1.0"
56
56
  },
57
57
  "scripts": {