@contentful/experience-design-system-cli 2.27.2-dev-build-240d86b.0 → 2.27.2-dev-build-d9f331e.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 +1 -1
- package/dist/src/index.js +156 -66
- package/dist/src/runs/picker-labels.d.ts +24 -0
- package/package.json +5 -5
package/dist/package.json
CHANGED
package/dist/src/index.js
CHANGED
|
@@ -16207,25 +16207,103 @@ 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
|
-
return `${
|
|
16306
|
+
return `${label} ${when} ${count} ${pushStatus(run)}`;
|
|
16229
16307
|
}
|
|
16230
16308
|
function ActionScreen({
|
|
16231
16309
|
runId,
|
|
@@ -16293,6 +16371,12 @@ function RunPicker({ runs, staleRunIds, onSelect, onCancel }) {
|
|
|
16293
16371
|
const [actionRunId, setActionRunId] = useState10(null);
|
|
16294
16372
|
const rows = buildRows(runs, expanded);
|
|
16295
16373
|
const clampedFocus = Math.min(focusIdx, rows.length - 1);
|
|
16374
|
+
const visibleRunLabels = useMemo2(() => {
|
|
16375
|
+
const visibleRuns = rows.filter((r) => r.kind === "run").map((r) => ({ id: r.run.id, projectPath: r.run.projectPath }));
|
|
16376
|
+
return disambiguateLabels(visibleRuns);
|
|
16377
|
+
}, [rows]);
|
|
16378
|
+
const focusedRow = rows[clampedFocus];
|
|
16379
|
+
const focusedRunId = focusedRow?.kind === "run" ? focusedRow.run.id : null;
|
|
16296
16380
|
const selectRow = (row) => {
|
|
16297
16381
|
if (row.kind === "show-all") {
|
|
16298
16382
|
setExpanded(true);
|
|
@@ -16355,9 +16439,10 @@ function RunPicker({ runs, staleRunIds, onSelect, onCancel }) {
|
|
|
16355
16439
|
const cursor = focused ? ">" : " ";
|
|
16356
16440
|
if (row.kind === "run") {
|
|
16357
16441
|
const isStale = staleRunIds?.has(row.run.id) ?? false;
|
|
16442
|
+
const label = visibleRunLabels.get(row.run.id) ?? row.run.projectPath;
|
|
16358
16443
|
return /* @__PURE__ */ jsxs20(Box20, { gap: 1, children: [
|
|
16359
16444
|
/* @__PURE__ */ jsx20(Text20, { color, children: cursor }),
|
|
16360
|
-
/* @__PURE__ */ jsx20(Text20, { color, children: runLine(row.run) }),
|
|
16445
|
+
/* @__PURE__ */ jsx20(Text20, { color, children: runLine(row.run, label) }),
|
|
16361
16446
|
isStale ? /* @__PURE__ */ jsx20(Text20, { dimColor: true, children: " (stale)" }) : null
|
|
16362
16447
|
] }, `run-${row.run.id}`);
|
|
16363
16448
|
}
|
|
@@ -16376,6 +16461,10 @@ function RunPicker({ runs, staleRunIds, onSelect, onCancel }) {
|
|
|
16376
16461
|
/* @__PURE__ */ jsx20(Text20, { color, children: "[n] Start a new run" })
|
|
16377
16462
|
] }, "new");
|
|
16378
16463
|
}) }),
|
|
16464
|
+
focusedRunId ? /* @__PURE__ */ jsx20(Box20, { marginTop: 1, children: /* @__PURE__ */ jsxs20(Text20, { dimColor: true, children: [
|
|
16465
|
+
"ID: ",
|
|
16466
|
+
focusedRunId
|
|
16467
|
+
] }) }) : null,
|
|
16379
16468
|
/* @__PURE__ */ jsxs20(Box20, { gap: 3, marginTop: 1, children: [
|
|
16380
16469
|
/* @__PURE__ */ jsx20(Text20, { dimColor: true, children: "[j/k] Navigate" }),
|
|
16381
16470
|
/* @__PURE__ */ jsx20(Text20, { dimColor: true, children: "[Enter] Select" }),
|
|
@@ -16389,6 +16478,7 @@ var init_run_picker = __esm({
|
|
|
16389
16478
|
"packages/experience-design-system-cli/src/runs/run-picker.tsx"() {
|
|
16390
16479
|
"use strict";
|
|
16391
16480
|
init_useImmediateInput();
|
|
16481
|
+
init_picker_labels();
|
|
16392
16482
|
COLLAPSED_LIMIT = 10;
|
|
16393
16483
|
COLLAPSE_THRESHOLD = 12;
|
|
16394
16484
|
ACTION_OPTIONS = [
|
|
@@ -17327,7 +17417,7 @@ var init_preview_diff = __esm({
|
|
|
17327
17417
|
});
|
|
17328
17418
|
|
|
17329
17419
|
// packages/experience-design-system-cli/src/import/tui/steps/WizardPreviewStep.tsx
|
|
17330
|
-
import { useState as useState16, useMemo as
|
|
17420
|
+
import { useState as useState16, useMemo as useMemo3 } from "react";
|
|
17331
17421
|
import { Box as Box28, Text as Text28, useStdout as useStdout3 } from "ink";
|
|
17332
17422
|
import { Fragment as Fragment9, jsx as jsx28, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
17333
17423
|
function buildPreviewDiffLines(preview) {
|
|
@@ -17433,7 +17523,7 @@ function WizardPreviewStep({
|
|
|
17433
17523
|
const { stdout } = useStdout3();
|
|
17434
17524
|
const terminalRows = stdout?.rows ?? 40;
|
|
17435
17525
|
const viewportHeight = Math.max(terminalRows - 14, 10);
|
|
17436
|
-
const allDiffLines =
|
|
17526
|
+
const allDiffLines = useMemo3(() => {
|
|
17437
17527
|
if (!diffExpanded) return [];
|
|
17438
17528
|
return buildPreviewDiffLines(preview).map((line) => ({
|
|
17439
17529
|
key: line.key,
|
|
@@ -19179,12 +19269,12 @@ var init_lineage = __esm({
|
|
|
19179
19269
|
});
|
|
19180
19270
|
|
|
19181
19271
|
// packages/experience-design-system-cli/src/import/tui/hooks/useLineage.ts
|
|
19182
|
-
import { useMemo as
|
|
19272
|
+
import { useMemo as useMemo4 } from "react";
|
|
19183
19273
|
function useLineage(focusedKey, graph) {
|
|
19184
|
-
const graphKey =
|
|
19185
|
-
const stableGraph =
|
|
19186
|
-
const closures =
|
|
19187
|
-
const entries =
|
|
19274
|
+
const graphKey = useMemo4(() => JSON.stringify(graph), [graph]);
|
|
19275
|
+
const stableGraph = useMemo4(() => graph, [graphKey]);
|
|
19276
|
+
const closures = useMemo4(() => computeAllClosures(stableGraph), [stableGraph]);
|
|
19277
|
+
const entries = useMemo4(() => {
|
|
19188
19278
|
if (!focusedKey) return [];
|
|
19189
19279
|
const name = focusedKey;
|
|
19190
19280
|
const tree = buildAncestorTree(name, stableGraph);
|
|
@@ -19218,7 +19308,7 @@ function useLineage(focusedKey, graph) {
|
|
|
19218
19308
|
}
|
|
19219
19309
|
return out;
|
|
19220
19310
|
}, [focusedKey, stableGraph, closures]);
|
|
19221
|
-
const jumpables =
|
|
19311
|
+
const jumpables = useMemo4(
|
|
19222
19312
|
() => entries.map((entry, i) => ({ entry, i })).filter(({ entry }) => entry.kind === "ancestor" || entry.kind === "descendant"),
|
|
19223
19313
|
[entries]
|
|
19224
19314
|
);
|
|
@@ -19864,7 +19954,7 @@ var init_scope_gate_columns = __esm({
|
|
|
19864
19954
|
|
|
19865
19955
|
// packages/experience-design-system-cli/src/import/tui/steps/ScopeGateStep.tsx
|
|
19866
19956
|
import { Box as Box38, Text as Text40, useStdout as useStdout4 } from "ink";
|
|
19867
|
-
import React20, { useEffect as useEffect10, useMemo as
|
|
19957
|
+
import React20, { useEffect as useEffect10, useMemo as useMemo5, useRef as useRef4, useState as useState21 } from "react";
|
|
19868
19958
|
import { Fragment as Fragment11, jsx as jsx41, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
19869
19959
|
function capReasonForFocusedRow(reason, width) {
|
|
19870
19960
|
const safeWidth = Math.max(20, width);
|
|
@@ -19897,7 +19987,7 @@ function ScopeGateStep({
|
|
|
19897
19987
|
}) {
|
|
19898
19988
|
const { stdout } = useStdout4();
|
|
19899
19989
|
const totalWidth = stdout?.columns ?? 80;
|
|
19900
|
-
const columnPlan =
|
|
19990
|
+
const columnPlan = useMemo5(() => computeColumnWidths(totalWidth), [totalWidth]);
|
|
19901
19991
|
const sidebarWidth = columnPlan.main;
|
|
19902
19992
|
const [userDecisions, setUserDecisions] = useState21(/* @__PURE__ */ new Map());
|
|
19903
19993
|
const [nav, setNav] = useState21({ cursor: 0, scrollOffset: 0 });
|
|
@@ -19932,7 +20022,7 @@ function ScopeGateStep({
|
|
|
19932
20022
|
return next;
|
|
19933
20023
|
});
|
|
19934
20024
|
};
|
|
19935
|
-
const groupedItems =
|
|
20025
|
+
const groupedItems = useMemo5(
|
|
19936
20026
|
() => components.map((c2) => ({
|
|
19937
20027
|
key: c2.name,
|
|
19938
20028
|
entry: toSidebarEntry(c2),
|
|
@@ -19940,21 +20030,21 @@ function ScopeGateStep({
|
|
|
19940
20030
|
})),
|
|
19941
20031
|
[components]
|
|
19942
20032
|
);
|
|
19943
|
-
const graph =
|
|
19944
|
-
const slotCycles =
|
|
20033
|
+
const graph = useMemo5(() => buildComponentGraph(groupedItems), [groupedItems]);
|
|
20034
|
+
const slotCycles = useMemo5(() => {
|
|
19945
20035
|
try {
|
|
19946
20036
|
return findSlotCycles(graph);
|
|
19947
20037
|
} catch {
|
|
19948
20038
|
return [];
|
|
19949
20039
|
}
|
|
19950
20040
|
}, [graph]);
|
|
19951
|
-
const cycleParticipants =
|
|
20041
|
+
const cycleParticipants = useMemo5(() => {
|
|
19952
20042
|
const set = /* @__PURE__ */ new Set();
|
|
19953
20043
|
for (const c2 of slotCycles) for (const n of c2.path) set.add(n);
|
|
19954
20044
|
return set;
|
|
19955
20045
|
}, [slotCycles]);
|
|
19956
|
-
const cycleUnits =
|
|
19957
|
-
const cyclesJumpables =
|
|
20046
|
+
const cycleUnits = useMemo5(() => buildCycleUnits(slotCycles), [slotCycles]);
|
|
20047
|
+
const cyclesJumpables = useMemo5(
|
|
19958
20048
|
() => slotCycles.map((c2, i) => ({
|
|
19959
20049
|
cycleIndex: i,
|
|
19960
20050
|
jumpTarget: c2.path[0]
|
|
@@ -19962,7 +20052,7 @@ function ScopeGateStep({
|
|
|
19962
20052
|
[slotCycles]
|
|
19963
20053
|
);
|
|
19964
20054
|
const hasCycles = slotCycles.length > 0;
|
|
19965
|
-
const closures =
|
|
20055
|
+
const closures = useMemo5(() => computeAllClosures(graph), [graph]);
|
|
19966
20056
|
const [expandedGroups, setExpandedGroups] = useState21(() => {
|
|
19967
20057
|
const seed = new Set(closures.keys());
|
|
19968
20058
|
for (const p of cycleParticipants) seed.add(p);
|
|
@@ -19977,7 +20067,7 @@ function ScopeGateStep({
|
|
|
19977
20067
|
for (const p of cycleParticipants) seed.add(p);
|
|
19978
20068
|
setExpandedGroups(seed);
|
|
19979
20069
|
}, [closures, cycleParticipants]);
|
|
19980
|
-
const hasGroupRoots =
|
|
20070
|
+
const hasGroupRoots = useMemo5(() => {
|
|
19981
20071
|
if (cycleParticipants.size > 0) return true;
|
|
19982
20072
|
for (const c2 of closures.values()) if (c2.nodes.length > 1) return true;
|
|
19983
20073
|
return false;
|
|
@@ -19990,12 +20080,12 @@ function ScopeGateStep({
|
|
|
19990
20080
|
return next;
|
|
19991
20081
|
});
|
|
19992
20082
|
};
|
|
19993
|
-
const brokenKeys =
|
|
20083
|
+
const brokenKeys = useMemo5(() => {
|
|
19994
20084
|
const set = /* @__PURE__ */ new Set();
|
|
19995
20085
|
for (const c2 of components) if (isAiFlagged(c2)) set.add(c2.name);
|
|
19996
20086
|
return set;
|
|
19997
20087
|
}, [components]);
|
|
19998
|
-
const filterVisibleKeys =
|
|
20088
|
+
const filterVisibleKeys = useMemo5(() => {
|
|
19999
20089
|
if (jumpFilterTarget) {
|
|
20000
20090
|
return findAllAncestors2(jumpFilterTarget, graph);
|
|
20001
20091
|
}
|
|
@@ -20011,7 +20101,7 @@ function ScopeGateStep({
|
|
|
20011
20101
|
})();
|
|
20012
20102
|
return intersectFilterKeys(categoryKeys, searchKeys);
|
|
20013
20103
|
}, [jumpFilterTarget, activeFilters, cycleParticipants, brokenKeys, searchQuery, groupedItems, graph]);
|
|
20014
|
-
const visibleRows =
|
|
20104
|
+
const visibleRows = useMemo5(
|
|
20015
20105
|
() => buildVisibleRows({
|
|
20016
20106
|
items: groupedItems,
|
|
20017
20107
|
cycleParticipants,
|
|
@@ -20028,19 +20118,19 @@ function ScopeGateStep({
|
|
|
20028
20118
|
const currentRow = visibleRows[safeCursor];
|
|
20029
20119
|
const currentRowKey = currentRow && currentRow.itemIdx >= 0 ? groupedItems[currentRow.itemIdx]?.key : void 0;
|
|
20030
20120
|
const focusedComponent = currentRowKey ? components.find((c2) => c2.name === currentRowKey) : void 0;
|
|
20031
|
-
const selectionStateByKey =
|
|
20121
|
+
const selectionStateByKey = useMemo5(() => {
|
|
20032
20122
|
const map = /* @__PURE__ */ new Map();
|
|
20033
20123
|
for (const c2 of components) {
|
|
20034
20124
|
map.set(c2.name, getState(c2.name));
|
|
20035
20125
|
}
|
|
20036
20126
|
return map;
|
|
20037
20127
|
}, [components, userDecisions]);
|
|
20038
|
-
const aiFlaggedByKey =
|
|
20128
|
+
const aiFlaggedByKey = useMemo5(() => {
|
|
20039
20129
|
const map = /* @__PURE__ */ new Map();
|
|
20040
20130
|
for (const c2 of components) map.set(c2.name, isAiFlagged(c2));
|
|
20041
20131
|
return map;
|
|
20042
20132
|
}, [components]);
|
|
20043
|
-
const dimPredicate =
|
|
20133
|
+
const dimPredicate = useMemo5(
|
|
20044
20134
|
() => buildFlatDimPredicate({
|
|
20045
20135
|
viewMode: columnOneView,
|
|
20046
20136
|
searchQuery,
|
|
@@ -20113,7 +20203,7 @@ function ScopeGateStep({
|
|
|
20113
20203
|
return { cursor: nextCursor, scrollOffset: nextScroll };
|
|
20114
20204
|
});
|
|
20115
20205
|
}, [visibleRows]);
|
|
20116
|
-
const searchMatches =
|
|
20206
|
+
const searchMatches = useMemo5(() => {
|
|
20117
20207
|
if (!searchQuery) return [];
|
|
20118
20208
|
return components.filter((c2) => fuzzyMatches(searchQuery, c2.name)).map((c2) => c2.name);
|
|
20119
20209
|
}, [components, searchQuery]);
|
|
@@ -20509,13 +20599,13 @@ function ScopeGateStep({
|
|
|
20509
20599
|
return;
|
|
20510
20600
|
}
|
|
20511
20601
|
});
|
|
20512
|
-
const includedCount =
|
|
20602
|
+
const includedCount = useMemo5(() => components.filter((c2) => isIncluded(c2.name)).length, [components, userDecisions]);
|
|
20513
20603
|
const hasAnyAi = components.some(isAiFlagged);
|
|
20514
20604
|
const aiExcludedCount = components.filter(isAiFlagged).length;
|
|
20515
20605
|
const aiExcludedWithReasons = components.filter(
|
|
20516
20606
|
(c2) => isAiFlagged(c2) && c2.aiReason !== null && c2.aiReason !== void 0 && c2.aiReason !== ""
|
|
20517
20607
|
);
|
|
20518
|
-
const aiRows =
|
|
20608
|
+
const aiRows = useMemo5(
|
|
20519
20609
|
() => aiExcludedWithReasons.map((c2) => ({
|
|
20520
20610
|
label: `${c2.name} \u2014 ${c2.aiReason}`,
|
|
20521
20611
|
jumpTarget: c2.name
|
|
@@ -20526,15 +20616,15 @@ function ScopeGateStep({
|
|
|
20526
20616
|
const nothingIncluded = components.length > 0 && components.every((c2) => !isIncluded(c2.name));
|
|
20527
20617
|
const totalComponents = components.length;
|
|
20528
20618
|
const totalMatches = searchQuery ? searchMatches.length : 0;
|
|
20529
|
-
const addedComponents =
|
|
20619
|
+
const addedComponents = useMemo5(
|
|
20530
20620
|
() => buildAddedComponentsList(components, selectionStateByKey, cycleParticipants),
|
|
20531
20621
|
[components, selectionStateByKey, cycleParticipants]
|
|
20532
20622
|
);
|
|
20533
|
-
const addedGroups =
|
|
20623
|
+
const addedGroups = useMemo5(
|
|
20534
20624
|
() => buildAddedGroupsList(closures, selectionStateByKey, cycleParticipants, cycleUnits),
|
|
20535
20625
|
[closures, selectionStateByKey, cycleParticipants, cycleUnits]
|
|
20536
20626
|
);
|
|
20537
|
-
const counters =
|
|
20627
|
+
const counters = useMemo5(
|
|
20538
20628
|
() => computeCounters(components, closures, selectionStateByKey),
|
|
20539
20629
|
[components, closures, selectionStateByKey]
|
|
20540
20630
|
);
|
|
@@ -20995,7 +21085,7 @@ var init_ScopeGateStep = __esm({
|
|
|
20995
21085
|
|
|
20996
21086
|
// packages/experience-design-system-cli/src/import/tui/steps/AtomicScopeGateStep.tsx
|
|
20997
21087
|
import { Box as Box39, Text as Text41, useStdout as useStdout5 } from "ink";
|
|
20998
|
-
import React21, { useMemo as
|
|
21088
|
+
import React21, { useMemo as useMemo6, useState as useState22 } from "react";
|
|
20999
21089
|
import { jsx as jsx42, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
21000
21090
|
function truncateReason(reason) {
|
|
21001
21091
|
if (reason === null || reason === void 0 || reason === "") return "<no reason given>";
|
|
@@ -21142,7 +21232,7 @@ function AtomicScopeGateStep({
|
|
|
21142
21232
|
}
|
|
21143
21233
|
});
|
|
21144
21234
|
const total = flatList.length;
|
|
21145
|
-
const includedCount =
|
|
21235
|
+
const includedCount = useMemo6(
|
|
21146
21236
|
() => flatList.filter((c2) => isIncluded(c2)).length,
|
|
21147
21237
|
[components, userExcluded, userUnExcluded]
|
|
21148
21238
|
);
|
|
@@ -23667,7 +23757,7 @@ var init_history = __esm({
|
|
|
23667
23757
|
});
|
|
23668
23758
|
|
|
23669
23759
|
// packages/experience-design-system-cli/src/import/tui/steps/GenerateReviewStep.tsx
|
|
23670
|
-
import { useEffect as useEffect13, useMemo as
|
|
23760
|
+
import { useEffect as useEffect13, useMemo as useMemo7, useRef as useRef7, useState as useState26 } from "react";
|
|
23671
23761
|
import { Box as Box44, Text as Text46, useStdout as useStdout6 } from "ink";
|
|
23672
23762
|
import { Fragment as Fragment14, jsx as jsx47, jsxs as jsxs46 } from "react/jsx-runtime";
|
|
23673
23763
|
function sortComponentsForSidebar2(components, cycleParticipants) {
|
|
@@ -23963,12 +24053,12 @@ function GenerateReviewStep({
|
|
|
23963
24053
|
} catch {
|
|
23964
24054
|
}
|
|
23965
24055
|
};
|
|
23966
|
-
const componentGraph =
|
|
23967
|
-
const sidebarGraph =
|
|
24056
|
+
const componentGraph = useMemo7(() => buildComponentGraph(components), [components]);
|
|
24057
|
+
const sidebarGraph = useMemo7(
|
|
23968
24058
|
() => buildComponentGraph(components, { stripRejectedEdges: true }),
|
|
23969
24059
|
[components]
|
|
23970
24060
|
);
|
|
23971
|
-
const closures =
|
|
24061
|
+
const closures = useMemo7(() => computeAllClosures(componentGraph), [componentGraph]);
|
|
23972
24062
|
useEffect13(() => {
|
|
23973
24063
|
if (seededGroupsRef.current) return;
|
|
23974
24064
|
if (closures.size === 0 && slotCycles.length === 0) return;
|
|
@@ -23977,14 +24067,14 @@ function GenerateReviewStep({
|
|
|
23977
24067
|
for (const cyc of slotCycles) for (const p of cyc.path) seed.add(p);
|
|
23978
24068
|
setExpandedGroups(seed);
|
|
23979
24069
|
}, [closures, slotCycles]);
|
|
23980
|
-
const directIssues =
|
|
24070
|
+
const directIssues = useMemo7(() => {
|
|
23981
24071
|
const m = /* @__PURE__ */ new Map();
|
|
23982
24072
|
for (const c2 of components) {
|
|
23983
24073
|
if (c2.status === "rejected") m.set(c2.key, "error");
|
|
23984
24074
|
}
|
|
23985
24075
|
return m;
|
|
23986
24076
|
}, [components]);
|
|
23987
|
-
const cycleView =
|
|
24077
|
+
const cycleView = useMemo7(() => computeCycleView(components), [components]);
|
|
23988
24078
|
useEffect13(() => {
|
|
23989
24079
|
const decision = computeAutoRejectDecision({
|
|
23990
24080
|
loading,
|
|
@@ -24094,7 +24184,7 @@ function GenerateReviewStep({
|
|
|
24094
24184
|
setLoadError(String(e));
|
|
24095
24185
|
}
|
|
24096
24186
|
};
|
|
24097
|
-
const groupedItemsMemo =
|
|
24187
|
+
const groupedItemsMemo = useMemo7(
|
|
24098
24188
|
() => components.map((c2) => ({
|
|
24099
24189
|
key: c2.key,
|
|
24100
24190
|
entry: c2.entry,
|
|
@@ -24102,12 +24192,12 @@ function GenerateReviewStep({
|
|
|
24102
24192
|
})),
|
|
24103
24193
|
[components, directIssues]
|
|
24104
24194
|
);
|
|
24105
|
-
const brokenKeys =
|
|
24195
|
+
const brokenKeys = useMemo7(
|
|
24106
24196
|
() => new Set(breakingChanges.map((b) => b.componentName)),
|
|
24107
24197
|
[breakingChanges]
|
|
24108
24198
|
);
|
|
24109
|
-
const breakingRows =
|
|
24110
|
-
const filterVisibleKeys =
|
|
24199
|
+
const breakingRows = useMemo7(() => buildBreakingRows(breakingChanges), [breakingChanges]);
|
|
24200
|
+
const filterVisibleKeys = useMemo7(() => {
|
|
24111
24201
|
if (jumpFilterTarget) {
|
|
24112
24202
|
return findAllAncestors2(jumpFilterTarget, sidebarGraph);
|
|
24113
24203
|
}
|
|
@@ -24123,7 +24213,7 @@ function GenerateReviewStep({
|
|
|
24123
24213
|
})();
|
|
24124
24214
|
return intersectFilterKeys(categoryKeys, searchKeys);
|
|
24125
24215
|
}, [jumpFilterTarget, activeFilters, cycleView, brokenKeys, searchQuery, groupedItemsMemo, sidebarGraph]);
|
|
24126
|
-
const visibleRowsMemo =
|
|
24216
|
+
const visibleRowsMemo = useMemo7(
|
|
24127
24217
|
() => buildVisibleRows({
|
|
24128
24218
|
items: groupedItemsMemo,
|
|
24129
24219
|
cycleParticipants: cycleView.structural,
|
|
@@ -24134,7 +24224,7 @@ function GenerateReviewStep({
|
|
|
24134
24224
|
}),
|
|
24135
24225
|
[groupedItemsMemo, cycleView, expandedGroups, columnOneView, sidebarGraph, filterVisibleKeys]
|
|
24136
24226
|
);
|
|
24137
|
-
const selectableRowPositions =
|
|
24227
|
+
const selectableRowPositions = useMemo7(() => {
|
|
24138
24228
|
const out = [];
|
|
24139
24229
|
for (let i = 0; i < visibleRowsMemo.length; i++) {
|
|
24140
24230
|
if (visibleRowsMemo[i].itemIdx >= 0) out.push(i);
|
|
@@ -24191,7 +24281,7 @@ function GenerateReviewStep({
|
|
|
24191
24281
|
db.close();
|
|
24192
24282
|
}
|
|
24193
24283
|
}, [selectedIdx, components, extractSessionId]);
|
|
24194
|
-
const renderStatusByKey =
|
|
24284
|
+
const renderStatusByKey = useMemo7(() => {
|
|
24195
24285
|
const merged = /* @__PURE__ */ new Map();
|
|
24196
24286
|
for (const closure of closures.values()) {
|
|
24197
24287
|
const per = computeRenderStatuses(closure, directIssues);
|
|
@@ -24204,7 +24294,7 @@ function GenerateReviewStep({
|
|
|
24204
24294
|
}
|
|
24205
24295
|
return merged;
|
|
24206
24296
|
}, [closures, directIssues]);
|
|
24207
|
-
const selectionStateByKey =
|
|
24297
|
+
const selectionStateByKey = useMemo7(() => {
|
|
24208
24298
|
const map = /* @__PURE__ */ new Map();
|
|
24209
24299
|
for (const c2 of components) {
|
|
24210
24300
|
if (c2.status === "accepted") map.set(c2.key, "accepted");
|
|
@@ -24213,7 +24303,7 @@ function GenerateReviewStep({
|
|
|
24213
24303
|
}
|
|
24214
24304
|
return map;
|
|
24215
24305
|
}, [components]);
|
|
24216
|
-
const searchMatches =
|
|
24306
|
+
const searchMatches = useMemo7(() => {
|
|
24217
24307
|
if (!searchQuery) return [];
|
|
24218
24308
|
const out = [];
|
|
24219
24309
|
for (const pos of selectableRowPositions) {
|
|
@@ -24223,7 +24313,7 @@ function GenerateReviewStep({
|
|
|
24223
24313
|
}
|
|
24224
24314
|
return out;
|
|
24225
24315
|
}, [searchQuery, selectableRowPositions, visibleRowsMemo, components]);
|
|
24226
|
-
const searchMatchCount =
|
|
24316
|
+
const searchMatchCount = useMemo7(() => {
|
|
24227
24317
|
if (searchMatches.length === 0) return 0;
|
|
24228
24318
|
const seen = /* @__PURE__ */ new Set();
|
|
24229
24319
|
for (const pos of searchMatches) {
|
|
@@ -24232,7 +24322,7 @@ function GenerateReviewStep({
|
|
|
24232
24322
|
}
|
|
24233
24323
|
return seen.size;
|
|
24234
24324
|
}, [searchMatches, visibleRowsMemo]);
|
|
24235
|
-
const dimPredicate =
|
|
24325
|
+
const dimPredicate = useMemo7(
|
|
24236
24326
|
() => buildFlatDimPredicate({
|
|
24237
24327
|
viewMode: columnOneView,
|
|
24238
24328
|
searchQuery,
|
|
@@ -24300,7 +24390,7 @@ function GenerateReviewStep({
|
|
|
24300
24390
|
setDraftValue("");
|
|
24301
24391
|
setSaveError(null);
|
|
24302
24392
|
};
|
|
24303
|
-
const breakEdges =
|
|
24393
|
+
const breakEdges = useMemo7(() => {
|
|
24304
24394
|
const cycle = slotCycles[cyclesCursor];
|
|
24305
24395
|
if (!cycle) return [];
|
|
24306
24396
|
return enumerateCycleBreaks(cycle, components);
|
|
@@ -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.2-dev-build-
|
|
3
|
+
"version": "2.27.2-dev-build-d9f331e.0",
|
|
4
4
|
"description": "Contentful Experiences design system import CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
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.2-dev-build-
|
|
42
|
+
"@contentful/experience-design-system-types": "2.27.2-dev-build-d9f331e.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-
|
|
55
|
-
"@contentful/experience-design-system-generation": "2.27.2-dev-build-
|
|
56
|
-
"@contentful/experience-design-system-
|
|
54
|
+
"@contentful/experience-design-system-extraction": "2.27.2-dev-build-d9f331e.0",
|
|
55
|
+
"@contentful/experience-design-system-generation": "2.27.2-dev-build-d9f331e.0",
|
|
56
|
+
"@contentful/experience-design-system-client": "2.27.2-dev-build-d9f331e.0"
|
|
57
57
|
},
|
|
58
58
|
"repository": {
|
|
59
59
|
"type": "git",
|