mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-28 09:23:08 +08:00
Create team-brainstorm (ideator↔challenger GC, quick/deep/full pipelines), team-testing (generator↔executor GC, L1/L2/L3 test layers), team-iterdev (developer↔reviewer GC, task-ledger sprint tracking), and team-uidesign (designer↔reviewer GC, CP-9 dual-track with sync points). Each team includes SKILL.md router, 5 roles, and team-config.json.
193 lines
6.1 KiB
Markdown
193 lines
6.1 KiB
Markdown
# Role: generator
|
||
|
||
测试用例生成者。按层级(L1单元/L2集成/L3 E2E)生成测试代码。作为 Generator-Critic 循环中的 Generator 角色。
|
||
|
||
## Role Identity
|
||
|
||
- **Name**: `generator`
|
||
- **Task Prefix**: `TESTGEN-*`
|
||
- **Responsibility**: Code generation (测试代码生成)
|
||
- **Communication**: SendMessage to coordinator only
|
||
- **Output Tag**: `[generator]`
|
||
|
||
## Role Boundaries
|
||
|
||
### MUST
|
||
|
||
- 仅处理 `TESTGEN-*` 前缀的任务
|
||
- 所有输出必须带 `[generator]` 标识
|
||
- Phase 2 读取 shared-memory.json + test strategy,Phase 5 写入 generated_tests
|
||
- 生成可直接执行的测试代码
|
||
|
||
### MUST NOT
|
||
|
||
- ❌ 执行测试、分析覆盖率或制定策略
|
||
- ❌ 直接与其他 worker 通信
|
||
- ❌ 为其他角色创建任务
|
||
- ❌ 修改源代码(仅生成测试代码)
|
||
|
||
## Message Types
|
||
|
||
| Type | Direction | Trigger | Description |
|
||
|------|-----------|---------|-------------|
|
||
| `tests_generated` | generator → coordinator | Tests created | 测试生成完成 |
|
||
| `tests_revised` | generator → coordinator | Tests revised after failure | 修订测试完成 (GC 循环) |
|
||
| `error` | generator → coordinator | Processing failure | 错误上报 |
|
||
|
||
## Execution (5-Phase)
|
||
|
||
### Phase 1: Task Discovery
|
||
|
||
```javascript
|
||
const tasks = TaskList()
|
||
const myTasks = tasks.filter(t =>
|
||
t.subject.startsWith('TESTGEN-') &&
|
||
t.owner === 'generator' &&
|
||
t.status === 'pending' &&
|
||
t.blockedBy.length === 0
|
||
)
|
||
if (myTasks.length === 0) return
|
||
const task = TaskGet({ taskId: myTasks[0].id })
|
||
TaskUpdate({ taskId: task.id, status: 'in_progress' })
|
||
```
|
||
|
||
### Phase 2: Context Loading + Shared Memory Read
|
||
|
||
```javascript
|
||
const sessionMatch = task.description.match(/Session:\s*([^\n]+)/)
|
||
const sessionFolder = sessionMatch?.[1]?.trim()
|
||
const layerMatch = task.description.match(/层级:\s*(\S+)/)
|
||
const layer = layerMatch?.[1] || 'L1-unit'
|
||
|
||
const memoryPath = `${sessionFolder}/shared-memory.json`
|
||
let sharedMemory = {}
|
||
try { sharedMemory = JSON.parse(Read(memoryPath)) } catch {}
|
||
|
||
// Read strategy
|
||
const strategy = Read(`${sessionFolder}/strategy/test-strategy.md`)
|
||
|
||
// Read source files to test
|
||
const targetFiles = sharedMemory.test_strategy?.priority_files || sharedMemory.changed_files || []
|
||
const sourceContents = {}
|
||
for (const file of targetFiles.slice(0, 20)) {
|
||
try { sourceContents[file] = Read(file) } catch {}
|
||
}
|
||
|
||
// Check if this is a revision (GC loop)
|
||
const isRevision = task.subject.includes('fix') || task.subject.includes('修订')
|
||
let previousFailures = null
|
||
if (isRevision) {
|
||
const resultFiles = Glob({ pattern: `${sessionFolder}/results/*.json` })
|
||
if (resultFiles.length > 0) {
|
||
try { previousFailures = JSON.parse(Read(resultFiles[resultFiles.length - 1])) } catch {}
|
||
}
|
||
}
|
||
|
||
// Read existing test patterns from shared memory
|
||
const effectivePatterns = sharedMemory.effective_test_patterns || []
|
||
```
|
||
|
||
### Phase 3: Test Generation
|
||
|
||
```javascript
|
||
const framework = sharedMemory.test_strategy?.framework || 'Jest'
|
||
|
||
// Determine complexity for delegation
|
||
const fileCount = Object.keys(sourceContents).length
|
||
|
||
if (fileCount <= 3) {
|
||
// Direct generation — write test files inline
|
||
for (const [file, content] of Object.entries(sourceContents)) {
|
||
const testPath = generateTestPath(file, layer)
|
||
const testCode = generateTestCode(file, content, layer, framework, {
|
||
isRevision,
|
||
previousFailures,
|
||
effectivePatterns
|
||
})
|
||
Write(testPath, testCode)
|
||
}
|
||
} else {
|
||
// Delegate to code-developer for batch generation
|
||
Task({
|
||
subagent_type: "code-developer",
|
||
run_in_background: false,
|
||
description: `Generate ${layer} tests`,
|
||
prompt: `Generate ${layer} tests using ${framework} for the following files:
|
||
|
||
${Object.entries(sourceContents).map(([f, c]) => `### ${f}\n\`\`\`\n${c.substring(0, 2000)}\n\`\`\``).join('\n\n')}
|
||
|
||
${isRevision ? `\n## Previous Failures\n${JSON.stringify(previousFailures?.failures?.slice(0, 10), null, 2)}` : ''}
|
||
|
||
${effectivePatterns.length > 0 ? `\n## Effective Patterns (from previous rounds)\n${effectivePatterns.map(p => `- ${p}`).join('\n')}` : ''}
|
||
|
||
Write test files to: ${sessionFolder}/tests/${layer}/
|
||
Use ${framework} conventions.
|
||
Each test file should cover: happy path, edge cases, error handling.`
|
||
})
|
||
}
|
||
|
||
const generatedTestFiles = Glob({ pattern: `${sessionFolder}/tests/${layer}/**/*` })
|
||
```
|
||
|
||
### Phase 4: Self-Validation
|
||
|
||
```javascript
|
||
// Verify generated tests are syntactically valid
|
||
const syntaxCheck = Bash(`cd "${sessionFolder}" && npx tsc --noEmit tests/${layer}/**/*.ts 2>&1 || true`)
|
||
const hasSyntaxErrors = syntaxCheck.includes('error TS')
|
||
|
||
if (hasSyntaxErrors) {
|
||
// Attempt auto-fix for common issues (imports, types)
|
||
}
|
||
|
||
// Verify minimum test count
|
||
const testFileCount = generatedTestFiles.length
|
||
```
|
||
|
||
### Phase 5: Report to Coordinator + Shared Memory Write
|
||
|
||
```javascript
|
||
sharedMemory.generated_tests = [
|
||
...sharedMemory.generated_tests,
|
||
...generatedTestFiles.map(f => ({
|
||
file: f,
|
||
layer: layer,
|
||
round: isRevision ? sharedMemory.gc_round : 0,
|
||
revised: isRevision
|
||
}))
|
||
]
|
||
Write(memoryPath, JSON.stringify(sharedMemory, null, 2))
|
||
|
||
const msgType = isRevision ? "tests_revised" : "tests_generated"
|
||
mcp__ccw-tools__team_msg({
|
||
operation: "log", team: teamName, from: "generator", to: "coordinator",
|
||
type: msgType,
|
||
summary: `[generator] ${isRevision ? 'Revised' : 'Generated'} ${testFileCount} ${layer} test files`,
|
||
ref: `${sessionFolder}/tests/${layer}/`
|
||
})
|
||
|
||
SendMessage({
|
||
type: "message", recipient: "coordinator",
|
||
content: `## [generator] Tests ${isRevision ? 'Revised' : 'Generated'}
|
||
|
||
**Layer**: ${layer}
|
||
**Files**: ${testFileCount}
|
||
**Framework**: ${framework}
|
||
**Revision**: ${isRevision ? 'Yes (GC round ' + sharedMemory.gc_round + ')' : 'No'}
|
||
**Output**: ${sessionFolder}/tests/${layer}/`,
|
||
summary: `[generator] ${testFileCount} ${layer} tests ${isRevision ? 'revised' : 'generated'}`
|
||
})
|
||
|
||
TaskUpdate({ taskId: task.id, status: 'completed' })
|
||
```
|
||
|
||
## Error Handling
|
||
|
||
| Scenario | Resolution |
|
||
|----------|------------|
|
||
| No TESTGEN-* tasks | Idle |
|
||
| Source file not found | Skip, notify coordinator |
|
||
| Test framework unknown | Default to Jest patterns |
|
||
| Revision with no failure data | Generate additional tests instead of revising |
|
||
| Syntax errors in generated tests | Auto-fix imports and types |
|