@contentful/experience-design-system-cli 2.34.5-dev-build-f6f44159.0 → 2.34.5-dev-build-ab8465d2.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/src/index.js
CHANGED
|
@@ -110,41 +110,58 @@ var init_credentials_store = __esm({
|
|
|
110
110
|
var render_with_goodbye_exports = {};
|
|
111
111
|
__export(render_with_goodbye_exports, {
|
|
112
112
|
GoodbyeBoundary: () => GoodbyeBoundary,
|
|
113
|
-
renderWithGoodbye: () => renderWithGoodbye
|
|
113
|
+
renderWithGoodbye: () => renderWithGoodbye,
|
|
114
|
+
useScreenTransitionClear: () => useScreenTransitionClear
|
|
114
115
|
});
|
|
115
|
-
import { useEffect, useRef, useState } from "react";
|
|
116
|
-
import { render, Text } from "ink";
|
|
116
|
+
import { createContext, useCallback, useContext, useEffect, useRef, useState } from "react";
|
|
117
|
+
import { render, Text, useInput } from "ink";
|
|
117
118
|
import { Fragment, jsx } from "react/jsx-runtime";
|
|
119
|
+
function useScreenTransitionClear() {
|
|
120
|
+
return useContext(ScreenTransitionClearContext);
|
|
121
|
+
}
|
|
118
122
|
function GoodbyeBoundary({ children }) {
|
|
119
123
|
const [isExiting, setIsExiting] = useState(false);
|
|
120
124
|
const isExitingRef = useRef(false);
|
|
125
|
+
const exitTimerRef = useRef(void 0);
|
|
126
|
+
const requestExit = useCallback(() => {
|
|
127
|
+
if (isExitingRef.current) return;
|
|
128
|
+
isExitingRef.current = true;
|
|
129
|
+
setIsExiting(true);
|
|
130
|
+
exitTimerRef.current = setTimeout(() => process.exit(0), GOODBYE_RENDER_DELAY_MS);
|
|
131
|
+
}, []);
|
|
132
|
+
useInput((input, key) => {
|
|
133
|
+
if (key.ctrl && input === "c") requestExit();
|
|
134
|
+
});
|
|
121
135
|
useEffect(() => {
|
|
122
|
-
|
|
123
|
-
const handleSigint = () => {
|
|
124
|
-
if (isExitingRef.current) return;
|
|
125
|
-
isExitingRef.current = true;
|
|
126
|
-
setIsExiting(true);
|
|
127
|
-
exitTimer = setTimeout(() => process.exit(0), GOODBYE_RENDER_DELAY_MS);
|
|
128
|
-
};
|
|
129
|
-
process.on("SIGINT", handleSigint);
|
|
136
|
+
process.on("SIGINT", requestExit);
|
|
130
137
|
return () => {
|
|
131
|
-
process.off("SIGINT",
|
|
132
|
-
if (
|
|
138
|
+
process.off("SIGINT", requestExit);
|
|
139
|
+
if (exitTimerRef.current) clearTimeout(exitTimerRef.current);
|
|
133
140
|
};
|
|
134
|
-
}, []);
|
|
141
|
+
}, [requestExit]);
|
|
135
142
|
return isExiting ? /* @__PURE__ */ jsx(Text, { children: "Goodbye!" }) : /* @__PURE__ */ jsx(Fragment, { children });
|
|
136
143
|
}
|
|
137
144
|
function renderWithGoodbye(element, options) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
145
|
+
const instanceRef = {};
|
|
146
|
+
const clearScreen = () => {
|
|
147
|
+
instanceRef.current?.clear();
|
|
148
|
+
};
|
|
149
|
+
const instance = render(
|
|
150
|
+
/* @__PURE__ */ jsx(ScreenTransitionClearContext.Provider, { value: clearScreen, children: /* @__PURE__ */ jsx(GoodbyeBoundary, { children: element }) }),
|
|
151
|
+
{
|
|
152
|
+
...options,
|
|
153
|
+
exitOnCtrlC: false
|
|
154
|
+
}
|
|
155
|
+
);
|
|
156
|
+
instanceRef.current = instance;
|
|
157
|
+
return instance;
|
|
142
158
|
}
|
|
143
|
-
var GOODBYE_RENDER_DELAY_MS;
|
|
159
|
+
var GOODBYE_RENDER_DELAY_MS, ScreenTransitionClearContext;
|
|
144
160
|
var init_render_with_goodbye = __esm({
|
|
145
161
|
"packages/experience-design-system-cli/src/tui/render-with-goodbye.tsx"() {
|
|
146
162
|
"use strict";
|
|
147
163
|
GOODBYE_RENDER_DELAY_MS = 50;
|
|
164
|
+
ScreenTransitionClearContext = createContext(() => void 0);
|
|
148
165
|
}
|
|
149
166
|
});
|
|
150
167
|
|
|
@@ -764,7 +781,7 @@ function renderTokenCandidateSection(kind, entries) {
|
|
|
764
781
|
${formatTokenCandidateLines(entries)}`;
|
|
765
782
|
}
|
|
766
783
|
function buildPreamble(options) {
|
|
767
|
-
const { skill, rawComponentsInline, rawTokensInline, rawTokensFilename, tokensInline, tokenMapInline, generatedCdf, tokenTree, componentSourceRefs, existingComponentsInline, existingTokensInline } = options;
|
|
784
|
+
const { skill, rawComponentsInline, rawTokensInline, rawTokensFilename, tokensInline, tokenMapInline, generatedCdf, tokenTree, componentSourceRefs, existingComponentsInline, existingTokensInline, componentAllowlistInline } = options;
|
|
768
785
|
const sections = [];
|
|
769
786
|
if (existingComponentsInline) {
|
|
770
787
|
sections.push(`Existing components in the target Contentful space (JSON) \u2014 use for alignment, not as a hard filter:
|
|
@@ -776,6 +793,12 @@ ${existingComponentsInline}
|
|
|
776
793
|
sections.push(`Existing design tokens in the target Contentful space (JSON) \u2014 prefer binding to these paths over inventing new ones:
|
|
777
794
|
\`\`\`json
|
|
778
795
|
${existingTokensInline}
|
|
796
|
+
\`\`\``);
|
|
797
|
+
}
|
|
798
|
+
if (componentAllowlistInline) {
|
|
799
|
+
sections.push(`Known component names for slot allowed_components (hard allowlist; never use any other name):
|
|
800
|
+
\`\`\`json
|
|
801
|
+
${componentAllowlistInline}
|
|
779
802
|
\`\`\``);
|
|
780
803
|
}
|
|
781
804
|
if (rawComponentsInline) {
|
|
@@ -918,6 +941,7 @@ Rules:
|
|
|
918
941
|
- Q2: is the value written straight into a style or attribute (\`rx={radius}\`, \`padding: \${padding}\`)? no \u2192 not \`token\`, apply the type rules.
|
|
919
942
|
- Q3: is there a design-token reference at that use \u2014 a \`tokens.*\` parameter default, a \`tokenReference\`, an inline \`tokens.*\` / \`var(--*)\`? yes \u2192 \`token\` (cite both lines in "reason"); no \u2192 \`string\`. "Ambiguity resolves to \`enum\`" applies only when Q1\u2013Q3 cannot be answered from the source shown.
|
|
920
943
|
- CSS design props (className, style, styles, positional/geometric props: top, bottom, left, right, rotation, offset, etc.) \u2192 classify_prop, cdf_type: "string", cdf_category: "design".
|
|
944
|
+
- For \`classify_slot.allowed_components\`, use only exact names from the hard allowlist provided below. Never invent a child from an import, JSX element, type name, icon name, or implementation helper; if a child is not listed, omit it.
|
|
921
945
|
- On classify_component, "rationale" fields are operator-facing (read-only) but may surface in customer-facing exports. The "rationale.description" field is subject to the description content rules in the skill prompt (no internal initiative names). "rationale.props" and "rationale.slots" describe your reasoning about scope; "classify_slot.rationale" explains why each slot was kept.
|
|
922
946
|
- On classify_prop, "reason" is REQUIRED and is the LLM's internal rationale \u2014 shown to the developer reviewing the import, never to end-users. "description" is the customer-facing copy and is subject to the description content rules in the skill prompt. Keep them distinct: "description" is short and customer-facing; "reason" explains your reasoning in detail.
|
|
923
947
|
- You may emit prose lines (not starting with {) anywhere \u2014 they are ignored by the parser and serve as your reasoning log.`;
|
|
@@ -1952,8 +1976,7 @@ function hashComponentShape(component) {
|
|
|
1952
1976
|
})),
|
|
1953
1977
|
slots: component.slots.map((s) => ({
|
|
1954
1978
|
name: s.name,
|
|
1955
|
-
isDefault: s.isDefault
|
|
1956
|
-
allowedComponents: [...s.allowedComponents ?? []].sort()
|
|
1979
|
+
isDefault: s.isDefault
|
|
1957
1980
|
}))
|
|
1958
1981
|
};
|
|
1959
1982
|
return createHash2("sha256").update(JSON.stringify(payload)).digest("hex");
|
|
@@ -2498,7 +2521,7 @@ function loadComponentRationale(db, sessionId2, componentName) {
|
|
|
2498
2521
|
}))
|
|
2499
2522
|
};
|
|
2500
2523
|
}
|
|
2501
|
-
function applyToolCalls(db, sessionId2, componentId, componentName, calls, incomingWarnings) {
|
|
2524
|
+
function applyToolCalls(db, sessionId2, componentId, componentName, calls, incomingWarnings, options = {}) {
|
|
2502
2525
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2503
2526
|
const warnings = [...incomingWarnings];
|
|
2504
2527
|
let classified = 0;
|
|
@@ -2633,9 +2656,18 @@ function applyToolCalls(db, sessionId2, componentId, componentName, calls, incom
|
|
|
2633
2656
|
}
|
|
2634
2657
|
if (call.allowed_components !== void 0) {
|
|
2635
2658
|
deleteAllowedComponents.run(sessionId2, componentId, call.slot);
|
|
2636
|
-
call.allowed_components.
|
|
2637
|
-
|
|
2638
|
-
|
|
2659
|
+
const allowedComponents = options.allowedComponentNames ? call.allowed_components.filter((allowedComponent) => options.allowedComponentNames.has(allowedComponent)) : call.allowed_components;
|
|
2660
|
+
if (options.allowedComponentNames) {
|
|
2661
|
+
const dropped = [
|
|
2662
|
+
...new Set(call.allowed_components.filter((ac) => !options.allowedComponentNames.has(ac)))
|
|
2663
|
+
];
|
|
2664
|
+
for (const allowedComponent of dropped) {
|
|
2665
|
+
warnings.push(
|
|
2666
|
+
`${componentName}: classify_slot '${call.slot}' \u2014 dropped unknown allowed component '${allowedComponent}'`
|
|
2667
|
+
);
|
|
2668
|
+
}
|
|
2669
|
+
}
|
|
2670
|
+
allowedComponents.forEach((ac, i) => insertAllowedComponent.run(sessionId2, componentId, call.slot, ac, i));
|
|
2639
2671
|
}
|
|
2640
2672
|
slots++;
|
|
2641
2673
|
}
|
|
@@ -3185,9 +3217,7 @@ function storeCDFComponents(db, sessionId2, components) {
|
|
|
3185
3217
|
}
|
|
3186
3218
|
}
|
|
3187
3219
|
const existingDefaults = new Map(
|
|
3188
|
-
readExistingSlotDefaults.all(sessionId2, componentId).map(
|
|
3189
|
-
(r) => [r.name, r.is_default]
|
|
3190
|
-
)
|
|
3220
|
+
readExistingSlotDefaults.all(sessionId2, componentId).map((r) => [r.name, r.is_default])
|
|
3191
3221
|
);
|
|
3192
3222
|
deleteSlotAllowedComponents.run(sessionId2, componentId);
|
|
3193
3223
|
deleteSlots.run(sessionId2, componentId);
|
|
@@ -3543,15 +3573,38 @@ function lookupCacheByEntity(db, entityType, entityId) {
|
|
|
3543
3573
|
};
|
|
3544
3574
|
}
|
|
3545
3575
|
function storeCache(db, inputHash, entityType, entityId, sourceSessionId, humanEdited, promptHash = "") {
|
|
3576
|
+
storeCaches(db, [{ inputHash, entityType, entityId, sourceSessionId, humanEdited, promptHash }]);
|
|
3577
|
+
}
|
|
3578
|
+
function storeCaches(db, entries) {
|
|
3579
|
+
if (entries.length === 0) return;
|
|
3546
3580
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3547
|
-
db.prepare(
|
|
3581
|
+
const insert = db.prepare(
|
|
3548
3582
|
`INSERT INTO generation_cache (input_hash, entity_type, entity_id, source_session_id, human_edited, created_at, updated_at, prompt_hash)
|
|
3549
3583
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
3550
3584
|
ON CONFLICT(input_hash, prompt_hash, entity_type, entity_id) DO UPDATE SET
|
|
3551
3585
|
source_session_id = excluded.source_session_id,
|
|
3552
3586
|
human_edited = CASE WHEN generation_cache.human_edited = 1 THEN 1 ELSE excluded.human_edited END,
|
|
3553
3587
|
updated_at = excluded.updated_at`
|
|
3554
|
-
)
|
|
3588
|
+
);
|
|
3589
|
+
db.exec("BEGIN");
|
|
3590
|
+
try {
|
|
3591
|
+
for (const entry of entries) {
|
|
3592
|
+
insert.run(
|
|
3593
|
+
entry.inputHash,
|
|
3594
|
+
entry.entityType,
|
|
3595
|
+
entry.entityId,
|
|
3596
|
+
entry.sourceSessionId,
|
|
3597
|
+
entry.humanEdited ? 1 : 0,
|
|
3598
|
+
now,
|
|
3599
|
+
now,
|
|
3600
|
+
entry.promptHash ?? ""
|
|
3601
|
+
);
|
|
3602
|
+
}
|
|
3603
|
+
db.exec("COMMIT");
|
|
3604
|
+
} catch (e) {
|
|
3605
|
+
db.exec("ROLLBACK");
|
|
3606
|
+
throw e;
|
|
3607
|
+
}
|
|
3555
3608
|
}
|
|
3556
3609
|
function storeScannedFiles(db, sessionId2, filePaths) {
|
|
3557
3610
|
db.exec("BEGIN");
|
|
@@ -3601,9 +3654,43 @@ function loadSlotCycles(db, sessionId2) {
|
|
|
3601
3654
|
suggestedBreak: r.suggested_break_json ? JSON.parse(r.suggested_break_json) : null
|
|
3602
3655
|
}));
|
|
3603
3656
|
}
|
|
3604
|
-
function
|
|
3605
|
-
const
|
|
3657
|
+
function findUnknownSlotAllowedComponents(db, sessionId2, allowedComponentNames2, componentId) {
|
|
3658
|
+
const rows = db.prepare(
|
|
3659
|
+
`SELECT a.component_id, c.name AS component_name, a.slot_name, a.allowed_component
|
|
3660
|
+
FROM raw_slot_allowed_components a
|
|
3661
|
+
JOIN raw_components c ON c.session_id = a.session_id AND c.component_id = a.component_id
|
|
3662
|
+
WHERE a.session_id = ? AND (? IS NULL OR a.component_id = ?)
|
|
3663
|
+
ORDER BY a.component_id, a.slot_name, a.position`
|
|
3664
|
+
).all(sessionId2, componentId ?? null, componentId ?? null);
|
|
3665
|
+
return rows.filter((row) => !allowedComponentNames2.has(row.allowed_component)).map((row) => ({
|
|
3666
|
+
componentId: row.component_id,
|
|
3667
|
+
componentName: row.component_name,
|
|
3668
|
+
slotName: row.slot_name,
|
|
3669
|
+
allowedComponent: row.allowed_component
|
|
3670
|
+
}));
|
|
3671
|
+
}
|
|
3672
|
+
function filterUnknownSlotAllowedComponents(db, sessionId2, allowedComponentNames2) {
|
|
3673
|
+
const unknown = findUnknownSlotAllowedComponents(db, sessionId2, allowedComponentNames2);
|
|
3674
|
+
if (unknown.length === 0) return unknown;
|
|
3606
3675
|
db.exec("BEGIN");
|
|
3676
|
+
try {
|
|
3677
|
+
const remove = db.prepare(
|
|
3678
|
+
`DELETE FROM raw_slot_allowed_components
|
|
3679
|
+
WHERE session_id = ? AND component_id = ? AND slot_name = ? AND allowed_component = ?`
|
|
3680
|
+
);
|
|
3681
|
+
for (const row of unknown) {
|
|
3682
|
+
remove.run(sessionId2, row.componentId, row.slotName, row.allowedComponent);
|
|
3683
|
+
}
|
|
3684
|
+
db.exec("COMMIT");
|
|
3685
|
+
} catch (e) {
|
|
3686
|
+
db.exec("ROLLBACK");
|
|
3687
|
+
throw e;
|
|
3688
|
+
}
|
|
3689
|
+
return unknown;
|
|
3690
|
+
}
|
|
3691
|
+
function copyComponentFromCache(db, sourceSessionId, targetSessionId, componentId, manageTransaction = true, options = {}) {
|
|
3692
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3693
|
+
if (manageTransaction) db.exec("BEGIN");
|
|
3607
3694
|
try {
|
|
3608
3695
|
const srcComp = db.prepare(
|
|
3609
3696
|
`SELECT description, status, component_description_rationale, props_rationale, slots_rationale
|
|
@@ -3675,10 +3762,24 @@ function copyComponentFromCache(db, sourceSessionId, targetSessionId, componentI
|
|
|
3675
3762
|
const insertSAC = db.prepare(
|
|
3676
3763
|
`INSERT INTO raw_slot_allowed_components (session_id, component_id, slot_name, allowed_component, position) VALUES (?, ?, ?, ?, ?)`
|
|
3677
3764
|
);
|
|
3678
|
-
|
|
3765
|
+
const allowedSAC = options.allowedComponentNames ? srcSAC.filter((sac) => options.allowedComponentNames.has(sac.allowed_component)) : srcSAC;
|
|
3766
|
+
for (const sac of allowedSAC) {
|
|
3679
3767
|
insertSAC.run(targetSessionId, componentId, sac.slot_name, sac.allowed_component, sac.position);
|
|
3680
3768
|
}
|
|
3681
3769
|
db.prepare("UPDATE sessions SET updated_at = ? WHERE id = ?").run(now, targetSessionId);
|
|
3770
|
+
if (manageTransaction) db.exec("COMMIT");
|
|
3771
|
+
} catch (e) {
|
|
3772
|
+
if (manageTransaction) db.exec("ROLLBACK");
|
|
3773
|
+
throw e;
|
|
3774
|
+
}
|
|
3775
|
+
}
|
|
3776
|
+
function copyComponentsFromCache(db, entries, options = {}) {
|
|
3777
|
+
if (entries.length === 0) return;
|
|
3778
|
+
db.exec("BEGIN");
|
|
3779
|
+
try {
|
|
3780
|
+
for (const entry of entries) {
|
|
3781
|
+
copyComponentFromCache(db, entry.sourceSessionId, entry.targetSessionId, entry.componentId, false, options);
|
|
3782
|
+
}
|
|
3682
3783
|
db.exec("COMMIT");
|
|
3683
3784
|
} catch (e) {
|
|
3684
3785
|
db.exec("ROLLBACK");
|
|
@@ -4821,43 +4922,85 @@ function printFallbackInstructions(options) {
|
|
|
4821
4922
|
lines.push(` Re-run the generate command with the agent available, or use --dry-run to inspect the prompt.`);
|
|
4822
4923
|
process.stderr.write(lines.join("\n") + "\n");
|
|
4823
4924
|
}
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
}
|
|
4843
|
-
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
|
|
4925
|
+
function createCachedComponentResult(componentName, warnings = []) {
|
|
4926
|
+
return {
|
|
4927
|
+
componentName,
|
|
4928
|
+
classified: 0,
|
|
4929
|
+
excluded: 0,
|
|
4930
|
+
slots: 0,
|
|
4931
|
+
warnings,
|
|
4932
|
+
failed: false,
|
|
4933
|
+
cached: true,
|
|
4934
|
+
renamedSlotsCount: 0
|
|
4935
|
+
};
|
|
4936
|
+
}
|
|
4937
|
+
async function showGenerateView(result) {
|
|
4938
|
+
if (process.stdout.isTTY) {
|
|
4939
|
+
const { waitUntilExit } = renderWithGoodbye(
|
|
4940
|
+
createElement(GenerateView, {
|
|
4941
|
+
result,
|
|
4942
|
+
onExit: () => void exitWithAnalytics(0)
|
|
4943
|
+
})
|
|
4944
|
+
);
|
|
4945
|
+
await waitUntilExit();
|
|
4946
|
+
return;
|
|
4947
|
+
}
|
|
4948
|
+
process.stdout.write(
|
|
4949
|
+
`generate complete
|
|
4950
|
+
skill: ${result.skill}
|
|
4951
|
+
agent: ${result.agent}
|
|
4952
|
+
session=${result.sessionId}
|
|
4953
|
+
`
|
|
4954
|
+
);
|
|
4955
|
+
await exitWithAnalytics(0);
|
|
4956
|
+
}
|
|
4957
|
+
function writeCachedComponentStatus(position, componentName, pinned) {
|
|
4958
|
+
const status = pinned ? c.cyan("pinned (human-edited)") : c.green("cached");
|
|
4959
|
+
process.stderr.write(` ${position} ${c.bold(componentName)} ${status}
|
|
4848
4960
|
`);
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4961
|
+
}
|
|
4962
|
+
function normalizeComponentForCache(component) {
|
|
4963
|
+
const slots = component.slots.map((slot, index, allSlots) => ({
|
|
4964
|
+
...slot,
|
|
4965
|
+
name: slot.name.trim() || (allSlots.length === 1 ? "children" : `slot_${index}`)
|
|
4966
|
+
}));
|
|
4967
|
+
return { ...component, slots };
|
|
4968
|
+
}
|
|
4969
|
+
function lookupComponentCache(db, component, promptHash) {
|
|
4970
|
+
const normalized = normalizeComponentForCache(component);
|
|
4971
|
+
const inputHash = hashComponentShape(normalized);
|
|
4972
|
+
const cached = lookupCache(db, inputHash, "component", component.component_id, promptHash);
|
|
4973
|
+
if (cached) return cached;
|
|
4974
|
+
const legacyInputHash = hashComponentShape(component);
|
|
4975
|
+
return legacyInputHash === inputHash ? null : lookupCache(db, legacyInputHash, "component", component.component_id, promptHash);
|
|
4976
|
+
}
|
|
4977
|
+
function resolveComponentCache(db, component, promptHash, allowedComponentNames2) {
|
|
4978
|
+
const cached = lookupComponentCache(db, component, promptHash);
|
|
4979
|
+
if (cached && findUnknownSlotAllowedComponents(db, cached.sourceSessionId, allowedComponentNames2, component.component_id).length === 0) {
|
|
4980
|
+
return { entry: cached, humanEdited: cached.humanEdited };
|
|
4860
4981
|
}
|
|
4982
|
+
const pinned = lookupCacheByEntity(db, "component", component.component_id);
|
|
4983
|
+
return pinned?.humanEdited && findUnknownSlotAllowedComponents(db, pinned.sourceSessionId, allowedComponentNames2, component.component_id).length === 0 ? { entry: pinned, humanEdited: true } : null;
|
|
4984
|
+
}
|
|
4985
|
+
async function runOneComponent(options, component, index, total) {
|
|
4986
|
+
const {
|
|
4987
|
+
agent,
|
|
4988
|
+
model,
|
|
4989
|
+
db,
|
|
4990
|
+
sessionId: sessionId2,
|
|
4991
|
+
tokensInline,
|
|
4992
|
+
tokenMapInline,
|
|
4993
|
+
verbose,
|
|
4994
|
+
noCache,
|
|
4995
|
+
skillPathOverride,
|
|
4996
|
+
skillContentOverride,
|
|
4997
|
+
promptHash,
|
|
4998
|
+
existingContentfulEntities,
|
|
4999
|
+
existingTokensInline,
|
|
5000
|
+
precomputedCachedNames,
|
|
5001
|
+
allowedComponentNames: allowedComponentNames2
|
|
5002
|
+
} = options;
|
|
5003
|
+
const pos = c.dim(`[${index + 1}/${total}]`);
|
|
4861
5004
|
const { renames, warnings: renameWarnings } = renameEmptySlots(
|
|
4862
5005
|
db,
|
|
4863
5006
|
sessionId2,
|
|
@@ -4872,6 +5015,47 @@ async function runOneComponent(agent, model, db, sessionId2, component, tokensIn
|
|
|
4872
5015
|
for (const w of renameWarnings) process.stderr.write(` ${c.yellow("\u26A0")} ${w}
|
|
4873
5016
|
`);
|
|
4874
5017
|
}
|
|
5018
|
+
effectiveSlots = effectiveSlots.map((slot) => {
|
|
5019
|
+
if (!slot.allowedComponents) return slot;
|
|
5020
|
+
return {
|
|
5021
|
+
...slot,
|
|
5022
|
+
allowedComponents: slot.allowedComponents.filter((name) => allowedComponentNames2.has(name))
|
|
5023
|
+
};
|
|
5024
|
+
});
|
|
5025
|
+
const cacheComponent = normalizeComponentForCache(component);
|
|
5026
|
+
if (!noCache && precomputedCachedNames.has(component.name)) {
|
|
5027
|
+
writeCachedComponentStatus(pos, component.name, false);
|
|
5028
|
+
return createCachedComponentResult(component.name);
|
|
5029
|
+
}
|
|
5030
|
+
if (!noCache) {
|
|
5031
|
+
const inputHash = hashComponentShape(cacheComponent);
|
|
5032
|
+
const resolution = resolveComponentCache(db, component, promptHash, allowedComponentNames2);
|
|
5033
|
+
if (resolution && !resolution.humanEdited) {
|
|
5034
|
+
copyComponentFromCache(db, resolution.entry.sourceSessionId, sessionId2, component.component_id, true, {
|
|
5035
|
+
allowedComponentNames: allowedComponentNames2
|
|
5036
|
+
});
|
|
5037
|
+
storeCache(
|
|
5038
|
+
db,
|
|
5039
|
+
inputHash,
|
|
5040
|
+
"component",
|
|
5041
|
+
component.component_id,
|
|
5042
|
+
resolution.entry.sourceSessionId,
|
|
5043
|
+
resolution.entry.humanEdited,
|
|
5044
|
+
promptHash
|
|
5045
|
+
);
|
|
5046
|
+
writeCachedComponentStatus(pos, component.name, false);
|
|
5047
|
+
return createCachedComponentResult(component.name);
|
|
5048
|
+
}
|
|
5049
|
+
if (resolution?.humanEdited) {
|
|
5050
|
+
copyComponentFromCache(db, resolution.entry.sourceSessionId, sessionId2, component.component_id, true, {
|
|
5051
|
+
allowedComponentNames: allowedComponentNames2
|
|
5052
|
+
});
|
|
5053
|
+
writeCachedComponentStatus(pos, component.name, true);
|
|
5054
|
+
return createCachedComponentResult(component.name, [
|
|
5055
|
+
`${component.name}: source changed but human edits preserved`
|
|
5056
|
+
]);
|
|
5057
|
+
}
|
|
5058
|
+
}
|
|
4875
5059
|
const rawComponentsInline = JSON.stringify(
|
|
4876
5060
|
[
|
|
4877
5061
|
{
|
|
@@ -4904,7 +5088,8 @@ async function runOneComponent(agent, model, db, sessionId2, component, tokensIn
|
|
|
4904
5088
|
skillPathOverride,
|
|
4905
5089
|
skillContentOverride,
|
|
4906
5090
|
existingComponentsInline,
|
|
4907
|
-
existingTokensInline
|
|
5091
|
+
existingTokensInline,
|
|
5092
|
+
componentAllowlistInline: JSON.stringify([...allowedComponentNames2].sort())
|
|
4908
5093
|
});
|
|
4909
5094
|
const maxAttempts = 2;
|
|
4910
5095
|
let lastError = "";
|
|
@@ -4939,9 +5124,11 @@ ${outputBuf}`);
|
|
|
4939
5124
|
lastError = describeAgentFailure(result);
|
|
4940
5125
|
continue;
|
|
4941
5126
|
}
|
|
4942
|
-
const applied = applyToolCalls(db, sessionId2, component.component_id, component.name, calls, warnings
|
|
5127
|
+
const applied = applyToolCalls(db, sessionId2, component.component_id, component.name, calls, warnings, {
|
|
5128
|
+
allowedComponentNames: allowedComponentNames2
|
|
5129
|
+
});
|
|
4943
5130
|
if (!noCache) {
|
|
4944
|
-
const inputHash = hashComponentShape(
|
|
5131
|
+
const inputHash = hashComponentShape(cacheComponent);
|
|
4945
5132
|
storeCache(db, inputHash, "component", component.component_id, sessionId2, false, promptHash);
|
|
4946
5133
|
}
|
|
4947
5134
|
return {
|
|
@@ -4965,7 +5152,7 @@ ${outputBuf}`);
|
|
|
4965
5152
|
renamedSlotsCount: renames.length
|
|
4966
5153
|
};
|
|
4967
5154
|
}
|
|
4968
|
-
async function runAllComponents(
|
|
5155
|
+
async function runAllComponents(options, components) {
|
|
4969
5156
|
const concurrency = Number(process.env.EDS_GENERATE_CONCURRENCY ?? DEFAULT_COMPONENT_CONCURRENCY);
|
|
4970
5157
|
process.stderr.write(
|
|
4971
5158
|
`Categorizing ${c.bold(String(components.length))} component${components.length === 1 ? "" : "s"}` + c.dim(` (concurrency: ${concurrency})`) + "\n"
|
|
@@ -4976,24 +5163,7 @@ async function runAllComponents(agent, model, db, sessionId2, components, tokens
|
|
|
4976
5163
|
async function worker() {
|
|
4977
5164
|
while (next < components.length) {
|
|
4978
5165
|
const i = next++;
|
|
4979
|
-
results[i] = await runOneComponent(
|
|
4980
|
-
agent,
|
|
4981
|
-
model,
|
|
4982
|
-
db,
|
|
4983
|
-
sessionId2,
|
|
4984
|
-
components[i],
|
|
4985
|
-
tokensInline,
|
|
4986
|
-
tokenMapInline,
|
|
4987
|
-
i,
|
|
4988
|
-
components.length,
|
|
4989
|
-
verbose,
|
|
4990
|
-
noCache,
|
|
4991
|
-
skillPathOverride,
|
|
4992
|
-
skillContentOverride,
|
|
4993
|
-
promptHash,
|
|
4994
|
-
existingContentfulEntities,
|
|
4995
|
-
existingTokensInline
|
|
4996
|
-
);
|
|
5166
|
+
results[i] = await runOneComponent(options, components[i], i, components.length);
|
|
4997
5167
|
completed += 1;
|
|
4998
5168
|
process.stderr.write(`${formatGenerateProgressLine(completed, components.length, results[i].componentName)}
|
|
4999
5169
|
`);
|
|
@@ -5021,6 +5191,15 @@ async function loadAcceptedNames(sessionId2) {
|
|
|
5021
5191
|
return null;
|
|
5022
5192
|
}
|
|
5023
5193
|
}
|
|
5194
|
+
function parsePrecomputedCachedNames(value) {
|
|
5195
|
+
if (!value) return /* @__PURE__ */ new Set();
|
|
5196
|
+
try {
|
|
5197
|
+
const parsed = JSON.parse(value);
|
|
5198
|
+
return new Set(Array.isArray(parsed) ? parsed.filter((name) => typeof name === "string") : []);
|
|
5199
|
+
} catch {
|
|
5200
|
+
return /* @__PURE__ */ new Set();
|
|
5201
|
+
}
|
|
5202
|
+
}
|
|
5024
5203
|
async function runGenerateSkill(skill, opts, verbose = false) {
|
|
5025
5204
|
const savedCreds = await readExperiencesCredentials();
|
|
5026
5205
|
const agentName = opts.agent ?? savedCreds.agent;
|
|
@@ -5086,6 +5265,7 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
5086
5265
|
}
|
|
5087
5266
|
let sessionId2;
|
|
5088
5267
|
let allComponents;
|
|
5268
|
+
let allowedComponentNames2;
|
|
5089
5269
|
if (skill === "components") {
|
|
5090
5270
|
sessionId2 = await resolveSessionId(opts.session);
|
|
5091
5271
|
await bindAnalyticsSessionId(sessionId2);
|
|
@@ -5099,6 +5279,27 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
5099
5279
|
if (allComponents.length === 0) {
|
|
5100
5280
|
die(`Error: session '${sessionId2}' has no raw components. Run analyze extract first.`);
|
|
5101
5281
|
}
|
|
5282
|
+
allowedComponentNames2 = /* @__PURE__ */ new Set([
|
|
5283
|
+
...allComponents.map((component) => component.name),
|
|
5284
|
+
...(existingContentfulEntities?.components ?? []).map((component) => component.name)
|
|
5285
|
+
]);
|
|
5286
|
+
if (!opts.dryRun) {
|
|
5287
|
+
const dbForReferences = openPipelineDb();
|
|
5288
|
+
try {
|
|
5289
|
+
const dropped = filterUnknownSlotAllowedComponents(dbForReferences, sessionId2, allowedComponentNames2);
|
|
5290
|
+
for (const reference of dropped) {
|
|
5291
|
+
process.stderr.write(
|
|
5292
|
+
`Warning: ${reference.componentName}: slot '${reference.slotName}' \u2014 dropped unknown allowed component '${reference.allowedComponent}'
|
|
5293
|
+
`
|
|
5294
|
+
);
|
|
5295
|
+
}
|
|
5296
|
+
if (dropped.length > 0) {
|
|
5297
|
+
allComponents = loadRawComponents(dbForReferences, sessionId2, acceptedNames ?? void 0);
|
|
5298
|
+
}
|
|
5299
|
+
} finally {
|
|
5300
|
+
dbForReferences.close();
|
|
5301
|
+
}
|
|
5302
|
+
}
|
|
5102
5303
|
if (acceptedNames) {
|
|
5103
5304
|
process.stderr.write(`Scope: ${allComponents.length} accepted component(s) from analyze select
|
|
5104
5305
|
`);
|
|
@@ -5158,7 +5359,8 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
5158
5359
|
skillPathOverride: generatePromptPath,
|
|
5159
5360
|
skillContentOverride: generatePrompt,
|
|
5160
5361
|
existingComponentsInline: dryRunExistingComponentsInline,
|
|
5161
|
-
existingTokensInline: skill === "components" ? existingTokensInline : void 0
|
|
5362
|
+
existingTokensInline: skill === "components" ? existingTokensInline : void 0,
|
|
5363
|
+
componentAllowlistInline: skill === "components" && allowedComponentNames2 ? JSON.stringify([...allowedComponentNames2].sort()) : void 0
|
|
5162
5364
|
});
|
|
5163
5365
|
process.stdout.write(prompt + "\n");
|
|
5164
5366
|
await exitWithAnalytics(0);
|
|
@@ -5175,6 +5377,7 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
5175
5377
|
if (skill === "components" && allComponents && sessionId2) {
|
|
5176
5378
|
const db = openPipelineDb();
|
|
5177
5379
|
let componentResults;
|
|
5380
|
+
const precomputedCachedNames = parsePrecomputedCachedNames(opts.cachedComponents);
|
|
5178
5381
|
try {
|
|
5179
5382
|
const existingContentfulEntitiesHashInputs = [];
|
|
5180
5383
|
if (existingTokensInline) existingContentfulEntitiesHashInputs.push(hashContent(existingTokensInline));
|
|
@@ -5186,21 +5389,71 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
5186
5389
|
existingContentfulEntitiesHashInputs,
|
|
5187
5390
|
generatePrompt
|
|
5188
5391
|
);
|
|
5392
|
+
if (opts.cacheStatus) {
|
|
5393
|
+
const cacheEnabled = opts.cache !== false && process.env.EDS_NO_CACHE !== "1";
|
|
5394
|
+
const cachedComponents = cacheEnabled ? allComponents.flatMap((component) => {
|
|
5395
|
+
const resolution = resolveComponentCache(db, component, promptHash, allowedComponentNames2);
|
|
5396
|
+
return resolution ? [{ component, resolution }] : [];
|
|
5397
|
+
}) : [];
|
|
5398
|
+
if (cacheEnabled && opts.restoreCache) {
|
|
5399
|
+
const restorations = [];
|
|
5400
|
+
const rekeyed = [];
|
|
5401
|
+
const componentStatus = db.prepare(
|
|
5402
|
+
"SELECT status FROM raw_components WHERE session_id = ? AND component_id = ?"
|
|
5403
|
+
);
|
|
5404
|
+
for (const { component, resolution } of cachedComponents) {
|
|
5405
|
+
const current = componentStatus.get(sessionId2, component.component_id);
|
|
5406
|
+
if (current?.status === "generated") continue;
|
|
5407
|
+
renameEmptySlots(db, sessionId2, component.component_id, component.name, component.slots.length);
|
|
5408
|
+
restorations.push({
|
|
5409
|
+
sourceSessionId: resolution.entry.sourceSessionId,
|
|
5410
|
+
targetSessionId: sessionId2,
|
|
5411
|
+
componentId: component.component_id
|
|
5412
|
+
});
|
|
5413
|
+
rekeyed.push({ component, cached: resolution.entry });
|
|
5414
|
+
}
|
|
5415
|
+
copyComponentsFromCache(db, restorations, { allowedComponentNames: allowedComponentNames2 });
|
|
5416
|
+
storeCaches(
|
|
5417
|
+
db,
|
|
5418
|
+
rekeyed.map(({ component, cached }) => ({
|
|
5419
|
+
inputHash: hashComponentShape(normalizeComponentForCache(component)),
|
|
5420
|
+
entityType: "component",
|
|
5421
|
+
entityId: component.component_id,
|
|
5422
|
+
sourceSessionId: cached.sourceSessionId,
|
|
5423
|
+
humanEdited: cached.humanEdited,
|
|
5424
|
+
promptHash
|
|
5425
|
+
}))
|
|
5426
|
+
);
|
|
5427
|
+
}
|
|
5428
|
+
const fullyCached = cacheEnabled && cachedComponents.length === allComponents.length;
|
|
5429
|
+
process.stdout.write(`cache-status=${fullyCached ? "hit" : "miss"}
|
|
5430
|
+
`);
|
|
5431
|
+
process.stdout.write(
|
|
5432
|
+
`cache-components=${JSON.stringify(cachedComponents.map(({ component }) => component.name))}
|
|
5433
|
+
`
|
|
5434
|
+
);
|
|
5435
|
+
await exitWithAnalytics(0);
|
|
5436
|
+
return;
|
|
5437
|
+
}
|
|
5189
5438
|
componentResults = await runAllComponents(
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5439
|
+
{
|
|
5440
|
+
agent,
|
|
5441
|
+
model,
|
|
5442
|
+
db,
|
|
5443
|
+
sessionId: sessionId2,
|
|
5444
|
+
tokensInline,
|
|
5445
|
+
tokenMapInline,
|
|
5446
|
+
verbose,
|
|
5447
|
+
noCache: opts.cache === false || process.env.EDS_NO_CACHE === "1",
|
|
5448
|
+
skillPathOverride: generatePromptPath,
|
|
5449
|
+
skillContentOverride: generatePrompt,
|
|
5450
|
+
promptHash,
|
|
5451
|
+
existingContentfulEntities,
|
|
5452
|
+
existingTokensInline,
|
|
5453
|
+
precomputedCachedNames,
|
|
5454
|
+
allowedComponentNames: allowedComponentNames2
|
|
5455
|
+
},
|
|
5456
|
+
allComponents
|
|
5204
5457
|
);
|
|
5205
5458
|
} finally {
|
|
5206
5459
|
db.close();
|
|
@@ -5275,20 +5528,7 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
5275
5528
|
`
|
|
5276
5529
|
);
|
|
5277
5530
|
db.close();
|
|
5278
|
-
|
|
5279
|
-
if (process.stdout.isTTY) {
|
|
5280
|
-
const { waitUntilExit } = renderWithGoodbye(
|
|
5281
|
-
createElement(GenerateView, { result: viewResult2, onExit: () => void exitWithAnalytics(0) })
|
|
5282
|
-
);
|
|
5283
|
-
await waitUntilExit();
|
|
5284
|
-
} else {
|
|
5285
|
-
process.stdout.write(`generate complete
|
|
5286
|
-
skill: ${skill}
|
|
5287
|
-
agent: ${agent}
|
|
5288
|
-
session=${sessionId2}
|
|
5289
|
-
`);
|
|
5290
|
-
await exitWithAnalytics(0);
|
|
5291
|
-
}
|
|
5531
|
+
await showGenerateView({ skill, agent, sessionId: sessionId2 ?? "" });
|
|
5292
5532
|
return;
|
|
5293
5533
|
}
|
|
5294
5534
|
}
|
|
@@ -5344,27 +5584,7 @@ ${tokenWarnings.map((w) => ` ${w}`).join("\n")}
|
|
|
5344
5584
|
db.close();
|
|
5345
5585
|
}
|
|
5346
5586
|
}
|
|
5347
|
-
|
|
5348
|
-
skill,
|
|
5349
|
-
agent,
|
|
5350
|
-
sessionId: sessionId2 ?? ""
|
|
5351
|
-
};
|
|
5352
|
-
if (process.stdout.isTTY) {
|
|
5353
|
-
const { waitUntilExit } = renderWithGoodbye(
|
|
5354
|
-
createElement(GenerateView, {
|
|
5355
|
-
result: viewResult,
|
|
5356
|
-
onExit: () => void exitWithAnalytics(0)
|
|
5357
|
-
})
|
|
5358
|
-
);
|
|
5359
|
-
await waitUntilExit();
|
|
5360
|
-
} else {
|
|
5361
|
-
process.stdout.write(`generate complete
|
|
5362
|
-
skill: ${skill}
|
|
5363
|
-
agent: ${agent}
|
|
5364
|
-
session=${sessionId2 ?? ""}
|
|
5365
|
-
`);
|
|
5366
|
-
await exitWithAnalytics(0);
|
|
5367
|
-
}
|
|
5587
|
+
await showGenerateView({ skill, agent, sessionId: sessionId2 ?? "" });
|
|
5368
5588
|
}
|
|
5369
5589
|
function addAgentFlags(cmd) {
|
|
5370
5590
|
return addAgentModelOptions(cmd).option("--verbose", "Show full agent output including reasoning text").option("--dry-run", "Print the prompt without invoking the agent").option(
|
|
@@ -5386,6 +5606,12 @@ function registerInternalGenerateCommand(program) {
|
|
|
5386
5606
|
"--existing-entities-path <path>",
|
|
5387
5607
|
"Path to the .existing-entities.json file written after CMA credentials are supplied. When present, per-component prompts include a summary of the target space so classifications can align to existing prop names/tokens. Missing/malformed files are treated as no-op."
|
|
5388
5608
|
);
|
|
5609
|
+
componentsCmd.option("--cache-status", "Check whether all selected component definitions are cached");
|
|
5610
|
+
componentsCmd.option("--restore-cache", "Restore cached component definitions into the current session");
|
|
5611
|
+
componentsCmd.option(
|
|
5612
|
+
"--cached-components <json>",
|
|
5613
|
+
"Component names already restored by a prior cache-status lookup; skip per-component cache lookup"
|
|
5614
|
+
);
|
|
5389
5615
|
addAgentFlags(componentsCmd).action(async (opts) => {
|
|
5390
5616
|
await runGenerateSkill("components", opts, opts.verbose ?? false);
|
|
5391
5617
|
});
|
|
@@ -7145,7 +7371,7 @@ var init_contentful_urls = __esm({
|
|
|
7145
7371
|
});
|
|
7146
7372
|
|
|
7147
7373
|
// packages/experience-design-system-cli/src/apply/tui/ServerApplyView.tsx
|
|
7148
|
-
import { Box as Box3, Text as Text4, useInput } from "ink";
|
|
7374
|
+
import { Box as Box3, Text as Text4, useInput as useInput2 } from "ink";
|
|
7149
7375
|
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
7150
7376
|
function ServerPreviewConfirm({
|
|
7151
7377
|
preview,
|
|
@@ -7155,7 +7381,7 @@ function ServerPreviewConfirm({
|
|
|
7155
7381
|
onConfirm,
|
|
7156
7382
|
onCancel
|
|
7157
7383
|
}) {
|
|
7158
|
-
|
|
7384
|
+
useInput2((input, key) => {
|
|
7159
7385
|
if (key.return) onConfirm(breakingWithImpact);
|
|
7160
7386
|
else if (key.escape || input === "q") onCancel();
|
|
7161
7387
|
});
|
|
@@ -7184,7 +7410,7 @@ function ServerApplyProgress({
|
|
|
7184
7410
|
operationId,
|
|
7185
7411
|
error
|
|
7186
7412
|
}) {
|
|
7187
|
-
|
|
7413
|
+
useInput2((_input, key) => {
|
|
7188
7414
|
if (status === "error" && (key.escape || _input === "q")) process.exit(1);
|
|
7189
7415
|
});
|
|
7190
7416
|
return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
|
|
@@ -7212,7 +7438,7 @@ function ServerApplyProgress({
|
|
|
7212
7438
|
] });
|
|
7213
7439
|
}
|
|
7214
7440
|
function ServerApplyDone({ operation, spaceId, environmentId, host }) {
|
|
7215
|
-
|
|
7441
|
+
useInput2((input, key) => {
|
|
7216
7442
|
if (key.escape || input === "q") {
|
|
7217
7443
|
process.exit(operation.sys.status === "succeeded" ? 0 : 1);
|
|
7218
7444
|
}
|
|
@@ -7326,7 +7552,6 @@ var init_terminal_capabilities = __esm({
|
|
|
7326
7552
|
|
|
7327
7553
|
// packages/experience-design-system-cli/src/apply/command.ts
|
|
7328
7554
|
import { createElement as createElement2 } from "react";
|
|
7329
|
-
import { render as render2 } from "ink";
|
|
7330
7555
|
import { readFile as readFile9, readdir as readdir2, stat as stat2 } from "node:fs/promises";
|
|
7331
7556
|
import { join as join8 } from "node:path";
|
|
7332
7557
|
import {
|
|
@@ -7730,11 +7955,11 @@ function registerApplyCommand(program) {
|
|
|
7730
7955
|
environmentId,
|
|
7731
7956
|
host,
|
|
7732
7957
|
acknowledgeBreakingChanges: acknowledge,
|
|
7733
|
-
rerender: (element) => instance.rerender(element),
|
|
7958
|
+
rerender: (element) => instance.rerender(createElement2(GoodbyeBoundary, null, element)),
|
|
7734
7959
|
onDone: resolvePromise
|
|
7735
7960
|
});
|
|
7736
7961
|
};
|
|
7737
|
-
const instance =
|
|
7962
|
+
const instance = renderWithGoodbye(
|
|
7738
7963
|
createElement2(ServerPreviewConfirm, {
|
|
7739
7964
|
preview,
|
|
7740
7965
|
spaceId,
|
|
@@ -7756,6 +7981,7 @@ var IGNORE_TOKEN_DIRS;
|
|
|
7756
7981
|
var init_command2 = __esm({
|
|
7757
7982
|
"packages/experience-design-system-cli/src/apply/command.ts"() {
|
|
7758
7983
|
"use strict";
|
|
7984
|
+
init_render_with_goodbye();
|
|
7759
7985
|
init_api_client();
|
|
7760
7986
|
init_error_parser();
|
|
7761
7987
|
init_cycle_detection();
|
|
@@ -10176,7 +10402,7 @@ var init_SpaceEnvironment = __esm({
|
|
|
10176
10402
|
});
|
|
10177
10403
|
|
|
10178
10404
|
// packages/experience-design-system-cli/src/import/tui/preview-confirmation-input.ts
|
|
10179
|
-
import { useCallback } from "react";
|
|
10405
|
+
import { useCallback as useCallback2 } from "react";
|
|
10180
10406
|
function handlePreviewConfirmationInput(_input, key, options) {
|
|
10181
10407
|
if (key.return) {
|
|
10182
10408
|
options.onConfirm(options.breakingWithImpact);
|
|
@@ -10185,7 +10411,7 @@ function handlePreviewConfirmationInput(_input, key, options) {
|
|
|
10185
10411
|
return false;
|
|
10186
10412
|
}
|
|
10187
10413
|
function usePreviewConfirmationInput(breakingWithImpact, onConfirm) {
|
|
10188
|
-
return
|
|
10414
|
+
return useCallback2(
|
|
10189
10415
|
(input, key) => handlePreviewConfirmationInput(input, key, {
|
|
10190
10416
|
breakingWithImpact,
|
|
10191
10417
|
onConfirm
|
|
@@ -19517,20 +19743,20 @@ var init_SearchMatchSummary = __esm({
|
|
|
19517
19743
|
});
|
|
19518
19744
|
|
|
19519
19745
|
// packages/experience-design-system-cli/src/import/tui/hooks/useOverlayPanel.ts
|
|
19520
|
-
import { useCallback as
|
|
19746
|
+
import { useCallback as useCallback3, useState as useState13 } from "react";
|
|
19521
19747
|
function useOverlayPanel(opts) {
|
|
19522
19748
|
const { toggleKey, onClose } = opts;
|
|
19523
19749
|
const [isOpen, setIsOpen] = useState13(false);
|
|
19524
|
-
const open =
|
|
19750
|
+
const open = useCallback3(() => {
|
|
19525
19751
|
setIsOpen(true);
|
|
19526
19752
|
}, []);
|
|
19527
|
-
const close =
|
|
19753
|
+
const close = useCallback3(() => {
|
|
19528
19754
|
setIsOpen((prev) => {
|
|
19529
19755
|
if (prev && onClose) onClose();
|
|
19530
19756
|
return false;
|
|
19531
19757
|
});
|
|
19532
19758
|
}, [onClose]);
|
|
19533
|
-
const handleInput =
|
|
19759
|
+
const handleInput = useCallback3(
|
|
19534
19760
|
(input, key) => {
|
|
19535
19761
|
if (!isOpen) return false;
|
|
19536
19762
|
if (input === toggleKey || key.escape === true) {
|
|
@@ -24254,7 +24480,7 @@ var init_useFinalizePreview = __esm({
|
|
|
24254
24480
|
});
|
|
24255
24481
|
|
|
24256
24482
|
// packages/experience-design-system-cli/src/import/tui/hooks/useReviewSession.ts
|
|
24257
|
-
import { useCallback as
|
|
24483
|
+
import { useCallback as useCallback4, useEffect as useEffect10, useRef as useRef6, useState as useState17 } from "react";
|
|
24258
24484
|
function loadReviewSessionState({
|
|
24259
24485
|
extractSessionId,
|
|
24260
24486
|
tokenSessionId,
|
|
@@ -24304,7 +24530,7 @@ function useReviewSession({
|
|
|
24304
24530
|
const [loading, setLoading] = useState17(true);
|
|
24305
24531
|
const [loadError, setLoadError] = useState17(null);
|
|
24306
24532
|
const [availableTokens, setAvailableTokens] = useState17([]);
|
|
24307
|
-
const loadInitialState =
|
|
24533
|
+
const loadInitialState = useCallback4(async () => {
|
|
24308
24534
|
const result = loadSession();
|
|
24309
24535
|
if (result.error || !tokensPath) return { result, catalog: result.tokens };
|
|
24310
24536
|
const catalog = (await readTokensFromPath("tokens", tokensPath)).map((token) => ({
|
|
@@ -25005,7 +25231,7 @@ var init_preview_annotations = __esm({
|
|
|
25005
25231
|
});
|
|
25006
25232
|
|
|
25007
25233
|
// packages/experience-design-system-cli/src/import/tui/useLivePreview.ts
|
|
25008
|
-
import { useCallback as
|
|
25234
|
+
import { useCallback as useCallback5, useEffect as useEffect12, useRef as useRef8, useState as useState20 } from "react";
|
|
25009
25235
|
function useLivePreview(opts) {
|
|
25010
25236
|
const debounceMs = opts.debounceMs ?? DEFAULT_DEBOUNCE_MS;
|
|
25011
25237
|
const [status, setStatus] = useState20("idle");
|
|
@@ -25030,7 +25256,7 @@ function useLivePreview(opts) {
|
|
|
25030
25256
|
}
|
|
25031
25257
|
};
|
|
25032
25258
|
}, []);
|
|
25033
|
-
const trigger =
|
|
25259
|
+
const trigger = useCallback5(() => {
|
|
25034
25260
|
const current = optsRef.current;
|
|
25035
25261
|
if (!current.enabled) return;
|
|
25036
25262
|
if (disabledRef.current) return;
|
|
@@ -25103,7 +25329,7 @@ var init_useLivePreview = __esm({
|
|
|
25103
25329
|
});
|
|
25104
25330
|
|
|
25105
25331
|
// packages/experience-design-system-cli/src/import/tui/hooks/useReviewPreview.ts
|
|
25106
|
-
import { useCallback as
|
|
25332
|
+
import { useCallback as useCallback6, useEffect as useEffect13, useState as useState21 } from "react";
|
|
25107
25333
|
function useReviewPreview({
|
|
25108
25334
|
components,
|
|
25109
25335
|
loading,
|
|
@@ -25119,7 +25345,7 @@ function useReviewPreview({
|
|
|
25119
25345
|
}) {
|
|
25120
25346
|
const [previewAnnotations, setPreviewAnnotations] = useState21(/* @__PURE__ */ new Map());
|
|
25121
25347
|
const [removedComponents, setRemovedComponents] = useState21([]);
|
|
25122
|
-
const handleResult =
|
|
25348
|
+
const handleResult = useCallback6(
|
|
25123
25349
|
(response) => {
|
|
25124
25350
|
if (!response) return;
|
|
25125
25351
|
setPreviewAnnotations(
|
|
@@ -25208,7 +25434,7 @@ var init_LivePreviewSummary = __esm({
|
|
|
25208
25434
|
});
|
|
25209
25435
|
|
|
25210
25436
|
// packages/experience-design-system-cli/src/import/tui/steps/GenerateReviewStep.tsx
|
|
25211
|
-
import { useCallback as
|
|
25437
|
+
import { useCallback as useCallback7, useEffect as useEffect14, useMemo as useMemo3, useRef as useRef9, useState as useState22 } from "react";
|
|
25212
25438
|
import figures6 from "figures";
|
|
25213
25439
|
import { Box as Box41, Text as Text45 } from "ink";
|
|
25214
25440
|
import { Fragment as Fragment18, jsx as jsx49, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
@@ -25374,10 +25600,10 @@ function GenerateReviewStepView({
|
|
|
25374
25600
|
}) {
|
|
25375
25601
|
const { columns: terminalWidth, rows: terminalRows } = useTerminalSize();
|
|
25376
25602
|
const [slotCycles, setSlotCycles] = useState22([]);
|
|
25377
|
-
const setLoadedSlotCycles =
|
|
25603
|
+
const setLoadedSlotCycles = useCallback7((cycles) => {
|
|
25378
25604
|
setSlotCycles(cycles ?? []);
|
|
25379
25605
|
}, []);
|
|
25380
|
-
const loadSessionState =
|
|
25606
|
+
const loadSessionState = useCallback7(
|
|
25381
25607
|
() => loadReviewSessionState({
|
|
25382
25608
|
extractSessionId,
|
|
25383
25609
|
tokenSessionId,
|
|
@@ -25999,7 +26225,7 @@ function GenerateReviewStepView({
|
|
|
25999
26225
|
}
|
|
26000
26226
|
return;
|
|
26001
26227
|
}
|
|
26002
|
-
if (input === "c" && cycleRows.length > 0) {
|
|
26228
|
+
if (input === "c" && !key.ctrl && !key.meta && cycleRows.length > 0) {
|
|
26003
26229
|
cyclePanel.open();
|
|
26004
26230
|
setCyclePanelScroll(0);
|
|
26005
26231
|
setCyclesCursor(0);
|
|
@@ -26587,10 +26813,31 @@ var init_GenerateReviewStep = __esm({
|
|
|
26587
26813
|
|
|
26588
26814
|
// packages/experience-design-system-cli/src/import/tui/runScopeGate.ts
|
|
26589
26815
|
async function runScopeGate(opts) {
|
|
26816
|
+
const startedAt = Date.now();
|
|
26817
|
+
getDebugLogger().event("wizard", "scope-decision-persistence.start", {
|
|
26818
|
+
sessionId: opts.sessionId,
|
|
26819
|
+
acceptedCount: opts.decisions.accepted.length,
|
|
26820
|
+
rejectedCount: opts.decisions.rejected.length
|
|
26821
|
+
});
|
|
26590
26822
|
const db = openPipelineDb();
|
|
26591
26823
|
try {
|
|
26592
26824
|
applyScopeDecisions(db, opts.sessionId, opts.decisions);
|
|
26593
26825
|
await writeScopeDecisionsSnapshot(db, opts.sessionId, opts.decisions);
|
|
26826
|
+
getDebugLogger().event("wizard", "scope-decision-persistence.complete", {
|
|
26827
|
+
sessionId: opts.sessionId,
|
|
26828
|
+
acceptedCount: opts.decisions.accepted.length,
|
|
26829
|
+
rejectedCount: opts.decisions.rejected.length,
|
|
26830
|
+
durationMs: Date.now() - startedAt
|
|
26831
|
+
});
|
|
26832
|
+
} catch (error) {
|
|
26833
|
+
getDebugLogger().event("wizard", "scope-decision-persistence.error", {
|
|
26834
|
+
sessionId: opts.sessionId,
|
|
26835
|
+
acceptedCount: opts.decisions.accepted.length,
|
|
26836
|
+
rejectedCount: opts.decisions.rejected.length,
|
|
26837
|
+
durationMs: Date.now() - startedAt,
|
|
26838
|
+
error: error instanceof Error ? error.message : String(error)
|
|
26839
|
+
});
|
|
26840
|
+
throw error;
|
|
26594
26841
|
} finally {
|
|
26595
26842
|
db.close();
|
|
26596
26843
|
}
|
|
@@ -26604,6 +26851,7 @@ var init_runScopeGate = __esm({
|
|
|
26604
26851
|
"packages/experience-design-system-cli/src/import/tui/runScopeGate.ts"() {
|
|
26605
26852
|
"use strict";
|
|
26606
26853
|
init_persistence();
|
|
26854
|
+
init_debug_logger();
|
|
26607
26855
|
init_db();
|
|
26608
26856
|
}
|
|
26609
26857
|
});
|
|
@@ -26857,6 +27105,10 @@ function buildGenerateComponentsArgs(opts) {
|
|
|
26857
27105
|
if (opts.generatePromptPath) args.push("--generate-prompt-path", opts.generatePromptPath);
|
|
26858
27106
|
for (const prompt of opts.promptOverrides ?? []) args.push("--prompt", prompt);
|
|
26859
27107
|
if (opts.existingEntitiesPath) args.push("--existing-entities-path", opts.existingEntitiesPath);
|
|
27108
|
+
if (opts.restoreCache) args.push("--restore-cache");
|
|
27109
|
+
if (opts.cachedComponents && opts.cachedComponents.length > 0) {
|
|
27110
|
+
args.push("--cached-components", JSON.stringify(opts.cachedComponents));
|
|
27111
|
+
}
|
|
26860
27112
|
return args;
|
|
26861
27113
|
}
|
|
26862
27114
|
function buildGenerateTokensArgs(opts) {
|
|
@@ -26940,6 +27192,17 @@ function logStep(entry) {
|
|
|
26940
27192
|
appendFileSync2(WIZARD_LOG, line);
|
|
26941
27193
|
getDebugLogger().event("wizard", "step", entry);
|
|
26942
27194
|
}
|
|
27195
|
+
function startWizardTimer(name, payload = {}) {
|
|
27196
|
+
const startedAt = Date.now();
|
|
27197
|
+
getDebugLogger().event("wizard", `${name}.start`, payload);
|
|
27198
|
+
return startedAt;
|
|
27199
|
+
}
|
|
27200
|
+
function finishWizardTimer(name, startedAt, payload = {}) {
|
|
27201
|
+
getDebugLogger().event("wizard", `${name}.complete`, {
|
|
27202
|
+
...payload,
|
|
27203
|
+
durationMs: Date.now() - startedAt
|
|
27204
|
+
});
|
|
27205
|
+
}
|
|
26943
27206
|
function WizardApp({
|
|
26944
27207
|
initialSpaceId = "",
|
|
26945
27208
|
initialEnvironmentId = "master",
|
|
@@ -26962,6 +27225,7 @@ function WizardApp({
|
|
|
26962
27225
|
const resolveWizardHost = (hostValue) => hostValue || defaultConfiguredHost;
|
|
26963
27226
|
const credentialKey = (spaceId, environmentId, cmaToken, hostValue) => [spaceId.trim(), environmentId.trim(), cmaToken.trim(), resolveWizardHost(hostValue)].join("\0");
|
|
26964
27227
|
const { columns: terminalWidth } = useTerminalSize();
|
|
27228
|
+
const clearScreenOnTransition = useScreenTransitionClear();
|
|
26965
27229
|
const logInit = useRef10(false);
|
|
26966
27230
|
const initialAgentAuthRef = useRef10(initialAgentAuth ?? null);
|
|
26967
27231
|
if (!logInit.current) {
|
|
@@ -26975,6 +27239,8 @@ function WizardApp({
|
|
|
26975
27239
|
});
|
|
26976
27240
|
const allowEmptyDeleteAllRef = useRef10(false);
|
|
26977
27241
|
const generateChildRef = useRef10(null);
|
|
27242
|
+
const generationCachePreflightRef = useRef10(null);
|
|
27243
|
+
const selectionToReviewStartedAtRef = useRef10(null);
|
|
26978
27244
|
const credentialsValidationIdRef = useRef10(0);
|
|
26979
27245
|
const pendingCredentialValidationRef = useRef10(null);
|
|
26980
27246
|
const validatedCredentialsKeyRef = useRef10(null);
|
|
@@ -26982,7 +27248,9 @@ function WizardApp({
|
|
|
26982
27248
|
const extractPromiseRef = useRef10(null);
|
|
26983
27249
|
const extractStartedRef = useRef10(false);
|
|
26984
27250
|
const credentialsReadyRef = useRef10(false);
|
|
27251
|
+
const agentAuthVerifiedRef = useRef10(false);
|
|
26985
27252
|
const scopeGateCompletedRef = useRef10(false);
|
|
27253
|
+
const scopeComponentsRef = useRef10(null);
|
|
26986
27254
|
const existingEntitiesPromiseRef = useRef10(null);
|
|
26987
27255
|
const generatePromiseRef = useRef10(null);
|
|
26988
27256
|
const rawTokensEntryReady = !!initialRawTokensPath;
|
|
@@ -27052,7 +27320,10 @@ function WizardApp({
|
|
|
27052
27320
|
tokensPath: state.tokensPath
|
|
27053
27321
|
};
|
|
27054
27322
|
}, [state.extractSessionId, state.tokensPath]);
|
|
27055
|
-
const update = (partial) => {
|
|
27323
|
+
const update = (partial, options = {}) => {
|
|
27324
|
+
if (partial.step !== void 0 && partial.step !== state.step && options.clearScreen !== false) {
|
|
27325
|
+
clearScreenOnTransition();
|
|
27326
|
+
}
|
|
27056
27327
|
const sanitized = { ...partial };
|
|
27057
27328
|
if (sanitized.serverPreview) {
|
|
27058
27329
|
const p = sanitized.serverPreview;
|
|
@@ -27099,12 +27370,41 @@ function WizardApp({
|
|
|
27099
27370
|
logStep({ update: sanitized });
|
|
27100
27371
|
setState((prev) => ({ ...prev, ...partial }));
|
|
27101
27372
|
};
|
|
27102
|
-
const
|
|
27373
|
+
const finishSelectionToReviewTimer = (mode) => {
|
|
27374
|
+
const startedAt = selectionToReviewStartedAtRef.current;
|
|
27375
|
+
if (startedAt === null) return;
|
|
27376
|
+
selectionToReviewStartedAtRef.current = null;
|
|
27377
|
+
finishWizardTimer("selection-to-review", startedAt, { mode });
|
|
27378
|
+
};
|
|
27379
|
+
const runAgentAuthCheck = async (nextStep, deferStep = false) => {
|
|
27380
|
+
const timer = startWizardTimer("agent-auth-validation", {
|
|
27381
|
+
agent: state.agent,
|
|
27382
|
+
deferred: deferStep,
|
|
27383
|
+
nextStep
|
|
27384
|
+
});
|
|
27385
|
+
if (agentAuthVerifiedRef.current) {
|
|
27386
|
+
finishWizardTimer("agent-auth-validation", timer, { status: "already-verified" });
|
|
27387
|
+
if (!deferStep) update({ step: nextStep });
|
|
27388
|
+
return true;
|
|
27389
|
+
}
|
|
27103
27390
|
const authCheckStepNumber = state.tokensPath ? 4 : 3;
|
|
27104
27391
|
const prefetchedAuth = initialAgentAuthRef.current;
|
|
27105
27392
|
initialAgentAuthRef.current = null;
|
|
27106
|
-
if (!prefetchedAuth) update({ step: "checking-claude-auth", authCheckStepNumber });
|
|
27107
|
-
|
|
27393
|
+
if (!prefetchedAuth && !deferStep) update({ step: "checking-claude-auth", authCheckStepNumber });
|
|
27394
|
+
let status;
|
|
27395
|
+
try {
|
|
27396
|
+
status = await (prefetchedAuth ?? checkAgentAuth(state.agent));
|
|
27397
|
+
} catch (error) {
|
|
27398
|
+
finishWizardTimer("agent-auth-validation", timer, {
|
|
27399
|
+
status: "error",
|
|
27400
|
+
error: error instanceof Error ? error.message : String(error)
|
|
27401
|
+
});
|
|
27402
|
+
throw error;
|
|
27403
|
+
}
|
|
27404
|
+
finishWizardTimer("agent-auth-validation", timer, {
|
|
27405
|
+
status,
|
|
27406
|
+
prefetched: Boolean(prefetchedAuth)
|
|
27407
|
+
});
|
|
27108
27408
|
if (status === "not-found") {
|
|
27109
27409
|
update({
|
|
27110
27410
|
step: "error",
|
|
@@ -27128,7 +27428,8 @@ If you are using AWS Bedrock, run:
|
|
|
27128
27428
|
});
|
|
27129
27429
|
return false;
|
|
27130
27430
|
}
|
|
27131
|
-
|
|
27431
|
+
agentAuthVerifiedRef.current = true;
|
|
27432
|
+
if (!deferStep) update({ step: nextStep });
|
|
27132
27433
|
return true;
|
|
27133
27434
|
};
|
|
27134
27435
|
const runGenerateTokens = async (rawTokensPath, outDir, forceRegenerate = false) => {
|
|
@@ -27183,7 +27484,13 @@ If you are using AWS Bedrock, run:
|
|
|
27183
27484
|
update({ tokensPath, tokenSessionId, tokenCount, tokenGenerationStatus: "complete" });
|
|
27184
27485
|
return true;
|
|
27185
27486
|
};
|
|
27186
|
-
const runMapTokens2 = async (sessionId2) => {
|
|
27487
|
+
const runMapTokens2 = async (sessionId2, silent = false) => {
|
|
27488
|
+
const timer = startWizardTimer("token-mapping", {
|
|
27489
|
+
sessionId: sessionId2,
|
|
27490
|
+
silent,
|
|
27491
|
+
noCache: effectiveNoCache,
|
|
27492
|
+
skipAgent: skipMapTokens
|
|
27493
|
+
});
|
|
27187
27494
|
let mappablePropCount = 0;
|
|
27188
27495
|
let rawTokenCount = 0;
|
|
27189
27496
|
try {
|
|
@@ -27210,13 +27517,22 @@ If you are using AWS Bedrock, run:
|
|
|
27210
27517
|
errorStep: "map tokens",
|
|
27211
27518
|
errorMessage: error instanceof Error ? error.message : String(error)
|
|
27212
27519
|
});
|
|
27520
|
+
finishWizardTimer("token-mapping", timer, {
|
|
27521
|
+
status: "error",
|
|
27522
|
+
error: error instanceof Error ? error.message : String(error)
|
|
27523
|
+
});
|
|
27213
27524
|
return false;
|
|
27214
27525
|
}
|
|
27215
27526
|
if (!shouldRunMapTokens({ mappablePropCount, rawTokenCount })) {
|
|
27216
|
-
update({ mapTokensEligible: false, mapTokensStatus: "complete" });
|
|
27527
|
+
if (!silent) update({ mapTokensEligible: false, mapTokensStatus: "complete" });
|
|
27528
|
+
finishWizardTimer("token-mapping", timer, {
|
|
27529
|
+
status: "skipped",
|
|
27530
|
+
mappablePropCount,
|
|
27531
|
+
rawTokenCount
|
|
27532
|
+
});
|
|
27217
27533
|
return true;
|
|
27218
27534
|
}
|
|
27219
|
-
update({ mapTokensEligible: true, mapTokensStatus: "running" });
|
|
27535
|
+
if (!silent) update({ mapTokensEligible: true, mapTokensStatus: "running", step: "generating" });
|
|
27220
27536
|
const args = buildMapTokensArgs({
|
|
27221
27537
|
sessionId: sessionId2,
|
|
27222
27538
|
agent: state.agent,
|
|
@@ -27234,9 +27550,21 @@ If you are using AWS Bedrock, run:
|
|
|
27234
27550
|
errorStep: "map tokens",
|
|
27235
27551
|
errorMessage: result.stderr.trim() || "Unknown error"
|
|
27236
27552
|
});
|
|
27553
|
+
finishWizardTimer("token-mapping", timer, {
|
|
27554
|
+
status: "error",
|
|
27555
|
+
exitCode: result.exitCode,
|
|
27556
|
+
mappablePropCount,
|
|
27557
|
+
rawTokenCount
|
|
27558
|
+
});
|
|
27237
27559
|
return false;
|
|
27238
27560
|
}
|
|
27239
|
-
update({ mapTokensStatus: "complete" });
|
|
27561
|
+
if (!silent) update({ mapTokensStatus: "complete" });
|
|
27562
|
+
finishWizardTimer("token-mapping", timer, {
|
|
27563
|
+
status: "complete",
|
|
27564
|
+
exitCode: result.exitCode,
|
|
27565
|
+
mappablePropCount,
|
|
27566
|
+
rawTokenCount
|
|
27567
|
+
});
|
|
27240
27568
|
return true;
|
|
27241
27569
|
};
|
|
27242
27570
|
const startExistingEntitiesFetch = (projectPath, outDir) => {
|
|
@@ -27486,7 +27814,7 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
27486
27814
|
generateProgress: null
|
|
27487
27815
|
}));
|
|
27488
27816
|
};
|
|
27489
|
-
const
|
|
27817
|
+
const buildGenerateOptions = (extractSessionId, tokensPath, generatePromptPath2, cachedComponents) => ({
|
|
27490
27818
|
sessionId: extractSessionId,
|
|
27491
27819
|
tokensPath,
|
|
27492
27820
|
agent: state.agent,
|
|
@@ -27495,8 +27823,127 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
27495
27823
|
noCache: effectiveNoCache,
|
|
27496
27824
|
...state.existingEntitiesPath ? { existingEntitiesPath: state.existingEntitiesPath } : {},
|
|
27497
27825
|
...generatePromptPath2 ? { generatePromptPath: generatePromptPath2 } : {},
|
|
27498
|
-
promptOverrides
|
|
27826
|
+
promptOverrides,
|
|
27827
|
+
...cachedComponents && cachedComponents.length > 0 ? { cachedComponents } : {}
|
|
27499
27828
|
});
|
|
27829
|
+
const buildGenerateArgs = (extractSessionId, tokensPath, generatePromptPath2, cachedComponents) => buildGenerateProcessArgs(buildGenerateOptions(extractSessionId, tokensPath, generatePromptPath2, cachedComponents));
|
|
27830
|
+
const buildGenerateCliArgs = (extractSessionId, tokensPath, generatePromptPath2, cachedComponents) => buildGenerateComponentsArgs(
|
|
27831
|
+
buildGenerateOptions(extractSessionId, tokensPath, generatePromptPath2, cachedComponents)
|
|
27832
|
+
);
|
|
27833
|
+
const checkGenerateCache = async (extractSessionId, tokensPath) => {
|
|
27834
|
+
const timer = startWizardTimer("generation-cache-status", {
|
|
27835
|
+
sessionId: extractSessionId,
|
|
27836
|
+
noCache: effectiveNoCache
|
|
27837
|
+
});
|
|
27838
|
+
if (effectiveNoCache) {
|
|
27839
|
+
finishWizardTimer("generation-cache-status", timer, { status: "skipped" });
|
|
27840
|
+
return false;
|
|
27841
|
+
}
|
|
27842
|
+
const result = await runCli([...buildGenerateCliArgs(extractSessionId, tokensPath), "--cache-status"]);
|
|
27843
|
+
const hit = result.exitCode === 0 && /^cache-status=hit$/m.test(result.stdout);
|
|
27844
|
+
finishWizardTimer("generation-cache-status", timer, {
|
|
27845
|
+
status: hit ? "hit" : "miss",
|
|
27846
|
+
exitCode: result.exitCode,
|
|
27847
|
+
...result.exitCode !== 0 ? { stderrTail: result.stderr.trim().slice(-500) } : {}
|
|
27848
|
+
});
|
|
27849
|
+
return hit;
|
|
27850
|
+
};
|
|
27851
|
+
const checkGenerateCacheComponents = async (extractSessionId, tokensPath, restoreCache = false) => {
|
|
27852
|
+
const timer = startWizardTimer("generation-cache-components", {
|
|
27853
|
+
sessionId: extractSessionId,
|
|
27854
|
+
restoreCache,
|
|
27855
|
+
noCache: effectiveNoCache
|
|
27856
|
+
});
|
|
27857
|
+
if (effectiveNoCache) {
|
|
27858
|
+
finishWizardTimer("generation-cache-components", timer, { status: "skipped" });
|
|
27859
|
+
return /* @__PURE__ */ new Set();
|
|
27860
|
+
}
|
|
27861
|
+
const args = [...buildGenerateCliArgs(extractSessionId, tokensPath), "--cache-status"];
|
|
27862
|
+
if (restoreCache) args.push("--restore-cache");
|
|
27863
|
+
const result = await runCli(args);
|
|
27864
|
+
if (result.exitCode !== 0) {
|
|
27865
|
+
finishWizardTimer("generation-cache-components", timer, {
|
|
27866
|
+
status: "error",
|
|
27867
|
+
exitCode: result.exitCode,
|
|
27868
|
+
stderrTail: result.stderr.trim().slice(-500)
|
|
27869
|
+
});
|
|
27870
|
+
return /* @__PURE__ */ new Set();
|
|
27871
|
+
}
|
|
27872
|
+
const line = /^cache-components=(.+)$/m.exec(result.stdout)?.[1];
|
|
27873
|
+
if (!line) {
|
|
27874
|
+
finishWizardTimer("generation-cache-components", timer, {
|
|
27875
|
+
status: "missing-output",
|
|
27876
|
+
exitCode: result.exitCode,
|
|
27877
|
+
cachedCount: 0
|
|
27878
|
+
});
|
|
27879
|
+
return /* @__PURE__ */ new Set();
|
|
27880
|
+
}
|
|
27881
|
+
try {
|
|
27882
|
+
const names = JSON.parse(line);
|
|
27883
|
+
const cachedNames = new Set(
|
|
27884
|
+
Array.isArray(names) ? names.filter((name) => typeof name === "string") : []
|
|
27885
|
+
);
|
|
27886
|
+
finishWizardTimer("generation-cache-components", timer, {
|
|
27887
|
+
status: "complete",
|
|
27888
|
+
exitCode: result.exitCode,
|
|
27889
|
+
cachedCount: cachedNames.size
|
|
27890
|
+
});
|
|
27891
|
+
return cachedNames;
|
|
27892
|
+
} catch {
|
|
27893
|
+
finishWizardTimer("generation-cache-components", timer, {
|
|
27894
|
+
status: "invalid-output",
|
|
27895
|
+
exitCode: result.exitCode,
|
|
27896
|
+
cachedCount: 0
|
|
27897
|
+
});
|
|
27898
|
+
return /* @__PURE__ */ new Set();
|
|
27899
|
+
}
|
|
27900
|
+
};
|
|
27901
|
+
useEffect15(() => {
|
|
27902
|
+
if (state.step !== "extracting" && state.step !== "scope-gate" || !state.extractSessionId || state.existingEntitiesStatus === "running" || state.existingEntitiesStatus === "idle" || state.selectionAgentStatus !== "complete" || state.compositionPhase !== "done" && state.compositionPhase !== "cache-hit" || state.rawTokensPath && state.tokenGenerationStatus !== "complete" || effectiveNoCache) {
|
|
27903
|
+
return;
|
|
27904
|
+
}
|
|
27905
|
+
const sessionId2 = state.extractSessionId;
|
|
27906
|
+
if (generationCachePreflightRef.current?.sessionId === sessionId2) return;
|
|
27907
|
+
const timer = startWizardTimer("generation-cache-preflight", { sessionId: sessionId2 });
|
|
27908
|
+
const db = openPipelineDb();
|
|
27909
|
+
let generatedNames = null;
|
|
27910
|
+
try {
|
|
27911
|
+
const rows = db.prepare("SELECT name, status FROM raw_components WHERE session_id = ?").all(sessionId2);
|
|
27912
|
+
if (rows.length > 0 && rows.every((row) => row.status === "generated")) {
|
|
27913
|
+
generatedNames = new Set(rows.map((row) => row.name));
|
|
27914
|
+
}
|
|
27915
|
+
} finally {
|
|
27916
|
+
db.close();
|
|
27917
|
+
}
|
|
27918
|
+
if (generatedNames) {
|
|
27919
|
+
generationCachePreflightRef.current = { sessionId: sessionId2, promise: Promise.resolve(generatedNames) };
|
|
27920
|
+
finishWizardTimer("generation-cache-preflight", timer, {
|
|
27921
|
+
status: "complete",
|
|
27922
|
+
source: "session-db",
|
|
27923
|
+
cachedCount: generatedNames.size
|
|
27924
|
+
});
|
|
27925
|
+
return;
|
|
27926
|
+
}
|
|
27927
|
+
const promise = checkGenerateCacheComponents(sessionId2, state.tokensPath, true);
|
|
27928
|
+
generationCachePreflightRef.current = { sessionId: sessionId2, promise };
|
|
27929
|
+
void promise.then((cachedNames) => {
|
|
27930
|
+
finishWizardTimer("generation-cache-preflight", timer, {
|
|
27931
|
+
status: "complete",
|
|
27932
|
+
source: "cache-status",
|
|
27933
|
+
cachedCount: cachedNames.size
|
|
27934
|
+
});
|
|
27935
|
+
});
|
|
27936
|
+
}, [
|
|
27937
|
+
state.step,
|
|
27938
|
+
state.extractSessionId,
|
|
27939
|
+
state.tokensPath,
|
|
27940
|
+
state.rawTokensPath,
|
|
27941
|
+
state.tokenGenerationStatus,
|
|
27942
|
+
state.selectionAgentStatus,
|
|
27943
|
+
state.compositionPhase,
|
|
27944
|
+
state.existingEntitiesStatus,
|
|
27945
|
+
state.existingEntitiesPath
|
|
27946
|
+
]);
|
|
27500
27947
|
const startGeneratePrefetch = (extractSessionId, tokensPath) => {
|
|
27501
27948
|
const args = buildGenerateArgs(extractSessionId, tokensPath);
|
|
27502
27949
|
let progressCursor = null;
|
|
@@ -27551,8 +27998,14 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
27551
27998
|
});
|
|
27552
27999
|
return donePromise;
|
|
27553
28000
|
};
|
|
27554
|
-
const runGenerate = async (extractSessionId, tokensPath, acceptedCount) => {
|
|
27555
|
-
const
|
|
28001
|
+
const runGenerate = async (extractSessionId, tokensPath, acceptedCount, suppressScreen = false, cachedComponents = []) => {
|
|
28002
|
+
const timer = startWizardTimer("component-generation", {
|
|
28003
|
+
sessionId: extractSessionId,
|
|
28004
|
+
acceptedCount,
|
|
28005
|
+
suppressScreen,
|
|
28006
|
+
noCache: effectiveNoCache
|
|
28007
|
+
});
|
|
28008
|
+
const args = buildGenerateArgs(extractSessionId, tokensPath, generatePromptPath, cachedComponents);
|
|
27556
28009
|
let progressCursor = state.generateProgress;
|
|
27557
28010
|
const { donePromise } = spawnGenerateChild({
|
|
27558
28011
|
command: "node",
|
|
@@ -27561,12 +28014,17 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
27561
28014
|
const nextProgress = parseGenerateStderrChunk(chunk, progressCursor);
|
|
27562
28015
|
if (nextProgress !== progressCursor) {
|
|
27563
28016
|
progressCursor = nextProgress;
|
|
27564
|
-
update({ generateProgress: nextProgress });
|
|
28017
|
+
if (!suppressScreen) update({ generateProgress: nextProgress });
|
|
27565
28018
|
}
|
|
27566
28019
|
}
|
|
27567
28020
|
});
|
|
27568
28021
|
const result = await donePromise;
|
|
27569
28022
|
if (result.exitCode !== 0) {
|
|
28023
|
+
finishWizardTimer("component-generation", timer, {
|
|
28024
|
+
status: "error",
|
|
28025
|
+
exitCode: result.exitCode
|
|
28026
|
+
});
|
|
28027
|
+
finishSelectionToReviewTimer("error");
|
|
27570
28028
|
update({
|
|
27571
28029
|
step: "error",
|
|
27572
28030
|
errorStep: "generate components",
|
|
@@ -27574,14 +28032,67 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
27574
28032
|
});
|
|
27575
28033
|
return;
|
|
27576
28034
|
}
|
|
27577
|
-
const { generateSessionId: generateSessionId2, generatedCount } = parseGenerateResult(result, acceptedCount);
|
|
28035
|
+
const { generateSessionId: generateSessionId2, generatedCount, renamedSlotsCount } = parseGenerateResult(result, acceptedCount);
|
|
27578
28036
|
const mappedSessionId = generateSessionId2 ?? extractSessionId;
|
|
27579
|
-
|
|
27580
|
-
|
|
28037
|
+
finishWizardTimer("component-generation", timer, {
|
|
28038
|
+
status: "complete",
|
|
28039
|
+
exitCode: result.exitCode,
|
|
27581
28040
|
generatedCount,
|
|
27582
|
-
|
|
28041
|
+
renamedSlotsCount
|
|
27583
28042
|
});
|
|
27584
|
-
if (
|
|
28043
|
+
if (!suppressScreen) {
|
|
28044
|
+
update({
|
|
28045
|
+
acceptedCount,
|
|
28046
|
+
autoRejectedCount: 0,
|
|
28047
|
+
generateSessionId: mappedSessionId,
|
|
28048
|
+
generatedCount,
|
|
28049
|
+
generateProgress: null
|
|
28050
|
+
});
|
|
28051
|
+
if (await runMapTokens2(mappedSessionId)) {
|
|
28052
|
+
finishSelectionToReviewTimer("generated");
|
|
28053
|
+
update({ step: "final-review" });
|
|
28054
|
+
} else {
|
|
28055
|
+
finishSelectionToReviewTimer("error");
|
|
28056
|
+
}
|
|
28057
|
+
return;
|
|
28058
|
+
}
|
|
28059
|
+
const mapped = await runMapTokens2(mappedSessionId, true);
|
|
28060
|
+
if (mapped) {
|
|
28061
|
+
finishSelectionToReviewTimer("generated");
|
|
28062
|
+
update(
|
|
28063
|
+
{
|
|
28064
|
+
acceptedCount,
|
|
28065
|
+
autoRejectedCount: 0,
|
|
28066
|
+
generateSessionId: mappedSessionId,
|
|
28067
|
+
generatedCount,
|
|
28068
|
+
generateProgress: null,
|
|
28069
|
+
mapTokensStatus: "complete",
|
|
28070
|
+
step: "final-review"
|
|
28071
|
+
},
|
|
28072
|
+
{ clearScreen: false }
|
|
28073
|
+
);
|
|
28074
|
+
} else {
|
|
28075
|
+
finishSelectionToReviewTimer("error");
|
|
28076
|
+
}
|
|
28077
|
+
};
|
|
28078
|
+
const finishCachedGeneration = async (sessionId2, acceptedCount) => {
|
|
28079
|
+
if (await runMapTokens2(sessionId2, true)) {
|
|
28080
|
+
finishSelectionToReviewTimer("cached");
|
|
28081
|
+
update(
|
|
28082
|
+
{
|
|
28083
|
+
acceptedCount,
|
|
28084
|
+
autoRejectedCount: 0,
|
|
28085
|
+
generateSessionId: sessionId2,
|
|
28086
|
+
generatedCount: acceptedCount,
|
|
28087
|
+
generateProgress: null,
|
|
28088
|
+
mapTokensStatus: "complete",
|
|
28089
|
+
step: "final-review"
|
|
28090
|
+
},
|
|
28091
|
+
{ clearScreen: false }
|
|
28092
|
+
);
|
|
28093
|
+
} else {
|
|
28094
|
+
finishSelectionToReviewTimer("error");
|
|
28095
|
+
}
|
|
27585
28096
|
};
|
|
27586
28097
|
const advanceToPushFlow = (generatedAcceptedCount) => {
|
|
27587
28098
|
update({ generatedAcceptedCount });
|
|
@@ -27766,8 +28277,15 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
27766
28277
|
return;
|
|
27767
28278
|
}
|
|
27768
28279
|
}
|
|
27769
|
-
if (await runAgentAuthCheck("generating")) {
|
|
27770
|
-
|
|
28280
|
+
if (await runAgentAuthCheck("generating", true)) {
|
|
28281
|
+
const cacheHit = await checkGenerateCache(sid, state.tokensPath);
|
|
28282
|
+
if (cacheHit) {
|
|
28283
|
+
update({ step: "generating" });
|
|
28284
|
+
void finishCachedGeneration(sid, state.acceptedCount);
|
|
28285
|
+
} else {
|
|
28286
|
+
update({ step: "generating" });
|
|
28287
|
+
void runGenerate(sid, state.tokensPath, state.acceptedCount);
|
|
28288
|
+
}
|
|
27771
28289
|
}
|
|
27772
28290
|
return;
|
|
27773
28291
|
}
|
|
@@ -28135,13 +28653,13 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28135
28653
|
update(nextStateAfterPrint({ skipGate: opts.skipGate, componentsPath }));
|
|
28136
28654
|
return { ok: true };
|
|
28137
28655
|
};
|
|
28138
|
-
const runSaveAndPush = async () => {
|
|
28139
|
-
await startSaveFlow({ skipGate: true, andPush: true });
|
|
28656
|
+
const runSaveAndPush = async (statePatch = {}) => {
|
|
28657
|
+
await startSaveFlow({ skipGate: true, andPush: true }, statePatch);
|
|
28140
28658
|
};
|
|
28141
28659
|
const pendingSaveOptionsRef = useRef10({});
|
|
28142
|
-
const startSaveFlow = async (opts = {}) => {
|
|
28660
|
+
const startSaveFlow = async (opts = {}, statePatch = {}) => {
|
|
28143
28661
|
pendingSaveOptionsRef.current = opts;
|
|
28144
|
-
|
|
28662
|
+
update({ ...statePatch, step: "path-prompt" });
|
|
28145
28663
|
};
|
|
28146
28664
|
const proceedToWrite = async (path) => {
|
|
28147
28665
|
setState((prev) => ({ ...prev, outDir: path }));
|
|
@@ -28373,42 +28891,103 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28373
28891
|
}
|
|
28374
28892
|
const sessionId2 = state.extractSessionId;
|
|
28375
28893
|
const db = openPipelineDb();
|
|
28376
|
-
let
|
|
28894
|
+
let loadedComponents;
|
|
28377
28895
|
try {
|
|
28378
|
-
|
|
28896
|
+
loadedComponents = loadScopeComponents(db, sessionId2);
|
|
28379
28897
|
} finally {
|
|
28380
28898
|
db.close();
|
|
28381
28899
|
}
|
|
28900
|
+
const remembered = scopeComponentsRef.current;
|
|
28901
|
+
if (loadedComponents.length > 0 && remembered?.sessionId !== sessionId2) {
|
|
28902
|
+
scopeComponentsRef.current = { sessionId: sessionId2, components: loadedComponents };
|
|
28903
|
+
}
|
|
28904
|
+
const rememberedForSession = scopeComponentsRef.current?.sessionId === sessionId2 ? scopeComponentsRef.current.components : null;
|
|
28905
|
+
const components = scopeGateCompletedRef.current && rememberedForSession ? rememberedForSession : loadedComponents.length > 0 ? loadedComponents : rememberedForSession ?? [];
|
|
28382
28906
|
return /* @__PURE__ */ jsx50(
|
|
28383
28907
|
ScopeGateStep,
|
|
28384
28908
|
{
|
|
28385
28909
|
components,
|
|
28386
28910
|
onConfirm: (decisions) => {
|
|
28387
|
-
void
|
|
28388
|
-
|
|
28389
|
-
|
|
28390
|
-
|
|
28391
|
-
|
|
28392
|
-
|
|
28393
|
-
|
|
28394
|
-
|
|
28395
|
-
|
|
28396
|
-
|
|
28397
|
-
|
|
28398
|
-
|
|
28399
|
-
|
|
28400
|
-
|
|
28911
|
+
void (async () => {
|
|
28912
|
+
selectionToReviewStartedAtRef.current = decisions.accepted.length > 0 ? startWizardTimer("selection-to-review", {
|
|
28913
|
+
sessionId: sessionId2,
|
|
28914
|
+
acceptedCount: decisions.accepted.length,
|
|
28915
|
+
rejectedCount: decisions.rejected.length
|
|
28916
|
+
}) : null;
|
|
28917
|
+
const preflight = generationCachePreflightRef.current;
|
|
28918
|
+
const cachePromise = preflight?.sessionId === sessionId2 ? preflight.promise : checkGenerateCacheComponents(sessionId2, state.tokensPath, true);
|
|
28919
|
+
if (!preflight || preflight.sessionId !== sessionId2) {
|
|
28920
|
+
generationCachePreflightRef.current = { sessionId: sessionId2, promise: cachePromise };
|
|
28921
|
+
}
|
|
28922
|
+
const cacheWaitStartedAt = startWizardTimer("selection-cache-restoration-wait", {
|
|
28923
|
+
sessionId: sessionId2,
|
|
28924
|
+
preflight: Boolean(preflight?.sessionId === sessionId2)
|
|
28925
|
+
});
|
|
28926
|
+
try {
|
|
28927
|
+
const cachedNames = await cachePromise;
|
|
28928
|
+
finishWizardTimer("selection-cache-restoration-wait", cacheWaitStartedAt, {
|
|
28929
|
+
status: "complete",
|
|
28930
|
+
cachedCount: cachedNames.size
|
|
28931
|
+
});
|
|
28932
|
+
} catch (error) {
|
|
28933
|
+
finishWizardTimer("selection-cache-restoration-wait", cacheWaitStartedAt, {
|
|
28934
|
+
status: "error",
|
|
28935
|
+
error: error instanceof Error ? error.message : String(error)
|
|
28936
|
+
});
|
|
28937
|
+
finishSelectionToReviewTimer("error");
|
|
28938
|
+
throw error;
|
|
28939
|
+
}
|
|
28940
|
+
await runScopeGate({
|
|
28941
|
+
sessionId: sessionId2,
|
|
28942
|
+
decisions,
|
|
28943
|
+
onAdvanceToGenerate: async ({ sessionId: sid, acceptedCount }) => {
|
|
28944
|
+
scopeGateCompletedRef.current = true;
|
|
28945
|
+
if (shouldGenerateAfterScopeGate({ acceptedCount })) {
|
|
28946
|
+
const authPromise = runAgentAuthCheck("generating", true);
|
|
28947
|
+
if (await authPromise) {
|
|
28948
|
+
const comparisonStartedAt = startWizardTimer("generation-cache-set-comparison", {
|
|
28949
|
+
sessionId: sid,
|
|
28950
|
+
acceptedCount: decisions?.accepted.length ?? 0
|
|
28951
|
+
});
|
|
28952
|
+
let cachedNames = await cachePromise;
|
|
28953
|
+
const acceptedNames = decisions?.accepted ?? [];
|
|
28954
|
+
let cacheHit = !effectiveNoCache && acceptedNames.length > 0 && acceptedNames.every((name) => cachedNames.has(name));
|
|
28955
|
+
if (!cacheHit && !effectiveNoCache && acceptedNames.length > 0) {
|
|
28956
|
+
cachedNames = await checkGenerateCacheComponents(sid, state.tokensPath, true);
|
|
28957
|
+
cacheHit = acceptedNames.every((name) => cachedNames.has(name));
|
|
28958
|
+
}
|
|
28959
|
+
finishWizardTimer("generation-cache-set-comparison", comparisonStartedAt, {
|
|
28960
|
+
status: "complete",
|
|
28961
|
+
cacheHit,
|
|
28962
|
+
cachedCount: cachedNames.size,
|
|
28963
|
+
acceptedCount: acceptedNames.length
|
|
28964
|
+
});
|
|
28965
|
+
if (cacheHit) {
|
|
28966
|
+
void finishCachedGeneration(sid, acceptedCount);
|
|
28967
|
+
} else {
|
|
28968
|
+
const acceptedNameSet = new Set(acceptedNames);
|
|
28969
|
+
const restoredCachedNames = [...cachedNames].filter((name) => acceptedNameSet.has(name));
|
|
28970
|
+
update({
|
|
28971
|
+
step: "generating",
|
|
28972
|
+
generateProgress: null,
|
|
28973
|
+
acceptedCount
|
|
28974
|
+
});
|
|
28975
|
+
void runGenerate(sid, state.tokensPath, acceptedCount, false, restoredCachedNames);
|
|
28976
|
+
}
|
|
28977
|
+
} else {
|
|
28978
|
+
finishSelectionToReviewTimer("error");
|
|
28979
|
+
}
|
|
28980
|
+
return;
|
|
28401
28981
|
}
|
|
28402
|
-
|
|
28982
|
+
void runSaveAndPush();
|
|
28983
|
+
},
|
|
28984
|
+
onAdvanceToPushFlow: (count) => {
|
|
28985
|
+
scopeGateCompletedRef.current = true;
|
|
28986
|
+
update({ acceptedCount: count, autoRejectedCount: 0 });
|
|
28987
|
+
advanceToPushFlow(count);
|
|
28403
28988
|
}
|
|
28404
|
-
|
|
28405
|
-
|
|
28406
|
-
onAdvanceToPushFlow: (count) => {
|
|
28407
|
-
scopeGateCompletedRef.current = true;
|
|
28408
|
-
update({ acceptedCount: count, autoRejectedCount: 0 });
|
|
28409
|
-
advanceToPushFlow(count);
|
|
28410
|
-
}
|
|
28411
|
-
});
|
|
28989
|
+
});
|
|
28990
|
+
})();
|
|
28412
28991
|
},
|
|
28413
28992
|
onQuit: () => process.exit(0)
|
|
28414
28993
|
}
|
|
@@ -28495,8 +29074,10 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28495
29074
|
}
|
|
28496
29075
|
const allowEmptyDeleteAll = acceptedCount === 0;
|
|
28497
29076
|
allowEmptyDeleteAllRef.current = allowEmptyDeleteAll;
|
|
28498
|
-
|
|
28499
|
-
|
|
29077
|
+
void runSaveAndPush({
|
|
29078
|
+
finalReviewPassed: true,
|
|
29079
|
+
generatedAcceptedCount: acceptedCount
|
|
29080
|
+
});
|
|
28500
29081
|
},
|
|
28501
29082
|
onQuit: () => process.exit(0)
|
|
28502
29083
|
}
|
|
@@ -28735,6 +29316,7 @@ var init_WizardApp = __esm({
|
|
|
28735
29316
|
init_prompt_overrides();
|
|
28736
29317
|
init_run_selection_agent();
|
|
28737
29318
|
init_use_terminal_size();
|
|
29319
|
+
init_render_with_goodbye();
|
|
28738
29320
|
SAVE_CONFIRMATION_DELAY_MS = 1e3;
|
|
28739
29321
|
WIZARD_LOG = join20(tmpdir(), "experiences-import-wizard.log");
|
|
28740
29322
|
}
|