@contentful/experience-design-system-cli 2.35.0-alpha.0 → 2.35.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.
Files changed (85) hide show
  1. package/README.md +65 -83
  2. package/dist/package.json +2 -1
  3. package/dist/src/analyze/composition/interchange-schema.d.ts +4 -24
  4. package/dist/src/analyze/composition/resolve-mapping-cli.d.ts +2 -11
  5. package/dist/src/analyze/composition/resolve-mapping.d.ts +5 -7
  6. package/dist/src/analyze/extract-command.d.ts +4 -0
  7. package/dist/src/analyze/select/tui/components/FieldEditor.d.ts +3 -1
  8. package/dist/src/analyze/select/tui/components/FinalizeDialog.d.ts +2 -2
  9. package/dist/src/analyze/select/tui/components/GroupedSidebar.d.ts +3 -0
  10. package/dist/src/analyze/select/tui/components/HelpOverlay.d.ts +2 -0
  11. package/dist/src/analyze/select/tui/components/Sidebar.d.ts +2 -1
  12. package/dist/src/analyze/select/tui/hooks/scroll-offset.d.ts +4 -3
  13. package/dist/src/analyze/select/tui/hooks/useImmediateInput.d.ts +1 -1
  14. package/dist/src/credentials-store.d.ts +3 -23
  15. package/dist/src/doctor/checks.d.ts +5 -0
  16. package/dist/src/doctor/command.d.ts +2 -0
  17. package/dist/src/doctor/report.d.ts +7 -0
  18. package/dist/src/import/agent-model-resolve.d.ts +8 -4
  19. package/dist/src/import/composition-options.d.ts +0 -2
  20. package/dist/src/import/tui/WizardApp.d.ts +21 -4
  21. package/dist/src/import/tui/components/CompactControlBar.d.ts +4 -0
  22. package/dist/src/import/tui/components/ReviewStatus.d.ts +0 -5
  23. package/dist/src/import/tui/hooks/review-input.d.ts +1 -1
  24. package/dist/src/import/tui/lineage-layout.d.ts +18 -25
  25. package/dist/src/import/tui/run-selection-agent.d.ts +9 -0
  26. package/dist/src/import/tui/scope-gate-columns.d.ts +14 -8
  27. package/dist/src/import/tui/steps/CredentialsStep.d.ts +4 -1
  28. package/dist/src/import/tui/steps/GateStep.d.ts +1 -1
  29. package/dist/src/import/tui/steps/GenerateReviewStep.d.ts +14 -3
  30. package/dist/src/import/tui/steps/RunningStep.d.ts +12 -1
  31. package/dist/src/import/tui/steps/ScopeGateStep.d.ts +1 -1
  32. package/dist/src/import/tui/steps/WizardPreviewStep.d.ts +2 -2
  33. package/dist/src/import/tui/wizard-state-transitions.d.ts +5 -7
  34. package/dist/src/index.js +24979 -23985
  35. package/dist/src/lib/agent-definitions.d.ts +14 -0
  36. package/dist/src/lib/agent-model-options.d.ts +4 -4
  37. package/dist/src/lib/command-options.d.ts +0 -1
  38. package/dist/src/lib/debug-logger.d.ts +1 -9
  39. package/dist/src/lib/debug-preamble.d.ts +1 -8
  40. package/dist/src/program.d.ts +3 -3
  41. package/dist/src/runs/store.d.ts +0 -5
  42. package/dist/src/session/db.d.ts +32 -2
  43. package/dist/src/setup/SetupScreen.d.ts +28 -0
  44. package/dist/src/setup/SetupStepper.d.ts +7 -0
  45. package/dist/src/setup/command.d.ts +1 -7
  46. package/dist/src/setup/lib/checks.d.ts +57 -0
  47. package/dist/src/setup/lib/shell.d.ts +12 -0
  48. package/dist/src/setup/steps/CodingAgentScreen.d.ts +20 -0
  49. package/dist/src/setup/steps/ContentfulCredentialsScreen.d.ts +11 -0
  50. package/dist/src/setup/steps/StepLayout.d.ts +20 -0
  51. package/dist/src/setup/steps/preferences/AnalyticsScreen.d.ts +5 -0
  52. package/dist/src/setup/steps/preferences/BooleanInput.d.ts +21 -0
  53. package/dist/src/setup/steps/preferences/ColorPreferenceScreen.d.ts +5 -0
  54. package/dist/src/setup/steps/preferences/CustomPromptScreen.d.ts +14 -0
  55. package/dist/src/setup/steps/preferences/DebugLogsScreen.d.ts +5 -0
  56. package/dist/src/setup/steps/preferences/PreferencesMenu.d.ts +26 -0
  57. package/dist/src/setup/steps/prerequisites/PrerequisitesScreen.d.ts +16 -0
  58. package/dist/src/setup/steps/prerequisites/build.d.ts +2 -0
  59. package/dist/src/setup/steps/prerequisites/deps.d.ts +33 -0
  60. package/dist/src/setup/steps/prerequisites/index.d.ts +4 -0
  61. package/dist/src/setup/steps/prerequisites/node.d.ts +2 -0
  62. package/dist/src/setup/steps/prerequisites/pnpm.d.ts +2 -0
  63. package/dist/src/tui/render-with-goodbye.d.ts +7 -0
  64. package/dist/src/tui/use-terminal-size.d.ts +6 -0
  65. package/dist/src/tui/windowed-panel.d.ts +37 -0
  66. package/package.json +7 -6
  67. package/skills/generate-components.md +99 -65
  68. package/dist/src/analyze/select/tui/components/LineagePanel.d.ts +0 -14
  69. package/dist/src/import/strip-allowed-components.d.ts +0 -18
  70. package/dist/src/import/tui/final-review-host.d.ts +0 -8
  71. package/dist/src/import/tui/hooks/useLineage.d.ts +0 -32
  72. package/dist/src/import/tui/lineage-input.d.ts +0 -18
  73. package/dist/src/import/tui/push-decision-gate-helpers.d.ts +0 -8
  74. package/dist/src/import/tui/review-step-props.d.ts +0 -13
  75. package/dist/src/import/tui/scope-gate-host.d.ts +0 -21
  76. package/dist/src/import/tui/steps/AtomicGenerateReviewStep.d.ts +0 -28
  77. package/dist/src/import/tui/steps/AtomicScopeGateStep.d.ts +0 -3
  78. package/dist/src/import/tui/steps/PushDecisionGateStep.d.ts +0 -12
  79. package/dist/src/import/tui/steps/useTerminalColumns.d.ts +0 -1
  80. package/dist/src/lib/composition-mode.d.ts +0 -21
  81. package/dist/src/runs/save-conflict.d.ts +0 -8
  82. package/dist/src/setup/analytics-prompt.d.ts +0 -13
  83. package/dist/src/setup/composition-mode-prompt.d.ts +0 -14
  84. package/dist/src/setup/debug-mode-prompt.d.ts +0 -11
  85. package/dist/src/setup/prompt-helpers.d.ts +0 -1
