mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-15 02:42:45 +08:00
feat: add team-command-designer skill with folder-based team structure and 10 collaboration patterns
Introduces a complete skill for designing and generating team command .md
files. Each team is organized as a folder under .claude/commands/team/{team-name}/
with colon-separated skill paths (e.g., team:spec:analyst). Includes 8
infrastructure patterns, 10 collaboration patterns (CP-1 through CP-10),
5-phase generation pipeline, and quality validation standards.
This commit is contained in:
@@ -0,0 +1,227 @@
|
||||
# Phase 1: Requirements Collection
|
||||
|
||||
Collect team definition, role definition, capabilities, and communication patterns for the new team command.
|
||||
|
||||
## Objective
|
||||
|
||||
- Determine team name (folder name)
|
||||
- Determine role name and responsibilities
|
||||
- Define task prefix and communication patterns
|
||||
- Select required tools and capabilities
|
||||
- Generate role-config.json
|
||||
|
||||
## Input
|
||||
|
||||
- Dependency: User request (`$ARGUMENTS` or interactive input)
|
||||
- Specification: `specs/team-design-patterns.md` (read in Phase 0)
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1: Team & Role Basic Information
|
||||
|
||||
```javascript
|
||||
const teamInfo = await AskUserQuestion({
|
||||
questions: [
|
||||
{
|
||||
question: "What is the team name? (lowercase, used as folder name under .claude/commands/team/{team-name}/)",
|
||||
header: "Team Name",
|
||||
multiSelect: false,
|
||||
options: [
|
||||
{ label: "Custom team", description: "Enter a custom team name" },
|
||||
{ label: "spec", description: "Specification documentation team" },
|
||||
{ label: "security", description: "Security audit and compliance team" },
|
||||
{ label: "devops", description: "Deployment and operations team" }
|
||||
]
|
||||
},
|
||||
{
|
||||
question: "What is the role name for this teammate? (lowercase, e.g., 'analyzer', 'deployer')",
|
||||
header: "Role Name",
|
||||
multiSelect: false,
|
||||
options: [
|
||||
{ label: "Custom role", description: "Enter a custom role name" },
|
||||
{ label: "coordinator", description: "Team coordinator / orchestrator" },
|
||||
{ label: "analyzer", description: "Code/data analysis specialist" },
|
||||
{ label: "deployer", description: "Deployment and release management" }
|
||||
]
|
||||
},
|
||||
{
|
||||
question: "What is the primary responsibility type?",
|
||||
header: "Responsibility",
|
||||
multiSelect: false,
|
||||
options: [
|
||||
{ label: "Read-only analysis", description: "Analyze, review, report (no file modification)" },
|
||||
{ label: "Code generation", description: "Write/modify code files" },
|
||||
{ label: "Orchestration", description: "Coordinate sub-tasks and agents" },
|
||||
{ label: "Validation", description: "Test, verify, audit" }
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
### Step 2: Task Configuration
|
||||
|
||||
```javascript
|
||||
const taskConfig = await AskUserQuestion({
|
||||
questions: [
|
||||
{
|
||||
question: "What task prefix should this role use? (UPPERCASE, unique, e.g., 'ANALYZE', 'DEPLOY')",
|
||||
header: "Task Prefix",
|
||||
multiSelect: false,
|
||||
options: [
|
||||
{ label: "Custom prefix", description: "Enter a unique task prefix" },
|
||||
{ label: "ANALYZE", description: "For analysis tasks (ANALYZE-001)" },
|
||||
{ label: "DEPLOY", description: "For deployment tasks (DEPLOY-001)" },
|
||||
{ label: "DOC", description: "For documentation tasks (DOC-001)" }
|
||||
]
|
||||
},
|
||||
{
|
||||
question: "Where does this role fit in the task chain?",
|
||||
header: "Chain Position",
|
||||
multiSelect: false,
|
||||
options: [
|
||||
{ label: "After PLAN (parallel with IMPL)", description: "Runs alongside implementation" },
|
||||
{ label: "After IMPL (parallel with TEST/REVIEW)", description: "Post-implementation validation" },
|
||||
{ label: "After TEST+REVIEW (final stage)", description: "Final processing before completion" },
|
||||
{ label: "Independent (coordinator-triggered)", description: "No dependency on other tasks" }
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
### Step 3: Capability Selection
|
||||
|
||||
```javascript
|
||||
const capabilities = await AskUserQuestion({
|
||||
questions: [
|
||||
{
|
||||
question: "What capabilities does this role need?",
|
||||
header: "Capabilities",
|
||||
multiSelect: true,
|
||||
options: [
|
||||
{ label: "File modification (Write/Edit)", description: "Can create and modify files" },
|
||||
{ label: "Sub-agent delegation (Task)", description: "Can spawn sub-agents for complex work" },
|
||||
{ label: "CLI tool invocation", description: "Can invoke ccw cli tools (gemini/qwen/codex)" },
|
||||
{ label: "User interaction (AskUserQuestion)", description: "Can ask user questions during execution" }
|
||||
]
|
||||
},
|
||||
{
|
||||
question: "Does this role need complexity-adaptive routing?",
|
||||
header: "Adaptive",
|
||||
multiSelect: false,
|
||||
options: [
|
||||
{ label: "Yes (Recommended)", description: "Low=direct, Medium/High=agent delegation" },
|
||||
{ label: "No", description: "Always use the same execution path" }
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
### Step 4: Message Types Definition
|
||||
|
||||
```javascript
|
||||
// Infer message types from role type
|
||||
const responsibilityType = roleInfo["Responsibility"]
|
||||
|
||||
const baseMessageTypes = [
|
||||
{ type: "error", direction: "-> coordinator", trigger: "Blocking error" }
|
||||
]
|
||||
|
||||
const roleMessageTypes = {
|
||||
"Read-only analysis": [
|
||||
{ type: "{role}_result", direction: "-> coordinator", trigger: "Analysis complete" },
|
||||
{ type: "{role}_progress", direction: "-> coordinator", trigger: "Long analysis progress" }
|
||||
],
|
||||
"Code generation": [
|
||||
{ type: "{role}_complete", direction: "-> coordinator", trigger: "Generation complete" },
|
||||
{ type: "{role}_progress", direction: "-> coordinator", trigger: "Batch progress update" }
|
||||
],
|
||||
"Orchestration": [
|
||||
{ type: "{role}_ready", direction: "-> coordinator", trigger: "Sub-task results ready" },
|
||||
{ type: "{role}_progress", direction: "-> coordinator", trigger: "Sub-task progress" }
|
||||
],
|
||||
"Validation": [
|
||||
{ type: "{role}_result", direction: "-> coordinator", trigger: "Validation complete" },
|
||||
{ type: "fix_required", direction: "-> coordinator", trigger: "Critical issues found" }
|
||||
]
|
||||
}
|
||||
|
||||
const messageTypes = [
|
||||
...baseMessageTypes,
|
||||
...(roleMessageTypes[responsibilityType] || [])
|
||||
]
|
||||
```
|
||||
|
||||
### Step 5: Generate Configuration
|
||||
|
||||
```javascript
|
||||
const teamName = teamInfo["Team Name"] === "Custom team"
|
||||
? teamInfo["Team Name_other"]
|
||||
: teamInfo["Team Name"]
|
||||
|
||||
const roleName = teamInfo["Role Name"] === "Custom role"
|
||||
? teamInfo["Role Name_other"]
|
||||
: teamInfo["Role Name"]
|
||||
|
||||
const taskPrefix = taskConfig["Task Prefix"] === "Custom prefix"
|
||||
? taskConfig["Task Prefix_other"]
|
||||
: taskConfig["Task Prefix"]
|
||||
|
||||
// Build allowed-tools list
|
||||
const baseTools = ["SendMessage(*)", "TaskUpdate(*)", "TaskList(*)", "TaskGet(*)", "TodoWrite(*)", "Read(*)", "Bash(*)", "Glob(*)", "Grep(*)"]
|
||||
const selectedCapabilities = capabilities["Capabilities"] || []
|
||||
|
||||
if (selectedCapabilities.includes("File modification")) {
|
||||
baseTools.push("Write(*)", "Edit(*)")
|
||||
}
|
||||
if (selectedCapabilities.includes("Sub-agent delegation")) {
|
||||
baseTools.push("Task(*)")
|
||||
}
|
||||
|
||||
const config = {
|
||||
team_name: teamName,
|
||||
role_name: roleName,
|
||||
display_name: `Team ${teamName} ${roleName}`,
|
||||
description_cn: `Team ${teamName} ${roleName} - ${teamInfo["Responsibility"]}`,
|
||||
responsibility_type: responsibilityType,
|
||||
task_prefix: taskPrefix.toUpperCase(),
|
||||
chain_position: taskConfig["Chain Position"],
|
||||
allowed_tools: baseTools,
|
||||
capabilities: selectedCapabilities,
|
||||
adaptive_routing: capabilities["Adaptive"].includes("Yes"),
|
||||
message_types: messageTypes.map(mt => ({
|
||||
...mt,
|
||||
type: mt.type.replace('{role}', roleName)
|
||||
})),
|
||||
cli_integration: selectedCapabilities.includes("CLI tool invocation"),
|
||||
user_interaction: selectedCapabilities.includes("User interaction"),
|
||||
// Derived paths
|
||||
skill_path: `team:${teamName}:${roleName}`, // e.g., team:spec:analyst
|
||||
output_folder: `.claude/commands/team/${teamName}`, // e.g., .claude/commands/team/spec
|
||||
output_file: `${roleName}.md` // e.g., analyst.md
|
||||
}
|
||||
|
||||
Write(`${workDir}/role-config.json`, JSON.stringify(config, null, 2))
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
- **File**: `role-config.json`
|
||||
- **Format**: JSON
|
||||
- **Location**: `{workDir}/role-config.json`
|
||||
|
||||
## Quality Checklist
|
||||
|
||||
- [ ] Team name is lowercase, valid as folder name
|
||||
- [ ] Role name is lowercase, unique within the team folder
|
||||
- [ ] Task prefix is UPPERCASE, unique (not PLAN/IMPL/TEST/REVIEW)
|
||||
- [ ] Allowed tools include minimum set (SendMessage, TaskUpdate, TaskList, TaskGet)
|
||||
- [ ] Message types follow naming convention
|
||||
- [ ] Chain position is clearly defined
|
||||
- [ ] Derived paths (skill_path, output_folder, output_file) are consistent
|
||||
|
||||
## Next Phase
|
||||
|
||||
-> [Phase 2: Pattern Analysis](02-pattern-analysis.md)
|
||||
@@ -0,0 +1,266 @@
|
||||
# Phase 2: Pattern Analysis
|
||||
|
||||
Identify applicable design patterns from existing team commands for the new role.
|
||||
|
||||
## Objective
|
||||
|
||||
- Find the most similar existing team command
|
||||
- Select applicable infrastructure patterns (Section A)
|
||||
- Select applicable collaboration patterns (Section B: CP-1 through CP-10)
|
||||
- Map role responsibilities to phase structure
|
||||
- Generate applicable-patterns.json
|
||||
|
||||
## Input
|
||||
|
||||
- Dependency: `role-config.json` (from Phase 1)
|
||||
- Specification: `specs/team-design-patterns.md` (read in Phase 0)
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1: Load Configuration
|
||||
|
||||
```javascript
|
||||
const config = JSON.parse(Read(`${workDir}/role-config.json`))
|
||||
```
|
||||
|
||||
### Step 2: Find Most Similar Existing Command
|
||||
|
||||
```javascript
|
||||
// Similarity mapping based on responsibility type
|
||||
const similarityMap = {
|
||||
"Read-only analysis": {
|
||||
primary: "review", // Multi-dimensional analysis -> report
|
||||
secondary: "plan", // Also does exploration
|
||||
reason: "Both analyze code and report findings with severity classification"
|
||||
},
|
||||
"Code generation": {
|
||||
primary: "execute", // Code implementation
|
||||
secondary: "test", // Also modifies code (fixes)
|
||||
reason: "Both write/modify code files and self-validate"
|
||||
},
|
||||
"Orchestration": {
|
||||
primary: "plan", // Manages exploration and plan generation
|
||||
secondary: "coordinate", // High-level orchestration
|
||||
reason: "Both coordinate multiple sub-tasks and produce structured output"
|
||||
},
|
||||
"Validation": {
|
||||
primary: "test", // Test execution and fix cycles
|
||||
secondary: "review", // Verification
|
||||
reason: "Both validate output quality with structured criteria"
|
||||
}
|
||||
}
|
||||
|
||||
const similarity = similarityMap[config.responsibility_type]
|
||||
|
||||
// Read the most similar command for pattern extraction
|
||||
const primaryRef = Read(`.claude/commands/team/${similarity.primary}.md`)
|
||||
const secondaryRef = Read(`.claude/commands/team/${similarity.secondary}.md`)
|
||||
```
|
||||
|
||||
### Step 3: Select Applicable Patterns
|
||||
|
||||
```javascript
|
||||
// All commands use these core patterns (mandatory)
|
||||
const corePatterns = [
|
||||
"pattern-1-message-bus", // Always required
|
||||
"pattern-2-yaml-front-matter", // Always required
|
||||
"pattern-3-task-lifecycle", // Always required
|
||||
"pattern-4-five-phase", // Always required
|
||||
"pattern-6-coordinator-spawn", // Always required
|
||||
"pattern-7-error-handling" // Always required
|
||||
]
|
||||
|
||||
// Conditional patterns based on config
|
||||
const conditionalPatterns = []
|
||||
|
||||
if (config.adaptive_routing) {
|
||||
conditionalPatterns.push("pattern-5-complexity-adaptive")
|
||||
}
|
||||
|
||||
if (config.responsibility_type === "Code generation" ||
|
||||
config.responsibility_type === "Orchestration") {
|
||||
conditionalPatterns.push("pattern-8-session-files")
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4: Map Phase Structure
|
||||
|
||||
```javascript
|
||||
// Map 5-phase structure to role-specific content
|
||||
const phaseMapping = {
|
||||
"Read-only analysis": {
|
||||
phase1: "Task Discovery",
|
||||
phase2: "Context Loading (read changed files, load plan)",
|
||||
phase3: `${config.role_name}-specific analysis`,
|
||||
phase4: "Finding Summary (classify severity)",
|
||||
phase5: "Report to Coordinator"
|
||||
},
|
||||
"Code generation": {
|
||||
phase1: "Task & Plan Loading",
|
||||
phase2: "Task Grouping (dependency analysis)",
|
||||
phase3: "Code Implementation (direct or sub-agent)",
|
||||
phase4: "Self-Validation (syntax, criteria)",
|
||||
phase5: "Completion Report"
|
||||
},
|
||||
"Orchestration": {
|
||||
phase1: "Task Discovery",
|
||||
phase2: "Context & Complexity Assessment",
|
||||
phase3: "Orchestrated Execution (parallel sub-agents)",
|
||||
phase4: "Result Aggregation",
|
||||
phase5: "Submit for Approval + Loop"
|
||||
},
|
||||
"Validation": {
|
||||
phase1: "Task Discovery",
|
||||
phase2: "Framework/Environment Detection",
|
||||
phase3: "Execution & Fix Cycle",
|
||||
phase4: "Result Analysis",
|
||||
phase5: "Report to Coordinator"
|
||||
}
|
||||
}
|
||||
|
||||
const phases = phaseMapping[config.responsibility_type]
|
||||
```
|
||||
|
||||
### Step 5: Extract Implementation Patterns from Reference
|
||||
|
||||
```javascript
|
||||
// Extract specific code patterns from the most similar command
|
||||
function extractPatterns(commandContent) {
|
||||
const patterns = {}
|
||||
|
||||
// Extract task discovery pattern
|
||||
const taskDiscovery = commandContent.match(
|
||||
/\/\/ Find my assigned.*?if \(my\w+Tasks\.length === 0\).*?return/s
|
||||
)
|
||||
if (taskDiscovery) patterns.taskDiscovery = taskDiscovery[0]
|
||||
|
||||
// Extract message bus examples
|
||||
const msgExamples = commandContent.match(
|
||||
/mcp__ccw-tools__team_msg\(\{[^}]+\}\)/g
|
||||
)
|
||||
if (msgExamples) patterns.messageExamples = msgExamples
|
||||
|
||||
// Extract error handling table
|
||||
const errorTable = commandContent.match(
|
||||
/## Error Handling[\s\S]*?\n\n/
|
||||
)
|
||||
if (errorTable) patterns.errorHandling = errorTable[0]
|
||||
|
||||
return patterns
|
||||
}
|
||||
|
||||
const referencePatterns = extractPatterns(primaryRef)
|
||||
```
|
||||
|
||||
### Step 6: Select Collaboration Patterns
|
||||
|
||||
```javascript
|
||||
// Collaboration pattern selection based on role characteristics
|
||||
function selectCollaborationPatterns(config) {
|
||||
const patterns = ['CP-1'] // CP-1 Linear Pipeline is always the base
|
||||
|
||||
const responsibilityType = config.responsibility_type
|
||||
|
||||
// Rule-based selection
|
||||
if (responsibilityType === 'Validation' || responsibilityType === 'Read-only analysis') {
|
||||
patterns.push('CP-2') // Review-Fix Cycle - natural for validation roles
|
||||
}
|
||||
|
||||
if (responsibilityType === 'Orchestration') {
|
||||
patterns.push('CP-3') // Fan-out/Fan-in for orchestration
|
||||
patterns.push('CP-4') // Consensus Gate for decisions
|
||||
}
|
||||
|
||||
if (config.adaptive_routing) {
|
||||
patterns.push('CP-5') // Escalation Chain for when self-repair fails
|
||||
}
|
||||
|
||||
if (responsibilityType === 'Code generation') {
|
||||
patterns.push('CP-6') // Incremental Delivery for large implementations
|
||||
patterns.push('CP-2') // Review-Fix Cycle for code quality
|
||||
}
|
||||
|
||||
// CP-5 Escalation is always available as a fallback
|
||||
if (!patterns.includes('CP-5')) {
|
||||
patterns.push('CP-5')
|
||||
}
|
||||
|
||||
// CP-10 Post-Mortem is always included at team level
|
||||
patterns.push('CP-10')
|
||||
|
||||
return [...new Set(patterns)] // Deduplicate
|
||||
}
|
||||
|
||||
const collaborationPatterns = selectCollaborationPatterns(config)
|
||||
|
||||
// Map collaboration patterns to convergence configurations
|
||||
const convergenceConfig = collaborationPatterns.map(cp => {
|
||||
const defaults = {
|
||||
'CP-1': { max_iterations: 1, timeout: null, success_gate: 'all_stages_completed' },
|
||||
'CP-2': { max_iterations: 5, timeout: null, success_gate: 'verdict_approve_or_conditional' },
|
||||
'CP-3': { max_iterations: 1, timeout: 300000, success_gate: 'quorum_100_percent' },
|
||||
'CP-4': { max_iterations: 2, timeout: 300000, success_gate: 'quorum_67_percent' },
|
||||
'CP-5': { max_iterations: null, timeout: null, success_gate: 'issue_resolved_at_any_level' },
|
||||
'CP-6': { max_iterations: 3, timeout: null, success_gate: 'all_increments_validated' },
|
||||
'CP-7': { max_iterations: 2, timeout: 600000, success_gate: 'blocker_resolved' },
|
||||
'CP-8': { max_iterations: 2, timeout: 120000, success_gate: 'advice_applied' },
|
||||
'CP-9': { max_iterations: 2, timeout: 300000, success_gate: 'all_sync_points_aligned' },
|
||||
'CP-10': { max_iterations: 1, timeout: 180000, success_gate: 'report_generated' }
|
||||
}
|
||||
return { pattern: cp, convergence: defaults[cp] }
|
||||
})
|
||||
```
|
||||
|
||||
### Step 7: Generate Patterns Document
|
||||
|
||||
```javascript
|
||||
const applicablePatterns = {
|
||||
role_name: config.role_name,
|
||||
similar_to: {
|
||||
primary: similarity.primary,
|
||||
secondary: similarity.secondary,
|
||||
reason: similarity.reason
|
||||
},
|
||||
// Infrastructure patterns
|
||||
core_patterns: corePatterns,
|
||||
conditional_patterns: conditionalPatterns,
|
||||
// Collaboration patterns
|
||||
collaboration_patterns: collaborationPatterns,
|
||||
convergence_config: convergenceConfig,
|
||||
// Phase and reference mapping
|
||||
phase_structure: phases,
|
||||
reference_patterns: {
|
||||
task_discovery: "Adapt from " + similarity.primary + ".md Phase 1",
|
||||
core_work: "Adapt from " + similarity.primary + ".md Phase 3",
|
||||
reporting: "Adapt from " + similarity.primary + ".md Phase 5"
|
||||
},
|
||||
message_types: config.message_types,
|
||||
implementation_hints: {
|
||||
phase1: `Standard task lifecycle with ${config.task_prefix}-* prefix`,
|
||||
phase2: phases.phase2,
|
||||
phase3: phases.phase3,
|
||||
phase4: phases.phase4,
|
||||
phase5: `SendMessage to coordinator with ${config.role_name} results`
|
||||
}
|
||||
}
|
||||
|
||||
Write(`${workDir}/applicable-patterns.json`, JSON.stringify(applicablePatterns, null, 2))
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
- **File**: `applicable-patterns.json`
|
||||
- **Format**: JSON
|
||||
- **Location**: `{workDir}/applicable-patterns.json`
|
||||
|
||||
## Quality Checklist
|
||||
|
||||
- [ ] Most similar existing command identified
|
||||
- [ ] All mandatory patterns included (6 core patterns)
|
||||
- [ ] Phase structure mapped to role responsibilities
|
||||
- [ ] Implementation hints are specific and actionable
|
||||
- [ ] Reference patterns point to concrete sections
|
||||
|
||||
## Next Phase
|
||||
|
||||
-> [Phase 3: Command Generation](03-command-generation.md)
|
||||
@@ -0,0 +1,353 @@
|
||||
# Phase 3: Command Generation
|
||||
|
||||
Generate the team command .md file using template and pattern analysis results.
|
||||
|
||||
## Objective
|
||||
|
||||
- Apply command template with role-specific content
|
||||
- Generate complete YAML front matter
|
||||
- Generate message bus section
|
||||
- Generate 5-phase implementation with code
|
||||
- Generate error handling table
|
||||
- Output final command file
|
||||
|
||||
## Input
|
||||
|
||||
- Dependency: `role-config.json` (Phase 1), `applicable-patterns.json` (Phase 2)
|
||||
- Template: `templates/command-template.md`
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1: Load Inputs
|
||||
|
||||
```javascript
|
||||
const config = JSON.parse(Read(`${workDir}/role-config.json`))
|
||||
const patterns = JSON.parse(Read(`${workDir}/applicable-patterns.json`))
|
||||
const template = Read(`${skillDir}/templates/command-template.md`)
|
||||
|
||||
// Read most similar command for code reference
|
||||
// Note: reference may be in a folder (e.g. .claude/commands/team/folder/cmd.md) if config.output_folder is set
|
||||
const refCommand = Read(`.claude/commands/team/${patterns.similar_to.primary}.md`)
|
||||
```
|
||||
|
||||
### Step 2: Generate YAML Front Matter
|
||||
|
||||
```javascript
|
||||
const frontMatter = `---
|
||||
name: ${config.role_name}
|
||||
description: ${config.description_cn}
|
||||
argument-hint: ""
|
||||
allowed-tools: ${config.allowed_tools.join(', ')}
|
||||
group: team
|
||||
---`
|
||||
```
|
||||
|
||||
### Step 3: Generate Message Bus Section
|
||||
|
||||
```javascript
|
||||
const messageBusSection = `## Message Bus
|
||||
|
||||
Every SendMessage **before**, must call \`mcp__ccw-tools__team_msg\` to log:
|
||||
|
||||
\`\`\`javascript
|
||||
mcp__ccw-tools__team_msg({ operation: "log", team: teamName, from: "${config.role_name}", to: "coordinator", type: "<type>", summary: "<summary>" })
|
||||
\`\`\`
|
||||
|
||||
### Supported Message Types
|
||||
|
||||
| Type | Direction | Trigger | Description |
|
||||
|------|-----------|---------|-------------|
|
||||
${config.message_types.map(mt =>
|
||||
`| \`${mt.type}\` | ${config.role_name} -> coordinator | ${mt.trigger} | ${mt.description || mt.trigger} |`
|
||||
).join('\n')}
|
||||
|
||||
### Examples
|
||||
|
||||
\`\`\`javascript
|
||||
${config.message_types.filter(mt => mt.type !== 'error').map(mt =>
|
||||
`// ${mt.trigger}
|
||||
mcp__ccw-tools__team_msg({ operation: "log", team: teamName, from: "${config.role_name}", to: "coordinator", type: "${mt.type}", summary: "${mt.trigger}" })`
|
||||
).join('\n\n')}
|
||||
\`\`\``
|
||||
```
|
||||
|
||||
### Step 4: Generate Phase Implementations
|
||||
|
||||
```javascript
|
||||
// Phase 1: Task Discovery (standard for all roles)
|
||||
const phase1 = `### Phase 1: Task Discovery
|
||||
|
||||
\`\`\`javascript
|
||||
// Find assigned ${config.task_prefix}-* tasks
|
||||
const tasks = TaskList()
|
||||
const myTasks = tasks.filter(t =>
|
||||
t.subject.startsWith('${config.task_prefix}-') &&
|
||||
t.owner === '${config.role_name}' &&
|
||||
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 (adapted by responsibility type)
|
||||
const phase2Templates = {
|
||||
"Read-only analysis": `### Phase 2: Context Loading
|
||||
|
||||
\`\`\`javascript
|
||||
// Load plan for criteria reference
|
||||
const planPathMatch = task.description.match(/\\.workflow\\/\\.team-plan\\/[^\\s]+\\/plan\\.json/)
|
||||
let plan = null
|
||||
if (planPathMatch) {
|
||||
try { plan = JSON.parse(Read(planPathMatch[0])) } catch {}
|
||||
}
|
||||
|
||||
// Get changed files
|
||||
const changedFiles = Bash(\`git diff --name-only HEAD~1 2>/dev/null || git diff --name-only --cached\`)
|
||||
.split('\\n').filter(Boolean)
|
||||
|
||||
// Read file contents for analysis
|
||||
const fileContents = {}
|
||||
for (const file of changedFiles.slice(0, 20)) {
|
||||
try { fileContents[file] = Read(file) } catch {}
|
||||
}
|
||||
\`\`\``,
|
||||
|
||||
"Code generation": `### Phase 2: Task & Plan Loading
|
||||
|
||||
\`\`\`javascript
|
||||
// Extract plan path from task description
|
||||
const planPathMatch = task.description.match(/\\.workflow\\/\\.team-plan\\/[^\\s]+\\/plan\\.json/)
|
||||
if (!planPathMatch) {
|
||||
SendMessage({ type: "message", recipient: "coordinator",
|
||||
content: \`Cannot find plan.json path in task \${task.subject}\`,
|
||||
summary: "Plan path not found" })
|
||||
return
|
||||
}
|
||||
|
||||
const plan = JSON.parse(Read(planPathMatch[0]))
|
||||
// Load task files from .task/ directory
|
||||
const planTasks = plan.task_ids.map(id =>
|
||||
JSON.parse(Read(\`\${planPathMatch[0].replace('plan.json', '')}.task/\${id}.json\`))
|
||||
)
|
||||
\`\`\``,
|
||||
|
||||
"Orchestration": `### Phase 2: Context & Complexity Assessment
|
||||
|
||||
\`\`\`javascript
|
||||
// Assess task complexity
|
||||
function assessComplexity(desc) {
|
||||
let score = 0
|
||||
if (/refactor|architect|restructure|module|system/.test(desc)) score += 2
|
||||
if (/multiple|across|cross/.test(desc)) score += 2
|
||||
if (/integrate|api|database/.test(desc)) score += 1
|
||||
if (/security|performance/.test(desc)) score += 1
|
||||
return score >= 4 ? 'High' : score >= 2 ? 'Medium' : 'Low'
|
||||
}
|
||||
|
||||
const complexity = assessComplexity(task.description)
|
||||
|
||||
// Load related context
|
||||
const projectTech = Bash(\`test -f .workflow/project-tech.json && cat .workflow/project-tech.json || echo "{}"\`)
|
||||
\`\`\``,
|
||||
|
||||
"Validation": `### Phase 2: Environment Detection
|
||||
|
||||
\`\`\`javascript
|
||||
// Detect relevant tools/frameworks
|
||||
// (customize based on specific validation domain)
|
||||
const changedFiles = Bash(\`git diff --name-only HEAD~1 2>/dev/null || git diff --name-only --cached\`)
|
||||
.split('\\n').filter(Boolean)
|
||||
|
||||
// Load context based on validation type
|
||||
\`\`\``
|
||||
}
|
||||
|
||||
const phase2 = phase2Templates[config.responsibility_type]
|
||||
|
||||
// Phase 3: Core Work (role-specific, provides skeleton)
|
||||
const phase3 = `### Phase 3: ${patterns.phase_structure.phase3}
|
||||
|
||||
\`\`\`javascript
|
||||
// Core ${config.role_name} logic
|
||||
// TODO: Implement based on role requirements
|
||||
// Reference: .claude/commands/team/${patterns.similar_to.primary}.md Phase 3
|
||||
|
||||
${config.adaptive_routing ? `
|
||||
// Complexity-adaptive execution
|
||||
if (complexity === 'Low') {
|
||||
// Direct execution
|
||||
} else {
|
||||
// Delegate to sub-agent
|
||||
Task({
|
||||
subagent_type: "universal-executor",
|
||||
run_in_background: false,
|
||||
description: "${config.role_name} work",
|
||||
prompt: \`
|
||||
## Task
|
||||
\${task.description}
|
||||
|
||||
## MANDATORY FIRST STEPS
|
||||
1. Read: .workflow/project-tech.json (if exists)
|
||||
2. Read: .workflow/project-guidelines.json (if exists)
|
||||
|
||||
## Expected Output
|
||||
\${expectedFormat}
|
||||
\`
|
||||
})
|
||||
}` : `// Direct execution for all tasks`}
|
||||
\`\`\``
|
||||
|
||||
// Phase 4: Validation/Summary
|
||||
const phase4 = `### Phase 4: ${patterns.phase_structure.phase4}
|
||||
|
||||
\`\`\`javascript
|
||||
// Validate/summarize results
|
||||
// TODO: Implement based on role requirements
|
||||
// Reference: .claude/commands/team/${patterns.similar_to.primary}.md Phase 4
|
||||
\`\`\``
|
||||
|
||||
// Phase 5: Report + Loop (standard for all roles)
|
||||
const phase5 = `### Phase 5: Report to Coordinator
|
||||
|
||||
\`\`\`javascript
|
||||
// Log message before SendMessage
|
||||
mcp__ccw-tools__team_msg({
|
||||
operation: "log", team: teamName,
|
||||
from: "${config.role_name}", to: "coordinator",
|
||||
type: "${config.message_types[0]?.type || config.role_name + '_complete'}",
|
||||
summary: \`${config.task_prefix} complete: \${task.subject}\`
|
||||
})
|
||||
|
||||
SendMessage({
|
||||
type: "message",
|
||||
recipient: "coordinator",
|
||||
content: \`## ${config.display_name} Results
|
||||
|
||||
**Task**: \${task.subject}
|
||||
**Status**: \${resultStatus}
|
||||
|
||||
### Summary
|
||||
\${resultSummary}
|
||||
|
||||
### Details
|
||||
\${resultDetails}\`,
|
||||
summary: \`${config.task_prefix} complete\`
|
||||
})
|
||||
|
||||
// Mark task completed
|
||||
TaskUpdate({ taskId: task.id, status: 'completed' })
|
||||
|
||||
// Check for next task
|
||||
const nextTasks = TaskList().filter(t =>
|
||||
t.subject.startsWith('${config.task_prefix}-') &&
|
||||
t.owner === '${config.role_name}' &&
|
||||
t.status === 'pending' &&
|
||||
t.blockedBy.length === 0
|
||||
)
|
||||
|
||||
if (nextTasks.length > 0) {
|
||||
// Continue with next task -> back to Phase 1
|
||||
}
|
||||
\`\`\``
|
||||
```
|
||||
|
||||
### Step 5: Generate Error Handling Table
|
||||
|
||||
```javascript
|
||||
const errorTable = `## Error Handling
|
||||
|
||||
| Scenario | Resolution |
|
||||
|----------|------------|
|
||||
| No ${config.task_prefix}-* tasks available | Idle, wait for coordinator assignment |
|
||||
| Plan/Context file not found | Notify coordinator, request location |
|
||||
${config.adaptive_routing ? '| Sub-agent failure | Retry once, then fallback to direct execution |\n' : ''}| Max iterations exceeded | Report to coordinator, suggest intervention |
|
||||
| Critical issue beyond scope | SendMessage fix_required to coordinator |
|
||||
| Unexpected error | Log error via team_msg, report to coordinator |`
|
||||
```
|
||||
|
||||
### Step 6: Assemble Final Command File
|
||||
|
||||
```javascript
|
||||
const commandContent = `${frontMatter}
|
||||
|
||||
# Team ${config.display_name} Command (/${config.skill_path})
|
||||
|
||||
## Overview
|
||||
|
||||
Team ${config.role_name} role command. Operates as a teammate within an Agent Team, responsible for ${config.responsibility_type.toLowerCase()}.
|
||||
|
||||
**Core capabilities:**
|
||||
- Task discovery from shared team task list (${config.task_prefix}-* tasks)
|
||||
${patterns.core_patterns.includes('pattern-5-complexity-adaptive') ? '- Complexity-adaptive routing (Low -> direct, Medium/High -> agent)\n' : ''}- ${config.responsibility_type}-specific processing
|
||||
- Structured result reporting to coordinator
|
||||
|
||||
## Role Definition
|
||||
|
||||
**Name**: \`${config.role_name}\`
|
||||
**Responsibility**: ${patterns.phase_structure.phase2} -> ${patterns.phase_structure.phase3} -> ${patterns.phase_structure.phase5}
|
||||
**Communication**: SendMessage to coordinator only
|
||||
|
||||
${messageBusSection}
|
||||
|
||||
## Execution Process
|
||||
|
||||
\`\`\`
|
||||
Phase 1: Task Discovery
|
||||
├─ TaskList to find unblocked ${config.task_prefix}-* tasks
|
||||
├─ TaskGet to read full task details
|
||||
└─ TaskUpdate to mark in_progress
|
||||
|
||||
Phase 2: ${patterns.phase_structure.phase2}
|
||||
|
||||
Phase 3: ${patterns.phase_structure.phase3}
|
||||
|
||||
Phase 4: ${patterns.phase_structure.phase4}
|
||||
|
||||
Phase 5: ${patterns.phase_structure.phase5}
|
||||
├─ team_msg log + SendMessage results
|
||||
├─ TaskUpdate completed
|
||||
└─ Check for next ${config.task_prefix}-* task
|
||||
\`\`\`
|
||||
|
||||
## Implementation
|
||||
|
||||
${phase1}
|
||||
|
||||
${phase2}
|
||||
|
||||
${phase3}
|
||||
|
||||
${phase4}
|
||||
|
||||
${phase5}
|
||||
|
||||
${errorTable}
|
||||
`
|
||||
|
||||
Write(`${workDir}/${config.role_name}.md`, commandContent)
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
- **File**: `{role-name}.md`
|
||||
- **Format**: Markdown
|
||||
- **Location**: `{workDir}/{role-name}.md`
|
||||
|
||||
## Quality Checklist
|
||||
|
||||
- [ ] YAML front matter includes all required fields
|
||||
- [ ] `group: team` is present
|
||||
- [ ] Message bus section has team_msg examples
|
||||
- [ ] All 5 phases are present with implementation code
|
||||
- [ ] Task lifecycle follows standard pattern
|
||||
- [ ] Error handling table is present
|
||||
- [ ] SendMessage always preceded by team_msg
|
||||
- [ ] Role communicates only with coordinator
|
||||
|
||||
## Next Phase
|
||||
|
||||
-> [Phase 4: Integration Verification](04-integration-verification.md)
|
||||
@@ -0,0 +1,212 @@
|
||||
# Phase 4: Integration Verification
|
||||
|
||||
Verify the generated command integrates correctly with the existing team system.
|
||||
|
||||
## Objective
|
||||
|
||||
- Verify consistency with coordinate.md spawn patterns
|
||||
- Check message type compatibility
|
||||
- Verify task prefix uniqueness
|
||||
- Ensure allowed-tools are sufficient
|
||||
- Generate integration-report.json
|
||||
|
||||
## Input
|
||||
|
||||
- Dependency: `{role-name}.md` (Phase 3), `role-config.json` (Phase 1)
|
||||
- Reference: `.claude/commands/team/coordinate.md`
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1: Load Generated Command and Config
|
||||
|
||||
```javascript
|
||||
const config = JSON.parse(Read(`${workDir}/role-config.json`))
|
||||
const generatedCommand = Read(`${workDir}/${config.role_name}.md`)
|
||||
const coordinateCmd = Read(`.claude/commands/team/coordinate.md`)
|
||||
```
|
||||
|
||||
### Step 2: Check Task Prefix Uniqueness
|
||||
|
||||
```javascript
|
||||
// Extract existing prefixes from coordinate.md
|
||||
const existingPrefixes = ['PLAN', 'IMPL', 'TEST', 'REVIEW']
|
||||
|
||||
// Also scan all team command files for prefixes
|
||||
const teamFiles = Glob('.claude/commands/team/**/*.md')
|
||||
for (const file of teamFiles) {
|
||||
const content = Read(file)
|
||||
const prefixMatch = content.match(/startsWith\('([A-Z]+)-'\)/)
|
||||
if (prefixMatch && !existingPrefixes.includes(prefixMatch[1])) {
|
||||
existingPrefixes.push(prefixMatch[1])
|
||||
}
|
||||
}
|
||||
|
||||
const prefixConflict = existingPrefixes.includes(config.task_prefix)
|
||||
|
||||
const prefixCheck = {
|
||||
status: prefixConflict ? 'FAIL' : 'PASS',
|
||||
existing: existingPrefixes,
|
||||
new_prefix: config.task_prefix,
|
||||
message: prefixConflict
|
||||
? `Prefix ${config.task_prefix} conflicts with existing: ${existingPrefixes.join(', ')}`
|
||||
: `Prefix ${config.task_prefix} is unique`
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3: Verify Spawn Pattern Compatibility
|
||||
|
||||
```javascript
|
||||
// Check that the generated command can be spawned by coordinate.md
|
||||
const spawnCheck = {
|
||||
has_skill_invocation: generatedCommand.includes('Skill(skill="team:'),
|
||||
has_task_lifecycle: generatedCommand.includes('TaskList') &&
|
||||
generatedCommand.includes('TaskGet') &&
|
||||
generatedCommand.includes('TaskUpdate'),
|
||||
has_message_bus: generatedCommand.includes('mcp__ccw-tools__team_msg'),
|
||||
has_send_message: generatedCommand.includes('SendMessage'),
|
||||
has_group_team: generatedCommand.includes('group: team')
|
||||
}
|
||||
|
||||
const spawnCompatible = Object.values(spawnCheck).every(v => v)
|
||||
```
|
||||
|
||||
### Step 4: Verify Message Type Compatibility
|
||||
|
||||
```javascript
|
||||
// Extract all message types used in coordinate.md handlers
|
||||
const coordinateTypes = coordinateCmd.match(/type:\s*["']([^"']+)["']/g)
|
||||
?.map(m => m.match(/["']([^"']+)["']/)[1]) || []
|
||||
|
||||
// Check new message types don't conflict
|
||||
const msgTypeCheck = {
|
||||
coordinator_knows: coordinateTypes,
|
||||
new_types: config.message_types.map(mt => mt.type),
|
||||
conflicts: config.message_types
|
||||
.filter(mt => coordinateTypes.includes(mt.type))
|
||||
.map(mt => mt.type),
|
||||
recommendation: "Add new message types to coordinate.md handler table"
|
||||
}
|
||||
```
|
||||
|
||||
### Step 5: Verify Allowed-Tools Sufficiency
|
||||
|
||||
```javascript
|
||||
const requiredTools = ['SendMessage', 'TaskUpdate', 'TaskList', 'TaskGet']
|
||||
const missingTools = requiredTools.filter(tool =>
|
||||
!config.allowed_tools.some(at => at.includes(tool))
|
||||
)
|
||||
|
||||
const toolCheck = {
|
||||
status: missingTools.length === 0 ? 'PASS' : 'FAIL',
|
||||
required: requiredTools,
|
||||
configured: config.allowed_tools,
|
||||
missing: missingTools
|
||||
}
|
||||
```
|
||||
|
||||
### Step 6: Verify Chain Position Integration
|
||||
|
||||
```javascript
|
||||
// Check coordinate.md has or can add the task chain
|
||||
const chainCheck = {
|
||||
position: config.chain_position,
|
||||
existing_chain: "PLAN-001 -> IMPL-001 -> TEST-001 + REVIEW-001",
|
||||
integration_needed: true,
|
||||
suggestion: generateChainSuggestion(config)
|
||||
}
|
||||
|
||||
function generateChainSuggestion(config) {
|
||||
const pos = config.chain_position
|
||||
if (pos.includes("After PLAN")) {
|
||||
return `PLAN-001 -> IMPL-001 + ${config.task_prefix}-001 -> TEST-001 + REVIEW-001`
|
||||
}
|
||||
if (pos.includes("After IMPL")) {
|
||||
return `PLAN-001 -> IMPL-001 -> TEST-001 + REVIEW-001 + ${config.task_prefix}-001`
|
||||
}
|
||||
if (pos.includes("After TEST")) {
|
||||
return `PLAN-001 -> IMPL-001 -> TEST-001 + REVIEW-001 -> ${config.task_prefix}-001`
|
||||
}
|
||||
return `PLAN-001 -> IMPL-001 -> TEST-001 + REVIEW-001 (+ ${config.task_prefix}-001 independent)`
|
||||
}
|
||||
```
|
||||
|
||||
### Step 7: Generate Coordinator Spawn Snippet
|
||||
|
||||
```javascript
|
||||
// Generate the spawn code that should be added to coordinate.md
|
||||
const spawnSnippet = `// ${config.display_name}
|
||||
Task({
|
||||
subagent_type: "general-purpose",
|
||||
team_name: teamName,
|
||||
name: "${config.role_name}",
|
||||
prompt: \`You are team "\${teamName}" ${config.role_name.toUpperCase()}.
|
||||
|
||||
When you receive ${config.task_prefix}-* tasks, call Skill(skill="${config.skill_path}") to execute.
|
||||
|
||||
Current requirement: \${taskDescription}
|
||||
Constraints: \${constraints}
|
||||
|
||||
## Message Bus (Required)
|
||||
Before each SendMessage, call mcp__ccw-tools__team_msg:
|
||||
mcp__ccw-tools__team_msg({ operation: "log", team: "\${teamName}", from: "${config.role_name}", to: "coordinator", type: "<type>", summary: "<summary>" })
|
||||
|
||||
Workflow:
|
||||
1. TaskList -> find ${config.task_prefix}-* tasks assigned to you
|
||||
2. Skill(skill="${config.skill_path}") to execute
|
||||
3. team_msg log + SendMessage results to coordinator
|
||||
4. TaskUpdate completed -> check next task\`
|
||||
})`
|
||||
```
|
||||
|
||||
```javascript
|
||||
// Skill path: ${config.skill_path} (e.g., team:spec:analyst)
|
||||
// Folder: ${config.output_folder} (e.g., .claude/commands/team/spec)
|
||||
```
|
||||
|
||||
### Step 8: Generate Integration Report
|
||||
|
||||
```javascript
|
||||
const report = {
|
||||
role_name: config.role_name,
|
||||
checks: {
|
||||
prefix_unique: prefixCheck,
|
||||
spawn_compatible: { status: spawnCompatible ? 'PASS' : 'FAIL', details: spawnCheck },
|
||||
message_types: msgTypeCheck,
|
||||
tools_sufficient: toolCheck,
|
||||
chain_integration: chainCheck
|
||||
},
|
||||
overall: (prefixCheck.status === 'PASS' &&
|
||||
spawnCompatible &&
|
||||
toolCheck.status === 'PASS') ? 'PASS' : 'NEEDS_ATTENTION',
|
||||
destination: `${config.output_folder}/${config.output_file}`,
|
||||
coordinator_updates: {
|
||||
spawn_snippet: spawnSnippet,
|
||||
task_chain: chainCheck.suggestion,
|
||||
handler_additions: config.message_types.map(mt => ({
|
||||
type: mt.type,
|
||||
action: `Handle ${mt.trigger}`
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
Write(`${workDir}/integration-report.json`, JSON.stringify(report, null, 2))
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
- **File**: `integration-report.json`
|
||||
- **Format**: JSON
|
||||
- **Location**: `{workDir}/integration-report.json`
|
||||
|
||||
## Quality Checklist
|
||||
|
||||
- [ ] Task prefix does not conflict with existing prefixes
|
||||
- [ ] Spawn pattern compatible with coordinate.md
|
||||
- [ ] All required tools are in allowed-tools
|
||||
- [ ] Message types documented
|
||||
- [ ] Chain position has integration suggestion
|
||||
- [ ] Coordinator spawn snippet is ready to copy
|
||||
|
||||
## Next Phase
|
||||
|
||||
-> [Phase 5: Validation](05-validation.md)
|
||||
254
.claude/skills/team-command-designer/phases/05-validation.md
Normal file
254
.claude/skills/team-command-designer/phases/05-validation.md
Normal file
@@ -0,0 +1,254 @@
|
||||
# Phase 5: Validation
|
||||
|
||||
Verify completeness and quality of the generated team command.
|
||||
|
||||
## Objective
|
||||
|
||||
- Check all required sections exist
|
||||
- Verify pattern compliance
|
||||
- Score against quality standards
|
||||
- Generate validation report
|
||||
- Deliver final command file
|
||||
|
||||
## Input
|
||||
|
||||
- Dependency: `{role-name}.md` (Phase 3), `integration-report.json` (Phase 4)
|
||||
- Specification: `specs/quality-standards.md`
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1: Load Files
|
||||
|
||||
```javascript
|
||||
const config = JSON.parse(Read(`${workDir}/role-config.json`))
|
||||
const command = Read(`${workDir}/${config.role_name}.md`)
|
||||
const integration = JSON.parse(Read(`${workDir}/integration-report.json`))
|
||||
```
|
||||
|
||||
### Step 2: Structural Completeness Check
|
||||
|
||||
```javascript
|
||||
const requiredSections = [
|
||||
{ name: "YAML Front Matter", pattern: /^---\n[\s\S]+?\n---/ },
|
||||
{ name: "group: team", pattern: /group:\s*team/ },
|
||||
{ name: "Overview Section", pattern: /## Overview/ },
|
||||
{ name: "Role Definition", pattern: /## Role Definition/ },
|
||||
{ name: "Message Bus Section", pattern: /## .*[Mm]essage.*[Bb]us/ },
|
||||
{ name: "team_msg Examples", pattern: /mcp__ccw-tools__team_msg/ },
|
||||
{ name: "Message Types Table", pattern: /\| Type \| Direction/ },
|
||||
{ name: "Execution Process", pattern: /## Execution Process/ },
|
||||
{ name: "Phase 1: Task Discovery", pattern: /Phase 1.*Task Discovery/i },
|
||||
{ name: "TaskList Usage", pattern: /TaskList/ },
|
||||
{ name: "TaskGet Usage", pattern: /TaskGet/ },
|
||||
{ name: "TaskUpdate Usage", pattern: /TaskUpdate/ },
|
||||
{ name: "SendMessage to Coordinator", pattern: /SendMessage.*coordinator/i },
|
||||
{ name: "Error Handling Table", pattern: /## Error Handling/ },
|
||||
{ name: "Implementation Section", pattern: /## Implementation/ }
|
||||
]
|
||||
|
||||
const structureResults = requiredSections.map(section => ({
|
||||
section: section.name,
|
||||
present: section.pattern.test(command),
|
||||
status: section.pattern.test(command) ? 'PASS' : 'FAIL'
|
||||
}))
|
||||
|
||||
const structureScore = structureResults.filter(r => r.status === 'PASS').length /
|
||||
structureResults.length * 100
|
||||
```
|
||||
|
||||
### Step 3: Pattern Compliance Check
|
||||
|
||||
```javascript
|
||||
const patternChecks = [
|
||||
{
|
||||
name: "Message Bus Before SendMessage",
|
||||
check: () => {
|
||||
// Every SendMessage should be preceded by team_msg
|
||||
const sendMessages = command.match(/SendMessage\(/g)?.length || 0
|
||||
const teamMsgs = command.match(/team_msg\(/g)?.length || 0
|
||||
return teamMsgs >= sendMessages
|
||||
},
|
||||
severity: "critical"
|
||||
},
|
||||
{
|
||||
name: "Task Lifecycle Pattern",
|
||||
check: () => {
|
||||
return command.includes('TaskList') &&
|
||||
command.includes('TaskGet') &&
|
||||
command.includes("status: 'in_progress'") &&
|
||||
command.includes("status: 'completed'")
|
||||
},
|
||||
severity: "critical"
|
||||
},
|
||||
{
|
||||
name: "Task Prefix Usage",
|
||||
check: () => {
|
||||
return command.includes(`'${config.task_prefix}-'`)
|
||||
},
|
||||
severity: "high"
|
||||
},
|
||||
{
|
||||
name: "Coordinator-Only Communication",
|
||||
check: () => {
|
||||
return command.includes('recipient: "coordinator"') &&
|
||||
!command.includes('recipient: "executor"') &&
|
||||
!command.includes('recipient: "planner"')
|
||||
},
|
||||
severity: "high"
|
||||
},
|
||||
{
|
||||
name: "Next Task Loop",
|
||||
check: () => {
|
||||
return command.includes('Check for next') ||
|
||||
command.includes('back to Phase 1')
|
||||
},
|
||||
severity: "medium"
|
||||
},
|
||||
{
|
||||
name: "Idle on No Tasks",
|
||||
check: () => {
|
||||
return command.includes('idle') || command.includes('return')
|
||||
},
|
||||
severity: "medium"
|
||||
}
|
||||
]
|
||||
|
||||
const patternResults = patternChecks.map(pc => ({
|
||||
pattern: pc.name,
|
||||
compliant: pc.check(),
|
||||
severity: pc.severity,
|
||||
status: pc.check() ? 'PASS' : 'FAIL'
|
||||
}))
|
||||
|
||||
const criticalFails = patternResults.filter(r =>
|
||||
r.status === 'FAIL' && r.severity === 'critical'
|
||||
)
|
||||
```
|
||||
|
||||
### Step 4: Quality Scoring
|
||||
|
||||
```javascript
|
||||
const qualityDimensions = {
|
||||
completeness: structureScore,
|
||||
pattern_compliance: patternResults.filter(r => r.status === 'PASS').length /
|
||||
patternResults.length * 100,
|
||||
integration: integration.overall === 'PASS' ? 100 : 50,
|
||||
consistency: checkConsistency(command, config)
|
||||
}
|
||||
|
||||
function checkConsistency(command, config) {
|
||||
let score = 100
|
||||
// Check role name consistency
|
||||
if (!command.includes(config.role_name)) score -= 20
|
||||
// Check task prefix consistency
|
||||
if (!command.includes(config.task_prefix)) score -= 20
|
||||
// Check front matter matches config
|
||||
if (!command.includes(`name: ${config.role_name}`)) score -= 20
|
||||
// Check group: team
|
||||
if (!command.includes('group: team')) score -= 20
|
||||
return Math.max(0, score)
|
||||
}
|
||||
|
||||
const overallScore = Object.values(qualityDimensions)
|
||||
.reduce((a, b) => a + b, 0) / Object.keys(qualityDimensions).length
|
||||
|
||||
const qualityGate = overallScore >= 80 ? 'PASS' :
|
||||
overallScore >= 60 ? 'REVIEW' : 'FAIL'
|
||||
```
|
||||
|
||||
### Step 5: Generate Validation Report
|
||||
|
||||
```javascript
|
||||
const report = {
|
||||
role_name: config.role_name,
|
||||
timestamp: new Date().toISOString(),
|
||||
scores: {
|
||||
completeness: qualityDimensions.completeness,
|
||||
pattern_compliance: qualityDimensions.pattern_compliance,
|
||||
integration: qualityDimensions.integration,
|
||||
consistency: qualityDimensions.consistency,
|
||||
overall: overallScore
|
||||
},
|
||||
quality_gate: qualityGate,
|
||||
structure_checks: structureResults,
|
||||
pattern_checks: patternResults,
|
||||
critical_failures: criticalFails,
|
||||
recommendations: generateRecommendations(structureResults, patternResults, integration),
|
||||
delivery: {
|
||||
source: `${workDir}/${config.role_name}.md`,
|
||||
destination: `${config.output_folder}/${config.output_file}`,
|
||||
ready: qualityGate !== 'FAIL' && criticalFails.length === 0
|
||||
}
|
||||
}
|
||||
|
||||
function generateRecommendations(structure, patterns, integration) {
|
||||
const recs = []
|
||||
structure.filter(s => s.status === 'FAIL').forEach(s => {
|
||||
recs.push(`Add missing section: ${s.section}`)
|
||||
})
|
||||
patterns.filter(p => p.status === 'FAIL').forEach(p => {
|
||||
recs.push(`Fix pattern violation: ${p.pattern} [${p.severity}]`)
|
||||
})
|
||||
if (integration.overall === 'NEEDS_ATTENTION') {
|
||||
recs.push('Review integration report for coordinate.md updates')
|
||||
}
|
||||
return recs
|
||||
}
|
||||
|
||||
Write(`${workDir}/validation-report.json`, JSON.stringify(report, null, 2))
|
||||
```
|
||||
|
||||
### Step 6: Deliver Final File
|
||||
|
||||
```javascript
|
||||
if (report.delivery.ready) {
|
||||
// Copy to final location
|
||||
const finalContent = Read(`${workDir}/${config.role_name}.md`)
|
||||
// Ensure team folder exists
|
||||
Bash(`mkdir -p "${config.output_folder}"`)
|
||||
Write(`${config.output_folder}/${config.output_file}`, finalContent)
|
||||
|
||||
// Report success
|
||||
console.log(`Team command delivered to: ${config.output_folder}/${config.output_file}`)
|
||||
console.log(`Skill path: /${config.skill_path}`)
|
||||
console.log(`Quality score: ${overallScore.toFixed(1)}% (${qualityGate})`)
|
||||
console.log(`Integration: ${integration.overall}`)
|
||||
|
||||
if (report.recommendations.length > 0) {
|
||||
console.log('\nRecommendations:')
|
||||
report.recommendations.forEach(r => console.log(` - ${r}`))
|
||||
}
|
||||
|
||||
// Remind about coordinate.md updates
|
||||
console.log('\nNext steps:')
|
||||
console.log('1. Update coordinate.md to add spawn snippet (see integration-report.json)')
|
||||
console.log('2. Add new message type handlers to coordinator')
|
||||
console.log(`3. Test with: /${config.skill_path}`)
|
||||
} else {
|
||||
console.log(`Validation FAILED (score: ${overallScore.toFixed(1)}%)`)
|
||||
console.log('Critical failures:')
|
||||
criticalFails.forEach(f => console.log(` - ${f.pattern}`))
|
||||
console.log('Fix issues and re-run Phase 3-5')
|
||||
}
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
- **File**: `validation-report.json`
|
||||
- **Format**: JSON
|
||||
- **Location**: `{workDir}/validation-report.json`
|
||||
- **Delivery**: `.claude/commands/team/{team-name}/{role-name}.md` (if validation passes)
|
||||
|
||||
## Quality Checklist
|
||||
|
||||
- [ ] All 15+ structural checks executed
|
||||
- [ ] All 6+ pattern compliance checks executed
|
||||
- [ ] No critical failures remaining
|
||||
- [ ] Overall score >= 80% (PASS gate)
|
||||
- [ ] Integration report reviewed
|
||||
- [ ] Final file delivered to `.claude/commands/team/{team-name}/`
|
||||
- [ ] Coordinator update instructions provided
|
||||
|
||||
## Completion
|
||||
|
||||
This is the final phase. The generated team command is ready for use.
|
||||
Reference in New Issue
Block a user