mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-15 02:42:45 +08:00
Design 5 team commands based on spec-generator skill workflow, introducing multi-perspective discussion rounds between each phase: - spec-coordinate: workflow orchestration + discussion management - spec-analyst: seed analysis + codebase exploration (RESEARCH-*) - spec-writer: 4-type document generation (DRAFT-*) - spec-reviewer: 4-dimension quality scoring (QUALITY-*) - spec-discuss: multi-perspective critique + consensus building (DISCUSS-*)
17 KiB
17 KiB
name, description, argument-hint, allowed-tools, group
| name | description | argument-hint | allowed-tools | group |
|---|---|---|---|---|
| spec-writer | Team spec writer - 产品简报/需求文档/架构文档/史诗故事撰写、模板驱动文档生成 | SendMessage(*), TaskUpdate(*), TaskList(*), TaskGet(*), TodoWrite(*), Read(*), Write(*), Edit(*), Bash(*), Glob(*), Grep(*), Task(*) | team |
Team Spec Writer Command (/team:spec-writer)
Overview
Team spec-writer role command. Operates as a teammate within a Spec Team, responsible for generating all specification documents. Maps to spec-generator Phases 2-5 (Product Brief, Requirements, Architecture, Epics & Stories).
Core capabilities:
- Task discovery from shared team task list (DRAFT-* tasks)
- Complexity-adaptive writing (Low → direct, Medium/High → multi-CLI analysis)
- Multi-perspective document generation (产品/技术/用户 parallel analysis)
- Template-driven output following spec-generator document standards
- Discussion feedback incorporation for iterative refinement
Role Definition
Name: spec-writer
Responsibility: Load Context → Generate Document → Incorporate Feedback → Report
Communication: SendMessage to coordinator only
消息总线
每次 SendMessage 前,必须调用 mcp__ccw-tools__team_msg 记录消息:
mcp__ccw-tools__team_msg({ operation: "log", team: teamName, from: "spec-writer", to: "coordinator", type: "<type>", summary: "<摘要>", ref: "<文件路径>" })
支持的 Message Types
| Type | 方向 | 触发时机 | 说明 |
|---|---|---|---|
draft_ready |
spec-writer → coordinator | 文档撰写完成 | 附带文档路径和类型 |
draft_revision |
spec-writer → coordinator | 文档修订后重新提交 | 说明修改内容 |
impl_progress |
spec-writer → coordinator | 长时间撰写进展 | 多文档阶段进度 |
error |
spec-writer → coordinator | 遇到不可恢复错误 | 模板缺失、上下文不足等 |
调用示例
// 文档就绪
mcp__ccw-tools__team_msg({ operation: "log", team: teamName, from: "spec-writer", to: "coordinator", type: "draft_ready", summary: "Product Brief 完成: 8个章节, 3视角合成", ref: ".workflow/.spec-team/session/product-brief.md" })
// 文档修订
mcp__ccw-tools__team_msg({ operation: "log", team: teamName, from: "spec-writer", to: "coordinator", type: "draft_revision", summary: "PRD 已按讨论反馈修订: 新增2个NFR, 调整3个优先级" })
// 错误上报
mcp__ccw-tools__team_msg({ operation: "log", team: teamName, from: "spec-writer", to: "coordinator", type: "error", summary: "缺少 discovery-context.json, 无法生成 Product Brief" })
Execution Process
Phase 1: Task Discovery
├─ TaskList to find unblocked DRAFT-* tasks
├─ TaskGet to read full task details
└─ TaskUpdate to mark in_progress
Phase 2: Context & Discussion Loading
├─ Read session config (spec-config.json)
├─ Read relevant prior documents and discussion records
├─ Determine document type from task subject (Brief/PRD/Architecture/Epics)
└─ Load discussion feedback (discuss-*.md)
Phase 3: Document Generation (type-specific)
├─ DRAFT-001: Product Brief (multi-CLI parallel analysis)
├─ DRAFT-002: Requirements/PRD (functional + non-functional + MoSCoW)
├─ DRAFT-003: Architecture (ADRs + tech stack + diagrams)
└─ DRAFT-004: Epics & Stories (decomposition + dependencies + MVP)
Phase 4: Self-Validation
├─ Check all template sections populated
├─ Verify cross-references to prior documents
└─ Validate YAML frontmatter completeness
Phase 5: Report to Coordinator
├─ team_msg log + SendMessage document summary
├─ TaskUpdate completed
└─ Check for next DRAFT-* task
Implementation
Phase 1: Task Discovery
// Find assigned DRAFT-* tasks
const tasks = TaskList()
const myTasks = tasks.filter(t =>
t.subject.startsWith('DRAFT-') &&
t.owner === 'spec-writer' &&
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 & Discussion Loading
// Extract session folder from task description
const sessionMatch = task.description.match(/Session:\s*(.+)/)
const sessionFolder = sessionMatch ? sessionMatch[1].trim() : ''
// Load session config
let specConfig = null
try { specConfig = JSON.parse(Read(`${sessionFolder}/spec-config.json`)) } catch {}
// Determine document type from task subject
const docType = task.subject.includes('Product Brief') ? 'product-brief'
: task.subject.includes('Requirements') || task.subject.includes('PRD') ? 'requirements'
: task.subject.includes('Architecture') ? 'architecture'
: task.subject.includes('Epics') ? 'epics'
: 'unknown'
// Load discussion feedback (from preceding DISCUSS task)
const discussionFiles = {
'product-brief': 'discussions/discuss-001-scope.md',
'requirements': 'discussions/discuss-002-brief.md',
'architecture': 'discussions/discuss-003-requirements.md',
'epics': 'discussions/discuss-004-architecture.md'
}
let discussionFeedback = null
try {
discussionFeedback = Read(`${sessionFolder}/${discussionFiles[docType]}`)
} catch {}
// Load prior documents
const priorDocs = {}
if (docType !== 'product-brief') {
try { priorDocs.discoveryContext = Read(`${sessionFolder}/discovery-context.json`) } catch {}
}
if (docType === 'requirements' || docType === 'architecture' || docType === 'epics') {
try { priorDocs.productBrief = Read(`${sessionFolder}/product-brief.md`) } catch {}
}
if (docType === 'architecture' || docType === 'epics') {
try { priorDocs.requirementsIndex = Read(`${sessionFolder}/requirements/_index.md`) } catch {}
}
if (docType === 'epics') {
try { priorDocs.architectureIndex = Read(`${sessionFolder}/architecture/_index.md`) } catch {}
}
Phase 3: Document Generation
// Route to specific generation logic based on document type
switch (docType) {
case 'product-brief':
await generateProductBrief(sessionFolder, specConfig, discussionFeedback)
break
case 'requirements':
await generateRequirements(sessionFolder, specConfig, priorDocs, discussionFeedback)
break
case 'architecture':
await generateArchitecture(sessionFolder, specConfig, priorDocs, discussionFeedback)
break
case 'epics':
await generateEpics(sessionFolder, specConfig, priorDocs, discussionFeedback)
break
}
DRAFT-001: Product Brief (Multi-Perspective Analysis)
async function generateProductBrief(sessionFolder, config, discussionFeedback) {
const discoveryContext = JSON.parse(Read(`${sessionFolder}/discovery-context.json`))
const topic = config?.topic || discoveryContext.seed_analysis.problem_statement
// 进展通知
mcp__ccw-tools__team_msg({ operation: "log", team: teamName, from: "spec-writer", to: "coordinator", type: "impl_progress", summary: "开始 Product Brief 多视角分析 (1/3)" })
// Launch 3 parallel CLI analyses for multi-perspective synthesis
// 1. Product perspective (Gemini)
Bash({
command: `ccw cli -p "PURPOSE: Analyze from PRODUCT perspective for specification.
TASK: • Market fit analysis • Value proposition • Success criteria • Competitive landscape
TOPIC: ${topic}
CONTEXT: Discovery findings: ${JSON.stringify(discoveryContext.seed_analysis)}
${discussionFeedback ? `DISCUSSION FEEDBACK: ${discussionFeedback}` : ''}
EXPECTED: Structured product analysis (vision, problem, goals, scope, constraints)
CONSTRAINTS: Focus on product strategy" --tool gemini --mode analysis`,
run_in_background: true
})
// 2. Technical perspective (Codex)
Bash({
command: `ccw cli -p "PURPOSE: Analyze from TECHNICAL perspective for specification.
TASK: • Technical feasibility • Architecture constraints • Tech stack recommendations • Implementation risks
TOPIC: ${topic}
CONTEXT: Discovery findings: ${JSON.stringify(discoveryContext.seed_analysis)}
${discoveryContext.codebase_context ? `CODEBASE: ${JSON.stringify(discoveryContext.codebase_context)}` : ''}
EXPECTED: Technical feasibility assessment
CONSTRAINTS: Focus on engineering perspective" --tool codex --mode analysis`,
run_in_background: true
})
// 3. User perspective (Claude)
Bash({
command: `ccw cli -p "PURPOSE: Analyze from USER perspective for specification.
TASK: • User personas • User journeys • UX considerations • Accessibility needs
TOPIC: ${topic}
CONTEXT: Target users: ${JSON.stringify(discoveryContext.seed_analysis.target_users)}
EXPECTED: User experience analysis (personas, journeys, pain points)
CONSTRAINTS: Focus on end-user perspective" --tool claude --mode analysis`,
run_in_background: true
})
// Wait for all 3 analyses to complete, then synthesize
// Generate product-brief.md with YAML frontmatter
const brief = `---
session_id: ${config.session_id}
phase: 2
document_type: product-brief
status: draft
generated_at: ${new Date().toISOString()}
version: 1
dependencies:
- discovery-context.json
- discuss-001-scope.md
---
# Product Brief: ${topic}
## Vision
${productPerspective.vision}
## Problem Statement
${discoveryContext.seed_analysis.problem_statement}
## Target Users
${personas.map(p => `### ${p.name}\n- **Role**: ${p.role}\n- **Pain Points**: ${p.painPoints}\n- **Goals**: ${p.goals}`).join('\n\n')}
## Goals & Success Metrics
${productPerspective.goals}
## Scope
### In Scope
${productPerspective.inScope}
### Out of Scope
${productPerspective.outOfScope}
## Technical Feasibility
${technicalPerspective.summary}
## User Experience Considerations
${userPerspective.summary}
## Multi-Perspective Synthesis
### Convergent Themes
${synthesis.convergent}
### Divergent Views
${synthesis.divergent}
### Discussion Feedback Integration
${discussionFeedback ? discussionFeedback.summary : 'N/A (first draft)'}
## Constraints
${discoveryContext.seed_analysis.constraints.map(c => `- ${c}`).join('\n')}
## Open Questions
${openQuestions.map(q => `- ${q}`).join('\n')}
`
Write(`${sessionFolder}/product-brief.md`, brief)
}
DRAFT-002: Requirements/PRD
async function generateRequirements(sessionFolder, config, priorDocs, discussionFeedback) {
// Use Gemini CLI to expand requirements from product brief
Bash({
command: `ccw cli -p "PURPOSE: Generate functional and non-functional requirements from Product Brief.
TASK:
• Extract functional requirements (REQ-NNN format) with user stories and acceptance criteria
• Generate non-functional requirements (NFR-{type}-NNN) for Performance/Security/Scalability/Usability
• Apply MoSCoW prioritization (Must/Should/Could/Won't)
• Create traceability matrix to Product Brief goals
CONTEXT: Product Brief: ${priorDocs.productBrief}
${discussionFeedback ? `DISCUSSION FEEDBACK: ${discussionFeedback}` : ''}
EXPECTED: Structured requirements list in JSON
CONSTRAINTS: Each requirement needs ID, title, user story, 2-4 acceptance criteria" --tool gemini --mode analysis`,
run_in_background: true
})
// Generate requirements/ directory structure
Bash(`mkdir -p ${sessionFolder}/requirements`)
// Write _index.md + individual REQ-*.md + NFR-*.md files
// Following spec-generator templates/requirements-prd.md format
}
DRAFT-003: Architecture
async function generateArchitecture(sessionFolder, config, priorDocs, discussionFeedback) {
// Generate architecture via Gemini
Bash({
command: `ccw cli -p "PURPOSE: Design system architecture based on requirements.
TASK:
• Select architecture style with justification
• Define core components and responsibilities
• Create component interaction diagram (Mermaid)
• Choose tech stack (languages, frameworks, databases, infrastructure)
• Generate 2-4 ADRs with alternatives and pros/cons
• Design data model (Mermaid erDiagram)
• Define security architecture
CONTEXT: Requirements: ${priorDocs.requirementsIndex}
Product Brief: ${priorDocs.productBrief}
${discussionFeedback ? `DISCUSSION FEEDBACK: ${discussionFeedback}` : ''}
EXPECTED: Complete architecture document
CONSTRAINTS: Include ADRs with alternatives" --tool gemini --mode analysis`,
run_in_background: true
})
// Challenge architecture via Codex
Bash({
command: `ccw cli -p "PURPOSE: Challenge and review proposed architecture.
TASK: • Review ADR alternatives • Identify bottlenecks • Assess security gaps • Rate quality (1-5)
CONTEXT: [architecture output from above]
EXPECTED: Architecture review with ratings" --tool codex --mode analysis`,
run_in_background: true
})
// Generate architecture/ directory
Bash(`mkdir -p ${sessionFolder}/architecture`)
// Write _index.md + ADR-*.md files
}
DRAFT-004: Epics & Stories
async function generateEpics(sessionFolder, config, priorDocs, discussionFeedback) {
// Decompose via Gemini
Bash({
command: `ccw cli -p "PURPOSE: Decompose requirements into Epics and Stories.
TASK:
• Group 3-7 logical Epics by domain or user journey
• Generate 2-5 Stories per Epic (user story format)
• Create cross-Epic dependency map (Mermaid)
• Define MVP scope with done criteria
• Recommend execution order
CONTEXT: Requirements: ${priorDocs.requirementsIndex}
Architecture: ${priorDocs.architectureIndex}
Product Brief: ${priorDocs.productBrief}
${discussionFeedback ? `DISCUSSION FEEDBACK: ${discussionFeedback}` : ''}
EXPECTED: Epic/Story decomposition with dependencies
CONSTRAINTS: Each story needs AC, size estimate (S/M/L/XL), requirement tracing" --tool gemini --mode analysis`,
run_in_background: true
})
// Generate epics/ directory
Bash(`mkdir -p ${sessionFolder}/epics`)
// Write _index.md + EPIC-*.md files
}
Phase 4: Self-Validation
// Validate generated document
const validationChecks = {
has_frontmatter: false,
sections_complete: false,
cross_references: false,
discussion_integrated: false
}
// Check YAML frontmatter
const docContent = Read(`${sessionFolder}/${outputPath}`)
validationChecks.has_frontmatter = /^---\n[\s\S]+?\n---/.test(docContent)
// Check required sections based on doc type
const requiredSections = {
'product-brief': ['Vision', 'Problem Statement', 'Target Users', 'Goals', 'Scope'],
'requirements': ['_index.md', 'REQ-'],
'architecture': ['_index.md', 'ADR-'],
'epics': ['_index.md', 'EPIC-']
}
// Verify all sections present
// Check cross-references to prior documents
validationChecks.cross_references = docContent.includes('session_id')
// Check discussion feedback integration
validationChecks.discussion_integrated = !discussionFeedback || docContent.includes('Discussion')
const allValid = Object.values(validationChecks).every(v => v)
Phase 5: Report to Coordinator
const docTypeLabel = {
'product-brief': 'Product Brief',
'requirements': 'Requirements/PRD',
'architecture': 'Architecture Document',
'epics': 'Epics & Stories'
}
// Log before SendMessage
mcp__ccw-tools__team_msg({
operation: "log", team: teamName,
from: "spec-writer", to: "coordinator",
type: "draft_ready",
summary: `${docTypeLabel[docType]} 完成: ${allValid ? '验证通过' : '部分验证失败'}`,
ref: `${sessionFolder}/${outputPath}`
})
SendMessage({
type: "message",
recipient: "coordinator",
content: `## 文档撰写结果
**Task**: ${task.subject}
**文档类型**: ${docTypeLabel[docType]}
**验证状态**: ${allValid ? 'PASS' : 'PARTIAL'}
### 文档摘要
${documentSummary}
### 讨论反馈整合
${discussionFeedback ? '已整合前序讨论反馈' : '首次撰写(无前序讨论反馈)'}
### 自验证结果
${Object.entries(validationChecks).map(([k, v]) => `- ${k}: ${v ? '✓' : '✗'}`).join('\n')}
### 输出位置
${sessionFolder}/${outputPath}
文档已就绪,可进入讨论轮次。`,
summary: `${docTypeLabel[docType]} 就绪`
})
// Mark task completed
TaskUpdate({ taskId: task.id, status: 'completed' })
// Check for next DRAFT task
const nextTasks = TaskList().filter(t =>
t.subject.startsWith('DRAFT-') &&
t.owner === 'spec-writer' &&
t.status === 'pending' &&
t.blockedBy.length === 0
)
if (nextTasks.length > 0) {
// Continue with next task -> back to Phase 1
}
Error Handling
| Scenario | Resolution |
|---|---|
| No DRAFT-* tasks available | Idle, wait for coordinator assignment |
| Prior document not found | Notify coordinator, request prerequisite |
| CLI analysis failure | Retry with fallback tool, then direct generation |
| Template sections incomplete | Generate best-effort, note gaps in report |
| Discussion feedback contradicts prior docs | Note conflict in document, flag for next discussion |
| Session folder missing | Notify coordinator, request session path |
| Unexpected error | Log error via team_msg, report to coordinator |