Files
Claude-Code-Workflow/.claude/skills/ccw/phases/orchestrator.md
catlog22 1f5ce9c03a Enhance CCW Orchestrator with Requirement Analysis Features
- Updated SKILL.md to reflect new requirement analysis capabilities, including input analysis and clarity scoring.
- Expanded issue workflow in issue.md to include discovery and creation phases, along with detailed command references.
- Introduced requirement analysis specification in requirement-analysis.md, outlining clarity scoring, dimension extraction, and validation processes.
- Added output templates specification in output-templates.md for consistent user experience across classification, planning, clarification, execution, and summary outputs.
2026-01-14 20:15:42 +08:00

35 KiB

CCW Orchestrator

无状态编排器:分析输入 → 选择工作流链 → TODO 跟踪执行

Architecture

┌──────────────────────────────────────────────────────────────────┐
│  CCW Orchestrator (CLI-Enhanced + Requirement Analysis)           │
├──────────────────────────────────────────────────────────────────┤
│                                                                   │
│  Phase 1: Input Analysis (Rule-Based, Fast Path)                  │
│  ├─ Parse input (natural language / explicit command)            │
│  ├─ Classify intent (bugfix / feature / issue / ui / docs)       │
│  ├─ Assess complexity (low / medium / high)                      │
│  └─ Extract requirement dimensions (WHAT/WHERE/WHY/HOW)          │
│                                                                   │
│  Phase 1.5: CLI-Assisted Classification (Smart Path)             │
│  ├─ Trigger: low match count / high complexity / long input      │
│  ├─ Use Gemini CLI for semantic intent understanding             │
│  ├─ Get confidence score and reasoning                           │
│  └─ Fallback to rule-based if CLI fails                          │
│                                                                   │
│  Phase 1.75: Requirement Clarification (NEW)                      │
│  ├─ Calculate clarity score (0-3)                                 │
│  ├─ Trigger: clarity_score < 2 OR missing critical dimensions    │
│  ├─ Generate targeted clarification questions                     │
│  └─ Refine requirement dimensions with user input                 │
│                                                                   │
│  Phase 2: Chain Selection                                         │
│  ├─ Load index/workflow-chains.json                              │
│  ├─ Match intent → chain(s)                                       │
│  ├─ Filter by complexity                                          │
│  └─ Select optimal chain                                          │
│                                                                   │
│  Phase 2.5: CLI-Assisted Action Planning (Optimization)          │
│  ├─ Trigger: high complexity / many steps / long request         │
│  ├─ Use Gemini CLI to optimize execution strategy                │
│  ├─ Suggest step modifications or CLI injections                 │
│  └─ Identify risks and provide mitigations                       │
│                                                                   │
│  Phase 3: User Confirmation (optional)                            │
│  ├─ Display selected chain and steps                              │
│  └─ Allow modification or manual selection                        │
│                                                                   │
│  Phase 4: TODO Tracking Setup                                     │
│  ├─ Create TodoWrite with chain steps                             │
│  └─ Mark first step as in_progress                                │
│                                                                   │
│  Phase 5: Execution Loop                                          │
│  ├─ Execute current step (SlashCommand)                           │
│  ├─ Update TODO status (completed)                                │
│  ├─ Check auto_continue flag                                      │
│  └─ Proceed to next step or wait for user                         │
│                                                                   │
└──────────────────────────────────────────────────────────────────┘

Requirement Analysis Integration

See specs/requirement-analysis.md for full specification.

Clarity Scoring

Score Level Action
0 模糊 必须澄清
1 基本 建议澄清
2 清晰 可直接执行
3 详细 直接执行

Dimension Extraction

// Extract requirement dimensions during Phase 1
function extractDimensions(input) {
  return {
    what: extractWhat(input),     // Action + Target
    where: extractWhere(input),   // Scope + Paths
    why: extractWhy(input),       // Goal + Motivation
    how: extractHow(input),       // Constraints + Preferences
    clarity_score: 0,             // Calculated later
    missing_dimensions: []        // Identified later
  }
}

Output Templates Integration

See specs/output-templates.md for full specification.

All output uses standardized templates for consistency:

  • Classification Summary
  • Requirement Analysis
  • Planning Summary
  • Execution Progress
  • Workflow Complete

CLI Enhancement Features

Trigger Conditions

