@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,131 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState } from 'react';
3
- import { PALETTE } from '../theme.js';
4
- import { Box, Text } from 'ink';
5
- import { useUndo } from '../hooks/useUndo.js';
6
- import { useImmediateInput } from '../hooks/useImmediateInput.js';
7
- export function JsonEditor({ value, width, height, onSave, onDiscard }) {
8
- const undo = useUndo({
9
- lines: value.split('\n'),
10
- cursorRow: 0,
11
- cursorCol: 0,
12
- });
13
- const [scrollRow, setScrollRow] = useState(0);
14
- const [validationError, setValidationError] = useState(null);
15
- const { lines, cursorRow, cursorCol } = undo.current;
16
- const scrollCol = 0;
17
- let effectiveScrollRow = scrollRow;
18
- if (cursorRow < scrollRow)
19
- effectiveScrollRow = cursorRow;
20
- if (cursorRow >= scrollRow + height)
21
- effectiveScrollRow = cursorRow - height + 1;
22
- if (effectiveScrollRow !== scrollRow)
23
- setScrollRow(effectiveScrollRow);
24
- useImmediateInput((input, key) => {
25
- const currentLines = undo.current.lines;
26
- const currentRow = undo.current.cursorRow;
27
- const currentCol = undo.current.cursorCol;
28
- if (key.ctrl && input === 's') {
29
- const text = currentLines.join('\n');
30
- try {
31
- JSON.parse(text);
32
- setValidationError(null);
33
- onSave(text);
34
- }
35
- catch (e) {
36
- setValidationError(e instanceof Error ? e.message : String(e));
37
- }
38
- return;
39
- }
40
- if (key.escape) {
41
- onDiscard();
42
- return;
43
- }
44
- if (key.ctrl && input === 'z') {
45
- undo.undo();
46
- return;
47
- }
48
- let newLines = [...currentLines];
49
- let newRow = currentRow;
50
- let newCol = currentCol;
51
- if (key.return) {
52
- const before = newLines[currentRow].slice(0, currentCol);
53
- const after = newLines[currentRow].slice(currentCol);
54
- newLines = [...newLines.slice(0, currentRow), before, after, ...newLines.slice(currentRow + 1)];
55
- newRow = currentRow + 1;
56
- newCol = 0;
57
- }
58
- else if (key.backspace) {
59
- if (currentCol > 0) {
60
- newLines[currentRow] = newLines[currentRow].slice(0, currentCol - 1) + newLines[currentRow].slice(currentCol);
61
- newCol = currentCol - 1;
62
- }
63
- else if (currentRow > 0) {
64
- const prevLen = newLines[currentRow - 1].length;
65
- newLines[currentRow - 1] = newLines[currentRow - 1] + newLines[currentRow];
66
- newLines = [...newLines.slice(0, currentRow), ...newLines.slice(currentRow + 1)];
67
- newRow = currentRow - 1;
68
- newCol = prevLen;
69
- }
70
- }
71
- else if (key.delete) {
72
- if (currentCol < newLines[currentRow].length) {
73
- newLines[currentRow] = newLines[currentRow].slice(0, currentCol) + newLines[currentRow].slice(currentCol + 1);
74
- }
75
- else if (currentRow < newLines.length - 1) {
76
- newLines[currentRow] = newLines[currentRow] + newLines[currentRow + 1];
77
- newLines = [...newLines.slice(0, currentRow + 1), ...newLines.slice(currentRow + 2)];
78
- }
79
- }
80
- else if (key.leftArrow) {
81
- if (currentCol > 0)
82
- newCol = currentCol - 1;
83
- else if (currentRow > 0) {
84
- newRow = currentRow - 1;
85
- newCol = newLines[currentRow - 1].length;
86
- }
87
- }
88
- else if (key.rightArrow) {
89
- if (currentCol < newLines[currentRow].length)
90
- newCol = currentCol + 1;
91
- else if (currentRow < newLines.length - 1) {
92
- newRow = currentRow + 1;
93
- newCol = 0;
94
- }
95
- }
96
- else if (key.upArrow) {
97
- if (currentRow > 0) {
98
- newRow = currentRow - 1;
99
- newCol = Math.min(currentCol, newLines[currentRow - 1].length);
100
- }
101
- }
102
- else if (key.downArrow) {
103
- if (currentRow < newLines.length - 1) {
104
- newRow = currentRow + 1;
105
- newCol = Math.min(currentCol, newLines[currentRow + 1].length);
106
- }
107
- }
108
- else if (input && input.length === 1 && !key.ctrl && !key.meta) {
109
- newLines[currentRow] =
110
- newLines[currentRow].slice(0, currentCol) + input + newLines[currentRow].slice(currentCol);
111
- newCol = currentCol + 1;
112
- }
113
- else {
114
- return;
115
- }
116
- undo.push({ lines: newLines, cursorRow: newRow, cursorCol: newCol });
117
- });
118
- const innerWidth = Math.max(1, width - 2);
119
- const visibleLines = lines.slice(effectiveScrollRow, effectiveScrollRow + height);
120
- return (_jsxs(Box, { flexDirection: "column", width: width, borderStyle: "single", borderColor: PALETTE.inverse, children: [_jsx(Text, { bold: true, children: 'EDIT [EDITING — Ctrl+S save · Esc discard]' }), visibleLines.map((line, displayRow) => {
121
- const actualRow = displayRow + effectiveScrollRow;
122
- const displayLine = line.slice(scrollCol, scrollCol + innerWidth);
123
- if (actualRow === cursorRow) {
124
- const beforeCursor = displayLine.slice(0, cursorCol - scrollCol);
125
- const cursorChar = displayLine[cursorCol - scrollCol] ?? ' ';
126
- const afterCursor = displayLine.slice(cursorCol - scrollCol + 1);
127
- return (_jsxs(Box, { children: [_jsx(Text, { children: beforeCursor }), _jsx(Text, { inverse: true, children: cursorChar }), _jsx(Text, { children: afterCursor })] }, displayRow));
128
- }
129
- return _jsx(Text, { children: displayLine }, displayRow);
130
- }), validationError && _jsx(Text, { color: PALETTE.error, children: '✗ Invalid JSON: ' + validationError })] }));
131
- }
@@ -1,66 +0,0 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, Text } from 'ink';
3
- function highlightJson(line) {
4
- // Simple regex-based syntax highlighting
5
- const parts = [];
6
- let remaining = line;
7
- while (remaining.length > 0) {
8
- // Object key: "key":
9
- const keyMatch = remaining.match(/^("(?:[^"\\]|\\.)*"\s*:)/);
10
- if (keyMatch) {
11
- parts.push({ text: keyMatch[1], color: 'cyan' });
12
- remaining = remaining.slice(keyMatch[1].length);
13
- continue;
14
- }
15
- // String value
16
- const strMatch = remaining.match(/^("(?:[^"\\]|\\.)*")/);
17
- if (strMatch) {
18
- parts.push({ text: strMatch[1], color: 'green' });
19
- remaining = remaining.slice(strMatch[1].length);
20
- continue;
21
- }
22
- // Number
23
- const numMatch = remaining.match(/^(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)/);
24
- if (numMatch) {
25
- parts.push({ text: numMatch[1], color: 'yellow' });
26
- remaining = remaining.slice(numMatch[1].length);
27
- continue;
28
- }
29
- // Boolean
30
- const boolMatch = remaining.match(/^(true|false)/);
31
- if (boolMatch) {
32
- parts.push({ text: boolMatch[1], color: 'magenta' });
33
- remaining = remaining.slice(boolMatch[1].length);
34
- continue;
35
- }
36
- // Null
37
- const nullMatch = remaining.match(/^(null)/);
38
- if (nullMatch) {
39
- parts.push({ text: nullMatch[1], color: 'red', dim: true });
40
- remaining = remaining.slice(nullMatch[1].length);
41
- continue;
42
- }
43
- // Take one character as-is (punctuation, whitespace, etc.)
44
- parts.push({ text: remaining[0] });
45
- remaining = remaining.slice(1);
46
- }
47
- return (_jsx(_Fragment, { children: parts.map((part, i) => (_jsx(Text, { color: part.color, dimColor: part.dim, children: part.text }, i))) }));
48
- }
49
- function truncateLine(line, maxWidth) {
50
- if (line.length <= maxWidth)
51
- return line;
52
- return line.slice(0, maxWidth - 1) + '…';
53
- }
54
- export function JsonPanel({ label, value, scrollOffset, width, height, active }) {
55
- const allLines = value.split('\n');
56
- const visibleLines = allLines.slice(scrollOffset, scrollOffset + height);
57
- const innerWidth = Math.max(1, width - 2); // subtract border
58
- const totalLines = allLines.length;
59
- const truncated = totalLines > height;
60
- const visibleStart = totalLines === 0 ? 0 : scrollOffset + 1;
61
- const visibleEnd = Math.min(totalLines, scrollOffset + height);
62
- return (_jsxs(Box, { flexDirection: "column", width: width, height: height + 2, borderStyle: "single", borderColor: active ? 'white' : undefined, children: [_jsxs(Box, { children: [_jsx(Text, { bold: true, dimColor: !active, children: label }), truncated && (_jsxs(_Fragment, { children: [_jsx(Box, { flexGrow: 1 }), _jsx(Text, { dimColor: !active, children: `↕ ${visibleStart}-${visibleEnd}/${totalLines}` })] }))] }), visibleLines.map((line, i) => {
63
- const truncated = truncateLine(line, innerWidth);
64
- return _jsx(Box, { children: highlightJson(truncated) }, i);
65
- })] }));
66
- }
@@ -1,22 +0,0 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import { PALETTE } from '../theme.js';
3
- import { Text } from 'ink';
4
- import { GotoBanner } from './GotoBanner.js';
5
- const LINEAGE_FOOTER_HINT = '[↑/↓] move · [Enter] jump · [l/Esc] close';
6
- export function LineagePanel({ focusedComponentKey, entries, cursor, jumpables, maxRows, width, }) {
7
- const rows = entries.map((e) => ({
8
- label: e.label,
9
- jumpTarget: e.kind === 'ancestor' || e.kind === 'descendant' ? e.jumpTarget : '',
10
- kind: e.kind,
11
- }));
12
- const cursorRowIndex = jumpables[cursor]?.i ?? 0;
13
- return (_jsx(GotoBanner, { title: `Lineage: ${focusedComponentKey}`, rows: rows, cursor: cursor, cursorRowIndex: cursorRowIndex, maxRows: maxRows, width: width, footerHint: LINEAGE_FOOTER_HINT, renderRow: (row, i, isCursor) => {
14
- if (row.kind === 'section') {
15
- return (_jsxs(Text, { bold: true, children: [' ', row.label] }, i));
16
- }
17
- if (row.kind === 'empty') {
18
- return (_jsxs(Text, { children: [_jsx(Text, { children: " " }), _jsx(Text, { dimColor: true, children: ' ' + row.label })] }, i));
19
- }
20
- return (_jsxs(Text, { children: [isCursor ? (_jsx(Text, { color: PALETTE.info, bold: true, children: '▶' })) : (_jsx(Text, { children: " " })), _jsx(Text, { inverse: isCursor, children: ' ' + row.label })] }, i));
21
- } }));
22
- }
@@ -1,29 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, Text } from 'ink';
3
- export function PreviewSummaryBar({ preview, loading }) {
4
- if (!preview && !loading) {
5
- return _jsx(Box, {});
6
- }
7
- if (loading && !preview) {
8
- return (_jsx(Box, { gap: 1, children: _jsx(Text, { dimColor: true, children: "\u21BB Loading preview..." }) }));
9
- }
10
- const comp = preview.components;
11
- const tok = preview.tokens;
12
- const parts = [];
13
- const newCount = comp.new.length + tok.new.length;
14
- const changedCount = comp.changed.length + tok.changed.length;
15
- const removedCount = comp.removed.length + tok.removed.length;
16
- const unchangedCount = comp.unchanged.length + tok.unchanged.length;
17
- if (newCount > 0)
18
- parts.push({ label: `${newCount} new`, color: 'green' });
19
- if (changedCount > 0)
20
- parts.push({ label: `${changedCount} changed`, color: 'yellow' });
21
- if (removedCount > 0)
22
- parts.push({ label: `${removedCount} removed`, color: 'red' });
23
- if (unchangedCount > 0)
24
- parts.push({ label: `${unchangedCount} unchanged`, color: 'gray' });
25
- if (parts.length === 0 && !loading) {
26
- return (_jsx(Box, { gap: 1, children: _jsx(Text, { dimColor: true, children: "Preview: no changes detected" }) }));
27
- }
28
- return (_jsxs(Box, { gap: 1, children: [_jsx(Text, { dimColor: true, children: "Preview:" }), parts.map((part, i) => (_jsx(Text, { color: part.color, children: part.label }, i))), loading && _jsx(Text, { dimColor: true, children: "\u21BB" })] }));
29
- }
@@ -1,14 +0,0 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, Text } from 'ink';
3
- import { useImmediateInput } from '../hooks/useImmediateInput.js';
4
- export function QuitDialog({ hasUnsavedDrafts, onConfirm, onCancel }) {
5
- useImmediateInput((input, key) => {
6
- if (input === 'y' || key.return) {
7
- onConfirm();
8
- }
9
- else if (input === 'n' || key.escape) {
10
- onCancel();
11
- }
12
- });
13
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", padding: 1, width: 50, children: [_jsx(Text, { bold: true, children: '─'.repeat(19) + ' Quit ' + '─'.repeat(19) }), _jsx(Text, { children: " " }), hasUnsavedDrafts ? (_jsxs(_Fragment, { children: [_jsx(Text, { children: "You have unsaved draft edits." }), _jsx(Text, { children: 'Session state is preserved — you can resume' }), _jsx(Text, { children: 'by running the same review command again.' })] })) : (_jsx(Text, { children: "Session is saved. Quit without finalizing?" })), _jsx(Text, { children: " " }), _jsx(Text, { children: ' [y / Enter] Quit [n / Esc] Stay' })] }));
14
- }
@@ -1,80 +0,0 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { PALETTE } from '../theme.js';
3
- import { Box, Text } from 'ink';
4
- function wrapText(text, innerWidth) {
5
- if (!text)
6
- return [''];
7
- const width = Math.max(1, innerWidth);
8
- const words = text.split(/\s+/).filter((w) => w.length > 0);
9
- if (words.length === 0)
10
- return [''];
11
- const lines = [];
12
- let current = '';
13
- for (const w of words) {
14
- if (current.length === 0) {
15
- if (w.length > width) {
16
- let rest = w;
17
- while (rest.length > width) {
18
- lines.push(rest.slice(0, width));
19
- rest = rest.slice(width);
20
- }
21
- current = rest;
22
- }
23
- else {
24
- current = w;
25
- }
26
- continue;
27
- }
28
- if (current.length + 1 + w.length <= width) {
29
- current += ' ' + w;
30
- }
31
- else {
32
- lines.push(current);
33
- if (w.length > width) {
34
- let rest = w;
35
- while (rest.length > width) {
36
- lines.push(rest.slice(0, width));
37
- rest = rest.slice(width);
38
- }
39
- current = rest;
40
- }
41
- else {
42
- current = w;
43
- }
44
- }
45
- }
46
- if (current.length > 0)
47
- lines.push(current);
48
- return lines.length > 0 ? lines : [''];
49
- }
50
- export function renderRationaleLines(rows, innerWidth) {
51
- const out = [];
52
- rows.forEach((row, idx) => {
53
- out.push({ kind: 'name', text: row.name, isSlot: row.kind === 'slot' });
54
- for (const line of wrapText(row.rationale, innerWidth)) {
55
- out.push({ kind: 'text', text: line });
56
- }
57
- if (idx < rows.length - 1) {
58
- out.push({ kind: 'blank' });
59
- }
60
- });
61
- return out;
62
- }
63
- export function RationalePanel({ componentName, rows, scrollOffset, width, height, active, }) {
64
- const innerWidth = Math.max(1, width - 2); // subtract border
65
- const allLines = renderRationaleLines(rows, innerWidth);
66
- const totalLines = allLines.length;
67
- const visible = allLines.slice(scrollOffset, scrollOffset + height);
68
- const overflowed = totalLines > height;
69
- const visibleStart = totalLines === 0 ? 0 : scrollOffset + 1;
70
- const visibleEnd = Math.min(totalLines, scrollOffset + height);
71
- return (_jsxs(Box, { flexDirection: "column", width: width, height: height + 2, borderStyle: "single", borderColor: active ? PALETTE.inverse : undefined, children: [_jsxs(Box, { children: [_jsx(Text, { bold: true, dimColor: !active, children: `RATIONALE — ${componentName}` }), overflowed && (_jsxs(_Fragment, { children: [_jsx(Box, { flexGrow: 1 }), _jsx(Text, { dimColor: !active, children: `↕ ${visibleStart}-${visibleEnd}/${totalLines}` })] }))] }), visible.map((line, i) => {
72
- if (line.kind === 'blank') {
73
- return (_jsx(Box, { children: _jsx(Text, { children: " " }) }, i));
74
- }
75
- if (line.kind === 'name') {
76
- return (_jsxs(Box, { children: [_jsx(Text, { bold: true, color: PALETTE.info, dimColor: !active, children: line.text }), line.isSlot && _jsx(Text, { dimColor: true, children: " (slot)" })] }, i));
77
- }
78
- return (_jsx(Box, { children: _jsx(Text, { dimColor: !active, children: line.text }) }, i));
79
- })] }));
80
- }
@@ -1,92 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, Text } from 'ink';
3
- import { PALETTE } from '../theme.js';
4
- export function previewBadge(annotation) {
5
- switch (annotation) {
6
- case 'new':
7
- return { char: '+', color: PALETTE.success };
8
- case 'changed':
9
- return { char: '~', color: PALETTE.warning };
10
- case 'removed':
11
- return { char: '-', color: PALETTE.error, dim: true };
12
- case 'breaking':
13
- return { char: '!', color: PALETTE.error, bold: true };
14
- default:
15
- return null;
16
- }
17
- }
18
- export function statusIcon(status, validationErrorCount,
19
- // Warnings deliberately do NOT override the icon — the user's accept/reject
20
- // decision must remain visible. Color is already yellow via statusColor for
21
- // warning-only components, so the warning cue is preserved.
22
- _validationWarningCount) {
23
- if (validationErrorCount > 0)
24
- return '⚠';
25
- switch (status) {
26
- case 'accepted':
27
- return '✓';
28
- case 'rejected':
29
- return '✗';
30
- case 'reviewed':
31
- return '~';
32
- case 'needs-review':
33
- return '·';
34
- }
35
- }
36
- export function statusColor(status, validationErrorCount, validationWarningCount) {
37
- if (validationErrorCount > 0)
38
- return PALETTE.error;
39
- if (validationWarningCount > 0)
40
- return PALETTE.warning;
41
- switch (status) {
42
- case 'accepted':
43
- return PALETTE.success;
44
- case 'rejected':
45
- return PALETTE.error;
46
- case 'reviewed':
47
- return PALETTE.warning;
48
- case 'needs-review':
49
- return PALETTE.muted;
50
- }
51
- }
52
- function truncateName(name, maxLen) {
53
- if (name.length <= maxLen)
54
- return name;
55
- return name.slice(0, maxLen) + '…';
56
- }
57
- function withinTierComparator(a, b) {
58
- const aPending = a.needsReview && a.status === 'needs-review' ? 0 : 1;
59
- const bPending = b.needsReview && b.status === 'needs-review' ? 0 : 1;
60
- if (aPending !== bPending)
61
- return aPending - bPending;
62
- return (a.extractionConfidence ?? 6) - (b.extractionConfidence ?? 6);
63
- }
64
- export function sortComponentsForSidebar(components) {
65
- const withErrors = components.filter((c) => c.validationErrorCount > 0);
66
- const withWarnings = components.filter((c) => c.validationErrorCount === 0 && c.validationWarningCount > 0);
67
- const clean = components.filter((c) => c.validationErrorCount === 0 && c.validationWarningCount === 0);
68
- return [
69
- ...[...withErrors].sort(withinTierComparator),
70
- ...[...withWarnings].sort(withinTierComparator),
71
- ...[...clean].sort(withinTierComparator),
72
- ];
73
- }
74
- export function Sidebar({ components, selectedId, focused, scrollOffset, visibleCount, collapsed = false, width: widthProp, }) {
75
- const sorted = sortComponentsForSidebar(components);
76
- const visible = sorted.slice(scrollOffset, scrollOffset + visibleCount);
77
- const showScrollUp = scrollOffset > 0;
78
- const showScrollDown = scrollOffset + visibleCount < sorted.length;
79
- const width = collapsed ? 3 : (widthProp ?? 18);
80
- return (_jsxs(Box, { flexDirection: "column", width: width, flexShrink: 0, borderStyle: "single", borderColor: focused ? 'white' : undefined, children: [showScrollUp && !collapsed && _jsx(Text, { dimColor: true, children: "\u25B2" }), visible.map((component) => {
81
- const isSelected = component.id === selectedId;
82
- const icon = statusIcon(component.status, component.validationErrorCount, component.validationWarningCount);
83
- const color = statusColor(component.status, component.validationErrorCount, component.validationWarningCount);
84
- const badge = previewBadge(component.previewAnnotation);
85
- const maxNameLen = Math.max(1, width - 5);
86
- const name = truncateName(component.name, maxNameLen);
87
- if (collapsed) {
88
- return (_jsx(Box, { children: _jsx(Text, { color: color, inverse: isSelected && focused, underline: isSelected && !focused, children: icon }) }, component.id));
89
- }
90
- return (_jsxs(Box, { children: [_jsx(Text, { color: color, inverse: isSelected && focused, underline: isSelected && !focused, children: icon }), badge ? (_jsx(Text, { color: badge.color, bold: badge.bold, dimColor: badge.dim, children: badge.char })) : (_jsx(Text, { children: " " })), _jsx(Text, { color: color, inverse: isSelected && focused, underline: isSelected && !focused, wrap: "truncate", children: ' ' + name })] }, component.id));
91
- }), showScrollDown && !collapsed && _jsx(Text, { dimColor: true, children: "\u25BC" })] }));
92
- }
@@ -1,52 +0,0 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, Text } from 'ink';
3
- const KEYWORDS = /\b(function|export|const|let|import|return|interface|type|default|class|extends|implements|from|async|await)\b/;
4
- function highlightSourceLine(line) {
5
- const parts = [];
6
- let remaining = line;
7
- while (remaining.length > 0) {
8
- // String literal
9
- const strMatch = remaining.match(/^("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|`(?:[^`\\]|\\.)*`)/);
10
- if (strMatch) {
11
- parts.push({ text: strMatch[1], color: 'green' });
12
- remaining = remaining.slice(strMatch[1].length);
13
- continue;
14
- }
15
- // Keyword
16
- const kwMatch = remaining.match(KEYWORDS);
17
- if (kwMatch && kwMatch.index === 0) {
18
- parts.push({ text: kwMatch[0], color: 'cyan' });
19
- remaining = remaining.slice(kwMatch[0].length);
20
- continue;
21
- }
22
- parts.push({ text: remaining[0] });
23
- remaining = remaining.slice(1);
24
- }
25
- return (_jsx(_Fragment, { children: parts.map((part, i) => (_jsx(Text, { color: part.color, children: part.text }, i))) }));
26
- }
27
- function truncateFilePath(filePath, maxWidth) {
28
- if (filePath.length <= maxWidth)
29
- return filePath;
30
- const filename = filePath.split('/').pop() ?? filePath;
31
- if (filename.length >= maxWidth)
32
- return filename.slice(0, maxWidth - 1) + '…';
33
- return '…' + filePath.slice(filePath.length - (maxWidth - 1));
34
- }
35
- export function SourcePanel({ sourceCode, filePath, width, height, scrollX, scrollY, }) {
36
- const innerWidth = Math.max(1, width - 2);
37
- const header = truncateFilePath(filePath, innerWidth);
38
- if (!sourceCode) {
39
- return (_jsxs(Box, { flexDirection: "column", width: width, height: height + 2, borderStyle: "single", children: [_jsx(Text, { dimColor: true, children: header }), _jsx(Box, { justifyContent: "center", alignItems: "center", height: height, children: _jsx(Text, { dimColor: true, children: "[No source available]" }) })] }));
40
- }
41
- const allLines = sourceCode.split('\n');
42
- const visibleLines = allLines.slice(scrollY, scrollY + height);
43
- const showScrollUp = scrollY > 0;
44
- const showScrollDown = scrollY + height < allLines.length;
45
- const maxLineWidth = Math.max(...visibleLines.map((l) => l.length));
46
- const showScrollLeft = scrollX > 0;
47
- const showScrollRight = scrollX + innerWidth < maxLineWidth;
48
- return (_jsxs(Box, { flexDirection: "column", width: width, height: height + 2, borderStyle: "single", children: [_jsxs(Box, { justifyContent: "space-between", children: [_jsx(Text, { dimColor: true, children: header }), _jsxs(Text, { dimColor: true, children: [showScrollUp ? '▲' : ' ', showScrollDown ? '▼' : ' ', showScrollLeft ? '◀' : ' ', showScrollRight ? '▶' : ' '] })] }), visibleLines.map((line, i) => {
49
- const sliced = line.slice(scrollX, scrollX + innerWidth);
50
- return _jsx(Box, { children: highlightSourceLine(sliced) }, i);
51
- })] }));
52
- }
@@ -1,7 +0,0 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import { Box, Text } from 'ink';
3
- import { PALETTE } from '../theme.js';
4
- export function StatusBar({ accepted, rejected, reviewed, needsReview }) {
5
- const allResolved = needsReview === 0;
6
- return (_jsxs(Box, { gap: 2, flexWrap: "wrap", children: [_jsxs(Text, { color: PALETTE.success, children: [accepted, " accepted"] }), _jsxs(Text, { color: PALETTE.error, children: [rejected, " rejected"] }), _jsxs(Text, { dimColor: true, children: [needsReview, " pending"] }), _jsxs(Text, { color: PALETTE.info, children: [reviewed, " reviewed"] }), _jsx(Text, { dimColor: true, children: "\u00B7" }), _jsx(Text, { dimColor: true, children: "[A] accept all" }), _jsx(Text, { bold: allResolved, color: allResolved ? PALETTE.success : PALETTE.fg, children: "[F] finalize" })] }));
7
- }
@@ -1,10 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { createRequire } from 'node:module';
3
- import { Box, Text } from 'ink';
4
- // createRequire is needed because this is an ESM package — require() doesn't
5
- // exist natively, but it's the simplest way to read a JSON file at runtime.
6
- const _require = createRequire(import.meta.url);
7
- const VERSION = _require('../../../../../package.json').version;
8
- export function TopBar({ subcommand, hints }) {
9
- return (_jsxs(Box, { justifyContent: "space-between", children: [_jsx(Text, { bold: true, children: 'experience-design-system-cli ' + subcommand }), _jsxs(Text, { dimColor: true, children: [hints.map((h) => `[${h.key}] ${h.label}`).join(' '), ' v' + VERSION] })] }));
10
- }
@@ -1,11 +0,0 @@
1
- /** Header line for the removed-components surfaces (deletion panel + finalize
2
- * dialog). Kept in one place so both read identically. `withExpandHint` adds
3
- * the panel's "[d] to expand/collapse" affordance, which the dialog omits. */
4
- export function removedComponentsHeader(count, withExpandHint) {
5
- const hint = withExpandHint ? ' (press [d] to expand/collapse)' : '';
6
- return `Removed components (${count}) — will be DELETED from target space${hint}`;
7
- }
8
- /** One bullet line per removed component, matching the deletion panel. */
9
- export function removedComponentLine(rc) {
10
- return `- ${rc.name}${rc.id ? ` (${rc.id})` : ''}`;
11
- }
@@ -1,26 +0,0 @@
1
- export function computeNextScrollOffset(current, input, key, totalLines, panelHeight) {
2
- const maxOffset = Math.max(0, totalLines - panelHeight);
3
- const halfPage = Math.max(1, Math.floor(panelHeight / 2));
4
- if (key.ctrl && input === 'd') {
5
- return Math.min(maxOffset, current + halfPage);
6
- }
7
- if (key.ctrl && input === 'u') {
8
- return Math.max(0, current - halfPage);
9
- }
10
- if (key.downArrow || input === 'j') {
11
- return Math.min(maxOffset, current + 1);
12
- }
13
- if (key.upArrow || input === 'k') {
14
- return Math.max(0, current - 1);
15
- }
16
- if (key.pageDown) {
17
- return Math.min(maxOffset, current + panelHeight);
18
- }
19
- if (key.pageUp) {
20
- return Math.max(0, current - panelHeight);
21
- }
22
- if (input === 'G') {
23
- return maxOffset;
24
- }
25
- return null;
26
- }
@@ -1,66 +0,0 @@
1
- import { useLayoutEffect, useRef } from 'react';
2
- import { useStdin } from 'ink';
3
- function parseInput(data) {
4
- // Shift-Tab in most terminals emits CSI Z (\x1b[Z). We surface it as both
5
- // `tab` and `shiftTab` so callers that already branch on `tab` still fire,
6
- // and new callers can distinguish direction via `shiftTab`.
7
- const isShiftTab = data === '\x1b[Z';
8
- const key = {
9
- upArrow: data === '\x1b[A',
10
- downArrow: data === '\x1b[B',
11
- leftArrow: data === '\x1b[D',
12
- rightArrow: data === '\x1b[C',
13
- pageDown: data === '\x1b[6~',
14
- pageUp: data === '\x1b[5~',
15
- return: data === '\r' || data === '\n',
16
- escape: data === '\x1b',
17
- ctrl: false,
18
- shift: isShiftTab,
19
- tab: data === '\t' || isShiftTab,
20
- shiftTab: isShiftTab,
21
- backspace: data === '\x7f' || data === '\b',
22
- delete: data === '\x1b[3~',
23
- meta: data === '\x1b',
24
- };
25
- let input = data;
26
- if (data.length === 1) {
27
- const code = data.charCodeAt(0);
28
- if (code >= 1 && code <= 26) {
29
- key.ctrl = true;
30
- input = String.fromCharCode(code + 96);
31
- }
32
- }
33
- if (key.upArrow ||
34
- key.downArrow ||
35
- key.leftArrow ||
36
- key.rightArrow ||
37
- key.pageUp ||
38
- key.pageDown ||
39
- key.return ||
40
- key.escape ||
41
- key.tab ||
42
- key.backspace ||
43
- key.delete) {
44
- if (!key.ctrl)
45
- input = '';
46
- }
47
- return { input, key };
48
- }
49
- export function useImmediateInput(handler) {
50
- const { stdin, setRawMode } = useStdin();
51
- const handlerRef = useRef(handler);
52
- handlerRef.current = handler;
53
- useLayoutEffect(() => {
54
- setRawMode(true);
55
- const handleData = (data) => {
56
- const str = Buffer.isBuffer(data) ? data.toString('utf8') : data;
57
- const { input, key } = parseInput(str);
58
- handlerRef.current(input, key);
59
- };
60
- stdin.on('data', handleData);
61
- return () => {
62
- stdin.off('data', handleData);
63
- setRawMode(false);
64
- };
65
- }, [stdin, setRawMode]);
66
- }