runWizard function

Future<BlueprintConfig?> runWizard()

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;
}