Feature Trigger Condition Default Tool
CLI Classification matchCount < 2 OR complexity = high OR input > 100 chars gemini
CLI Action Planning complexity = high OR steps >= 3 OR input > 200 chars gemini

Fallback Behavior

  • Classification: If CLI fails, falls back to rule-based classification
  • Action Planning: If CLI fails, uses default chain without optimization
  • Tool Fallback: Primary tool (gemini) -> Secondary tool (qwen)

Configuration

All CLI enhancement settings are in index/intent-rules.json:

{
  "cli_classification": {
    "enabled": true,
    "trigger_conditions": { ... },
    "default_tool": "gemini",
    "fallback_tool": "qwen"
  },
  "cli_action_planning": {
    "enabled": true,
    "trigger_conditions": { ... },
    "allow_step_modification": true
  }
}

Implementation

Phase 1: Input Analysis

// Load external configuration (externalized for flexibility)
const intentRules = JSON.parse(Read('.claude/skills/ccw/index/intent-rules.json'))
const capabilities = JSON.parse(Read('.claude/skills/ccw/index/command-capabilities.json'))

function analyzeInput(userInput) {
  const input = userInput.trim()

  // Check for explicit command passthrough
  if (input.match(/^\/(?:workflow|issue|memory|task):/)) {
    return { type: 'explicit', command: input, passthrough: true }
  }

  // Classify intent using external rules
  const intent = classifyIntent(input, intentRules.intent_patterns)

  // Assess complexity using external indicators
  const complexity = assessComplexity(input, intentRules.complexity_indicators)

  // Detect tool preferences using external triggers
  const toolPreference = detectToolPreference(input, intentRules.cli_tool_triggers)

  return {
    type: 'natural',
    text: input,
    intent,
    complexity,
    toolPreference,
    passthrough: false
  }
}

function classifyIntent(text, patterns) {
  // Sort by priority
  const sorted = Object.entries(patterns)
    .sort((a, b) => a[1].priority - b[1].priority)

  for (const [intentType, config] of sorted) {
    // Handle variants (bugfix, ui, docs)
    if (config.variants) {
      for (const [variant, variantConfig] of Object.entries(config.variants)) {
        const variantPatterns = variantConfig.patterns || variantConfig.triggers || []
        if (matchesAnyPattern(text, variantPatterns)) {
          // For bugfix, check if standard patterns also match
          if (intentType === 'bugfix') {
            const standardMatch = matchesAnyPattern(text, config.variants.standard?.patterns || [])
            if (standardMatch) {
              return { type: intentType, variant, workflow: variantConfig.workflow }
            }
          } else {
            return { type: intentType, variant, workflow: variantConfig.workflow }
          }
        }
      }
      // Check default variant
      if (config.variants.standard) {
        if (matchesAnyPattern(text, config.variants.standard.patterns)) {
          return { type: intentType, variant: 'standard', workflow: config.variants.standard.workflow }
        }
      }
    }

    // Handle simple patterns (exploration, tdd, review)
    if (config.patterns && !config.require_both) {
      if (matchesAnyPattern(text, config.patterns)) {
        return { type: intentType, workflow: config.workflow }
      }
    }

    // Handle dual-pattern matching (issue_batch)
    if (config.require_both && config.patterns) {
      const matchBatch = matchesAnyPattern(text, config.patterns.batch_keywords)
      const matchAction = matchesAnyPattern(text, config.patterns.action_keywords)
      if (matchBatch && matchAction) {
        return { type: intentType, workflow: config.workflow }
      }
    }
  }

  // Default to feature
  return { type: 'feature' }
}

function matchesAnyPattern(text, patterns) {
  if (!Array.isArray(patterns)) return false
  const lowerText = text.toLowerCase()
  return patterns.some(p => lowerText.includes(p.toLowerCase()))
}

function assessComplexity(text, indicators) {
  let score = 0

  for (const [level, config] of Object.entries(indicators)) {
    if (config.patterns) {
      for (const [category, patternConfig] of Object.entries(config.patterns)) {
        if (matchesAnyPattern(text, patternConfig.keywords)) {
          score += patternConfig.weight || 1
        }
      }
    }
  }

  if (score >= indicators.high.score_threshold) return 'high'
  if (score >= indicators.medium.score_threshold) return 'medium'
  return 'low'
}

