@contentful/experience-design-system-cli 2.26.1-dev-build-a852362.0 → 2.26.1-dev-build-f03f014.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/dist/package.json +14 -10
  2. package/dist/src/index.js +34937 -9
  3. package/dist/src/lib/cli-path.d.ts +4 -0
  4. package/dist/src/runs/export-helpers.d.ts +1 -12
  5. package/dist/src/runs/push-helpers.d.ts +1 -6
  6. package/package.json +12 -7
  7. package/skills/generate-components.md +427 -0
  8. package/skills/generate-tokens.md +194 -0
  9. package/skills/select-components.md +224 -0
  10. package/dist/src/analytics/apply.js +0 -30
  11. package/dist/src/analytics/client.js +0 -81
  12. package/dist/src/analytics/constants.js +0 -4
  13. package/dist/src/analytics/env.js +0 -14
  14. package/dist/src/analytics/exit.js +0 -24
  15. package/dist/src/analytics/index.js +0 -9
  16. package/dist/src/analytics/normalize.js +0 -18
  17. package/dist/src/analytics/os.js +0 -13
  18. package/dist/src/analytics/session.js +0 -15
  19. package/dist/src/analytics/tracker.js +0 -126
  20. package/dist/src/analytics/types.js +0 -1
  21. package/dist/src/analyze/build-analyze-view-rows.js +0 -63
  22. package/dist/src/analyze/command.js +0 -599
  23. package/dist/src/analyze/composite-closure.js +0 -0
  24. package/dist/src/analyze/composition/agent-parser/author-prompt.js +0 -22
  25. package/dist/src/analyze/composition/agent-parser/extract-parser.js +0 -44
  26. package/dist/src/analyze/composition/agent-parser/load-prompt.js +0 -31
  27. package/dist/src/analyze/composition/agent-parser/resolve-via-parser.js +0 -88
  28. package/dist/src/analyze/composition/agent-parser/sandbox.js +0 -187
  29. package/dist/src/analyze/composition/apply-mapping.js +0 -67
  30. package/dist/src/analyze/composition/candidate-critic-agent.js +0 -39
  31. package/dist/src/analyze/composition/candidate-critic.js +0 -63
  32. package/dist/src/analyze/composition/candidate-files.js +0 -131
  33. package/dist/src/analyze/composition/composition-cache-key.js +0 -19
  34. package/dist/src/analyze/composition/interchange-schema.js +0 -61
  35. package/dist/src/analyze/composition/manifest-doc-evidence.js +0 -136
  36. package/dist/src/analyze/composition/merge-edges.js +0 -70
  37. package/dist/src/analyze/composition/parse-map-edges.js +0 -55
  38. package/dist/src/analyze/composition/resolve-mapping-cli.js +0 -29
  39. package/dist/src/analyze/composition/resolve-mapping.js +0 -111
  40. package/dist/src/analyze/cycle-detection.js +0 -234
  41. package/dist/src/analyze/cycle-view.js +0 -28
  42. package/dist/src/analyze/fuzzy-search.js +0 -55
  43. package/dist/src/analyze/issue-inheritance.js +0 -108
  44. package/dist/src/analyze/lineage.js +0 -0
  45. package/dist/src/analyze/scope-gate-cascade.js +0 -170
  46. package/dist/src/analyze/search-neighborhood.js +0 -56
  47. package/dist/src/analyze/select/command.js +0 -484
  48. package/dist/src/analyze/select/index.js +0 -5
  49. package/dist/src/analyze/select/parser.js +0 -53
  50. package/dist/src/analyze/select/persistence.js +0 -80
  51. package/dist/src/analyze/select/preview-annotations.js +0 -62
  52. package/dist/src/analyze/select/stdout.js +0 -3
  53. package/dist/src/analyze/select/tui/App.js +0 -483
  54. package/dist/src/analyze/select/tui/components/ComponentDetail.js +0 -48
  55. package/dist/src/analyze/select/tui/components/ComponentRationalePanel.js +0 -125
  56. package/dist/src/analyze/select/tui/components/FieldEditor.js +0 -1131
  57. package/dist/src/analyze/select/tui/components/FinalizeDialog.js +0 -36
  58. package/dist/src/analyze/select/tui/components/GotoBanner.js +0 -30
  59. package/dist/src/analyze/select/tui/components/GroupedSidebar.js +0 -517
  60. package/dist/src/analyze/select/tui/components/HelpOverlay.js +0 -17
  61. package/dist/src/analyze/select/tui/components/JsonEditor.js +0 -131
  62. package/dist/src/analyze/select/tui/components/JsonPanel.js +0 -66
  63. package/dist/src/analyze/select/tui/components/LineagePanel.js +0 -22
  64. package/dist/src/analyze/select/tui/components/PreviewSummaryBar.js +0 -29
  65. package/dist/src/analyze/select/tui/components/QuitDialog.js +0 -14
  66. package/dist/src/analyze/select/tui/components/RationalePanel.js +0 -80
  67. package/dist/src/analyze/select/tui/components/Sidebar.js +0 -92
  68. package/dist/src/analyze/select/tui/components/SourcePanel.js +0 -52
  69. package/dist/src/analyze/select/tui/components/StatusBar.js +0 -7
  70. package/dist/src/analyze/select/tui/components/TopBar.js +0 -10
  71. package/dist/src/analyze/select/tui/components/removed-components-text.js +0 -11
  72. package/dist/src/analyze/select/tui/hooks/scroll-offset.js +0 -26
  73. package/dist/src/analyze/select/tui/hooks/useImmediateInput.js +0 -66
  74. package/dist/src/analyze/select/tui/hooks/useKeymap.js +0 -67
  75. package/dist/src/analyze/select/tui/hooks/useSession.js +0 -52
  76. package/dist/src/analyze/select/tui/hooks/useUndo.js +0 -26
  77. package/dist/src/analyze/select/tui/theme.js +0 -28
  78. package/dist/src/analyze/select/types.js +0 -39
  79. package/dist/src/analyze/select-agent/command.js +0 -558
  80. package/dist/src/analyze/select-agent/context-builder.js +0 -197
  81. package/dist/src/analyze/select-agent/show-rationale.js +0 -92
  82. package/dist/src/analyze/selection-cascade.js +0 -19
  83. package/dist/src/analyze/slot-graph.js +0 -17
  84. package/dist/src/analyze/tui/AnalyzeView.js +0 -64
  85. package/dist/src/apply/api-client.js +0 -440
  86. package/dist/src/apply/command.js +0 -845
  87. package/dist/src/apply/manifest.js +0 -1
  88. package/dist/src/apply/preview-utils.js +0 -26
  89. package/dist/src/apply/tui/SelectView.js +0 -34
  90. package/dist/src/apply/tui/ServerApplyView.js +0 -49
  91. package/dist/src/apply/tui/ServerPreviewView.js +0 -23
  92. package/dist/src/credentials-store.js +0 -74
  93. package/dist/src/generate/command.js +0 -597
  94. package/dist/src/generate/edit/command.js +0 -127
  95. package/dist/src/generate/tui/GenerateView.js +0 -10
  96. package/dist/src/host-utils.js +0 -26
  97. package/dist/src/import/agent-model-resolve.js +0 -35
  98. package/dist/src/import/auto-filter-resolve.js +0 -16
  99. package/dist/src/import/command.js +0 -380
  100. package/dist/src/import/cycle-auto-reject.js +0 -14
  101. package/dist/src/import/orchestrator.js +0 -603
  102. package/dist/src/import/path-utils.js +0 -30
  103. package/dist/src/import/picker-dispatch.js +0 -44
  104. package/dist/src/import/print-prompt.js +0 -31
  105. package/dist/src/import/strip-allowed-components.js +0 -22
  106. package/dist/src/import/tui/CustomPromptBanner.js +0 -8
  107. package/dist/src/import/tui/WizardApp.js +0 -1670
  108. package/dist/src/import/tui/ai-flag.js +0 -6
  109. package/dist/src/import/tui/auto-filter-error.js +0 -29
  110. package/dist/src/import/tui/autocomplete.js +0 -32
  111. package/dist/src/import/tui/components/AutoFilterBanner.js +0 -19
  112. package/dist/src/import/tui/components/CounterStrip.js +0 -12
  113. package/dist/src/import/tui/components/LegendEntry.js +0 -6
  114. package/dist/src/import/tui/cycle-panel-scroll.js +0 -33
  115. package/dist/src/import/tui/final-review-host.js +0 -25
  116. package/dist/src/import/tui/group-collapse.js +0 -11
  117. package/dist/src/import/tui/history.js +0 -53
  118. package/dist/src/import/tui/hooks/useLineage.js +0 -50
  119. package/dist/src/import/tui/hooks/useOverlayPanel.js +0 -27
  120. package/dist/src/import/tui/lineage-layout.js +0 -82
  121. package/dist/src/import/tui/merge-ai-decisions.js +0 -22
  122. package/dist/src/import/tui/push-decision-gate-helpers.js +0 -8
  123. package/dist/src/import/tui/push-progress.js +0 -1
  124. package/dist/src/import/tui/run-print-files-helpers.js +0 -8
  125. package/dist/src/import/tui/run-teaser.js +0 -9
  126. package/dist/src/import/tui/runLivePreview.js +0 -82
  127. package/dist/src/import/tui/runScopeGate.js +0 -28
  128. package/dist/src/import/tui/scope-gate-columns.js +0 -94
  129. package/dist/src/import/tui/scope-gate-host.js +0 -28
  130. package/dist/src/import/tui/sidebar-width.js +0 -3
  131. package/dist/src/import/tui/spawn-generate.js +0 -53
  132. package/dist/src/import/tui/step-filters.js +0 -42
  133. package/dist/src/import/tui/steps/AtomicGenerateReviewStep.js +0 -726
  134. package/dist/src/import/tui/steps/AtomicScopeGateStep.js +0 -210
  135. package/dist/src/import/tui/steps/CredentialsStep.js +0 -108
  136. package/dist/src/import/tui/steps/DoneStep.js +0 -24
  137. package/dist/src/import/tui/steps/ErrorStep.js +0 -16
  138. package/dist/src/import/tui/steps/GateStep.js +0 -22
  139. package/dist/src/import/tui/steps/GenerateReviewStep.js +0 -1618
  140. package/dist/src/import/tui/steps/PathValidationStep.js +0 -152
  141. package/dist/src/import/tui/steps/PreviewStep.js +0 -37
  142. package/dist/src/import/tui/steps/PreviewValidationErrorStep.js +0 -23
  143. package/dist/src/import/tui/steps/PushDecisionGateStep.js +0 -73
  144. package/dist/src/import/tui/steps/PushingStep.js +0 -24
  145. package/dist/src/import/tui/steps/RunningStep.js +0 -21
  146. package/dist/src/import/tui/steps/ScopeGateStep.js +0 -907
  147. package/dist/src/import/tui/steps/TokenInputStep.js +0 -88
  148. package/dist/src/import/tui/steps/WelcomeStep.js +0 -34
  149. package/dist/src/import/tui/steps/WizardPreviewStep.js +0 -169
  150. package/dist/src/import/tui/steps/auto-reject-decision.js +0 -9
  151. package/dist/src/import/tui/steps/breaking-change-format.js +0 -24
  152. package/dist/src/import/tui/steps/enumerate-cycle-breaks.js +0 -0
  153. package/dist/src/import/tui/steps/preview-diff.js +0 -175
  154. package/dist/src/import/tui/useFinalizePreview.js +0 -0
  155. package/dist/src/import/tui/useLivePreview.js +0 -122
  156. package/dist/src/import/tui/wizard-422-helpers.js +0 -60
  157. package/dist/src/import/tui/wizard-generate-progress.js +0 -25
  158. package/dist/src/import/tui/wizard-save-flow.js +0 -20
  159. package/dist/src/import/tui/wizard-state-transitions.js +0 -32
  160. package/dist/src/lib/agent-model-options.js +0 -15
  161. package/dist/src/lib/command-options.js +0 -30
  162. package/dist/src/lib/composition-mode.js +0 -39
  163. package/dist/src/lib/contentful-urls.js +0 -27
  164. package/dist/src/lib/debug-logger.js +0 -229
  165. package/dist/src/lib/debug-preamble.js +0 -33
  166. package/dist/src/lib/error-parser.js +0 -269
  167. package/dist/src/lib/prompt-overrides.js +0 -69
  168. package/dist/src/lib/terminal-capabilities.js +0 -51
  169. package/dist/src/lib/user-agent.js +0 -29
  170. package/dist/src/output/format.js +0 -110
  171. package/dist/src/print/command.js +0 -221
  172. package/dist/src/print/validate/tui/ValidateView.js +0 -37
  173. package/dist/src/print/validate/validators/cdf-validator.js +0 -104
  174. package/dist/src/print/validate/validators/dtcg-validator.js +0 -110
  175. package/dist/src/print/validate/validators/format-errors.js +0 -18
  176. package/dist/src/program.js +0 -105
  177. package/dist/src/runs/export-helpers.js +0 -59
  178. package/dist/src/runs/fingerprint.js +0 -75
  179. package/dist/src/runs/ls-command.js +0 -137
  180. package/dist/src/runs/modify-launcher.js +0 -42
  181. package/dist/src/runs/path-prompt.js +0 -72
  182. package/dist/src/runs/push-creds-prompt.js +0 -39
  183. package/dist/src/runs/push-helpers.js +0 -72
  184. package/dist/src/runs/push-launcher.js +0 -77
  185. package/dist/src/runs/replay-helpers.js +0 -164
  186. package/dist/src/runs/resolve-run-target.js +0 -45
  187. package/dist/src/runs/run-picker-mount.js +0 -72
  188. package/dist/src/runs/run-picker.js +0 -129
  189. package/dist/src/runs/save-conflict.js +0 -56
  190. package/dist/src/runs/save-path-resolver.js +0 -75
  191. package/dist/src/runs/staleness.js +0 -140
  192. package/dist/src/runs/store.js +0 -136
  193. package/dist/src/session/cache-keys.js +0 -44
  194. package/dist/src/session/command.js +0 -261
  195. package/dist/src/session/db.js +0 -1538
  196. package/dist/src/session/migration.js +0 -117
  197. package/dist/src/session/session-id.js +0 -212
  198. package/dist/src/session/stats.js +0 -89
  199. package/dist/src/setup/analytics-prompt.js +0 -24
  200. package/dist/src/setup/auto-filter-prompt.js +0 -24
  201. package/dist/src/setup/command.js +0 -966
  202. package/dist/src/setup/composition-mode-prompt.js +0 -37
  203. package/dist/src/setup/debug-mode-prompt.js +0 -22
  204. package/dist/src/types.js +0 -1
