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 {
  if (!ContextService.isInitialized()) {
    print('ContextForge has not been initialized.\nRun: contextforge init');
    return;
  }

  ContextService.ensureDataFilesExist();

  // Prompt for task details
  stdout.write('Task ID (e.g., feature-auth): ');
  var id = stdin.readLineSync() ?? '';
  id = id.trim();
  if (id.isEmpty) {
    print('Task ID cannot be empty.');
    return;
  }

  stdout.write('Task title: ');
  final title = stdin.readLineSync() ?? '';
  if (title.isEmpty) {
    print('Task title cannot be empty.');
    return;
  }

  stdout.write('Short description (one line): ');
  final description = stdin.readLineSync() ?? '';

  stdout.write('Status (todo/in-progress/completed) [todo]: ');
  final statusInput = stdin.readLineSync() ?? '';
  final status = _validateStatus(statusInput.isEmpty ? 'todo' : statusInput);

  if (status == null) {
    print('Invalid status. Use: todo, in-progress, or completed');
    return;
  }

  stdout.write('Related files (comma-separated, optional): ');
  final filesInput = stdin.readLineSync() ?? '';
  final files = filesInput.isEmpty
      ? <String>[]
      : filesInput.split(',').map((f) => f.trim()).toList();

  // Load all features (active + archive) to catch duplicate IDs
  final features = ContextService.loadAllFeatures();

  // Check for duplicate ID
  if (features.any((f) => f.id == id)) {
    print('Task with ID "$id" already exists.');
    return;
  }

  // Create feature (tasks are managed as features)
  final feature = Feature(
    id: id,
    title: title,
    status: status,
    description: description,
    files: files,
  );

  // Add and save
  features.add(feature);
  ContextService.saveFeatures(features);
  print('✔ Task "$title" added successfully (ID: $id)');
}