@contentful/experience-design-system-cli 2.42.1-dev-build-99dae8de.0 → 2.42.1-dev-build-8fa38033.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/app.js CHANGED
@@ -3054,6 +3054,13 @@ import { Box as Box8, Text as Text8 } from "ink";
3054
3054
  import { ProgressBar, Spinner, ThemeProvider } from "@inkjs/ui";
3055
3055
 
3056
3056
  // packages/experience-design-system-cli/src/tui/import/shared/running-step/logic.ts
3057
+ function lineState(line) {
3058
+ if (line.state) return line.state;
3059
+ return line.complete ? "done" : "running";
3060
+ }
3061
+ function formatDuration(ms) {
3062
+ return ms < 1e3 ? "<1s" : formatElapsed(Math.round(ms / 1e3));
3063
+ }
3057
3064
  function progressPercent(progress) {
3058
3065
  if (progress.total <= 0) return 0;
3059
3066
  return Math.min(100, Math.max(0, Math.round(progress.done / progress.total * 100)));
@@ -3089,6 +3096,8 @@ function useElapsed() {
3089
3096
 
3090
3097
  // packages/experience-design-system-cli/src/tui/import/shared/running-step/running-step.tsx
3091
3098
  import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
3099
+ var STATE_ICON = { done: "\u2713", warning: "!", failed: "\u2717" };
3100
+ var STATE_COLOR = { done: PALETTE.success, warning: PALETTE.warning, failed: PALETTE.error };
3092
3101
  function Line({ line }) {
3093
3102
  if (line.progress) {
3094
3103
  return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", gap: 1, children: [
@@ -3103,9 +3112,11 @@ function Line({ line }) {
3103
3112
  /* @__PURE__ */ jsx8(Text8, { color: PALETTE.muted, children: line.text })
3104
3113
  ] });
3105
3114
  }
3115
+ const state2 = lineState(line);
3106
3116
  return /* @__PURE__ */ jsxs8(Box8, { gap: 1, children: [
3107
- line.complete ? /* @__PURE__ */ jsx8(Text8, { color: PALETTE.success, children: "\u2713" }) : /* @__PURE__ */ jsx8(Spinner, {}),
3108
- /* @__PURE__ */ jsx8(Text8, { color: PALETTE.muted, children: line.text })
3117
+ state2 === "running" ? /* @__PURE__ */ jsx8(Spinner, {}) : /* @__PURE__ */ jsx8(Text8, { color: STATE_COLOR[state2], children: STATE_ICON[state2] }),
3118
+ /* @__PURE__ */ jsx8(Text8, { color: state2 === "warning" || state2 === "failed" ? STATE_COLOR[state2] : PALETTE.muted, children: line.text }),
3119
+ line.ms !== void 0 && /* @__PURE__ */ jsx8(Text8, { color: PALETTE.muted, children: formatDuration(line.ms) })
3109
3120
  ] });
3110
3121
  }
