@contentful/experience-design-system-cli 2.27.3-dev-build-3597adc.0 → 2.27.3-dev-build-90d1ffe.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 +2 -2
- package/dist/src/index.js +170 -66
- package/dist/src/runs/picker-labels.d.ts +24 -0
- package/package.json +6 -6
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/experience-design-system-cli",
|
|
3
|
-
"version": "2.27.3-dev-build-
|
|
3
|
+
"version": "2.27.3-dev-build-90d1ffe.0",
|
|
4
4
|
"description": "Contentful Experiences design system import CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"react": "^18.3.1",
|
|
47
47
|
"react-devtools-core": "^4.19.1",
|
|
48
48
|
"react-dom": "^18.3.1",
|
|
49
|
-
"svelte": "^5.
|
|
49
|
+
"svelte": "^5.56.4",
|
|
50
50
|
"ts-morph": "^27.0.2",
|
|
51
51
|
"typescript": "^5.9.3"
|
|
52
52
|
},
|
package/dist/src/index.js
CHANGED
|
@@ -16207,25 +16207,104 @@ var init_path_prompt = __esm({
|
|
|
16207
16207
|
}
|
|
16208
16208
|
});
|
|
16209
16209
|
|
|
16210
|
+
// packages/experience-design-system-cli/src/runs/picker-labels.ts
|
|
16211
|
+
function pathSegments(projectPath) {
|
|
16212
|
+
const normalised = projectPath.replace(/\\/g, "/");
|
|
16213
|
+
return normalised.split("/").filter((s) => s.length > 0);
|
|
16214
|
+
}
|
|
16215
|
+
function disambiguateLabels(runs) {
|
|
16216
|
+
const entries = runs.map((r) => ({
|
|
16217
|
+
id: r.id,
|
|
16218
|
+
segments: pathSegments(r.projectPath),
|
|
16219
|
+
level: 1
|
|
16220
|
+
}));
|
|
16221
|
+
const labelAt = (e) => {
|
|
16222
|
+
if (e.segments.length === 0) return e.id;
|
|
16223
|
+
const take = Math.min(e.level, e.segments.length);
|
|
16224
|
+
return e.segments.slice(-take).join("/");
|
|
16225
|
+
};
|
|
16226
|
+
let stable = false;
|
|
16227
|
+
while (!stable) {
|
|
16228
|
+
stable = true;
|
|
16229
|
+
const groups = /* @__PURE__ */ new Map();
|
|
16230
|
+
for (const e of entries) {
|
|
16231
|
+
const key = labelAt(e);
|
|
16232
|
+
const arr = groups.get(key);
|
|
16233
|
+
if (arr) arr.push(e);
|
|
16234
|
+
else groups.set(key, [e]);
|
|
16235
|
+
}
|
|
16236
|
+
for (const group of groups.values()) {
|
|
16237
|
+
if (group.length < 2) continue;
|
|
16238
|
+
const anyExpandable = group.some((e) => e.level < e.segments.length);
|
|
16239
|
+
if (!anyExpandable) continue;
|
|
16240
|
+
for (const e of group) {
|
|
16241
|
+
if (e.level < e.segments.length) e.level += 1;
|
|
16242
|
+
}
|
|
16243
|
+
stable = false;
|
|
16244
|
+
}
|
|
16245
|
+
}
|
|
16246
|
+
const result = /* @__PURE__ */ new Map();
|
|
16247
|
+
const orderedGroups = [];
|
|
16248
|
+
const byLabel = /* @__PURE__ */ new Map();
|
|
16249
|
+
for (const e of entries) {
|
|
16250
|
+
const key = labelAt(e);
|
|
16251
|
+
const existing = byLabel.get(key);
|
|
16252
|
+
if (existing) {
|
|
16253
|
+
existing.push(e);
|
|
16254
|
+
} else {
|
|
16255
|
+
const fresh = [e];
|
|
16256
|
+
byLabel.set(key, fresh);
|
|
16257
|
+
orderedGroups.push(fresh);
|
|
16258
|
+
}
|
|
16259
|
+
}
|
|
16260
|
+
for (const group of orderedGroups) {
|
|
16261
|
+
if (group.length === 1) {
|
|
16262
|
+
const only = group[0];
|
|
16263
|
+
result.set(only.id, labelAt(only));
|
|
16264
|
+
} else {
|
|
16265
|
+
group.forEach((e, i) => {
|
|
16266
|
+
result.set(e.id, `${labelAt(e)} (#${i + 1})`);
|
|
16267
|
+
});
|
|
16268
|
+
}
|
|
16269
|
+
}
|
|
16270
|
+
return result;
|
|
16271
|
+
}
|
|
16272
|
+
function pad22(n) {
|
|
16273
|
+
return String(n).padStart(2, "0");
|
|
16274
|
+
}
|
|
16275
|
+
function formatRelativeTime(iso, now = /* @__PURE__ */ new Date()) {
|
|
16276
|
+
const then = new Date(iso);
|
|
16277
|
+
if (Number.isNaN(then.getTime())) return iso;
|
|
16278
|
+
const diffMs = now.getTime() - then.getTime();
|
|
16279
|
+
const diffSec = Math.floor(diffMs / 1e3);
|
|
16280
|
+
if (diffSec < 60) return "just now";
|
|
16281
|
+
const diffMin = Math.floor(diffSec / 60);
|
|
16282
|
+
if (diffMin < 60) return `${diffMin}m ago`;
|
|
16283
|
+
const diffHr = Math.floor(diffMin / 60);
|
|
16284
|
+
if (diffHr < 24) return `${diffHr}h ago`;
|
|
16285
|
+
const diffDay = Math.floor(diffHr / 24);
|
|
16286
|
+
if (diffDay < 7) return `${diffDay}d ago`;
|
|
16287
|
+
return `${then.getFullYear()}-${pad22(then.getMonth() + 1)}-${pad22(then.getDate())} ${pad22(then.getHours())}:${pad22(then.getMinutes())}`;
|
|
16288
|
+
}
|
|
16289
|
+
var init_picker_labels = __esm({
|
|
16290
|
+
"packages/experience-design-system-cli/src/runs/picker-labels.ts"() {
|
|
16291
|
+
"use strict";
|
|
16292
|
+
}
|
|
16293
|
+
});
|
|
16294
|
+
|
|
16210
16295
|
// packages/experience-design-system-cli/src/runs/run-picker.tsx
|
|
16211
|
-
import { useState as useState10 } from "react";
|
|
16296
|
+
import { useMemo as useMemo2, useState as useState10 } from "react";
|
|
16212
16297
|
import { Box as Box20, Text as Text20 } from "ink";
|
|
16213
16298
|
import { jsx as jsx20, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
16214
|
-
function
|
|
16215
|
-
|
|
16216
|
-
|
|
16217
|
-
|
|
16218
|
-
|
|
16219
|
-
const
|
|
16220
|
-
const hh = String(d.getHours()).padStart(2, "0");
|
|
16221
|
-
const mi = String(d.getMinutes()).padStart(2, "0");
|
|
16222
|
-
return `${yyyy}-${mm}-${dd} ${hh}:${mi}`;
|
|
16223
|
-
}
|
|
16224
|
-
function runLine(run) {
|
|
16225
|
-
const date = formatCreatedAt(run.createdAt);
|
|
16226
|
-
const pushedTag = run.pushedTo ? "pushed" : "not pushed";
|
|
16299
|
+
function pushStatus(run) {
|
|
16300
|
+
if (!run.pushedTo) return "not pushed";
|
|
16301
|
+
return `\u2192 ${run.pushedTo.spaceId}/${run.pushedTo.environmentId}`;
|
|
16302
|
+
}
|
|
16303
|
+
function runLine(run, label) {
|
|
16304
|
+
const when = formatRelativeTime(run.createdAt);
|
|
16227
16305
|
const count = `${run.componentCount} component${run.componentCount === 1 ? "" : "s"}`;
|
|
16228
|
-
|
|
16306
|
+
const agent = run.agent ? ` ${run.agent}` : "";
|
|
16307
|
+
return `${label} ${when} ${count} ${pushStatus(run)}${agent}`;
|
|
16229
16308
|
}
|
|
16230
16309
|
function ActionScreen({
|
|
16231
16310
|
runId,
|
|
@@ -16293,6 +16372,12 @@ function RunPicker({ runs, staleRunIds, onSelect, onCancel }) {
|
|
|
16293
16372
|
const [actionRunId, setActionRunId] = useState10(null);
|
|
16294
16373
|
const rows = buildRows(runs, expanded);
|
|
16295
16374
|
const clampedFocus = Math.min(focusIdx, rows.length - 1);
|
|
16375
|
+
const visibleRunLabels = useMemo2(() => {
|
|
16376
|
+
const visibleRuns = rows.filter((r) => r.kind === "run").map((r) => ({ id: r.run.id, projectPath: r.run.projectPath }));
|
|
16377
|
+
return disambiguateLabels(visibleRuns);
|
|
16378
|
+
}, [rows]);
|
|
16379
|
+
const focusedRow = rows[clampedFocus];
|
|
16380
|
+
const focusedRunId = focusedRow?.kind === "run" ? focusedRow.run.id : null;
|
|
16296
16381
|
const selectRow = (row) => {
|
|
16297
16382
|
if (row.kind === "show-all") {
|
|
16298
16383
|
setExpanded(true);
|
|
@@ -16355,9 +16440,10 @@ function RunPicker({ runs, staleRunIds, onSelect, onCancel }) {
|
|
|
16355
16440
|
const cursor = focused ? ">" : " ";
|
|
16356
16441
|
if (row.kind === "run") {
|
|
16357
16442
|
const isStale = staleRunIds?.has(row.run.id) ?? false;
|
|
16443
|
+
const label = visibleRunLabels.get(row.run.id) ?? row.run.projectPath;
|
|
16358
16444
|
return /* @__PURE__ */ jsxs20(Box20, { gap: 1, children: [
|
|
16359
16445
|
/* @__PURE__ */ jsx20(Text20, { color, children: cursor }),
|
|
16360
|
-
/* @__PURE__ */ jsx20(Text20, { color, children: runLine(row.run) }),
|
|
16446
|
+
/* @__PURE__ */ jsx20(Text20, { color, children: runLine(row.run, label) }),
|
|
16361
16447
|
isStale ? /* @__PURE__ */ jsx20(Text20, { dimColor: true, children: " (stale)" }) : null
|
|
16362
16448
|
] }, `run-${row.run.id}`);
|
|
16363
16449
|
}
|
|
@@ -16376,6 +16462,10 @@ function RunPicker({ runs, staleRunIds, onSelect, onCancel }) {
|
|
|
16376
16462
|
/* @__PURE__ */ jsx20(Text20, { color, children: "[n] Start a new run" })
|
|
16377
16463
|
] }, "new");
|
|
16378
16464
|
}) }),
|
|
16465
|
+
focusedRunId ? /* @__PURE__ */ jsx20(Box20, { marginTop: 1, children: /* @__PURE__ */ jsxs20(Text20, { dimColor: true, children: [
|
|
16466
|
+
"ID: ",
|
|
16467
|
+
focusedRunId
|
|
16468
|
+
] }) }) : null,
|
|
16379
16469
|
/* @__PURE__ */ jsxs20(Box20, { gap: 3, marginTop: 1, children: [
|
|
16380
16470
|
/* @__PURE__ */ jsx20(Text20, { dimColor: true, children: "[j/k] Navigate" }),
|
|
16381
16471
|
/* @__PURE__ */ jsx20(Text20, { dimColor: true, children: "[Enter] Select" }),
|
|
@@ -16389,6 +16479,7 @@ var init_run_picker = __esm({
|
|
|
16389
16479
|
"packages/experience-design-system-cli/src/runs/run-picker.tsx"() {
|
|
16390
16480
|
"use strict";
|
|
16391
16481
|
init_useImmediateInput();
|
|
16482
|
+
init_picker_labels();
|
|
16392
16483
|
COLLAPSED_LIMIT = 10;
|
|
16393
16484
|
COLLAPSE_THRESHOLD = 12;
|
|
16394
16485
|
ACTION_OPTIONS = [
|
|
@@ -17327,7 +17418,7 @@ var init_preview_diff = __esm({
|
|
|
17327
17418
|
});
|
|
17328
17419
|
|
|
17329
17420
|
// packages/experience-design-system-cli/src/import/tui/steps/WizardPreviewStep.tsx
|
|
17330
|
-
import { useState as useState16, useMemo as
|
|
17421
|
+
import { useState as useState16, useMemo as useMemo3 } from "react";
|
|
17331
17422
|
import { Box as Box28, Text as Text28, useStdout as useStdout3 } from "ink";
|
|
17332
17423
|
import { Fragment as Fragment9, jsx as jsx28, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
17333
17424
|
function buildPreviewDiffLines(preview) {
|
|
@@ -17433,7 +17524,7 @@ function WizardPreviewStep({
|
|
|
17433
17524
|
const { stdout } = useStdout3();
|
|
17434
17525
|
const terminalRows = stdout?.rows ?? 40;
|
|
17435
17526
|
const viewportHeight = Math.max(terminalRows - 14, 10);
|
|
17436
|
-
const allDiffLines =
|
|
17527
|
+
const allDiffLines = useMemo3(() => {
|
|
17437
17528
|
if (!diffExpanded) return [];
|
|
17438
17529
|
return buildPreviewDiffLines(preview).map((line) => ({
|
|
17439
17530
|
key: line.key,
|
|
@@ -19179,12 +19270,12 @@ var init_lineage = __esm({
|
|
|
19179
19270
|
});
|
|
19180
19271
|
|
|
19181
19272
|
// packages/experience-design-system-cli/src/import/tui/hooks/useLineage.ts
|
|
19182
|
-
import { useMemo as
|
|
19273
|
+
import { useMemo as useMemo4 } from "react";
|
|
19183
19274
|
function useLineage(focusedKey, graph) {
|
|
19184
|
-
const graphKey =
|
|
19185
|
-
const stableGraph =
|
|
19186
|
-
const closures =
|
|
19187
|
-
const entries =
|
|
19275
|
+
const graphKey = useMemo4(() => JSON.stringify(graph), [graph]);
|
|
19276
|
+
const stableGraph = useMemo4(() => graph, [graphKey]);
|
|
19277
|
+
const closures = useMemo4(() => computeAllClosures(stableGraph), [stableGraph]);
|
|
19278
|
+
const entries = useMemo4(() => {
|
|
19188
19279
|
if (!focusedKey) return [];
|
|
19189
19280
|
const name = focusedKey;
|
|
19190
19281
|
const tree = buildAncestorTree(name, stableGraph);
|
|
@@ -19218,7 +19309,7 @@ function useLineage(focusedKey, graph) {
|
|
|
19218
19309
|
}
|
|
19219
19310
|
return out;
|
|
19220
19311
|
}, [focusedKey, stableGraph, closures]);
|
|
19221
|
-
const jumpables =
|
|
19312
|
+
const jumpables = useMemo4(
|
|
19222
19313
|
() => entries.map((entry, i) => ({ entry, i })).filter(({ entry }) => entry.kind === "ancestor" || entry.kind === "descendant"),
|
|
19223
19314
|
[entries]
|
|
19224
19315
|
);
|
|
@@ -19864,7 +19955,7 @@ var init_scope_gate_columns = __esm({
|
|
|
19864
19955
|
|
|
19865
19956
|
// packages/experience-design-system-cli/src/import/tui/steps/ScopeGateStep.tsx
|
|
19866
19957
|
import { Box as Box38, Text as Text40, useStdout as useStdout4 } from "ink";
|
|
19867
|
-
import React20, { useEffect as useEffect10, useMemo as
|
|
19958
|
+
import React20, { useEffect as useEffect10, useMemo as useMemo5, useRef as useRef4, useState as useState21 } from "react";
|
|
19868
19959
|
import { Fragment as Fragment11, jsx as jsx41, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
19869
19960
|
function capReasonForFocusedRow(reason, width) {
|
|
19870
19961
|
const safeWidth = Math.max(20, width);
|
|
@@ -19897,7 +19988,7 @@ function ScopeGateStep({
|
|
|
19897
19988
|
}) {
|
|
19898
19989
|
const { stdout } = useStdout4();
|
|
19899
19990
|
const totalWidth = stdout?.columns ?? 80;
|
|
19900
|
-
const columnPlan =
|
|
19991
|
+
const columnPlan = useMemo5(() => computeColumnWidths(totalWidth), [totalWidth]);
|
|
19901
19992
|
const sidebarWidth = columnPlan.main;
|
|
19902
19993
|
const [userDecisions, setUserDecisions] = useState21(/* @__PURE__ */ new Map());
|
|
19903
19994
|
const [nav, setNav] = useState21({ cursor: 0, scrollOffset: 0 });
|
|
@@ -19932,7 +20023,7 @@ function ScopeGateStep({
|
|
|
19932
20023
|
return next;
|
|
19933
20024
|
});
|
|
19934
20025
|
};
|
|
19935
|
-
const groupedItems =
|
|
20026
|
+
const groupedItems = useMemo5(
|
|
19936
20027
|
() => components.map((c2) => ({
|
|
19937
20028
|
key: c2.name,
|
|
19938
20029
|
entry: toSidebarEntry(c2),
|
|
@@ -19940,21 +20031,21 @@ function ScopeGateStep({
|
|
|
19940
20031
|
})),
|
|
19941
20032
|
[components]
|
|
19942
20033
|
);
|
|
19943
|
-
const graph =
|
|
19944
|
-
const slotCycles =
|
|
20034
|
+
const graph = useMemo5(() => buildComponentGraph(groupedItems), [groupedItems]);
|
|
20035
|
+
const slotCycles = useMemo5(() => {
|
|
19945
20036
|
try {
|
|
19946
20037
|
return findSlotCycles(graph);
|
|
19947
20038
|
} catch {
|
|
19948
20039
|
return [];
|
|
19949
20040
|
}
|
|
19950
20041
|
}, [graph]);
|
|
19951
|
-
const cycleParticipants =
|
|
20042
|
+
const cycleParticipants = useMemo5(() => {
|
|
19952
20043
|
const set = /* @__PURE__ */ new Set();
|
|
19953
20044
|
for (const c2 of slotCycles) for (const n of c2.path) set.add(n);
|
|
19954
20045
|
return set;
|
|
19955
20046
|
}, [slotCycles]);
|
|
19956
|
-
const cycleUnits =
|
|
19957
|
-
const cyclesJumpables =
|
|
20047
|
+
const cycleUnits = useMemo5(() => buildCycleUnits(slotCycles), [slotCycles]);
|
|
20048
|
+
const cyclesJumpables = useMemo5(
|
|
19958
20049
|
() => slotCycles.map((c2, i) => ({
|
|
19959
20050
|
cycleIndex: i,
|
|
19960
20051
|
jumpTarget: c2.path[0]
|
|
@@ -19962,7 +20053,7 @@ function ScopeGateStep({
|
|
|
19962
20053
|
[slotCycles]
|
|
19963
20054
|
);
|
|
19964
20055
|
const hasCycles = slotCycles.length > 0;
|
|
19965
|
-
const closures =
|
|
20056
|
+
const closures = useMemo5(() => computeAllClosures(graph), [graph]);
|
|
19966
20057
|
const [expandedGroups, setExpandedGroups] = useState21(() => {
|
|
19967
20058
|
const seed = new Set(closures.keys());
|
|
19968
20059
|
for (const p of cycleParticipants) seed.add(p);
|
|
@@ -19977,7 +20068,7 @@ function ScopeGateStep({
|
|
|
19977
20068
|
for (const p of cycleParticipants) seed.add(p);
|
|
19978
20069
|
setExpandedGroups(seed);
|
|
19979
20070
|
}, [closures, cycleParticipants]);
|
|
19980
|
-
const hasGroupRoots =
|
|
20071
|
+
const hasGroupRoots = useMemo5(() => {
|
|
19981
20072
|
if (cycleParticipants.size > 0) return true;
|
|
19982
20073
|
for (const c2 of closures.values()) if (c2.nodes.length > 1) return true;
|
|
19983
20074
|
return false;
|
|
@@ -19990,12 +20081,12 @@ function ScopeGateStep({
|
|
|
19990
20081
|
return next;
|
|
19991
20082
|
});
|
|
19992
20083
|
};
|
|
19993
|
-
const brokenKeys =
|
|
20084
|
+
const brokenKeys = useMemo5(() => {
|
|
19994
20085
|
const set = /* @__PURE__ */ new Set();
|
|
19995
20086
|
for (const c2 of components) if (isAiFlagged(c2)) set.add(c2.name);
|
|
19996
20087
|
return set;
|
|
19997
20088
|
}, [components]);
|
|
19998
|
-
const filterVisibleKeys =
|
|
20089
|
+
const filterVisibleKeys = useMemo5(() => {
|
|
19999
20090
|
if (jumpFilterTarget) {
|
|
20000
20091
|
return findAllAncestors2(jumpFilterTarget, graph);
|
|
20001
20092
|
}
|
|
@@ -20011,7 +20102,7 @@ function ScopeGateStep({
|
|
|
20011
20102
|
})();
|
|
20012
20103
|
return intersectFilterKeys(categoryKeys, searchKeys);
|
|
20013
20104
|
}, [jumpFilterTarget, activeFilters, cycleParticipants, brokenKeys, searchQuery, groupedItems, graph]);
|
|
20014
|
-
const visibleRows =
|
|
20105
|
+
const visibleRows = useMemo5(
|
|
20015
20106
|
() => buildVisibleRows({
|
|
20016
20107
|
items: groupedItems,
|
|
20017
20108
|
cycleParticipants,
|
|
@@ -20028,19 +20119,19 @@ function ScopeGateStep({
|
|
|
20028
20119
|
const currentRow = visibleRows[safeCursor];
|
|
20029
20120
|
const currentRowKey = currentRow && currentRow.itemIdx >= 0 ? groupedItems[currentRow.itemIdx]?.key : void 0;
|
|
20030
20121
|
const focusedComponent = currentRowKey ? components.find((c2) => c2.name === currentRowKey) : void 0;
|
|
20031
|
-
const selectionStateByKey =
|
|
20122
|
+
const selectionStateByKey = useMemo5(() => {
|
|
20032
20123
|
const map = /* @__PURE__ */ new Map();
|
|
20033
20124
|
for (const c2 of components) {
|
|
20034
20125
|
map.set(c2.name, getState(c2.name));
|
|
20035
20126
|
}
|
|
20036
20127
|
return map;
|
|
20037
20128
|
}, [components, userDecisions]);
|
|
20038
|
-
const aiFlaggedByKey =
|
|
20129
|
+
const aiFlaggedByKey = useMemo5(() => {
|
|
20039
20130
|
const map = /* @__PURE__ */ new Map();
|
|
20040
20131
|
for (const c2 of components) map.set(c2.name, isAiFlagged(c2));
|
|
20041
20132
|
return map;
|
|
20042
20133
|
}, [components]);
|
|
20043
|
-
const dimPredicate =
|
|
20134
|
+
const dimPredicate = useMemo5(
|
|
20044
20135
|
() => buildFlatDimPredicate({
|
|
20045
20136
|
viewMode: columnOneView,
|
|
20046
20137
|
searchQuery,
|
|
@@ -20113,7 +20204,7 @@ function ScopeGateStep({
|
|
|
20113
20204
|
return { cursor: nextCursor, scrollOffset: nextScroll };
|
|
20114
20205
|
});
|
|
20115
20206
|
}, [visibleRows]);
|
|
20116
|
-
const searchMatches =
|
|
20207
|
+
const searchMatches = useMemo5(() => {
|
|
20117
20208
|
if (!searchQuery) return [];
|
|
20118
20209
|
return components.filter((c2) => fuzzyMatches(searchQuery, c2.name)).map((c2) => c2.name);
|
|
20119
20210
|
}, [components, searchQuery]);
|
|
@@ -20509,13 +20600,13 @@ function ScopeGateStep({
|
|
|
20509
20600
|
return;
|
|
20510
20601
|
}
|
|
20511
20602
|
});
|
|
20512
|
-
const includedCount =
|
|
20603
|
+
const includedCount = useMemo5(() => components.filter((c2) => isIncluded(c2.name)).length, [components, userDecisions]);
|
|
20513
20604
|
const hasAnyAi = components.some(isAiFlagged);
|
|
20514
20605
|
const aiExcludedCount = components.filter(isAiFlagged).length;
|
|
20515
20606
|
const aiExcludedWithReasons = components.filter(
|
|
20516
20607
|
(c2) => isAiFlagged(c2) && c2.aiReason !== null && c2.aiReason !== void 0 && c2.aiReason !== ""
|
|
20517
20608
|
);
|
|
20518
|
-
const aiRows =
|
|
20609
|
+
const aiRows = useMemo5(
|
|
20519
20610
|
() => aiExcludedWithReasons.map((c2) => ({
|
|
20520
20611
|
label: `${c2.name} \u2014 ${c2.aiReason}`,
|
|
20521
20612
|
jumpTarget: c2.name
|
|
@@ -20526,15 +20617,15 @@ function ScopeGateStep({
|
|
|
20526
20617
|
const nothingIncluded = components.length > 0 && components.every((c2) => !isIncluded(c2.name));
|
|
20527
20618
|
const totalComponents = components.length;
|
|
20528
20619
|
const totalMatches = searchQuery ? searchMatches.length : 0;
|
|
20529
|
-
const addedComponents =
|
|
20620
|
+
const addedComponents = useMemo5(
|
|
20530
20621
|
() => buildAddedComponentsList(components, selectionStateByKey, cycleParticipants),
|
|
20531
20622
|
[components, selectionStateByKey, cycleParticipants]
|
|
20532
20623
|
);
|
|
20533
|
-
const addedGroups =
|
|
20624
|
+
const addedGroups = useMemo5(
|
|
20534
20625
|
() => buildAddedGroupsList(closures, selectionStateByKey, cycleParticipants, cycleUnits),
|
|
20535
20626
|
[closures, selectionStateByKey, cycleParticipants, cycleUnits]
|
|
20536
20627
|
);
|
|
20537
|
-
const counters =
|
|
20628
|
+
const counters = useMemo5(
|
|
20538
20629
|
() => computeCounters(components, closures, selectionStateByKey),
|
|
20539
20630
|
[components, closures, selectionStateByKey]
|
|
20540
20631
|
);
|
|
@@ -20995,7 +21086,7 @@ var init_ScopeGateStep = __esm({
|
|
|
20995
21086
|
|
|
20996
21087
|
// packages/experience-design-system-cli/src/import/tui/steps/AtomicScopeGateStep.tsx
|
|
20997
21088
|
import { Box as Box39, Text as Text41, useStdout as useStdout5 } from "ink";
|
|
20998
|
-
import React21, { useMemo as
|
|
21089
|
+
import React21, { useMemo as useMemo6, useState as useState22 } from "react";
|
|
20999
21090
|
import { jsx as jsx42, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
21000
21091
|
function truncateReason(reason) {
|
|
21001
21092
|
if (reason === null || reason === void 0 || reason === "") return "<no reason given>";
|
|
@@ -21142,7 +21233,7 @@ function AtomicScopeGateStep({
|
|
|
21142
21233
|
}
|
|
21143
21234
|
});
|
|
21144
21235
|
const total = flatList.length;
|
|
21145
|
-
const includedCount =
|
|
21236
|
+
const includedCount = useMemo6(
|
|
21146
21237
|
() => flatList.filter((c2) => isIncluded(c2)).length,
|
|
21147
21238
|
[components, userExcluded, userUnExcluded]
|
|
21148
21239
|
);
|
|
@@ -23667,7 +23758,7 @@ var init_history = __esm({
|
|
|
23667
23758
|
});
|
|
23668
23759
|
|
|
23669
23760
|
// packages/experience-design-system-cli/src/import/tui/steps/GenerateReviewStep.tsx
|
|
23670
|
-
import { useEffect as useEffect13, useMemo as
|
|
23761
|
+
import { useEffect as useEffect13, useMemo as useMemo7, useRef as useRef7, useState as useState26 } from "react";
|
|
23671
23762
|
import { Box as Box44, Text as Text46, useStdout as useStdout6 } from "ink";
|
|
23672
23763
|
import { Fragment as Fragment14, jsx as jsx47, jsxs as jsxs46 } from "react/jsx-runtime";
|
|
23673
23764
|
function sortComponentsForSidebar2(components, cycleParticipants) {
|
|
@@ -23963,12 +24054,12 @@ function GenerateReviewStep({
|
|
|
23963
24054
|
} catch {
|
|
23964
24055
|
}
|
|
23965
24056
|
};
|
|
23966
|
-
const componentGraph =
|
|
23967
|
-
const sidebarGraph =
|
|
24057
|
+
const componentGraph = useMemo7(() => buildComponentGraph(components), [components]);
|
|
24058
|
+
const sidebarGraph = useMemo7(
|
|
23968
24059
|
() => buildComponentGraph(components, { stripRejectedEdges: true }),
|
|
23969
24060
|
[components]
|
|
23970
24061
|
);
|
|
23971
|
-
const closures =
|
|
24062
|
+
const closures = useMemo7(() => computeAllClosures(componentGraph), [componentGraph]);
|
|
23972
24063
|
useEffect13(() => {
|
|
23973
24064
|
if (seededGroupsRef.current) return;
|
|
23974
24065
|
if (closures.size === 0 && slotCycles.length === 0) return;
|
|
@@ -23977,14 +24068,14 @@ function GenerateReviewStep({
|
|
|
23977
24068
|
for (const cyc of slotCycles) for (const p of cyc.path) seed.add(p);
|
|
23978
24069
|
setExpandedGroups(seed);
|
|
23979
24070
|
}, [closures, slotCycles]);
|
|
23980
|
-
const directIssues =
|
|
24071
|
+
const directIssues = useMemo7(() => {
|
|
23981
24072
|
const m = /* @__PURE__ */ new Map();
|
|
23982
24073
|
for (const c2 of components) {
|
|
23983
24074
|
if (c2.status === "rejected") m.set(c2.key, "error");
|
|
23984
24075
|
}
|
|
23985
24076
|
return m;
|
|
23986
24077
|
}, [components]);
|
|
23987
|
-
const cycleView =
|
|
24078
|
+
const cycleView = useMemo7(() => computeCycleView(components), [components]);
|
|
23988
24079
|
useEffect13(() => {
|
|
23989
24080
|
const decision = computeAutoRejectDecision({
|
|
23990
24081
|
loading,
|
|
@@ -24094,7 +24185,7 @@ function GenerateReviewStep({
|
|
|
24094
24185
|
setLoadError(String(e));
|
|
24095
24186
|
}
|
|
24096
24187
|
};
|
|
24097
|
-
const groupedItemsMemo =
|
|
24188
|
+
const groupedItemsMemo = useMemo7(
|
|
24098
24189
|
() => components.map((c2) => ({
|
|
24099
24190
|
key: c2.key,
|
|
24100
24191
|
entry: c2.entry,
|
|
@@ -24102,12 +24193,12 @@ function GenerateReviewStep({
|
|
|
24102
24193
|
})),
|
|
24103
24194
|
[components, directIssues]
|
|
24104
24195
|
);
|
|
24105
|
-
const brokenKeys =
|
|
24196
|
+
const brokenKeys = useMemo7(
|
|
24106
24197
|
() => new Set(breakingChanges.map((b) => b.componentName)),
|
|
24107
24198
|
[breakingChanges]
|
|
24108
24199
|
);
|
|
24109
|
-
const breakingRows =
|
|
24110
|
-
const filterVisibleKeys =
|
|
24200
|
+
const breakingRows = useMemo7(() => buildBreakingRows(breakingChanges), [breakingChanges]);
|
|
24201
|
+
const filterVisibleKeys = useMemo7(() => {
|
|
24111
24202
|
if (jumpFilterTarget) {
|
|
24112
24203
|
return findAllAncestors2(jumpFilterTarget, sidebarGraph);
|
|
24113
24204
|
}
|
|
@@ -24123,7 +24214,7 @@ function GenerateReviewStep({
|
|
|
24123
24214
|
})();
|
|
24124
24215
|
return intersectFilterKeys(categoryKeys, searchKeys);
|
|
24125
24216
|
}, [jumpFilterTarget, activeFilters, cycleView, brokenKeys, searchQuery, groupedItemsMemo, sidebarGraph]);
|
|
24126
|
-
const visibleRowsMemo =
|
|
24217
|
+
const visibleRowsMemo = useMemo7(
|
|
24127
24218
|
() => buildVisibleRows({
|
|
24128
24219
|
items: groupedItemsMemo,
|
|
24129
24220
|
cycleParticipants: cycleView.structural,
|
|
@@ -24134,7 +24225,7 @@ function GenerateReviewStep({
|
|
|
24134
24225
|
}),
|
|
24135
24226
|
[groupedItemsMemo, cycleView, expandedGroups, columnOneView, sidebarGraph, filterVisibleKeys]
|
|
24136
24227
|
);
|
|
24137
|
-
const selectableRowPositions =
|
|
24228
|
+
const selectableRowPositions = useMemo7(() => {
|
|
24138
24229
|
const out = [];
|
|
24139
24230
|
for (let i = 0; i < visibleRowsMemo.length; i++) {
|
|
24140
24231
|
if (visibleRowsMemo[i].itemIdx >= 0) out.push(i);
|
|
@@ -24191,7 +24282,7 @@ function GenerateReviewStep({
|
|
|
24191
24282
|
db.close();
|
|
24192
24283
|
}
|
|
24193
24284
|
}, [selectedIdx, components, extractSessionId]);
|
|
24194
|
-
const renderStatusByKey =
|
|
24285
|
+
const renderStatusByKey = useMemo7(() => {
|
|
24195
24286
|
const merged = /* @__PURE__ */ new Map();
|
|
24196
24287
|
for (const closure of closures.values()) {
|
|
24197
24288
|
const per = computeRenderStatuses(closure, directIssues);
|
|
@@ -24204,7 +24295,7 @@ function GenerateReviewStep({
|
|
|
24204
24295
|
}
|
|
24205
24296
|
return merged;
|
|
24206
24297
|
}, [closures, directIssues]);
|
|
24207
|
-
const selectionStateByKey =
|
|
24298
|
+
const selectionStateByKey = useMemo7(() => {
|
|
24208
24299
|
const map = /* @__PURE__ */ new Map();
|
|
24209
24300
|
for (const c2 of components) {
|
|
24210
24301
|
if (c2.status === "accepted") map.set(c2.key, "accepted");
|
|
@@ -24213,7 +24304,7 @@ function GenerateReviewStep({
|
|
|
24213
24304
|
}
|
|
24214
24305
|
return map;
|
|
24215
24306
|
}, [components]);
|
|
24216
|
-
const searchMatches =
|
|
24307
|
+
const searchMatches = useMemo7(() => {
|
|
24217
24308
|
if (!searchQuery) return [];
|
|
24218
24309
|
const out = [];
|
|
24219
24310
|
for (const pos of selectableRowPositions) {
|
|
@@ -24223,7 +24314,7 @@ function GenerateReviewStep({
|
|
|
24223
24314
|
}
|
|
24224
24315
|
return out;
|
|
24225
24316
|
}, [searchQuery, selectableRowPositions, visibleRowsMemo, components]);
|
|
24226
|
-
const searchMatchCount =
|
|
24317
|
+
const searchMatchCount = useMemo7(() => {
|
|
24227
24318
|
if (searchMatches.length === 0) return 0;
|
|
24228
24319
|
const seen = /* @__PURE__ */ new Set();
|
|
24229
24320
|
for (const pos of searchMatches) {
|
|
@@ -24232,7 +24323,7 @@ function GenerateReviewStep({
|
|
|
24232
24323
|
}
|
|
24233
24324
|
return seen.size;
|
|
24234
24325
|
}, [searchMatches, visibleRowsMemo]);
|
|
24235
|
-
const dimPredicate =
|
|
24326
|
+
const dimPredicate = useMemo7(
|
|
24236
24327
|
() => buildFlatDimPredicate({
|
|
24237
24328
|
viewMode: columnOneView,
|
|
24238
24329
|
searchQuery,
|
|
@@ -24300,7 +24391,7 @@ function GenerateReviewStep({
|
|
|
24300
24391
|
setDraftValue("");
|
|
24301
24392
|
setSaveError(null);
|
|
24302
24393
|
};
|
|
24303
|
-
const breakEdges =
|
|
24394
|
+
const breakEdges = useMemo7(() => {
|
|
24304
24395
|
const cycle = slotCycles[cyclesCursor];
|
|
24305
24396
|
if (!cycle) return [];
|
|
24306
24397
|
return enumerateCycleBreaks(cycle, components);
|
|
@@ -27467,6 +27558,19 @@ If using a custom --host, make sure the space exists on that host.`
|
|
|
27467
27558
|
summary
|
|
27468
27559
|
};
|
|
27469
27560
|
}
|
|
27561
|
+
const pushSucceeded = pushResult.componentTypes.failed === 0 && pushResult.designTokens.failed === 0 && operation.sys.status !== "failed";
|
|
27562
|
+
if (pushSucceeded && state.lastRunId) {
|
|
27563
|
+
try {
|
|
27564
|
+
await updateRun(state.lastRunId, {
|
|
27565
|
+
pushedTo: { spaceId, environmentId, host: resolvedHost }
|
|
27566
|
+
});
|
|
27567
|
+
} catch (err) {
|
|
27568
|
+
process.stderr.write(
|
|
27569
|
+
`Warning: failed to record push target on run: ${err instanceof Error ? err.message : String(err)}
|
|
27570
|
+
`
|
|
27571
|
+
);
|
|
27572
|
+
}
|
|
27573
|
+
}
|
|
27470
27574
|
update({ step: "done", pushResult });
|
|
27471
27575
|
} catch (e) {
|
|
27472
27576
|
let msg;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type LabelInput = {
|
|
2
|
+
id: string;
|
|
3
|
+
projectPath: string;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Map each run to a display label. Labels start as the project path's leaf
|
|
7
|
+
* directory and expand one segment at a time (`<parent>/<leaf>`,
|
|
8
|
+
* `<gp>/<parent>/<leaf>`, …) until every label in the input set is unique.
|
|
9
|
+
* When two rows share the exact same absolute path, the collision is broken
|
|
10
|
+
* with numeric suffixes (`(#1)`, `(#2)`, …) in input order.
|
|
11
|
+
*/
|
|
12
|
+
export declare function disambiguateLabels(runs: readonly LabelInput[]): Map<string, string>;
|
|
13
|
+
/**
|
|
14
|
+
* Format an ISO-8601 timestamp relative to `now`. Buckets:
|
|
15
|
+
* < 60s → "just now"
|
|
16
|
+
* < 60 min → "Nm ago"
|
|
17
|
+
* < 24 h → "Nh ago"
|
|
18
|
+
* < 7 days → "Nd ago"
|
|
19
|
+
* otherwise → "YYYY-MM-DD HH:MM" (local time)
|
|
20
|
+
*
|
|
21
|
+
* Future timestamps (created after `now`) also render as "just now" — they
|
|
22
|
+
* only occur with clock skew and the delta is not worth surfacing.
|
|
23
|
+
*/
|
|
24
|
+
export declare function formatRelativeTime(iso: string, now?: Date): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/experience-design-system-cli",
|
|
3
|
-
"version": "2.27.3-dev-build-
|
|
3
|
+
"version": "2.27.3-dev-build-90d1ffe.0",
|
|
4
4
|
"description": "Contentful Experiences design system import CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -36,10 +36,10 @@
|
|
|
36
36
|
"react": "^18.3.1",
|
|
37
37
|
"react-devtools-core": "^4.19.1",
|
|
38
38
|
"react-dom": "^18.3.1",
|
|
39
|
-
"svelte": "^5.
|
|
39
|
+
"svelte": "^5.56.4",
|
|
40
40
|
"ts-morph": "^27.0.2",
|
|
41
41
|
"typescript": "^5.9.3",
|
|
42
|
-
"@contentful/experience-design-system-types": "2.27.3-dev-build-
|
|
42
|
+
"@contentful/experience-design-system-types": "2.27.3-dev-build-90d1ffe.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@tsconfig/node24": "^24.0.4",
|
|
@@ -51,9 +51,9 @@
|
|
|
51
51
|
"ink-testing-library": "^4.0.0",
|
|
52
52
|
"typescript-eslint": "^8.67.0",
|
|
53
53
|
"vitest": "^4.0.16",
|
|
54
|
-
"@contentful/experience-design-system-extraction": "2.27.3-dev-build-
|
|
55
|
-
"@contentful/experience-design-system-generation": "2.27.3-dev-build-
|
|
56
|
-
"@contentful/experience-design-system-client": "2.27.3-dev-build-
|
|
54
|
+
"@contentful/experience-design-system-extraction": "2.27.3-dev-build-90d1ffe.0",
|
|
55
|
+
"@contentful/experience-design-system-generation": "2.27.3-dev-build-90d1ffe.0",
|
|
56
|
+
"@contentful/experience-design-system-client": "2.27.3-dev-build-90d1ffe.0"
|
|
57
57
|
},
|
|
58
58
|
"repository": {
|
|
59
59
|
"type": "git",
|