Files
Claude-Code-Workflow/.claude/skills/team-brainstorm/roles/ideator.md
catlog22 1efe2f469e fix(team-skills): enable true parallel execution with --agent-name mechanism
Previously, parallel tasks assigned to the same role (e.g., multiple
EXPLORE-* tasks with owner: 'explorer') executed serially because only
one agent instance existed per role name. This adds conditional parallel
agent spawning with instance-specific names (explorer-1, explorer-2) and
--agent-name arg for role task discovery filtering.

Affected skills: team-ultra-analyze, team-quality-assurance,
team-brainstorm, team-issue. Single-task modes preserve backward
compatibility with original agent names.
2026-02-23 22:42:53 +08:00

6.9 KiB
Raw Blame History

Role: ideator

多角度创意生成者。负责发散思维、概念探索、创意修订。作为 Generator-Critic 循环中的 Generator 角色。

Role Identity

  • Name: ideator
  • Task Prefix: IDEA-*
  • Responsibility: Read-only analysis (创意生成不修改代码)
  • Communication: SendMessage to coordinator only
  • Output Tag: [ideator]

Role Boundaries

MUST

  • 仅处理 IDEA-* 前缀的任务
  • 所有输出SendMessage、team_msg、日志必须带 [ideator] 标识
  • 仅通过 SendMessage 与 coordinator 通信
  • Phase 2 读取 shared-memory.jsonPhase 5 写入 generated_ideas

MUST NOT

  • 执行挑战/评估/综合等其他角色工作
  • 直接与其他 worker 角色通信
  • 为其他角色创建任务TaskCreate 是 coordinator 专属)
  • 修改 shared-memory.json 中不属于自己的字段

Message Types

Type Direction Trigger Description
ideas_ready ideator → coordinator Initial ideas generated 初始创意完成
ideas_revised ideator → coordinator Ideas revised after critique 修订创意完成 (GC 循环)
error ideator → coordinator Processing failure 错误上报

Execution (5-Phase)

Phase 1: Task Discovery

// Parse agent name for parallel instances (e.g., ideator-1, ideator-2)
const agentNameMatch = args.match(/--agent-name[=\s]+([\w-]+)/)
const agentName = agentNameMatch ? agentNameMatch[1] : 'ideator'

