@contentful/experience-design-system-cli 2.12.1-dev-build-589b615.0 → 2.12.1-dev-build-bae15c7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +1 -1
- package/dist/src/analyze/select-agent/command.js +1 -0
- package/dist/src/import/tui/WizardApp.d.ts +1 -1
- package/dist/src/import/tui/WizardApp.js +7 -1
- package/dist/src/import/tui/merge-ai-decisions.d.ts +5 -0
- package/dist/src/import/tui/merge-ai-decisions.js +22 -0
- package/dist/src/import/tui/steps/ScopeGateStep.d.ts +1 -1
- package/dist/src/import/tui/steps/ScopeGateStep.js +10 -3
- package/package.json +2 -2
package/dist/package.json
CHANGED
|
@@ -167,6 +167,7 @@ async function selectBatch(agent, model, batch, total, verbose, skillPathOverrid
|
|
|
167
167
|
const call = calls.find((toolCall) => toolCall.name === component.name);
|
|
168
168
|
if (!call) {
|
|
169
169
|
process.stderr.write(` ${pos} ${c.bold(component.name)} ${c.yellow('no tool call')}\n`);
|
|
170
|
+
emitProgress(item, 'failed', 'no-tool-call-from-agent');
|
|
170
171
|
results.push({
|
|
171
172
|
componentKey: componentKey(component),
|
|
172
173
|
componentName: component.name,
|
|
@@ -40,6 +40,7 @@ import { readTokensFromPath, hasBreakingChangesWithImpact } from '../../apply/ma
|
|
|
40
40
|
import { buildManifest } from '@contentful/experience-design-system-types';
|
|
41
41
|
import { openPipelineDb, loadCDFComponents, loadScopeComponents, seedCDFFromPreviewResponse, seedDefaultsFromChangedItems, backfillUnclassifiedProps, } from '../../session/db.js';
|
|
42
42
|
import { ScopeGateHost } from './scope-gate-host.js';
|
|
43
|
+
import { mergeAiDecisions } from './merge-ai-decisions.js';
|
|
43
44
|
import { FinalReviewHost } from './final-review-host.js';
|
|
44
45
|
import { runScopeGate } from './runScopeGate.js';
|
|
45
46
|
import { buildAutoFilterErrorTail } from './auto-filter-error.js';
|
|
@@ -83,7 +84,7 @@ export function parseAutoFilterProgressLine(line) {
|
|
|
83
84
|
const counterMatch = /^(\d+)\/(\d+)$/.exec(counter);
|
|
84
85
|
if (!counterMatch)
|
|
85
86
|
return null;
|
|
86
|
-
if (decision !== 'accepted' && decision !== 'rejected')
|
|
87
|
+
if (decision !== 'accepted' && decision !== 'rejected' && decision !== 'failed')
|
|
87
88
|
return null;
|
|
88
89
|
if (!name)
|
|
89
90
|
return null;
|
|
@@ -1399,6 +1400,11 @@ export function WizardApp({ initialSpaceId = '', initialEnvironmentId = 'master'
|
|
|
1399
1400
|
finally {
|
|
1400
1401
|
db.close();
|
|
1401
1402
|
}
|
|
1403
|
+
// INTEG-4318: overlay the streamed auto-filter decisions (from
|
|
1404
|
+
// stderr progress lines) onto DB-loaded rows so 'failed' components
|
|
1405
|
+
// (LLM omitted a tool call in a batch) surface in the scope-gate
|
|
1406
|
+
// instead of silently defaulting to included.
|
|
1407
|
+
components = mergeAiDecisions(components, state.aiDecisions);
|
|
1402
1408
|
return (_jsx(ScopeGateHost, { components: components, autoAccept: autoAcceptScope, aiFilterStatus: state.aiFilterStatus, aiFilterProgress: state.aiFilterProgress, aiFilterError: state.aiFilterError, onCancelAutoFilter: cancelAutoFilter, onConfirm: (decisions) => {
|
|
1403
1409
|
void runScopeGate({
|
|
1404
1410
|
sessionId,
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
}
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
export type ScopeComponent = {
|
|
3
3
|
name: string;
|
|
4
4
|
componentId: string;
|
|
5
|
-
aiDecision?: 'accepted' | 'rejected' | null;
|
|
5
|
+
aiDecision?: 'accepted' | 'rejected' | 'failed' | null;
|
|
6
6
|
aiReason?: string | null;
|
|
7
7
|
};
|
|
8
8
|
export type ScopeGateStepProps = {
|
|
@@ -20,7 +20,11 @@ function truncateReason(reason) {
|
|
|
20
20
|
return reason.slice(0, REASON_DISPLAY_MAX - 1).trimEnd() + '…';
|
|
21
21
|
}
|
|
22
22
|
function isAiFlagged(row) {
|
|
23
|
-
|
|
23
|
+
// INTEG-4318: `failed` means the LLM omitted a decision for this component
|
|
24
|
+
// (e.g. batch under-emit). Surface these in the AI-recommended-exclusions
|
|
25
|
+
// section so the operator sees them and can override — silent inclusion was
|
|
26
|
+
// the bug.
|
|
27
|
+
return row.aiDecision === 'rejected' || row.aiDecision === 'failed';
|
|
24
28
|
}
|
|
25
29
|
export function ScopeGateStep({ components, onConfirm, onQuit, aiFilterStatus = 'idle', aiFilterProgress = null, aiFilterError = null, onCancelAutoFilter, }) {
|
|
26
30
|
// Pilot-2026-06-25: scope-gate UX overhaul — single unified list.
|
|
@@ -60,7 +64,10 @@ export function ScopeGateStep({ components, onConfirm, onQuit, aiFilterStatus =
|
|
|
60
64
|
return false;
|
|
61
65
|
if (userUnExcluded.has(row.name))
|
|
62
66
|
return true;
|
|
63
|
-
|
|
67
|
+
// INTEG-4318: exclude on 'rejected' AND 'failed'. Missing/null aiDecision
|
|
68
|
+
// (auto-filter not run, or component never seen) still defaults to
|
|
69
|
+
// included so --no-auto-filter and skip-credentials flows are unchanged.
|
|
70
|
+
return row.aiDecision !== 'rejected' && row.aiDecision !== 'failed';
|
|
64
71
|
};
|
|
65
72
|
const partition = () => {
|
|
66
73
|
const accepted = [];
|
|
@@ -216,7 +223,7 @@ export function ScopeGateStep({ components, onConfirm, onQuit, aiFilterStatus =
|
|
|
216
223
|
const showCancelledBanner = aiFilterStatus === 'cancelled';
|
|
217
224
|
const showFailedBanner = aiFilterStatus === 'failed';
|
|
218
225
|
const allRejected = aiFilterStatus === 'complete' && total > 0 && flatList.every((c) => !isIncluded(c));
|
|
219
|
-
return (_jsxs(Box, { flexDirection: "column", gap: 1, paddingX: 2, paddingY: 1, children: [_jsx(Text, { color: "green", children: "\u2713 Extraction complete" }), _jsxs(Text, { dimColor: true, children: ["Found ", total, " component", total === 1 ? '' : 's', ". Pick which ones to import. Generation runs only on the included set."] }), showRunningHeader && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsxs(Text, { color: "cyan", children: ["[AI filtering (", aiFilterProgress.done, "/", aiFilterProgress.total, ")\u2026] ", _jsx(Text, { dimColor: true, children: "[q] cancels" })] }) })), showCancelledBanner && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "yellow", children: ["AI auto-filter cancelled", aiFilterProgress ? ` at ${aiFilterProgress.done}/${aiFilterProgress.total}` : '', ". Review remaining manually."] }) })), showFailedBanner && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "yellow", children: ["AI auto-filter failed: ", aiFilterError ?? 'unknown error', ". Continuing without AI suggestions."] }) })), reasonPanelOpen && flatList[cursor]
|
|
226
|
+
return (_jsxs(Box, { flexDirection: "column", gap: 1, paddingX: 2, paddingY: 1, children: [_jsx(Text, { color: "green", children: "\u2713 Extraction complete" }), _jsxs(Text, { dimColor: true, children: ["Found ", total, " component", total === 1 ? '' : 's', ". Pick which ones to import. Generation runs only on the included set."] }), showRunningHeader && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsxs(Text, { color: "cyan", children: ["[AI filtering (", aiFilterProgress.done, "/", aiFilterProgress.total, ")\u2026] ", _jsx(Text, { dimColor: true, children: "[q] cancels" })] }) })), showCancelledBanner && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "yellow", children: ["AI auto-filter cancelled", aiFilterProgress ? ` at ${aiFilterProgress.done}/${aiFilterProgress.total}` : '', ". Review remaining manually."] }) })), showFailedBanner && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "yellow", children: ["AI auto-filter failed: ", aiFilterError ?? 'unknown error', ". Continuing without AI suggestions."] }) })), reasonPanelOpen && flatList[cursor] !== undefined && isAiFlagged(flatList[cursor]) && (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "gray", paddingX: 1, marginTop: 1, children: [_jsx(Text, { dimColor: true, bold: true, children: `AI rejection reason: ${flatList[cursor].name}` }), _jsx(Text, { children: flatList[cursor].aiReason ?? '<no reason given>' }), _jsx(Text, { dimColor: true, children: "[s] close \u00B7 [Esc] close" })] })), allRejected ? (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "yellow", children: "AI excluded all components \u2014 press [a] to override or [q] to quit" }) })) : (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [above > 0 && _jsxs(Text, { dimColor: true, children: ["\u2191 ", above, " above"] }), visible.map((c, vi) => {
|
|
220
227
|
const i = vi + scrollOffset;
|
|
221
228
|
const isCursor = i === cursor;
|
|
222
229
|
const included = isIncluded(c);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/experience-design-system-cli",
|
|
3
|
-
"version": "2.12.1-dev-build-
|
|
3
|
+
"version": "2.12.1-dev-build-bae15c7.0",
|
|
4
4
|
"description": "Contentful Experiences design system import CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"svelte": "^5.56.4",
|
|
38
38
|
"ts-morph": "^27.0.2",
|
|
39
39
|
"typescript": "^5.9.3",
|
|
40
|
-
"@contentful/experience-design-system-types": "2.12.1-dev-build-
|
|
40
|
+
"@contentful/experience-design-system-types": "2.12.1-dev-build-bae15c7.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@tsconfig/node24": "^24.0.3",
|