@contentful/experience-design-system-cli 2.34.5-dev-build-04d687d.0 → 2.34.5-dev-build-c62cd6f.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-04d687d.0",
3
+ "version": "2.34.5-dev-build-c62cd6f.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,11 +1,17 @@
1
1
  /**
2
2
  * The CLI-owned composition interchange format (spec T1).
3
3
  *
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).
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.
7
13
  */
8
- export type EdgeProvenance = 'typed-slot' | 'structural' | 'manifest' | 'doc' | `adapter:${string}` | 'agent';
14
+ export type EdgeProvenance = 'user' | 'typed-slot' | 'structural' | 'manifest' | 'doc' | `adapter:${string}` | 'agent';
9
15
  export type CompositionEdge = {
10
16
  parent: string;
11
17
  child: string;
@@ -15,3 +21,17 @@ export type CompositionEdge = {
15
21
  confidence?: number;
16
22
  provenance: EdgeProvenance;
17
23
  };
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,7 +1,18 @@
1
+ import { type InterchangeMap } from './interchange-schema.js';
1
2
  export type CompositionCliOptions = {
3
+ /** `--composition-map <path>` — hand-authored interchange file. */
4
+ compositionMap?: string;
2
5
  /** `--composition-refresh` — force edge emission to run even over resolved residue. */
3
6
  compositionRefresh?: boolean;
4
7
  };
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>;
5
16
  export type ResolvedCompositionSources = {
6
17
  forceAgent: boolean;
7
18
  };
@@ -1,8 +1,9 @@
1
1
  import type { RawComponentDefinition } from '../../types.js';
2
- import type { CompositionEdge } from './interchange-schema.js';
2
+ import { type CompositionEdge, type InterchangeMap } 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;
6
7
  edges: CompositionEdge[];
7
8
  conflicts: EdgeConflict[];
8
9
  warnings: string[];
@@ -10,9 +11,9 @@ export type ResolveMappingResult = {
10
11
  /**
11
12
  * Orchestrate composition-edge acquisition and enrichment.
12
13
  *
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
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
16
17
  * this function (see manifest-doc-evidence.ts) and joined via `extraEdges`.
17
18
  * ALL sources — including the code slots already on the incoming components —
18
19
  * are fed into one ranked merge and unioned; non-conflicting edges from every
@@ -27,6 +28,7 @@ export type ResolveMappingResult = {
27
28
  */
28
29
  export declare function resolveMapping(input: {
29
30
  components: RawComponentDefinition[];
31
+ userMap?: InterchangeMap;
30
32
  forceAgent?: boolean;
31
33
  files: Array<{
32
34
  path: string;
@@ -53,7 +55,7 @@ export declare function resolveMapping(input: {
53
55
  /**
54
56
  * Pre-resolved edges from an external source (e.g. manifest or documentation)
55
57
  * path). They join the ranked merge at their own provenance rank alongside
56
- * code slots and other automatic mapping sources.
58
+ * code slots and the user map.
57
59
  */
58
60
  extraEdges?: CompositionEdge[];
59
61
  }): Promise<ResolveMappingResult>;
@@ -1,7 +1,9 @@
1
1
  export type CompositionOptionInput = {
2
+ compositionMap?: string;
2
3
  prompt?: string[];
3
4
  };
4
5
  export type CompositionForwardingOptions = {
6
+ compositionMap?: string;
5
7
  promptOverrides?: string[];
6
8
  };
7
9
  export declare function buildCompositionForwardingOptions(options: CompositionOptionInput): CompositionForwardingOptions;
@@ -17,7 +17,6 @@ export declare function buildGenerateTokensArgs(opts: {
17
17
  model?: string;
18
18
  bedrock?: boolean;
19
19
  noCache?: boolean;
20
- promptOverrides?: string[];
21
20
  }): string[];
22
21
  export declare function buildMapTokensArgs(opts: {
23
22
  sessionId: string;
@@ -25,7 +24,6 @@ export declare function buildMapTokensArgs(opts: {
25
24
  model?: string;
26
25
  noCache?: boolean;
27
26
  skipAgent?: boolean;
28
- promptOverrides?: string[];
29
27
  existingEntitiesPath?: string;
30
28
  }): string[];
31
29
  export declare function shouldRunMapTokens(opts: {
@@ -53,6 +51,7 @@ export type WizardAppProps = {
53
51
  bedrock?: boolean;
54
52
  initialProjectPath?: string;
55
53
  host?: string;
54
+ compositionMap?: string;
56
55
  promptOverrides?: string[];
57
56
  noCache?: boolean;
58
57
  livePreview?: boolean;
@@ -60,4 +59,4 @@ export type WizardAppProps = {
60
59
  skipMapTokens?: boolean;
61
60
  initialRawTokensPath?: string;
62
61
  };
63
- export declare function WizardApp({ initialSpaceId, initialEnvironmentId, initialCmaToken, initialHost, initialAgent, initialModel, bedrock, initialProjectPath, host, promptOverrides, noCache, livePreview, generatePromptPath, skipMapTokens, initialRawTokensPath, }?: WizardAppProps): React.ReactElement;
62
+ export declare function WizardApp({ initialSpaceId, initialEnvironmentId, initialCmaToken, initialHost, initialAgent, initialModel, bedrock, initialProjectPath, host, compositionMap, promptOverrides, noCache, livePreview, generatePromptPath, skipMapTokens, initialRawTokensPath, }?: WizardAppProps): React.ReactElement;
package/dist/src/index.js CHANGED
@@ -4146,17 +4146,12 @@ var init_persistence = __esm({
4146
4146
 
4147
4147
  // packages/experience-design-system-cli/src/lib/agent-model-options.ts
4148
4148
  function addAgentModelOptions(cmd, config = {}) {
4149
- const {
4150
- agentDescription = AGENT_DESCRIPTION,
4151
- includeModel = true,
4152
- includeBedrock = true,
4153
- modelDescription = MODEL_DESCRIPTION
4154
- } = config;
4149
+ const { agentDescription = AGENT_DESCRIPTION, includeModel = true, modelDescription = MODEL_DESCRIPTION } = config;
4155
4150
  cmd.option("--agent <name>", agentDescription);
4156
4151
  if (includeModel) {
4157
4152
  cmd.option("--model <name>", modelDescription);
4158
4153
  }
4159
- if (includeBedrock) cmd.option("--bedrock", BEDROCK_DESCRIPTION);
4154
+ cmd.option("--bedrock", BEDROCK_DESCRIPTION);
4160
4155
  return cmd;
4161
4156
  }
4162
4157
  var AGENT_DESCRIPTION, MODEL_DESCRIPTION, BEDROCK_AGENTS, BEDROCK_DESCRIPTION;
@@ -4915,8 +4910,7 @@ async function runGenerateSkill(skill, opts, verbose = false) {
4915
4910
  const { overrides: promptOverrides, errors: promptErrors } = parsePromptOverrides(opts.prompt ?? []);
4916
4911
  if (promptErrors.length > 0) die(`Error: ${promptErrors.join("; ")}`);
4917
4912
  let generatePrompt;
4918
- const promptStage = skill === "tokens" ? "tokens" : "generate";
4919
- const generateOverride = promptOverrides.get(promptStage);
4913
+ const generateOverride = promptOverrides.get("generate");
4920
4914
  if (generateOverride) {
4921
4915
  try {
4922
4916
  generatePrompt = await resolvePromptOverride(generateOverride);
@@ -5266,12 +5260,7 @@ function registerInternalGenerateCommand(program) {
5266
5260
  addAgentFlags(componentsCmd).action(async (opts) => {
5267
5261
  await runGenerateSkill("components", opts, opts.verbose ?? false);
5268
5262
  });
5269
- const tokensCmd = generate.command("tokens").description("Invoke a coding agent to produce tokens.json from raw token data").option("--raw-tokens <path>", "Path to raw token input file").option(
5270
- "--prompt <stage=value>",
5271
- "Override a stage prompt (repeatable). Used here for the tokens stage.",
5272
- (v, acc) => [...acc, v],
5273
- []
5274
- );
5263
+ const tokensCmd = generate.command("tokens").description("Invoke a coding agent to produce tokens.json from raw token data").option("--raw-tokens <path>", "Path to raw token input file");
5275
5264
  addAgentFlags(tokensCmd).action(async (opts) => {
5276
5265
  await runGenerateSkill("tokens", opts, opts.verbose ?? false);
5277
5266
  });
@@ -7543,7 +7532,7 @@ function buildApplyOutput(operation, spaceId, environmentId, host) {
7543
7532
  };
7544
7533
  }
7545
7534
  function registerApplyCommand(program) {
7546
- 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");
7535
+ 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");
7547
7536
  applyCmd.action(async (file) => {
7548
7537
  const isTTY = getInteractiveTerminalSupport().supported;
7549
7538
  const inputs = await resolveSharedInputsOrDie(file);
@@ -8491,20 +8480,6 @@ async function runMapTokens(opts) {
8491
8480
  );
8492
8481
  }
8493
8482
  const resultAgent = configuredAgent ?? "skipped";
8494
- const { overrides: promptOverrides, errors: promptErrors } = parsePromptOverrides(opts.prompt ?? []);
8495
- if (promptErrors.length > 0) die(`Error: ${promptErrors.join("; ")}`);
8496
- const mapPromptOverride = promptOverrides.get("map-tokens");
8497
- let mapPromptText;
8498
- let mapPromptPath;
8499
- if (mapPromptOverride?.kind === "text") mapPromptText = mapPromptOverride.value;
8500
- if (mapPromptOverride?.kind === "path") {
8501
- mapPromptPath = resolve8(mapPromptOverride.value);
8502
- try {
8503
- await resolvePromptOverride(mapPromptOverride);
8504
- } catch (error) {
8505
- die(`Error: ${error instanceof Error ? error.message : String(error)}`);
8506
- }
8507
- }
8508
8483
  const db = openPipelineDb();
8509
8484
  try {
8510
8485
  const sessionId2 = opts.session ?? findLatestSessionForCommand(db, "generate components");
@@ -8607,19 +8582,16 @@ ${defaultDiagnostics.map((diagnostic) => ` ${diagnostic}`).join("\n")}
8607
8582
  );
8608
8583
  }
8609
8584
  }
8610
- const buildMapPrompt = () => buildPrompt({
8611
- skill: "map-tokens",
8612
- mode: "autonomous",
8613
- generatedCdf,
8614
- tokenTree,
8615
- componentSourceRefs,
8616
- outDir: process.cwd(),
8617
- existingTokensInline,
8618
- ...mapPromptText !== void 0 ? { skillContentOverride: mapPromptText } : {},
8619
- ...mapPromptText === void 0 && mapPromptPath ? { skillPathOverride: mapPromptPath } : {}
8620
- });
8621
8585
  if (opts.printPrompt) {
8622
- const prompt2 = await buildMapPrompt();
8586
+ const prompt2 = await buildPrompt({
8587
+ skill: "map-tokens",
8588
+ mode: "autonomous",
8589
+ generatedCdf,
8590
+ tokenTree,
8591
+ componentSourceRefs,
8592
+ outDir: process.cwd(),
8593
+ existingTokensInline
8594
+ });
8623
8595
  process.stdout.write(prompt2 + "\n");
8624
8596
  await exitWithAnalytics(0);
8625
8597
  return;
@@ -8641,8 +8613,7 @@ ${defaultDiagnostics.map((diagnostic) => ` ${diagnostic}`).join("\n")}
8641
8613
  agent,
8642
8614
  model,
8643
8615
  void 0,
8644
- existingTokensInline ? [hashContent(existingTokensInline)] : [],
8645
- mapPromptText
8616
+ existingTokensInline ? [hashContent(existingTokensInline)] : []
8646
8617
  );
8647
8618
  const inputHash = computeMapTokensInputHash(db, sessionId2, componentSourceRefs);
8648
8619
  if (!noCache) {
@@ -8664,7 +8635,15 @@ Install it, choose another agent with --agent, or use --print-prompt to run the
8664
8635
  );
8665
8636
  }
8666
8637
  const stepId = createStep(db, sessionId2, "map tokens", { agent, model: model ?? "" });
8667
- const prompt = await buildMapPrompt();
8638
+ const prompt = await buildPrompt({
8639
+ skill: "map-tokens",
8640
+ mode: "autonomous",
8641
+ generatedCdf,
8642
+ tokenTree,
8643
+ componentSourceRefs,
8644
+ outDir: process.cwd(),
8645
+ existingTokensInline
8646
+ });
8668
8647
  const invoker2 = createLocalCliAgentInvoker();
8669
8648
  const result = await invoker2.invoke({ agent, model, prompt, timeoutMs: DEFAULT_TIMEOUT_MS2 });
8670
8649
  if (result.timedOut || result.exitCode !== 0) {
@@ -8690,12 +8669,7 @@ ${warnings.map((w) => ` ${w}`).join("\n")}
8690
8669
  }
8691
8670
  function registerMapTokensCommand(program) {
8692
8671
  const map = program.command("map", { hidden: true }).description("Suggest token restrictions for generated design-token props");
8693
- const tokensCmd = map.command("tokens").description("Invoke a coding agent to suggest $token.allowed for design-category token props").option("--session <id>", "Session ID from generate components (defaults to most recent)").option("--print-prompt", "Print the prompt without invoking the agent").option("--skip-agent", "Resolve token defaults without agentic $token.allowed inference").option("--no-cache", "Bypass the map-tokens cache and force a re-run").option(
8694
- "--prompt <stage=value>",
8695
- "Override a stage prompt (repeatable). Used here for the map-tokens stage.",
8696
- (v, acc) => [...acc, v],
8697
- []
8698
- ).option("--token-map <path>", "Path to token-name-map.json sidecar").option(
8672
+ const tokensCmd = map.command("tokens").description("Invoke a coding agent to suggest $token.allowed for design-category token props").option("--session <id>", "Session ID from generate components (defaults to most recent)").option("--print-prompt", "Print the prompt without invoking the agent").option("--skip-agent", "Resolve token defaults without agentic $token.allowed inference").option("--no-cache", "Bypass the map-tokens cache and force a re-run").option("--token-map <path>", "Path to token-name-map.json sidecar").option(
8699
8673
  "--existing-entities-path <path>",
8700
8674
  "Path to the .existing-entities.json file written after CMA credentials are supplied. When present, the agent gets a list of the space's existing design tokens so it can prefer binding to them. Missing/malformed files are treated as no-op."
8701
8675
  );
@@ -8720,7 +8694,6 @@ var init_command4 = __esm({
8720
8694
  init_MapTokensView();
8721
8695
  init_resolve_defaults();
8722
8696
  init_cli_errors();
8723
- init_prompt_overrides();
8724
8697
  DEFAULT_TIMEOUT_MS2 = Number(process.env.EDS_AGENT_TIMEOUT_MS ?? 5 * 60 * 1e3);
8725
8698
  }
8726
8699
  });
@@ -8748,41 +8721,10 @@ var init_path_utils = __esm({
8748
8721
  }
8749
8722
  });
8750
8723
 
8751
- // packages/experience-design-system-cli/src/import/agent-model-resolve.ts
8752
- function parseAgentModel(value) {
8753
- if (!value?.trim()) return {};
8754
- const trimmed = value.trim();
8755
- const separator = trimmed.indexOf(":");
8756
- if (separator >= 0) {
8757
- return {
8758
- agent: trimmed.slice(0, separator).trim() || void 0,
8759
- model: trimmed.slice(separator + 1).trim() || void 0
8760
- };
8761
- }
8762
- const [agent, ...modelParts] = trimmed.split(/\s+/);
8763
- return { agent, ...modelParts.length > 0 ? { model: modelParts.join(" ") } : {} };
8764
- }
8765
- function resolveAgent(flagValue, storedValue) {
8766
- if (flagValue && flagValue.length > 0) return flagValue;
8767
- if (storedValue && storedValue.length > 0) return storedValue;
8768
- return DEFAULT_AGENT;
8769
- }
8770
- function resolveModel(flagValue, storedValue) {
8771
- if (flagValue && flagValue.length > 0) return flagValue;
8772
- if (storedValue && storedValue.length > 0) return storedValue;
8773
- return void 0;
8774
- }
8775
- var DEFAULT_AGENT;
8776
- var init_agent_model_resolve = __esm({
8777
- "packages/experience-design-system-cli/src/import/agent-model-resolve.ts"() {
8778
- "use strict";
8779
- DEFAULT_AGENT = "claude";
8780
- }
8781
- });
8782
-
8783
8724
  // packages/experience-design-system-cli/src/import/composition-options.ts
8784
8725
  function buildCompositionForwardingOptions(options) {
8785
8726
  return {
8727
+ ...options.compositionMap ? { compositionMap: options.compositionMap } : {},
8786
8728
  ...options.prompt && options.prompt.length > 0 ? { promptOverrides: options.prompt } : {}
8787
8729
  };
8788
8730
  }
@@ -26637,70 +26579,6 @@ var init_wizard_state_transitions = __esm({
26637
26579
  }
26638
26580
  });
26639
26581
 
26640
- // packages/experience-design-system-cli/src/import/tui/run-selection-agent.ts
26641
- async function runSelectionAgent(options) {
26642
- const db = openPipelineDb();
26643
- let components;
26644
- try {
26645
- components = loadRawComponents(db, options.sessionId);
26646
- } finally {
26647
- db.close();
26648
- }
26649
- if (components.length === 0) return;
26650
- const invoker2 = createLocalCliAgentInvoker({
26651
- onDebugEvent: (name, payload) => getDebugLogger().event("agent", name, payload)
26652
- });
26653
- const prompt = await buildPrompt({
26654
- skill: "select",
26655
- mode: "autonomous",
26656
- rawComponentsInline: JSON.stringify(components, null, 2),
26657
- outDir: process.cwd(),
26658
- ...options.promptText !== void 0 ? { skillContentOverride: options.promptText } : {},
26659
- ...options.promptText === void 0 && options.promptPath ? { skillPathOverride: options.promptPath } : {}
26660
- });
26661
- const { result } = await invokeAgentWithOutput(
26662
- invoker2,
26663
- { agent: options.agent, model: options.model, prompt, timeoutMs: DEFAULT_TIMEOUT_MS4 },
26664
- false
26665
- );
26666
- if (result.timedOut) throw new Error("selection agent timed out");
26667
- if (result.exitCode !== 0) throw new Error(`selection agent exited with code ${result.exitCode}`);
26668
- const { calls, warnings } = parseSelectToolCallLines(result.stdout);
26669
- for (const warning of warnings) process.stderr.write(`Warning: selection agent: ${warning}
26670
- `);
26671
- const byName = new Map(calls.map((call) => [call.name, call]));
26672
- const writeDb = openPipelineDb();
26673
- try {
26674
- const update = writeDb.prepare(
26675
- `UPDATE raw_components SET status = ?, reject_reason = ? WHERE session_id = ? AND component_id = ?`
26676
- );
26677
- for (const component of components) {
26678
- const call = byName.get(component.name);
26679
- if (!call) continue;
26680
- const rejected = call.tool === "reject_component";
26681
- update.run(
26682
- rejected ? "rejected" : "accepted",
26683
- rejected ? call.reason ?? null : null,
26684
- options.sessionId,
26685
- component.component_id
26686
- );
26687
- }
26688
- } finally {
26689
- writeDb.close();
26690
- }
26691
- }
26692
- var DEFAULT_TIMEOUT_MS4;
26693
- var init_run_selection_agent = __esm({
26694
- "packages/experience-design-system-cli/src/import/tui/run-selection-agent.ts"() {
26695
- "use strict";
26696
- init_src();
26697
- init_debug_logger();
26698
- init_agent_output();
26699
- init_db();
26700
- DEFAULT_TIMEOUT_MS4 = Number(process.env.EDS_AGENT_TIMEOUT_MS ?? 5 * 60 * 1e3);
26701
- }
26702
- });
26703
-
26704
26582
  // packages/experience-design-system-cli/src/import/tui/WizardApp.tsx
26705
26583
  var WizardApp_exports = {};
26706
26584
  __export(WizardApp_exports, {
@@ -26739,7 +26617,6 @@ function buildGenerateTokensArgs(opts) {
26739
26617
  if (opts.model) args.push("--model", opts.model);
26740
26618
  if (opts.bedrock) args.push("--bedrock");
26741
26619
  if (opts.noCache) args.push("--no-cache");
26742
- for (const prompt of opts.promptOverrides ?? []) args.push("--prompt", prompt);
26743
26620
  return args;
26744
26621
  }
26745
26622
  function buildMapTokensArgs(opts) {
@@ -26747,7 +26624,6 @@ function buildMapTokensArgs(opts) {
26747
26624
  if (opts.model) args.push("--model", opts.model);
26748
26625
  if (opts.noCache) args.push("--no-cache");
26749
26626
  if (opts.skipAgent) args.push("--skip-agent");
26750
- for (const prompt of opts.promptOverrides ?? []) args.push("--prompt", prompt);
26751
26627
  if (opts.existingEntitiesPath) args.push("--existing-entities-path", opts.existingEntitiesPath);
26752
26628
  return args;
26753
26629
  }
@@ -26823,6 +26699,7 @@ function WizardApp({
26823
26699
  bedrock = false,
26824
26700
  initialProjectPath,
26825
26701
  host,
26702
+ compositionMap,
26826
26703
  promptOverrides,
26827
26704
  noCache = false,
26828
26705
  livePreview = true,
@@ -26992,8 +26869,7 @@ If you are using AWS Bedrock, run:
26992
26869
  agent: state.agent,
26993
26870
  ...state.agentModel ? { model: state.agentModel } : {},
26994
26871
  ...state.bedrock ? { bedrock: true } : {},
26995
- noCache: effectiveNoCache,
26996
- promptOverrides
26872
+ noCache: effectiveNoCache
26997
26873
  });
26998
26874
  const result = await runSpawnedCli(tokenArgs);
26999
26875
  if (result.exitCode !== 0) {
@@ -27073,7 +26949,6 @@ If you are using AWS Bedrock, run:
27073
26949
  ...state.agentModel ? { model: state.agentModel } : {},
27074
26950
  noCache: effectiveNoCache,
27075
26951
  skipAgent: skipMapTokens,
27076
- promptOverrides,
27077
26952
  ...state.existingEntitiesPath ? { existingEntitiesPath: state.existingEntitiesPath } : {}
27078
26953
  });
27079
26954
  const result = await runCli(args);
@@ -27092,6 +26967,7 @@ If you are using AWS Bedrock, run:
27092
26967
  update({ step: "extracting", outDir, extractProgress: null, compositionPhase: null });
27093
26968
  const extractArgs = [findCliPath(), "__extract", "--project", projectPath];
27094
26969
  if (noCache) extractArgs.push("--composition-refresh");
26970
+ if (compositionMap) extractArgs.push("--composition-map", compositionMap);
27095
26971
  for (const p of promptOverrides ?? []) extractArgs.push("--prompt", p);
27096
26972
  if (state.agent) extractArgs.push("--agent", state.agent);
27097
26973
  if (state.bedrock) extractArgs.push("--bedrock");
@@ -27156,34 +27032,6 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
27156
27032
  });
27157
27033
  return;
27158
27034
  }
27159
- try {
27160
- const { overrides, errors } = parsePromptOverrides(promptOverrides ?? []);
27161
- if (errors.length > 0) throw new Error(errors.join("; "));
27162
- const selectOverride = overrides.get("select");
27163
- let promptText;
27164
- let promptPath;
27165
- if (selectOverride?.kind === "text") promptText = selectOverride.value;
27166
- if (selectOverride?.kind === "path") {
27167
- promptPath = resolve17(selectOverride.value);
27168
- await resolvePromptOverride(selectOverride);
27169
- }
27170
- if (state.agent) {
27171
- await runSelectionAgent({
27172
- sessionId: extractSessionId ?? "",
27173
- agent: state.agent,
27174
- ...state.agentModel ? { model: state.agentModel } : {},
27175
- ...promptText !== void 0 ? { promptText } : {},
27176
- ...promptPath ? { promptPath } : {}
27177
- });
27178
- }
27179
- } catch (error) {
27180
- update({
27181
- step: "error",
27182
- errorStep: "selection agent",
27183
- errorMessage: error instanceof Error ? error.message : String(error)
27184
- });
27185
- return;
27186
- }
27187
27035
  update({
27188
27036
  step: "scope-gate",
27189
27037
  extractSessionId
@@ -28430,8 +28278,6 @@ var init_WizardApp = __esm({
28430
28278
  init_fetch_and_persist_existing_contentful_entities();
28431
28279
  init_wizard_state_transitions();
28432
28280
  init_cli_path();
28433
- init_prompt_overrides();
28434
- init_run_selection_agent();
28435
28281
  WIZARD_LOG = join20(tmpdir(), "experiences-import-wizard.log");
28436
28282
  }
28437
28283
  });
@@ -28439,73 +28285,81 @@ var init_WizardApp = __esm({
28439
28285
  // packages/experience-design-system-cli/src/import/command.ts
28440
28286
  function registerImportCommand(program) {
28441
28287
  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", ".");
28442
- cmd.option(
28443
- "--tokens <path>",
28444
- "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."
28445
- );
28446
28288
  addAgentModelOptions(cmd, {
28447
- agentDescription: 'Agent and optional model as agent:model or "agent model" (overrides credentials.json; falls back to "claude")',
28448
- includeModel: false,
28449
- includeBedrock: false
28450
- });
28451
- cmd.option(
28289
+ agentDescription: 'Agent to use for generate components (overrides credentials.json; falls back to "claude")',
28290
+ modelDescription: "Model to use for generate components (defaults to a lightweight per-agent model; override with EDS_AGENT_MODEL_<AGENT>)"
28291
+ }).option(
28292
+ "--raw-tokens <path>",
28293
+ "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."
28294
+ ).option(
28295
+ "--skip-map-tokens",
28296
+ "Skip agentic token restrictions while still resolving deterministic token-default paths"
28297
+ ).option("--no-cache", "Re-run all steps even if output already exists");
28298
+ cmd.option("--composition-map <path>", "Consume a hand-authored parent\u2192children interchange map").option(
28452
28299
  "--prompt <stage=value>",
28453
- "Override a composition, selection, token, generation, or token-mapping prompt (repeatable). value is a file path or literal text, e.g. --prompt select=./p.md",
28300
+ "Override a stage prompt (repeatable). value is a file path or literal text, e.g. --prompt composition=./p.md",
28454
28301
  (v, acc) => [...acc, v],
28455
28302
  []
28456
- ).option("--no-cache", "Re-run all steps even if output already exists").action(async (opts) => {
28457
- const interactiveTerminalSupported = getInteractiveTerminalSupport().supported;
28458
- if (opts.tokens !== void 0) {
28459
- const { access: access9 } = await import("node:fs/promises");
28460
- try {
28461
- await access9(normalizePath(opts.tokens));
28462
- } catch {
28463
- process.stderr.write(`Error: --tokens: file not found: ${opts.tokens}
28303
+ ).action(
28304
+ async (opts) => {
28305
+ const interactiveTerminalSupported = getInteractiveTerminalSupport().supported;
28306
+ if (opts.rawTokens !== void 0) {
28307
+ const { access: access9 } = await import("node:fs/promises");
28308
+ try {
28309
+ await access9(normalizePath(opts.rawTokens));
28310
+ } catch {
28311
+ process.stderr.write(`Error: --raw-tokens: file not found: ${opts.rawTokens}
28464
28312
  `);
28465
- process.exit(1);
28313
+ process.exit(1);
28314
+ return;
28315
+ }
28316
+ }
28317
+ if (!interactiveTerminalSupported) {
28318
+ requireInteractiveTerminal({
28319
+ alternative: "run experiences import in an interactive terminal"
28320
+ });
28321
+ }
28322
+ {
28323
+ const { render: render5 } = await import("ink");
28324
+ const { createElement: createElement6 } = await import("react");
28325
+ const { WizardApp: WizardApp2 } = await Promise.resolve().then(() => (init_WizardApp(), WizardApp_exports));
28326
+ const creds = await readExperiencesCredentials();
28327
+ const resolvedAgent = opts.agent || creds.agent || "claude";
28328
+ const resolvedModel = opts.model || creds.agentModel || void 0;
28329
+ if (opts.bedrock && !(isAgentName(resolvedAgent) && agentSupportsBedrock(resolvedAgent))) {
28330
+ process.stderr.write(`Error: --bedrock is not supported for --agent ${resolvedAgent}
28331
+ `);
28332
+ process.exit(1);
28333
+ }
28334
+ const { waitUntilExit } = render5(
28335
+ createElement6(WizardApp2, {
28336
+ initialSpaceId: creds.spaceId,
28337
+ initialEnvironmentId: creds.environmentId || "master",
28338
+ initialCmaToken: creds.cmaToken,
28339
+ initialHost: toConfiguredHost(creds.host) ?? DEFAULT_CONFIGURED_HOST,
28340
+ initialAgent: resolvedAgent,
28341
+ ...resolvedModel ? { initialModel: resolvedModel } : {},
28342
+ ...opts.bedrock ? { bedrock: true } : {},
28343
+ initialProjectPath: opts.project !== "." ? normalizePath(opts.project) : void 0,
28344
+ ...buildCompositionForwardingOptions(opts),
28345
+ noCache: opts.cache === false,
28346
+ skipMapTokens: opts.skipMapTokens ?? false,
28347
+ livePreview: true,
28348
+ generatePromptPath: creds.generatePromptPath,
28349
+ ...opts.rawTokens ? { initialRawTokensPath: normalizePath(opts.rawTokens) } : {}
28350
+ })
28351
+ );
28352
+ await waitUntilExit();
28466
28353
  return;
28467
28354
  }
28468
28355
  }
28469
- if (!interactiveTerminalSupported) {
28470
- requireInteractiveTerminal({
28471
- alternative: "run experiences import in an interactive terminal"
28472
- });
28473
- }
28474
- {
28475
- const { render: render5 } = await import("ink");
28476
- const { createElement: createElement6 } = await import("react");
28477
- const { WizardApp: WizardApp2 } = await Promise.resolve().then(() => (init_WizardApp(), WizardApp_exports));
28478
- const creds = await readExperiencesCredentials();
28479
- const parsedAgentModel = parseAgentModel(opts.agent);
28480
- const resolvedAgent = resolveAgent(parsedAgentModel.agent, creds.agent);
28481
- const resolvedModel = resolveModel(parsedAgentModel.model, creds.agentModel);
28482
- const { waitUntilExit } = render5(
28483
- createElement6(WizardApp2, {
28484
- initialSpaceId: creds.spaceId,
28485
- initialEnvironmentId: creds.environmentId || "master",
28486
- initialCmaToken: creds.cmaToken,
28487
- initialHost: toConfiguredHost(creds.host) ?? DEFAULT_CONFIGURED_HOST,
28488
- initialAgent: resolvedAgent,
28489
- ...resolvedModel ? { initialModel: resolvedModel } : {},
28490
- initialProjectPath: opts.project !== "." ? normalizePath(opts.project) : void 0,
28491
- ...buildCompositionForwardingOptions(opts),
28492
- noCache: opts.cache === false,
28493
- skipMapTokens: false,
28494
- livePreview: true,
28495
- generatePromptPath: creds.generatePromptPath,
28496
- ...opts.tokens ? { initialRawTokensPath: normalizePath(opts.tokens) } : {}
28497
- })
28498
- );
28499
- await waitUntilExit();
28500
- return;
28501
- }
28502
- });
28356
+ );
28503
28357
  }
28504
28358
  var init_command6 = __esm({
28505
28359
  "packages/experience-design-system-cli/src/import/command.ts"() {
28506
28360
  "use strict";
28361
+ init_src();
28507
28362
  init_path_utils();
28508
- init_agent_model_resolve();
28509
28363
  init_agent_model_options();
28510
28364
  init_credentials_store();
28511
28365
  init_host_utils();
@@ -28816,7 +28670,7 @@ var init_checks2 = __esm({
28816
28670
  });
28817
28671
 
28818
28672
  // packages/experience-design-system-cli/src/doctor/command.ts
28819
- async function runChecks() {
28673
+ async function runChecks(opts) {
28820
28674
  const pkgRoot = findPkgRoot();
28821
28675
  const results = [];
28822
28676
  const record = (name, passed, required = true) => {
@@ -28825,11 +28679,13 @@ async function runChecks() {
28825
28679
  };
28826
28680
  if (record("Node.js version", await reportNode())) {
28827
28681
  const pnpmOk = record("pnpm", await reportPnpm(pkgRoot));
28828
- if (pnpmOk && record("dependencies", await reportDependencies(pkgRoot))) {
28682
+ if (opts.skipBuild) {
28683
+ info("\nSkipping install + build (--skip-build)");
28684
+ } else if (pnpmOk && record("dependencies", await reportDependencies(pkgRoot))) {
28829
28685
  record("build", await reportBuild(pkgRoot));
28830
28686
  }
28831
28687
  }
28832
- record("coding agent", await reportAgent(), false);
28688
+ if (!opts.skipAgent) record("coding agent", await reportAgent(), false);
28833
28689
  return results;
28834
28690
  }
28835
28691
  function printSummary(results) {
@@ -28869,13 +28725,13 @@ ${c.red(c.bold(`\u2717 ${requiredFailed} required check${requiredFailed === 1 ?
28869
28725
  `);
28870
28726
  return 1;
28871
28727
  }
28872
- async function runDoctor() {
28728
+ async function runDoctor(opts) {
28873
28729
  process.stderr.write(`${c.bold("experiences doctor")} \u2014 checking your environment
28874
28730
  `);
28875
- process.exitCode = printSummary(await runChecks());
28731
+ process.exitCode = printSummary(await runChecks(opts));
28876
28732
  }
28877
28733
  function registerDoctorCommand(program) {
28878
- program.command("doctor").description("Check prerequisites so experiences import runs without errors").helpOption(false).action(() => runDoctor());
28734
+ 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));
28879
28735
  }
28880
28736
  var init_command7 = __esm({
28881
28737
  "packages/experience-design-system-cli/src/doctor/command.ts"() {
@@ -30015,7 +29871,7 @@ async function runSetup(opts) {
30015
29871
  process.exit(finished.exitCode);
30016
29872
  }
30017
29873
  function registerSetupCommand(program) {
30018
- program.command("setup").description("Interactive setup: installs prerequisites and configures credentials for experiences import").helpOption(false).action(() => runSetup({}));
29874
+ 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));
30019
29875
  }
30020
29876
  var SETUP_REQUIRES_TTY_MESSAGE;
30021
29877
  var init_command8 = __esm({
@@ -30027,14 +29883,57 @@ var init_command8 = __esm({
30027
29883
  }
30028
29884
  });
30029
29885
 
29886
+ // packages/experience-design-system-cli/src/analyze/composition/interchange-schema.ts
29887
+ function validateInterchangeMap(input) {
29888
+ const errors = [];
29889
+ if (typeof input !== "object" || input === null || Array.isArray(input)) {
29890
+ return { valid: false, errors: ["interchange map must be a JSON object"] };
29891
+ }
29892
+ const obj = input;
29893
+ if (obj.version !== 1) {
29894
+ errors.push(`unsupported interchange version: expected 1, got ${JSON.stringify(obj.version)}`);
29895
+ }
29896
+ if (typeof obj.groups !== "object" || obj.groups === null || Array.isArray(obj.groups)) {
29897
+ errors.push("interchange map must have a `groups` object");
29898
+ return { valid: false, errors };
29899
+ }
29900
+ const groups = obj.groups;
29901
+ for (const [parent, children] of Object.entries(groups)) {
29902
+ if (!Array.isArray(children) || !children.every((c2) => typeof c2 === "string")) {
29903
+ errors.push(`groups["${parent}"] must be an array of strings`);
29904
+ }
29905
+ }
29906
+ if (errors.length > 0) return { valid: false, errors };
29907
+ return { valid: true, map: { version: 1, groups } };
29908
+ }
29909
+ function groupsToEdges(map, provenance) {
29910
+ const seen = /* @__PURE__ */ new Set();
29911
+ const edges = [];
29912
+ for (const [parent, children] of Object.entries(map.groups)) {
29913
+ for (const child of children) {
29914
+ const key = `${parent}::${child}`;
29915
+ if (seen.has(key)) continue;
29916
+ seen.add(key);
29917
+ edges.push({ parent, child, provenance });
29918
+ }
29919
+ }
29920
+ return edges;
29921
+ }
29922
+ var init_interchange_schema = __esm({
29923
+ "packages/experience-design-system-cli/src/analyze/composition/interchange-schema.ts"() {
29924
+ "use strict";
29925
+ }
29926
+ });
29927
+
30030
29928
  // packages/experience-design-system-cli/src/analyze/composition/merge-edges.ts
30031
29929
  function rank(p) {
30032
- if (p === "typed-slot") return 1;
30033
- if (p === "structural") return 2;
30034
- if (p === "manifest") return 3;
30035
- if (p === "doc") return 4;
30036
- if (p.startsWith("adapter:")) return 5;
30037
- return 6;
29930
+ if (p === "user") return 1;
29931
+ if (p === "typed-slot") return 2;
29932
+ if (p === "structural") return 3;
29933
+ if (p === "manifest") return 4;
29934
+ if (p === "doc") return 5;
29935
+ if (p.startsWith("adapter:")) return 6;
29936
+ return 7;
30038
29937
  }
30039
29938
  function mergeEdges(all) {
30040
29939
  const byKey = /* @__PURE__ */ new Map();
@@ -30140,7 +30039,7 @@ function applyMapping(components, edges) {
30140
30039
  }))
30141
30040
  }));
30142
30041
  const byName = new Map(cloned.map((c2) => [c2.name, c2]));
30143
- const isHighTrust = (p) => p === "typed-slot" || p.startsWith("adapter:");
30042
+ const isHighTrust = (p) => p === "user" || p === "typed-slot" || p.startsWith("adapter:");
30144
30043
  const addAllowed = (slot, child) => {
30145
30044
  const set = new Set(slot.allowedComponents ?? []);
30146
30045
  set.add(child);
@@ -30239,6 +30138,7 @@ async function resolveMapping(input) {
30239
30138
  }
30240
30139
  }
30241
30140
  }
30141
+ if (input.userMap) collected.push(...groupsToEdges(input.userMap, "user"));
30242
30142
  if (input.extraEdges) {
30243
30143
  collected.push(...input.extraEdges);
30244
30144
  }
@@ -30286,6 +30186,7 @@ ${f.content}`).join("\n\n");
30286
30186
  var init_resolve_mapping = __esm({
30287
30187
  "packages/experience-design-system-cli/src/analyze/composition/resolve-mapping.ts"() {
30288
30188
  "use strict";
30189
+ init_interchange_schema();
30289
30190
  init_merge_edges();
30290
30191
  init_parse_map_edges();
30291
30192
  init_apply_mapping();
@@ -30294,6 +30195,24 @@ var init_resolve_mapping = __esm({
30294
30195
  });
30295
30196
 
30296
30197
  // packages/experience-design-system-cli/src/analyze/composition/resolve-mapping-cli.ts
30198
+ import { readFile as readFile18 } from "node:fs/promises";
30199
+ async function loadUserMap(path) {
30200
+ let text;
30201
+ try {
30202
+ text = await readFile18(path, "utf8");
30203
+ } catch {
30204
+ return { ok: false, error: `--composition-map: file not found: ${path}` };
30205
+ }
30206
+ let parsed;
30207
+ try {
30208
+ parsed = JSON.parse(text);
30209
+ } catch {
30210
+ return { ok: false, error: `--composition-map: not valid JSON: ${path}` };
30211
+ }
30212
+ const result = validateInterchangeMap(parsed);
30213
+ if (!result.valid) return { ok: false, error: `--composition-map: ${result.errors.join("; ")}` };
30214
+ return { ok: true, map: result.map };
30215
+ }
30297
30216
  function resolveCompositionSources(opts) {
30298
30217
  return {
30299
30218
  forceAgent: !!opts.compositionRefresh
@@ -30302,6 +30221,7 @@ function resolveCompositionSources(opts) {
30302
30221
  var init_resolve_mapping_cli = __esm({
30303
30222
  "packages/experience-design-system-cli/src/analyze/composition/resolve-mapping-cli.ts"() {
30304
30223
  "use strict";
30224
+ init_interchange_schema();
30305
30225
  }
30306
30226
  });
30307
30227
 
@@ -30463,7 +30383,7 @@ var init_manifest_doc_evidence = __esm({
30463
30383
  });
30464
30384
 
30465
30385
  // packages/experience-design-system-cli/src/analyze/extract-command.ts
30466
- import { mkdir as mkdir6, readdir as readdir3, readFile as readFile18, stat as stat6 } from "node:fs/promises";
30386
+ import { mkdir as mkdir6, readdir as readdir3, readFile as readFile19, stat as stat6 } from "node:fs/promises";
30467
30387
  import { isAbsolute as isAbsolute2, join as join25, relative as relative2, resolve as resolve19 } from "node:path";
30468
30388
  function isDenylistedNoiseFile(name) {
30469
30389
  return DENYLISTED_EXACT_FILE_NAMES.has(name) || DENYLISTED_FILE_NAME_PATTERNS.some((pattern) => pattern.test(name));
@@ -30530,7 +30450,7 @@ async function readCandidateFiles(components, extraFiles = []) {
30530
30450
  await Promise.all(
30531
30451
  [...paths].map(async (p) => {
30532
30452
  try {
30533
- const content = await readFile18(p, "utf8");
30453
+ const content = await readFile19(p, "utf8");
30534
30454
  out.push({ path: p, content });
30535
30455
  } catch {
30536
30456
  }
@@ -30543,7 +30463,7 @@ function registerInternalExtractCommand(program) {
30543
30463
  "--resolve-unreachable <mode>",
30544
30464
  "Retry pass for unresolved Svelte Props types: 'auto' (default), 'always', or 'never'",
30545
30465
  "auto"
30546
- ).option("--composition-refresh", "Force the mapping agent to run even where deterministic sources answered").option(
30466
+ ).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(
30547
30467
  "--prompt <stage=value>",
30548
30468
  "Override a stage prompt (repeatable). value is a file path or literal text, e.g. --prompt composition=./p.md",
30549
30469
  (v, acc) => [...acc, v],
@@ -30659,6 +30579,16 @@ function registerInternalExtractCommand(program) {
30659
30579
  let validatedComponents = validateExtractedComponents(filteredComponents);
30660
30580
  {
30661
30581
  const sources = resolveCompositionSources(opts);
30582
+ let userMap;
30583
+ if (opts.compositionMap) {
30584
+ const loaded = await loadUserMap(opts.compositionMap);
30585
+ if (!loaded.ok) {
30586
+ process.stderr.write(`Error: ${loaded.error}
30587
+ `);
30588
+ process.exit(1);
30589
+ }
30590
+ userMap = loaded.map;
30591
+ }
30662
30592
  const { overrides: promptOverrides, errors: promptErrors } = parsePromptOverrides(opts.prompt ?? []);
30663
30593
  for (const err of promptErrors) {
30664
30594
  process.stderr.write(`Error: ${err}
@@ -30720,6 +30650,7 @@ function registerInternalExtractCommand(program) {
30720
30650
  });
30721
30651
  const result = await resolveMapping({
30722
30652
  components: validatedComponents,
30653
+ ...userMap ? { userMap } : {},
30723
30654
  ...extraEdges.length > 0 ? { extraEdges } : {},
30724
30655
  forceAgent: sources.forceAgent,
30725
30656
  files: promptFiles,
@@ -30926,7 +30857,7 @@ function resolveBedrockFromAncestors(actionCommand) {
30926
30857
  return false;
30927
30858
  }
30928
30859
  function registerImportV2Command(program) {
30929
- program.command("importv2").description("Launch the v2 import TUI (experience-design-system-cli-v2)").helpOption(false).action(async () => {
30860
+ program.command("importv2").description("Launch the v2 import TUI (experience-design-system-cli-v2)").action(async () => {
30930
30861
  const { render: render5 } = await import("ink");
30931
30862
  const { createElement: createElement6 } = await import("react");
30932
30863
  const { App } = await import("@contentful/experience-design-system-cli-v2/app");
@@ -30935,7 +30866,7 @@ function registerImportV2Command(program) {
30935
30866
  });
30936
30867
  }
30937
30868
  function registerBuildCommand(program) {
30938
- program.command("build").description("Rebuild from source and re-link exo/experiences binaries to this build").helpOption(false).action(async () => {
30869
+ program.command("build").description("Rebuild from source and re-link exo/experiences binaries to this build").action(async () => {
30939
30870
  const pkgRoot = resolve20(dirname13(fileURLToPath4(import.meta.url)), "..", "..");
30940
30871
  process.stderr.write("\u2699 Building from source...\n");
30941
30872
  const { exitCode } = await runBuild({
@@ -30945,35 +30876,32 @@ function registerBuildCommand(program) {
30945
30876
  process.exit(exitCode);
30946
30877
  });
30947
30878
  }
30948
- function configureRootHelpOrder(program) {
30949
- const order = ["build", "help", "import", "apply", "importv2", "setup", "doctor"];
30950
- const rank2 = new Map(order.map((name, index) => [name, index]));
30951
- program.configureHelp({
30952
- visibleCommands(command) {
30953
- const internals = command;
30954
- const visible = command.commands.filter((entry) => !entry._hidden);
30955
- const helpCommand = internals._getHelpCommand?.();
30956
- if (helpCommand && !helpCommand._hidden) visible.push(helpCommand);
30957
- if (command !== program) return visible;
30958
- return visible.sort((a, b) => (rank2.get(a.name()) ?? order.length) - (rank2.get(b.name()) ?? order.length));
30959
- }
30960
- });
30961
- }
30962
30879
  function createProgram() {
30963
30880
  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");
30964
30881
  registerInternalGenerateCommand(program);
30965
30882
  registerInternalExtractCommand(program);
30966
30883
  registerPrintCommand(program);
30967
30884
  registerMapTokensCommand(program);
30968
- registerBuildCommand(program);
30969
- program.helpCommand("help [command]", "display help for command");
30970
- registerImportCommand(program);
30971
30885
  registerApplyCommand(program);
30886
+ registerImportCommand(program);
30972
30887
  registerImportV2Command(program);
30973
- registerSetupCommand(program);
30974
30888
  registerDoctorCommand(program);
30975
- configureRootHelpOrder(program);
30889
+ registerSetupCommand(program);
30890
+ registerBuildCommand(program);
30891
+ program.option(
30892
+ "--debug",
30893
+ "Write a JSONL trace of every decision to ~/.contentful/experience-design-system-cli/debug/"
30894
+ );
30895
+ program.option("--no-debug", "Force debug logging off (overrides EDSI_DEBUG and persisted setup preference)");
30976
30896
  program.hook("preAction", async (_thisCommand, actionCommand) => {
30897
+ let debug;
30898
+ for (let c2 = actionCommand; c2; c2 = c2.parent) {
30899
+ const opts = c2.opts();
30900
+ if (opts.debug !== void 0) {
30901
+ debug = opts.debug;
30902
+ break;
30903
+ }
30904
+ }
30977
30905
  if (resolveBedrockFromAncestors(actionCommand)) {
30978
30906
  process.env.EDS_BEDROCK = "1";
30979
30907
  }
@@ -30983,7 +30911,7 @@ function createProgram() {
30983
30911
  const { analyticsDisabled } = await readExperiencesCredentials();
30984
30912
  setPersistedAnalyticsDisabled(analyticsDisabled ?? false);
30985
30913
  noteCommandStart(commandChain);
30986
- await beginCommand(commandChain, {});
30914
+ await beginCommand(commandChain, { ...debug !== void 0 ? { debug } : {} });
30987
30915
  });
30988
30916
  program.hook("postAction", async () => {
30989
30917
  await completeActiveCommand();
@@ -4,12 +4,12 @@ export declare const MODEL_DESCRIPTION = "Model to use (defaults to a lightweigh
4
4
  export interface AgentModelOptionsConfig {
5
5
  agentDescription?: string;
6
6
  includeModel?: boolean;
7
- includeBedrock?: boolean;
8
7
  modelDescription?: string;
9
8
  }
10
9
  /**
11
- * Register --agent plus optional --model and --bedrock flags with a Commander
12
- * command. The optional flags can be omitted for commands with a narrower
13
- * public surface.
10
+ * Register --agent, --bedrock, and optional --model flags with a Commander
11
+ * command. Pass includeModel: false to omit --model only — --bedrock is
12
+ * independent of model selection (it's a routing switch, not a model choice)
13
+ * and is always registered alongside --agent.
14
14
  */
15
15
  export declare function addAgentModelOptions(cmd: Command, config?: AgentModelOptionsConfig): Command;
@@ -29,8 +29,9 @@ export declare function __resetDebugLoggerForTest(): void;
29
29
  * Resolve effective debug-mode setting from three sources.
30
30
  *
31
31
  * Precedence (highest first):
32
- * 1. `EDSI_DEBUG` env var (truthy: 1, true, yes, on)
33
- * 2. Persisted `debug` field in credentials.json
32
+ * 1. `--debug` / `--no-debug` CLI flag
33
+ * 2. `EDSI_DEBUG` env var (truthy: 1, true, yes, on)
34
+ * 3. Persisted `debug` field in credentials.json
34
35
  * 4. Default: OFF
35
36
  */
36
37
  export declare function resolveDebugMode(opts: {
@@ -17,7 +17,7 @@ export declare function runBuild(opts: {
17
17
  }>;
18
18
  /**
19
19
  * Walks `actionCommand` and its ancestors for a truthy `--bedrock`. --bedrock
20
- * is registered per-subcommand, so a
20
+ * is registered per-subcommand (not at program scope, unlike --debug), so a
21
21
  * root-level or subcommand-level setting can each carry it.
22
22
  */
23
23
  export declare function resolveBedrockFromAncestors(actionCommand: Command): boolean;
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-04d687d.0",
3
+ "version": "2.34.5-dev-build-c62cd6f.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-04d687d.0",
45
- "@contentful/experience-design-system-types": "2.34.5-dev-build-04d687d.0"
44
+ "@contentful/experience-design-system-types": "2.34.5-dev-build-c62cd6f.0",
45
+ "@contentful/experience-design-system-cli-v2": "2.34.5-dev-build-c62cd6f.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-generation": "2.34.5-dev-build-04d687d.0",
58
- "@contentful/experience-design-system-extraction": "2.34.5-dev-build-04d687d.0",
59
- "@contentful/experience-design-system-client": "2.34.5-dev-build-04d687d.0"
57
+ "@contentful/experience-design-system-client": "2.34.5-dev-build-c62cd6f.0",
58
+ "@contentful/experience-design-system-generation": "2.34.5-dev-build-c62cd6f.0",
59
+ "@contentful/experience-design-system-extraction": "2.34.5-dev-build-c62cd6f.0"
60
60
  },
61
61
  "repository": {
62
62
  "type": "git",
@@ -1,27 +0,0 @@
1
- /**
2
- * Resolution chain for the combined `--agent` override on `experiences import`.
3
- *
4
- * The wizard path previously hard-defaulted `--agent` to `'claude'` at the
5
- * commander layer, which (a) shadowed the stored `credentials.json` value when
6
- * the user passed no flag, and (b) made it impossible to distinguish "user
7
- * explicitly passed --agent claude" from "user passed nothing". The combined
8
- * flag accepts either `agent:model` or `agent model`.
9
- *
10
- * These helpers produce the resolved values to feed into `WizardApp` /
11
- * the import wizard:
12
- *
13
- * 1. CLI flag wins when provided.
14
- * 2. Otherwise, the value persisted in `credentials.json` (written by
15
- * `experiences setup`) is used.
16
- * 3. Otherwise, the built-in default (currently `'claude'`) is used for
17
- * the agent. Model has no default — agents pick a small/fast model
18
- * themselves when no model is included in `--agent`.
19
- */
20
- /** Built-in fallback agent when neither a flag nor a stored preference is set. */
21
- export declare const DEFAULT_AGENT = "claude";
22
- export declare function parseAgentModel(value: string | undefined): {
23
- agent?: string;
24
- model?: string;
25
- };
26
- export declare function resolveAgent(flagValue: string | undefined, storedValue: string | undefined): string;
27
- export declare function resolveModel(flagValue: string | undefined, storedValue: string | undefined): string | undefined;
@@ -1,8 +0,0 @@
1
- import { type AgentName } from '@contentful/experience-design-system-generation';
2
- export declare function runSelectionAgent(options: {
3
- sessionId: string;
4
- agent: AgentName;
5
- model?: string;
6
- promptText?: string;
7
- promptPath?: string;
8
- }): Promise<void>;