run method

  1. @override
Future<void> run()
override

Runs this command.

The return value is wrapped in a Future if necessary and returned by CommandRunner.runCommand.

Implementation

@override
Future<void> run() async {
  final planFile = File('.spectra/PLAN.md');
  if (!planFile.existsSync()) {
    logger.err('PLAN.md not found. Run `spectra plan` first.');
    return;
  }

  final content = planFile.readAsStringSync();
  final taskDocs = _parseTasks(content);

  if (taskDocs.isEmpty) {
    logger.warn('No tasks found in PLAN.md.');
    return;
  }

  // Determine execution mode
  final config = await _configService.loadConfig();
  final manualFlag = argResults?['manual'] as bool? ?? false;
  final autoFlag = argResults?['auto'] as bool? ?? false;

  final ExecutionMode mode;
  if (manualFlag) {
    mode = ExecutionMode.manual;
  } else if (autoFlag) {
    mode = ExecutionMode.automatic;
  } else {
    // Use config or default to automatic
    final modeStr = config.executionMode ?? 'automatic';
    mode = ExecutionMode.values.firstWhere(
      (m) => m.name == modeStr,
      orElse: () => ExecutionMode.automatic,
    );
  }

  if (mode == ExecutionMode.manual) {
    await _displayTasksForManualExecution(taskDocs);
    return;
  }

  // Use coding provider for actual code generation
  final provider = await _llmService.getProviderForUsage(LLMUsageType.coding);
  if (provider == null) {
    logger.err('No coding provider configured.');
    return;
  }

  logger.info(
    'Executing ${taskDocs.length} tasks using ${provider.name} (Code Generation)...',
  );

  for (final taskDoc in taskDocs) {
    await _executeTask(taskDoc, provider);
  }

  // Prune state if it gets too large
  _stateManager.pruneState();

  logger.success('All tasks executed successfully!');
}