function detectToolPreference(text, triggers) {
  for (const [tool, config] of Object.entries(triggers)) {
    // Check explicit triggers
    if (matchesAnyPattern(text, config.explicit)) return tool
    // Check semantic triggers
    if (matchesAnyPattern(text, config.semantic)) return tool
  }
  return null
}

// Calculate match count for confidence assessment
function calculateMatchCount(text, patterns) {
  let count = 0
  for (const [intentType, config] of Object.entries(patterns)) {
    if (config.variants) {
      for (const [variant, variantConfig] of Object.entries(config.variants)) {
        const variantPatterns = variantConfig.patterns || variantConfig.triggers || []
        if (matchesAnyPattern(text, variantPatterns)) count++
      }
    }
    if (config.patterns && !config.require_both) {
      if (matchesAnyPattern(text, config.patterns)) count++
    }
  }
  return count
}

Phase 1.5: CLI-Assisted Classification

For ambiguous or complex inputs, use CLI tools for semantic understanding.

// CLI-assisted classification for ambiguous inputs
async function cliAssistedClassification(input, ruleBasedResult, intentRules) {
  const cliConfig = intentRules.cli_classification

  // Skip if CLI classification is disabled
  if (!cliConfig || !cliConfig.enabled) {
    return { ...ruleBasedResult, source: 'rules', matchCount: 0 }
  }

  // Calculate match count for confidence assessment
  const matchCount = calculateMatchCount(input, intentRules.intent_patterns)

  // Determine if CLI classification should be triggered
  const triggers = cliConfig.trigger_conditions
  const shouldUseCli =
    matchCount < triggers.low_match_count ||
    ruleBasedResult.complexity === triggers.complexity_trigger ||
    input.length > triggers.min_input_length ||
    matchesAnyPattern(input, triggers.ambiguous_patterns)

  if (!shouldUseCli) {
    return { ...ruleBasedResult, source: 'rules', matchCount }
  }

  console.log('### CLI-Assisted Intent Classification\n')
  console.log('> Using CLI for semantic understanding of ambiguous input...\n')

  // Build CLI prompt for intent classification
  const cliPrompt = `
PURPOSE: Classify user request intent and recommend optimal workflow
TASK:
- Analyze the semantic meaning of the user request
- Classify into one of: bugfix, feature, exploration, ui, issue, tdd, review, docs
- Assess complexity: low, medium, high
- Recommend workflow chain based on intent and complexity
- Provide confidence score (0-1)

MODE: analysis
CONTEXT: User request analysis for workflow orchestration
EXPECTED: JSON output with structure:
{
  "intent": {
    "type": "bugfix|feature|exploration|ui|issue|tdd|review|docs",
    "variant": "optional variant like hotfix, imitate, incremental",
    "confidence": 0.0-1.0,
    "reasoning": "brief explanation of classification"
  },
  "complexity": {
    "level": "low|medium|high",
    "factors": ["factor1", "factor2"],
    "confidence": 0.0-1.0
  },
  "recommended_workflow": {
    "chain_id": "rapid|full|coupled|bugfix|issue|tdd|ui|review-fix|docs",
    "reasoning": "why this workflow is optimal"
  },
  "tool_preference": {
    "suggested": "gemini|qwen|codex|null",
    "reasoning": "optional reasoning"
  }
}

USER REQUEST:
${input}

RULES: Output ONLY valid JSON without markdown code blocks. Be concise but accurate.
`

  // Select CLI tool (default or fallback)
  const tool = cliConfig.default_tool || 'gemini'
  const timeout = cliConfig.timeout_ms || 60000

  try {
    // Execute CLI call synchronously for classification
    const escapedPrompt = cliPrompt.replace(/"/g, '\\"').replace(/\n/g, '\\n')
    const cliResult = Bash({
      command: `ccw cli -p "${escapedPrompt}" --tool ${tool} --mode analysis`,
      run_in_background: false,
      timeout: timeout
    })

    // Parse CLI result - extract JSON from response
    const jsonMatch = cliResult.match(/\{[\s\S]*\}/)
    if (!jsonMatch) {
      throw new Error('No JSON found in CLI response')
    }

    const parsed = JSON.parse(jsonMatch[0])

    console.log(`
**CLI Classification Result**:
- **Intent**: ${parsed.intent.type}${parsed.intent.variant ? ` (${parsed.intent.variant})` : ''}
- **Complexity**: ${parsed.complexity.level}
- **Confidence**: ${(parsed.intent.confidence * 100).toFixed(0)}%
- **Reasoning**: ${parsed.intent.reasoning}
- **Recommended Chain**: ${parsed.recommended_workflow.chain_id}
`)

    return {
      type: 'natural',
      text: input,
      intent: {
        type: parsed.intent.type,
        variant: parsed.intent.variant,
        workflow: parsed.recommended_workflow.chain_id
      },
      complexity: parsed.complexity.level,
      toolPreference: parsed.tool_preference?.suggested || ruleBasedResult.toolPreference,
      confidence: parsed.intent.confidence,
      source: 'cli',
      cliReasoning: parsed.intent.reasoning,
      passthrough: false
    }
  } catch (error) {
    console.log(`> CLI classification failed: ${error.message}`)
    console.log('> Falling back to rule-based classification\n')

    // Try fallback tool if available
    if (cliConfig.fallback_tool && cliConfig.fallback_tool !== tool) {
      console.log(`> Attempting fallback with ${cliConfig.fallback_tool}...`)
      // Could recursively call with fallback tool, but for simplicity, just return rule-based
    }

    return { ...ruleBasedResult, source: 'rules', matchCount }
  }
}

Phase 1.75: Requirement Clarification

当需求不够清晰时,主动向用户发起澄清。

// Requirement clarification for ambiguous inputs
async function clarifyRequirement(analysis, dimensions) {
  // Skip if already clear
  if (dimensions.clarity_score >= 2) {
    return { needsClarification: false, dimensions }
  }

  // Skip for explicit commands
  if (analysis.passthrough) {
    return { needsClarification: false, dimensions }
  }

  console.log('### Requirement Clarification\n')
  console.log('> Your request needs more detail. Let me ask a few questions.\n')

  // Generate questions based on missing dimensions
  const questions = generateClarificationQuestions(dimensions)

  if (questions.length === 0) {
    return { needsClarification: false, dimensions }
  }

  // Display current understanding
  console.log(`
**Current Understanding**:
| Dimension | Value | Status |
|-----------|-------|--------|
| WHAT | ${dimensions.what.action || 'unknown'} ${dimensions.what.target || ''} | ${dimensions.what.target ? '✓' : '⚠'} |
| WHERE | ${dimensions.where.scope}: ${dimensions.where.paths?.join(', ') || 'unknown'} | ${dimensions.where.paths?.length ? '✓' : '⚠'} |
| WHY | ${dimensions.why.goal || 'not specified'} | ${dimensions.why.goal ? '✓' : '○'} |
| HOW | ${dimensions.how.constraints?.join(', ') || 'no constraints'} | ○ |

**Clarity Score**: ${dimensions.clarity_score}/3
`)

  // Ask user for clarification (max 4 questions)
  const responses = AskUserQuestion({
    questions: questions.slice(0, 4)
  })

  // Refine dimensions with user responses
  const refinedDimensions = refineDimensions(dimensions, responses)
  refinedDimensions.clarity_score = Math.min(3, dimensions.clarity_score + 1)

  console.log('> Requirements clarified. Proceeding with workflow selection.\n')

  return { needsClarification: false, dimensions: refinedDimensions }
}

// Generate clarification questions based on missing info
function generateClarificationQuestions(dimensions) {
  const questions = []

  // WHAT: If target is unclear
  if (!dimensions.what.target) {
    questions.push({
      question: "你想要对什么进行操作?",
      header: "目标",
      multiSelect: false,
      options: [
        { label: "特定文件", description: "修改特定的文件或代码" },
        { label: "功能模块", description: "处理整个功能模块" },
        { label: "系统级", description: "架构或系统级变更" },
        { label: "让我指定", description: "我会提供具体说明" }
      ]
    })
  }

  // WHERE: If scope is unknown
  if (dimensions.where.scope === 'unknown' && !dimensions.where.paths?.length) {
    questions.push({
      question: "操作的范围是什么?",
      header: "范围",
      multiSelect: false,
      options: [
        { label: "自动发现", description: "分析代码库后推荐相关位置" },
        { label: "当前目录", description: "只在当前工作目录" },
        { label: "全项目", description: "整个项目范围" },
        { label: "让我指定", description: "我会提供具体路径" }
      ]
    })
  }

  // WHY: If goal is unclear for complex tasks
  if (!dimensions.why.goal && dimensions.what.action !== 'analyze') {
    questions.push({
      question: "这个操作的主要目标是什么?",
      header: "目标",
      multiSelect: false,
      options: [
        { label: "修复问题", description: "解决已知的Bug或错误" },
        { label: "新增功能", description: "添加新的能力或特性" },
        { label: "改进质量", description: "提升性能、可维护性" },
        { label: "代码审查", description: "检查和评估代码" }
      ]
    })
  }

  // HOW: If constraints matter for the task
  if (dimensions.what.action === 'refactor' || dimensions.what.action === 'create') {
    questions.push({
      question: "有什么特殊要求或限制?",
      header: "约束",
      multiSelect: true,
      options: [
        { label: "保持兼容", description: "不破坏现有功能" },
        { label: "最小改动", description: "尽量少修改文件" },
        { label: "包含测试", description: "需要添加测试" },
        { label: "无特殊要求", description: "按最佳实践处理" }
      ]
    })
  }

  return questions
}

// Refine dimensions based on user responses
function refineDimensions(dimensions, responses) {
  const refined = { ...dimensions }

  // Apply user selections to dimensions
  if (responses['目标']) {
    if (responses['目标'] === '特定文件') {
      refined.where.scope = 'file'
    } else if (responses['目标'] === '功能模块') {
      refined.where.scope = 'module'
    } else if (responses['目标'] === '系统级') {
      refined.where.scope = 'system'
    }
  }

  if (responses['范围']) {
    if (responses['范围'] === '全项目') {
      refined.where.scope = 'system'
    } else if (responses['范围'] === '当前目录') {
      refined.where.scope = 'module'
    }
  }

  if (responses['目标']) {
    const goalMapping = {
      '修复问题': 'fix bug',
      '新增功能': 'add feature',
      '改进质量': 'improve quality',
      '代码审查': 'code review'
    }
    refined.why.goal = goalMapping[responses['目标']] || responses['目标']
  }

  if (responses['约束']) {
    const constraints = Array.isArray(responses['约束']) ? responses['约束'] : [responses['约束']]
    refined.how.constraints = constraints.filter(c => c !== '无特殊要求')
  }

  // Update missing dimensions
  refined.missing_dimensions = identifyMissing(refined)

  return refined
}

// Identify still-missing dimensions
function identifyMissing(dimensions) {
  const missing = []
  if (!dimensions.what.target) missing.push('what.target')
  if (dimensions.where.scope === 'unknown') missing.push('where.scope')
  // why and how are optional
  return missing
}

Phase 2: Chain Selection

// Load workflow chains index
const chains = JSON.parse(Read('.claude/skills/ccw/index/workflow-chains.json'))

function selectChain(analysis) {
  const { intent, complexity } = analysis
  
  // Map intent type (from intent-rules.json) to chain ID (from workflow-chains.json)
  const chainMapping = {
    'bugfix': 'bugfix',
    'issue_batch': 'issue',       // intent-rules.json key → chains.json chain ID
    'exploration': 'full',
    'ui_design': 'ui',            // intent-rules.json key → chains.json chain ID
    'tdd': 'tdd',
    'review': 'review-fix',
    'documentation': 'docs',      // intent-rules.json key → chains.json chain ID
    'feature': null               // Use complexity fallback
  }
  
  let chainId = chainMapping[intent.type]
  
  // Fallback to complexity-based selection
  if (!chainId) {
    chainId = chains.chain_selection_rules.complexity_fallback[complexity]
  }
  
  const chain = chains.chains[chainId]
  
  // Handle variants
  let steps = chain.steps
  if (chain.variants) {
    const variant = intent.variant || Object.keys(chain.variants)[0]
    steps = chain.variants[variant].steps
  }
  
  return {
    id: chainId,
    name: chain.name,
    description: chain.description,
    steps,
    complexity: chain.complexity,
    estimated_time: chain.estimated_time
  }
}

Phase 2.5: CLI-Assisted Action Planning

For high complexity tasks, use CLI to plan optimal execution strategy.

// CLI-assisted action planning for complex tasks
async function cliAssistedPlanning(analysis, selectedChain, intentRules) {
  const planConfig = intentRules.cli_action_planning

  // Skip if action planning is disabled
  if (!planConfig || !planConfig.enabled) {
    return { useDefaultChain: true, chain: selectedChain }
  }

  // Determine if CLI planning should be triggered
  const triggers = planConfig.trigger_conditions
  const shouldUseCli =
    analysis.complexity === triggers.complexity_threshold ||
    selectedChain.steps.length >= triggers.step_count_threshold ||
    (analysis.text && analysis.text.length > 200)

  if (!shouldUseCli) {
    return { useDefaultChain: true, chain: selectedChain }
  }

  console.log('### CLI-Assisted Action Planning\n')
  console.log('> Using CLI to optimize execution strategy for complex task...\n')

  // Build CLI prompt for action planning
  const planningPrompt = `
PURPOSE: Plan optimal workflow execution strategy for complex task
TASK:
- Review the selected workflow chain and its steps
- Consider task complexity, dependencies, and potential risks
- Suggest step modifications, additions, or reordering if beneficial
- Identify potential risks and provide mitigations
- Recommend CLI tool injection points for efficiency

MODE: analysis
CONTEXT:
- User Intent: ${analysis.intent.type}${analysis.intent.variant ? ` (${analysis.intent.variant})` : ''}
- Complexity: ${analysis.complexity}
- Selected Chain: ${selectedChain.name}
- Current Steps: ${selectedChain.steps.map((s, i) => `${i + 1}. ${s.command}`).join(', ')}
- User Request: ${analysis.text ? analysis.text.substring(0, 200) : 'N/A'}

EXPECTED: JSON output with structure:
{
  "recommendation": "use_default|modify|upgrade",
  "modified_steps": [
    { "command": "/workflow:xxx", "optional": false, "auto_continue": true, "reason": "why this step" }
  ],
  "cli_injections": [
    { "before_step": 1, "tool": "gemini", "mode": "analysis", "purpose": "pre-analysis" }
  ],
  "reasoning": "explanation of recommendations",
  "risks": ["risk1", "risk2"],
  "mitigations": ["mitigation1", "mitigation2"],
  "suggestions": ["suggestion1", "suggestion2"]
}

RULES: Output ONLY valid JSON. If no modifications needed, set recommendation to "use_default" and leave modified_steps empty.
`

  const tool = planConfig.default_tool || 'gemini'
  const timeout = planConfig.timeout_ms || 60000

  try {
    const escapedPrompt = planningPrompt.replace(/"/g, '\\"').replace(/\n/g, '\\n')
    const cliResult = Bash({
      command: `ccw cli -p "${escapedPrompt}" --tool ${tool} --mode analysis`,
      run_in_background: false,
      timeout: timeout
    })

    // Parse CLI result
    const jsonMatch = cliResult.match(/\{[\s\S]*\}/)
    if (!jsonMatch) {
      throw new Error('No JSON found in CLI response')
    }

    const parsed = JSON.parse(jsonMatch[0])

    // Display planning results
    console.log(`
**CLI Planning Result**:
- **Recommendation**: ${parsed.recommendation}
- **Reasoning**: ${parsed.reasoning}
${parsed.risks && parsed.risks.length > 0 ? `- **Risks**: ${parsed.risks.join(', ')}` : ''}
${parsed.suggestions && parsed.suggestions.length > 0 ? `- **Suggestions**: ${parsed.suggestions.join(', ')}` : ''}
`)

    // Handle step modification
    if (parsed.recommendation === 'modify' && parsed.modified_steps && parsed.modified_steps.length > 0) {
      if (planConfig.allow_step_modification) {
        console.log('> Applying modified execution plan\n')
        return {
          useDefaultChain: false,
          chain: {
            ...selectedChain,
            steps: parsed.modified_steps
          },
          reasoning: parsed.reasoning,
          risks: parsed.risks,
          cliInjections: parsed.cli_injections,
          source: 'cli-planned'
        }
      } else {
        console.log('> Step modification disabled, using default chain with suggestions\n')
      }
    }

    // Handle upgrade recommendation
    if (parsed.recommendation === 'upgrade') {
      console.log('> CLI recommends upgrading to a more comprehensive workflow\n')
      // Could select a more complex chain here
    }

    return {
      useDefaultChain: true,
      chain: selectedChain,
      suggestions: parsed.suggestions,
      risks: parsed.risks,
      cliInjections: parsed.cli_injections,
      source: 'cli-reviewed'
    }
  } catch (error) {
    console.log(`> CLI planning failed: ${error.message}`)
    console.log('> Using default chain without optimization\n')

    return { useDefaultChain: true, chain: selectedChain, source: 'default' }
  }
}

Phase 3: User Confirmation

function confirmChain(selectedChain, analysis) {
  // Skip confirmation for simple chains
  if (selectedChain.steps.length <= 2 && analysis.complexity === 'low') {
    return selectedChain
  }
  
  console.log(`
## CCW Workflow Selection

**Task**: ${analysis.text.substring(0, 80)}...
**Intent**: ${analysis.intent.type}${analysis.intent.variant ? ` (${analysis.intent.variant})` : ''}
**Complexity**: ${analysis.complexity}

**Selected Chain**: ${selectedChain.name}
**Description**: ${selectedChain.description}
**Estimated Time**: ${selectedChain.estimated_time}

**Steps**:
${selectedChain.steps.map((s, i) => `${i + 1}. ${s.command}${s.optional ? ' (optional)' : ''}`).join('\n')}
`)
  
  const response = AskUserQuestion({
    questions: [{
      question: `Proceed with ${selectedChain.name}?`,
      header: "Confirm",
      multiSelect: false,
      options: [
        { label: "Proceed", description: `Execute ${selectedChain.steps.length} steps` },
        { label: "Rapid", description: "Use lite-plan → lite-execute" },
        { label: "Full", description: "Use brainstorm → plan → execute" },
        { label: "Manual", description: "Specify commands manually" }
      ]
    }]
  })
  
  // Handle alternative selection
  if (response.Confirm === 'Rapid') {
    return selectChain({ intent: { type: 'feature' }, complexity: 'low' })
  }
  if (response.Confirm === 'Full') {
    return chains.chains['full']
  }
  if (response.Confirm === 'Manual') {
    return null  // User will specify
  }
  
  return selectedChain
}

Phase 4: TODO Tracking Setup

function setupTodoTracking(chain, analysis) {
  const todos = chain.steps.map((step, index) => ({
    content: `[${index + 1}/${chain.steps.length}] ${step.command}`,
    status: index === 0 ? 'in_progress' : 'pending',
    activeForm: `Executing ${step.command}`
  }))
  
  // Add header todo
  todos.unshift({
    content: `CCW: ${chain.name} (${chain.steps.length} steps)`,
    status: 'in_progress',
    activeForm: `Running ${chain.name} workflow`
  })
  
  TodoWrite({ todos })
  
  return {
    chain,
    currentStep: 0,
    todos
  }
}

Phase 5: Execution Loop

async function executeChain(execution, analysis) {
  const { chain, todos } = execution
  let currentStep = 0
  
  while (currentStep < chain.steps.length) {
    const step = chain.steps[currentStep]
    
    // Update TODO: mark current as in_progress
    const updatedTodos = todos.map((t, i) => ({
      ...t,
      status: i === 0 
        ? 'in_progress' 
        : i === currentStep + 1 
          ? 'in_progress' 
          : i <= currentStep 
            ? 'completed' 
            : 'pending'
    }))
    TodoWrite({ todos: updatedTodos })
    
    console.log(`\n### Step ${currentStep + 1}/${chain.steps.length}: ${step.command}\n`)
    
    // Check for confirmation requirement
    if (step.confirm_before) {
      const proceed = AskUserQuestion({
        questions: [{
          question: `Ready to execute ${step.command}?`,
          header: "Step",
          multiSelect: false,
          options: [
            { label: "Execute", description: "Run this step" },
            { label: "Skip", description: "Skip to next step" },
            { label: "Abort", description: "Stop workflow" }
          ]
        }]
      })
      
      if (proceed.Step === 'Skip') {
        currentStep++
        continue
      }
      if (proceed.Step === 'Abort') {
        break
      }
    }
    
    // Execute the command
    const args = analysis.text
    SlashCommand(step.command, { args })
    
    // Mark step as completed
    updatedTodos[currentStep + 1].status = 'completed'
    TodoWrite({ todos: updatedTodos })
    
    currentStep++
    
    // Check auto_continue
    if (!step.auto_continue && currentStep < chain.steps.length) {
      console.log(`
Step completed. Next: ${chain.steps[currentStep].command}
Type "continue" to proceed or specify different action.
`)
      // Wait for user input before continuing
      break
    }
  }
  
  // Final status
  if (currentStep >= chain.steps.length) {
    const finalTodos = todos.map(t => ({ ...t, status: 'completed' }))
    TodoWrite({ todos: finalTodos })
    
    console.log(`\n✓ ${chain.name} workflow completed (${chain.steps.length} steps)`)
  }
  
  return { completed: currentStep, total: chain.steps.length }
}

Main Orchestration Entry

async function ccwOrchestrate(userInput) {
  console.log('## CCW Orchestrator\n')

  // Phase 1: Analyze input (rule-based, fast path)
  const ruleBasedAnalysis = analyzeInput(userInput)

  // Handle explicit command passthrough
  if (ruleBasedAnalysis.passthrough) {
    console.log(`Direct command: ${ruleBasedAnalysis.command}`)
    return SlashCommand(ruleBasedAnalysis.command)
  }

  // Phase 1.5: CLI-Assisted Classification (smart path for ambiguous inputs)
  const analysis = await cliAssistedClassification(userInput, ruleBasedAnalysis, intentRules)

  // Display classification source
  if (analysis.source === 'cli') {
    console.log(`
### Classification Summary
- **Source**: CLI-Assisted (${analysis.confidence ? (analysis.confidence * 100).toFixed(0) + '% confidence' : 'semantic analysis'})
- **Intent**: ${analysis.intent.type}${analysis.intent.variant ? ` (${analysis.intent.variant})` : ''}
- **Complexity**: ${analysis.complexity}
${analysis.cliReasoning ? `- **Reasoning**: ${analysis.cliReasoning}` : ''}
`)
  } else {
    console.log(`
### Classification Summary
- **Source**: Rule-Based (fast path)
- **Intent**: ${analysis.intent.type}${analysis.intent.variant ? ` (${analysis.intent.variant})` : ''}
- **Complexity**: ${analysis.complexity}
`)
  }

  // Phase 2: Select chain
  const selectedChain = selectChain(analysis)

  // Phase 2.5: CLI-Assisted Action Planning (for high complexity)
  const planningResult = await cliAssistedPlanning(analysis, selectedChain, intentRules)
  const optimizedChain = planningResult.chain

  // Display planning result if CLI was used
  if (planningResult.source === 'cli-planned' || planningResult.source === 'cli-reviewed') {
    console.log(`
### Planning Summary
- **Source**: CLI-Assisted
${planningResult.reasoning ? `- **Reasoning**: ${planningResult.reasoning}` : ''}
${planningResult.risks && planningResult.risks.length > 0 ? `- **Identified Risks**: ${planningResult.risks.join(', ')}` : ''}
${planningResult.suggestions && planningResult.suggestions.length > 0 ? `- **Suggestions**: ${planningResult.suggestions.join(', ')}` : ''}
`)
  }

  // Phase 3: Confirm (for complex workflows)
  const confirmedChain = confirmChain(optimizedChain, analysis)
  if (!confirmedChain) {
    console.log('Manual mode selected. Specify commands directly.')
    return
  }

  // Phase 4: Setup TODO tracking
  const execution = setupTodoTracking(confirmedChain, analysis)

  // Phase 5: Execute
  const result = await executeChain(execution, analysis)

  return result
}

Decision Matrix

Intent Complexity Chain Steps
bugfix (standard) * bugfix lite-fix
bugfix (hotfix) * bugfix lite-fix --hotfix
issue * issue plan → queue → execute
exploration * full brainstorm → plan → execute
ui (explore) * ui ui-design:explore → sync → plan → execute
ui (imitate) * ui ui-design:imitate → sync → plan → execute
tdd * tdd tdd-plan → execute → tdd-verify
review * review-fix review-session-cycle → review-fix
docs low docs update-related
docs medium+ docs docs → execute
feature low rapid lite-plan → lite-execute
feature medium coupled plan → verify → execute
feature high full brainstorm → plan → execute

Continuation Commands

After each step pause:

User Input Action
continue Execute next step
skip Skip current step
abort Stop workflow
/workflow:* Execute specific command
Natural language Re-analyze and potentially switch chains