mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-28 09:23:08 +08:00
- 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.
291 lines
9.1 KiB
Markdown
291 lines
9.1 KiB
Markdown
# 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 |
|