@@ -0,0 +1,14 @@
1
+ import type { AgentName } from '@contentful/experience-design-system-generation';
2
+ export interface AgentDefinition {
3
+ name: string;
4
+ binary: AgentName;
5
+ /** The npm package that installs this agent, so callers never spell it out again. */
6
+ packageName: string;
7
+ installSuffix?: string;
8
+ /** Whether `experiences setup` offers to install it. Copilot is detect-only. */
9
+ installable: boolean;
10
+ }
11
+ export declare const AGENT_DEFS: readonly AgentDefinition[];
12
+ export declare function installCommand(agent: AgentDefinition): string;
13
+ export declare function installHint(agent: AgentDefinition): string;
14
+ export declare const INSTALLABLE_AGENTS: AgentDefinition[];
@@ -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;
7
8
  modelDescription?: string;
8
9
  }
9
10
  /**
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.
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.
14
14
  */
15
15
  export declare function addAgentModelOptions(cmd: Command, config?: AgentModelOptionsConfig): Command;
@@ -1,4 +1,3 @@
1
1
  import type { Command } from 'commander';
2
2
  export declare function addArtifactInputOptions(cmd: Command): Command;
3
3
  export declare function addContentfulTargetOptions(cmd: Command): Command;
4
- export declare function addCompositionOptions(cmd: Command): Command;
@@ -25,15 +25,7 @@ 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. `--debug` / `--no-debug` CLI flag
33
- * 2. `EDSI_DEBUG` env var (truthy: 1, true, yes, on)
34
- * 3. Persisted `debug` field in credentials.json
35
- * 4. Default: OFF
36
- */
28
+ /** Resolve debug mode from an explicit option, environment, or saved settings. */
37
29
  export declare function resolveDebugMode(opts: {
38
30
  debug?: boolean;
39
31
  }, configDebug?: boolean): boolean;
