@contentful/experience-design-system-cli 2.34.5-dev-build-d42cd1ad.0 → 2.34.5-dev-build-4bbbf2f0.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/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-d42cd1ad.0",
3
+ "version": "2.34.5-dev-build-4bbbf2f0.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,17 +1,11 @@
1
1
  /**
2
2
  * The CLI-owned composition interchange format (spec T1).
3
3
  *
4
- * Two views of the same data:
5
- * - `InterchangeMap` — the human-authored / on-disk `{ version, groups }`
6
- * shape (parent → children), consumed by the composition-map option.
7
- * `--composition-map` consumes and the resolver can emit.
8
- * - `CompositionEdge[]` — the flat internal runtime view, one edge per
9
- * parent→child relationship, carrying optional `slot` (T7), `confidence`,
10
- * and `provenance`. Easier to merge/dedupe across sources (T2).
11
- *
12
- * This module owns both shapes and the converters between them.
4
+ * `CompositionEdge[]` is the flat internal runtime view, one edge per
5
+ * parent→child relationship, carrying optional `slot` (T7), `confidence`,
6
+ * and `provenance`. It is easier to merge and dedupe across sources (T2).
13
7
  */
14
- export type EdgeProvenance = 'user' | 'typed-slot' | 'structural' | 'manifest' | 'doc' | `adapter:${string}` | 'agent';
8
+ export type EdgeProvenance = 'typed-slot' | 'structural' | 'manifest' | 'doc' | `adapter:${string}` | 'agent';
15
9
  export type CompositionEdge = {
16
10
  parent: string;
17
11
  child: string;
@@ -21,17 +15,3 @@ export type CompositionEdge = {
21
15
  confidence?: number;
22
16
  provenance: EdgeProvenance;
23
17
  };
24
- export type InterchangeMap = {
25
- version: 1;
26
- groups: Record<string, string[]>;
27
- };
28
- export type ValidateResult = {
29
- valid: true;
30
- map: InterchangeMap;
31
- } | {
32
- valid: false;
33
- errors: string[];
34
- };
35
- export declare function validateInterchangeMap(input: unknown): ValidateResult;
36
- export declare function groupsToEdges(map: InterchangeMap, provenance: EdgeProvenance): CompositionEdge[];
37
- export declare function edgesToGroups(edges: CompositionEdge[]): InterchangeMap;
@@ -1,18 +1,7 @@
1
- import { type InterchangeMap } from './interchange-schema.js';
2
1
  export type CompositionCliOptions = {
3
- /** `--composition-map <path>` — hand-authored interchange file. */
4
- compositionMap?: string;
5
2
  /** `--composition-refresh` — force edge emission to run even over resolved residue. */
6
3
  compositionRefresh?: boolean;
7
4
  };
8
- export type LoadUserMapResult = {
9
- ok: true;
10
- map: InterchangeMap;
11
- } | {
12
- ok: false;
13
- error: string;
14
- };
15
- export declare function loadUserMap(path: string): Promise<LoadUserMapResult>;
16
5
  export type ResolvedCompositionSources = {
17
6
  forceAgent: boolean;
18
7
  };
@@ -1,9 +1,8 @@
1
1
  import type { RawComponentDefinition } from '../../types.js';
2
- import { type CompositionEdge, type InterchangeMap } from './interchange-schema.js';
2
+ import type { CompositionEdge } from './interchange-schema.js';
3
3
  import { type EdgeConflict } from './merge-edges.js';
4
4
  export type ResolveMappingResult = {
5
5
  components: RawComponentDefinition[];
6
- userMap?: InterchangeMap;
7
6
  edges: CompositionEdge[];
8
7
  conflicts: EdgeConflict[];
9
8
  warnings: string[];
@@ -11,9 +10,9 @@ export type ResolveMappingResult = {
11
10
  /**
12
11
  * Orchestrate composition-edge acquisition and enrichment.
13
12
  *
14
- * Sources by rank: user map (1) > typed-slot / "code slots" (2) > structural
15
- * usage evidence (3) > manifest (4) > doc (5) > adapter-resolved / extraEdges
16
- * (6) > edge-emitting agent (7). Manifest/doc edges are computed deterministically outside
13
+ * Sources by rank: typed-slot / "code slots" (2) > structural usage evidence
14
+ * (3) > manifest (4) > doc (5) > adapter-resolved / extraEdges (6) >
15
+ * edge-emitting agent (7). Manifest/doc edges are computed deterministically outside
17
16
  * this function (see manifest-doc-evidence.ts) and joined via `extraEdges`.
18
17
  * ALL sources — including the code slots already on the incoming components —
19
18
  * are fed into one ranked merge and unioned; non-conflicting edges from every
@@ -28,7 +27,6 @@ export type ResolveMappingResult = {
28
27
  */
29
28
  export declare function resolveMapping(input: {
30
29
  components: RawComponentDefinition[];
31
- userMap?: InterchangeMap;
32
30
  forceAgent?: boolean;
33
31
  files: Array<{
34
32
  path: string;
@@ -55,7 +53,7 @@ export declare function resolveMapping(input: {
55
53
  /**
56
54
  * Pre-resolved edges from an external source (e.g. manifest or documentation)
57
55
  * path). They join the ranked merge at their own provenance rank alongside
58
- * code slots and the user map.
56
+ * code slots and other automatic mapping sources.
59
57
  */
60
58
  extraEdges?: CompositionEdge[];
61
59
  }): Promise<ResolveMappingResult>;
@@ -7,7 +7,7 @@ export type ExperiencesCredentials = {
7
7
  agentModel?: string;
8
8
  /** Feature 8: persisted custom prompt path for `generate components`. */
9
9
  generatePromptPath?: string;
10
- /** Write JSONL trace of every command decision to ~/.contentful/experience-design-system-cli/debug/. */
10
+ /** Feature: default debug-mode (writes JSONL trace of every decision) for all commands. */
11
11
  debug?: boolean;
12
12
  /** Print plain text with no color; an exported NO_COLOR still wins. */
13
13
  noColor?: boolean;
@@ -1,9 +1,7 @@
1
1
  export type CompositionOptionInput = {
2
- compositionMap?: string;
3
2
  prompt?: string[];
4
3
  };
5
4
  export type CompositionForwardingOptions = {
6
- compositionMap?: string;
7
5
  promptOverrides?: string[];
8
6
  };
9
7
  export declare function buildCompositionForwardingOptions(options: CompositionOptionInput): CompositionForwardingOptions;
package/dist/src/index.js CHANGED
@@ -1184,6 +1184,17 @@ function initDebugLogger(opts) {
1184
1184
  function getDebugLogger() {
1185
1185
  return singleton ?? new NoopDebugLogger();
1186
1186
  }
1187
+ function resolveDebugMode(opts, configDebug) {
1188
+ if (opts.debug !== void 0) return opts.debug;
1189
+ const env = process.env["EDSI_DEBUG"];
1190
+ if (env !== void 0 && env !== "") {
1191
+ const v = env.toLowerCase();
1192
+ if (v === "1" || v === "true" || v === "yes" || v === "on") return true;
1193
+ if (v === "0" || v === "false" || v === "no" || v === "off") return false;
1194
+ }
1195
+ if (configDebug !== void 0) return configDebug;
1196
+ return false;
1197
+ }
1187
1198
  function printDebugBanner(logger, phase) {
1188
1199
  if (!logger.enabled || !logger.path) return;
1189
1200
  const prefix = phase === "start" ? "\x1B[92m[debug]\x1B[0m " : "\x1B[92m[debug]\x1B[0m ";
@@ -7521,7 +7532,7 @@ function buildApplyOutput(operation, spaceId, environmentId, host) {
7521
7532
  };
7522
7533
  }
7523
7534
  function registerApplyCommand(program) {
7524
- const applyCmd = program.command("apply").description("Write component types and design tokens to Contentful ExO").argument("<file>", "CDF file containing all component and design token definitions");
7535
+ const applyCmd = program.command("apply").description("Write component types and design tokens to Contentful ExO").helpOption(false).argument("<file>", "CDF file containing all component and design token definitions");
7525
7536
  applyCmd.action(async (file) => {
7526
7537
  const isTTY = getInteractiveTerminalSupport().supported;
7527
7538
  const inputs = await resolveSharedInputsOrDie(file);
@@ -8571,16 +8582,17 @@ ${defaultDiagnostics.map((diagnostic) => ` ${diagnostic}`).join("\n")}
8571
8582
  );
8572
8583
  }
8573
8584
  }
8585
+ const buildMapPrompt = () => buildPrompt({
8586
+ skill: "map-tokens",
8587
+ mode: "autonomous",
8588
+ generatedCdf,
8589
+ tokenTree,
8590
+ componentSourceRefs,
8591
+ outDir: process.cwd(),
8592
+ existingTokensInline
8593
+ });
8574
8594
  if (opts.printPrompt) {
8575
- const prompt2 = await buildPrompt({
8576
- skill: "map-tokens",
8577
- mode: "autonomous",
8578
- generatedCdf,
8579
- tokenTree,
8580
- componentSourceRefs,
8581
- outDir: process.cwd(),
8582
- existingTokensInline
8583
- });
8595
+ const prompt2 = await buildMapPrompt();
8584
8596
  process.stdout.write(prompt2 + "\n");
8585
8597
  await exitWithAnalytics(0);
8586
8598
  return;
@@ -8624,15 +8636,7 @@ Install it, choose another agent with --agent, or use --print-prompt to run the
8624
8636
  );
8625
8637
  }
8626
8638
  const stepId = createStep(db, sessionId2, "map tokens", { agent, model: model ?? "" });
8627
- const prompt = await buildPrompt({
8628
- skill: "map-tokens",
8629
- mode: "autonomous",
8630
- generatedCdf,
8631
- tokenTree,
8632
- componentSourceRefs,
8633
- outDir: process.cwd(),
8634
- existingTokensInline
8635
- });
8639
+ const prompt = await buildMapPrompt();
8636
8640
  const invoker2 = createLocalCliAgentInvoker();
8637
8641
  const result = await invoker2.invoke({ agent, model, prompt, timeoutMs: DEFAULT_TIMEOUT_MS2 });
8638
8642
  if (result.timedOut || result.exitCode !== 0) {
@@ -8710,19 +8714,6 @@ var init_path_utils = __esm({
8710
8714
  }
8711
8715
  });
8712
8716
 
8713
- // packages/experience-design-system-cli/src/import/composition-options.ts
8714
- function buildCompositionForwardingOptions(options) {
8715
- return {
8716
- ...options.compositionMap ? { compositionMap: options.compositionMap } : {},
8717
- ...options.prompt && options.prompt.length > 0 ? { promptOverrides: options.prompt } : {}
8718
- };
8719
- }
8720
- var init_composition_options = __esm({
8721
- "packages/experience-design-system-cli/src/import/composition-options.ts"() {
8722
- "use strict";
8723
- }
8724
- });
8725
-
8726
8717
  // packages/experience-design-system-cli/src/analyze/select/tui/theme.ts
8727
8718
  var PALETTE;
8728
8719
  var init_theme = __esm({
@@ -28273,86 +28264,63 @@ var init_WizardApp = __esm({
28273
28264
 
28274
28265
  // packages/experience-design-system-cli/src/import/command.ts
28275
28266
  function registerImportCommand(program) {
28276
- const cmd = program.command("import").description("Run the full pipeline: analyze \u2192 select \u2192 generate \u2192 push").option("--project <path>", "Path to the project root to analyze", ".");
28277
- addAgentModelOptions(cmd, {
28278
- agentDescription: 'Agent to use for generate components (overrides credentials.json; falls back to "claude")',
28279
- modelDescription: "Model to use for generate components (defaults to a lightweight per-agent model; override with EDS_AGENT_MODEL_<AGENT>)"
28280
- }).option(
28281
- "--raw-tokens <path>",
28282
- "Path to a raw token source file (SCSS, CSS variables, JS/TS, Style Dictionary, etc.) to classify and import alongside components. Bypasses the interactive token prompt."
28283
- ).option(
28284
- "--skip-map-tokens",
28285
- "Skip agentic token restrictions while still resolving deterministic token-default paths"
28286
- ).option("--no-cache", "Re-run all steps even if output already exists");
28287
- cmd.option("--composition-map <path>", "Consume a hand-authored parent\u2192children interchange map").option(
28267
+ program.command("import").description("Run the full pipeline: analyze \u2192 select \u2192 generate \u2192 push").option("--project <path>", "Path to the project root to analyze", ".").option("--tokens <path>", "Path to a raw token source file to import alongside components").option("--agent <name>", 'Agent to use for generation (overrides credentials.json; falls back to "claude")').option(
28288
28268
  "--prompt <stage=value>",
28289
28269
  "Override a stage prompt (repeatable). value is a file path or literal text, e.g. --prompt composition=./p.md",
28290
28270
  (v, acc) => [...acc, v],
28291
28271
  []
28292
- ).action(
28293
- async (opts) => {
28294
- const interactiveTerminalSupported = getInteractiveTerminalSupport().supported;
28295
- if (opts.rawTokens !== void 0) {
28296
- const { access: access9 } = await import("node:fs/promises");
28297
- try {
28298
- await access9(normalizePath(opts.rawTokens));
28299
- } catch {
28300
- process.stderr.write(`Error: --raw-tokens: file not found: ${opts.rawTokens}
28301
- `);
28302
- process.exit(1);
28303
- return;
28304
- }
28305
- }
28306
- if (!interactiveTerminalSupported) {
28307
- requireInteractiveTerminal({
28308
- alternative: "run experiences import in an interactive terminal"
28309
- });
28310
- }
28311
- {
28312
- const { render: render5 } = await import("ink");
28313
- const { createElement: createElement6 } = await import("react");
28314
- const { WizardApp: WizardApp2 } = await Promise.resolve().then(() => (init_WizardApp(), WizardApp_exports));
28315
- const creds = await readExperiencesCredentials();
28316
- const resolvedAgent = opts.agent || creds.agent || "claude";
28317
- const resolvedModel = opts.model || creds.agentModel || void 0;
28318
- if (opts.bedrock && !(isAgentName(resolvedAgent) && agentSupportsBedrock(resolvedAgent))) {
28319
- process.stderr.write(`Error: --bedrock is not supported for --agent ${resolvedAgent}
28272
+ ).option("--no-cache", "Re-run all steps even if output already exists").action(async (opts) => {
28273
+ const interactiveTerminalSupported = getInteractiveTerminalSupport().supported;
28274
+ if (opts.tokens !== void 0) {
28275
+ const { access: access9 } = await import("node:fs/promises");
28276
+ try {
28277
+ await access9(normalizePath(opts.tokens));
28278
+ } catch {
28279
+ process.stderr.write(`Error: --tokens: file not found: ${opts.tokens}
28320
28280
  `);
28321
- process.exit(1);
28322
- }
28323
- const { waitUntilExit } = render5(
28324
- createElement6(WizardApp2, {
28325
- initialSpaceId: creds.spaceId,
28326
- initialEnvironmentId: creds.environmentId || "master",
28327
- initialCmaToken: creds.cmaToken,
28328
- initialHost: toConfiguredHost(creds.host) ?? DEFAULT_CONFIGURED_HOST,
28329
- initialAgent: resolvedAgent,
28330
- ...resolvedModel ? { initialModel: resolvedModel } : {},
28331
- ...opts.bedrock ? { bedrock: true } : {},
28332
- initialProjectPath: opts.project !== "." ? normalizePath(opts.project) : void 0,
28333
- ...buildCompositionForwardingOptions(opts),
28334
- noCache: opts.cache === false,
28335
- skipMapTokens: opts.skipMapTokens ?? false,
28336
- livePreview: true,
28337
- generatePromptPath: creds.generatePromptPath,
28338
- ...opts.rawTokens ? { initialRawTokensPath: normalizePath(opts.rawTokens) } : {}
28339
- })
28340
- );
28341
- await waitUntilExit();
28281
+ process.exit(1);
28342
28282
  return;
28343
28283
  }
28344
28284
  }
28345
- );
28285
+ if (!interactiveTerminalSupported) {
28286
+ requireInteractiveTerminal({
28287
+ alternative: "run experiences import in an interactive terminal"
28288
+ });
28289
+ }
28290
+ {
28291
+ const { render: render5 } = await import("ink");
28292
+ const { createElement: createElement6 } = await import("react");
28293
+ const { WizardApp: WizardApp2 } = await Promise.resolve().then(() => (init_WizardApp(), WizardApp_exports));
28294
+ const creds = await readExperiencesCredentials();
28295
+ const resolvedAgent = opts.agent || creds.agent || "claude";
28296
+ const resolvedModel = creds.agentModel || void 0;
28297
+ const { waitUntilExit } = render5(
28298
+ createElement6(WizardApp2, {
28299
+ initialSpaceId: creds.spaceId,
28300
+ initialEnvironmentId: creds.environmentId || "master",
28301
+ initialCmaToken: creds.cmaToken,
28302
+ initialHost: toConfiguredHost(creds.host) ?? DEFAULT_CONFIGURED_HOST,
28303
+ initialAgent: resolvedAgent,
28304
+ ...resolvedModel ? { initialModel: resolvedModel } : {},
28305
+ initialProjectPath: opts.project !== "." ? normalizePath(opts.project) : void 0,
28306
+ ...opts.prompt && opts.prompt.length > 0 ? { promptOverrides: opts.prompt } : {},
28307
+ noCache: opts.cache === false,
28308
+ livePreview: true,
28309
+ generatePromptPath: creds.generatePromptPath,
28310
+ ...opts.tokens ? { initialRawTokensPath: normalizePath(opts.tokens) } : {}
28311
+ })
28312
+ );
28313
+ await waitUntilExit();
28314
+ return;
28315
+ }
28316
+ });
28346
28317
  }
28347
28318
  var init_command6 = __esm({
28348
28319
  "packages/experience-design-system-cli/src/import/command.ts"() {
28349
28320
  "use strict";
28350
- init_src();
28351
28321
  init_path_utils();
28352
- init_agent_model_options();
28353
28322
  init_credentials_store();
28354
28323
  init_host_utils();
28355
- init_composition_options();
28356
28324
  init_terminal_capabilities();
28357
28325
  }
28358
28326
  });
@@ -28659,7 +28627,7 @@ var init_checks2 = __esm({
28659
28627
  });
28660
28628
 
28661
28629
  // packages/experience-design-system-cli/src/doctor/command.ts
28662
- async function runChecks(opts) {
28630
+ async function runChecks() {
28663
28631
  const pkgRoot = findPkgRoot();
28664
28632
  const results = [];
28665
28633
  const record = (name, passed, required = true) => {
@@ -28668,13 +28636,11 @@ async function runChecks(opts) {
28668
28636
  };
28669
28637
  if (record("Node.js version", await reportNode())) {
28670
28638
  const pnpmOk = record("pnpm", await reportPnpm(pkgRoot));
28671
- if (opts.skipBuild) {
28672
- info("\nSkipping install + build (--skip-build)");
28673
- } else if (pnpmOk && record("dependencies", await reportDependencies(pkgRoot))) {
28639
+ if (pnpmOk && record("dependencies", await reportDependencies(pkgRoot))) {
28674
28640
  record("build", await reportBuild(pkgRoot));
28675
28641
  }
28676
28642
  }
28677
- if (!opts.skipAgent) record("coding agent", await reportAgent(), false);
28643
+ record("coding agent", await reportAgent(), false);
28678
28644
  return results;
28679
28645
  }
28680
28646
  function printSummary(results) {
@@ -28714,13 +28680,13 @@ ${c.red(c.bold(`\u2717 ${requiredFailed} required check${requiredFailed === 1 ?
28714
28680
  `);
28715
28681
  return 1;
28716
28682
  }
28717
- async function runDoctor(opts) {
28683
+ async function runDoctor() {
28718
28684
  process.stderr.write(`${c.bold("experiences doctor")} \u2014 checking your environment
28719
28685
  `);
28720
- process.exitCode = printSummary(await runChecks(opts));
28686
+ process.exitCode = printSummary(await runChecks());
28721
28687
  }
28722
28688
  function registerDoctorCommand(program) {
28723
- program.command("doctor").description("Check prerequisites so experiences import runs without errors").option("--skip-build", "Skip the pnpm install + build step (useful if already built)").option("--skip-agent", "Skip the coding agent check").action((opts) => runDoctor(opts));
28689
+ program.command("doctor").description("Check prerequisites so experiences import runs without errors").helpOption(false).action(() => runDoctor());
28724
28690
  }
28725
28691
  var init_command7 = __esm({
28726
28692
  "packages/experience-design-system-cli/src/doctor/command.ts"() {
@@ -29860,7 +29826,7 @@ async function runSetup(opts) {
29860
29826
  process.exit(finished.exitCode);
29861
29827
  }
29862
29828
  function registerSetupCommand(program) {
29863
- program.command("setup").description("Interactive setup: installs prerequisites and configures credentials for experiences import").option("--skip-build", "Skip the pnpm install + build step").option("--skip-agent", "Skip the coding agent check").option("--skip-credentials", "Skip the Contentful credentials step").option("--skip-optional", "Skip optional quality-of-life extras").action((opts) => runSetup(opts));
29829
+ program.command("setup").description("Interactive setup: installs prerequisites and configures credentials for experiences import").helpOption(false).action(() => runSetup({}));
29864
29830
  }
29865
29831
  var SETUP_REQUIRES_TTY_MESSAGE;
29866
29832
  var init_command8 = __esm({
@@ -29872,57 +29838,14 @@ var init_command8 = __esm({
29872
29838
  }
29873
29839
  });
29874
29840
 
29875
- // packages/experience-design-system-cli/src/analyze/composition/interchange-schema.ts
29876
- function validateInterchangeMap(input) {
29877
- const errors = [];
29878
- if (typeof input !== "object" || input === null || Array.isArray(input)) {
29879
- return { valid: false, errors: ["interchange map must be a JSON object"] };
29880
- }
29881
- const obj = input;
29882
- if (obj.version !== 1) {
29883
- errors.push(`unsupported interchange version: expected 1, got ${JSON.stringify(obj.version)}`);
29884
- }
29885
- if (typeof obj.groups !== "object" || obj.groups === null || Array.isArray(obj.groups)) {
29886
- errors.push("interchange map must have a `groups` object");
29887
- return { valid: false, errors };
29888
- }
29889
- const groups = obj.groups;
29890
- for (const [parent, children] of Object.entries(groups)) {
29891
- if (!Array.isArray(children) || !children.every((c2) => typeof c2 === "string")) {
29892
- errors.push(`groups["${parent}"] must be an array of strings`);
29893
- }
29894
- }
29895
- if (errors.length > 0) return { valid: false, errors };
29896
- return { valid: true, map: { version: 1, groups } };
29897
- }
29898
- function groupsToEdges(map, provenance) {
29899
- const seen = /* @__PURE__ */ new Set();
29900
- const edges = [];
29901
- for (const [parent, children] of Object.entries(map.groups)) {
29902
- for (const child of children) {
29903
- const key = `${parent}::${child}`;
29904
- if (seen.has(key)) continue;
29905
- seen.add(key);
29906
- edges.push({ parent, child, provenance });
29907
- }
29908
- }
29909
- return edges;
29910
- }
29911
- var init_interchange_schema = __esm({
29912
- "packages/experience-design-system-cli/src/analyze/composition/interchange-schema.ts"() {
29913
- "use strict";
29914
- }
29915
- });
29916
-
29917
29841
  // packages/experience-design-system-cli/src/analyze/composition/merge-edges.ts
29918
29842
  function rank(p) {
29919
- if (p === "user") return 1;
29920
- if (p === "typed-slot") return 2;
29921
- if (p === "structural") return 3;
29922
- if (p === "manifest") return 4;
29923
- if (p === "doc") return 5;
29924
- if (p.startsWith("adapter:")) return 6;
29925
- return 7;
29843
+ if (p === "typed-slot") return 1;
29844
+ if (p === "structural") return 2;
29845
+ if (p === "manifest") return 3;
29846
+ if (p === "doc") return 4;
29847
+ if (p.startsWith("adapter:")) return 5;
29848
+ return 6;
29926
29849
  }
29927
29850
  function mergeEdges(all) {
29928
29851
  const byKey = /* @__PURE__ */ new Map();
@@ -30028,7 +29951,7 @@ function applyMapping(components, edges) {
30028
29951
  }))
30029
29952
  }));
30030
29953
  const byName = new Map(cloned.map((c2) => [c2.name, c2]));
30031
- const isHighTrust = (p) => p === "user" || p === "typed-slot" || p.startsWith("adapter:");
29954
+ const isHighTrust = (p) => p === "typed-slot" || p.startsWith("adapter:");
30032
29955
  const addAllowed = (slot, child) => {
30033
29956
  const set = new Set(slot.allowedComponents ?? []);
30034
29957
  set.add(child);
@@ -30127,7 +30050,6 @@ async function resolveMapping(input) {
30127
30050
  }
30128
30051
  }
30129
30052
  }
30130
- if (input.userMap) collected.push(...groupsToEdges(input.userMap, "user"));
30131
30053
  if (input.extraEdges) {
30132
30054
  collected.push(...input.extraEdges);
30133
30055
  }
@@ -30175,7 +30097,6 @@ ${f.content}`).join("\n\n");
30175
30097
  var init_resolve_mapping = __esm({
30176
30098
  "packages/experience-design-system-cli/src/analyze/composition/resolve-mapping.ts"() {
30177
30099
  "use strict";
30178
- init_interchange_schema();
30179
30100
  init_merge_edges();
30180
30101
  init_parse_map_edges();
30181
30102
  init_apply_mapping();
@@ -30184,24 +30105,6 @@ var init_resolve_mapping = __esm({
30184
30105
  });
30185
30106
 
30186
30107
  // packages/experience-design-system-cli/src/analyze/composition/resolve-mapping-cli.ts
30187
- import { readFile as readFile18 } from "node:fs/promises";
30188
- async function loadUserMap(path) {
30189
- let text;
30190
- try {
30191
- text = await readFile18(path, "utf8");
30192
- } catch {
30193
- return { ok: false, error: `--composition-map: file not found: ${path}` };
30194
- }
30195
- let parsed;
30196
- try {
30197
- parsed = JSON.parse(text);
30198
- } catch {
30199
- return { ok: false, error: `--composition-map: not valid JSON: ${path}` };
30200
- }
30201
- const result = validateInterchangeMap(parsed);
30202
- if (!result.valid) return { ok: false, error: `--composition-map: ${result.errors.join("; ")}` };
30203
- return { ok: true, map: result.map };
30204
- }
30205
30108
  function resolveCompositionSources(opts) {
30206
30109
  return {
30207
30110
  forceAgent: !!opts.compositionRefresh
@@ -30210,7 +30113,6 @@ function resolveCompositionSources(opts) {
30210
30113
  var init_resolve_mapping_cli = __esm({
30211
30114
  "packages/experience-design-system-cli/src/analyze/composition/resolve-mapping-cli.ts"() {
30212
30115
  "use strict";
30213
- init_interchange_schema();
30214
30116
  }
30215
30117
  });
30216
30118
 
@@ -30372,7 +30274,7 @@ var init_manifest_doc_evidence = __esm({
30372
30274
  });
30373
30275
 
30374
30276
  // packages/experience-design-system-cli/src/analyze/extract-command.ts
30375
- import { mkdir as mkdir6, readdir as readdir3, readFile as readFile19, stat as stat6 } from "node:fs/promises";
30277
+ import { mkdir as mkdir6, readdir as readdir3, readFile as readFile18, stat as stat6 } from "node:fs/promises";
30376
30278
  import { isAbsolute as isAbsolute2, join as join25, relative as relative2, resolve as resolve19 } from "node:path";
30377
30279
  function isDenylistedNoiseFile(name) {
30378
30280
  return DENYLISTED_EXACT_FILE_NAMES.has(name) || DENYLISTED_FILE_NAME_PATTERNS.some((pattern) => pattern.test(name));
@@ -30439,7 +30341,7 @@ async function readCandidateFiles(components, extraFiles = []) {
30439
30341
  await Promise.all(
30440
30342
  [...paths].map(async (p) => {
30441
30343
  try {
30442
- const content = await readFile19(p, "utf8");
30344
+ const content = await readFile18(p, "utf8");
30443
30345
  out.push({ path: p, content });
30444
30346
  } catch {
30445
30347
  }
@@ -30452,7 +30354,7 @@ function registerInternalExtractCommand(program) {
30452
30354
  "--resolve-unreachable <mode>",
30453
30355
  "Retry pass for unresolved Svelte Props types: 'auto' (default), 'always', or 'never'",
30454
30356
  "auto"
30455
- ).option("--composition-refresh", "Force the mapping agent to run even where deterministic sources answered").option("--composition-map <path>", "Consume a hand-authored parent\u2192children interchange map").option(
30357
+ ).option("--composition-refresh", "Force the mapping agent to run even where deterministic sources answered").option(
30456
30358
  "--prompt <stage=value>",
30457
30359
  "Override a stage prompt (repeatable). value is a file path or literal text, e.g. --prompt composition=./p.md",
30458
30360
  (v, acc) => [...acc, v],
@@ -30568,16 +30470,6 @@ function registerInternalExtractCommand(program) {
30568
30470
  let validatedComponents = validateExtractedComponents(filteredComponents);
30569
30471
  {
30570
30472
  const sources = resolveCompositionSources(opts);
30571
- let userMap;
30572
- if (opts.compositionMap) {
30573
- const loaded = await loadUserMap(opts.compositionMap);
30574
- if (!loaded.ok) {
30575
- process.stderr.write(`Error: ${loaded.error}
30576
- `);
30577
- process.exit(1);
30578
- }
30579
- userMap = loaded.map;
30580
- }
30581
30473
  const { overrides: promptOverrides, errors: promptErrors } = parsePromptOverrides(opts.prompt ?? []);
30582
30474
  for (const err of promptErrors) {
30583
30475
  process.stderr.write(`Error: ${err}
@@ -30639,7 +30531,6 @@ function registerInternalExtractCommand(program) {
30639
30531
  });
30640
30532
  const result = await resolveMapping({
30641
30533
  components: validatedComponents,
30642
- ...userMap ? { userMap } : {},
30643
30534
  ...extraEdges.length > 0 ? { extraEdges } : {},
30644
30535
  forceAgent: sources.forceAgent,
30645
30536
  files: promptFiles,
@@ -30780,14 +30671,14 @@ var init_extract_command = __esm({
30780
30671
  });
30781
30672
 
30782
30673
  // packages/experience-design-system-cli/src/lib/debug-preamble.ts
30783
- async function beginCommand(command) {
30674
+ async function beginCommand(command, opts) {
30784
30675
  let configDebug;
30785
30676
  try {
30786
30677
  const creds = await readExperiencesCredentials();
30787
30678
  configDebug = creds.debug;
30788
30679
  } catch {
30789
30680
  }
30790
- const enabled = configDebug ?? false;
30681
+ const enabled = resolveDebugMode(opts, configDebug);
30791
30682
  const logger = initDebugLogger({ enabled, command });
30792
30683
  if (logger.enabled) {
30793
30684
  printDebugBanner(logger, "start");
@@ -30846,7 +30737,7 @@ function resolveBedrockFromAncestors(actionCommand) {
30846
30737
  return false;
30847
30738
  }
30848
30739
  function registerImportV2Command(program) {
30849
- program.command("importv2").description("Launch the v2 import").action(async () => {
30740
+ program.command("importv2").description("Launch the v2 import TUI (experience-design-system-cli-v2)").helpOption(false).action(async () => {
30850
30741
  const v2Path = join26(
30851
30742
  dirname13(fileURLToPath4(import.meta.url)),
30852
30743
  "..",
@@ -30864,7 +30755,7 @@ function registerImportV2Command(program) {
30864
30755
  });
30865
30756
  }
30866
30757
  function registerBuildCommand(program) {
30867
- program.command("build").description("Rebuild from source and re-link exo/experiences binaries to this build").action(async () => {
30758
+ program.command("build").description("Rebuild from source and re-link exo/experiences binaries to this build").helpOption(false).action(async () => {
30868
30759
  const pkgRoot = resolve20(dirname13(fileURLToPath4(import.meta.url)), "..", "..");
30869
30760
  process.stderr.write("\u2699 Building from source...\n");
30870
30761
  const { exitCode } = await runBuild({
@@ -30874,18 +30765,34 @@ function registerBuildCommand(program) {
30874
30765
  process.exit(exitCode);
30875
30766
  });
30876
30767
  }
30768
+ function configureRootHelpOrder(program) {
30769
+ const order = ["build", "help", "import", "apply", "importv2", "setup", "doctor"];
30770
+ const rank2 = new Map(order.map((name, index) => [name, index]));
30771
+ program.configureHelp({
30772
+ visibleCommands(command) {
30773
+ const internals = command;
30774
+ const visible = command.commands.filter((entry) => !entry._hidden);
30775
+ const helpCommand = internals._getHelpCommand?.();
30776
+ if (helpCommand && !helpCommand._hidden) visible.push(helpCommand);
30777
+ if (command !== program) return visible;
30778
+ return visible.sort((a, b) => (rank2.get(a.name()) ?? order.length) - (rank2.get(b.name()) ?? order.length));
30779
+ }
30780
+ });
30781
+ }
30877
30782
  function createProgram() {
30878
30783
  const program = new Command().name("experience-design-system-cli").description("Static analysis, validation, generation, and import of Contentful design system artifacts").version(pkg3.version, "--version", "Print version number");
30879
30784
  registerInternalGenerateCommand(program);
30880
30785
  registerInternalExtractCommand(program);
30881
30786
  registerPrintCommand(program);
30882
30787
  registerMapTokensCommand(program);
30883
- registerApplyCommand(program);
30788
+ registerBuildCommand(program);
30789
+ program.helpCommand("help [command]", "display help for command");
30884
30790
  registerImportCommand(program);
30791
+ registerApplyCommand(program);
30885
30792
  registerImportV2Command(program);
30886
- registerDoctorCommand(program);
30887
30793
  registerSetupCommand(program);
30888
- registerBuildCommand(program);
30794
+ registerDoctorCommand(program);
30795
+ configureRootHelpOrder(program);
30889
30796
  program.hook("preAction", async (_thisCommand, actionCommand) => {
30890
30797
  if (resolveBedrockFromAncestors(actionCommand)) {
30891
30798
  process.env.EDS_BEDROCK = "1";
@@ -30896,7 +30803,7 @@ function createProgram() {
30896
30803
  const { analyticsDisabled } = await readExperiencesCredentials();
30897
30804
  setPersistedAnalyticsDisabled(analyticsDisabled ?? false);
30898
30805
  noteCommandStart(commandChain);
30899
- await beginCommand(commandChain);
30806
+ await beginCommand(commandChain, {});
30900
30807
  });
30901
30808
  program.hook("postAction", async () => {
30902
30809
  await completeActiveCommand();
@@ -25,6 +25,17 @@ export declare function initDebugLogger(opts: InitDebugLoggerOptions): DebugLogg
25
25
  export declare function getDebugLogger(): DebugLogger;
26
26
  /** Test-only: reset the singleton. */
27
27
  export declare function __resetDebugLoggerForTest(): void;
28
+ /**
29
+ * Resolve effective debug-mode setting from three sources.
30
+ *
31
+ * Precedence (highest first):
32
+ * 1. `EDSI_DEBUG` env var (truthy: 1, true, yes, on)
33
+ * 2. Persisted `debug` field in credentials.json
34
+ * 4. Default: OFF
35
+ */
36
+ export declare function resolveDebugMode(opts: {
37
+ debug?: boolean;
38
+ }, configDebug?: boolean): boolean;
28
39
  /**
29
40
  * Emit the bright-green "debug logs at <path>" banner to stderr.
30
41
  * No-op when debug is disabled or stderr is not a TTY-friendly stream.
@@ -1,6 +1,14 @@
1
1
  import { type DebugLogger } from './debug-logger.js';
2
2
  /**
3
- * Initialize the debug logger from persisted credentials.
4
- * Debug mode can only be configured via setup preferences;
3
+ * Preamble every top-level command action should call before doing work.
4
+ *
5
+ * Resolves the effective debug decision (flag > env > persisted config),
6
+ * initializes the singleton, and prints the bright-green start banner.
7
+ * Registers a process-exit handler that prints the end banner once.
8
+ *
9
+ * Returns the logger so the caller can emit events without a second import.
10
+ * When debug is disabled, the returned logger is a no-op.
5
11
  */
6
- export declare function beginCommand(command: string): Promise<DebugLogger>;
12
+ export declare function beginCommand(command: string, opts: {
13
+ debug?: boolean;
14
+ }): Promise<DebugLogger>;
@@ -16,9 +16,9 @@ export declare function runBuild(opts: {
16
16
  exitCode: number;
17
17
  }>;
18
18
  /**
19
- * Walks `actionCommand` and its ancestors for a truthy `--bedrock`.
20
- * --bedrock is registered per-subcommand, so a root-level or
21
- * subcommand-level setting can each carry it.
19
+ * Walks `actionCommand` and its ancestors for a truthy `--bedrock`. --bedrock
20
+ * is registered per-subcommand, so a
21
+ * root-level or subcommand-level setting can each carry it.
22
22
  */
23
23
  export declare function resolveBedrockFromAncestors(actionCommand: Command): boolean;
24
24
  export declare function createProgram(): Command;
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-d42cd1ad.0",
3
+ "version": "2.34.5-dev-build-4bbbf2f0.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -41,8 +41,8 @@
41
41
  "svelte": "^5.56.4",
42
42
  "ts-morph": "^27.0.2",
43
43
  "typescript": "^5.9.3",
44
- "@contentful/experience-design-system-cli-v2": "2.34.5-dev-build-d42cd1ad.0",
45
- "@contentful/experience-design-system-types": "2.34.5-dev-build-d42cd1ad.0"
44
+ "@contentful/experience-design-system-cli-v2": "2.34.5-dev-build-4bbbf2f0.0",
45
+ "@contentful/experience-design-system-types": "2.34.5-dev-build-4bbbf2f0.0"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@tsconfig/node24": "^24.0.4",
@@ -54,9 +54,9 @@
54
54
  "ink-testing-library": "^4.0.0",
55
55
  "typescript-eslint": "^8.67.0",
56
56
  "vitest": "^4.0.16",
57
- "@contentful/experience-design-system-client": "2.34.5-dev-build-d42cd1ad.0",
58
- "@contentful/experience-design-system-generation": "2.34.5-dev-build-d42cd1ad.0",
59
- "@contentful/experience-design-system-extraction": "2.34.5-dev-build-d42cd1ad.0"
57
+ "@contentful/experience-design-system-client": "2.34.5-dev-build-4bbbf2f0.0",
58
+ "@contentful/experience-design-system-extraction": "2.34.5-dev-build-4bbbf2f0.0",
59
+ "@contentful/experience-design-system-generation": "2.34.5-dev-build-4bbbf2f0.0"
60
60
  },
61
61
  "repository": {
62
62
  "type": "git",