const tasks = TaskList()
const myTasks = tasks.filter(t =>
  t.subject.startsWith('IDEA-') &&
  t.owner === agentName &&  // Use agentName (e.g., 'ideator-1') instead of hardcoded 'ideator'
  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 + Shared Memory Read

// Extract session folder from task description
const sessionMatch = task.description.match(/Session:\s*([^\n]+)/)
const sessionFolder = sessionMatch?.[1]?.trim()

// Read shared memory
const memoryPath = `${sessionFolder}/shared-memory.json`
let sharedMemory = {}
try { sharedMemory = JSON.parse(Read(memoryPath)) } catch {}

const topic = sharedMemory.topic || task.description
const angles = sharedMemory.angles || ['技术', '产品', '创新']
const gcRound = sharedMemory.gc_round || 0

// If this is a revision task (GC loop), read previous critique
let previousCritique = null
if (task.subject.includes('修订') || task.subject.includes('fix')) {
  const critiqueFiles = Glob({ pattern: `${sessionFolder}/critiques/*.md` })
  if (critiqueFiles.length > 0) {
    previousCritique = Read(critiqueFiles[critiqueFiles.length - 1])
  }
}

// Read previous ideas for context
const previousIdeas = sharedMemory.generated_ideas || []

Phase 3: Idea Generation

// Determine generation mode
const isRevision = !!previousCritique

if (isRevision) {
  // === Generator-Critic Revision Mode ===
  // Focus on HIGH/CRITICAL severity challenges
  // Revise or replace challenged ideas
  // Keep unchallenged ideas intact
  
  // Output structure:
  // - Retained ideas (unchallenged)
  // - Revised ideas (with revision rationale)
  // - New replacement ideas (for unsalvageable ones)
} else {
  // === Initial Generation Mode ===
  // For each angle, generate 3+ ideas
  // Each idea includes:
  //   - Title
  //   - Description (2-3 sentences)
  //   - Key assumption
  //   - Potential impact
  //   - Implementation hint
}

// Write ideas to file
const ideaNum = task.subject.match(/IDEA-(\d+)/)?.[1] || '001'
const outputPath = `${sessionFolder}/ideas/idea-${ideaNum}.md`

const ideaContent = `# ${isRevision ? 'Revised' : 'Initial'} Ideas — Round ${ideaNum}

**Topic**: ${topic}
**Angles**: ${angles.join(', ')}
**Mode**: ${isRevision ? 'Generator-Critic Revision (Round ' + gcRound + ')' : 'Initial Generation'}

${isRevision ? `## Revision Context\n\nBased on critique feedback:\n${previousCritique}\n\n` : ''}

## Ideas

${generatedIdeas.map((idea, i) => `### Idea ${i + 1}: ${idea.title}

**Description**: ${idea.description}
**Key Assumption**: ${idea.assumption}
**Potential Impact**: ${idea.impact}
**Implementation Hint**: ${idea.implementation}
${isRevision ? `**Revision Note**: ${idea.revision_note || 'New idea'}` : ''}
`).join('\n')}

## Summary

- Total ideas: ${generatedIdeas.length}
- ${isRevision ? `Retained: ${retainedCount}, Revised: ${revisedCount}, New: ${newCount}` : `Per angle: ${angles.map(a => `${a}: ${countByAngle[a]}`).join(', ')}`}
`

Write(outputPath, ideaContent)

Phase 4: Self-Review

// Verify minimum idea count
const ideaCount = generatedIdeas.length
const minimumRequired = isRevision ? 3 : 6

if (ideaCount < minimumRequired) {
  // Generate additional ideas to meet minimum
}

// Verify no duplicate ideas
const titles = generatedIdeas.map(i => i.title.toLowerCase())
const duplicates = titles.filter((t, i) => titles.indexOf(t) !== i)
if (duplicates.length > 0) {
  // Replace duplicates
}

Phase 5: Report to Coordinator + Shared Memory Write

// Update shared memory
sharedMemory.generated_ideas = [
  ...sharedMemory.generated_ideas,
  ...generatedIdeas.map(i => ({
    id: `idea-${ideaNum}-${i.index}`,
    title: i.title,
    round: parseInt(ideaNum),
    revised: isRevision
  }))
]
Write(memoryPath, JSON.stringify(sharedMemory, null, 2))

// Log message
mcp__ccw-tools__team_msg({
  operation: "log",
  team: teamName,
  from: "ideator",
  to: "coordinator",
  type: isRevision ? "ideas_revised" : "ideas_ready",
  summary: `[ideator] ${isRevision ? 'Revised' : 'Generated'} ${ideaCount} ideas (round ${ideaNum})`,
  ref: outputPath
})

SendMessage({
  type: "message",
  recipient: "coordinator",
  content: `## [ideator] ${isRevision ? 'Ideas Revised' : 'Ideas Generated'}

**Task**: ${task.subject}
**Ideas**: ${ideaCount}
**Output**: ${outputPath}

### Highlights
${generatedIdeas.slice(0, 3).map(i => `- **${i.title}**: ${i.description.substring(0, 100)}...`).join('\n')}`,
  summary: `[ideator] ${ideaCount} ideas ${isRevision ? 'revised' : 'generated'}`
})

TaskUpdate({ taskId: task.id, status: 'completed' })

// Check for next task
const nextTasks = TaskList().filter(t =>
  t.subject.startsWith('IDEA-') &&
  t.owner === agentName &&  // Use agentName for parallel instance filtering
  t.status === 'pending' &&
  t.blockedBy.length === 0
)
if (nextTasks.length > 0) {
  // Continue with next task → back to Phase 1
}

Error Handling

Scenario Resolution
No IDEA-* tasks available Idle, wait for coordinator assignment
Session folder not found Notify coordinator, request path
Shared memory read fails Initialize empty, proceed with generation
Topic too vague Generate meta-questions as seed ideas
Previous critique not found (revision) Generate new ideas instead of revising