run method

  1. @override
void run()
override

Runs this command.

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

Implementation

@override
void run() {
  final contextDir = '.contextforge';
  final ide = argResults?['ide'] as String? ?? 'vscode';

  try {
    // Check if context directory already exists and has content
    if (Directory(contextDir).existsSync()) {
      final hasExistingContext = _hasExistingContext(contextDir);

      if (hasExistingContext) {
        final (taskCount, decisionCount) = _countExistingContext(contextDir);
        _handleExistingContext(contextDir, taskCount, decisionCount, ide);
        return;
      }
    }

    // Create fresh .contextforge directory
    Directory(contextDir).createSync(recursive: true);

    // Create data directory and YAML files
    final dataDir = '$contextDir/data';
    Directory(dataDir).createSync(recursive: true);
    _createFile('$dataDir/features.yaml', 'features: []');
    _createFile('$dataDir/decisions.yaml', 'decisions: []');

    // Create config file with IDE preference
    final configContent = 'ide: $ide\ngenerated: true';
    _createFile('$contextDir/config.yaml', configContent);

    // Create tasks and decisions folders with .gitkeep files
    final tasksDir = '$dataDir/tasks';
    final decisionsDir = '$dataDir/decisions';
    Directory(tasksDir).createSync(recursive: true);
    Directory(decisionsDir).createSync(recursive: true);
    _createFile('$tasksDir/.gitkeep', '');
    _createFile('$decisionsDir/.gitkeep', '');

    // Create context markdown files
    _createFile('$contextDir/ai_context.md', _aiContextMd);
    _createFile('$contextDir/project.md', _projectMd);
    _createFile('$contextDir/architecture.md', _architectureMd);
    _createFile('$contextDir/progress.md', _progressMd);
    _createFile('$contextDir/decisions.md', _decisionsMd);
    _createFile('$contextDir/tasks.md', _tasksMd);

    // Create MCP server directory and files
    final mcpServerDir = '$contextDir/mcp_server';
    Directory(mcpServerDir).createSync(recursive: true);
    _createFile('$mcpServerDir/package.json', _mcpPackageJson);
    _createFile('$mcpServerDir/index.js', _mcpIndexJs);

    // Create IDE-specific MCP config
    _createIdeMcpConfig(ide);

    // Create rules directory with AI behaviour rules
    final rulesDir = '$contextDir/rules';
    Directory(rulesDir).createSync(recursive: true);
    _createFile('$rulesDir/git.md', _gitRules);
    _createFile('$rulesDir/tasks.md', _tasksRules);
    _createFile('$rulesDir/files.md', _filesRules);
    _createFile('$rulesDir/communication.md', _communicationRules);

    // Create .github directory and copilot-instructions.md
    final githubDir = '.github';
    Directory(githubDir).createSync(recursive: true);
    final ideInstructions = _getIdeSpecificInstructions(ide);
    _createFile('$githubDir/copilot-instructions.md', ideInstructions);

    // Run npm install in MCP server directory
    final result = Process.runSync('npm', ['install'], workingDirectory: mcpServerDir);
    if (result.exitCode != 0) {
      print('Error running npm install: ${result.stderr}');
      return;
    }

    print('ContextForge initialized successfully for $ide.');
    print('Restart your editor to activate the MCP server.');
    _checkAndFixPath();
  } catch (e) {
    print('Error initializing ContextForge: $e');
  }
}