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 {
  print('\nContextForge Doctor');
  print('-' * 60);

  final checks = <String, bool>{};
  final fixes = <String, String>{};

  // Check 1: ContextForge initialized
  if (_checkContextForgeInitialized()) {
    print('✅ ContextForge initialized');
    checks['initialized'] = true;
  } else {
    print('❌ ContextForge not initialized');
    fixes['initialized'] =
        'Run contextforge init in your project root';
    checks['initialized'] = false;
  }

  // Check 2: Data files exist
  if (_checkDataFilesExist()) {
    print('✅ Data files exist');
    checks['dataFiles'] = true;
  } else {
    print('❌ Data files missing');
    fixes['dataFiles'] = 'Run contextforge upgrade to restore missing files';
    checks['dataFiles'] = false;
  }

  // Check 3: MCP server files exist
  if (_checkMcpServerFilesExist()) {
    print('✅ MCP server files exist');
    checks['mcpFiles'] = true;
  } else {
    print('❌ MCP server files missing');
    fixes['mcpFiles'] =
        'Run contextforge upgrade to restore MCP server';
    checks['mcpFiles'] = false;
  }

  // Check 4: npm packages installed
  if (_checkNpmPackagesInstalled()) {
    print('✅ npm packages installed');
    checks['npm'] = true;
  } else {
    print('❌ npm packages not installed');
    fixes['npm'] =
        'Run: cd .contextforge/mcp_server && npm install';
    checks['npm'] = false;
  }

  // Check 5: VS Code config exists
  if (_checkVscodeConfigExists()) {
    print('✅ VS Code config exists');
    checks['vscode'] = true;
  } else {
    print('❌ VS Code config missing');
    fixes['vscode'] =
        'Run contextforge init to generate .vscode/mcp.json';
    checks['vscode'] = false;
  }

  // Check 6: Node.js installed
  final nodeVersion = await _checkNodeInstalled();
  if (nodeVersion != null) {
    print('✅ Node.js $nodeVersion');
    checks['node'] = true;
  } else {
    print('❌ Node.js not found');
    fixes['node'] =
        'Node.js not found. Install from nodejs.org';
    checks['node'] = false;
  }

  // Check 7: copilot-instructions exists
  if (_checkCopilotInstructionsExist()) {
    print('✅ Copilot instructions exist');
    checks['copilot'] = true;
  } else {
    print('❌ Copilot instructions missing');
    fixes['copilot'] =
        'Run contextforge upgrade to restore instructions';
    checks['copilot'] = false;
  }

  // Check 8: Rules folder exists
  if (_checkRulesFolderExists()) {
    print('✅ AI rules exist');
    checks['rules'] = true;
  } else {
    print('❌ AI rules missing');
    fixes['rules'] =
        'Run contextforge upgrade to restore rules';
    checks['rules'] = false;
  }

  print('');

  // Print fixes for failed checks
  final failedChecks = checks.entries.where((e) => !e.value).toList();

  if (failedChecks.isNotEmpty) {
    for (final entry in failedChecks) {
      final fix = fixes[entry.key];
      if (fix != null) {
        print('  → $fix');
      }
    }
    print('');
    print('${failedChecks.length} issue${failedChecks.length > 1 ? 's' : ''} found. '
        'Run the suggested commands above to fix.');
    exitCode = 1;
  } else {
    print('No issues found. ContextForge is ready to use.');
    exitCode = 0;
  }

  print('');
}