@@ -1,13 +1,6 @@
1
1
  import { type DebugLogger } from './debug-logger.js';
2
2
  /**
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.
3
+ * Resolve and initialize the debug logger before a top-level command runs.
11
4
  */
12
5
  export declare function beginCommand(command: string, opts: {
13
6
  debug?: boolean;
@@ -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`. --bedrock
20
- * is registered per-subcommand (not at program scope, unlike --debug), so a
21
- * root-level or subcommand-level setting can each carry it.
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.
22
22
  */
23
23
  export declare function resolveBedrockFromAncestors(actionCommand: Command): boolean;
24
24
  export declare function createProgram(): Command;
@@ -1,4 +1,3 @@
1
- import type { CompositionMode } from '../lib/composition-mode.js';
2
1
  export declare const RUNS_FILE_VERSION: 3;
3
2
  /** Versions this CLI can read. v1 / v2 files are auto-migrated in memory;
4
3
  * new writes always use the latest version. */
@@ -45,10 +44,6 @@ export type RunRecord = {
45
44
  * satisfy `RunRecord`; `appendRun` always normalizes a missing value to
46
45
  * null on the way to disk. */
47
46
  sourceFingerprint?: SourceFingerprint | null;
48
- /** Composition mode the run was produced in, so replay resumes in the
49
- * same mode (`composite` vs `atomic`). Absent on records written before this
50
- * field existed; callers treat a missing value as `atomic` (the default). */
51
- compositionMode?: CompositionMode;
52
47
  notes?: string;
53
48
  };
54
49
  export type RunsFile = {
@@ -22,6 +22,10 @@ export interface ApplyToolCallsResult {
22
22
  slots: number;
23
23
  warnings: string[];
24
24
  }
25
+ export interface ApplyToolCallsOptions {
26
+ /** Component names that may appear in generated slot allowed-components lists. */
27
+ allowedComponentNames?: ReadonlySet<string>;
28
+ }
25
29
  export interface ComponentReviewMetadata {
26
30
  sourcePath: string | null;
27
31
  componentSource: string | null;
@@ -51,7 +55,7 @@ export interface ComponentRationale {
51
55
  }>;
52
56
  }
53
57
  export declare function loadComponentRationale(db: DatabaseSync, sessionId: string, componentName: string): ComponentRationale | null;
54
- export declare function applyToolCalls(db: DatabaseSync, sessionId: string, componentId: string, componentName: string, calls: ToolCall[], incomingWarnings: string[]): ApplyToolCallsResult;
58
+ export declare function applyToolCalls(db: DatabaseSync, sessionId: string, componentId: string, componentName: string, calls: ToolCall[], incomingWarnings: string[], options?: ApplyToolCallsOptions): ApplyToolCallsResult;
55
59
  export type MatchHints = SessionMatchHints;
56
60
  export type { SessionResolution };
57
61
  export declare function getOrCreateSession(db: DatabaseSync, sessionFlag: string | undefined, sessionName: string | undefined, hints: MatchHints): SessionResolution;
@@ -60,6 +64,7 @@ export declare function updateStep(db: DatabaseSync, stepId: number, status: 'co
60
64
  export declare function storeRawComponents(db: DatabaseSync, sessionId: string, components: RawComponentDefinition[], options?: {
61
65
  status?: string;
62
66
  preserveCDF?: boolean;
67
+ preserveStatus?: boolean;
63
68
  }): void;
64
69
  export type RawComponentWithId = RawComponentDefinition & {
65
70
  component_id: string;
@@ -121,6 +126,14 @@ export declare function computeMapTokensInputHash(db: DatabaseSync, sessionId: s
121
126
  export declare function lookupCache(db: DatabaseSync, inputHash: string, entityType: CacheEntityType, entityId: string, promptHash?: string): CacheEntry | null;
122
127
  export declare function lookupCacheByEntity(db: DatabaseSync, entityType: CacheEntityType, entityId: string): CacheEntry | null;
123
128
  export declare function storeCache(db: DatabaseSync, inputHash: string, entityType: CacheEntityType, entityId: string, sourceSessionId: string, humanEdited: boolean, promptHash?: string): void;
129
+ export declare function storeCaches(db: DatabaseSync, entries: Array<{
130
+ inputHash: string;
131
+ entityType: CacheEntityType;
132
+ entityId: string;
133
+ sourceSessionId: string;
134
+ humanEdited: boolean;
135
+ promptHash?: string;
136
+ }>): void;
124
137
  export declare function storeScannedFiles(db: DatabaseSync, sessionId: string, filePaths: string[]): void;
125
138
  export declare function loadScannedFiles(db: DatabaseSync, sessionId: string): string[];
126
139
  export declare function storeSlotCycles(db: DatabaseSync, sessionId: string, cycles: Array<SlotCycle & {
@@ -132,7 +145,24 @@ export interface StoredSlotCycle extends SlotCycle {
132
145
  export declare function loadSlotCycles(db: DatabaseSync, sessionId: string): StoredSlotCycle[];
133
146
  export declare function clearSlotCycles(db: DatabaseSync, sessionId: string): void;
134
147
  export declare function markCacheHumanEdited(db: DatabaseSync, entityType: 'component' | 'token_set', entityId: string): void;
135
- export declare function copyComponentFromCache(db: DatabaseSync, sourceSessionId: string, targetSessionId: string, componentId: string): void;
148
+ export interface UnknownSlotAllowedComponent {
149
+ componentId: string;
150
+ componentName: string;
151
+ slotName: string;
152
+ allowedComponent: string;
153
+ }
154
+ export declare function findUnknownSlotAllowedComponents(db: DatabaseSync, sessionId: string, allowedComponentNames: ReadonlySet<string>, componentId?: string): UnknownSlotAllowedComponent[];
155
+ /** Remove slot references that cannot resolve in the current manifest or target space. */
156
+ export declare function filterUnknownSlotAllowedComponents(db: DatabaseSync, sessionId: string, allowedComponentNames: ReadonlySet<string>): UnknownSlotAllowedComponent[];
157
+ export interface CopyComponentFromCacheOptions {
158
+ allowedComponentNames?: ReadonlySet<string>;
159
+ }
160
+ export declare function copyComponentFromCache(db: DatabaseSync, sourceSessionId: string, targetSessionId: string, componentId: string, manageTransaction?: boolean, options?: CopyComponentFromCacheOptions): void;
161
+ export declare function copyComponentsFromCache(db: DatabaseSync, entries: Array<{
162
+ sourceSessionId: string;
163
+ targetSessionId: string;
164
+ componentId: string;
165
+ }>, options?: CopyComponentFromCacheOptions): void;
136
166
  export declare function copyTokensFromCache(db: DatabaseSync, sourceSessionId: string, targetSessionId: string): void;
137
167
  export declare function copyMapTokensFromCache(db: DatabaseSync, sourceSessionId: string, targetSessionId: string): number;
138
168
  export declare function getCliCacheVersion(): Promise<string>;
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ export type SetupResultEntry = {
3
+ name: string;
4
+ status: 'completed' | 'skipped' | 'failed';
5
+ required: boolean;
6
+ };
7
+ export declare function formatSetupCompletionMessage(results: readonly SetupResultEntry[]): string;
8
+ /** Prompts and output are UI-owned; the screen supplies the rest itself. */
9
+ export type SetupSkipFlags = {
10
+ skipBuild?: boolean;
11
+ skipAgent?: boolean;
12
+ skipCredentials?: boolean;
13
+ skipOptional?: boolean;
14
+ };
15
+ export type SetupOutcome = {
16
+ results: SetupResultEntry[];
17
+ exitCode: number;
18
+ };
19
+ type SetupScreenProps = {
20
+ version: string;
21
+ repoRoot: string;
22
+ skip?: SetupSkipFlags;
23
+ /** Defaults to the live Ink stdout columns. */
24
+ columns?: number;
25
+ onComplete: (outcome: SetupOutcome) => void;
26
+ };
27
+ export declare function SetupScreen({ version, repoRoot, skip, columns: columnsOverride, onComplete, }: SetupScreenProps): React.ReactElement;
28
+ export {};
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ type SetupStepperProps = {
3
+ activeStep: number;
4
+ columns?: number;
5
+ };
6
+ export declare function SetupStepper({ activeStep, columns }: SetupStepperProps): React.ReactElement;
7
+ export {};
@@ -1,9 +1,3 @@
1
1
  import type { Command } from 'commander';
2
- export declare function promptCodexModel(ask?: (q: string) => Promise<string>): Promise<string | undefined>;
3
- /**
4
- * Prompt the operator for a custom skill prompt path. Returns the resolved
5
- * trimmed value, or `undefined` to leave the current value unchanged, or `null`
6
- * to clear it. `ask` is injectable so tests can stub stdin.
7
- */
8
- export declare function promptCustomSkillPath(current: string | undefined, ask?: (q: string) => Promise<string>): Promise<string | undefined | null>;
2
+ export declare const SETUP_REQUIRES_TTY_MESSAGE = "Error: experiences setup requires an interactive terminal.";
9
3
  export declare function registerSetupCommand(program: Command): void;
@@ -0,0 +1,57 @@
1
+ import { binaryExists, pathExists, runSpawn, type ShellCommandResult } from './shell.js';
2
+ /**
3
+ * The decision half of each prerequisite check, shared by `experiences doctor`
4
+ * and the setup wizard's Prerequisites step. Neither writes output from here:
5
+ * doctor streams ANSI, setup emits events for Ink, and both need the same
6
+ * verdict. Anything a caller needs for its own wording is returned rather than
7
+ * printed.
8
+ */
9
+ export interface NodeVersionCheck {
10
+ passed: boolean;
11
+ version: string;
12
+ major: number;
13
+ required: number;
14
+ }
15
+ export declare function checkNodeVersion(nodeVersion?: string): NodeVersionCheck;
16
+ /** Which Node version manager is available, so callers can offer the right fix. */
17
+ export interface NodeVersionManagers {
18
+ nvm: boolean;
19
+ fnm: boolean;
20
+ nvmScript: string;
21
+ }
22
+ export declare function detectNodeVersionManagers(homeDir: string, deps?: {
23
+ binaryExists: typeof binaryExists;
24
+ pathExists: typeof pathExists;
25
+ }): Promise<NodeVersionManagers>;
26
+ export type PnpmCheck = {
27
+ status: 'missing';
28
+ } | {
29
+ status: 'broken';
30
+ } | {
31
+ status: 'unusable-in-repo';
32
+ version: string;
33
+ } | {
34
+ status: 'ok';
35
+ version: string;
36
+ };
37
+ type PnpmDeps = {
38
+ binaryExists: typeof binaryExists;
39
+ run: typeof runSpawn;
40
+ };
41
+ /**
42
+ * `detectPnpm` plus proof that pnpm can execute inside the repo. A store built
43
+ * against a different Node version still passes `--version` but fails there,
44
+ * which is the failure operators actually hit — so both doctor and setup check it.
45
+ */
46
+ export declare function checkPnpm(pkgRoot: string, deps?: PnpmDeps): Promise<PnpmCheck>;
47
+ export interface CommandCheck {
48
+ passed: boolean;
49
+ result: ShellCommandResult;
50
+ }
51
+ export declare function installDependencies(repoRoot: string, deps?: {
52
+ run: typeof runSpawn;
53
+ }): Promise<CommandCheck>;
54
+ export declare function buildCli(repoRoot: string, deps?: {
55
+ run: typeof runSpawn;
56
+ }): Promise<CommandCheck>;
57
+ export {};
@@ -0,0 +1,12 @@
1
+ export declare const REQUIRED_NODE_MAJOR = 24;
2
+ export interface ShellCommandResult {
3
+ exitCode: number;
4
+ stdout: string;
5
+ stderr: string;
6
+ }
7
+ export declare function binaryExists(name: string): Promise<boolean>;
8
+ export declare function pathExists(path: string): Promise<boolean>;
9
+ export declare function runSpawn(cmd: string, args: string[], opts?: {
10
+ cwd?: string;
11
+ env?: NodeJS.ProcessEnv;
12
+ }): Promise<ShellCommandResult>;
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import type { AgentName } from '@contentful/experience-design-system-generation';
3
+ import { type AgentDefinition } from '../../lib/agent-definitions.js';
4
+ import { binaryExists, runSpawn } from '../lib/shell.js';
5
+ import { type StepDone } from './StepLayout.js';
6
+ export declare function detectAgents(exists?: (binary: string) => Promise<boolean>): Promise<AgentDefinition[]>;
7
+ /** Codex needs a model only when it authenticates through a ChatGPT account. */
8
+ export declare function needsCodexModel(agent: AgentName, env: NodeJS.ProcessEnv): boolean;
9
+ export type CodingAgentDeps = {
10
+ binaryExists: typeof binaryExists;
11
+ run: typeof runSpawn;
12
+ env: NodeJS.ProcessEnv;
13
+ };
14
+ type CodingAgentScreenProps = {
15
+ onDone: StepDone;
16
+ /** Injected so tests can drive detection and install without spawning. */
17
+ deps?: CodingAgentDeps;
18
+ };
19
+ export declare function CodingAgentScreen({ onDone, deps }: CodingAgentScreenProps): React.ReactElement;
20
+ export {};
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { type StepDone } from './StepLayout.js';
3
+ /**
4
+ * Env vars still act as a fallback when a field on disk is empty, so an operator
5
+ * who skips this step should know an ambient value would take effect.
6
+ */
7
+ export declare function envShadowingWarning(env: NodeJS.ProcessEnv): string | null;
8
+ export declare function maskToken(token: string): string;
9
+ export declare function ContentfulCredentialsScreen({ onDone }: {
10
+ onDone: StepDone;
11
+ }): React.ReactElement;
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ export type StepStatus = 'completed' | 'skipped' | 'failed';
3
+ export type StepDone = (status: StepStatus) => void;
4
+ type StepLayoutProps = {
5
+ helpText?: string;
6
+ children?: React.ReactNode;
7
+ prompt?: React.ReactNode;
8
+ };
9
+ export declare function StepLayout({ helpText, children, prompt }: StepLayoutProps): React.ReactElement;
10
+ export declare function StepSuccess({ children }: {
11
+ children: React.ReactNode;
12
+ }): React.ReactElement;
13
+ export declare function StepWarning({ children }: {
14
+ children: React.ReactNode;
15
+ }): React.ReactElement;
16
+ export declare function StepValue({ label, value }: {
17
+ label: string;
18
+ value: string | undefined;
19
+ }): React.ReactElement;
20
+ export {};
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import type { StepDone } from '../StepLayout.js';
3
+ export declare function AnalyticsScreen({ onDone }: {
4
+ onDone: StepDone;
5
+ }): React.ReactElement;
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import { type ExperiencesCredentials } from '../../../credentials-store.js';
3
+ import { type StepDone } from '../StepLayout.js';
4
+ type BooleanPreferenceProps = {
5
+ helpText: string;
6
+ question: string;
7
+ /** What choosing each option means, named after the outcome rather than yes/no. */
8
+ labels: {
9
+ on: string;
10
+ off: string;
11
+ };
12
+ /** Reads the stored value; `undefined` means the operator has never set it. */
13
+ read: (credentials: ExperiencesCredentials) => boolean | undefined;
14
+ /** Applied to the stored credentials when the answer differs from the default. */
15
+ write: (credentials: ExperiencesCredentials, value: boolean) => ExperiencesCredentials;
16
+ /** What the setting means when it has never been set. */
17
+ fallback: boolean;
18
+ onDone: StepDone;
19
+ };
20
+ export declare function BooleanInput({ helpText, question, labels, read, write, fallback, onDone, }: BooleanPreferenceProps): React.ReactElement;
21
+ export {};
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import type { StepDone } from '../StepLayout.js';
3
+ export declare function ColorPreferenceScreen({ onDone }: {
4
+ onDone: StepDone;
5
+ }): React.ReactElement;
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import { type ExperiencesCredentials } from '../../../credentials-store.js';
3
+ import { type StepDone } from '../StepLayout.js';
4
+ /**
5
+ * Interpret an answer to a custom prompt path question: empty keeps whatever is
6
+ * stored, `-` clears it, anything else is the new path.
7
+ */
8
+ export declare function parseCustomSkillPath(answer: string): string | undefined | null;
9
+ export declare function customSkillPathQuestion(current: string | undefined): string;
10
+ /** Apply a parsed answer to the credentials, clearing the field on `null`. */
11
+ export declare function applyCustomSkillPath(credentials: ExperiencesCredentials, parsed: string | undefined | null): ExperiencesCredentials;
12
+ export declare function CustomPromptsScreen({ onDone }: {
13
+ onDone: StepDone;
14
+ }): React.ReactElement;
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import type { StepDone } from '../StepLayout.js';
3
+ export declare function DebugLogsScreen({ onDone }: {
4
+ onDone: StepDone;
5
+ }): React.ReactElement;
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ import { type StepDone } from '../StepLayout.js';
3
+ type PreferenceScreenProps = {
4
+ onDone: StepDone;
5
+ };
6
+ export declare const PREFERENCE_OPTIONS: readonly [{
7
+ readonly key: "customPrompts";
8
+ readonly label: "Custom prompts";
9
+ readonly Screen: ({ onDone }: PreferenceScreenProps) => import("react/jsx-runtime").JSX.Element;
10
+ }, {
11
+ readonly key: "debug";
12
+ readonly label: "Debug logging";
13
+ readonly Screen: ({ onDone }: PreferenceScreenProps) => import("react/jsx-runtime").JSX.Element;
14
+ }, {
15
+ readonly key: "analytics";
16
+ readonly label: "Usage analytics";
17
+ readonly Screen: ({ onDone }: PreferenceScreenProps) => import("react/jsx-runtime").JSX.Element;
18
+ }, {
19
+ readonly key: "noColor";
20
+ readonly label: "Terminal colors";
21
+ readonly Screen: ({ onDone }: PreferenceScreenProps) => import("react/jsx-runtime").JSX.Element;
22
+ }];
23
+ export declare function PreferencesMenu({ onDone }: {
24
+ onDone: StepDone;
25
+ }): React.ReactElement;
26
+ export {};
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import type { PrerequisiteDeps, PrerequisitesOutcome } from './deps.js';
3
+ export type PrerequisitesScreenProps = {
4
+ repoRoot: string;
5
+ skipBuild?: boolean;
6
+ onDone: (outcome: PrerequisitesOutcome) => void;
7
+ /** Injected so tests can drive the checks without spawning processes. */
8
+ deps?: Pick<PrerequisiteDeps, 'nodeVersion' | 'homeDir' | 'binaryExists' | 'pathExists' | 'run'>;
9
+ };
10
+ /**
11
+ * Prerequisites runs as soon as the wizard opens and reports each check as it
12
+ * finishes. It keeps a driver rather than a per-question screen because the flow
13
+ * is sequential — a failed check may offer an install, and the next check depends
14
+ * on that answer.
15
+ */
16
+ export declare function PrerequisitesScreen({ repoRoot, skipBuild, onDone, deps, }: PrerequisitesScreenProps): React.ReactElement;
@@ -0,0 +1,2 @@
1
+ import { type PrerequisiteDeps, type PrerequisiteResult } from './deps.js';
2
+ export declare function runBuildSetup(dependencies: PrerequisiteDeps, repoRoot: string): Promise<PrerequisiteResult>;
@@ -0,0 +1,33 @@
1
+ import type { binaryExists, pathExists, runSpawn } from '../../lib/shell.js';
2
+ export type PrerequisiteEventKind = 'success' | 'failure' | 'warning' | 'info';
3
+ export interface PrerequisiteEvent {
4
+ kind: PrerequisiteEventKind;
5
+ message: string;
6
+ }
7
+ /**
8
+ * What the prerequisite checks need from the outside world.
9
+ *
10
+ * Unlike the other steps, this one is a sequential process rather than a form —
11
+ * it checks Node, may offer to install a version manager, checks pnpm, may offer
12
+ * corepack or npm, then installs and builds. Those mid-flow confirmations mean it
13
+ * keeps an imperative shape, so it takes `confirm` and `emit` rather than
14
+ * rendering each question itself.
15
+ */
16
+ export interface PrerequisiteDeps {
17
+ nodeVersion: string;
18
+ homeDir: string;
19
+ binaryExists: typeof binaryExists;
20
+ pathExists: typeof pathExists;
21
+ run: typeof runSpawn;
22
+ confirm(question: string, defaultYes?: boolean): Promise<boolean>;
23
+ emit(event: PrerequisiteEvent): void;
24
+ }
25
+ export interface PrerequisiteResult {
26
+ passed: boolean;
27
+ }
28
+ export interface PrerequisitesOutcome {
29
+ node: PrerequisiteResult;
30
+ pnpm?: PrerequisiteResult;
31
+ build?: PrerequisiteResult;
32
+ }
33
+ export declare function emit(deps: PrerequisiteDeps, kind: PrerequisiteEventKind, message: string): void;
@@ -0,0 +1,4 @@
1
+ import type { PrerequisiteDeps, PrerequisitesOutcome } from './deps.js';
2
+ export declare function runPrerequisitesSetup(dependencies: PrerequisiteDeps, repoRoot: string, options?: {
3
+ skipBuild?: boolean;
4
+ }): Promise<PrerequisitesOutcome>;
@@ -0,0 +1,2 @@
1
+ import { type PrerequisiteDeps, type PrerequisiteResult } from './deps.js';
2
+ export declare function runNodeSetup(dependencies: PrerequisiteDeps): Promise<PrerequisiteResult>;
@@ -0,0 +1,2 @@
1
+ import { type PrerequisiteDeps, type PrerequisiteResult } from './deps.js';
2
+ export declare function runPnpmSetup(dependencies: PrerequisiteDeps, repoRoot: string): Promise<PrerequisiteResult>;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { type Instance, type RenderOptions } from 'ink';
3
+ export declare function useScreenTransitionClear(): () => void;
4
+ export declare function GoodbyeBoundary({ children }: {
5
+ children: React.ReactNode;
6
+ }): React.ReactElement;
7
+ export declare function renderWithGoodbye(element: React.ReactElement, options?: RenderOptions): Instance;
@@ -0,0 +1,6 @@
1
+ export type TerminalSize = {
2
+ columns: number;
3
+ rows: number;
4
+ };
5
+ /** Keep layout consumers synchronized with terminal resize events. */
6
+ export declare function useTerminalSize(): TerminalSize;
@@ -0,0 +1,37 @@
1
+ import { type BoxProps } from 'ink';
2
+ import type { ReactElement, ReactNode } from 'react';
3
+ export type WindowDirection = 'up' | 'down';
4
+ /** Size a standalone panel to the terminal while reserving a small safety margin. */
5
+ export declare function terminalPanelHeight(rows: number, reservedRows?: number): number;
6
+ export interface WindowedPanelProps {
7
+ width: number;
8
+ height?: number;
9
+ title?: string;
10
+ focused: boolean;
11
+ children: ReactNode;
12
+ }
13
+ export interface FixedPanelProps {
14
+ width: number;
15
+ height?: number;
16
+ minHeight?: BoxProps['minHeight'];
17
+ focused?: boolean;
18
+ borderStyle?: BoxProps['borderStyle'];
19
+ borderColor?: BoxProps['borderColor'];
20
+ paddingLeft?: BoxProps['paddingLeft'];
21
+ clipOverflow?: boolean;
22
+ children: ReactNode;
23
+ }
24
+ /** Shared panel frame that clips content instead of resizing its layout slot. */
25
+ export declare function FixedPanel({ width, height, minHeight, focused, borderStyle, borderColor, paddingLeft, clipOverflow, children, }: FixedPanelProps): ReactElement;
26
+ /** Shared frame for panels whose viewport must not change with their contents. */
27
+ export declare function WindowedPanel({ width, height, title, focused, children }: WindowedPanelProps): ReactElement;
28
+ export declare function WindowedPanelHeader({ title, width, focused, }: {
29
+ title: string;
30
+ width: number;
31
+ focused: boolean;
32
+ }): ReactElement;
33
+ export declare function formatWindowIndicator(direction: WindowDirection, count: number): string;
34
+ export declare function WindowIndicator({ direction, count }: {
35
+ direction: WindowDirection;
36
+ count: number;
37
+ }): ReactElement;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.35.0-alpha.0",
3
+ "version": "2.35.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -29,6 +29,7 @@
29
29
  "skills/"
30
30
  ],
31
31
  "dependencies": {
32
+ "@inkjs/ui": "^2.0.0",
32
33
  "@segment/analytics-node": "^3.0.0",
33
34
  "@vue/compiler-sfc": "^3.5.31",
34
35
  "commander": "^13.1.0",
@@ -40,8 +41,8 @@
40
41
  "svelte": "^5.56.4",
41
42
  "ts-morph": "^27.0.2",
42
43
  "typescript": "^5.9.3",
43
- "@contentful/experience-design-system-types": "2.35.0-alpha.0",
44
- "@contentful/experience-design-system-cli-v2": "2.35.0-alpha.0"
44
+ "@contentful/experience-design-system-cli-v2": "2.35.0",
45
+ "@contentful/experience-design-system-types": "2.35.0"
45
46
  },
46
47
  "devDependencies": {
47
48
  "@tsconfig/node24": "^24.0.4",
@@ -53,9 +54,9 @@
53
54
  "ink-testing-library": "^4.0.0",
54
55
  "typescript-eslint": "^8.67.0",
55
56
  "vitest": "^4.0.16",
56
- "@contentful/experience-design-system-extraction": "2.35.0-alpha.0",
57
- "@contentful/experience-design-system-client": "2.35.0-alpha.0",
58
- "@contentful/experience-design-system-generation": "2.35.0-alpha.0"
57
+ "@contentful/experience-design-system-client": "2.35.0",
58
+ "@contentful/experience-design-system-generation": "2.35.0",
59
+ "@contentful/experience-design-system-extraction": "2.35.0"
59
60
  },
60
61
  "repository": {
61
62
  "type": "git",