feat(mosaic): migrate install wizard from v0 to v1 (#103)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
Co-authored-by: Jason Woltje <jason@diversecanvas.com> Co-committed-by: Jason Woltje <jason@diversecanvas.com>
This commit was merged in pull request #103.
This commit is contained in:
95
packages/mosaic/src/wizard.ts
Normal file
95
packages/mosaic/src/wizard.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import type { WizardPrompter } from './prompter/interface.js';
|
||||
import type { ConfigService } from './config/config-service.js';
|
||||
import type { WizardState } from './types.js';
|
||||
import { welcomeStage } from './stages/welcome.js';
|
||||
import { detectInstallStage } from './stages/detect-install.js';
|
||||
import { modeSelectStage } from './stages/mode-select.js';
|
||||
import { soulSetupStage } from './stages/soul-setup.js';
|
||||
import { userSetupStage } from './stages/user-setup.js';
|
||||
import { toolsSetupStage } from './stages/tools-setup.js';
|
||||
import { runtimeSetupStage } from './stages/runtime-setup.js';
|
||||
import { skillsSelectStage } from './stages/skills-select.js';
|
||||
import { finalizeStage } from './stages/finalize.js';
|
||||
|
||||
export interface WizardOptions {
|
||||
mosaicHome: string;
|
||||
sourceDir: string;
|
||||
prompter: WizardPrompter;
|
||||
configService: ConfigService;
|
||||
cliOverrides?: Partial<WizardState>;
|
||||
}
|
||||
|
||||
export async function runWizard(options: WizardOptions): Promise<void> {
|
||||
const { prompter, configService, mosaicHome, sourceDir } = options;
|
||||
|
||||
const state: WizardState = {
|
||||
mosaicHome,
|
||||
sourceDir,
|
||||
mode: 'quick',
|
||||
installAction: 'fresh',
|
||||
soul: {},
|
||||
user: {},
|
||||
tools: {},
|
||||
runtimes: { detected: [], mcpConfigured: false },
|
||||
selectedSkills: [],
|
||||
};
|
||||
|
||||
// Apply CLI overrides (strip undefined values)
|
||||
if (options.cliOverrides) {
|
||||
if (options.cliOverrides.soul) {
|
||||
for (const [k, v] of Object.entries(options.cliOverrides.soul)) {
|
||||
if (v !== undefined) {
|
||||
(state.soul as Record<string, unknown>)[k] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options.cliOverrides.user) {
|
||||
for (const [k, v] of Object.entries(options.cliOverrides.user)) {
|
||||
if (v !== undefined) {
|
||||
(state.user as Record<string, unknown>)[k] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options.cliOverrides.tools) {
|
||||
for (const [k, v] of Object.entries(options.cliOverrides.tools)) {
|
||||
if (v !== undefined) {
|
||||
(state.tools as Record<string, unknown>)[k] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options.cliOverrides.mode) {
|
||||
state.mode = options.cliOverrides.mode;
|
||||
}
|
||||
}
|
||||
|
||||
// Stage 1: Welcome
|
||||
await welcomeStage(prompter, state);
|
||||
|
||||
// Stage 2: Existing Install Detection
|
||||
await detectInstallStage(prompter, state, configService);
|
||||
|
||||
// Stage 3: Quick Start vs Advanced (skip if keeping existing)
|
||||
if (state.installAction === 'fresh' || state.installAction === 'reset') {
|
||||
await modeSelectStage(prompter, state);
|
||||
} else if (state.installAction === 'reconfigure') {
|
||||
state.mode = 'advanced';
|
||||
}
|
||||
|
||||
// Stage 4: SOUL.md
|
||||
await soulSetupStage(prompter, state);
|
||||
|
||||
// Stage 5: USER.md
|
||||
await userSetupStage(prompter, state);
|
||||
|
||||
// Stage 6: TOOLS.md
|
||||
await toolsSetupStage(prompter, state);
|
||||
|
||||
// Stage 7: Runtime Detection & Installation
|
||||
await runtimeSetupStage(prompter, state);
|
||||
|
||||
// Stage 8: Skills Selection
|
||||
await skillsSelectStage(prompter, state);
|
||||
|
||||
// Stage 9: Finalize
|
||||
await finalizeStage(prompter, state, configService);
|
||||
}
|
||||
Reference in New Issue
Block a user