fix(wizard): avoid rerunning completed setup steps (#692)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/publish Pipeline was successful

This commit was merged in pull request #692.
This commit is contained in:
2026-06-25 18:44:35 +00:00
parent b96cc7982a
commit 495f73bfdb
6 changed files with 182 additions and 6 deletions

View File

@@ -126,6 +126,11 @@ type MenuChoice =
| 'advanced'
| 'finish';
function menuSectionKey(section: MenuChoice): MenuSection | null {
if (section === 'quick-start' || section === 'finish') return null;
return section === 'gateway-config' ? 'gateway' : section;
}
function menuLabel(section: MenuChoice, completed: Set<MenuSection>): string {
const labels: Record<MenuChoice, string> = {
'quick-start': 'Quick Start',
@@ -137,14 +142,24 @@ function menuLabel(section: MenuChoice, completed: Set<MenuSection>): string {
finish: 'Finish & Apply',
};
const base = labels[section];
const sectionKey: MenuSection =
section === 'gateway-config' ? 'gateway' : (section as MenuSection);
if (completed.has(sectionKey)) {
const sectionKey = menuSectionKey(section);
if (sectionKey && completed.has(sectionKey)) {
return `${base} [done]`;
}
return base;
}
function skipCompletedMenuChoice(
prompter: WizardPrompter,
completed: Set<MenuSection>,
choice: MenuChoice,
): boolean {
const sectionKey = menuSectionKey(choice);
if (!sectionKey || !completed.has(sectionKey)) return false;
prompter.log(`${menuLabel(choice, completed)} is already complete; skipping.`);
return true;
}
async function runMenuLoop(
prompter: WizardPrompter,
state: WizardState,
@@ -201,21 +216,25 @@ async function runMenuLoop(
return; // Quick start is a complete flow — exit menu
case 'providers':
if (skipCompletedMenuChoice(prompter, completed, choice)) break;
await providerSetupStage(prompter, state);
completed.add('providers');
break;
case 'identity':
if (skipCompletedMenuChoice(prompter, completed, choice)) break;
await agentIntentStage(prompter, state);
completed.add('identity');
break;
case 'skills':
if (skipCompletedMenuChoice(prompter, completed, choice)) break;
await skillsSelectStage(prompter, state);
completed.add('skills');
break;
case 'gateway-config':
if (skipCompletedMenuChoice(prompter, completed, choice)) break;
// Gateway config is handled during Finish — mark as "configured"
// after user reviews settings.
await runGatewaySubMenu(prompter, state, options);
@@ -223,6 +242,7 @@ async function runMenuLoop(
break;
case 'advanced':
if (skipCompletedMenuChoice(prompter, completed, choice)) break;
await runAdvancedSubMenu(prompter, state);
completed.add('advanced');
break;
@@ -325,7 +345,7 @@ async function runFinishPath(
portOverride: options.gatewayPortOverride,
skipInstall: options.skipGatewayNpmInstall,
providerKey: state.providerKey,
providerType: state.providerType ?? 'none',
providerType: state.providerType,
});
if (configResult.ready && configResult.host && configResult.port) {
@@ -396,7 +416,7 @@ async function runHeadlessPath(
portOverride: options.gatewayPortOverride,
skipInstall: options.skipGatewayNpmInstall,
providerKey: state.providerKey,
providerType: state.providerType ?? 'none',
providerType: state.providerType,
});
if (!configResult.ready || !configResult.host || !configResult.port) {