3111
3122
  function RunningStep({
@@ -18751,7 +18762,7 @@ function plural(count, noun) {
18751
18762
  function compositionDone(progress) {
18752
18763
  return progress.composition === "done" || progress.composition === "cache-hit";
18753
18764
  }
18754
- function progressRows(progress, agent) {
18765
+ function progressRows(progress, agent, rowMs = []) {
18755
18766
  const { scan, composition, selection, existingEntities, tokens } = progress;
18756
18767
  const scanned = scan?.scanned ?? 0;
18757
18768
  const scanComplete = (scan?.total ?? 0) > 0;
@@ -18772,16 +18783,23 @@ function progressRows(progress, agent) {
18772
18783
  if (existingEntities !== "idle") {
18773
18784
  rows.push({
18774
18785
  text: existingEntities === "running" ? "Fetching existing components and tokens..." : existingEntities === "complete" ? "Existing components and tokens ready" : "Existing entities unavailable; continuing without them",
18775
- complete: existingEntities !== "running"
18786
+ complete: existingEntities !== "running",
18787
+ // The import carries on without them, so this is not shown as a success.
18788
+ ...existingEntities === "failed" ? { state: "warning" } : {}
18776
18789
  });
18777
18790
  }
18778
18791
  if (tokens !== "idle") {
18779
18792
  rows.push({
18780
18793
  text: tokens === "complete" ? "Token definitions ready" : tokens === "failed" ? "Token definition generation failed" : `Generating token definitions via ${agent}...`,
18781
- complete: tokens === "complete"
18794
+ complete: tokens === "complete",
18795
+ // A failed job is not still running.
18796
+ ...tokens === "failed" ? { state: "failed" } : {}
18782
18797
  });
18783
18798
  }
18784
- return rows;
18799
+ return rows.map((row, index) => rowMs[index] === void 0 ? row : { ...row, ms: rowMs[index] });
18800
+ }
18801
+ function trackFinished(previous, rows, elapsedMs) {
18802
+ return rows.map((row, index) => previous[index] ?? (lineState(row) === "running" ? void 0 : elapsedMs));
18785
18803
  }
18786
18804
  function noComponentsMessage(projectPath) {
18787
18805
  return `No components found in ${projectPath}.
@@ -18810,13 +18828,13 @@ function resolveAgentChoice(flag, stored) {
18810
18828
 
18811
18829
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/screen.tsx
18812
18830
  import { jsx as jsx16 } from "react/jsx-runtime";
18813
- function ExtractionScreen({ progress, agent }) {
18831
+ function ExtractionScreen({ progress, agent, rowMs }) {
18814
18832
  return /* @__PURE__ */ jsx16(
18815
18833
  RunningStep,
18816
18834
  {
18817
18835
  step: "extraction",
18818
18836
  description: "Extracting context from your source files.",
18819
- lines: progressRows(progress, agent)
18837
+ lines: progressRows(progress, agent, rowMs)
18820
18838
  }
18821
18839
  );
18822
18840
  }
@@ -19245,9 +19263,12 @@ function useExtraction(input) {
19245
19263
  progress: initialProgress({
19246
19264
  hasCredentials: input.credentials !== null,
19247
19265
  hasRawTokens: input.rawTokensPath !== ""
19248
- })
19266
+ }),
19267
+ rowMs: []
19249
19268
  });
19250
19269
  let lastProgress;
19270
+ const startedAt = Date.now();
19271
+ let rowMs = [];
19251
19272
  startDebugRun({
19252
19273
  flow: "import/extraction",
19253
19274
  step: "06-extraction",
@@ -19256,7 +19277,8 @@ function useExtraction(input) {
19256
19277
  });
19257
19278
  void runExtraction(input, (progress) => {
19258
19279
  lastProgress = progress;
19259
- if (current.current === input) setState({ status: "running", progress });
19280
+ rowMs = trackFinished(rowMs, progressRows(progress, input.agent), Date.now() - startedAt);
19281
+ if (current.current === input) setState({ status: "running", progress, rowMs });
19260
19282
  }).then((result) => {
19261
19283
  if (current.current !== input) return;
19262
19284
  void finishDebugRun({
@@ -31833,7 +31855,14 @@ function App({ importOptions, inkClear }) {
31833
31855
  return /* @__PURE__ */ jsx66(ErrorStep, { stepName: extraction.result.step, message: extraction.result.message, onExit: leaveImport });
31834
31856
  }
31835
31857
  if (extraction?.status === "running") {
31836
- return /* @__PURE__ */ jsx66(ExtractionScreen, { progress: extraction.progress, agent: extractionRun.input.agent });
31858
+ return /* @__PURE__ */ jsx66(
31859
+ ExtractionScreen,
31860
+ {
31861
+ progress: extraction.progress,
31862
+ agent: extractionRun.input.agent,
31863
+ rowMs: extraction.rowMs
31864
+ }
31865
+ );
31837
31866
  }
31838
31867
  return /* @__PURE__ */ jsx66(Fragment22, {});
31839
31868
  }
package/dist/index.js CHANGED
@@ -20138,6 +20138,13 @@ var init_overview_box = __esm({
20138
20138
  });
20139
20139
 
20140
20140
  // packages/experience-design-system-cli/src/tui/import/shared/running-step/logic.ts
20141
+ function lineState(line) {
20142
+ if (line.state) return line.state;
20143
+ return line.complete ? "done" : "running";
20144
+ }
20145
+ function formatDuration(ms) {
20146
+ return ms < 1e3 ? "<1s" : formatElapsed(Math.round(ms / 1e3));
20147
+ }
20141
20148
  function progressPercent(progress) {
20142
20149
  if (progress.total <= 0) return 0;
20143
20150
  return Math.min(100, Math.max(0, Math.round(progress.done / progress.total * 100)));
@@ -20207,9 +20214,11 @@ function Line({ line }) {
20207
20214
  /* @__PURE__ */ jsx8(Text8, { color: PALETTE.muted, children: line.text })
20208
20215
  ] });
20209
20216
  }
20217
+ const state2 = lineState(line);
20210
20218
  return /* @__PURE__ */ jsxs8(Box8, { gap: 1, children: [
20211
- line.complete ? /* @__PURE__ */ jsx8(Text8, { color: PALETTE.success, children: "\u2713" }) : /* @__PURE__ */ jsx8(Spinner, {}),
20212
- /* @__PURE__ */ jsx8(Text8, { color: PALETTE.muted, children: line.text })
20219
+ state2 === "running" ? /* @__PURE__ */ jsx8(Spinner, {}) : /* @__PURE__ */ jsx8(Text8, { color: STATE_COLOR[state2], children: STATE_ICON[state2] }),
20220
+ /* @__PURE__ */ jsx8(Text8, { color: state2 === "warning" || state2 === "failed" ? STATE_COLOR[state2] : PALETTE.muted, children: line.text }),
20221
+ line.ms !== void 0 && /* @__PURE__ */ jsx8(Text8, { color: PALETTE.muted, children: formatDuration(line.ms) })
20213
20222
  ] });
20214
20223
  }
20215
20224
  function RunningStep({
@@ -20230,6 +20239,7 @@ function RunningStep({
20230
20239
  ] })
20231
20240
  ] });
20232
20241
  }
20242
+ var STATE_ICON, STATE_COLOR;
20233
20243
  var init_running_step = __esm({
20234
20244
  "packages/experience-design-system-cli/src/tui/import/shared/running-step/running-step.tsx"() {
20235
20245
  "use strict";
@@ -20238,6 +20248,8 @@ var init_running_step = __esm({
20238
20248
  init_theme2();
20239
20249
  init_StepHeader();
20240
20250
  init_use_elapsed();
20251
+ STATE_ICON = { done: "\u2713", warning: "!", failed: "\u2717" };
20252
+ STATE_COLOR = { done: PALETTE.success, warning: PALETTE.warning, failed: PALETTE.error };
20241
20253
  }
20242
20254
  });
20243
20255
 
@@ -21535,7 +21547,7 @@ function plural(count, noun) {
21535
21547
  function compositionDone(progress) {
21536
21548
  return progress.composition === "done" || progress.composition === "cache-hit";
21537
21549
  }
21538
- function progressRows(progress, agent) {
21550
+ function progressRows(progress, agent, rowMs = []) {
21539
21551
  const { scan, composition, selection, existingEntities, tokens } = progress;
21540
21552
  const scanned = scan?.scanned ?? 0;
21541
21553
  const scanComplete = (scan?.total ?? 0) > 0;
@@ -21556,16 +21568,23 @@ function progressRows(progress, agent) {
21556
21568
  if (existingEntities !== "idle") {
21557
21569
  rows.push({
21558
21570
  text: existingEntities === "running" ? "Fetching existing components and tokens..." : existingEntities === "complete" ? "Existing components and tokens ready" : "Existing entities unavailable; continuing without them",
21559
- complete: existingEntities !== "running"
21571
+ complete: existingEntities !== "running",
21572
+ // The import carries on without them, so this is not shown as a success.
21573
+ ...existingEntities === "failed" ? { state: "warning" } : {}
21560
21574
  });
21561
21575
  }
21562
21576
  if (tokens !== "idle") {
21563
21577
  rows.push({
21564
21578
  text: tokens === "complete" ? "Token definitions ready" : tokens === "failed" ? "Token definition generation failed" : `Generating token definitions via ${agent}...`,
21565
- complete: tokens === "complete"
21579
+ complete: tokens === "complete",
21580
+ // A failed job is not still running.
21581
+ ...tokens === "failed" ? { state: "failed" } : {}
21566
21582
  });
21567
21583
  }
21568
- return rows;
21584
+ return rows.map((row, index) => rowMs[index] === void 0 ? row : { ...row, ms: rowMs[index] });
21585
+ }
21586
+ function trackFinished(previous, rows, elapsedMs) {
21587
+ return rows.map((row, index) => previous[index] ?? (lineState(row) === "running" ? void 0 : elapsedMs));
21569
21588
  }
21570
21589
  function noComponentsMessage(projectPath) {
21571
21590
  return `No components found in ${projectPath}.
@@ -21596,18 +21615,19 @@ var init_logic9 = __esm({
21596
21615
  "use strict";
21597
21616
  init_src3();
21598
21617
  init_debug_trail();
21618
+ init_logic4();
21599
21619
  }
21600
21620
  });
21601
21621
 
21602
21622
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/screen.tsx
21603
21623
  import { jsx as jsx16 } from "react/jsx-runtime";
21604
- function ExtractionScreen({ progress, agent }) {
21624
+ function ExtractionScreen({ progress, agent, rowMs }) {
21605
21625
  return /* @__PURE__ */ jsx16(
21606
21626
  RunningStep,
21607
21627
  {
21608
21628
  step: "extraction",
21609
21629
  description: "Extracting context from your source files.",
21610
- lines: progressRows(progress, agent)
21630
+ lines: progressRows(progress, agent, rowMs)
21611
21631
  }
21612
21632
  );
21613
21633
  }
@@ -22092,9 +22112,12 @@ function useExtraction(input) {
22092
22112
  progress: initialProgress({
22093
22113
  hasCredentials: input.credentials !== null,
22094
22114
  hasRawTokens: input.rawTokensPath !== ""
22095
- })
22115
+ }),
22116
+ rowMs: []
22096
22117
  });
22097
22118
  let lastProgress;
22119
+ const startedAt = Date.now();
22120
+ let rowMs = [];
22098
22121
  startDebugRun({
22099
22122
  flow: "import/extraction",
22100
22123
  step: "06-extraction",
@@ -22103,7 +22126,8 @@ function useExtraction(input) {
22103
22126
  });
22104
22127
  void runExtraction(input, (progress) => {
22105
22128
  lastProgress = progress;
22106
- if (current.current === input) setState({ status: "running", progress });
22129
+ rowMs = trackFinished(rowMs, progressRows(progress, input.agent), Date.now() - startedAt);
22130
+ if (current.current === input) setState({ status: "running", progress, rowMs });
22107
22131
  }).then((result) => {
22108
22132
  if (current.current !== input) return;
22109
22133
  void finishDebugRun({
@@ -35690,7 +35714,14 @@ function App({ importOptions, inkClear }) {
35690
35714
  return /* @__PURE__ */ jsx66(ErrorStep, { stepName: extraction.result.step, message: extraction.result.message, onExit: leaveImport });
35691
35715
  }
35692
35716
  if (extraction?.status === "running") {
35693
- return /* @__PURE__ */ jsx66(ExtractionScreen, { progress: extraction.progress, agent: extractionRun.input.agent });
35717
+ return /* @__PURE__ */ jsx66(
35718
+ ExtractionScreen,
35719
+ {
35720
+ progress: extraction.progress,
35721
+ agent: extractionRun.input.agent,
35722
+ rowMs: extraction.rowMs
35723
+ }
35724
+ );
35694
35725
  }
35695
35726
  return /* @__PURE__ */ jsx66(Fragment22, {});
35696
35727
  }
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.42.1-dev-build-99dae8de.0",
3
+ "version": "2.42.1-dev-build-8fa38033.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -5,7 +5,15 @@ export interface Progress {
5
5
  export interface RunningLine {
6
6
  text: string;
7
7
  complete?: boolean;
8
+ /** Set for a row that ended badly. A warning carries on without it; a failure does not. Otherwise `complete` decides. */
9
+ state?: 'warning' | 'failed';
8
10
  progress?: Progress;
11
+ /** How long the row took, once it has finished. */
12
+ ms?: number;
9
13
  }
14
+ export type LineState = 'running' | 'done' | 'warning' | 'failed';
15
+ /** What a row looks like. A row that ended badly is never shown as running or as done. */
16
+ export declare function lineState(line: RunningLine): LineState;
17
+ export declare function formatDuration(ms: number): string;
10
18
  export declare function progressPercent(progress: Progress): number;
11
19
  export declare function formatElapsed(totalSeconds: number): string;
@@ -1,4 +1,5 @@
1
1
  import type { ExtractAndComposeProgress } from '@contentful/experience-design-system-backend-pipeline';
2
+ import { type RunningLine } from '../../shared/running-step/logic.js';
2
3
  import type { ExtractionInput, ExtractionProgress, ExtractionResult } from './types.js';
3
4
  /** Structured progress events emitted by the orchestrator (extraction + composition). */
4
5
  export type ProgressEvent = ExtractAndComposeProgress;
@@ -24,11 +25,17 @@ export declare function initialProgress(input: {
24
25
  hasRawTokens: boolean;
25
26
  }): ExtractionProgress;
26
27
  export declare function applyProgressEvent(progress: ExtractionProgress, event: ProgressEvent): ExtractionProgress;
27
- /** The rows the screen shows, in the order the wizard showed them. Rows that do not apply are left out. */
28
- export declare function progressRows(progress: ExtractionProgress, agent: string): Array<{
29
- text: string;
30
- complete: boolean;
31
- }>;
28
+ /**
29
+ * The rows the screen shows, in the order the wizard showed them. Rows that do not apply are left out. `rowMs` is how long
30
+ * each finished row took, by position (see `trackFinished`).
31
+ */
32
+ export declare function progressRows(progress: ExtractionProgress, agent: string, rowMs?: ReadonlyArray<number | undefined>): RunningLine[];
33
+ /**
34
+ * How long each row took, by position, for the rows that have finished. The jobs all start together, so a row's time is how
35
+ * long the run had been going when it was first seen finished, and it does not change after that. Rows keep their position
36
+ * for the whole run, since every job that applies is started up front.
37
+ */
38
+ export declare function trackFinished(previous: ReadonlyArray<number | undefined>, rows: readonly RunningLine[], elapsedMs: number): Array<number | undefined>;
32
39
  /** True when every job is already done, so the screen would only flash. The wizard shows nothing in this case. */
33
40
  export declare function isFullCacheHit(progress: ExtractionProgress): boolean;
34
41
  export declare function noComponentsMessage(projectPath: string): string;
@@ -3,6 +3,8 @@ import type { ExtractionProgress } from './types.js';
3
3
  interface ExtractionScreenProps {
4
4
  progress: ExtractionProgress;
5
5
  agent: string;
6
+ /** How long each finished row took, by position. */
7
+ rowMs?: ReadonlyArray<number | undefined>;
6
8
  }
7
- export declare function ExtractionScreen({ progress, agent }: ExtractionScreenProps): React.ReactElement;
9
+ export declare function ExtractionScreen({ progress, agent, rowMs }: ExtractionScreenProps): React.ReactElement;
8
10
  export {};
@@ -2,6 +2,7 @@ import type { ExtractionInput, ExtractionProgress, ExtractionResult } from './ty
2
2
  export type ExtractionState = {
3
3
  status: 'running';
4
4
  progress: ExtractionProgress;
5
+ rowMs: Array<number | undefined>;
5
6
  } | {
6
7
  status: 'done';
7
8
  result: ExtractionResult;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.42.1-dev-build-99dae8de.0",
3
+ "version": "2.42.1-dev-build-8fa38033.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -45,7 +45,7 @@
45
45
  "ts-morph": "^27.0.2",
46
46
  "typescript": "^5.9.3",
47
47
  "zod": "^4.6.5",
48
- "@contentful/experience-design-system-types": "2.42.1-dev-build-99dae8de.0"
48
+ "@contentful/experience-design-system-types": "2.42.1-dev-build-8fa38033.0"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@tsconfig/node24": "^24.0.4",
@@ -59,7 +59,7 @@
59
59
  "ink-testing-library": "^4.0.0",
60
60
  "typescript-eslint": "^8.67.0",
61
61
  "vitest": "^4.0.16",
62
- "@contentful/experience-design-system-backend-pipeline": "2.42.1-dev-build-99dae8de.0"
62
+ "@contentful/experience-design-system-backend-pipeline": "2.42.1-dev-build-8fa38033.0"
63
63
  },
64
64
  "repository": {
65
65
  "type": "git",