@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.
- package/dist/package.json +14 -10
- package/dist/src/index.js +34937 -9
- package/dist/src/lib/cli-path.d.ts +4 -0
- package/dist/src/runs/export-helpers.d.ts +1 -12
- package/dist/src/runs/push-helpers.d.ts +1 -6
- package/package.json +12 -7
- package/skills/generate-components.md +427 -0
- package/skills/generate-tokens.md +194 -0
- package/skills/select-components.md +224 -0
- package/dist/src/analytics/apply.js +0 -30
- package/dist/src/analytics/client.js +0 -81
- package/dist/src/analytics/constants.js +0 -4
- package/dist/src/analytics/env.js +0 -14
- package/dist/src/analytics/exit.js +0 -24
- package/dist/src/analytics/index.js +0 -9
- package/dist/src/analytics/normalize.js +0 -18
- package/dist/src/analytics/os.js +0 -13
- package/dist/src/analytics/session.js +0 -15
- package/dist/src/analytics/tracker.js +0 -126
- package/dist/src/analytics/types.js +0 -1
- package/dist/src/analyze/build-analyze-view-rows.js +0 -63
- package/dist/src/analyze/command.js +0 -599
- package/dist/src/analyze/composite-closure.js +0 -0
- package/dist/src/analyze/composition/agent-parser/author-prompt.js +0 -22
- package/dist/src/analyze/composition/agent-parser/extract-parser.js +0 -44
- package/dist/src/analyze/composition/agent-parser/load-prompt.js +0 -31
- package/dist/src/analyze/composition/agent-parser/resolve-via-parser.js +0 -88
- package/dist/src/analyze/composition/agent-parser/sandbox.js +0 -187
- package/dist/src/analyze/composition/apply-mapping.js +0 -67
- package/dist/src/analyze/composition/candidate-critic-agent.js +0 -39
- package/dist/src/analyze/composition/candidate-critic.js +0 -63
- package/dist/src/analyze/composition/candidate-files.js +0 -131
- package/dist/src/analyze/composition/composition-cache-key.js +0 -19
- package/dist/src/analyze/composition/interchange-schema.js +0 -61
- package/dist/src/analyze/composition/manifest-doc-evidence.js +0 -136
- package/dist/src/analyze/composition/merge-edges.js +0 -70
- package/dist/src/analyze/composition/parse-map-edges.js +0 -55
- package/dist/src/analyze/composition/resolve-mapping-cli.js +0 -29
- package/dist/src/analyze/composition/resolve-mapping.js +0 -111
- package/dist/src/analyze/cycle-detection.js +0 -234
- package/dist/src/analyze/cycle-view.js +0 -28
- package/dist/src/analyze/fuzzy-search.js +0 -55
- package/dist/src/analyze/issue-inheritance.js +0 -108
- package/dist/src/analyze/lineage.js +0 -0
- package/dist/src/analyze/scope-gate-cascade.js +0 -170
- package/dist/src/analyze/search-neighborhood.js +0 -56
- package/dist/src/analyze/select/command.js +0 -484
- package/dist/src/analyze/select/index.js +0 -5
- package/dist/src/analyze/select/parser.js +0 -53
- package/dist/src/analyze/select/persistence.js +0 -80
- package/dist/src/analyze/select/preview-annotations.js +0 -62
- package/dist/src/analyze/select/stdout.js +0 -3
- package/dist/src/analyze/select/tui/App.js +0 -483
- package/dist/src/analyze/select/tui/components/ComponentDetail.js +0 -48
- package/dist/src/analyze/select/tui/components/ComponentRationalePanel.js +0 -125
- package/dist/src/analyze/select/tui/components/FieldEditor.js +0 -1131
- package/dist/src/analyze/select/tui/components/FinalizeDialog.js +0 -36
- package/dist/src/analyze/select/tui/components/GotoBanner.js +0 -30
- package/dist/src/analyze/select/tui/components/GroupedSidebar.js +0 -517
- package/dist/src/analyze/select/tui/components/HelpOverlay.js +0 -17
- package/dist/src/analyze/select/tui/components/JsonEditor.js +0 -131
- package/dist/src/analyze/select/tui/components/JsonPanel.js +0 -66
- package/dist/src/analyze/select/tui/components/LineagePanel.js +0 -22
- package/dist/src/analyze/select/tui/components/PreviewSummaryBar.js +0 -29
- package/dist/src/analyze/select/tui/components/QuitDialog.js +0 -14
- package/dist/src/analyze/select/tui/components/RationalePanel.js +0 -80
- package/dist/src/analyze/select/tui/components/Sidebar.js +0 -92
- package/dist/src/analyze/select/tui/components/SourcePanel.js +0 -52
- package/dist/src/analyze/select/tui/components/StatusBar.js +0 -7
- package/dist/src/analyze/select/tui/components/TopBar.js +0 -10
- package/dist/src/analyze/select/tui/components/removed-components-text.js +0 -11
- package/dist/src/analyze/select/tui/hooks/scroll-offset.js +0 -26
- package/dist/src/analyze/select/tui/hooks/useImmediateInput.js +0 -66
- package/dist/src/analyze/select/tui/hooks/useKeymap.js +0 -67
- package/dist/src/analyze/select/tui/hooks/useSession.js +0 -52
- package/dist/src/analyze/select/tui/hooks/useUndo.js +0 -26
- package/dist/src/analyze/select/tui/theme.js +0 -28
- package/dist/src/analyze/select/types.js +0 -39
- package/dist/src/analyze/select-agent/command.js +0 -558
- package/dist/src/analyze/select-agent/context-builder.js +0 -197
- package/dist/src/analyze/select-agent/show-rationale.js +0 -92
- package/dist/src/analyze/selection-cascade.js +0 -19
- package/dist/src/analyze/slot-graph.js +0 -17
- package/dist/src/analyze/tui/AnalyzeView.js +0 -64
- package/dist/src/apply/api-client.js +0 -440
- package/dist/src/apply/command.js +0 -845
- package/dist/src/apply/manifest.js +0 -1
- package/dist/src/apply/preview-utils.js +0 -26
- package/dist/src/apply/tui/SelectView.js +0 -34
- package/dist/src/apply/tui/ServerApplyView.js +0 -49
- package/dist/src/apply/tui/ServerPreviewView.js +0 -23
- package/dist/src/credentials-store.js +0 -74
- package/dist/src/generate/command.js +0 -597
- package/dist/src/generate/edit/command.js +0 -127
- package/dist/src/generate/tui/GenerateView.js +0 -10
- package/dist/src/host-utils.js +0 -26
- package/dist/src/import/agent-model-resolve.js +0 -35
- package/dist/src/import/auto-filter-resolve.js +0 -16
- package/dist/src/import/command.js +0 -380
- package/dist/src/import/cycle-auto-reject.js +0 -14
- package/dist/src/import/orchestrator.js +0 -603
- package/dist/src/import/path-utils.js +0 -30
- package/dist/src/import/picker-dispatch.js +0 -44
- package/dist/src/import/print-prompt.js +0 -31
- package/dist/src/import/strip-allowed-components.js +0 -22
- package/dist/src/import/tui/CustomPromptBanner.js +0 -8
- package/dist/src/import/tui/WizardApp.js +0 -1670
- package/dist/src/import/tui/ai-flag.js +0 -6
- package/dist/src/import/tui/auto-filter-error.js +0 -29
- package/dist/src/import/tui/autocomplete.js +0 -32
- package/dist/src/import/tui/components/AutoFilterBanner.js +0 -19
- package/dist/src/import/tui/components/CounterStrip.js +0 -12
- package/dist/src/import/tui/components/LegendEntry.js +0 -6
- package/dist/src/import/tui/cycle-panel-scroll.js +0 -33
- package/dist/src/import/tui/final-review-host.js +0 -25
- package/dist/src/import/tui/group-collapse.js +0 -11
- package/dist/src/import/tui/history.js +0 -53
- package/dist/src/import/tui/hooks/useLineage.js +0 -50
- package/dist/src/import/tui/hooks/useOverlayPanel.js +0 -27
- package/dist/src/import/tui/lineage-layout.js +0 -82
- package/dist/src/import/tui/merge-ai-decisions.js +0 -22
- package/dist/src/import/tui/push-decision-gate-helpers.js +0 -8
- package/dist/src/import/tui/push-progress.js +0 -1
- package/dist/src/import/tui/run-print-files-helpers.js +0 -8
- package/dist/src/import/tui/run-teaser.js +0 -9
- package/dist/src/import/tui/runLivePreview.js +0 -82
- package/dist/src/import/tui/runScopeGate.js +0 -28
- package/dist/src/import/tui/scope-gate-columns.js +0 -94
- package/dist/src/import/tui/scope-gate-host.js +0 -28
- package/dist/src/import/tui/sidebar-width.js +0 -3
- package/dist/src/import/tui/spawn-generate.js +0 -53
- package/dist/src/import/tui/step-filters.js +0 -42
- package/dist/src/import/tui/steps/AtomicGenerateReviewStep.js +0 -726
- package/dist/src/import/tui/steps/AtomicScopeGateStep.js +0 -210
- package/dist/src/import/tui/steps/CredentialsStep.js +0 -108
- package/dist/src/import/tui/steps/DoneStep.js +0 -24
- package/dist/src/import/tui/steps/ErrorStep.js +0 -16
- package/dist/src/import/tui/steps/GateStep.js +0 -22
- package/dist/src/import/tui/steps/GenerateReviewStep.js +0 -1618
- package/dist/src/import/tui/steps/PathValidationStep.js +0 -152
- package/dist/src/import/tui/steps/PreviewStep.js +0 -37
- package/dist/src/import/tui/steps/PreviewValidationErrorStep.js +0 -23
- package/dist/src/import/tui/steps/PushDecisionGateStep.js +0 -73
- package/dist/src/import/tui/steps/PushingStep.js +0 -24
- package/dist/src/import/tui/steps/RunningStep.js +0 -21
- package/dist/src/import/tui/steps/ScopeGateStep.js +0 -907
- package/dist/src/import/tui/steps/TokenInputStep.js +0 -88
- package/dist/src/import/tui/steps/WelcomeStep.js +0 -34
- package/dist/src/import/tui/steps/WizardPreviewStep.js +0 -169
- package/dist/src/import/tui/steps/auto-reject-decision.js +0 -9
- package/dist/src/import/tui/steps/breaking-change-format.js +0 -24
- package/dist/src/import/tui/steps/enumerate-cycle-breaks.js +0 -0
- package/dist/src/import/tui/steps/preview-diff.js +0 -175
- package/dist/src/import/tui/useFinalizePreview.js +0 -0
- package/dist/src/import/tui/useLivePreview.js +0 -122
- package/dist/src/import/tui/wizard-422-helpers.js +0 -60
- package/dist/src/import/tui/wizard-generate-progress.js +0 -25
- package/dist/src/import/tui/wizard-save-flow.js +0 -20
- package/dist/src/import/tui/wizard-state-transitions.js +0 -32
- package/dist/src/lib/agent-model-options.js +0 -15
- package/dist/src/lib/command-options.js +0 -30
- package/dist/src/lib/composition-mode.js +0 -39
- package/dist/src/lib/contentful-urls.js +0 -27
- package/dist/src/lib/debug-logger.js +0 -229
- package/dist/src/lib/debug-preamble.js +0 -33
- package/dist/src/lib/error-parser.js +0 -269
- package/dist/src/lib/prompt-overrides.js +0 -69
- package/dist/src/lib/terminal-capabilities.js +0 -51
- package/dist/src/lib/user-agent.js +0 -29
- package/dist/src/output/format.js +0 -110
- package/dist/src/print/command.js +0 -221
- package/dist/src/print/validate/tui/ValidateView.js +0 -37
- package/dist/src/print/validate/validators/cdf-validator.js +0 -104
- package/dist/src/print/validate/validators/dtcg-validator.js +0 -110
- package/dist/src/print/validate/validators/format-errors.js +0 -18
- package/dist/src/program.js +0 -105
- package/dist/src/runs/export-helpers.js +0 -59
- package/dist/src/runs/fingerprint.js +0 -75
- package/dist/src/runs/ls-command.js +0 -137
- package/dist/src/runs/modify-launcher.js +0 -42
- package/dist/src/runs/path-prompt.js +0 -72
- package/dist/src/runs/push-creds-prompt.js +0 -39
- package/dist/src/runs/push-helpers.js +0 -72
- package/dist/src/runs/push-launcher.js +0 -77
- package/dist/src/runs/replay-helpers.js +0 -164
- package/dist/src/runs/resolve-run-target.js +0 -45
- package/dist/src/runs/run-picker-mount.js +0 -72
- package/dist/src/runs/run-picker.js +0 -129
- package/dist/src/runs/save-conflict.js +0 -56
- package/dist/src/runs/save-path-resolver.js +0 -75
- package/dist/src/runs/staleness.js +0 -140
- package/dist/src/runs/store.js +0 -136
- package/dist/src/session/cache-keys.js +0 -44
- package/dist/src/session/command.js +0 -261
- package/dist/src/session/db.js +0 -1538
- package/dist/src/session/migration.js +0 -117
- package/dist/src/session/session-id.js +0 -212
- package/dist/src/session/stats.js +0 -89
- package/dist/src/setup/analytics-prompt.js +0 -24
- package/dist/src/setup/auto-filter-prompt.js +0 -24
- package/dist/src/setup/command.js +0 -966
- package/dist/src/setup/composition-mode-prompt.js +0 -37
- package/dist/src/setup/debug-mode-prompt.js +0 -22
- package/dist/src/types.js +0 -1
|
@@ -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,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
|
-
}
|