@contentful/experience-design-system-cli 2.34.5-dev-build-75bf00ac.0 → 2.34.5-dev-build-5e798cb1.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
@@ -89,7 +89,7 @@ export CONTENTFUL_ENVIRONMENT_ID=master # required
89
89
 
90
90
  Or run `experiences setup` once and they get saved to `credentials.json` and pre-filled in the wizard.
91
91
 
92
- In the wizard's credentials step you can press `[s] Skip` to save-only without pushing — useful when you want a checked-in `components.json` without a live push.
92
+ In the wizard's credentials step you can press `[s] Skip` to save-only without pushing — useful when you want a checked-in combined CDF file without a live push.
93
93
 
94
94
  ---
95
95
 
@@ -134,7 +134,7 @@ The auto-filter (`analyze select-agent` invoked before scope-gate) is on by defa
134
134
 
135
135
  ### Save-and-push default
136
136
 
137
- The push-decision-gate defaults to **save AND push**: it writes `components.json` and `tokens.json` to disk *and* pushes to Contentful in one step.
137
+ The push-decision-gate defaults to **save AND push**: it writes one combined `components.json` CDF containing components and design tokens, then pushes it to Contentful in one step.
138
138
 
139
139
  ### Custom skill prompts
140
140
 
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.34.5-dev-build-75bf00ac.0",
3
+ "version": "2.34.5-dev-build-5e798cb1.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import type { CDFDocument, CDFComponentEntry, DTCGTokenEntry } from '@contentful/experience-design-system-types';
2
3
  export declare function buildGenerateComponentsArgs(opts: {
3
4
  sessionId: string;
4
5
  tokensPath?: string;
@@ -29,6 +30,12 @@ export declare function shouldRunMapTokens(opts: {
29
30
  mappablePropCount: number;
30
31
  rawTokenCount: number;
31
32
  }): boolean;
33
+ export declare function buildSavedCDF(components: Array<{
34
+ key: string;
35
+ entry: CDFComponentEntry;
36
+ }>, tokens: DTCGTokenEntry[], opts?: {
37
+ deleteAll?: boolean;
38
+ }): CDFDocument;
32
39
  export declare function formatAcceptanceSummary(opts: {
33
40
  accepted: number;
34
41
  autoRejected: number;
package/dist/src/index.js CHANGED
@@ -24533,6 +24533,7 @@ __export(WizardApp_exports, {
24533
24533
  buildGenerateComponentsArgs: () => buildGenerateComponentsArgs,
24534
24534
  buildGenerateTokensArgs: () => buildGenerateTokensArgs,
24535
24535
  buildMapTokensArgs: () => buildMapTokensArgs,
24536
+ buildSavedCDF: () => buildSavedCDF,
24536
24537
  formatAcceptanceSummary: () => formatAcceptanceSummary,
24537
24538
  parsePrintTokensCount: () => parsePrintTokensCount,
24538
24539
  shouldRunMapTokens: () => shouldRunMapTokens
@@ -24541,11 +24542,11 @@ import { useEffect as useEffect11, useRef as useRef9, useState as useState23 } f
24541
24542
  import { Box as Box46, Text as Text50, useStdout as useStdout4 } from "ink";
24542
24543
  import { join as join20, resolve as resolve17 } from "node:path";
24543
24544
  import { appendFileSync as appendFileSync2, writeFileSync } from "node:fs";
24544
- import { access as access7, stat as stat5 } from "node:fs/promises";
24545
+ import { access as access7, stat as stat5, writeFile as writeFile6 } from "node:fs/promises";
24545
24546
  import { tmpdir } from "node:os";
24546
24547
  import { execFile as execFile2, spawn as spawn3 } from "node:child_process";
24547
24548
  import { mkdir as mkdir5 } from "node:fs/promises";
24548
- import { buildCDF as buildCDF3, validateSlotReferences as validateSlotReferences2 } from "@contentful/experience-design-system-types";
24549
+ import { buildCDF as buildCDF3, validateCDF as validateCDF3, validateSlotReferences as validateSlotReferences2 } from "@contentful/experience-design-system-types";
24549
24550
  import { jsx as jsx54, jsxs as jsxs45 } from "react/jsx-runtime";
24550
24551
  function buildGenerateComponentsArgs(opts) {
24551
24552
  const args = ["__generate", "components", "--agent", opts.agent, "--session", opts.sessionId];
@@ -24576,6 +24577,15 @@ function buildMapTokensArgs(opts) {
24576
24577
  function shouldRunMapTokens(opts) {
24577
24578
  return opts.mappablePropCount > 0 && opts.rawTokenCount > 0;
24578
24579
  }
24580
+ function buildSavedCDF(components, tokens, opts = {}) {
24581
+ const cdf = buildCDF3(components, toCDFTokens(tokens), opts);
24582
+ if (!cdf) throw new Error("nothing to save \u2014 no components or tokens resolved");
24583
+ const validation = validateCDF3(cdf);
24584
+ if (!validation.valid) {
24585
+ throw new Error(`generated CDF failed validation: ${validation.errors.map((error) => error.message).join(", ")}`);
24586
+ }
24587
+ return cdf;
24588
+ }
24579
24589
  function formatAcceptanceSummary(opts) {
24580
24590
  const acceptedClause = `${opts.accepted} component${opts.accepted === 1 ? "" : "s"} accepted`;
24581
24591
  if (opts.autoRejected === 0) return `${acceptedClause}.`;
@@ -25548,41 +25558,34 @@ If using a custom host configuration, make sure the space exists on that host.`
25548
25558
  const runPrintFiles = async (extractSessionId, outDir, opts = {}) => {
25549
25559
  update({ step: "printing" });
25550
25560
  const componentsPath = join20(outDir, "components.json");
25551
- const printArgs = ["print", "components", "--out", componentsPath];
25552
- if (extractSessionId) printArgs.push("--session", extractSessionId);
25553
- if (opts.allowEmpty) printArgs.push("--allow-empty");
25554
- const r = await runCli(printArgs);
25555
- if (r.exitCode !== 0) {
25561
+ try {
25562
+ const db = openPipelineDb();
25563
+ let components = [];
25564
+ let tokens = [];
25565
+ try {
25566
+ if (extractSessionId) components = loadCDFComponents(db, extractSessionId);
25567
+ if (opts.tokenSessionId) tokens = getDtcgTokensForSession(db, opts.tokenSessionId).tokens;
25568
+ } finally {
25569
+ db.close();
25570
+ }
25571
+ if (!opts.tokenSessionId && opts.tokensPath) tokens = await readTokensFromPath("tokens", opts.tokensPath);
25572
+ const cdf = buildSavedCDF(components, tokens, { deleteAll: opts.allowEmpty });
25573
+ await writeFile6(componentsPath, `${JSON.stringify(cdf, null, 2)}
25574
+ `);
25575
+ process.stderr.write(
25576
+ `wrote ${componentsPath} (${components.length} component${components.length === 1 ? "" : "s"}, ${tokens.length} token${tokens.length === 1 ? "" : "s"})
25577
+ `
25578
+ );
25579
+ } catch (error) {
25556
25580
  update({
25557
25581
  step: "error",
25558
- errorStep: "print components",
25559
- errorMessage: r.stderr.trim() || "Unknown error"
25582
+ errorStep: "save CDF",
25583
+ errorMessage: error instanceof Error ? error.message : "Unknown error"
25560
25584
  });
25561
25585
  return { ok: false };
25562
25586
  }
25563
- let emittedTokensPath;
25564
- let emittedTokenCount;
25565
- if (opts.tokenSessionId) {
25566
- const tokensOut = join20(outDir, "tokens.json");
25567
- const tokenArgs = ["print", "tokens", "--out", tokensOut, "--session", opts.tokenSessionId];
25568
- const tr = await runCli(tokenArgs);
25569
- if (tr.exitCode !== 0) {
25570
- update({
25571
- step: "error",
25572
- errorStep: "print tokens",
25573
- errorMessage: tr.stderr.trim() || "Unknown error"
25574
- });
25575
- return { ok: false };
25576
- }
25577
- emittedTokensPath = tokensOut;
25578
- emittedTokenCount = parsePrintTokensCount(tr.stdout);
25579
- }
25580
25587
  update(nextStateAfterPrint({ skipGate: opts.skipGate, componentsPath }));
25581
- return {
25582
- ok: true,
25583
- ...emittedTokensPath ? { tokensPath: emittedTokensPath } : {},
25584
- ...typeof emittedTokenCount === "number" ? { tokenCount: emittedTokenCount } : {}
25585
- };
25588
+ return { ok: true };
25586
25589
  };
25587
25590
  const runSaveAndPush = async () => {
25588
25591
  await startSaveFlow({ skipGate: true, andPush: true });
@@ -25599,11 +25602,12 @@ If using a custom host configuration, make sure the space exists on that host.`
25599
25602
  const result = await runPrintFiles(extractSessionId, path, {
25600
25603
  ...skipGate ? { skipGate: true } : {},
25601
25604
  ...state.tokenSessionId ? { tokenSessionId: state.tokenSessionId } : {},
25605
+ ...tokensPath ? { tokensPath } : {},
25602
25606
  ...allowEmptyDeleteAllRef.current ? { allowEmpty: true } : {}
25603
25607
  });
25604
25608
  if (!result.ok) return;
25605
- const recordedTokensPath = result.tokensPath ?? (state.tokenSessionId ? tokensPath || null : null);
25606
- const recordedTokenCount = result.tokenCount ?? state.tokenCount;
25609
+ const recordedTokensPath = state.tokenSessionId ? tokensPath || null : null;
25610
+ const recordedTokenCount = state.tokenCount;
25607
25611
  if (result.ok) {
25608
25612
  try {
25609
25613
  let sourceFingerprint = null;
@@ -25938,9 +25942,7 @@ If using a custom host configuration, make sure the space exists on that host.`
25938
25942
  );
25939
25943
  }
25940
25944
  case "push-decision-gate": {
25941
- const tokenDesc = hasTokens ? "tokens.json" : null;
25942
- const compDesc = hasComponents ? "components.json" : null;
25943
- const files = [tokenDesc, compDesc].filter(Boolean).join(" and ");
25945
+ const files = hasComponents || hasTokens ? "components.json" : null;
25944
25946
  const count = state.generatedAcceptedCount > 0 ? state.generatedAcceptedCount : state.generatedCount;
25945
25947
  const summary = hasComponents ? `${count} component definition${count !== 1 ? "s" : ""} ready${hasTokens ? ", design tokens ready" : ""}.` : hasTokens ? "Design tokens ready." : "Ready to continue.";
25946
25948
  return /* @__PURE__ */ jsx54(
@@ -26101,8 +26103,7 @@ If using a custom host configuration, make sure the space exists on that host.`
26101
26103
  {
26102
26104
  successMessage: "Files saved",
26103
26105
  summary: [
26104
- hasComponents && state.componentsPath ? `components.json \u2192 ${state.componentsPath}` : null,
26105
- hasTokens && state.tokensPath ? `tokens.json \u2192 ${state.tokensPath}` : null
26106
+ (hasComponents || hasTokens) && state.componentsPath ? `components.json \u2192 ${state.componentsPath}` : null
26106
26107
  ].filter(Boolean).join("\n"),
26107
26108
  context: teaser ? `Your files are saved to disk. ${teaser}` : "Your files are saved to disk. Run `experiences import` again when you're ready to push to Contentful.",
26108
26109
  continueLabel: "Exit",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.34.5-dev-build-75bf00ac.0",
3
+ "version": "2.34.5-dev-build-5e798cb1.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -40,8 +40,8 @@
40
40
  "svelte": "^5.56.4",
41
41
  "ts-morph": "^27.0.2",
42
42
  "typescript": "^5.9.3",
43
- "@contentful/experience-design-system-cli-v2": "2.34.5-dev-build-75bf00ac.0",
44
- "@contentful/experience-design-system-types": "2.34.5-dev-build-75bf00ac.0"
43
+ "@contentful/experience-design-system-cli-v2": "2.34.5-dev-build-5e798cb1.0",
44
+ "@contentful/experience-design-system-types": "2.34.5-dev-build-5e798cb1.0"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@tsconfig/node24": "^24.0.4",
@@ -53,9 +53,9 @@
53
53
  "ink-testing-library": "^4.0.0",
54
54
  "typescript-eslint": "^8.67.0",
55
55
  "vitest": "^4.0.16",
56
- "@contentful/experience-design-system-generation": "2.34.5-dev-build-75bf00ac.0",
57
- "@contentful/experience-design-system-extraction": "2.34.5-dev-build-75bf00ac.0",
58
- "@contentful/experience-design-system-client": "2.34.5-dev-build-75bf00ac.0"
56
+ "@contentful/experience-design-system-client": "2.34.5-dev-build-5e798cb1.0",
57
+ "@contentful/experience-design-system-extraction": "2.34.5-dev-build-5e798cb1.0",
58
+ "@contentful/experience-design-system-generation": "2.34.5-dev-build-5e798cb1.0"
59
59
  },
60
60
  "repository": {
61
61
  "type": "git",