# Action: Collect Context

收集审查目标的上下文信息。

## Purpose

在开始审查前，收集目标代码的基本信息：
- 确定审查范围（文件/目录）
- 识别编程语言和框架
- 统计代码规模

## Preconditions

- [ ] state.status === 'pending' || state.context === null

## Execution

```javascript
async function execute(state, workDir) {
  // 1. 询问用户审查目标
  const input = await AskUserQuestion({
    questions: [{
      question: "请指定要审查的代码路径：",
      header: "审查目标",
      multiSelect: false,
      options: [
        { label: "当前目录", description: "审查当前工作目录下的所有代码" },
        { label: "src/", description: "审查 src/ 目录" },
        { label: "手动指定", description: "输入自定义路径" }
      ]
    }]
  });
  
  const targetPath = input["审查目标"] === "手动指定" 
    ? input["其他"] 
    : input["审查目标"] === "当前目录" ? "." : "src/";
  
  // 2. 收集文件列表
  const files = Glob(`${targetPath}/**/*.{ts,tsx,js,jsx,py,java,go,rs,cpp,c,cs}`);
  
  // 3. 检测主要语言
  const languageCounts = {};
  files.forEach(file => {
    const ext = file.split('.').pop();
    const langMap = {
      'ts': 'TypeScript', 'tsx': 'TypeScript',
      'js': 'JavaScript', 'jsx': 'JavaScript',
      'py': 'Python',
      'java': 'Java',
      'go': 'Go',
      'rs': 'Rust',
      'cpp': 'C++', 'c': 'C',
      'cs': 'C#'
    };
    const lang = langMap[ext] || 'Unknown';
    languageCounts[lang] = (languageCounts[lang] || 0) + 1;
  });
  
  const primaryLanguage = Object.entries(languageCounts)
    .sort((a, b) => b[1] - a[1])[0]?.[0] || 'Unknown';
  
  // 4. 统计代码行数
  let totalLines = 0;
  for (const file of files.slice(0, 100)) {  // 限制前100个文件
    try {
      const content = Read(file);
      totalLines += content.split('\n').length;
    } catch (e) {}
  }
  
  // 5. 检测框架
  let framework = null;
  if (files.some(f => f.includes('package.json'))) {
    const pkg = JSON.parse(Read('package.json'));
    if (pkg.dependencies?.react) framework = 'React';
    else if (pkg.dependencies?.vue) framework = 'Vue';
    else if (pkg.dependencies?.angular) framework = 'Angular';
    else if (pkg.dependencies?.express) framework = 'Express';
    else if (pkg.dependencies?.next) framework = 'Next.js';
  }
  
  // 6. 构建上下文
  const context = {
    target_path: targetPath,
    files: files.slice(0, 200),  // 限制最多200个文件
    language: primaryLanguage,
    framework: framework,
    total_lines: totalLines,
    file_count: files.length
  };
  
  // 7. 保存上下文
  Write(`${workDir}/context.json`, JSON.stringify(context, null, 2));
  
  return {
    stateUpdates: {
      status: 'running',
      context: context
    }
  };
}
```

## State Updates

```javascript
return {
  stateUpdates: {
    status: 'running',
    context: {
      target_path: targetPath,
      files: fileList,
      language: primaryLanguage,
      framework: detectedFramework,
      total_lines: totalLines,
      file_count: fileCount
    }
  }
};
```

## Output

- **File**: `context.json`
- **Location**: `${workDir}/context.json`
- **Format**: JSON

## Error Handling

| Error Type | Recovery |
|------------|----------|
| 路径不存在 | 提示用户重新输入 |
| 无代码文件 | 返回错误，终止审查 |
| 读取权限问题 | 跳过该文件，记录警告 |

## Next Actions

- 成功: action-quick-scan
- 失败: action-abort
