runWizard function
Runs the interactive TUI wizard and returns the assembled config.
Implementation
Future<BlueprintConfig?> runWizard() async {
// Step 1: Project info
final (name, org) = await projectInfoStep();
// Step 2: Output directory
final outputDir = Input(
prompt: 'Output directory',
defaultValue: './$name',
).interact();
// Step 3: Architecture
final architecture = await architectureStep();
// Step 4: State management
final stateManagement = await stateManagementStep();
// Step 5: Routing
final routing = await routingStep();
// Step 6: API
final api = await apiStep();
// Step 7: UI Feedback
final uiFeedback = await uiFeedbackStep();
// Step 8: Flavors
final flavors = await flavorsStep();
// Step 9: Notifications
final notifications = Confirm(
prompt: 'Include push notifications?',
defaultValue: false,
).interact();
// Step 10: Codegen
final codegen = await codegenStep();
// Step 11: Testing
final testing = await testingStep();
// Step 12: CI/CD
final ci = await ciStep();
final config = BlueprintConfig(
name: name,
org: org,
outputDir: outputDir,
architecture: architecture,
stateManagement: stateManagement,
routing: routing,
api: api,
features: FeaturesConfig(
uiFeedback: uiFeedback,
flavors: flavors,
notifications: notifications,
),
build: const BuildConfig(),
codegen: codegen,
testing: testing,
ci: ci,
);
// Step 13: Dry-run plan
print('\n─────────────────────────────────────────');
print('Planned actions:');
final planItems = <PlanItemMessage>[];
late EngineBridge bridge;
try {
bridge = EngineBridge(onMessage: (msg) {
if (msg is PlanItemMessage) planItems.add(msg);
});
final targetDir = config.outputDir == '.' ? Directory.current.path : config.outputDir;
await Directory(targetDir).create(recursive: true);
await bridge.run(config, targetDir, dryRun: true);
} catch (e) {
print('\n⚠ Could not run dry-run plan: $e');
print(' The engine may not be installed. Run `flutter_blueprint doctor` for details.');
}
displayPlan(planItems);
// Step 14: Confirm
final confirmed = Confirm(
prompt: 'Apply this plan?',
defaultValue: true,
).interact();
if (!confirmed) {
print('\nAborted. No files were written.');
return null;
}
return config;
}