@contentful/experience-design-system-cli 2.12.4-dev-build-ff57340.0 → 2.13.1-dev-build-fa478b3.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 +3 -6
- package/dist/src/analyze/command.js +2 -22
- package/dist/src/analyze/select/command.js +1 -1
- package/dist/src/analyze/select/tui/components/FieldEditor.d.ts +1 -24
- package/dist/src/analyze/select/tui/components/FieldEditor.js +10 -137
- package/dist/src/analyze/select-agent/command.js +1 -1
- package/dist/src/apply/command.d.ts +1 -34
- package/dist/src/apply/command.js +0 -81
- package/dist/src/import/tui/WizardApp.js +10 -59
- package/dist/src/import/tui/steps/GenerateReviewStep.d.ts +1 -1
- package/dist/src/import/tui/steps/GenerateReviewStep.js +23 -213
- package/dist/src/import/tui/steps/WizardPreviewStep.d.ts +0 -10
- package/dist/src/import/tui/steps/WizardPreviewStep.js +51 -95
- package/dist/src/import/tui/steps/preview-diff.js +0 -48
- package/dist/src/session/db.d.ts +0 -9
- package/dist/src/session/db.js +0 -46
- package/dist/src/types.d.ts +2 -76
- package/dist/src/types.js +1 -4
- package/package.json +3 -6
- package/dist/src/analyze/cycle-detection.d.ts +0 -93
- package/dist/src/analyze/cycle-detection.js +0 -326
- package/dist/src/analyze/extract/astro.d.ts +0 -5
- package/dist/src/analyze/extract/astro.js +0 -289
- package/dist/src/analyze/extract/non-authorable-filter.d.ts +0 -16
- package/dist/src/analyze/extract/non-authorable-filter.js +0 -60
- package/dist/src/analyze/extract/pipeline.d.ts +0 -6
- package/dist/src/analyze/extract/pipeline.js +0 -314
- package/dist/src/analyze/extract/react.d.ts +0 -2
- package/dist/src/analyze/extract/react.js +0 -2041
- package/dist/src/analyze/extract/scoring.d.ts +0 -12
- package/dist/src/analyze/extract/scoring.js +0 -108
- package/dist/src/analyze/extract/slot-allowed-components.d.ts +0 -8
- package/dist/src/analyze/extract/slot-allowed-components.js +0 -40
- package/dist/src/analyze/extract/slot-detection.d.ts +0 -35
- package/dist/src/analyze/extract/slot-detection.js +0 -101
- package/dist/src/analyze/extract/source-inspection.d.ts +0 -13
- package/dist/src/analyze/extract/source-inspection.js +0 -189
- package/dist/src/analyze/extract/stencil.d.ts +0 -2
- package/dist/src/analyze/extract/stencil.js +0 -296
- package/dist/src/analyze/extract/svelte.d.ts +0 -5
- package/dist/src/analyze/extract/svelte.js +0 -1626
- package/dist/src/analyze/extract/tsx-shared.d.ts +0 -8
- package/dist/src/analyze/extract/tsx-shared.js +0 -263
- package/dist/src/analyze/extract/validate.d.ts +0 -16
- package/dist/src/analyze/extract/validate.js +0 -94
- package/dist/src/analyze/extract/vue-tsx.d.ts +0 -2
- package/dist/src/analyze/extract/vue-tsx.js +0 -498
- package/dist/src/analyze/extract/vue.d.ts +0 -5
- package/dist/src/analyze/extract/vue.js +0 -653
- package/dist/src/analyze/extract/web-components.d.ts +0 -2
- package/dist/src/analyze/extract/web-components.js +0 -876
- package/dist/src/analyze/pre-classify.d.ts +0 -17
- package/dist/src/analyze/pre-classify.js +0 -211
- package/dist/src/apply/error-parser.d.ts +0 -43
- package/dist/src/apply/error-parser.js +0 -163
|
@@ -8,8 +8,7 @@ import { StatusBar } from '../../../analyze/select/tui/components/StatusBar.js';
|
|
|
8
8
|
import { FinalizeDialog } from '../../../analyze/select/tui/components/FinalizeDialog.js';
|
|
9
9
|
import { QuitDialog } from '../../../analyze/select/tui/components/QuitDialog.js';
|
|
10
10
|
import { useImmediateInput } from '../../../analyze/select/tui/hooks/useImmediateInput.js';
|
|
11
|
-
import { openPipelineDb, loadCDFComponents, storeCDFComponents, loadComponentReviewMetadata, loadComponentRationale,
|
|
12
|
-
import { formatCyclePathSegments, findSlotCycles, suggestCycleBreakEdge } from '../../../analyze/cycle-detection.js';
|
|
11
|
+
import { openPipelineDb, loadCDFComponents, storeCDFComponents, loadComponentReviewMetadata, loadComponentRationale, } from '../../../session/db.js';
|
|
13
12
|
import { RationalePanel } from '../../../analyze/select/tui/components/RationalePanel.js';
|
|
14
13
|
import { ComponentRationalePanel } from '../../../analyze/select/tui/components/ComponentRationalePanel.js';
|
|
15
14
|
import { applyPreviewAnnotations } from '../../../analyze/select/preview-annotations.js';
|
|
@@ -25,22 +24,12 @@ import { computeNextScrollOffset } from '../../../analyze/select/tui/hooks/scrol
|
|
|
25
24
|
*
|
|
26
25
|
* Within each tier (empty / non-empty) we tie-break alphabetically by `key`.
|
|
27
26
|
*/
|
|
28
|
-
export function sortComponentsForSidebar(components
|
|
29
|
-
const isEmpty = (entry) => Object.keys(entry.$properties ?? {}).length === 0 && Object.keys(entry.$slots ?? {}).length === 0;
|
|
30
|
-
// Tier order: cycle members first (they block push — surface loudest),
|
|
31
|
-
// then empty (soft warning), then everything else. Ties broken alpha.
|
|
32
|
-
const tier = (c) => {
|
|
33
|
-
if (cycleParticipants?.has(c.key))
|
|
34
|
-
return 0;
|
|
35
|
-
if (isEmpty(c.entry))
|
|
36
|
-
return 1;
|
|
37
|
-
return 2;
|
|
38
|
-
};
|
|
27
|
+
export function sortComponentsForSidebar(components) {
|
|
39
28
|
return [...components].sort((a, b) => {
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
if (
|
|
43
|
-
return
|
|
29
|
+
const aEmpty = Object.keys(a.entry.$properties ?? {}).length === 0;
|
|
30
|
+
const bEmpty = Object.keys(b.entry.$properties ?? {}).length === 0;
|
|
31
|
+
if (aEmpty !== bEmpty)
|
|
32
|
+
return aEmpty ? -1 : 1;
|
|
44
33
|
return a.key.localeCompare(b.key);
|
|
45
34
|
});
|
|
46
35
|
}
|
|
@@ -86,12 +75,6 @@ export function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, liveP
|
|
|
86
75
|
// Tracks the first `g` of a potential `gg` double-tap (jumps to top in
|
|
87
76
|
// JSON-view + panel-focused state). Reset on any non-`g` key.
|
|
88
77
|
const pendingGRef = useRef(false);
|
|
89
|
-
// INTEG-4401: slot-dependency cycles loaded from the session DB. Non-empty
|
|
90
|
-
// triggers sidebar (cycle) badges, banner + [c] detail-panel affordance,
|
|
91
|
-
// and (at push time) a hard block.
|
|
92
|
-
const [slotCycles, setSlotCycles] = useState([]);
|
|
93
|
-
const [showCyclePanel, setShowCyclePanel] = useState(false);
|
|
94
|
-
const [cyclePanelScroll, setCyclePanelScroll] = useState(0);
|
|
95
78
|
const handleLivePreviewResult = (response) => {
|
|
96
79
|
if (!response)
|
|
97
80
|
return;
|
|
@@ -123,10 +106,8 @@ export function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, liveP
|
|
|
123
106
|
async function load() {
|
|
124
107
|
const db = openPipelineDb();
|
|
125
108
|
let cdfComponents;
|
|
126
|
-
let cycles = [];
|
|
127
109
|
try {
|
|
128
110
|
cdfComponents = loadCDFComponents(db, extractSessionId);
|
|
129
|
-
cycles = loadSlotCycles(db, extractSessionId);
|
|
130
111
|
}
|
|
131
112
|
finally {
|
|
132
113
|
db.close();
|
|
@@ -141,12 +122,7 @@ export function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, liveP
|
|
|
141
122
|
entry,
|
|
142
123
|
status: 'needs-review',
|
|
143
124
|
}));
|
|
144
|
-
|
|
145
|
-
for (const c of cycles)
|
|
146
|
-
for (const p of c.path)
|
|
147
|
-
cycleParticipants.add(p);
|
|
148
|
-
setSlotCycles(cycles);
|
|
149
|
-
setComponents(sortComponentsForSidebar(reviewEntries, cycleParticipants));
|
|
125
|
+
setComponents(sortComponentsForSidebar(reviewEntries));
|
|
150
126
|
setLoading(false);
|
|
151
127
|
}
|
|
152
128
|
load().catch((e) => {
|
|
@@ -253,66 +229,6 @@ export function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, liveP
|
|
|
253
229
|
}
|
|
254
230
|
onFinalize(acceptedCount, explicitlyRejected.length, unresolved.length);
|
|
255
231
|
};
|
|
256
|
-
/**
|
|
257
|
-
* INTEG-4401 (Fix 3/4): re-run cycle detection against the current in-memory
|
|
258
|
-
* component state and, if the result differs from the persisted `slotCycles`
|
|
259
|
-
* state, update both React state and the session DB. Called from:
|
|
260
|
-
* - `handleEditSave` after a FieldEditor save mutates a slot's
|
|
261
|
-
* `$allowedComponents`, so the banner / sidebar badges / [c] panel reflect
|
|
262
|
-
* reality instead of the stale extract-time snapshot.
|
|
263
|
-
* - The `r` reject keystroke, since dropping a component from the manifest
|
|
264
|
-
* can collapse cycles that routed through it.
|
|
265
|
-
*
|
|
266
|
-
* Rejected components are excluded from the graph — they will never ship, so
|
|
267
|
-
* they cannot contribute to a real push-time cycle even if their slot config
|
|
268
|
-
* still references other components locally.
|
|
269
|
-
*
|
|
270
|
-
* Cheap for typical N: findSlotCycles is O((V+E)(C+1)) and most manifests
|
|
271
|
-
* have zero or a handful of cycles. Wrapped in try/catch so a malformed
|
|
272
|
-
* $slots shape can't crash the render pipeline.
|
|
273
|
-
*/
|
|
274
|
-
const recomputeCycles = (currentComponents) => {
|
|
275
|
-
try {
|
|
276
|
-
const graph = currentComponents
|
|
277
|
-
.filter((c) => c.status !== 'rejected')
|
|
278
|
-
.map((c) => ({
|
|
279
|
-
name: c.key,
|
|
280
|
-
slots: Object.entries(c.entry.$slots ?? {}).map(([slotName, slotDef]) => ({
|
|
281
|
-
name: slotName,
|
|
282
|
-
allowedComponents: Array.isArray(slotDef?.$allowedComponents)
|
|
283
|
-
? slotDef.$allowedComponents.filter((v) => typeof v === 'string')
|
|
284
|
-
: [],
|
|
285
|
-
})),
|
|
286
|
-
}));
|
|
287
|
-
const rawCycles = findSlotCycles(graph);
|
|
288
|
-
const next = rawCycles.map((cycle) => ({
|
|
289
|
-
path: cycle.path,
|
|
290
|
-
edges: cycle.edges,
|
|
291
|
-
suggestedBreak: cycle.edges.length > 0 ? suggestCycleBreakEdge(cycle, rawCycles) : null,
|
|
292
|
-
}));
|
|
293
|
-
// Cheap structural equality via JSON.stringify — cycle count is tiny and
|
|
294
|
-
// this only fires on user actions, not on every render.
|
|
295
|
-
const prevSerialized = JSON.stringify(slotCycles);
|
|
296
|
-
const nextSerialized = JSON.stringify(next);
|
|
297
|
-
if (prevSerialized === nextSerialized)
|
|
298
|
-
return;
|
|
299
|
-
setSlotCycles(next);
|
|
300
|
-
const db = openPipelineDb();
|
|
301
|
-
try {
|
|
302
|
-
storeSlotCycles(db, extractSessionId, next);
|
|
303
|
-
}
|
|
304
|
-
finally {
|
|
305
|
-
db.close();
|
|
306
|
-
}
|
|
307
|
-
// If the new cycle set is empty, clear any lingering finalize error the
|
|
308
|
-
// [F] guard may have surfaced. Otherwise leave it alone.
|
|
309
|
-
if (next.length === 0)
|
|
310
|
-
setFinalizeError(null);
|
|
311
|
-
}
|
|
312
|
-
catch {
|
|
313
|
-
// Defensive: swallow — never let cycle detection crash the review UI.
|
|
314
|
-
}
|
|
315
|
-
};
|
|
316
232
|
const handleEditSave = () => {
|
|
317
233
|
const current = components[selectedIdx];
|
|
318
234
|
if (!current)
|
|
@@ -328,11 +244,7 @@ export function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, liveP
|
|
|
328
244
|
setSaveError('Invalid CDF entry: must have $type: "component" and $properties object');
|
|
329
245
|
return;
|
|
330
246
|
}
|
|
331
|
-
|
|
332
|
-
setComponents((prev) => {
|
|
333
|
-
updatedComponents = prev.map((c, i) => i === selectedIdx ? { ...c, entry, status: c.status === 'needs-review' ? 'accepted' : c.status } : c);
|
|
334
|
-
return updatedComponents;
|
|
335
|
-
});
|
|
247
|
+
setComponents((prev) => prev.map((c, i) => i === selectedIdx ? { ...c, entry, status: c.status === 'needs-review' ? 'accepted' : c.status } : c));
|
|
336
248
|
setDraftValue('');
|
|
337
249
|
setSaveError(null);
|
|
338
250
|
const db = openPipelineDb();
|
|
@@ -342,12 +254,6 @@ export function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, liveP
|
|
|
342
254
|
finally {
|
|
343
255
|
db.close();
|
|
344
256
|
}
|
|
345
|
-
// INTEG-4401 (Fix 3/4): recompute cycles against the freshly-edited
|
|
346
|
-
// component set so banner/badges/[c]-panel stay in sync. The FieldEditor
|
|
347
|
-
// picker filters cycle-forming candidates, but free-text edits + JSON
|
|
348
|
-
// pastes still slip through, and edits that BREAK an existing cycle
|
|
349
|
-
// won't propagate without this call.
|
|
350
|
-
recomputeCycles(updatedComponents);
|
|
351
257
|
// Feature 2: re-fire the live preview now that pipeline.db reflects
|
|
352
258
|
// the new state. The hook owns debounce + cred-missing short-circuit.
|
|
353
259
|
livePreviewHook.trigger();
|
|
@@ -376,31 +282,6 @@ export function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, liveP
|
|
|
376
282
|
}
|
|
377
283
|
return;
|
|
378
284
|
}
|
|
379
|
-
// INTEG-4401: slot-cycle detail panel. Same modal-swallow rules as
|
|
380
|
-
// showRemovedPanel; q/Esc close, ↑↓ scroll.
|
|
381
|
-
if (showCyclePanel) {
|
|
382
|
-
if (input === 'c' || input === 'q' || key.escape) {
|
|
383
|
-
setShowCyclePanel(false);
|
|
384
|
-
setCyclePanelScroll(0);
|
|
385
|
-
return;
|
|
386
|
-
}
|
|
387
|
-
if (key.upArrow || input === 'k') {
|
|
388
|
-
setCyclePanelScroll((v) => Math.max(0, v - 1));
|
|
389
|
-
return;
|
|
390
|
-
}
|
|
391
|
-
if (key.downArrow || input === 'j') {
|
|
392
|
-
setCyclePanelScroll((v) => v + 1);
|
|
393
|
-
return;
|
|
394
|
-
}
|
|
395
|
-
return;
|
|
396
|
-
}
|
|
397
|
-
// Open the cycle panel from sidebar-focused state when there is at
|
|
398
|
-
// least one cycle to display.
|
|
399
|
-
if (input === 'c' && sidebarFocused && slotCycles.length > 0) {
|
|
400
|
-
setShowCyclePanel(true);
|
|
401
|
-
setCyclePanelScroll(0);
|
|
402
|
-
return;
|
|
403
|
-
}
|
|
404
285
|
// `d` opens the panel only when live-preview is enabled and there is at
|
|
405
286
|
// least one removed component to display. Sidebar-focused only so it
|
|
406
287
|
// doesn't collide with FieldEditor input.
|
|
@@ -530,14 +411,6 @@ export function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, liveP
|
|
|
530
411
|
return;
|
|
531
412
|
}
|
|
532
413
|
if (input === 'F') {
|
|
533
|
-
// INTEG-4401: refuse to open the finalize dialog while any slot cycle
|
|
534
|
-
// is unresolved. The push-time hard block (`assertNoSlotCycles`) would
|
|
535
|
-
// catch this downstream, but showing an inline banner here saves the
|
|
536
|
-
// operator from confirming the dialog only to hit a stderr crash.
|
|
537
|
-
if (slotCycles.length > 0) {
|
|
538
|
-
setFinalizeError('Cannot finalize — resolve slot dependency cycle(s) first (press [c] for detail)');
|
|
539
|
-
return;
|
|
540
|
-
}
|
|
541
414
|
setShowFinalize(true);
|
|
542
415
|
return;
|
|
543
416
|
}
|
|
@@ -547,14 +420,7 @@ export function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, liveP
|
|
|
547
420
|
return;
|
|
548
421
|
}
|
|
549
422
|
if (input === 'r') {
|
|
550
|
-
|
|
551
|
-
// manifest, so recompute cycles across the reduced graph — any cycle
|
|
552
|
-
// that routed through this component collapses. We build the "next"
|
|
553
|
-
// components array inline (mirroring updateStatus) so recomputeCycles
|
|
554
|
-
// sees the post-update graph without waiting for a render tick.
|
|
555
|
-
const next = components.map((c, i) => i === selectedIdx ? { ...c, status: 'rejected' } : c);
|
|
556
|
-
setComponents(next);
|
|
557
|
-
recomputeCycles(next);
|
|
423
|
+
updateStatus(selectedIdx, 'rejected');
|
|
558
424
|
return;
|
|
559
425
|
}
|
|
560
426
|
if (input === 'A') {
|
|
@@ -607,89 +473,37 @@ export function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, liveP
|
|
|
607
473
|
}
|
|
608
474
|
const selected = components[selectedIdx] ?? null;
|
|
609
475
|
const selectedJson = selected ? JSON.stringify({ [selected.key]: selected.entry }, null, 2) : '';
|
|
610
|
-
|
|
476
|
+
// A component with zero classified $properties is a real defensibility issue —
|
|
477
|
+
// it can't be pushed to Contentful (no fields). Surface it in the sidebar via
|
|
478
|
+
// the existing warning-color path (yellow) and a "(empty)" suffix so the user
|
|
479
|
+
// can see what went wrong. They can manually add props in FieldEditor or
|
|
480
|
+
// explicitly reject the component.
|
|
481
|
+
const isEmpty = (c) => Object.keys(c.entry.$properties).length === 0;
|
|
611
482
|
const emptyCount = components.filter(isEmpty).length;
|
|
612
|
-
// INTEG-4401: cycle-participant set drives sidebar `(cycle)` badges plus
|
|
613
|
-
// the banner counts. Recomputed on every render — cheap for typical N.
|
|
614
|
-
const cycleParticipantSet = new Set();
|
|
615
|
-
for (const cycle of slotCycles)
|
|
616
|
-
for (const p of cycle.path)
|
|
617
|
-
cycleParticipantSet.add(p);
|
|
618
|
-
const sidebarSuffix = (c) => {
|
|
619
|
-
if (cycleParticipantSet.has(c.key))
|
|
620
|
-
return ' (cycle)';
|
|
621
|
-
if (isEmpty(c))
|
|
622
|
-
return ' (empty)';
|
|
623
|
-
return '';
|
|
624
|
-
};
|
|
625
483
|
const sidebarItems = components.map((c) => ({
|
|
626
484
|
id: c.key,
|
|
627
|
-
name: `${c.key}
|
|
485
|
+
name: isEmpty(c) ? `${c.key} (empty)` : c.key,
|
|
628
486
|
status: c.status,
|
|
629
487
|
previewAnnotation: previewAnnotations.get(c.key),
|
|
630
488
|
extractionConfidence: null,
|
|
631
489
|
needsReview: false,
|
|
632
490
|
validationErrorCount: 0,
|
|
633
|
-
validationWarningCount:
|
|
491
|
+
validationWarningCount: isEmpty(c) ? 1 : 0,
|
|
634
492
|
}));
|
|
635
|
-
// Account for the "(
|
|
636
|
-
//
|
|
637
|
-
const longestName = components.reduce((m, c) => Math.max(m, c.key.length +
|
|
493
|
+
// Account for the "(empty)" suffix added to zero-prop component names so the
|
|
494
|
+
// sidebar doesn't truncate it.
|
|
495
|
+
const longestName = components.reduce((m, c) => Math.max(m, c.key.length + (isEmpty(c) ? ' (empty)'.length : 0)), 0);
|
|
638
496
|
// +5 = border (1) + status icon (1) + badge column (1) + space (1) + border (1).
|
|
639
497
|
// The badge column is reserved even when no annotation is present so the
|
|
640
498
|
// sidebar width doesn't jitter as live-preview annotations flip in/out.
|
|
641
499
|
const sidebarWidth = Math.min(Math.max(longestName + 5, 14), 30);
|
|
642
500
|
const panelWidth = Math.max(10, terminalWidth - sidebarWidth - 4);
|
|
643
|
-
// INTEG-4401: project-wide slot graph passed to FieldEditor so its
|
|
644
|
-
// $allowedComponents picker can filter out cycle-forming candidates. Built
|
|
645
|
-
// from every review entry's $slots — includes accepted, rejected, and
|
|
646
|
-
// needs-review components so the graph reflects what will actually be
|
|
647
|
-
// pushed. The FieldEditor replaces its own entry in-simulation with its
|
|
648
|
-
// live editor state, so pending edits are always reflected.
|
|
649
|
-
const projectSlotGraph = components.map((c) => ({
|
|
650
|
-
name: c.key,
|
|
651
|
-
slots: Object.entries(c.entry.$slots ?? {}).map(([slotName, slotDef]) => ({
|
|
652
|
-
name: slotName,
|
|
653
|
-
allowedComponents: Array.isArray(slotDef?.$allowedComponents)
|
|
654
|
-
? slotDef.$allowedComponents.filter((v) => typeof v === 'string')
|
|
655
|
-
: [],
|
|
656
|
-
})),
|
|
657
|
-
}));
|
|
658
501
|
const accepted = components.filter((c) => c.status === 'accepted').length;
|
|
659
502
|
const rejected = components.filter((c) => c.status === 'rejected').length;
|
|
660
503
|
const needsReview = components.filter((c) => c.status === 'needs-review').length;
|
|
661
504
|
const propCount = selected ? Object.keys(selected.entry.$properties).length : 0;
|
|
662
505
|
const slotCount = selected?.entry.$slots ? Object.keys(selected.entry.$slots).length : 0;
|
|
663
|
-
return (_jsxs(Box, { flexDirection: "column", children: [showFinalize && (_jsx(FinalizeDialog, { accepted: accepted, rejected: rejected, needsReview: needsReview, onConfirm: handleFinalizeConfirm, onCancel: () => setShowFinalize(false) })), showQuit && _jsx(QuitDialog, { hasUnsavedDrafts: false, onConfirm: onQuit, onCancel: () => setShowQuit(false) }), showRemovedPanel && !dialogOpen && (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: `Removed components (${removedComponents.length})` }), _jsx(Text, { dimColor: true, children: "these will be DELETED from the target space" }), _jsx(Text, { children: " " }), removedComponents.map((rc) => (_jsx(Text, { children: `- ${rc.name}${rc.id ? ` (${rc.id})` : ''}` }, rc.id))), _jsx(Text, { children: " " }), _jsx(Text, { dimColor: true, children: "press d or Esc to close" })] })),
|
|
664
|
-
!dialogOpen &&
|
|
665
|
-
(() => {
|
|
666
|
-
// Materialize the full panel body as a flat list of Text lines,
|
|
667
|
-
// then slice by cyclePanelScroll so ↑↓ can walk arbitrarily long
|
|
668
|
-
// content. Each cycle contributes 3-4 lines: heading, path,
|
|
669
|
-
// suggested fix (if any), and a blank separator.
|
|
670
|
-
const PANEL_H = 20;
|
|
671
|
-
const lines = [];
|
|
672
|
-
lines.push(_jsx(Text, { bold: true, color: "yellow", children: `SLOT DEPENDENCY CYCLES (${slotCycles.length})` }, "cyc-title"));
|
|
673
|
-
lines.push(_jsx(Text, { dimColor: true, children: 'push will fail until these are resolved' }, "cyc-sub"));
|
|
674
|
-
lines.push(_jsx(Text, { children: " " }, "cyc-space"));
|
|
675
|
-
slotCycles.forEach((cycle, idx) => {
|
|
676
|
-
const nodeCount = new Set(cycle.path).size;
|
|
677
|
-
lines.push(_jsx(Text, { bold: true, children: `▸ Cycle ${idx + 1} (${nodeCount} component${nodeCount === 1 ? '' : 's'}):` }, `cyc-h-${idx}`));
|
|
678
|
-
// Colorize slots (cyan, bracketed) distinctly from components so
|
|
679
|
-
// the operator can visually parse the alternating structure.
|
|
680
|
-
// Brackets on slot names ensure the distinction survives when
|
|
681
|
-
// ANSI is stripped (logs, redirected output).
|
|
682
|
-
const segs = formatCyclePathSegments(cycle, 16);
|
|
683
|
-
lines.push(_jsxs(Text, { children: [' ', segs.map((seg, si) => seg.kind === 'slot' ? (_jsx(Text, { color: "cyan", children: seg.text }, si)) : seg.kind === 'arrow' ? (_jsx(Text, { dimColor: true, children: seg.text }, si)) : (_jsx(Text, { children: seg.text }, si)))] }, `cyc-p-${idx}`));
|
|
684
|
-
if (cycle.suggestedBreak) {
|
|
685
|
-
const b = cycle.suggestedBreak;
|
|
686
|
-
lines.push(_jsx(Text, { dimColor: true, children: ` Suggested fix: remove '${b.toComponent}' from ${b.fromComponent}.$slots.${b.slotName}.$allowedComponents` }, `cyc-f-${idx}`));
|
|
687
|
-
}
|
|
688
|
-
lines.push(_jsx(Text, { children: " " }, `cyc-s-${idx}`));
|
|
689
|
-
});
|
|
690
|
-
const visible = lines.slice(cyclePanelScroll, cyclePanelScroll + PANEL_H);
|
|
691
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [visible, _jsx(Text, { dimColor: true, children: '[↑↓/j/k] scroll [c/q/Esc] close' })] }));
|
|
692
|
-
})(), !dialogOpen &&
|
|
506
|
+
return (_jsxs(Box, { flexDirection: "column", children: [showFinalize && (_jsx(FinalizeDialog, { accepted: accepted, rejected: rejected, needsReview: needsReview, onConfirm: handleFinalizeConfirm, onCancel: () => setShowFinalize(false) })), showQuit && _jsx(QuitDialog, { hasUnsavedDrafts: false, onConfirm: onQuit, onCancel: () => setShowQuit(false) }), showRemovedPanel && !dialogOpen && (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: `Removed components (${removedComponents.length})` }), _jsx(Text, { dimColor: true, children: "these will be DELETED from the target space" }), _jsx(Text, { children: " " }), removedComponents.map((rc) => (_jsx(Text, { children: `- ${rc.name}${rc.id ? ` (${rc.id})` : ''}` }, rc.id))), _jsx(Text, { children: " " }), _jsx(Text, { dimColor: true, children: "press d or Esc to close" })] })), !dialogOpen &&
|
|
693
507
|
livePreview &&
|
|
694
508
|
(() => {
|
|
695
509
|
// Pilot-2026-06-23 R2: at-a-glance diff summary at the top of the
|
|
@@ -712,10 +526,7 @@ export function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, liveP
|
|
|
712
526
|
if (!hasCounts)
|
|
713
527
|
return null;
|
|
714
528
|
return (_jsxs(Box, { children: [_jsx(Text, { children: 'Preview: ' }), _jsx(Text, { color: "green", children: `${counts.new} new` }), _jsx(Text, { children: ' · ' }), _jsx(Text, { color: "yellow", children: `${counts.changed} changed` }), _jsx(Text, { children: ' · ' }), _jsx(Text, { dimColor: true, children: `${counts.removed} removed` }), removedComponents.length > 0 && _jsx(Text, { dimColor: true, children: ' ([d] removed list)' }), _jsx(Text, { children: ' · ' }), _jsx(Text, { color: "red", bold: true, children: `${counts.breaking} breaking` })] }));
|
|
715
|
-
})(), !dialogOpen &&
|
|
716
|
-
const segs = formatCyclePathSegments(cycle);
|
|
717
|
-
return (_jsxs(Text, { color: "yellow", children: [' Cycle: ', segs.map((seg, si) => seg.kind === 'slot' ? (_jsx(Text, { color: "cyan", children: seg.text }, si)) : seg.kind === 'arrow' ? (_jsx(Text, { dimColor: true, children: seg.text }, si)) : (_jsx(Text, { color: "yellow", children: seg.text }, si)))] }, `cyc-banner-${idx}`));
|
|
718
|
-
}), slotCycles.length > 3 && _jsx(Text, { color: "yellow", children: ` …${slotCycles.length - 3} more` }), _jsx(Text, { dimColor: true, children: ' press [c] for detail' })] })), !dialogOpen && emptyCount > 0 && (_jsx(Text, { color: "yellow", children: `⚠ ${emptyCount} component${emptyCount === 1 ? '' : 's'} had no classifiable props — review with care` })), !dialogOpen && finalizeError && _jsx(Text, { color: "red", children: `⚠ ${finalizeError}` }), !dialogOpen && (_jsxs(Box, { children: [_jsx(Sidebar, { components: sidebarItems, selectedId: selected?.key ?? null, focused: sidebarFocused, scrollOffset: sidebarScrollOffset, visibleCount: VISIBLE_COUNT, onSelect: (id) => {
|
|
529
|
+
})(), !dialogOpen && emptyCount > 0 && (_jsx(Text, { color: "yellow", children: `⚠ ${emptyCount} component${emptyCount === 1 ? '' : 's'} had no classifiable props — review with care` })), !dialogOpen && finalizeError && _jsx(Text, { color: "red", children: `⚠ ${finalizeError}` }), !dialogOpen && (_jsxs(Box, { children: [_jsx(Sidebar, { components: sidebarItems, selectedId: selected?.key ?? null, focused: sidebarFocused, scrollOffset: sidebarScrollOffset, visibleCount: VISIBLE_COUNT, onSelect: (id) => {
|
|
719
530
|
const idx = components.findIndex((c) => c.key === id);
|
|
720
531
|
if (idx >= 0) {
|
|
721
532
|
setSelectedIdx(idx);
|
|
@@ -764,12 +575,11 @@ export function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, liveP
|
|
|
764
575
|
}, onToggleSourceExternal: () => {
|
|
765
576
|
setPanelOpen('source');
|
|
766
577
|
setPanelScrollOffset(() => 0);
|
|
767
|
-
}, onTextEntryActiveChange: setTextEntryActive
|
|
578
|
+
}, onTextEntryActiveChange: setTextEntryActive }, selected.key)), saveError && _jsx(Text, { color: "red", children: '✗ ' + saveError }), _jsxs(Text, { dimColor: true, children: [sidebarFocused
|
|
768
579
|
? ' [a] accept [r] reject [A] accept all [J] ' +
|
|
769
580
|
(showJson ? 'hide JSON' : 'show JSON') +
|
|
770
581
|
' [F] finalize [e/Tab] focus panel' +
|
|
771
582
|
(livePreview && removedComponents.length > 0 ? ' [d] removed list' : '') +
|
|
772
|
-
(slotCycles.length > 0 ? ' [c] cycles' : '') +
|
|
773
583
|
' [q] quit'
|
|
774
584
|
: showJson
|
|
775
585
|
? ' [j/k] scroll [Ctrl+u/d] half-page [gg/G] top/bottom [Tab] focus list'
|
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { ServerPreviewResponse } from '@contentful/experience-design-system-types';
|
|
3
|
-
export interface PreviewDiffLine {
|
|
4
|
-
key: string;
|
|
5
|
-
color: 'green' | 'red' | 'yellow' | 'gray';
|
|
6
|
-
text: string;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Pure builder for the wizard preview diff lines. Extracted from the render
|
|
10
|
-
* layer so it can be unit-tested independently of Ink.
|
|
11
|
-
*/
|
|
12
|
-
export declare function buildPreviewDiffLines(preview: ServerPreviewResponse): PreviewDiffLine[];
|
|
13
3
|
type WizardPreviewStepProps = {
|
|
14
4
|
preview: ServerPreviewResponse;
|
|
15
5
|
spaceId: string;
|
|
@@ -1,99 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useState, useMemo } from 'react';
|
|
3
3
|
import { Box, Text, useStdout } from 'ink';
|
|
4
4
|
import { useImmediateInput } from '../../../analyze/select/tui/hooks/useImmediateInput.js';
|
|
5
5
|
import { hasBreakingChangesWithImpact } from '../../../apply/manifest.js';
|
|
6
6
|
import { computeComponentDiffLines } from './preview-diff.js';
|
|
7
|
-
/**
|
|
8
|
-
* Pure builder for the wizard preview diff lines. Extracted from the render
|
|
9
|
-
* layer so it can be unit-tested independently of Ink.
|
|
10
|
-
*/
|
|
11
|
-
export function buildPreviewDiffLines(preview) {
|
|
12
|
-
const lines = [];
|
|
13
|
-
const { components, tokens } = preview;
|
|
14
|
-
for (const item of components.new) {
|
|
15
|
-
const raw = item;
|
|
16
|
-
const name = raw.key ?? raw.$name ?? 'unknown';
|
|
17
|
-
lines.push({ key: `comp-new-${name}`, color: 'green', text: ` + ${name}` });
|
|
18
|
-
const slots = (raw.$slots ?? {});
|
|
19
|
-
for (const slotName of Object.keys(slots).sort()) {
|
|
20
|
-
lines.push({
|
|
21
|
-
key: `comp-new-${name}-slot-${slotName}`,
|
|
22
|
-
color: 'green',
|
|
23
|
-
text: ` slot: ${slotName}`,
|
|
24
|
-
});
|
|
25
|
-
const allowed = slots[slotName]?.['$allowedComponents'];
|
|
26
|
-
if (Array.isArray(allowed) && allowed.length > 0) {
|
|
27
|
-
const names = allowed.filter((n) => typeof n === 'string');
|
|
28
|
-
lines.push({
|
|
29
|
-
key: `comp-new-${name}-slot-${slotName}-allow`,
|
|
30
|
-
color: 'green',
|
|
31
|
-
text: ` allowedComponents: [${names.join(', ')}]`,
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
for (const item of components.removed) {
|
|
37
|
-
lines.push({ key: `comp-rm-${item.name}`, color: 'red', text: ` - ${item.name}` });
|
|
38
|
-
}
|
|
39
|
-
for (const item of components.changed) {
|
|
40
|
-
lines.push({
|
|
41
|
-
key: `comp-h-${item.current.name}`,
|
|
42
|
-
color: 'yellow',
|
|
43
|
-
text: ` ~ ${item.current.name}${item.hasPendingDraftChanges ? ' ⚡ has pending draft changes' : ''}`,
|
|
44
|
-
});
|
|
45
|
-
if (item.changeClassification?.classification === 'breaking') {
|
|
46
|
-
const reasons = item.changeClassification.breakingChanges
|
|
47
|
-
.map((bc) => `${bc.propertyId}: ${bc.reason}`)
|
|
48
|
-
.join(', ');
|
|
49
|
-
lines.push({ key: `comp-b-${item.current.name}`, color: 'red', text: ` ⚠ BREAKING: ${reasons}` });
|
|
50
|
-
}
|
|
51
|
-
const diffLines = computeComponentDiffLines(item.current, item.proposed, item.changeClassification);
|
|
52
|
-
for (const d of diffLines) {
|
|
53
|
-
lines.push({ key: `comp-d-${item.current.name}-${d.key}`, color: d.color, text: ` ${d.text}` });
|
|
54
|
-
}
|
|
55
|
-
// Also enumerate slots + allowedComponents from the proposed side so the
|
|
56
|
-
// reviewer sees the shape they're pushing, not just the delta.
|
|
57
|
-
const proposedSlots = item.proposed['$slots'] ?? {};
|
|
58
|
-
for (const slotName of Object.keys(proposedSlots).sort()) {
|
|
59
|
-
const allowed = proposedSlots[slotName]?.['$allowedComponents'];
|
|
60
|
-
if (Array.isArray(allowed) && allowed.length > 0) {
|
|
61
|
-
const names = allowed.filter((n) => typeof n === 'string');
|
|
62
|
-
const key = `comp-d-${item.current.name}-slot-${slotName}-allow-list`;
|
|
63
|
-
if (!lines.some((l) => l.key === key)) {
|
|
64
|
-
lines.push({
|
|
65
|
-
key,
|
|
66
|
-
color: 'gray',
|
|
67
|
-
text: ` slot ${slotName} allowedComponents: [${names.join(', ')}]`,
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
for (const item of tokens.new) {
|
|
74
|
-
const raw = item;
|
|
75
|
-
const name = raw.name ?? raw.path ?? 'unknown';
|
|
76
|
-
lines.push({ key: `tok-new-${name}`, color: 'green', text: ` + ${name}` });
|
|
77
|
-
}
|
|
78
|
-
for (const item of tokens.removed) {
|
|
79
|
-
lines.push({ key: `tok-rm-${item.name}`, color: 'red', text: ` - ${item.name}` });
|
|
80
|
-
}
|
|
81
|
-
for (const item of tokens.changed) {
|
|
82
|
-
const tokenName = item.current.name;
|
|
83
|
-
lines.push({
|
|
84
|
-
key: `tok-h-${tokenName}`,
|
|
85
|
-
color: 'yellow',
|
|
86
|
-
text: ` ~ ${tokenName}${item.hasPendingDraftChanges ? ' ⚡ has pending draft changes' : ''}`,
|
|
87
|
-
});
|
|
88
|
-
if (item.changeClassification?.classification === 'breaking') {
|
|
89
|
-
const reasons = item.changeClassification.breakingChanges
|
|
90
|
-
.map((bc) => `${bc.propertyId}: ${bc.reason}`)
|
|
91
|
-
.join(', ');
|
|
92
|
-
lines.push({ key: `tok-b-${tokenName}`, color: 'red', text: ` ⚠ BREAKING: ${reasons}` });
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
return lines;
|
|
96
|
-
}
|
|
97
7
|
export function WizardPreviewStep({ preview, spaceId, environmentId, stepNumber, totalSteps, onConfirm, onEdit, onSaveFiles, onQuit, }) {
|
|
98
8
|
const breakingWithImpact = hasBreakingChangesWithImpact(preview);
|
|
99
9
|
const [diffExpanded, setDiffExpanded] = useState(false);
|
|
@@ -104,10 +14,56 @@ export function WizardPreviewStep({ preview, spaceId, environmentId, stepNumber,
|
|
|
104
14
|
const allDiffLines = useMemo(() => {
|
|
105
15
|
if (!diffExpanded)
|
|
106
16
|
return [];
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
17
|
+
const lines = [];
|
|
18
|
+
const { components, tokens } = preview;
|
|
19
|
+
for (const item of components.new) {
|
|
20
|
+
const name = item.key ??
|
|
21
|
+
item.$name ??
|
|
22
|
+
'unknown';
|
|
23
|
+
lines.push({ key: `comp-new-${name}`, element: _jsxs(Text, { color: "green", children: [" + ", name] }) });
|
|
24
|
+
}
|
|
25
|
+
for (const item of components.removed) {
|
|
26
|
+
lines.push({ key: `comp-rm-${item.name}`, element: _jsxs(Text, { color: "red", children: [" - ", item.name] }) });
|
|
27
|
+
}
|
|
28
|
+
for (const item of components.changed) {
|
|
29
|
+
lines.push({
|
|
30
|
+
key: `comp-h-${item.current.name}`,
|
|
31
|
+
element: (_jsxs(Text, { color: "yellow", children: [' ', "~ ", item.current.name, item.hasPendingDraftChanges ? _jsx(Text, { color: "yellow", children: " \u26A1 has pending draft changes" }) : null] })),
|
|
32
|
+
});
|
|
33
|
+
if (item.changeClassification?.classification === 'breaking') {
|
|
34
|
+
const reasons = item.changeClassification.breakingChanges
|
|
35
|
+
.map((bc) => `${bc.propertyId}: ${bc.reason}`)
|
|
36
|
+
.join(', ');
|
|
37
|
+
lines.push({ key: `comp-b-${item.current.name}`, element: _jsxs(Text, { color: "red", children: [" \u26A0 BREAKING: ", reasons] }) });
|
|
38
|
+
}
|
|
39
|
+
const diffLines = computeComponentDiffLines(item.current, item.proposed, item.changeClassification);
|
|
40
|
+
for (const d of diffLines) {
|
|
41
|
+
lines.push({ key: `comp-d-${item.current.name}-${d.key}`, element: _jsxs(Text, { color: d.color, children: [" ", d.text] }) });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
for (const item of tokens.new) {
|
|
45
|
+
const name = item.name ??
|
|
46
|
+
item.path ??
|
|
47
|
+
'unknown';
|
|
48
|
+
lines.push({ key: `tok-new-${name}`, element: _jsxs(Text, { color: "green", children: [" + ", name] }) });
|
|
49
|
+
}
|
|
50
|
+
for (const item of tokens.removed) {
|
|
51
|
+
lines.push({ key: `tok-rm-${item.name}`, element: _jsxs(Text, { color: "red", children: [" - ", item.name] }) });
|
|
52
|
+
}
|
|
53
|
+
for (const item of tokens.changed) {
|
|
54
|
+
const tokenName = item.current.name;
|
|
55
|
+
lines.push({
|
|
56
|
+
key: `tok-h-${tokenName}`,
|
|
57
|
+
element: (_jsxs(Text, { color: "yellow", children: [' ', "~ ", tokenName, item.hasPendingDraftChanges ? _jsx(Text, { color: "yellow", children: " \u26A1 has pending draft changes" }) : null] })),
|
|
58
|
+
});
|
|
59
|
+
if (item.changeClassification?.classification === 'breaking') {
|
|
60
|
+
const reasons = item.changeClassification.breakingChanges
|
|
61
|
+
.map((bc) => `${bc.propertyId}: ${bc.reason}`)
|
|
62
|
+
.join(', ');
|
|
63
|
+
lines.push({ key: `tok-b-${tokenName}`, element: _jsxs(Text, { color: "red", children: [" \u26A0 BREAKING: ", reasons] }) });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return lines;
|
|
111
67
|
}, [diffExpanded, preview]);
|
|
112
68
|
const maxScroll = Math.max(0, allDiffLines.length - viewportHeight);
|
|
113
69
|
useImmediateInput((input, key) => {
|
|
@@ -59,7 +59,6 @@ export function computeComponentDiffLines(current, proposed, changeClassificatio
|
|
|
59
59
|
const currentSlots = new Set(current.slots);
|
|
60
60
|
const proposedSlots = (proposed['$slots'] ?? {});
|
|
61
61
|
const proposedSlotNames = new Set(Object.keys(proposedSlots));
|
|
62
|
-
const currentSlotAllowed = current.currentSlotAllowed ?? {};
|
|
63
62
|
for (const name of [...proposedSlotNames].sort()) {
|
|
64
63
|
if (!currentSlots.has(name)) {
|
|
65
64
|
lines.push({ key: `slot-${name}-add`, color: 'green', text: `+ slot: ${name}` });
|
|
@@ -70,55 +69,8 @@ export function computeComponentDiffLines(current, proposed, changeClassificatio
|
|
|
70
69
|
lines.push({ key: `slot-${name}-rm`, color: 'red', text: `- slot: ${name}` });
|
|
71
70
|
}
|
|
72
71
|
}
|
|
73
|
-
// $allowedComponents diffs — for each slot present in both sides, or newly-added
|
|
74
|
-
// with a non-empty allowedComponents list.
|
|
75
|
-
for (const name of [...proposedSlotNames].sort()) {
|
|
76
|
-
const nextAllowed = normalizeAllowedComponents(proposedSlots[name]?.['$allowedComponents']);
|
|
77
|
-
const prevAllowed = normalizeAllowedComponents(currentSlotAllowed[name]);
|
|
78
|
-
const prevExists = currentSlots.has(name);
|
|
79
|
-
if (!prevExists) {
|
|
80
|
-
if (nextAllowed.length > 0) {
|
|
81
|
-
lines.push({
|
|
82
|
-
key: `slot-${name}-allow-new`,
|
|
83
|
-
color: 'green',
|
|
84
|
-
text: `+ slot ${name} allowedComponents: [${nextAllowed.join(', ')}]`,
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
continue;
|
|
88
|
-
}
|
|
89
|
-
if (arraysEqual(prevAllowed, nextAllowed))
|
|
90
|
-
continue;
|
|
91
|
-
lines.push({
|
|
92
|
-
key: `slot-${name}-allow-old`,
|
|
93
|
-
color: 'red',
|
|
94
|
-
text: `- slot ${name} allowedComponents: [${prevAllowed.join(', ')}]`,
|
|
95
|
-
});
|
|
96
|
-
lines.push({
|
|
97
|
-
key: `slot-${name}-allow-new`,
|
|
98
|
-
color: 'green',
|
|
99
|
-
text: `+ slot ${name} allowedComponents: [${nextAllowed.join(', ')}]`,
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
72
|
return lines;
|
|
103
73
|
}
|
|
104
|
-
function normalizeAllowedComponents(value) {
|
|
105
|
-
if (!Array.isArray(value))
|
|
106
|
-
return [];
|
|
107
|
-
const out = [];
|
|
108
|
-
for (const item of value) {
|
|
109
|
-
if (typeof item === 'string' && item.length > 0)
|
|
110
|
-
out.push(item);
|
|
111
|
-
}
|
|
112
|
-
return out.sort();
|
|
113
|
-
}
|
|
114
|
-
function arraysEqual(a, b) {
|
|
115
|
-
if (a.length !== b.length)
|
|
116
|
-
return false;
|
|
117
|
-
for (let i = 0; i < a.length; i++)
|
|
118
|
-
if (a[i] !== b[i])
|
|
119
|
-
return false;
|
|
120
|
-
return true;
|
|
121
|
-
}
|
|
122
74
|
function normalizeType(type) {
|
|
123
75
|
switch (type.toLowerCase()) {
|
|
124
76
|
case 'boolean':
|
package/dist/src/session/db.d.ts
CHANGED
|
@@ -3,7 +3,6 @@ import type { RawComponentDefinition } from '../types.js';
|
|
|
3
3
|
import type { CDFComponentEntry, DTCGTokenEntry, DTCGTokenGroup } from '@contentful/experience-design-system-types';
|
|
4
4
|
import type { ToolCall, TokenToolCall } from '../generate/agent-runner.js';
|
|
5
5
|
import type { ComponentTypeSummary } from '@contentful/experience-design-system-types';
|
|
6
|
-
import type { SlotCycle, SlotEdge } from '../analyze/cycle-detection.js';
|
|
7
6
|
export type StepStatus = 'pending' | 'complete' | 'failed' | 'interrupted';
|
|
8
7
|
export type CommandName = 'analyze extract' | 'analyze select' | 'generate components' | 'generate tokens' | 'generate edit' | 'apply preview' | 'apply select' | 'apply push' | 'print components' | 'print tokens' | 'import';
|
|
9
8
|
export interface SessionRow {
|
|
@@ -177,14 +176,6 @@ export declare function lookupCacheByEntity(db: DatabaseSync, entityType: 'compo
|
|
|
177
176
|
export declare function storeCache(db: DatabaseSync, inputHash: string, entityType: 'component' | 'token_set', entityId: string, sourceSessionId: string, humanEdited: boolean, promptHash?: string): void;
|
|
178
177
|
export declare function storeScannedFiles(db: DatabaseSync, sessionId: string, filePaths: string[]): void;
|
|
179
178
|
export declare function loadScannedFiles(db: DatabaseSync, sessionId: string): string[];
|
|
180
|
-
export declare function storeSlotCycles(db: DatabaseSync, sessionId: string, cycles: Array<SlotCycle & {
|
|
181
|
-
suggestedBreak?: SlotEdge | null;
|
|
182
|
-
}>): void;
|
|
183
|
-
export interface StoredSlotCycle extends SlotCycle {
|
|
184
|
-
suggestedBreak: SlotEdge | null;
|
|
185
|
-
}
|
|
186
|
-
export declare function loadSlotCycles(db: DatabaseSync, sessionId: string): StoredSlotCycle[];
|
|
187
|
-
export declare function clearSlotCycles(db: DatabaseSync, sessionId: string): void;
|
|
188
179
|
export declare function markCacheHumanEdited(db: DatabaseSync, entityType: 'component' | 'token_set', entityId: string): void;
|
|
189
180
|
export declare function copyComponentFromCache(db: DatabaseSync, sourceSessionId: string, targetSessionId: string, componentId: string): void;
|
|
190
181
|
export declare function copyTokensFromCache(db: DatabaseSync, sourceSessionId: string, targetSessionId: string): void;
|