@@ -1,6 +0,0 @@
1
- export function isAiFlagged(row) {
2
- return row.needsReview === true || row.aiDecision === 'rejected' || row.aiDecision === 'failed';
3
- }
4
- export function isDefaultIncluded(row) {
5
- return !isAiFlagged(row);
6
- }
@@ -1,29 +0,0 @@
1
- // Pure helpers for shaping the auto-filter subprocess stderr stream into a
2
- // human-readable error tail. The auto-filter (select-agent) subprocess emits
3
- // three classes of lines on stderr:
4
- //
5
- // 1. `progress=...` machine-parseable progress lines consumed by the wizard
6
- // to drive `aiDecisions` / `aiFilterProgress` state.
7
- // 2. `[N/total] Name <verb> ...` per-component status lines (human-readable
8
- // mirror of the progress emission).
9
- // 3. Free-form error output — what we actually want to surface on failure.
10
- //
11
- // `buildAutoFilterErrorTail` strips classes (1) and (2) plus ANSI color
12
- // escapes, then returns the last 3 lines joined with " / " (matching the
13
- // pre-existing tail format in WizardApp.tsx).
14
- const ANSI_RE = /\x1b\[[0-9;]*m/g;
15
- const PROGRESS_RE = /^progress=/;
16
- const PER_COMPONENT_RE = /\[\d+\/\d+\]/;
17
- export function stripAnsi(s) {
18
- return s.replace(ANSI_RE, '');
19
- }
20
- function isStructured(line) {
21
- return PROGRESS_RE.test(line) || PER_COMPONENT_RE.test(line);
22
- }
23
- export function buildAutoFilterErrorTail(raw) {
24
- const lines = raw
25
- .split('\n')
26
- .map((l) => stripAnsi(l.trim()))
27
- .filter((l) => l.length > 0 && !isStructured(l));
28
- return lines.slice(-3).join(' / ');
29
- }
@@ -1,32 +0,0 @@
1
- function longestCommonPrefix(names) {
2
- if (names.length === 0)
3
- return '';
4
- let prefixLen = names[0].length;
5
- for (let i = 1; i < names.length; i++) {
6
- const other = names[i];
7
- let j = 0;
8
- while (j < prefixLen && j < other.length && names[0][j].toLowerCase() === other[j].toLowerCase()) {
9
- j++;
10
- }
11
- prefixLen = j;
12
- if (prefixLen === 0)
13
- break;
14
- }
15
- return names[0].slice(0, prefixLen);
16
- }
17
- export function computeAutocomplete(query, names) {
18
- const q = query.toLowerCase();
19
- const candidates = names.filter((n) => n.toLowerCase().startsWith(q));
20
- if (candidates.length === 0) {
21
- return { completion: query, candidates: [] };
22
- }
23
- if (candidates.length === 1) {
24
- return { completion: candidates[0], candidates: [] };
25
- }
26
- const lcp = longestCommonPrefix(candidates);
27
- // Guard: never return a completion shorter than the current query (e.g. if
28
- // casing differences shrank the LCP below the typed length, keep the query).
29
- const completion = lcp.length >= query.length ? lcp : query;
30
- const sorted = [...candidates].sort();
31
- return { completion, candidates: sorted };
32
- }
@@ -1,19 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, Text } from 'ink';
3
- import { PALETTE } from '../../../analyze/select/tui/theme.js';
4
- export function AutoFilterBanner(props) {
5
- const { status, progress, error } = props;
6
- const showRunningHeader = status === 'running' && progress !== null && progress !== undefined && progress.total > 0;
7
- const showCancelledBanner = status === 'cancelled';
8
- const showFailedBanner = status === 'failed';
9
- if (showRunningHeader) {
10
- return (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsxs(Text, { color: PALETTE.info, children: ["[AI filtering (", progress.done, "/", progress.total, ")\u2026] ", _jsx(Text, { dimColor: true, children: "[q] cancels" })] }) }));
11
- }
12
- if (showCancelledBanner) {
13
- return (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: PALETTE.warning, children: ["AI auto-filter cancelled", progress ? ` at ${progress.done}/${progress.total}` : '', ". Review remaining manually."] }) }));
14
- }
15
- if (showFailedBanner) {
16
- return (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: PALETTE.warning, children: ["AI auto-filter failed: ", error ?? 'unknown error', ". Continuing without AI suggestions."] }) }));
17
- }
18
- return null;
19
- }
@@ -1,12 +0,0 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import { Box, Text } from 'ink';
3
- export function CounterStrip(props) {
4
- const { counters, totalWidth } = props;
5
- const condensed = totalWidth < 60;
6
- const labelAcc = condensed ? 'Acc' : 'Accepted';
7
- const labelGrp = condensed ? 'Grp' : 'Groups';
8
- const labelRej = condensed ? 'Rej' : 'Rejected';
9
- const labelUnd = condensed ? 'Und' : 'Undecided';
10
- const sep = condensed ? ' | ' : ' ';
11
- return (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { children: [_jsxs(Text, { dimColor: true, children: [labelAcc, " "] }), _jsx(Text, { bold: true, children: counters.accepted }), _jsx(Text, { dimColor: true, children: `/${counters.total}` }), _jsx(Text, { dimColor: true, children: sep }), _jsxs(Text, { dimColor: true, children: [labelGrp, " "] }), _jsx(Text, { bold: true, children: counters.groups }), _jsx(Text, { dimColor: true, children: sep }), _jsxs(Text, { dimColor: true, children: [labelRej, " "] }), _jsx(Text, { bold: true, children: counters.rejected }), _jsx(Text, { dimColor: true, children: sep }), _jsxs(Text, { dimColor: true, children: [labelUnd, " "] }), _jsx(Text, { bold: true, children: counters.undecided })] }) }));
12
- }
@@ -1,6 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Text } from 'ink';
3
- import { PALETTE } from '../../../analyze/select/tui/theme.js';
4
- export function legendEntry(keyBracket, label, active = false) {
5
- return (_jsxs(Text, { children: [_jsx(Text, { color: active ? PALETTE.warning : PALETTE.info, inverse: active, children: keyBracket }), _jsx(Text, { color: active ? PALETTE.warning : undefined, inverse: active, dimColor: !active, children: ' ' + label })] }, keyBracket + label));
6
- }
@@ -1,33 +0,0 @@
1
- export const CYCLE_PANEL_PREAMBLE_LINES = 4;
2
- export function cycleLineCount(cycle) {
3
- return 3 + (cycle.suggestedBreak ? 1 : 0);
4
- }
5
- export function cycleLineOffsets(cycles, preamble = CYCLE_PANEL_PREAMBLE_LINES) {
6
- const offsets = [];
7
- let acc = preamble;
8
- for (const cycle of cycles) {
9
- offsets.push(acc);
10
- acc += cycleLineCount(cycle);
11
- }
12
- return offsets;
13
- }
14
- export function totalCyclePanelLines(cycles, preamble = CYCLE_PANEL_PREAMBLE_LINES) {
15
- let acc = preamble;
16
- for (const cycle of cycles)
17
- acc += cycleLineCount(cycle);
18
- return acc;
19
- }
20
- export function followCycleScroll(currentScroll, cursorIdx, cycles, panelHeight, preamble = CYCLE_PANEL_PREAMBLE_LINES) {
21
- if (cursorIdx < 0 || cursorIdx >= cycles.length)
22
- return currentScroll;
23
- const offsets = cycleLineOffsets(cycles, preamble);
24
- const blockStart = offsets[cursorIdx];
25
- const lastContentLine = blockStart + cycleLineCount(cycles[cursorIdx]) - 2;
26
- let next = currentScroll;
27
- if (blockStart < currentScroll)
28
- next = blockStart;
29
- else if (lastContentLine >= currentScroll + panelHeight)
30
- next = lastContentLine - panelHeight + 1;
31
- const maxOffset = Math.max(0, totalCyclePanelLines(cycles, preamble) - panelHeight);
32
- return Math.max(0, Math.min(next, maxOffset));
33
- }
@@ -1,25 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, Text } from 'ink';
3
- import { PALETTE } from '../../analyze/select/tui/theme.js';
4
- import React from 'react';
5
- import { GenerateReviewStep } from './steps/GenerateReviewStep.js';
6
- import { AtomicGenerateReviewStep } from './steps/AtomicGenerateReviewStep.js';
7
- export function FinalReviewHost({ extractSessionId, generatedCount, autoAccept, compositionMode = 'atomic', onFinalize, onQuit, livePreview, spaceId, environmentId, cmaToken, host, tokensPath, initialFinalizeError, allowDeletions, }) {
8
- if (!extractSessionId) {
9
- return (_jsx(Box, { paddingX: 2, paddingY: 1, children: _jsx(Text, { color: PALETTE.error, children: "Error: no session ID \u2014 cannot load generated definitions." }) }));
10
- }
11
- if (autoAccept) {
12
- return _jsx(FinalReviewAutoAccept, { generatedCount: generatedCount, onFinalize: onFinalize });
13
- }
14
- // Atomic mode (spec T9): render the pre-composite flat review step. It never
15
- // passes projectSlotGraph to FieldEditor and never walks closures/cycles, so
16
- // slot-composition editing and every hierarchy affordance stay absent.
17
- const StepComponent = compositionMode === 'atomic' ? AtomicGenerateReviewStep : GenerateReviewStep;
18
- return (_jsx(StepComponent, { extractSessionId: extractSessionId, onFinalize: onFinalize, onQuit: onQuit, livePreview: livePreview, spaceId: spaceId, environmentId: environmentId, cmaToken: cmaToken, host: host, tokensPath: tokensPath, initialFinalizeError: initialFinalizeError, ...(compositionMode !== 'atomic' ? { allowDeletions } : {}) }));
19
- }
20
- function FinalReviewAutoAccept({ generatedCount, onFinalize, }) {
21
- React.useEffect(() => {
22
- onFinalize(generatedCount, 0, 0);
23
- }, []);
24
- return (_jsx(Box, { paddingX: 2, paddingY: 1, children: _jsxs(Text, { dimColor: true, children: ["Auto-accepting ", generatedCount, " generated components..."] }) }));
25
- }
@@ -1,11 +0,0 @@
1
- export function resolveGroupRoot(key, closures, cycleSet) {
2
- if (cycleSet.has(key))
3
- return key;
4
- if (closures.has(key))
5
- return key;
6
- for (const [root, closure] of closures.entries()) {
7
- if (closure.nodes.some((n) => n.name === key))
8
- return root;
9
- }
10
- return undefined;
11
- }
@@ -1,53 +0,0 @@
1
- const DEFAULT_MAX_DEPTH = 50;
2
- function cloneSnapshot(snap) {
3
- return {
4
- components: snap.components.map((c) => ({
5
- key: c.key,
6
- entry: JSON.parse(JSON.stringify(c.entry)),
7
- status: c.status,
8
- })),
9
- autoRejected: [...snap.autoRejected],
10
- undoSnapshot: snap.undoSnapshot === null ? null : new Map(Array.from(snap.undoSnapshot.entries())),
11
- };
12
- }
13
- export function createHistoryStack(seed, maxDepth = DEFAULT_MAX_DEPTH) {
14
- const cap = Math.max(1, maxDepth);
15
- let stack = [cloneSnapshot(seed)];
16
- let cursor = 0;
17
- function push(snapshot, _label) {
18
- if (cursor < stack.length - 1) {
19
- stack = stack.slice(0, cursor + 1);
20
- }
21
- stack.push(cloneSnapshot(snapshot));
22
- while (stack.length > cap) {
23
- stack.shift();
24
- }
25
- cursor = stack.length - 1;
26
- }
27
- function undo() {
28
- if (cursor <= 0)
29
- return null;
30
- cursor -= 1;
31
- return cloneSnapshot(stack[cursor]);
32
- }
33
- function redo() {
34
- if (cursor >= stack.length - 1)
35
- return null;
36
- cursor += 1;
37
- return cloneSnapshot(stack[cursor]);
38
- }
39
- function canUndo() {
40
- return cursor > 0;
41
- }
42
- function canRedo() {
43
- return cursor < stack.length - 1;
44
- }
45
- function reset(nextSeed) {
46
- stack = [cloneSnapshot(nextSeed)];
47
- cursor = 0;
48
- }
49
- function size() {
50
- return stack.length;
51
- }
52
- return { push, undo, redo, canUndo, canRedo, reset, size };
53
- }
@@ -1,50 +0,0 @@
1
- import { useMemo } from 'react';
2
- import { computeAllClosures } from '../../../analyze/composite-closure.js';
3
- import { buildAncestorTree, renderAncestorTree } from '../../../analyze/lineage.js';
4
- export function useLineage(focusedKey, graph) {
5
- const graphKey = useMemo(() => JSON.stringify(graph), [graph]);
6
- const stableGraph = useMemo(() => graph, [graphKey]);
7
- const closures = useMemo(() => computeAllClosures(stableGraph), [stableGraph]);
8
- const entries = useMemo(() => {
9
- if (!focusedKey)
10
- return [];
11
- const name = focusedKey;
12
- const tree = buildAncestorTree(name, stableGraph);
13
- const closure = closures.get(name);
14
- const out = [];
15
- out.push({ kind: 'section', label: 'Ancestors:' });
16
- if (tree.parents.length === 0) {
17
- out.push({ kind: 'empty', label: ' (no ancestors)' });
18
- }
19
- else {
20
- const lines = renderAncestorTree(tree);
21
- for (const line of lines) {
22
- out.push({
23
- kind: 'ancestor',
24
- label: ' ' + line.text,
25
- jumpTarget: line.jumpTarget ?? name,
26
- });
27
- }
28
- }
29
- out.push({ kind: 'section', label: 'Descendants:' });
30
- if (!closure || closure.nodes.length <= 1) {
31
- out.push({ kind: 'empty', label: ' (none)' });
32
- }
33
- else {
34
- for (const node of closure.nodes) {
35
- if (node.name === name)
36
- continue;
37
- out.push({
38
- kind: 'descendant',
39
- label: ' ' + ' '.repeat(Math.max(0, node.depth - 1)) + node.name,
40
- jumpTarget: node.name,
41
- });
42
- }
43
- }
44
- return out;
45
- }, [focusedKey, stableGraph, closures]);
46
- const jumpables = useMemo(() => entries
47
- .map((entry, i) => ({ entry, i }))
48
- .filter(({ entry }) => entry.kind === 'ancestor' || entry.kind === 'descendant'), [entries]);
49
- return { entries, jumpables };
50
- }
@@ -1,27 +0,0 @@
1
- import { useCallback, useState } from 'react';
2
- export function useOverlayPanel(opts) {
3
- const { toggleKey, onClose } = opts;
4
- const [isOpen, setIsOpen] = useState(false);
5
- const open = useCallback(() => {
6
- setIsOpen(true);
7
- }, []);
8
- const close = useCallback(() => {
9
- setIsOpen((prev) => {
10
- if (prev && onClose)
11
- onClose();
12
- return false;
13
- });
14
- }, [onClose]);
15
- const handleInput = useCallback((input, key) => {
16
- if (!isOpen)
17
- return false;
18
- if (input === toggleKey || key.escape === true) {
19
- if (onClose)
20
- onClose();
21
- setIsOpen(false);
22
- return true;
23
- }
24
- return false;
25
- }, [isOpen, toggleKey, onClose]);
26
- return { isOpen, open, close, handleInput };
27
- }
@@ -1,82 +0,0 @@
1
- /** Sidebar height (rows) — unchanged whether or not the panel is open. */
2
- export const VISIBLE_COUNT = 20;
3
- /** Panel window ceiling (matches LineagePanel's DEFAULT_MAX_ROWS from L2b). */
4
- export const MAX_PANEL_ROWS = 15;
5
- /** Floors — both surfaces stay usable even on a small terminal. */
6
- export const SIDEBAR_MIN = 4;
7
- export const MIN_PANEL_ROWS = 4;
8
- /**
9
- * Fallback when `stdout.rows` is unavailable (piped output, tests). No TTY
10
- * means Ink is not interactively repainting, so there is no flicker risk — we
11
- * assume enough height for the FULL sidebar (BASE_CHROME_OVERHEAD + the full
12
- * VISIBLE_COUNT) so the non-interactive render is complete and unclipped.
13
- */
14
- export const FALLBACK_ROWS = 40;
15
- const HEADER_ROWS = 2;
16
- const COUNTER_STRIP_ROWS = 2;
17
- const FOCUSED_DETAIL_ROWS = 2;
18
- const LEGEND_ROWS = 3;
19
- /**
20
- * Vertical space consumed by everything ABOVE/BELOW the columns row. The panel
21
- * shares the columns row, so the fit constraint while open is simply
22
- * `FIXED_OVERHEAD + panelBoxHeight <= rows`.
23
- */
24
- export const FIXED_OVERHEAD = HEADER_ROWS + COUNTER_STRIP_ROWS + FOCUSED_DETAIL_ROWS + LEGEND_ROWS;
25
- // Panel box rows that are NOT entry rows: top border + header + footer hint +
26
- // bottom border (+ up to two scroll indicators on large lineages).
27
- export const PANEL_BOX_CHROME = 6;
28
- /**
29
- * L2e — fixed vertical chrome around the sidebar in the BASE (no-panel) case,
30
- * counting EVERYTHING that is not a variable sidebar entry row: the wizard
31
- * header bar, the "✓ Extraction complete" + "Found N…" intro, the counter
32
- * strip (with its blank separator), the cycle banner, the nothing-selected /
33
- * AI-exclusion hint, the GroupedSidebar box borders + scroll indicator, the
34
- * focused-detail block, and the wrapping legend region. Measured via the PTY
35
- * harness against the react-ux-matrix fixture (cycles present = a tall case):
36
- * the base frame was 39 lines with a 20-row sidebar after the legend row-gap
37
- * compression, i.e. ≈19 lines of chrome. We use 20 for a one-line safety
38
- * margin so the total frame stays strictly within `stdout.rows`.
39
- */
40
- export const BASE_CHROME_OVERHEAD = 20;
41
- function clamp(value, min, max) {
42
- return Math.max(min, Math.min(max, value));
43
- }
44
- /**
45
- * The sidebar height is constant (the panel replaces it in the same slot, so
46
- * there is nothing to shrink). When the panel is open its entry window is sized
47
- * to fit the sidebar's footprint AND the terminal — never taller than the
48
- * sidebar was, so opening lineage cannot grow the frame past `rows`.
49
- */
50
- export function computeLineageLayout({ rows, panelOpen, entryCount }) {
51
- const sidebarVisible = VISIBLE_COUNT;
52
- if (!panelOpen) {
53
- return { sidebarVisible, panelMaxRows: MAX_PANEL_ROWS };
54
- }
55
- // Rows available for panel ENTRIES given the terminal and the panel's box
56
- // chrome; also never taller than the sidebar footprint it replaces.
57
- const terminalFit = rows - FIXED_OVERHEAD - PANEL_BOX_CHROME;
58
- let panelBase = Math.min(VISIBLE_COUNT, terminalFit);
59
- if (entryCount !== undefined && entryCount > 0) {
60
- panelBase = Math.min(panelBase, entryCount);
61
- }
62
- const panelMaxRows = clamp(panelBase, MIN_PANEL_ROWS, MAX_PANEL_ROWS);
63
- return { sidebarVisible, panelMaxRows };
64
- }
65
- /**
66
- * L2e — autoscale the BASE frame to the terminal height. Even with the lineage
67
- * panel closed, a fixed 20-row sidebar plus the always-on chrome can exceed a
68
- * small terminal's rows, so plain Ink (no alt-screen) full-repaints (`\x1b[2J`)
69
- * on every cursor move = flicker. This sizes the sidebar's visible-row budget
70
- * from `stdout.rows` minus `BASE_CHROME_OVERHEAD` so the whole frame fits at
71
- * 24/30/40 rows, and unifies the panel-open sizing with `computeLineageLayout`
72
- * so BOTH cases stay within the terminal.
73
- *
74
- * Floor: `BASE_CHROME_OVERHEAD + SIDEBAR_MIN`. Below it `SIDEBAR_MIN`
75
- * (usability) intentionally wins over the fit — a terminal that small can't
76
- * host the chrome regardless.
77
- */
78
- export function computeSidebarBudget({ rows, panelOpen, entryCount }) {
79
- const sidebarVisibleCount = clamp(rows - BASE_CHROME_OVERHEAD, SIDEBAR_MIN, VISIBLE_COUNT);
80
- const { panelMaxRows } = computeLineageLayout({ rows, panelOpen, entryCount });
81
- return { sidebarVisibleCount, panelMaxRows };
82
- }
@@ -1,22 +0,0 @@
1
- // INTEG-4318: overlay streamed auto-filter decisions (from the select-agent
2
- // child's stderr progress lines) onto components loaded from raw_components.
3
- // Only fills gaps where the DB has no decision — the DB row is authoritative
4
- // once the child persists its status. This is what lets the scope-gate see
5
- // a 'failed' status for components where the LLM omitted a tool call in a
6
- // batch (the select-agent does not persist a 'failed' status to the DB).
7
- export function mergeAiDecisions(components, aiDecisions) {
8
- return components.map((component) => {
9
- if (component.aiDecision !== null && component.aiDecision !== undefined) {
10
- return component;
11
- }
12
- const streamed = aiDecisions[component.name];
13
- if (!streamed) {
14
- return component;
15
- }
16
- return {
17
- ...component,
18
- aiDecision: streamed.decision,
19
- aiReason: streamed.reason,
20
- };
21
- });
22
- }
@@ -1,8 +0,0 @@
1
- /**
2
- * Maps a `PushDecisionGateStep` choice to the wizard action it triggers.
3
- * Centralizing this keeps the gate component free of wizard-side semantics
4
- * and gives us a unit-testable seam between UI choice and side-effect.
5
- */
6
- export function chooseGateAction(choice) {
7
- return choice === 'both' ? 'save-and-push' : choice;
8
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,8 +0,0 @@
1
- export function nextStateAfterPrint(opts) {
2
- const base = opts.outDir
3
- ? { componentsPath: opts.componentsPath, outDir: opts.outDir }
4
- : { componentsPath: opts.componentsPath };
5
- if (opts.skipGate)
6
- return base;
7
- return { step: 'print-gate', ...base };
8
- }
@@ -1,9 +0,0 @@
1
- /**
2
- * Task 8 — one-line teaser appended at the end of every successful run.
3
- * Format pinned in dsi-tui-local-save-tooling-spec.md Part 6.
4
- */
5
- export function buildRunTeaserLine(runId) {
6
- if (!runId)
7
- return '';
8
- return `Run saved as ${runId} — push to Contentful with 'experiences import --push-from-run ${runId}' or modify with 'experiences import --modify ${runId}'.`;
9
- }
@@ -1,82 +0,0 @@
1
- import { buildManifest } from '@contentful/experience-design-system-types';
2
- import { ImportApiClient } from '../../apply/api-client.js';
3
- import { readTokensFromPath } from '../../apply/manifest.js';
4
- import { backfillUnclassifiedProps, loadCDFComponents, openPipelineDb } from '../../session/db.js';
5
- export class TimeoutError extends Error {
6
- constructor(message = 'live-preview timed out') {
7
- super(message);
8
- this.name = 'TimeoutError';
9
- }
10
- }
11
- const DEFAULT_TIMEOUT_MS = 15_000;
12
- /**
13
- * Pure async helper used by `useLivePreview` to re-fire `previewImport` after a
14
- * FieldEditor save in the wizard's final-review step. Mirrors the round-1
15
- * `runScopeGate` shape: a side-effect-bearing pure orchestrator that owns no
16
- * React state.
17
- *
18
- * Skips silently (returns `{ response: null }`) when any of `spaceId`,
19
- * `environmentId`, or `cmaToken` is missing — live preview is an enhancement
20
- * and the caller treats `null` as a no-op. Throws on API errors so the caller
21
- * (`useLivePreview`) can downgrade to local-only mode on 401/403 and log a
22
- * warning otherwise. Wraps the API call in a timeout so a hung backend doesn't
23
- * leave the spinner stuck.
24
- *
25
- * Does NOT run the second-pass seeding from `WizardApp.runPreview`; that's a
26
- * one-shot wizard-step concern and would re-seed on every save.
27
- */
28
- export async function runLivePreview(opts) {
29
- const { sessionId, tokensPath, spaceId, environmentId, cmaToken, host, generation } = opts;
30
- const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
31
- if (!spaceId || !environmentId || !cmaToken) {
32
- return { generation, response: null };
33
- }
34
- let components = [];
35
- if (sessionId) {
36
- const db = openPipelineDb();
37
- try {
38
- backfillUnclassifiedProps(db, sessionId);
39
- components = loadCDFComponents(db, sessionId);
40
- }
41
- finally {
42
- db.close();
43
- }
44
- }
45
- // Narrow to the accepted set when provided, so the preview reflects exactly
46
- // what a push of those components would create/update/remove — the session's
47
- // generated rows still include not-yet-reclassified rejects at this point.
48
- if (opts.acceptedKeys) {
49
- components = components.filter((c) => opts.acceptedKeys.has(c.key));
50
- }
51
- let tokens = [];
52
- if (tokensPath) {
53
- tokens = await readTokensFromPath('tokens', tokensPath);
54
- }
55
- const manifest = buildManifest(components, tokens, { deleteAllComponents: opts.deleteAllComponents === true });
56
- const client = new ImportApiClient({ host, cmaToken, spaceId, environmentId });
57
- const startedAt = Date.now();
58
- let timeoutHandle;
59
- const timeoutPromise = new Promise((_resolve, reject) => {
60
- timeoutHandle = setTimeout(() => reject(new TimeoutError()), timeoutMs);
61
- });
62
- try {
63
- const response = (await Promise.race([
64
- client.previewImport(manifest, opts.allowDeletions === true),
65
- timeoutPromise,
66
- ]));
67
- if (process.env['EDS_VERBOSE']) {
68
- const durationMs = Date.now() - startedAt;
69
- try {
70
- process.stderr.write(`live-preview: ${durationMs}ms\n`);
71
- }
72
- catch {
73
- // best-effort
74
- }
75
- }
76
- return { generation, response };
77
- }
78
- finally {
79
- if (timeoutHandle)
80
- clearTimeout(timeoutHandle);
81
- }
82
- }
@@ -1,28 +0,0 @@
1
- import { writeScopeDecisionsSnapshot } from '../../analyze/select/persistence.js';
2
- import { applyScopeDecisions, openPipelineDb } from '../../session/db.js';
3
- export async function runScopeGate(opts) {
4
- // Cancel-and-await BEFORE any DB / snapshot write. The subprocess's
5
- // in-flight write may complete before SIGTERM lands; that's fine — we wait
6
- // for it to fully exit, then our authoritative write goes last.
7
- if (opts.cancelAutoFilter) {
8
- await opts.cancelAutoFilter();
9
- }
10
- const db = openPipelineDb();
11
- try {
12
- applyScopeDecisions(db, opts.sessionId, opts.decisions);
13
- // Also persist a review-state snapshot so `generate components` can filter
14
- // out rejected components via loadAcceptedNames. Without this the wizard's
15
- // scope-gate decisions never reach the generator and rejected components
16
- // get processed by the LLM anyway.
17
- await writeScopeDecisionsSnapshot(db, opts.sessionId, opts.decisions);
18
- }
19
- finally {
20
- db.close();
21
- }
22
- if (opts.decisions.accepted.length > 0) {
23
- await opts.onAdvanceToGenerate({ sessionId: opts.sessionId, acceptedCount: opts.decisions.accepted.length });
24
- }
25
- else {
26
- await opts.onAdvanceToPushFlow(0);
27
- }
28
- }