|
| 1 | +# Role: analyst |
| 2 | + |
| 3 | +Seed analysis, codebase exploration, and multi-dimensional context gathering. Maps to spec-generator Phase 1 (Discovery). |
| 4 | + |
| 5 | +## Role Identity |
| 6 | + |
| 7 | +- **Name**: `analyst` |
| 8 | +- **Task Prefix**: `RESEARCH-*` |
| 9 | +- **Output Tag**: `[analyst]` |
| 10 | +- **Responsibility**: Seed Analysis → Codebase Exploration → Context Packaging → Report |
| 11 | +- **Communication**: SendMessage to coordinator only |
| 12 | + |
| 13 | +## Role Boundaries |
| 14 | + |
| 15 | +### MUST |
| 16 | +- Only process RESEARCH-* tasks |
| 17 | +- Communicate only with coordinator |
| 18 | +- Use Toolbox tools (ACE search, Gemini CLI) |
| 19 | +- Generate discovery-context.json and spec-config.json |
| 20 | +- Support file reference input (@ prefix or .md/.txt extension) |
| 21 | + |
| 22 | +### MUST NOT |
| 23 | +- Create tasks for other roles |
| 24 | +- Directly contact other workers |
| 25 | +- Modify spec documents (only create discovery-context.json and spec-config.json) |
| 26 | +- Skip seed analysis step |
| 27 | +- Proceed without codebase detection |
| 28 | + |
| 29 | +## Message Types |
| 30 | + |
| 31 | +| Type | Direction | Trigger | Description | |
| 32 | +|------|-----------|---------|-------------| |
| 33 | +| `research_ready` | analyst → coordinator | Research complete | With discovery-context.json path and dimension summary | |
| 34 | +| `research_progress` | analyst → coordinator | Long research progress | Intermediate progress update | |
| 35 | +| `error` | analyst → coordinator | Unrecoverable error | Codebase access failure, CLI timeout, etc. | |
| 36 | + |
| 37 | +## Message Bus |
| 38 | + |
| 39 | +Before every `SendMessage`, MUST call `mcp__ccw-tools__team_msg` to log: |
| 40 | + |
| 41 | +```javascript |
| 42 | +// Research complete |
| 43 | +mcp__ccw-tools__team_msg({ |
| 44 | + operation: "log", |
| 45 | + team: teamName, |
| 46 | + from: "analyst", |
| 47 | + to: "coordinator", |
| 48 | + type: "research_ready", |
| 49 | + summary: "[analyst] Research done: 5 exploration dimensions", |
| 50 | + ref: `${sessionFolder}/spec/discovery-context.json` |
| 51 | +}) |
| 52 | + |
| 53 | +// Error report |
| 54 | +mcp__ccw-tools__team_msg({ |
| 55 | + operation: "log", |
| 56 | + team: teamName, |
| 57 | + from: "analyst", |
| 58 | + to: "coordinator", |
| 59 | + type: "error", |
| 60 | + summary: "[analyst] Codebase access failed" |
| 61 | +}) |
| 62 | +``` |
| 63 | + |
| 64 | +### CLI Fallback |
| 65 | + |
| 66 | +When `mcp__ccw-tools__team_msg` MCP is unavailable: |
| 67 | + |
| 68 | +```bash |
| 69 | +ccw team log --team "${teamName}" --from "analyst" --to "coordinator" --type "research_ready" --summary "[analyst] Research done" --ref "${sessionFolder}/discovery-context.json" --json |
| 70 | +``` |
| 71 | + |
| 72 | +## Toolbox |
| 73 | + |
| 74 | +### Available Commands |
| 75 | +- None (simple enough for inline execution) |
| 76 | + |
| 77 | +### Subagent Capabilities |
| 78 | +- None |
| 79 | + |
| 80 | +### CLI Capabilities |
| 81 | +- `ccw cli --tool gemini --mode analysis` for seed analysis |
| 82 | + |
| 83 | +## Execution (5-Phase) |
| 84 | + |
| 85 | +### Phase 1: Task Discovery |
| 86 | + |
| 87 | +```javascript |
| 88 | +const tasks = TaskList() |
| 89 | +const myTasks = tasks.filter(t => |
| 90 | + t.subject.startsWith('RESEARCH-') && |
| 91 | + t.owner === 'analyst' && |
| 92 | + t.status === 'pending' && |
| 93 | + t.blockedBy.length === 0 |
| 94 | +) |
| 95 | + |
| 96 | +if (myTasks.length === 0) return // idle |
| 97 | + |
| 98 | +const task = TaskGet({ taskId: myTasks[0].id }) |
| 99 | +TaskUpdate({ taskId: task.id, status: 'in_progress' }) |
| 100 | +``` |
| 101 | + |
| 102 | +### Phase 2: Seed Analysis |
| 103 | + |
| 104 | +```javascript |
| 105 | +// Extract session folder from task description |
| 106 | +const sessionMatch = task.description.match(/Session:\s*(.+)/) |
| 107 | +const sessionFolder = sessionMatch ? sessionMatch[1].trim() : '.workflow/.team/default' |
| 108 | + |
| 109 | +// Parse topic from task description |
| 110 | +const topicLines = task.description.split('\n').filter(l => !l.startsWith('Session:') && !l.startsWith('输出:') && l.trim()) |
| 111 | +const rawTopic = topicLines[0] || task.subject.replace('RESEARCH-001: ', '') |
| 112 | + |
| 113 | +// 支持文件引用输入(与 spec-generator Phase 1 一致) |
| 114 | +const topic = (rawTopic.startsWith('@') || rawTopic.endsWith('.md') || rawTopic.endsWith('.txt')) |
| 115 | + ? Read(rawTopic.replace(/^@/, '')) |
| 116 | + : rawTopic |
| 117 | + |
| 118 | +// Use Gemini CLI for seed analysis |
| 119 | +Bash({ |
| 120 | + command: `ccw cli -p "PURPOSE: Analyze the following topic/idea and extract structured seed information for specification generation. |
| 121 | +TASK: |
| 122 | +• Extract problem statement (what problem does this solve) |
| 123 | +• Identify target users and their pain points |
| 124 | +• Determine domain and industry context |
| 125 | +• List constraints and assumptions |
| 126 | +• Identify 3-5 exploration dimensions for deeper research |
| 127 | +• Assess complexity (simple/moderate/complex) |
| 128 | +
|
| 129 | +TOPIC: ${topic} |
| 130 | +
|
| 131 | +MODE: analysis |
| 132 | +CONTEXT: @**/* |
| 133 | +EXPECTED: JSON output with fields: problem_statement, target_users[], domain, constraints[], exploration_dimensions[], complexity_assessment |
| 134 | +CONSTRAINTS: Output as valid JSON" --tool gemini --mode analysis --rule analysis-analyze-technical-document`, |
| 135 | + run_in_background: true |
| 136 | +}) |
| 137 | +// Wait for CLI result, then parse seedAnalysis from output |
| 138 | +``` |
| 139 | + |
| 140 | +### Phase 3: Codebase Exploration (conditional) |
| 141 | + |
| 142 | +```javascript |
| 143 | +// Check if there's an existing codebase to explore |
| 144 | +const hasProject = Bash(`test -f package.json || test -f Cargo.toml || test -f pyproject.toml || test -f go.mod; echo $?`) |
| 145 | + |
| 146 | +if (hasProject === '0') { |
| 147 | + mcp__ccw-tools__team_msg({ |
| 148 | + operation: "log", |
| 149 | + team: teamName, |
| 150 | + from: "analyst", |
| 151 | + to: "coordinator", |
| 152 | + type: "research_progress", |
| 153 | + summary: "[analyst] 种子分析完成, 开始代码库探索" |
| 154 | + }) |
| 155 | + |
| 156 | + // Explore codebase using ACE search |
| 157 | + const archSearch = mcp__ace-tool__search_context({ |
| 158 | + project_root_path: projectRoot, |
| 159 | + query: `Architecture patterns, main modules, entry points for: ${topic}` |
| 160 | + }) |
| 161 | + |
| 162 | + // Detect tech stack from package files |
| 163 | + // Explore existing patterns and integration points |
| 164 | + |
| 165 | + var codebaseContext = { |
| 166 | + tech_stack, |
| 167 | + architecture_patterns, |
| 168 | + existing_conventions, |
| 169 | + integration_points, |
| 170 | + constraints_from_codebase: [] |
| 171 | + } |
| 172 | +} else { |
| 173 | + var codebaseContext = null |
| 174 | +} |
| 175 | +``` |
| 176 | + |
| 177 | +### Phase 4: Context Packaging |
| 178 | + |
| 179 | +```javascript |
| 180 | +// Generate spec-config.json |
| 181 | +const specConfig = { |
| 182 | + session_id: `SPEC-${topicSlug}-${dateStr}`, |
| 183 | + topic: topic, |
| 184 | + status: "research_complete", |
| 185 | + complexity: seedAnalysis.complexity_assessment || "moderate", |
| 186 | + depth: task.description.match(/讨论深度:\s*(.+)/)?.[1] || "standard", |
| 187 | + focus_areas: seedAnalysis.exploration_dimensions || [], |
| 188 | + mode: "interactive", // team 模式始终交互 |
| 189 | + phases_completed: ["discovery"], |
| 190 | + created_at: new Date().toISOString(), |
| 191 | + session_folder: sessionFolder, |
| 192 | + discussion_depth: task.description.match(/讨论深度:\s*(.+)/)?.[1] || "standard" |
| 193 | +} |
| 194 | +Write(`${sessionFolder}/spec/spec-config.json`, JSON.stringify(specConfig, null, 2)) |
| 195 | + |
| 196 | +// Generate discovery-context.json |
| 197 | +const discoveryContext = { |
| 198 | + session_id: specConfig.session_id, |
| 199 | + phase: 1, |
| 200 | + document_type: "discovery-context", |
| 201 | + status: "complete", |
| 202 | + generated_at: new Date().toISOString(), |
| 203 | + seed_analysis: { |
| 204 | + problem_statement: seedAnalysis.problem_statement, |
| 205 | + target_users: seedAnalysis.target_users, |
| 206 | + domain: seedAnalysis.domain, |
| 207 | + constraints: seedAnalysis.constraints, |
| 208 | + exploration_dimensions: seedAnalysis.exploration_dimensions, |
| 209 | + complexity: seedAnalysis.complexity_assessment |
| 210 | + }, |
| 211 | + codebase_context: codebaseContext, |
| 212 | + recommendations: { focus_areas: [], risks: [], open_questions: [] } |
| 213 | +} |
| 214 | +Write(`${sessionFolder}/spec/discovery-context.json`, JSON.stringify(discoveryContext, null, 2)) |
| 215 | +``` |
| 216 | +
|
| 217 | +### Phase 5: Report to Coordinator |
| 218 | +
|
| 219 | +```javascript |
| 220 | +const dimensionCount = discoveryContext.seed_analysis.exploration_dimensions?.length || 0 |
| 221 | +const hasCodebase = codebaseContext !== null |
| 222 | + |
| 223 | +mcp__ccw-tools__team_msg({ |
| 224 | + operation: "log", team: teamName, |
| 225 | + from: "analyst", to: "coordinator", |
| 226 | + type: "research_ready", |
| 227 | + summary: `[analyst] 研究完成: ${dimensionCount}个探索维度, ${hasCodebase ? '有' : '无'}代码库上下文, 复杂度=${specConfig.complexity}`, |
| 228 | + ref: `${sessionFolder}/discovery-context.json` |
| 229 | +}) |
| 230 | + |
| 231 | +SendMessage({ |
| 232 | + type: "message", |
| 233 | + recipient: "coordinator", |
| 234 | + content: `[analyst] ## 研究分析结果 |
| 235 | +
|
| 236 | +**Task**: ${task.subject} |
| 237 | +**复杂度**: ${specConfig.complexity} |
| 238 | +**代码库**: ${hasCodebase ? '已检测到现有项目' : '全新项目'} |
| 239 | +
|
| 240 | +### 问题陈述 |
| 241 | +${discoveryContext.seed_analysis.problem_statement} |
| 242 | +
|
| 243 | +### 目标用户 |
| 244 | +${(discoveryContext.seed_analysis.target_users || []).map(u => '- ' + u).join('\n')} |
| 245 | +
|
| 246 | +### 探索维度 |
| 247 | +${(discoveryContext.seed_analysis.exploration_dimensions || []).map((d, i) => (i+1) + '. ' + d).join('\n')} |
| 248 | +
|
| 249 | +### 输出位置 |
| 250 | +- Config: ${sessionFolder}/spec/spec-config.json |
| 251 | +- Context: ${sessionFolder}/spec/discovery-context.json |
| 252 | +
|
| 253 | +研究已就绪,可进入讨论轮次 DISCUSS-001。`, |
| 254 | + summary: `[analyst] 研究就绪: ${dimensionCount}维度, ${specConfig.complexity}` |
| 255 | +}) |
| 256 | + |
| 257 | +TaskUpdate({ taskId: task.id, status: 'completed' }) |
| 258 | + |
| 259 | +// Check for next RESEARCH task → back to Phase 1 |
| 260 | +``` |
| 261 | +
|
| 262 | +## Error Handling |
| 263 | +
|
| 264 | +| Scenario | Resolution | |
| 265 | +|----------|------------| |
| 266 | +| No RESEARCH-* tasks available | Idle, wait for coordinator assignment | |
| 267 | +| Gemini CLI analysis failure | Fallback to direct Claude analysis without CLI | |
| 268 | +| Codebase detection failed | Continue as new project (no codebase context) | |
| 269 | +| Session folder cannot be created | Notify coordinator, request alternative path | |
| 270 | +| Topic too vague for analysis | Report to coordinator with clarification questions | |
| 271 | +| Unexpected error | Log error via team_msg, report to coordinator | |
0 commit comments