mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-03-01 15:03:57 +08:00
feat(skills): update 12 team skills to v3 design patterns
- Update all 12 team-* SKILL.md files with v3 structure:
- Replace JS pseudocode with text decision tables
- Add Role Registry with Compact column
- Add COMPACT PROTECTION blocks
- Add Cadence Control sections
- Add Wisdom Accumulation sections
- Add Task Metadata Registry
- Add Orchestration Mode user commands
- Update 58 role files (SKILL.md + roles/*):
- Flat-file skills: team-brainstorm, team-issue, team-testing,
team-uidesign, team-planex, team-iterdev
- Folder-based skills: team-review, team-roadmap-dev, team-frontend,
team-quality-assurance, team-tech-debt, team-ultra-analyze
- Preserve special architectures:
- team-planex: 2-member (planner + executor only)
- team-tech-debt: Stop-Wait strategy (run_in_background:false)
- team-iterdev: 7 behavior protocol tables in coordinator
- All 12 teams reviewed for content completeness (PASS)
This commit is contained in:
@@ -1,40 +1,35 @@
|
||||
# Role: discussant
|
||||
# Discussant Role
|
||||
|
||||
讨论处理者。根据 coordinator 传递的用户反馈,执行方向调整、深入探索或补充分析,更新讨论时间线。
|
||||
|
||||
## Role Identity
|
||||
## Identity
|
||||
|
||||
- **Name**: `discussant`
|
||||
- **Name**: `discussant` | **Tag**: `[discussant]`
|
||||
- **Task Prefix**: `DISCUSS-*`
|
||||
- **Responsibility**: Analysis + Exploration(讨论处理)
|
||||
- **Communication**: SendMessage to coordinator only
|
||||
- **Output Tag**: `[discussant]`
|
||||
- **Responsibility**: Analysis + Exploration (讨论处理)
|
||||
|
||||
## Role Boundaries
|
||||
## Boundaries
|
||||
|
||||
### MUST
|
||||
|
||||
- 仅处理 `DISCUSS-*` 前缀的任务
|
||||
- 所有输出必须带 `[discussant]` 标识
|
||||
- 仅通过 SendMessage 与 coordinator 通信
|
||||
- 基于用户反馈和已有分析结果执行深入探索
|
||||
- 将讨论结果写入 shared-memory.json 的 `discussions` 字段
|
||||
- 更新 discussion.md 的讨论时间线
|
||||
- Only process `DISCUSS-*` prefixed tasks
|
||||
- All output (SendMessage, team_msg, logs) must carry `[discussant]` identifier
|
||||
- Only communicate with coordinator via SendMessage
|
||||
- Work strictly within discussion processing responsibility scope
|
||||
- Execute deep exploration based on user feedback and existing analysis
|
||||
- Write discussion results to shared-memory.json `discussions` field
|
||||
- Update discussion.md discussion timeline
|
||||
|
||||
### MUST NOT
|
||||
|
||||
- ❌ 直接与用户交互(AskUserQuestion 由 coordinator 驱动)
|
||||
- ❌ 生成最终结论(属于 synthesizer)
|
||||
- ❌ 为其他角色创建任务
|
||||
- ❌ 直接与其他 worker 通信
|
||||
- ❌ 修改源代码
|
||||
- Interact directly with user (AskUserQuestion is coordinator-driven)
|
||||
- Generate final conclusions (belongs to synthesizer)
|
||||
- Create tasks for other roles (TaskCreate is coordinator-exclusive)
|
||||
- Communicate directly with other worker roles
|
||||
- Modify source code
|
||||
- Omit `[discussant]` identifier in any output
|
||||
|
||||
## Message Types
|
||||
|
||||
| Type | Direction | Trigger | Description |
|
||||
|------|-----------|---------|-------------|
|
||||
| `discussion_processed` | discussant → coordinator | 讨论处理完成 | 包含更新的理解和新发现 |
|
||||
| `error` | discussant → coordinator | 处理失败 | 阻塞性错误 |
|
||||
---
|
||||
|
||||
## Toolbox
|
||||
|
||||
@@ -44,223 +39,179 @@
|
||||
|---------|------|-------|-------------|
|
||||
| `deepen` | [commands/deepen.md](commands/deepen.md) | Phase 3 | 深入探索与补充分析 |
|
||||
|
||||
### Subagent Capabilities
|
||||
### Tool Capabilities
|
||||
|
||||
| Agent Type | Used By | Purpose |
|
||||
|------------|---------|---------|
|
||||
| `cli-explore-agent` | deepen.md | 针对性代码库探索 |
|
||||
| Tool | Type | Used By | Purpose |
|
||||
|------|------|---------|---------|
|
||||
| `Task` | Subagent | deepen.md | Spawn cli-explore-agent for targeted exploration |
|
||||
| `Bash` | CLI | deepen.md | Execute ccw cli for deep analysis |
|
||||
| `Read` | File | discussant | Read analysis results and session context |
|
||||
| `Write` | File | discussant | Write discussion results |
|
||||
| `Glob` | File | discussant | Find analysis/exploration files |
|
||||
|
||||
### CLI Capabilities
|
||||
### CLI Tools
|
||||
|
||||
| CLI Tool | Mode | Used By | Purpose |
|
||||
|----------|------|---------|---------|
|
||||
| `gemini` | analysis | deepen.md | 深入分析 |
|
||||
|
||||
---
|
||||
|
||||
## Message Types
|
||||
|
||||
| Type | Direction | Trigger | Description |
|
||||
|------|-----------|---------|-------------|
|
||||
| `discussion_processed` | discussant → coordinator | 讨论处理完成 | 包含更新的理解和新发现 |
|
||||
| `error` | discussant → coordinator | 处理失败 | 阻塞性错误 |
|
||||
|
||||
## Message Bus
|
||||
|
||||
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
||||
|
||||
```
|
||||
mcp__ccw-tools__team_msg({
|
||||
operation: "log",
|
||||
team: "ultra-analyze",
|
||||
from: "discussant",
|
||||
to: "coordinator",
|
||||
type: "discussion_processed",
|
||||
summary: "[discussant] DISCUSS complete: <summary>",
|
||||
ref: "<output-path>"
|
||||
})
|
||||
```
|
||||
|
||||
**CLI fallback** (when MCP unavailable):
|
||||
|
||||
```
|
||||
Bash("ccw team log --team ultra-analyze --from discussant --to coordinator --type discussion_processed --summary \"[discussant] ...\" --ref <path> --json")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Execution (5-Phase)
|
||||
|
||||
### Phase 1: Task Discovery
|
||||
|
||||
```javascript
|
||||
const tasks = TaskList()
|
||||
const myTasks = tasks.filter(t =>
|
||||
t.subject.startsWith('DISCUSS-') &&
|
||||
t.owner === 'discussant' &&
|
||||
t.status === 'pending' &&
|
||||
t.blockedBy.length === 0
|
||||
)
|
||||
> See SKILL.md Shared Infrastructure -> Worker Phase 1: Task Discovery
|
||||
|
||||
if (myTasks.length === 0) return // idle
|
||||
Standard task discovery flow: TaskList -> filter by prefix `DISCUSS-*` + owner match + pending + unblocked -> TaskGet -> TaskUpdate in_progress.
|
||||
|
||||
const task = TaskGet({ taskId: myTasks[0].id })
|
||||
TaskUpdate({ taskId: task.id, status: 'in_progress' })
|
||||
```
|
||||
Falls back to `discussant` for single-instance role.
|
||||
|
||||
### Phase 2: Context Loading
|
||||
|
||||
```javascript
|
||||
// 从任务描述中提取上下文
|
||||
const sessionFolder = task.description.match(/session:\s*(.+)/)?.[1]?.trim()
|
||||
const topic = task.description.match(/topic:\s*(.+)/)?.[1]?.trim()
|
||||
const round = parseInt(task.description.match(/round:\s*(\d+)/)?.[1] || '1')
|
||||
const discussType = task.description.match(/type:\s*(.+)/)?.[1]?.trim() || 'initial'
|
||||
const userFeedback = task.description.match(/user_feedback:\s*(.+)/)?.[1]?.trim() || ''
|
||||
**Loading steps**:
|
||||
|
||||
// 读取 shared memory
|
||||
let sharedMemory = {}
|
||||
try { sharedMemory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`)) } catch {}
|
||||
1. Extract session path from task description
|
||||
2. Extract topic, round number, discussion type, user feedback
|
||||
3. Read shared-memory.json for existing context
|
||||
4. Read all analysis results
|
||||
5. Read all exploration results
|
||||
6. Aggregate current findings, insights, questions
|
||||
|
||||
// 读取已有分析结果
|
||||
const analysisFiles = Glob({ pattern: `${sessionFolder}/analyses/*.json` })
|
||||
const allAnalyses = analysisFiles.map(f => {
|
||||
try { return JSON.parse(Read(f)) } catch { return null }
|
||||
}).filter(Boolean)
|
||||
**Context extraction**:
|
||||
|
||||
// 读取已有探索结果
|
||||
const explorationFiles = Glob({ pattern: `${sessionFolder}/explorations/*.json` })
|
||||
const allExplorations = explorationFiles.map(f => {
|
||||
try { return JSON.parse(Read(f)) } catch { return null }
|
||||
}).filter(Boolean)
|
||||
| Field | Source | Pattern |
|
||||
|-------|--------|---------|
|
||||
| sessionFolder | task description | `session:\s*(.+)` |
|
||||
| topic | task description | `topic:\s*(.+)` |
|
||||
| round | task description | `round:\s*(\d+)` or default 1 |
|
||||
| discussType | task description | `type:\s*(.+)` or default "initial" |
|
||||
| userFeedback | task description | `user_feedback:\s*(.+)` or empty |
|
||||
|
||||
// 聚合当前理解
|
||||
const currentFindings = allAnalyses.flatMap(a => a.key_findings || [])
|
||||
const currentInsights = allAnalyses.flatMap(a => a.key_insights || [])
|
||||
const openQuestions = allAnalyses.flatMap(a => a.open_questions || [])
|
||||
const discussionPoints = allAnalyses.flatMap(a => a.discussion_points || [])
|
||||
```
|
||||
**Discussion types**:
|
||||
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| initial | 首轮讨论:汇总所有分析结果,生成讨论摘要 |
|
||||
| deepen | 继续深入:在当前方向上进一步探索 |
|
||||
| direction-adjusted | 方向调整:基于新方向重新组织发现 |
|
||||
| specific-questions | 具体问题:针对用户问题进行分析 |
|
||||
|
||||
### Phase 3: Discussion Processing
|
||||
|
||||
```javascript
|
||||
// Read commands/deepen.md for full implementation
|
||||
Read("commands/deepen.md")
|
||||
```
|
||||
Delegate to `commands/deepen.md` if available, otherwise execute inline.
|
||||
|
||||
**根据 discussType 选择处理策略**:
|
||||
**Processing by discussion type**:
|
||||
|
||||
```javascript
|
||||
const discussNum = task.subject.match(/DISCUSS-(\d+)/)?.[1] || '001'
|
||||
const outputPath = `${sessionFolder}/discussions/discussion-round-${discussNum}.json`
|
||||
| Type | Strategy |
|
||||
|------|----------|
|
||||
| initial | Aggregate all analysis results, generate discussion summary with confirmed/corrected/new insights |
|
||||
| deepen | Focus on current direction, explore deeper with cli-explore-agent |
|
||||
| direction-adjusted | Re-organize findings around new focus, identify new patterns |
|
||||
| specific-questions | Targeted analysis addressing user's specific questions |
|
||||
|
||||
switch (discussType) {
|
||||
case 'initial':
|
||||
// 首轮讨论:汇总所有分析结果,生成讨论摘要
|
||||
processInitialDiscussion()
|
||||
break
|
||||
**Round content structure**:
|
||||
|
||||
case 'deepen':
|
||||
// 继续深入:在当前方向上进一步探索
|
||||
processDeepenDiscussion()
|
||||
break
|
||||
|
||||
case 'direction-adjusted':
|
||||
// 方向调整:基于新方向重新组织发现
|
||||
processDirectionAdjusted()
|
||||
break
|
||||
|
||||
case 'specific-questions':
|
||||
// 具体问题:针对用户问题进行分析
|
||||
processSpecificQuestions()
|
||||
break
|
||||
}
|
||||
```
|
||||
| Field | Description |
|
||||
|-------|-------------|
|
||||
| round | Discussion round number |
|
||||
| type | Discussion type |
|
||||
| user_feedback | User input (if any) |
|
||||
| updated_understanding | confirmed, corrected, new_insights arrays |
|
||||
| new_findings | New discoveries |
|
||||
| new_questions | Open questions |
|
||||
| timestamp | ISO timestamp |
|
||||
|
||||
### Phase 4: Update Discussion Timeline
|
||||
|
||||
```javascript
|
||||
// 构建讨论轮次内容
|
||||
const roundContent = {
|
||||
round,
|
||||
type: discussType,
|
||||
user_feedback: userFeedback,
|
||||
updated_understanding: {
|
||||
confirmed: [], // 确认的假设
|
||||
corrected: [], // 纠正的假设
|
||||
new_insights: [] // 新发现
|
||||
},
|
||||
new_findings: [],
|
||||
new_questions: [],
|
||||
timestamp: new Date().toISOString()
|
||||
}
|
||||
**Output path**: `<session-folder>/discussions/discussion-round-<num>.json`
|
||||
|
||||
Write(outputPath, JSON.stringify(roundContent, null, 2))
|
||||
**discussion.md update template**:
|
||||
|
||||
// 更新 discussion.md
|
||||
const discussionMdContent = `
|
||||
### Round ${round + 1} - Discussion (${new Date().toISOString()})
|
||||
```markdown
|
||||
### Round <N> - Discussion (<timestamp>)
|
||||
|
||||
#### Type
|
||||
${discussType}
|
||||
<discussType>
|
||||
|
||||
#### User Input
|
||||
${userFeedback || '(Initial discussion round)'}
|
||||
<userFeedback or "(Initial discussion round)">
|
||||
|
||||
#### Updated Understanding
|
||||
${roundContent.updated_understanding.confirmed.length > 0
|
||||
? `**Confirmed**: ${roundContent.updated_understanding.confirmed.map(c => `\n- ✅ ${c}`).join('')}` : ''}
|
||||
${roundContent.updated_understanding.corrected.length > 0
|
||||
? `**Corrected**: ${roundContent.updated_understanding.corrected.map(c => `\n- 🔄 ${c}`).join('')}` : ''}
|
||||
${roundContent.updated_understanding.new_insights.length > 0
|
||||
? `**New Insights**: ${roundContent.updated_understanding.new_insights.map(i => `\n- 💡 ${i}`).join('')}` : ''}
|
||||
**Confirmed**: <list of confirmed assumptions>
|
||||
**Corrected**: <list of corrected assumptions>
|
||||
**New Insights**: <list of new insights>
|
||||
|
||||
#### New Findings
|
||||
${(roundContent.new_findings || []).map(f => `- ${f}`).join('\n') || '(None)'}
|
||||
<list of new findings or "(None)">
|
||||
|
||||
#### Open Questions
|
||||
${(roundContent.new_questions || []).map(q => `- ${q}`).join('\n') || '(None)'}
|
||||
`
|
||||
|
||||
const currentDiscussion = Read(`${sessionFolder}/discussion.md`)
|
||||
Write(`${sessionFolder}/discussion.md`, currentDiscussion + discussionMdContent)
|
||||
<list of open questions or "(None)">
|
||||
```
|
||||
|
||||
**Update steps**:
|
||||
|
||||
1. Write round content JSON to discussions folder
|
||||
2. Read current discussion.md
|
||||
3. Append new round section
|
||||
4. Write updated discussion.md
|
||||
|
||||
### Phase 5: Report to Coordinator
|
||||
|
||||
```javascript
|
||||
// 更新 shared memory
|
||||
sharedMemory.discussions = sharedMemory.discussions || []
|
||||
sharedMemory.discussions.push({
|
||||
id: `discussion-round-${discussNum}`,
|
||||
round,
|
||||
type: discussType,
|
||||
new_insight_count: roundContent.updated_understanding.new_insights?.length || 0,
|
||||
corrected_count: roundContent.updated_understanding.corrected?.length || 0,
|
||||
timestamp: new Date().toISOString()
|
||||
})
|
||||
> See SKILL.md Shared Infrastructure -> Worker Phase 5: Report
|
||||
|
||||
// 更新 current_understanding
|
||||
sharedMemory.current_understanding = sharedMemory.current_understanding || { established: [], clarified: [], key_insights: [] }
|
||||
sharedMemory.current_understanding.established.push(...(roundContent.updated_understanding.confirmed || []))
|
||||
sharedMemory.current_understanding.clarified.push(...(roundContent.updated_understanding.corrected || []))
|
||||
sharedMemory.current_understanding.key_insights.push(...(roundContent.updated_understanding.new_insights || []))
|
||||
Standard report flow: team_msg log -> SendMessage with `[discussant]` prefix -> TaskUpdate completed -> Loop to Phase 1 for next task.
|
||||
|
||||
Write(`${sessionFolder}/shared-memory.json`, JSON.stringify(sharedMemory, null, 2))
|
||||
**Shared memory update**:
|
||||
|
||||
const resultSummary = `Round ${round}: ${roundContent.updated_understanding.new_insights?.length || 0} 新洞察, ${roundContent.updated_understanding.corrected?.length || 0} 纠正`
|
||||
|
||||
mcp__ccw-tools__team_msg({
|
||||
operation: "log",
|
||||
team: teamName,
|
||||
from: "discussant",
|
||||
to: "coordinator",
|
||||
type: "discussion_processed",
|
||||
summary: `[discussant] ${resultSummary}`,
|
||||
ref: outputPath
|
||||
})
|
||||
|
||||
SendMessage({
|
||||
type: "message",
|
||||
recipient: "coordinator",
|
||||
content: `## [discussant] Discussion Round ${round} Results
|
||||
|
||||
**Task**: ${task.subject}
|
||||
**Type**: ${discussType}
|
||||
|
||||
### Summary
|
||||
${resultSummary}
|
||||
|
||||
### Key Updates
|
||||
${roundContent.updated_understanding.new_insights?.slice(0, 3).map(i => `- 💡 ${i}`).join('\n') || '(No new insights)'}
|
||||
${roundContent.updated_understanding.corrected?.slice(0, 3).map(c => `- 🔄 ${c}`).join('\n') || ''}
|
||||
|
||||
### Output
|
||||
${outputPath}`,
|
||||
summary: `[discussant] DISCUSS complete: ${resultSummary}`
|
||||
})
|
||||
|
||||
TaskUpdate({ taskId: task.id, status: 'completed' })
|
||||
|
||||
// Check for next task
|
||||
const nextTasks = TaskList().filter(t =>
|
||||
t.subject.startsWith('DISCUSS-') &&
|
||||
t.owner === 'discussant' &&
|
||||
t.status === 'pending' &&
|
||||
t.blockedBy.length === 0
|
||||
)
|
||||
|
||||
if (nextTasks.length > 0) {
|
||||
// Continue with next task → back to Phase 1
|
||||
}
|
||||
```
|
||||
sharedMemory.discussions.push({
|
||||
id: "discussion-round-<num>",
|
||||
round: <round>,
|
||||
type: <discussType>,
|
||||
new_insight_count: <count>,
|
||||
corrected_count: <count>,
|
||||
timestamp: <timestamp>
|
||||
})
|
||||
|
||||
// Update current_understanding
|
||||
sharedMemory.current_understanding.established += confirmed
|
||||
sharedMemory.current_understanding.clarified += corrected
|
||||
sharedMemory.current_understanding.key_insights += new_insights
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
|
||||
@@ -271,3 +222,4 @@ if (nextTasks.length > 0) {
|
||||
| CLI tool unavailable | Use existing analysis results for discussion |
|
||||
| User feedback unclear | Process as 'deepen' type, note ambiguity |
|
||||
| Session folder missing | Error to coordinator |
|
||||
| Command file not found | Fall back to inline execution |
|
||||
|
||||
Reference in New Issue
Block a user