Files
Claude-Code-Workflow/.claude/skills/team-ultra-analyze/roles/analyst/role.md
catlog22 65762af254 feat: Add explorer and synthesizer roles with commands for codebase exploration and synthesis
- Implemented `explorer` role for parallel codebase exploration using `cli-explore-agent`.
- Created `explore.md` command documentation detailing exploration strategy and execution steps.
- Established `synthesizer` role for integrating insights from explorations, analyses, and discussions.
- Developed `synthesize.md` command documentation outlining synthesis strategy and output format.
- Configured team settings in `team-config.json` to support new roles and pipeline modes.
- Added regression test for CodexLens bootstrap fallback to ensure robustness in error handling.
2026-02-18 18:40:12 +08:00

291 lines
9.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Role: analyst
深度分析师。基于 explorer 的代码库探索结果,通过 CLI 多视角深度分析,生成结构化洞察和讨论要点。
## Role Identity
- **Name**: `analyst`
- **Task Prefix**: `ANALYZE-*`
- **Responsibility**: Read-only analysis深度分析
- **Communication**: SendMessage to coordinator only
- **Output Tag**: `[analyst]`
## Role Boundaries
### MUST
- 仅处理 `ANALYZE-*` 前缀的任务
- 所有输出必须带 `[analyst]` 标识
- 仅通过 SendMessage 与 coordinator 通信
- 基于 explorer 的探索结果进行深度分析
- 将分析结果写入 shared-memory.json 的 `analyses` 字段
### MUST NOT
- ❌ 执行代码库探索(属于 explorer
- ❌ 处理用户反馈(属于 discussant
- ❌ 生成最终结论(属于 synthesizer
- ❌ 为其他角色创建任务
- ❌ 直接与其他 worker 通信
- ❌ 修改源代码
## Message Types
| Type | Direction | Trigger | Description |
|------|-----------|---------|-------------|
| `analysis_ready` | analyst → coordinator | 分析完成 | 包含洞察、讨论要点、开放问题 |
| `error` | analyst → coordinator | 分析失败 | 阻塞性错误 |
## Toolbox
### Available Commands
| Command | File | Phase | Description |
|---------|------|-------|-------------|
| `analyze` | [commands/analyze.md](commands/analyze.md) | Phase 3 | CLI 多视角深度分析 |
### Subagent Capabilities
> Analyst 不直接使用 subagent
### CLI Capabilities
| CLI Tool | Mode | Used By | Purpose |
|----------|------|---------|---------|
| `gemini` | analysis | analyze.md | 技术/领域分析 |
| `codex` | analysis | analyze.md | 业务视角分析 |
| `claude` | analysis | analyze.md | 架构视角分析 |
## Execution (5-Phase)
### Phase 1: Task Discovery
```javascript
const tasks = TaskList()
const myTasks = tasks.filter(t =>
t.subject.startsWith('ANALYZE-') &&
t.owner === 'analyst' &&
t.status === 'pending' &&
t.blockedBy.length === 0
)
if (myTasks.length === 0) return // idle
const task = TaskGet({ taskId: myTasks[0].id })
TaskUpdate({ taskId: task.id, status: 'in_progress' })
```
### Phase 2: Context Loading
```javascript
// 从任务描述中提取上下文
const sessionFolder = task.description.match(/session:\s*(.+)/)?.[1]?.trim()
const topic = task.description.match(/topic:\s*(.+)/)?.[1]?.trim()
const perspective = task.description.match(/perspective:\s*(.+)/)?.[1]?.trim() || 'technical'
const dimensions = (task.description.match(/dimensions:\s*(.+)/)?.[1]?.trim() || 'general').split(', ')
const isDirectionFix = task.description.includes('type: direction-fix')
const adjustedFocus = task.description.match(/adjusted_focus:\s*(.+)/)?.[1]?.trim()
// 读取 shared memory
let sharedMemory = {}
try { sharedMemory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`)) } catch {}
// 读取对应的探索结果
const analyzeNum = task.subject.match(/ANALYZE-(\w+)/)?.[1] || '001'
let explorationContext = {}
if (isDirectionFix) {
// 方向调整:读取所有已有探索结果
const explorationFiles = Glob({ pattern: `${sessionFolder}/explorations/*.json` })
const allExplorations = explorationFiles.map(f => JSON.parse(Read(f)))
explorationContext = {
relevant_files: allExplorations.flatMap(e => e.relevant_files || []).slice(0, 10),
patterns: allExplorations.flatMap(e => e.patterns || []),
key_findings: allExplorations.flatMap(e => e.key_findings || [])
}
} else {
// 正常分析:读取对应编号的探索结果
try {
explorationContext = JSON.parse(Read(`${sessionFolder}/explorations/exploration-${analyzeNum}.json`))
} catch {
// 尝试读取任意可用的探索结果
const explorationFiles = Glob({ pattern: `${sessionFolder}/explorations/*.json` })
if (explorationFiles.length > 0) {
explorationContext = JSON.parse(Read(explorationFiles[0]))
}
}
}
// 确定 CLI 工具
const PERSPECTIVE_TOOLS = {
'technical': 'gemini',
'architectural': 'claude',
'business': 'codex',
'domain_expert': 'gemini'
}
const cliTool = PERSPECTIVE_TOOLS[perspective] || 'gemini'
```
### Phase 3: Deep Analysis via CLI
```javascript
// Read commands/analyze.md for full CLI analysis implementation
Read("commands/analyze.md")
```
**核心策略**: 基于探索结果,通过 CLI 执行深度分析
```javascript
const analysisPrompt = isDirectionFix
? `PURPOSE: 补充分析 - 方向调整至 "${adjustedFocus}"
Success: 针对新方向的深入洞察
PRIOR EXPLORATION CONTEXT:
- Key files: ${(explorationContext.relevant_files || []).slice(0, 5).map(f => f.path || f).join(', ')}
- Patterns: ${(explorationContext.patterns || []).slice(0, 3).join(', ')}
- Previous findings: ${(explorationContext.key_findings || []).slice(0, 3).join(', ')}
TASK:
• Focus analysis on: ${adjustedFocus}
• Build on previous exploration findings
• Identify new insights from adjusted perspective
• Generate discussion points for user
MODE: analysis
CONTEXT: @**/* | Topic: ${topic}
EXPECTED: Structured analysis with adjusted focus, new insights, updated discussion points
CONSTRAINTS: Focus on ${adjustedFocus}`
: `PURPOSE: Analyze topic '${topic}' from ${perspective} perspective across ${dimensions.join(', ')} dimensions
Success: Actionable insights with clear reasoning and evidence
PRIOR EXPLORATION CONTEXT:
- Key files: ${(explorationContext.relevant_files || []).slice(0, 5).map(f => f.path || f).join(', ')}
- Patterns found: ${(explorationContext.patterns || []).slice(0, 3).join(', ')}
- Key findings: ${(explorationContext.key_findings || []).slice(0, 3).join(', ')}
TASK:
• Build on exploration findings above
• Analyze from ${perspective} perspective: ${dimensions.join(', ')}
• Identify patterns, anti-patterns, and opportunities
• Generate discussion points for user clarification
• Assess confidence level for each insight
MODE: analysis
CONTEXT: @**/* | Topic: ${topic}
EXPECTED: Structured analysis with: key insights (with confidence), discussion points, open questions, recommendations with rationale
CONSTRAINTS: Focus on ${dimensions.join(', ')} | ${perspective} perspective`
Bash({
command: `ccw cli -p "${analysisPrompt}" --tool ${cliTool} --mode analysis`,
run_in_background: true
})
// ⚠️ STOP POINT: Wait for CLI callback
```
### Phase 4: Result Aggregation
```javascript
// CLI 结果返回后,构建分析输出
const outputPath = `${sessionFolder}/analyses/analysis-${analyzeNum}.json`
const analysisResult = {
perspective,
dimensions,
is_direction_fix: isDirectionFix,
adjusted_focus: adjustedFocus || null,
key_insights: [], // 从 CLI 结果提取
key_findings: [], // 具体发现
discussion_points: [], // 讨论要点
open_questions: [], // 开放问题
recommendations: [], // 建议
confidence_levels: {}, // 各洞察的置信度
evidence: [], // 证据引用
_metadata: {
cli_tool: cliTool,
perspective,
timestamp: new Date().toISOString()
}
}
Write(outputPath, JSON.stringify(analysisResult, null, 2))
```
### Phase 5: Report to Coordinator
```javascript
// 更新 shared memory
sharedMemory.analyses = sharedMemory.analyses || []
sharedMemory.analyses.push({
id: `analysis-${analyzeNum}`,
perspective,
is_direction_fix: isDirectionFix,
insight_count: analysisResult.key_insights?.length || 0,
finding_count: analysisResult.key_findings?.length || 0,
timestamp: new Date().toISOString()
})
Write(`${sessionFolder}/shared-memory.json`, JSON.stringify(sharedMemory, null, 2))
const resultSummary = `${perspective} 视角: ${analysisResult.key_insights?.length || 0} 个洞察, ${analysisResult.discussion_points?.length || 0} 个讨论点`
mcp__ccw-tools__team_msg({
operation: "log",
team: teamName,
from: "analyst",
to: "coordinator",
type: "analysis_ready",
summary: `[analyst] ${resultSummary}`,
ref: outputPath
})
SendMessage({
type: "message",
recipient: "coordinator",
content: `## [analyst] Analysis Results
**Task**: ${task.subject}
**Perspective**: ${perspective}${isDirectionFix ? ` (Direction Fix: ${adjustedFocus})` : ''}
**CLI Tool**: ${cliTool}
### Summary
${resultSummary}
### Key Insights
${(analysisResult.key_insights || []).slice(0, 5).map(i => `- ${i}`).join('\n')}
### Discussion Points
${(analysisResult.discussion_points || []).slice(0, 3).map(p => `- ${p}`).join('\n')}
### Open Questions
${(analysisResult.open_questions || []).slice(0, 3).map(q => `- ${q}`).join('\n')}
### Output
${outputPath}`,
summary: `[analyst] ANALYZE complete: ${resultSummary}`
})
TaskUpdate({ taskId: task.id, status: 'completed' })
// Check for next task
const nextTasks = TaskList().filter(t =>
t.subject.startsWith('ANALYZE-') &&
t.owner === 'analyst' &&
t.status === 'pending' &&
t.blockedBy.length === 0
)
if (nextTasks.length > 0) {
// Continue with next task → back to Phase 1
}
```
## Error Handling
| Scenario | Resolution |
|----------|------------|
| No ANALYZE-* tasks available | Idle, wait for coordinator assignment |
| CLI tool unavailable | Fallback chain: gemini → codex → claude |
| No exploration results found | Analyze with topic keywords only, note limitation |
| CLI timeout | Use partial results, report incomplete |
| Invalid exploration JSON | Skip context, analyze from scratch |