From 24efef7f179a27ae3c5890ca516171449969ebc2 Mon Sep 17 00:00:00 2001 From: catlog22 Date: Sat, 24 Jan 2026 13:43:47 +0800 Subject: [PATCH] feat: Add main workflow orchestrator (ccw) with intent analysis and command execution - Implemented the ccw command as a main workflow orchestrator. - Added a 5-phase workflow including intent analysis, requirement clarification, workflow selection, user confirmation, and command execution. - Developed functions for analyzing user input, selecting workflows, and executing command chains. - Integrated TODO tracking for command execution progress. - Created comprehensive tests for the CommandRegistry, covering YAML parsing, command retrieval, and error handling. --- .claude/commands/ccw.md | 664 +++++++++++++++++ .claude/skills/ccw-coordinator/README.md | 161 ----- .claude/skills/ccw-coordinator/SKILL.md | 411 ----------- .../phases/actions/action-abort.md | 9 - .../phases/actions/action-command-build.md | 40 -- .../phases/actions/action-command-execute.md | 349 --------- .../actions/action-command-selection.md | 48 -- .../phases/actions/action-complete.md | 25 - .../phases/actions/action-init.md | 26 - .../ccw-coordinator/phases/orchestrator.md | 59 -- .../ccw-coordinator/phases/state-schema.md | 66 -- .../skills/ccw-coordinator/skill-config.json | 66 -- .../ccw-coordinator/specs/command-library.md | 169 ----- .../ccw-coordinator/specs/prompt-templates.md | 544 -------------- .claude/skills/ccw-coordinator/specs/specs.md | 371 ---------- .../skills/ccw-coordinator/tools/README.md | 117 --- .../ccw-coordinator/tools/chain-validate.cjs | 320 --------- .../tools/command-registry.cjs | 255 ------- .claude/skills/ccw/SKILL.md | 522 -------------- .claude/skills/ccw/command.json | 641 ----------------- ccw/src/tools/command-registry.test.ts | 669 ++++++++++++++++++ 21 files changed, 1333 insertions(+), 4199 deletions(-) create mode 100644 .claude/commands/ccw.md delete mode 100644 .claude/skills/ccw-coordinator/README.md delete mode 100644 .claude/skills/ccw-coordinator/SKILL.md delete mode 100644 .claude/skills/ccw-coordinator/phases/actions/action-abort.md delete mode 100644 .claude/skills/ccw-coordinator/phases/actions/action-command-build.md delete mode 100644 .claude/skills/ccw-coordinator/phases/actions/action-command-execute.md delete mode 100644 .claude/skills/ccw-coordinator/phases/actions/action-command-selection.md delete mode 100644 .claude/skills/ccw-coordinator/phases/actions/action-complete.md delete mode 100644 .claude/skills/ccw-coordinator/phases/actions/action-init.md delete mode 100644 .claude/skills/ccw-coordinator/phases/orchestrator.md delete mode 100644 .claude/skills/ccw-coordinator/phases/state-schema.md delete mode 100644 .claude/skills/ccw-coordinator/skill-config.json delete mode 100644 .claude/skills/ccw-coordinator/specs/command-library.md delete mode 100644 .claude/skills/ccw-coordinator/specs/prompt-templates.md delete mode 100644 .claude/skills/ccw-coordinator/specs/specs.md delete mode 100644 .claude/skills/ccw-coordinator/tools/README.md delete mode 100644 .claude/skills/ccw-coordinator/tools/chain-validate.cjs delete mode 100644 .claude/skills/ccw-coordinator/tools/command-registry.cjs delete mode 100644 .claude/skills/ccw/SKILL.md delete mode 100644 .claude/skills/ccw/command.json create mode 100644 ccw/src/tools/command-registry.test.ts diff --git a/.claude/commands/ccw.md b/.claude/commands/ccw.md new file mode 100644 index 00000000..607d8bf8 --- /dev/null +++ b/.claude/commands/ccw.md @@ -0,0 +1,664 @@ +--- +name: ccw +description: Main workflow orchestrator - analyze intent, select workflow, execute command chain in main process +argument-hint: "\"task description\"" +allowed-tools: SlashCommand(*), TodoWrite(*), AskUserQuestion(*), Read(*), Grep(*), Glob(*) +--- + +# CCW Command - Main Workflow Orchestrator + +Main process workflow orchestrator: intent analysis → workflow selection → command chain execution. + +**Execution Model**: Execute command chain directly in main process using SlashCommand. + +## 5-Phase Workflow + +### Phase 1: Analyze Intent + +Analyze user input to extract task intent and characteristics. + +```javascript +function analyzeIntent(input) { + return { + goal: extractGoal(input), // Main objective + scope: extractScope(input), // Affected scope + constraints: extractConstraints(input), // Constraints + task_type: detectTaskType(input), // Task type + complexity: assessComplexity(input), // Complexity level + clarity_score: calculateClarity(input) // Requirement clarity (0-3) + }; +} + +// Task type detection (priority order) +function detectTaskType(text) { + if (/urgent|production|critical/.test(text) && /fix|bug/.test(text)) return 'bugfix-hotfix'; + if (/fix|bug|error|crash|fail|debug/.test(text)) return 'bugfix'; + if (/issues?|batch/.test(text) && /fix|resolve/.test(text)) return 'issue-batch'; + if (/uncertain|explore|research|what if/.test(text)) return 'exploration'; + if (/multi-perspective|compare|cross-verify/.test(text)) return 'multi-perspective'; + if (/quick|simple|small/.test(text) && /feature|function/.test(text)) return 'quick-task'; + if (/ui|design|component|style/.test(text)) return 'ui-design'; + if (/tdd|test-driven|test first/.test(text)) return 'tdd'; + if (/test fail|fix test|failing test/.test(text)) return 'test-fix'; + if (/review|code review/.test(text)) return 'review'; + if (/docs|documentation|readme/.test(text)) return 'documentation'; + return 'feature'; +} + +// Complexity assessment +function assessComplexity(text) { + let score = 0; + if (/refactor|migrate|architect|system/.test(text)) score += 2; + if (/multiple|across|all|entire/.test(text)) score += 2; + if (/integrate|api|database/.test(text)) score += 1; + if (/security|performance|scale/.test(text)) score += 1; + return score >= 4 ? 'high' : score >= 2 ? 'medium' : 'low'; +} + +// Requirement clarity calculation +function calculateClarity(text) { + let score = 0; + if (/create|fix|refactor|optimize|analyze/.test(text)) score += 0.5; // Has action + if (/\.(ts|js|py|java|go|md)/.test(text)) score += 0.5; // Has file path + if (/for|because|to achieve/.test(text)) score += 0.5; // Has goal + if (/must|should|no|without/.test(text)) score += 0.5; // Has constraints + if (/uncertain|maybe|how to/.test(text)) score -= 0.5; // Has uncertainty + return Math.max(0, Math.min(3, score)); +} +``` + +**Display to user**: +``` +Intent Analysis: + Type: [task_type] + Goal: [goal] + Complexity: [complexity] + Clarity: [clarity_score]/3 +``` + +--- + +### Phase 1.5: Requirement Clarification (if needed) + +When clarity_score < 2, clarify requirements through questions. + +```javascript +async function clarifyRequirements(analysis) { + if (analysis.clarity_score >= 2) return analysis; + + const questions = generateClarificationQuestions(analysis); + const answers = await AskUserQuestion({ questions }); + + // Update analysis based on user answers + return updateAnalysis(analysis, answers); +} + +function generateClarificationQuestions(analysis) { + const questions = []; + + if (!analysis.goal) { + questions.push({ + question: "What is the main goal of this task?", + header: "Goal", + options: [ + { label: "Create new feature", description: "Implement new functionality" }, + { label: "Fix issue", description: "Fix bugs or errors" }, + { label: "Optimize/Improve", description: "Refactor or performance optimization" }, + { label: "Analyze/Research", description: "Explore or analyze code" } + ], + multiSelect: false + }); + } + + if (!analysis.scope || analysis.scope.length === 0) { + questions.push({ + question: "What is the scope of this task?", + header: "Scope", + options: [ + { label: "Single file", description: "Modify single file" }, + { label: "Single module", description: "One functional module" }, + { label: "Multiple modules", description: "Cross-module changes" }, + { label: "Entire system", description: "System-level changes" } + ], + multiSelect: false + }); + } + + if (!analysis.constraints || analysis.constraints.length === 0) { + questions.push({ + question: "Any special requirements or constraints?", + header: "Constraints", + options: [ + { label: "No constraints", description: "No special requirements" }, + { label: "Backward compatible", description: "Maintain compatibility" }, + { label: "Skip tests", description: "No test execution needed" }, + { label: "Urgent hotfix", description: "Production issue" } + ], + multiSelect: true + }); + } + + return questions; +} +``` + +--- + +### Phase 2: Select Workflow & Build Command Chain + +Select workflow level and build command chain based on intent analysis. + +```javascript +function selectWorkflow(analysis) { + const { task_type, complexity, constraints } = analysis; + + // Level mapping + const levelMap = { + 'bugfix-hotfix': { level: 2, flow: 'bugfix.hotfix' }, + 'bugfix': { level: 2, flow: 'bugfix.standard' }, + 'issue-batch': { level: 'Issue', flow: 'issue' }, + 'exploration': { level: 4, flow: 'full' }, + 'multi-perspective': { level: 2, flow: 'multi-cli-plan' }, + 'quick-task': { level: 1, flow: 'lite-lite-lite' }, + 'ui-design': { level: complexity === 'high' ? 4 : 3, flow: 'ui' }, + 'tdd': { level: 3, flow: 'tdd' }, + 'test-fix': { level: 3, flow: 'test-fix-gen' }, + 'review': { level: 3, flow: 'review-fix' }, + 'documentation': { level: 2, flow: 'docs' }, + 'feature': { level: complexity === 'high' ? 3 : 2, flow: complexity === 'high' ? 'coupled' : 'rapid' } + }; + + const selected = levelMap[task_type] || levelMap['feature']; + + return buildCommandChain(selected, analysis); +} + +// Build command chain (port-based matching) +function buildCommandChain(workflow, analysis) { + const chains = { + // Level 1 - Rapid + 'lite-lite-lite': [ + { cmd: '/workflow:lite-lite-lite', args: `"${analysis.goal}"` } + ], + + // Level 2 - Lightweight + 'rapid': [ + { cmd: '/workflow:lite-plan', args: `"${analysis.goal}"` }, + { cmd: '/workflow:lite-execute', args: '--in-memory' }, + ...(analysis.constraints?.includes('skip-tests') ? [] : [ + { cmd: '/workflow:test-cycle-execute', args: '' } + ]) + ], + + 'bugfix.standard': [ + { cmd: '/workflow:lite-fix', args: `"${analysis.goal}"` }, + ...(analysis.constraints?.includes('skip-tests') ? [] : [ + { cmd: '/workflow:test-cycle-execute', args: '' } + ]) + ], + + 'bugfix.hotfix': [ + { cmd: '/workflow:lite-fix', args: `--hotfix "${analysis.goal}"` } + ], + + 'multi-cli-plan': [ + { cmd: '/workflow:multi-cli-plan', args: `"${analysis.goal}"` }, + { cmd: '/workflow:lite-execute', args: '--in-memory' }, + ...(analysis.constraints?.includes('skip-tests') ? [] : [ + { cmd: '/workflow:test-cycle-execute', args: '' } + ]) + ], + + 'docs': [ + { cmd: '/workflow:lite-plan', args: `"${analysis.goal}"` }, + { cmd: '/workflow:lite-execute', args: '--in-memory' } + ], + + // Level 3 - Standard + 'coupled': [ + { cmd: '/workflow:plan', args: `"${analysis.goal}"` }, + { cmd: '/workflow:plan-verify', args: '' }, + { cmd: '/workflow:execute', args: '' }, + { cmd: '/workflow:review-session-cycle', args: '' }, + ...(analysis.constraints?.includes('skip-tests') ? [] : [ + { cmd: '/workflow:test-cycle-execute', args: '' } + ]) + ], + + 'tdd': [ + { cmd: '/workflow:tdd-plan', args: `"${analysis.goal}"` }, + { cmd: '/workflow:execute', args: '' }, + { cmd: '/workflow:tdd-verify', args: '' } + ], + + 'test-fix-gen': [ + { cmd: '/workflow:test-fix-gen', args: `"${analysis.goal}"` }, + { cmd: '/workflow:test-cycle-execute', args: '' } + ], + + 'review-fix': [ + { cmd: '/workflow:review', args: '' }, + { cmd: '/workflow:review-fix', args: '' }, + { cmd: '/workflow:test-cycle-execute', args: '' } + ], + + 'ui': [ + { cmd: '/workflow:ui-design:explore-auto', args: `"${analysis.goal}"` }, + { cmd: '/workflow:plan', args: '' }, + { cmd: '/workflow:execute', args: '' } + ], + + // Level 4 - Brainstorm + 'full': [ + { cmd: '/workflow:brainstorm:auto-parallel', args: `"${analysis.goal}"` }, + { cmd: '/workflow:plan', args: '' }, + { cmd: '/workflow:plan-verify', args: '' }, + { cmd: '/workflow:execute', args: '' }, + { cmd: '/workflow:test-cycle-execute', args: '' } + ], + + // Issue Workflow + 'issue': [ + { cmd: '/issue:discover', args: '' }, + { cmd: '/issue:plan', args: '--all-pending' }, + { cmd: '/issue:queue', args: '' }, + { cmd: '/issue:execute', args: '' } + ] + }; + + return chains[workflow.flow] || chains['rapid']; +} +``` + +**Display to user**: +``` +Selected Workflow: Level [X] - [flow_name] + +Pipeline: +requirement -> lite-plan -> plan -> lite-execute -> code -> test-cycle-execute -> test-passed + +Commands: +1. /workflow:lite-plan +2. /workflow:lite-execute +3. /workflow:test-cycle-execute + +Proceed? [Confirm / Adjust / Cancel] +``` + +--- + +### Phase 3: User Confirmation (Optional) + +Get user confirmation or adjust command chain. + +```javascript +async function getUserConfirmation(chain, analysis) { + const response = await AskUserQuestion({ + questions: [{ + question: "Execute this command chain?", + header: "Confirm", + options: [ + { label: "Confirm", description: "Start execution" }, + { label: "Adjust", description: "Modify commands" }, + { label: "Cancel", description: "Abort" } + ], + multiSelect: false + }] + }); + + if (response.Confirm === "Cancel") { + throw new Error("User cancelled"); + } + + if (response.Confirm === "Adjust") { + return await adjustChain(chain); + } + + return chain; +} + +async function adjustChain(chain) { + // Show current chain, allow user to remove or reorder + const adjustOptions = chain.map((step, i) => ({ + label: `${i + 1}. ${step.cmd}`, + description: step.args || "No arguments" + })); + + const response = await AskUserQuestion({ + questions: [{ + question: "Select commands to keep (multi-select)", + header: "Adjust", + options: adjustOptions, + multiSelect: true + }] + }); + + // Rebuild chain based on user selection + return rebuildChain(chain, response); +} +``` + +--- + +### Phase 4: Setup TODO Tracking + +Initialize TodoWrite to track command execution progress. + +```javascript +function setupTodoTracking(chain, workflow) { + const todos = chain.map((step, i) => ({ + content: `CCW:${workflow}: [${i + 1}/${chain.length}] ${step.cmd}`, + status: i === 0 ? 'in_progress' : 'pending', + activeForm: `Executing ${step.cmd}` + })); + + TodoWrite({ todos }); +} +``` + +**Display to user**: +``` +TODO Tracking Initialized: +-> CCW:rapid: [1/3] /workflow:lite-plan + CCW:rapid: [2/3] /workflow:lite-execute + CCW:rapid: [3/3] /workflow:test-cycle-execute +``` + +--- + +### Phase 5: Execute Command Chain + +Execute commands sequentially, update TODO status. + +```javascript +async function executeCommandChain(chain, workflow, analysis) { + let previousResult = null; + + for (let i = 0; i < chain.length; i++) { + const step = chain[i]; + + console.log(`\n[${i + 1}/${chain.length}] Executing: ${step.cmd}`); + + try { + // Assemble full command + const fullCommand = assembleCommand(step, previousResult, analysis); + + // Execute via SlashCommand (in main process) + const result = await SlashCommand({ + command: fullCommand + }); + + // Record result + previousResult = { + command: step.cmd, + success: true, + output: result + }; + + // Update TODO status + updateTodoStatus(i, chain.length, workflow, 'completed'); + + console.log(`Done: ${step.cmd}`); + + } catch (error) { + console.error(`Failed: ${step.cmd}: ${error.message}`); + + // Ask user how to handle error + const action = await handleError(step, error, i, chain.length); + + if (action === 'retry') { + i--; // Retry current step + } else if (action === 'abort') { + console.log("Workflow aborted"); + return { success: false, error: error.message, completed: i }; + } + // 'skip' - continue to next step + } + } + + console.log("\nWorkflow completed successfully!"); + return { success: true, completed: chain.length }; +} + +// Assemble command arguments +function assembleCommand(step, previousResult, analysis) { + let command = step.cmd; + + // Dynamically assemble arguments based on command type + if (step.args) { + // Use existing arguments + command += ` ${step.args}`; + } else if (previousResult?.session_id) { + // Use previous step's session + command += ` --session="${previousResult.session_id}"`; + } else if (previousResult?.plan_exists) { + // execute command uses --resume-session + if (step.cmd.includes('execute')) { + command += ` --resume-session="${previousResult.session_id}"`; + } + } + + return command; +} + +// Update TODO status +function updateTodoStatus(currentIndex, total, workflow, status) { + const todos = getAllCurrentTodos(); // Get all current todos + + const updatedTodos = todos.map((todo, i) => { + if (todo.content.startsWith(`CCW:${workflow}:`)) { + const stepIndex = extractStepIndex(todo.content); + if (stepIndex === currentIndex + 1) { + return { ...todo, status }; + } + if (stepIndex === currentIndex + 2 && status === 'completed') { + return { ...todo, status: 'in_progress' }; + } + } + return todo; + }); + + TodoWrite({ todos: updatedTodos }); +} + +// Error handling +async function handleError(step, error, index, total) { + const response = await AskUserQuestion({ + questions: [{ + question: `Command ${step.cmd} failed. How to proceed?`, + header: "Error", + options: [ + { label: "Retry", description: "Re-execute this command" }, + { label: "Skip", description: "Skip and continue next" }, + { label: "Abort", description: "Stop execution" } + ], + multiSelect: false + }] + }); + + const actionMap = { + "Retry": "retry", + "Skip": "skip", + "Abort": "abort" + }; + + return actionMap[response.Error] || "abort"; +} +``` + +--- + +## Execution Flow Summary + +``` +User Input + | +Phase 1: Analyze Intent + |-- Extract: goal, scope, constraints, task_type, complexity, clarity + +-- If clarity < 2 -> Phase 1.5: Clarify Requirements + | +Phase 2: Select Workflow & Build Chain + |-- Map task_type -> Level (1/2/3/4/Issue) + |-- Select flow based on complexity + +-- Build command chain (port-based) + | +Phase 3: User Confirmation (optional) + |-- Show pipeline visualization + +-- Allow adjustment + | +Phase 4: Setup TODO Tracking + +-- Create todos with CCW prefix + | +Phase 5: Execute Command Chain + |-- For each command: + | |-- Assemble full command + | |-- Execute via SlashCommand + | |-- Update TODO status + | +-- Handle errors (retry/skip/abort) + +-- Return workflow result +``` + +--- + +## Pipeline Examples + +### Simple Feature (Level 2 - Rapid) +``` +Input: "Add user profile API endpoint" + +Analysis: + Type: feature + Complexity: low + Level: 2 + +Pipeline: +requirement -> lite-plan -> plan -> lite-execute -> code -> test-cycle-execute -> test-passed + +Execution: +1. SlashCommand("/workflow:lite-plan \"Add user profile API endpoint\"") +2. SlashCommand("/workflow:lite-execute --in-memory") +3. SlashCommand("/workflow:test-cycle-execute") +``` + +### Bug Fix (Level 2 - Bugfix) +``` +Input: "Fix login timeout issue" + +Analysis: + Type: bugfix + Complexity: low + Level: 2 + +Pipeline: +bug-report -> lite-fix -> fixed-code -> test-cycle-execute -> test-passed + +Execution: +1. SlashCommand("/workflow:lite-fix \"Fix login timeout issue\"") +2. SlashCommand("/workflow:test-cycle-execute") +``` + +### Complex Feature (Level 3 - Coupled) +``` +Input: "Implement OAuth2 authentication system" + +Analysis: + Type: feature + Complexity: high + Level: 3 + +Pipeline: +requirement -> plan -> detailed-plan -> plan-verify -> verified-plan -> execute -> code + -> review-session-cycle -> review-passed -> test-cycle-execute -> test-passed + +Execution: +1. SlashCommand("/workflow:plan \"Implement OAuth2...\"") +2. SlashCommand("/workflow:plan-verify") +3. SlashCommand("/workflow:execute") +4. SlashCommand("/workflow:review-session-cycle") +5. SlashCommand("/workflow:test-cycle-execute") +``` + +### TDD Workflow (Level 3) +``` +Input: "Implement authentication with TDD" + +Analysis: + Type: tdd + Complexity: medium + Level: 3 + +Pipeline: +requirement -> tdd-plan -> tdd-tasks -> execute -> code -> tdd-verify -> tdd-verified + +Execution: +1. SlashCommand("/workflow:tdd-plan \"Implement authentication...\"") +2. SlashCommand("/workflow:execute") +3. SlashCommand("/workflow:tdd-verify") +``` + +### Exploration (Level 4 - Brainstorm) +``` +Input: "Uncertain about real-time notification architecture" + +Analysis: + Type: exploration + Clarity: 1.5 -> needs clarification + Level: 4 + +Pipeline: +exploration-topic -> brainstorm:auto-parallel -> analysis -> plan -> detailed-plan + -> execute -> code -> test-cycle-execute -> test-passed + +Execution: +1. SlashCommand("/workflow:brainstorm:auto-parallel \"Real-time notification...\"") +2. SlashCommand("/workflow:plan") +3. SlashCommand("/workflow:plan-verify") +4. SlashCommand("/workflow:execute") +5. SlashCommand("/workflow:test-cycle-execute") +``` + +--- + +## Key Design Principles + +1. **Main Process Execution** - Use SlashCommand in main process, no external CLI +2. **Intent-Driven** - Auto-select workflow based on task intent +3. **Port-Based Chaining** - Build command chain using port matching +4. **Progressive Clarification** - Low clarity triggers clarification phase +5. **TODO Tracking** - Use CCW prefix to isolate workflow todos +6. **Error Resilient** - Support retry/skip/abort error handling +7. **User Control** - Optional user confirmation at each phase + +--- + +## Difference from ccw-coordinator + +| Aspect | ccw | ccw-coordinator | +|--------|-----|-----------------| +| **Execution** | SlashCommand (main process) | Bash + ccw cli (external) | +| **Workflow Selection** | Auto by intent | Manual chain building | +| **Intent Analysis** | 5-phase with clarity check | 3-phase requirement analysis | +| **Error Handling** | Interactive retry/skip/abort | Retry/skip/abort via AskUser | +| **State Tracking** | TodoWrite only | state.json + TodoWrite | +| **Use Case** | Auto workflow selection | Manual command orchestration | + +--- + +## Usage + +```bash +# Auto-select workflow +ccw "Add user authentication" + +# Complex requirement (triggers clarification) +ccw "Optimize system performance" + +# Bug fix +ccw "Fix memory leak in WebSocket handler" + +# TDD development +ccw "Implement user registration with TDD" + +# Exploratory task +ccw "Uncertain about architecture for real-time notifications" +``` diff --git a/.claude/skills/ccw-coordinator/README.md b/.claude/skills/ccw-coordinator/README.md deleted file mode 100644 index 3a53578f..00000000 --- a/.claude/skills/ccw-coordinator/README.md +++ /dev/null @@ -1,161 +0,0 @@ -# CCW Coordinator - -交互式命令编排工具:选择命令 → 形成命令链 → 通过 ccw cli 调用 Claude 循环执行 - -## 核心特性 - -- ✅ **仅支持 Claude**:所有执行通过 `ccw cli --tool claude` 调用 -- ✅ **命令在提示词中**:提示词直接包含完整命令调用(如 `/workflow:lite-plan --yes "任务"`) -- ✅ **智能参数组装**:根据命令 YAML 头自动生成正确参数 -- ✅ **循环执行**:每次根据上次完成情况组装下个命令的提示词 - -## 使用 - -``` -/ccw-coordinator -或 -/coordinator -``` - -## 流程 - -1. **用户描述任务**(如"实现用户注册功能") -2. **Claude 推荐命令链**(如 lite-plan → lite-execute → test-cycle-execute) -3. **用户确认或调整**(可以修改顺序或添加/删除命令) -4. **循环执行**: - - 第1个命令:`ccw cli -p "任务: xxx\n/workflow:lite-plan --yes \"xxx\"" --tool claude` - - 第2个命令:`ccw cli -p "任务: xxx\n前序: ...\n/workflow:lite-execute --yes --in-memory" --tool claude` - - ... 以此类推 -5. **生成报告**(保存到 `.workflow/.ccw-coordinator/{timestamp}/`) - -## 示例场景 - -### 标准开发流程 - -**任务**:实现用户注册功能 - -**推荐命令链**: -``` -1. /workflow:lite-plan -2. /workflow:lite-execute -3. /workflow:test-cycle-execute -``` - -**执行过程**: -- `lite-plan` → 生成 IMPL_PLAN.md 和探索文件 -- `lite-execute --in-memory` → 使用规划执行任务 -- `test-cycle-execute --session="WFS-xxx"` → 运行测试 - -### Bug 修复 - -**任务**:修复登录页面验证失败问题 - -**推荐命令链**: -``` -1. /workflow:lite-fix -``` - -**执行过程**: -- `lite-fix --yes "修复登录页面验证失败问题"` → 独立修复(不依赖规划) - -### 完整规划流程 - -**任务**:重构认证模块 - -**推荐命令链**: -``` -1. /workflow:plan -2. /workflow:execute -3. /workflow:review-session-cycle -``` - -**执行过程**: -- `plan` → 生成完整规划文档 -- `execute --resume-session="WFS-xxx"` → 执行规划 -- `review-session-cycle --session="WFS-xxx"` → 审查改动 - -## 提示词示例 - -### 第一个命令 - -``` -任务: 实现用户注册功能,包括邮箱验证和密码加密 - -/workflow:lite-plan --yes "实现用户注册功能,包括邮箱验证和密码加密" -``` - -### 第二个命令 - -``` -任务: 实现用户注册功能,包括邮箱验证和密码加密 - -前序完成: -- /workflow:lite-plan: WFS-register-2025-01-24 (IMPL_PLAN.md, exploration-architecture.json) - -/workflow:lite-execute --yes --in-memory -``` - -### 第三个命令 - -``` -任务: 实现用户注册功能,包括邮箱验证和密码加密 - -前序完成: -- /workflow:lite-plan: WFS-register-2025-01-24 (IMPL_PLAN.md) -- /workflow:lite-execute: WFS-register-2025-01-24 (完成) - -/workflow:test-cycle-execute --yes --session="WFS-register-2025-01-24" -``` - -## 架构说明 - -``` -用户触发: /ccw-coordinator - ↓ -Orchestrator (主流程状态机) - ├─ action-init (初始化会话) - ├─ action-command-selection (选择命令,Claude 推荐) - ├─ action-command-build (调整命令链,可选) - ├─ action-command-execute (循环调用 ccw cli) - │ └─ for each command: - │ 1. 组装提示词 - │ 2. ccw cli --tool claude - │ 3. 解析产物 - │ 4. 更新状态 - └─ action-complete (生成报告) -``` - -## 输出结构 - -``` -.workflow/.ccw-coordinator/{timestamp}/ -├── state.json # 会话状态(命令链、执行结果) -├── command-chain.json # 编排的完整命令链 -├── execution-log.md # 执行日志 -├── final-summary.md # 最终报告 -├── commands/ # 各命令执行详情 -│ ├── 01-workflow-lite-plan.log -│ ├── 02-workflow-lite-execute.log -│ └── 03-workflow-test-cycle-execute.log -└── logs/ # 错误和警告 - ├── errors.log - └── warnings.log -``` - -## 文件说明 - -| 文件 | 用途 | -|------|------| -| SKILL.md | Skill 入口和架构说明 | -| phases/orchestrator.md | 编排器实现(状态机决策逻辑) | -| phases/state-schema.md | 状态结构定义 | -| phases/actions/action-command-execute.md | **核心**:循环执行逻辑 | -| specs/specs.md | 命令库、验证规则、注册表 | -| tools/chain-validate.cjs | 命令链验证工具 | -| tools/command-registry.cjs | 命令注册表(按需提取 YAML 头) | - -## 详细文档 - -- 架构和设计原则 → **SKILL.md** -- 执行逻辑和提示词组装 → **phases/actions/action-command-execute.md** -- 命令库和验证规则 → **specs/specs.md** diff --git a/.claude/skills/ccw-coordinator/SKILL.md b/.claude/skills/ccw-coordinator/SKILL.md deleted file mode 100644 index bd0188ec..00000000 --- a/.claude/skills/ccw-coordinator/SKILL.md +++ /dev/null @@ -1,411 +0,0 @@ ---- -name: ccw-coordinator -description: Interactive command orchestration tool for building and executing Claude CLI command chains. Triggers on "coordinator", "ccw-coordinator", "命令编排", "command chain", "orchestrate commands", "编排CLI命令". -allowed-tools: Task, AskUserQuestion, Read, Write, Bash, Glob, Grep ---- - -# CCW Coordinator - -交互式命令编排工具:允许用户依次选择命令,形成命令链,然后通过 ccw cli 调用 Claude 循环执行每个命令。 - -**核心特性**: -- **保持为 Skill**:用户通过 `/ccw-coordinator` 触发 -- **仅支持 Claude**:所有执行通过 `ccw cli --tool claude` 调用 -- **命令在提示词中体现**:提示词直接包含完整命令调用(如 `/workflow:lite-plan --yes "任务"`) -- **智能参数组装**:根据命令 YAML 头的 `argument-hint` 组装正确参数 -- **循环执行**:每次根据上次完成情况和下个命令参数动态组装提示词 - -## Architecture Overview - -``` -用户: /ccw-coordinator - ↓ -┌─────────────────────────────────────────────────────────────────┐ -│ Orchestrator (主流程状态机) │ -│ 直接在 Claude Code 主流程中运行 │ -└───────────────┬─────────────────────────────────────────────────┘ - │ - ┌───────────┼───────────┬───────────────┐ - ↓ ↓ ↓ ↓ -┌─────────┐ ┌──────────────┐ ┌────────────┐ ┌──────────┐ -│ Init │ │ Command │ │ Command │ │ Execute │ ← 核心 -│ │ │ Selection │ │ Build │ │ │ -│ 初始化 │ │ 选择命令 │ │ 编排调整 │ │ 循环调用 │ -│ 会话 │ │ 推荐确认 │ │ (可选) │ │ ccw cli │ -└─────────┘ └──────────────┘ └────────────┘ └────┬─────┘ - │ │ │ │ - └───────────────┼──────────────┴──────────────┘ - │ │ - ↓ │ - ┌──────────────┐ │ - │ Complete │ │ - │ 生成报告 │ │ - └──────────────┘ │ - │ - ┌──────────────────────────────┘ - │ 循环执行每个命令 - ↓ - ┌───────────────────────────────────────┐ - │ action-command-execute │ - │ for each command in chain: │ - │ 1. 组装提示词 │ - │ 2. 调用 ccw cli --tool claude │ - │ 3. 解析产物 │ - │ 4. 更新状态 │ - └───────────────────┬───────────────────┘ - │ - ↓ - ┌───────────────────────────────┐ - │ ccw cli -p " │ - │ 任务: xxx │ - │ 前序: /workflow:lite-plan │ - │ /workflow:lite-execute ..." │ - │ --tool claude --mode write │ - └───────────────┬───────────────┘ - │ - ↓ - ┌───────────────┐ - │ Claude 执行 │ - │ workflow 命令 │ - └───────────────┘ -``` - -## Key Design Principles - -1. **智能推荐**:Claude 根据用户任务描述自动推荐最优命令链 -2. **交互式编排**:用户通过交互界面选择和编排命令,实时反馈推荐 -3. **状态持久化**:会话状态保存到 `state.json`,支持中途暂停和恢复 -4. **仅支持 Claude**:所有执行通过 `ccw cli --tool claude` 调用 -5. **命令在提示词中**:提示词直接包含完整命令调用,不是告诉 Claude 去执行什么 -6. **智能参数组装**:根据命令的 YAML 头 `argument-hint` 动态生成参数 -7. **循环执行**:每个命令执行后立即更新状态,根据产物组装下个命令的提示词 -8. **自动确认**:所有命令自动添加 `-y` 参数,跳过交互式确认 -9. **产物追踪**:自动提取会话 ID 和产物文件,用于后续命令链接 - -## Intelligent Prompt Generation - -执行命令时,系统智能生成 `ccw cli -p` 提示词。 - -### 核心原则 - -**提示词直接包含完整命令调用**,而不是告诉 Claude 去执行什么: - -``` -✅ 正确: -任务: 实现用户注册 - -/workflow:lite-plan --yes "实现用户注册" - -❌ 错误: -任务: 实现用户注册 -命令: /workflow:lite-plan -参数格式: [--yes] "task" -执行要求: 请执行 lite-plan 命令 -``` - -### 提示词构成 - -```javascript -// 集成命令注册表(按需提取) -const registry = new CommandRegistry(); -const commandMeta = registry.getCommands(commandNames); - -function generatePrompt(cmd, state, commandMeta) { - // 1. 任务描述 - let prompt = `任务: ${state.task_description}\n`; - - // 2. 前序完成情况 - if (state.execution_results.length > 0) { - const previousOutputs = state.execution_results - .filter(r => r.status === 'success') - .map(r => { - if (r.summary?.session) { - return `- ${r.command}: ${r.summary.session} (${r.summary.files?.join(', ')})`; - } - return `- ${r.command}: 已完成`; - }) - .join('\n'); - - prompt += `\n前序完成:\n${previousOutputs}\n`; - } - - // 3. 组装完整命令行(关键) - const commandLine = assembleCommandLine(cmd, state, commandMeta); - prompt += `\n${commandLine}`; - - return prompt; -} - -// 根据 argument-hint 智能组装参数 -function assembleCommandLine(cmd, state, commandMeta) { - let commandLine = cmd.command; // /workflow:lite-plan - - // 添加 --yes 标志 - commandLine += ' --yes'; - - // 根据命令类型添加特定参数 - const cmdName = cmd.command.split(':').pop(); - - if (cmdName === 'lite-plan') { - commandLine += ` "${state.task_description}"`; - } else if (cmdName === 'lite-execute') { - // 如果有前序规划,使用 --in-memory - if (state.execution_results.some(r => r.command.includes('plan'))) { - commandLine += ' --in-memory'; - } else { - commandLine += ` "${state.task_description}"`; - } - } - // ... 其他命令类型 - - return commandLine; -} -``` - -### 产物追踪 - -每个命令执行后自动提取关键产物: - -```javascript -{ - command: "/workflow:lite-plan", - status: "success", - output: "...", - summary: { - session: "WFS-plan-20250123", // 会话ID - files: [".workflow/IMPL_PLAN.md"], // 产物文件 - timestamp: "2025-01-23T10:30:00Z" - } -} -``` - -### 命令调用示例 - -**第一个命令(lite-plan)**: -```bash -ccw cli -p "任务: 实现用户认证功能 - -/workflow:lite-plan --yes \"实现用户认证功能\"" --tool claude --mode write -y -``` - -**第二个命令(lite-execute)**: -```bash -ccw cli -p "任务: 实现用户认证功能 - -前序完成: -- /workflow:lite-plan: WFS-auth-2025-01-24 (IMPL_PLAN.md, exploration-architecture.json) - -/workflow:lite-execute --yes --in-memory" --tool claude --mode write -y -``` - -**第三个命令(test-cycle-execute)**: -```bash -ccw cli -p "任务: 实现用户认证功能 - -前序完成: -- /workflow:lite-plan: WFS-auth-2025-01-24 (IMPL_PLAN.md) -- /workflow:lite-execute: WFS-auth-2025-01-24 (完成) - -/workflow:test-cycle-execute --yes --session=\"WFS-auth-2025-01-24\"" --tool claude --mode write -y -``` - -### 命令注册表集成 - -- **位置**: `tools/command-registry.js` (skill 内置) -- **工作模式**: 按需提取(只提取用户任务链中的命令) -- **功能**: 自动查找全局 `.claude/commands/workflow` 目录,解析命令 YAML 头元数据 -- **作用**: 确保提示词包含准确的命令参数和上下文 - -详见 `tools/README.md` - ---- - -## Execution Flow - -### Orchestrator Execution Loop - -```javascript -1. 初始化会话 - ↓ -2. 循环执行直到完成 - ├─ 读取当前状态 - ├─ 选择下一个动作(根据状态和用户意图) - ├─ 执行动作,更新状态 - └─ 检查终止条件 - ↓ -3. 生成最终报告 -``` - -### Action Sequence (Typical) - -``` -action-init - ↓ (status: pending → running) -action-command-selection (可重复) - ↓ (添加命令到链) -action-command-build (可选) - ↓ (调整命令顺序) -action-command-execute - ↓ (依次执行所有命令) -action-complete - ↓ (status: running → completed) -``` - -## State Management - -### Initial State - -```json -{ - "status": "pending", - "task_description": "", - "command_chain": [], - "confirmed": false, - "error_count": 0, - "execution_results": [], - "current_command_index": 0, - "started_at": null -} -``` - -### State Transitions - -``` -pending → running (init) → running → completed (execute) - ↓ - aborted (error or user exit) -``` - -## Directory Setup - -```javascript -const timestamp = new Date().toISOString().slice(0,19).replace(/[-:T]/g, ''); -const workDir = `.workflow/.ccw-coordinator/${timestamp}`; - -Bash(`mkdir -p "${workDir}"`); -Bash(`mkdir -p "${workDir}/commands"`); -Bash(`mkdir -p "${workDir}/logs"`); -``` - -## Output Structure - -``` -.workflow/.ccw-coordinator/{timestamp}/ -├── state.json # 当前会话状态 -├── command-chain.json # 编排的完整命令链 -├── execution-log.md # 执行日志 -├── final-summary.md # 最终报告 -├── commands/ # 各命令执行详情 -│ ├── 01-command.log -│ ├── 02-command.log -│ └── ... -└── logs/ # 错误和警告日志 - ├── errors.log - └── warnings.log -``` - -## Reference Documents - -| Document | Purpose | -|----------|---------| -| [phases/orchestrator.md](phases/orchestrator.md) | 编排器实现 | -| [phases/state-schema.md](phases/state-schema.md) | 状态结构定义 | -| [phases/actions/action-init.md](phases/actions/action-init.md) | 初始化动作 | -| [phases/actions/action-command-selection.md](phases/actions/action-command-selection.md) | 命令选择动作 | -| [phases/actions/action-command-build.md](phases/actions/action-command-build.md) | 命令编排动作 | -| [phases/actions/action-command-execute.md](phases/actions/action-command-execute.md) | 命令执行动作 | -| [phases/actions/action-complete.md](phases/actions/action-complete.md) | 完成动作 | -| [phases/actions/action-abort.md](phases/actions/action-abort.md) | 中止动作 | -| [specs/specs.md](specs/specs.md) | 命令库、验证规则、注册表 | -| [tools/chain-validate.cjs](tools/chain-validate.cjs) | 验证工具 | -| [tools/command-registry.cjs](tools/command-registry.cjs) | 命令注册表工具 | - ---- - -## Usage Examples - -### 快速命令链 - -用户想要执行:规划 → 执行 → 测试 - -``` -1. 触发 /ccw-coordinator -2. 描述任务:"实现用户注册功能" -3. Claude推荐: plan → execute → test-cycle-execute -4. 用户确认 -5. 执行命令链 -``` - -### 复杂工作流 - -用户想要执行:规划 → 执行 → 审查 → 修复 - -``` -1. 触发 /ccw-coordinator -2. 描述任务:"重构认证模块" -3. Claude推荐: plan → execute → review-session-cycle → review-fix -4. 用户可调整命令顺序 -5. 确认执行 -6. 实时查看执行进度 -``` - -### 紧急修复 - -用户想要快速修复bug - -``` -1. 触发 /ccw-coordinator -2. 描述任务:"修复生产环境登录bug" -3. Claude推荐: lite-fix --hotfix → test-cycle-execute -4. 用户确认 -5. 快速执行修复 -``` - -## Constraints and Rules - -### 1. 命令推荐约束 - -- **智能推荐优先**: 必须先基于用户任务描述进行智能推荐,而非直接展示命令库 -- **不使用静态映射**: 禁止使用查表或硬编码的推荐逻辑(如 `if task=bug则推荐lite-fix`) -- **推荐必须说明理由**: Claude 推荐命令链时必须解释为什么这样推荐 -- **用户保留选择权**: 推荐后,用户可选择:使用推荐/调整/手动选择 - -### 2. 验证约束 - -- **执行前必须验证**: 使用 `chain-validate.js` 验证命令链合法性 -- **不合法必须提示**: 如果验证失败,必须明确告知用户错误原因和修复方法 -- **允许用户覆盖**: 验证失败时,询问用户是否仍要执行(警告模式) - -### 3. 执行约束 - -- **顺序执行**: 命令必须严格按照 command_chain 中的 order 顺序执行 -- **错误处理**: 单个命令失败时,询问用户:重试/跳过/中止 -- **错误上限**: 连续 3 次错误自动中止会话 -- **实时反馈**: 每个命令执行时显示进度(如 `[2/5] 执行: lite-execute`) - -### 4. 状态管理约束 - -- **状态持久化**: 每次状态更新必须立即写入磁盘 -- **单一数据源**: 状态只保存在 `state.json`,禁止多个状态文件 -- **原子操作**: 状态更新必须使用 read-modify-write 模式,避免并发冲突 - -### 5. 用户体验约束 - -- **最小交互**: 默认使用智能推荐 + 一次确认,避免多次询问 -- **清晰输出**: 每个步骤输出必须包含:当前状态、可用选项、建议操作 -- **可恢复性**: 会话中断后,用户可从上次状态恢复 - -### 6. 禁止行为 - -- ❌ **禁止跳过推荐步骤**: 不能直接进入手动选择,必须先尝试推荐 -- ❌ **禁止静态推荐**: 不能使用 recommended-chains.json 查表 -- ❌ **禁止无验证执行**: 不能跳过链条验证直接执行 -- ❌ **禁止静默失败**: 错误必须明确报告,不能静默跳过 - -## Notes - -- 编排器使用状态机模式,确保执行流程的可靠性 -- 所有命令链和执行结果都被持久化保存,支持后续查询和调试 -- 支持用户中途修改命令链(在执行前) -- 执行错误会自动记录,支持重试机制 -- Claude 智能推荐基于任务分析,非查表静态推荐 diff --git a/.claude/skills/ccw-coordinator/phases/actions/action-abort.md b/.claude/skills/ccw-coordinator/phases/actions/action-abort.md deleted file mode 100644 index d1b54dab..00000000 --- a/.claude/skills/ccw-coordinator/phases/actions/action-abort.md +++ /dev/null @@ -1,9 +0,0 @@ -# action-abort - -中止会话,保存状态 - -```javascript -updateState({ status: 'aborted' }); - -console.log(`会话已中止: ${workDir}`); -``` diff --git a/.claude/skills/ccw-coordinator/phases/actions/action-command-build.md b/.claude/skills/ccw-coordinator/phases/actions/action-command-build.md deleted file mode 100644 index a71e9989..00000000 --- a/.claude/skills/ccw-coordinator/phases/actions/action-command-build.md +++ /dev/null @@ -1,40 +0,0 @@ -# action-command-build - -调整命令链顺序或删除命令 - -## 流程 - -1. 显示当前命令链 -2. 让用户调整(重新排序、删除) -3. 确认执行 - -## 伪代码 - -```javascript -// 显示链 -console.log('命令链:'); -state.command_chain.forEach((cmd, i) => { - console.log(`${i+1}. ${cmd.command}`); -}); - -// 询问用户 -const action = await AskUserQuestion({ - options: [ - '继续执行', - '删除命令', - '重新排序', - '返回选择' - ] -}); - -// 处理用户操作 -if (action === '继续执行') { - updateState({confirmed: true, status: 'executing'}); -} -// ... 其他操作 -``` - -## 状态更新 - -- command_chain (可能修改) -- confirmed = true 时状态转为 executing diff --git a/.claude/skills/ccw-coordinator/phases/actions/action-command-execute.md b/.claude/skills/ccw-coordinator/phases/actions/action-command-execute.md deleted file mode 100644 index 5776acca..00000000 --- a/.claude/skills/ccw-coordinator/phases/actions/action-command-execute.md +++ /dev/null @@ -1,349 +0,0 @@ -# action-command-execute - -循环执行命令链,通过 ccw cli 调用 Claude 执行每个命令。 - -## 核心原则 - -1. **仅支持 Claude**:所有执行通过 `ccw cli --tool claude` 调用 -2. **命令在提示词中体现**:提示词直接包含完整的命令调用(如 `/workflow:lite-plan --yes "任务"`) -3. **智能参数组装**:根据命令的 `argument-hint` 组装正确的参数 -4. **循环执行**:每次根据上次完成情况和下个命令参数组装提示词 - -## 命令注册表集成 - -```javascript -// 从 ./tools/command-registry.cjs 按需提取命令元数据 -const CommandRegistry = require('./tools/command-registry.cjs'); -const registry = new CommandRegistry(); - -// 只提取当前任务链中的命令 -const commandNames = command_chain.map(cmd => cmd.command); -const commandMeta = registry.getCommands(commandNames); -``` - -## 参数组装逻辑 - -根据命令的 `argument-hint` 和执行上下文,智能组装命令行参数: - -```javascript -function assembleCommandLine(cmd, state, commandMeta) { - const cmdInfo = commandMeta[cmd.command]; - const { task_description, execution_results } = state; - - let commandLine = cmd.command; // e.g., /workflow:lite-plan - - // 1. 添加 --yes 标志(跳过确认) - commandLine += ' --yes'; - - // 2. 根据命令类型添加特定参数 - const cmdName = cmd.command.split(':').pop(); // lite-plan, lite-execute, etc. - - switch (cmdName) { - case 'lite-plan': - case 'plan': - case 'multi-cli-plan': - case 'tdd-plan': - // 规划命令:需要任务描述 - commandLine += ` "${task_description}"`; - break; - - case 'lite-execute': - // 执行命令:如果有前序规划产物,使用 --in-memory - if (execution_results.some(r => - r.command.includes('plan') && r.status === 'success' - )) { - commandLine += ' --in-memory'; - } else { - commandLine += ` "${task_description}"`; - } - break; - - case 'execute': - // 标准执行:可能需要 --resume-session - const planResult = execution_results.find(r => - r.command.includes('plan') && r.status === 'success' - ); - if (planResult?.summary?.session) { - commandLine += ` --resume-session="${planResult.summary.session}"`; - } - break; - - case 'lite-fix': - // 修复命令:如果有 hotfix 标志 - if (cmd.hotfix) { - commandLine += ' --hotfix'; - } - commandLine += ` "${task_description}"`; - break; - - case 'test-cycle-execute': - case 'test-gen': - case 'test-fix-gen': - // 测试命令:使用前序会话 - const execResult = execution_results.find(r => - (r.command.includes('execute') || r.command.includes('fix')) && - r.status === 'success' - ); - if (execResult?.summary?.session) { - commandLine += ` --session="${execResult.summary.session}"`; - } - break; - - case 'review-session-cycle': - case 'review-module-cycle': - case 'review-fix': - // 审查命令:使用前序会话 - const prevSession = execution_results - .filter(r => r.status === 'success' && r.summary?.session) - .pop()?.summary?.session; - if (prevSession) { - commandLine += ` --session="${prevSession}"`; - } - break; - - default: - // 其他命令:尝试传递任务描述 - if (cmdInfo?.argumentHint?.includes('task') || - cmdInfo?.argumentHint?.includes('description')) { - commandLine += ` "${task_description}"`; - } - } - - // 3. 添加用户自定义参数(如果有) - if (cmd.customArgs) { - commandLine += ` ${cmd.customArgs}`; - } - - return commandLine; -} -``` - -## 提示词生成 - -提示词结构:任务描述 + 前序完成 + 完整命令行 - -```javascript -function generatePrompt(cmd, state, commandMeta) { - const { task_description, execution_results } = state; - - // 1. 任务描述 - let prompt = `任务: ${task_description}\n`; - - // 2. 前序完成情况 - const successResults = execution_results.filter(r => r.status === 'success'); - if (successResults.length > 0) { - const previousOutputs = successResults - .map(r => { - const summary = r.summary; - if (summary?.session) { - const files = summary.files?.length > 0 - ? summary.files.join(', ') - : '完成'; - return `- ${r.command}: ${summary.session} (${files})`; - } - return `- ${r.command}: 已完成`; - }) - .join('\n'); - - prompt += `\n前序完成:\n${previousOutputs}\n`; - } - - // 3. 组装完整命令行(关键) - const commandLine = assembleCommandLine(cmd, state, commandMeta); - prompt += `\n${commandLine}`; - - return prompt; -} -``` - -### 提示词示例 - -**第一个命令(lite-plan)**: -``` -任务: 实现用户注册功能,包括邮箱验证和密码加密 - -/workflow:lite-plan --yes "实现用户注册功能,包括邮箱验证和密码加密" -``` - -**第二个命令(lite-execute)**: -``` -任务: 实现用户注册功能,包括邮箱验证和密码加密 - -前序完成: -- /workflow:lite-plan: WFS-register-2025-01-24 (IMPL_PLAN.md, exploration-architecture.json) - -/workflow:lite-execute --yes --in-memory -``` - -**第三个命令(test-cycle-execute)**: -``` -任务: 实现用户注册功能,包括邮箱验证和密码加密 - -前序完成: -- /workflow:lite-plan: WFS-register-2025-01-24 (IMPL_PLAN.md) -- /workflow:lite-execute: WFS-register-2025-01-24 (完成) - -/workflow:test-cycle-execute --yes --session="WFS-register-2025-01-24" -``` - -## 执行逻辑 - -```javascript -for (let i = current_command_index; i < command_chain.length; i++) { - const cmd = command_chain[i]; - - console.log(`[${i+1}/${command_chain.length}] 执行: ${cmd.command}`); - - // 1. 生成智能提示词 - const prompt = generatePrompt(cmd, state, commandMeta); - - // 2. 转义提示词中的特殊字符 - const escapedPrompt = prompt - .replace(/\\/g, '\\\\') - .replace(/"/g, '\\"') - .replace(/\n/g, '\\n'); - - try { - // 3. 调用 ccw cli(仅支持 claude) - const result = Bash(`ccw cli -p "${escapedPrompt}" --tool claude --mode write -y`, { - run_in_background: true - }); - - // 4. 等待执行完成(通过 hook 回调) - // ... 等待逻辑由调用者处理 - - // 5. 解析输出,提取产物 - const summary = extractSummary(result.stdout); - - // 6. 记录执行结果 - execution_results.push({ - command: cmd.command, - status: result.exit_code === 0 ? 'success' : 'failed', - exit_code: result.exit_code, - output: result.stdout, - summary: summary - }); - - // 7. 更新命令状态 - command_chain[i].status = 'completed'; - current_command_index = i + 1; - - } catch (error) { - error_count++; - command_chain[i].status = 'failed'; - - // 错误上限检查 - if (error_count >= 3) { - console.log('连续错误超过3次,中止执行'); - break; - } - - // 用户决策 - const action = await AskUserQuestion({ - questions: [{ - question: `命令 ${cmd.command} 执行失败,如何处理?`, - header: "Error", - multiSelect: false, - options: [ - { label: "重试", description: "重新执行此命令" }, - { label: "跳过", description: "跳过此命令,继续下一个" }, - { label: "中止", description: "终止整个命令链" } - ] - }] - }); - - if (action.answers['Error'] === '重试') i--; - if (action.answers['Error'] === '中止') break; - } - - // 8. 持久化状态 - updateState({ - command_chain, - execution_results, - current_command_index, - error_count - }); -} -``` - -## 产物提取 - -```javascript -function extractSummary(output) { - // 从 ccw cli 输出提取关键产物信息 - - // 1. 提取会话 ID (WFS-* 或其他格式) - const sessionMatch = output.match(/WFS-[\w-]+/); - - // 2. 提取产物文件路径 - const fileMatches = output.match(/\.workflow\/[^\s\n\r"']+/g); - - // 3. 提取完成状态 - const isSuccess = /✓|completed|success|完成/i.test(output); - - return { - session: sessionMatch?.[0] || null, - files: fileMatches ? [...new Set(fileMatches)] : [], // 去重 - status: isSuccess ? 'success' : 'unknown', - timestamp: new Date().toISOString() - }; -} -``` - -## 状态更新 - -每次命令执行后立即更新 `state.json`: - -```javascript -function updateState(updates) { - const statePath = `${workDir}/state.json`; - const currentState = JSON.parse(Read(statePath)); - - const newState = { - ...currentState, - ...updates, - updated_at: new Date().toISOString() - }; - - Write(statePath, JSON.stringify(newState, null, 2)); -} -``` - -### 更新字段 - -| 字段 | 说明 | -|------|------| -| `execution_results` | 每个命令的执行结果(含 summary 产物信息) | -| `command_chain[].status` | 各命令状态(pending/in_progress/completed/failed) | -| `current_command_index` | 当前执行到的命令索引 | -| `error_count` | 连续错误计数 | - -## 日志记录 - -每个命令执行详情保存到独立日志: - -```javascript -function logCommandExecution(index, cmd, result, workDir) { - const logPath = `${workDir}/commands/${String(index + 1).padStart(2, '0')}-${cmd.command.replace(/[/:]/g, '-')}.log`; - - const logContent = ` -# Command Execution Log -Command: ${cmd.command} -Status: ${result.status} -Exit Code: ${result.exit_code} -Timestamp: ${new Date().toISOString()} - -## Prompt -${result.prompt} - -## Output -${result.output} - -## Summary -Session: ${result.summary?.session || 'N/A'} -Files: ${result.summary?.files?.join(', ') || 'N/A'} -`; - - Write(logPath, logContent); -} -``` diff --git a/.claude/skills/ccw-coordinator/phases/actions/action-command-selection.md b/.claude/skills/ccw-coordinator/phases/actions/action-command-selection.md deleted file mode 100644 index 35cc1d2e..00000000 --- a/.claude/skills/ccw-coordinator/phases/actions/action-command-selection.md +++ /dev/null @@ -1,48 +0,0 @@ -# action-command-selection - -## 流程 - -1. 问用户任务 -2. Claude推荐命令链 -3. 用户确认/手动选择 -4. 添加到command_chain - -## 伪代码 - -```javascript -// 1. 获取用户任务描述 -const taskInput = await AskUserQuestion({ - question: '请描述您的任务', - options: [ - { label: '手动选择命令', value: 'manual' } - ] -}); - -// 保存任务描述到状态 -updateState({ task_description: taskInput.text || taskInput.value }); - -// 2. 若用户描述任务,Claude推荐 -if (taskInput.text) { - console.log('推荐: ', recommendChain(taskInput.text)); - const confirm = await AskUserQuestion({ - question: '是否使用推荐链?', - options: ['使用推荐', '调整', '手动选择'] - }); - if (confirm === '使用推荐') { - addCommandsToChain(recommendedChain); - updateState({ confirmed: true }); - return; - } -} - -// 3. 手动选择 -const commands = loadCommandLibrary(); -const selected = await AskUserQuestion(commands); -addToChain(selected); -``` - -## 状态更新 - -- task_description = 用户任务描述 -- command_chain.push(newCommand) -- 如果用户确认: confirmed = true diff --git a/.claude/skills/ccw-coordinator/phases/actions/action-complete.md b/.claude/skills/ccw-coordinator/phases/actions/action-complete.md deleted file mode 100644 index 3d005289..00000000 --- a/.claude/skills/ccw-coordinator/phases/actions/action-complete.md +++ /dev/null @@ -1,25 +0,0 @@ -# action-complete - -生成执行报告 - -```javascript -const success = execution_results.filter(r => r.status === 'success').length; -const failed = execution_results.filter(r => r.status === 'failed').length; -const duration = Date.now() - new Date(started_at).getTime(); - -const report = ` -# 执行报告 - -- 会话: ${session_id} -- 耗时: ${Math.round(duration/1000)}s -- 成功: ${success} -- 失败: ${failed} - -## 命令详情 - -${command_chain.map((c, i) => `${i+1}. ${c.command} - ${c.status}`).join('\n')} -`; - -Write(`${workDir}/final-report.md`, report); -updateState({ status: 'completed' }); -``` diff --git a/.claude/skills/ccw-coordinator/phases/actions/action-init.md b/.claude/skills/ccw-coordinator/phases/actions/action-init.md deleted file mode 100644 index 2db437a0..00000000 --- a/.claude/skills/ccw-coordinator/phases/actions/action-init.md +++ /dev/null @@ -1,26 +0,0 @@ -# action-init - -初始化编排会话 - -```javascript -const timestamp = Date.now(); -const workDir = `.workflow/.ccw-coordinator/${timestamp}`; - -Bash(`mkdir -p "${workDir}"`); - -const state = { - session_id: `coord-${timestamp}`, - status: 'running', - started_at: new Date().toISOString(), - task_description: '', - command_chain: [], - current_command_index: 0, - execution_results: [], - confirmed: false, - error_count: 0 -}; - -Write(`${workDir}/state.json`, JSON.stringify(state, null, 2)); - -console.log(`会话已初始化: ${workDir}`); -``` diff --git a/.claude/skills/ccw-coordinator/phases/orchestrator.md b/.claude/skills/ccw-coordinator/phases/orchestrator.md deleted file mode 100644 index dc0614b7..00000000 --- a/.claude/skills/ccw-coordinator/phases/orchestrator.md +++ /dev/null @@ -1,59 +0,0 @@ -# Orchestrator - -状态驱动编排:读状态 → 选动作 → 执行 → 更新状态 - -## 决策逻辑 - -```javascript -function selectNextAction(state) { - if (['completed', 'aborted'].includes(state.status)) return null; - if (state.error_count >= 3) return 'action-abort'; - - switch (state.status) { - case 'pending': - return 'action-init'; - case 'running': - return state.confirmed && state.command_chain.length > 0 - ? 'action-command-execute' - : 'action-command-selection'; - case 'executing': - const pending = state.command_chain.filter(c => c.status === 'pending'); - return pending.length === 0 ? 'action-complete' : 'action-command-execute'; - default: - return 'action-abort'; - } -} -``` - -## 执行循环 - -```javascript -const timestamp = Date.now(); -const workDir = `.workflow/.ccw-coordinator/${timestamp}`; -Bash(`mkdir -p "${workDir}"`); - -const state = { - session_id: `coord-${timestamp}`, - status: 'pending', - started_at: new Date().toISOString(), - task_description: '', // 从 action-command-selection 获取 - command_chain: [], - current_command_index: 0, - execution_results: [], - confirmed: false, - error_count: 0 -}; -Write(`${workDir}/state.json`, JSON.stringify(state, null, 2)); - -let iterations = 0; -while (iterations < 50) { - const state = JSON.parse(Read(`${workDir}/state.json`)); - const nextAction = selectNextAction(state); - if (!nextAction) break; - - console.log(`[${nextAction}]`); - // 执行 phases/actions/{nextAction}.md - - iterations++; -} -``` diff --git a/.claude/skills/ccw-coordinator/phases/state-schema.md b/.claude/skills/ccw-coordinator/phases/state-schema.md deleted file mode 100644 index 95bf3f07..00000000 --- a/.claude/skills/ccw-coordinator/phases/state-schema.md +++ /dev/null @@ -1,66 +0,0 @@ -# State Schema - -```typescript -interface State { - session_id: string; - status: 'pending' | 'running' | 'executing' | 'completed' | 'aborted'; - started_at: string; - task_description: string; // 用户任务描述 - command_chain: Command[]; - current_command_index: number; - execution_results: ExecutionResult[]; - confirmed: boolean; - error_count: number; -} - -interface Command { - id: string; - order: number; - command: string; - status: 'pending' | 'running' | 'completed' | 'failed'; - result?: ExecutionResult; -} - -interface ExecutionResult { - command: string; - status: 'success' | 'failed'; - exit_code: number; - output?: string; - summary?: { // 提取的关键产物 - session?: string; - files?: string[]; - timestamp: string; - }; -} -``` - -## 状态转移 - -``` -pending → running → executing → completed - ↓ ↓ - (abort) (error → abort) -``` - -## 初始化 - -```javascript -{ - session_id: generateId(), - status: 'pending', - started_at: new Date().toISOString(), - task_description: '', // 从用户输入获取 - command_chain: [], - current_command_index: 0, - execution_results: [], - confirmed: false, - error_count: 0 -} -``` - -## 更新 - -- 添加命令: `command_chain.push(cmd)` -- 确认执行: `confirmed = true, status = 'executing'` -- 记录执行: `execution_results.push(...), current_command_index++` -- 错误计数: `error_count++` diff --git a/.claude/skills/ccw-coordinator/skill-config.json b/.claude/skills/ccw-coordinator/skill-config.json deleted file mode 100644 index 70c4f9e8..00000000 --- a/.claude/skills/ccw-coordinator/skill-config.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "skill_name": "ccw-coordinator", - "display_name": "CCW Coordinator", - "description": "Interactive command orchestration - select, build, and execute workflow command chains", - "execution_mode": "autonomous", - "version": "1.0.0", - "triggers": [ - "coordinator", - "ccw-coordinator", - "命令编排", - "command chain" - ], - "allowed_tools": [ - "Task", - "AskUserQuestion", - "Read", - "Write", - "Bash" - ], - "actions": [ - { - "id": "action-init", - "name": "Init", - "description": "Initialize orchestration session" - }, - { - "id": "action-command-selection", - "name": "Select Commands", - "description": "Interactive command selection from library" - }, - { - "id": "action-command-build", - "name": "Build Chain", - "description": "Adjust and confirm command chain" - }, - { - "id": "action-command-execute", - "name": "Execute", - "description": "Execute command chain sequentially" - }, - { - "id": "action-complete", - "name": "Complete", - "description": "Generate final report" - }, - { - "id": "action-abort", - "name": "Abort", - "description": "Abort session and save state" - } - ], - "termination_conditions": [ - "user_exit", - "task_completed", - "error" - ], - "output": { - "location": ".workflow/.ccw-coordinator/{timestamp}", - "artifacts": [ - "state.json", - "command-chain.json", - "execution-log.md", - "final-report.md" - ] - } -} diff --git a/.claude/skills/ccw-coordinator/specs/command-library.md b/.claude/skills/ccw-coordinator/specs/command-library.md deleted file mode 100644 index c01c007d..00000000 --- a/.claude/skills/ccw-coordinator/specs/command-library.md +++ /dev/null @@ -1,169 +0,0 @@ -# Command Library - -CCW Coordinator 支持的命令库。基于 CCW workflow 命令系统。 - -## Command Categories - -### Planning Commands - -| Command | Description | Level | -|---------|-------------|-------| -| `/workflow:lite-plan` | 轻量级规划 | L2 | -| `/workflow:plan` | 标准规划 | L3 | -| `/workflow:multi-cli-plan` | 多CLI协作规划 | L2 | -| `/workflow:brainstorm:auto-parallel` | 头脑风暴规划 | L4 | -| `/workflow:tdd-plan` | TDD规划 | L3 | - -### Execution Commands - -| Command | Description | Level | -|---------|-------------|-------| -| `/workflow:lite-execute` | 轻量级执行 | L2 | -| `/workflow:execute` | 标准执行 | L3 | -| `/workflow:test-cycle-execute` | 测试循环执行 | L3 | - -### BugFix Commands - -| Command | Description | Level | -|---------|-------------|-------| -| `/workflow:lite-fix` | 轻量级修复 | L2 | -| `/workflow:lite-fix --hotfix` | 紧急修复 | L2 | - -### Testing Commands - -| Command | Description | Level | -|---------|-------------|-------| -| `/workflow:test-gen` | 测试生成 | L3 | -| `/workflow:test-fix-gen` | 测试修复生成 | L3 | -| `/workflow:tdd-verify` | TDD验证 | L3 | - -### Review Commands - -| Command | Description | Level | -|---------|-------------|-------| -| `/workflow:review-session-cycle` | 会话审查 | L3 | -| `/workflow:review-module-cycle` | 模块审查 | L3 | -| `/workflow:review-fix` | 审查修复 | L3 | -| `/workflow:plan-verify` | 计划验证 | L3 | - -### Documentation Commands - -| Command | Description | Level | -|---------|-------------|-------| -| `/memory:docs` | 生成文档 | L2 | -| `/memory:update-related` | 更新相关文档 | L2 | -| `/memory:update-full` | 全面更新文档 | L2 | - -### Issue Commands - -| Command | Description | Level | -|---------|-------------|-------| -| `/issue:discover` | 发现Issue | Supplementary | -| `/issue:discover-by-prompt` | 基于提示发现Issue | Supplementary | -| `/issue:plan --all-pending` | 规划所有待处理Issue | Supplementary | -| `/issue:queue` | 排队Issue | Supplementary | -| `/issue:execute` | 执行Issue | Supplementary | - -## Command Chains (Recommended) - -### 标准开发流程 - -``` -1. /workflow:lite-plan -2. /workflow:lite-execute -3. /workflow:test-cycle-execute -``` - -### 完整规划流程 - -``` -1. /workflow:plan -2. /workflow:plan-verify -3. /workflow:execute -4. /workflow:review-session-cycle -``` - -### TDD 流程 - -``` -1. /workflow:tdd-plan -2. /workflow:execute -3. /workflow:tdd-verify -``` - -### Issue 批处理流程 - -``` -1. /issue:plan --all-pending -2. /issue:queue -3. /issue:execute -``` - -## JSON Format - -```json -{ - "workflow_commands": [ - { - "category": "Planning", - "commands": [ - { "name": "/workflow:lite-plan", "description": "轻量级规划" }, - { "name": "/workflow:plan", "description": "标准规划" }, - { "name": "/workflow:multi-cli-plan", "description": "多CLI协作规划" }, - { "name": "/workflow:brainstorm:auto-parallel", "description": "头脑风暴" }, - { "name": "/workflow:tdd-plan", "description": "TDD规划" } - ] - }, - { - "category": "Execution", - "commands": [ - { "name": "/workflow:lite-execute", "description": "轻量级执行" }, - { "name": "/workflow:execute", "description": "标准执行" }, - { "name": "/workflow:test-cycle-execute", "description": "测试循环执行" } - ] - }, - { - "category": "BugFix", - "commands": [ - { "name": "/workflow:lite-fix", "description": "轻量级修复" }, - { "name": "/workflow:lite-fix --hotfix", "description": "紧急修复" } - ] - }, - { - "category": "Testing", - "commands": [ - { "name": "/workflow:test-gen", "description": "测试生成" }, - { "name": "/workflow:test-fix-gen", "description": "测试修复" }, - { "name": "/workflow:tdd-verify", "description": "TDD验证" } - ] - }, - { - "category": "Review", - "commands": [ - { "name": "/workflow:review-session-cycle", "description": "会话审查" }, - { "name": "/workflow:review-module-cycle", "description": "模块审查" }, - { "name": "/workflow:review-fix", "description": "审查修复" }, - { "name": "/workflow:plan-verify", "description": "计划验证" } - ] - }, - { - "category": "Documentation", - "commands": [ - { "name": "/memory:docs", "description": "生成文档" }, - { "name": "/memory:update-related", "description": "更新相关文档" }, - { "name": "/memory:update-full", "description": "全面更新文档" } - ] - }, - { - "category": "Issues", - "commands": [ - { "name": "/issue:discover", "description": "发现Issue" }, - { "name": "/issue:discover-by-prompt", "description": "基于提示发现Issue" }, - { "name": "/issue:plan --all-pending", "description": "规划所有待处理Issue" }, - { "name": "/issue:queue", "description": "排队Issue" }, - { "name": "/issue:execute", "description": "执行Issue" } - ] - } - ] -} -``` diff --git a/.claude/skills/ccw-coordinator/specs/prompt-templates.md b/.claude/skills/ccw-coordinator/specs/prompt-templates.md deleted file mode 100644 index f84ed6c6..00000000 --- a/.claude/skills/ccw-coordinator/specs/prompt-templates.md +++ /dev/null @@ -1,544 +0,0 @@ -# Prompt Templates for CLI Execution - -通过 `ccw cli --tool claude` 执行各类命令的提示词模板和实际示例。 - ---- - -## 模板格式 - -``` -任务: {task_description} - -{前序完成信息(如果有)} -{完整的命令调用} -``` - -### 组件说明 - -| 组件 | 说明 | 例子 | -|------|------|------| -| `任务:` | 用户的任务描述 | "实现用户注册功能" | -| 前序完成 | 已完成命令的会话和产物 | "- /workflow:lite-plan: WFS-001 (IMPL_PLAN.md)" | -| 命令行 | 完整的命令调用 | "/workflow:lite-plan --yes \"任务\"" | - ---- - -## 1. 规划命令 (Planning) - -### 1.1 lite-plan - -**模板**: -``` -任务: {task_description} - -/workflow:lite-plan --yes "{task_description}" -``` - -**实例 - 简单任务**: -``` -任务: 添加用户登出功能 - -/workflow:lite-plan --yes "添加用户登出功能" -``` - -**实例 - 复杂任务**: -``` -任务: 重构认证模块,实现 JWT 刷新令牌和会话管理 - -/workflow:lite-plan --yes "重构认证模块,实现 JWT 刷新令牌和会话管理" -``` - -**实例 - 带探索强制**: -``` -任务: 优化数据库查询性能 - -/workflow:lite-plan --yes --explore "优化数据库查询性能" -``` - -### 1.2 plan - -**模板**: -``` -任务: {task_description} - -/workflow:plan --yes "{task_description}" -``` - -**实例**: -``` -任务: 实现支付系统集成 (Stripe) - -/workflow:plan --yes "实现支付系统集成 (Stripe)" -``` - -### 1.3 multi-cli-plan - -**模板**: -``` -任务: {task_description} - -/workflow:multi-cli-plan --yes "{task_description}" -``` - -**实例**: -``` -任务: 设计微服务架构并实现 API 网关 - -/workflow:multi-cli-plan --yes "设计微服务架构并实现 API 网关" -``` - ---- - -## 2. 执行命令 (Execution) - -### 2.1 lite-execute(有规划产物) - -**模板**: -``` -任务: {task_description} - -前序完成: -- /workflow:lite-plan: {session_id} ({artifact_files}) - -/workflow:lite-execute --yes --in-memory -``` - -**实例**: -``` -任务: 实现用户注册功能 - -前序完成: -- /workflow:lite-plan: WFS-register-2025-01-24 (IMPL_PLAN.md, exploration-architecture.json, exploration-security.json) - -/workflow:lite-execute --yes --in-memory -``` - -### 2.2 lite-execute(无规划产物) - -**模板**: -``` -任务: {task_description} - -/workflow:lite-execute --yes "{task_description}" -``` - -**实例**: -``` -任务: 修复页面布局响应式问题 - -/workflow:lite-execute --yes "修复页面布局响应式问题" -``` - -### 2.3 execute(有规划会话) - -**模板**: -``` -任务: {task_description} - -前序完成: -- /workflow:plan: {session_id} ({artifact_files}) - -/workflow:execute --yes --resume-session="{session_id}" -``` - -**实例**: -``` -任务: 实现微服务网关 - -前序完成: -- /workflow:plan: WFS-gateway-2025-01-24 (IMPL_PLAN.md, .workflow/tasks/) - -/workflow:execute --yes --resume-session="WFS-gateway-2025-01-24" -``` - ---- - -## 3. Bug 修复命令 (BugFix) - -### 3.1 lite-fix(轻量级修复) - -**模板**: -``` -任务: {task_description} - -/workflow:lite-fix --yes "{task_description}" -``` - -**实例**: -``` -任务: 修复登录表单验证失败问题 - -/workflow:lite-fix --yes "修复登录表单验证失败问题" -``` - -### 3.2 lite-fix --hotfix(紧急修复) - -**模板**: -``` -任务: {task_description} - -/workflow:lite-fix --yes --hotfix "{task_description}" -``` - -**实例**: -``` -任务: 紧急修复生产环境支付流程中断 - -/workflow:lite-fix --yes --hotfix "紧急修复生产环境支付流程中断" -``` - ---- - -## 4. 测试命令 (Testing) - -### 4.1 test-cycle-execute(有前序执行) - -**模板**: -``` -任务: {task_description} - -前序完成: -- /workflow:lite-execute: {session_id} ({artifact_files}) - -/workflow:test-cycle-execute --yes --session="{session_id}" -``` - -**实例**: -``` -任务: 实现用户注册功能 - -前序完成: -- /workflow:lite-plan: WFS-register-2025-01-24 (IMPL_PLAN.md) -- /workflow:lite-execute: WFS-register-2025-01-24 (完成) - -/workflow:test-cycle-execute --yes --session="WFS-register-2025-01-24" -``` - -### 4.2 test-gen(生成测试) - -**模板**: -``` -任务: {task_description} - -/workflow:test-gen --yes "{task_description}" -``` - -**实例**: -``` -任务: 为认证模块生成单元测试 - -/workflow:test-gen --yes "为认证模块生成单元测试" -``` - -### 4.3 test-fix-gen(生成测试和修复) - -**模板**: -``` -任务: {task_description} - -/workflow:test-fix-gen --yes "{task_description}" -``` - -**实例**: -``` -任务: 生成并修复数据库连接超时问题的测试 - -/workflow:test-fix-gen --yes "生成并修复数据库连接超时问题的测试" -``` - ---- - -## 5. 代码审查命令 (Review) - -### 5.1 review-session-cycle(审查执行会话) - -**模板**: -``` -任务: {task_description} - -前序完成: -- /workflow:execute: {session_id} ({artifact_files}) - -/workflow:review-session-cycle --yes --session="{session_id}" -``` - -**实例**: -``` -任务: 实现支付系统集成 - -前序完成: -- /workflow:plan: WFS-payment-2025-01-24 (IMPL_PLAN.md) -- /workflow:execute: WFS-payment-2025-01-24 (完成) - -/workflow:review-session-cycle --yes --session="WFS-payment-2025-01-24" -``` - -### 5.2 review-module-cycle(审查特定模块) - -**模板**: -``` -任务: {task_description} - -/workflow:review-module-cycle --yes "{module_path}" --dimensions="{dimensions}" -``` - -**实例**: -``` -任务: 审查认证模块的安全性 - -/workflow:review-module-cycle --yes "src/auth" --dimensions="security,error-handling" -``` - -### 5.3 review-fix(审查和修复) - -**模板**: -``` -任务: {task_description} - -前序完成: -- /workflow:review-session-cycle: {session_id} ({findings}) - -/workflow:review-fix --yes --session="{session_id}" -``` - -**实例**: -``` -任务: 修复代码审查发现的问题 - -前序完成: -- /workflow:review-session-cycle: WFS-payment-2025-01-24 (审查完成) - -/workflow:review-fix --yes --session="WFS-payment-2025-01-24" -``` - ---- - -## 6. 验证命令 (Verification) - -### 6.1 plan-verify(计划验证) - -**模板**: -``` -任务: {task_description} - -前序完成: -- /workflow:plan: {session_id} (IMPL_PLAN.md) - -/workflow:plan-verify --yes --session="{session_id}" -``` - -**实例**: -``` -任务: 验证支付系统实现计划 - -前序完成: -- /workflow:plan: WFS-payment-2025-01-24 (IMPL_PLAN.md) - -/workflow:plan-verify --yes --session="WFS-payment-2025-01-24" -``` - -### 6.2 tdd-verify(TDD 验证) - -**模板**: -``` -任务: {task_description} - -前序完成: -- /workflow:execute: {session_id} (完成) - -/workflow:tdd-verify --yes --session="{session_id}" -``` - -**实例**: -``` -任务: 验证 TDD 流程合规性 - -前序完成: -- /workflow:execute: WFS-tdd-auth-2025-01-24 (完成) - -/workflow:tdd-verify --yes --session="WFS-tdd-auth-2025-01-24" -``` - ---- - -## 7. 常见命令链提示词 - -### 7.1 标准开发流程:plan → execute → test - -**第 1 步 - 规划**: -``` -任务: 实现用户注册功能,包括邮箱验证和密码加密 - -/workflow:lite-plan --yes "实现用户注册功能,包括邮箱验证和密码加密" -``` - -**第 2 步 - 执行**: -``` -任务: 实现用户注册功能,包括邮箱验证和密码加密 - -前序完成: -- /workflow:lite-plan: WFS-register-2025-01-24 (IMPL_PLAN.md, exploration-architecture.json, exploration-security.json) - -/workflow:lite-execute --yes --in-memory -``` - -**第 3 步 - 测试**: -``` -任务: 实现用户注册功能,包括邮箱验证和密码加密 - -前序完成: -- /workflow:lite-plan: WFS-register-2025-01-24 (IMPL_PLAN.md) -- /workflow:lite-execute: WFS-register-2025-01-24 (完成) - -/workflow:test-cycle-execute --yes --session="WFS-register-2025-01-24" -``` - -### 7.2 完整规划流程:plan → execute → review → review-fix - -**第 1 步 - 规划**: -``` -任务: 重构认证模块,实现 OAuth2 和会话管理 - -/workflow:plan --yes "重构认证模块,实现 OAuth2 和会话管理" -``` - -**第 2 步 - 执行**: -``` -任务: 重构认证模块,实现 OAuth2 和会话管理 - -前序完成: -- /workflow:plan: WFS-auth-2025-01-24 (IMPL_PLAN.md, .workflow/tasks/) - -/workflow:execute --yes --resume-session="WFS-auth-2025-01-24" -``` - -**第 3 步 - 审查**: -``` -任务: 重构认证模块,实现 OAuth2 和会话管理 - -前序完成: -- /workflow:plan: WFS-auth-2025-01-24 (IMPL_PLAN.md) -- /workflow:execute: WFS-auth-2025-01-24 (完成) - -/workflow:review-session-cycle --yes --session="WFS-auth-2025-01-24" -``` - -**第 4 步 - 审查修复**: -``` -任务: 重构认证模块,实现 OAuth2 和会话管理 - -前序完成: -- /workflow:plan: WFS-auth-2025-01-24 (IMPL_PLAN.md) -- /workflow:execute: WFS-auth-2025-01-24 (完成) -- /workflow:review-session-cycle: WFS-auth-2025-01-24 (审查完成) - -/workflow:review-fix --yes --session="WFS-auth-2025-01-24" -``` - -### 7.3 Bug 修复 + 测试 - -**第 1 步 - 修复**: -``` -任务: 修复页面加载超时问题 - -/workflow:lite-fix --yes "修复页面加载超时问题" -``` - -**第 2 步 - 测试**: -``` -任务: 修复页面加载超时问题 - -前序完成: -- /workflow:lite-fix: WFS-fix-timeout-2025-01-24 (完成) - -/workflow:test-cycle-execute --yes --session="WFS-fix-timeout-2025-01-24" -``` - ---- - -## 8. 参数组装规则 - -### 规则 1:任务描述 - -- 规划命令(`lite-plan`, `plan` 等)**必须** 包含任务描述 -- 格式:`命令 --yes "任务描述"` - -### 规则 2:会话复用 - -- 执行命令在有规划产物时使用 `--in-memory` -- 其他命令使用 `--session="WFS-xxx"` 引用前序会话 - -### 规则 3:自动确认 - -- 所有命令都添加 `--yes` 标志跳过交互式确认 - -### 规则 4:文件路径 - -- 需要文件路径时(如 `review-module-cycle`),使用相对于项目根的路径 -- 例:`src/auth`, `src/modules/payment` - ---- - -## 9. 特殊情况处理 - -### 9.1 特殊字符转义 - -**问题**:提示词中包含双引号 - -**解决**: -```bash -# 在双引号内使用 \" -ccw cli -p "任务: 实现 \"特殊\" 功能\n/workflow:lite-plan ..." --tool claude -``` - -### 9.2 多行任务描述 - -**问题**:任务描述很长 - -**解决**: -``` -任务: 实现完整的支付系统,包括: -- Stripe 集成 -- 订单管理 -- 发票生成 -- 退款处理 - -/workflow:plan --yes "实现完整的支付系统:Stripe 集成、订单管理、发票生成、退款处理" -``` - -### 9.3 特殊路径处理 - -**问题**:路径包含空格 - -**解决**: -``` -任务: 审查用户管理模块 - -/workflow:review-module-cycle --yes "src/modules/user management" --dimensions="security" -``` - ---- - -## 10. 调试技巧 - -### 查看实际调用 - -在 `action-command-execute.md` 中添加日志: - -```javascript -console.log(`[DEBUG] Assembling prompt for: ${cmd.command}`) -console.log(`[DEBUG] Prompt:\n${prompt}`) -console.log(`[DEBUG] CLI Call:\nccw cli -p "${escapedPrompt}" --tool claude --mode write -y`) -``` - -### 验证产物提取 - -检查 `.workflow/.ccw-coordinator/{timestamp}/commands/` 目录下的日志文件,查看 CLI 输出和产物提取结果。 - -### 测试提示词 - -手动调用 ccw cli 测试: - -```bash -ccw cli -p "任务: 测试任务\n/workflow:lite-plan --yes \"测试任务\"" --tool claude --mode write -y -``` diff --git a/.claude/skills/ccw-coordinator/specs/specs.md b/.claude/skills/ccw-coordinator/specs/specs.md deleted file mode 100644 index 7191ef83..00000000 --- a/.claude/skills/ccw-coordinator/specs/specs.md +++ /dev/null @@ -1,371 +0,0 @@ -# CCW Coordinator Specifications - -命令库、验证规则和注册表一体化规范。 - ---- - -## 命令库 - -### Planning Commands - -| Command | Description | Level | -|---------|-------------|-------| -| `/workflow:lite-plan` | 轻量级规划 | L2 | -| `/workflow:plan` | 标准规划 | L3 | -| `/workflow:multi-cli-plan` | 多CLI协作规划 | L2 | -| `/workflow:brainstorm:auto-parallel` | 头脑风暴规划 | L4 | -| `/workflow:tdd-plan` | TDD规划 | L3 | - -### Execution Commands - -| Command | Description | Level | -|---------|-------------|-------| -| `/workflow:lite-execute` | 轻量级执行 | L2 | -| `/workflow:execute` | 标准执行 | L3 | -| `/workflow:test-cycle-execute` | 测试循环执行 | L3 | - -### BugFix Commands - -| Command | Description | Level | -|---------|-------------|-------| -| `/workflow:lite-fix` | 轻量级修复 | L2 | -| `/workflow:lite-fix --hotfix` | 紧急修复 | L2 | - -### Testing Commands - -| Command | Description | Level | -|---------|-------------|-------| -| `/workflow:test-gen` | 测试生成 | L3 | -| `/workflow:test-fix-gen` | 测试修复生成 | L3 | -| `/workflow:tdd-verify` | TDD验证 | L3 | - -### Review Commands - -| Command | Description | Level | -|---------|-------------|-------| -| `/workflow:review-session-cycle` | 会话审查 | L3 | -| `/workflow:review-module-cycle` | 模块审查 | L3 | -| `/workflow:review-fix` | 审查修复 | L3 | -| `/workflow:plan-verify` | 计划验证 | L3 | - -### Documentation Commands - -| Command | Description | Level | -|---------|-------------|-------| -| `/memory:docs` | 生成文档 | L2 | -| `/memory:update-related` | 更新相关文档 | L2 | -| `/memory:update-full` | 全面更新文档 | L2 | - -### Issue Commands - -| Command | Description | -|---------|-------------| -| `/issue:discover` | 发现Issue | -| `/issue:discover-by-prompt` | 基于提示发现Issue | -| `/issue:plan --all-pending` | 规划所有待处理Issue | -| `/issue:queue` | 排队Issue | -| `/issue:execute` | 执行Issue | - ---- - -## 命令链推荐 - -### 标准开发流程 - -``` -1. /workflow:lite-plan -2. /workflow:lite-execute -3. /workflow:test-cycle-execute -``` - -### 完整规划流程 - -``` -1. /workflow:plan -2. /workflow:plan-verify -3. /workflow:execute -4. /workflow:review-session-cycle -``` - -### TDD 流程 - -``` -1. /workflow:tdd-plan -2. /workflow:execute -3. /workflow:tdd-verify -``` - -### Issue 批处理流程 - -``` -1. /issue:plan --all-pending -2. /issue:queue -3. /issue:execute -``` - ---- - -## 验证规则 - -### Rule 1: Single Planning Command - -每条链最多包含一个规划命令。 - -| 有效 | 无效 | -|------|------| -| `plan → execute` | `plan → lite-plan → execute` | - -### Rule 2: Compatible Pairs - -规划和执行命令必须兼容。 - -| Planning | Execution | 兼容 | -|----------|-----------|------| -| lite-plan | lite-execute | ✓ | -| lite-plan | execute | ✗ | -| multi-cli-plan | lite-execute | ✓ | -| multi-cli-plan | execute | ✓ | -| plan | execute | ✓ | -| plan | lite-execute | ✗ | -| tdd-plan | execute | ✓ | -| tdd-plan | lite-execute | ✗ | - -### Rule 3: Testing After Execution - -测试命令必须在执行命令之后。 - -| 有效 | 无效 | -|------|------| -| `execute → test-cycle-execute` | `test-cycle-execute → execute` | - -### Rule 4: Review After Execution - -审查命令必须在执行命令之后。 - -| 有效 | 无效 | -|------|------| -| `execute → review-session-cycle` | `review-session-cycle → execute` | - -### Rule 5: BugFix Standalone - -`lite-fix` 必须单独执行,不能与其他命令组合。 - -| 有效 | 无效 | -|------|------| -| `lite-fix` | `plan → lite-fix → execute` | -| `lite-fix --hotfix` | `lite-fix → test-cycle-execute` | - -### Rule 6: Dependency Satisfaction - -每个命令的依赖必须在前面执行。 - -```javascript -test-fix-gen → test-cycle-execute ✓ -test-cycle-execute ✗ -``` - -### Rule 7: No Redundancy - -链条中不能有重复的命令。 - -| 有效 | 无效 | -|------|------| -| `plan → execute → test` | `plan → plan → execute` | - -### Rule 8: Command Exists - -所有命令必须在此规范中定义。 - ---- - -## 反模式(避免) - -### ❌ Pattern 1: Multiple Planning - -``` -plan → lite-plan → execute -``` -**问题**: 重复分析,浪费时间 -**修复**: 选一个规划命令 - -### ❌ Pattern 2: Test Without Context - -``` -test-cycle-execute (独立执行) -``` -**问题**: 没有执行上下文,无法工作 -**修复**: 先执行 `execute` 或 `test-fix-gen` - -### ❌ Pattern 3: BugFix with Planning - -``` -plan → execute → lite-fix -``` -**问题**: lite-fix 是独立命令,不应与规划混合 -**修复**: 用 `lite-fix` 单独修复,或用 `plan → execute` 做大改 - -### ❌ Pattern 4: Review Without Changes - -``` -review-session-cycle (独立执行) -``` -**问题**: 没有 git 改动可审查 -**修复**: 先执行 `execute` 生成改动 - -### ❌ Pattern 5: TDD Misuse - -``` -tdd-plan → lite-execute -``` -**问题**: lite-execute 无法处理 TDD 任务结构 -**修复**: 用 `tdd-plan → execute → tdd-verify` - ---- - -## 命令注册表 - -### 命令元数据结构 - -```json -{ - "command_name": { - "category": "Planning|Execution|Testing|Review|BugFix|Maintenance", - "level": "L0|L1|L2|L3", - "description": "命令描述", - "inputs": ["input1", "input2"], - "outputs": ["output1", "output2"], - "dependencies": ["依赖命令"], - "parameters": [ - {"name": "--flag", "type": "string|boolean|number", "default": "value"} - ], - "chain_position": "start|middle|middle_or_end|end|standalone", - "next_recommended": ["推荐的下一个命令"] - } -} -``` - -### 命令分组 - -| Group | Commands | -|-------|----------| -| planning | lite-plan, multi-cli-plan, plan, tdd-plan | -| execution | lite-execute, execute, develop-with-file | -| testing | test-gen, test-fix-gen, test-cycle-execute, tdd-verify | -| review | review-session-cycle, review-module-cycle, review-fix | -| bugfix | lite-fix, debug, debug-with-file | -| maintenance | clean, replan | -| verification | plan-verify, tdd-verify | - -### 兼容性矩阵 - -| 组合 | 状态 | -|------|------| -| lite-plan + lite-execute | ✓ compatible | -| lite-plan + execute | ✗ incompatible - use plan | -| multi-cli-plan + lite-execute | ✓ compatible | -| plan + execute | ✓ compatible | -| plan + lite-execute | ✗ incompatible - use lite-plan | -| tdd-plan + execute | ✓ compatible | -| execute + test-cycle-execute | ✓ compatible | -| lite-execute + test-cycle-execute | ✓ compatible | -| test-fix-gen + test-cycle-execute | ✓ required | -| review-session-cycle + review-fix | ✓ compatible | -| lite-fix + test-cycle-execute | ✗ incompatible - lite-fix standalone | - ---- - -## 验证工具 - -### chain-validate.cjs - -位置: `tools/chain-validate.cjs` - -验证命令链合法性: - -```bash -node tools/chain-validate.cjs plan execute test-cycle-execute -``` - -输出: -``` -{ - "valid": true, - "errors": [], - "warnings": [] -} -``` - -## 命令注册表 - -### 工具位置 - -位置: `tools/command-registry.cjs` (skill 内置) - -### 工作模式 - -**按需提取**: 只提取用户确定的任务链中的命令,不是全量扫描。 - -```javascript -// 用户任务链: [lite-plan, lite-execute] -const commandNames = command_chain.map(cmd => cmd.command); -const commandMeta = registry.getCommands(commandNames); -// 只提取这 2 个命令的元数据 -``` - -### 功能 - -- 自动查找全局 `.claude/commands/workflow` 目录(相对路径 > 用户 home) -- 按需提取指定命令的 YAML 头元数据 -- 缓存机制避免重复读取 -- 提供批量查询接口 - -### 集成方式 - -在 action-command-execute 中自动集成: - -```javascript -const CommandRegistry = require('./tools/command-registry.cjs'); -const registry = new CommandRegistry(); - -// 只提取任务链中的命令 -const commandNames = command_chain.map(cmd => cmd.command); -const commandMeta = registry.getCommands(commandNames); - -// 使用元数据生成提示词 -const cmdInfo = commandMeta[cmd.command]; -// { -// name: 'lite-plan', -// description: '轻量级规划...', -// argumentHint: '[-e|--explore] "task description"', -// allowedTools: [...], -// filePath: '...' -// } -``` - -### 提示词生成 - -智能提示词直接包含完整命令调用: - -1. **任务描述**: 用户的任务描述 -2. **前序产物**: 已完成命令的会话和产物信息 -3. **完整命令行**: 下个命令的完整调用(通过 `argument-hint` 组装) - -**✅ 正确示例**: -``` -任务: 实现用户注册功能 - -前序完成: -- /workflow:lite-plan: WFS-plan-001 (IMPL_PLAN.md) - -/workflow:lite-execute --yes --in-memory -``` - -**❌ 旧的错误示例**(不再使用): -``` -任务: 实现用户注册功能 -前序完成: -- /workflow:lite-plan: WFS-plan-001 (IMPL_PLAN.md) -命令: /workflow:lite-execute [--resume-session="session-id"] -``` - -详见 `tools/README.md` 和 `specs/prompt-templates.md`。 diff --git a/.claude/skills/ccw-coordinator/tools/README.md b/.claude/skills/ccw-coordinator/tools/README.md deleted file mode 100644 index 58222c6f..00000000 --- a/.claude/skills/ccw-coordinator/tools/README.md +++ /dev/null @@ -1,117 +0,0 @@ -# CCW Coordinator Tools - -## command-registry.cjs - -命令注册表工具:获取和提取命令元数据。 - -### 功能 - -- **按需提取**: 只提取指定命令的完整信息(name, description, argumentHint, allowedTools 等) -- **全量获取**: 获取所有命令的名称和描述(快速查询) -- **自动查找**: 从全局 `.claude/commands/workflow` 目录读取(项目相对路径 > 用户 home) -- **缓存机制**: 避免重复读取文件 - -### 编程接口 - -```javascript -const CommandRegistry = require('./tools/command-registry.cjs'); -const registry = new CommandRegistry(); - -// 1. 获取所有命令的名称和描述(快速) -const allCommands = registry.getAllCommandsSummary(); -// { -// "/workflow:lite-plan": { -// name: 'lite-plan', -// description: '轻量级规划...' -// }, -// "/workflow:lite-execute": { ... } -// } - -// 2. 按需提取指定命令的完整信息 -const commands = registry.getCommands([ - '/workflow:lite-plan', - '/workflow:lite-execute' -]); -// { -// "/workflow:lite-plan": { -// name: 'lite-plan', -// description: '...', -// argumentHint: '[-e|--explore] "task description"', -// allowedTools: [...], -// filePath: '...' -// }, -// ... -// } -``` - -### 命令行接口 - -```bash -# 获取所有命令的名称和描述 -node .claude/skills/ccw-coordinator/tools/command-registry.cjs -node .claude/skills/ccw-coordinator/tools/command-registry.cjs --all - -# 输出: 23 个命令的简明列表 (name + description) -``` - -```bash -# 按需提取指定命令的完整信息 -node .claude/skills/ccw-coordinator/tools/command-registry.cjs lite-plan lite-execute - -# 输出: 完整信息 (name, description, argumentHint, allowedTools, filePath) -``` - -### 集成用途 - -在 `action-command-execute` 中使用: - -```javascript -// 1. 初始化时只提取任务链中的命令(完整信息) -const commandNames = command_chain.map(cmd => cmd.command); -const commandMeta = registry.getCommands(commandNames); - -// 2. 参数组装时使用 argumentHint -function assembleCommandLine(cmd, state, commandMeta) { - const cmdInfo = commandMeta[cmd.command]; - let commandLine = cmd.command; // /workflow:lite-plan - - commandLine += ' --yes'; // 自动确认 - - // 根据 argumentHint 智能组装参数 - const cmdName = cmd.command.split(':').pop(); - if (cmdName === 'lite-plan') { - commandLine += ` "${state.task_description}"`; - } else if (cmdName === 'lite-execute' && hasPlanResult(state)) { - commandLine += ' --in-memory'; - } - - return commandLine; -} - -// 3. 生成提示词(直接包含完整命令) -function generatePrompt(cmd, state, commandMeta) { - let prompt = `任务: ${state.task_description}\n`; - - // 添加前序完成 - if (state.execution_results.length > 0) { - prompt += `\n前序完成:\n${formatResults(state.execution_results)}\n`; - } - - // 组装完整命令行(关键) - const commandLine = assembleCommandLine(cmd, state, commandMeta); - prompt += `\n${commandLine}`; - - return prompt; -} -``` - -确保 `ccw cli -p "..."` 提示词直接包含完整命令调用,而不是准则。 - -### 目录查找逻辑 - -自动查找顺序: -1. `.claude/commands/workflow` (相对于当前工作目录) -2. `~/.claude/commands/workflow` (用户 home 目录) - - - diff --git a/.claude/skills/ccw-coordinator/tools/chain-validate.cjs b/.claude/skills/ccw-coordinator/tools/chain-validate.cjs deleted file mode 100644 index 28c1edeb..00000000 --- a/.claude/skills/ccw-coordinator/tools/chain-validate.cjs +++ /dev/null @@ -1,320 +0,0 @@ -#!/usr/bin/env node - -/** - * Chain Validation Tool - * - * Validates workflow command chains against defined rules. - * - * Usage: - * node chain-validate.js plan execute test-cycle-execute - * node chain-validate.js --json "plan,execute,test-cycle-execute" - * node chain-validate.js --file custom-chain.json - */ - -const fs = require('fs'); -const path = require('path'); - -// Optional registry loading - gracefully degrade if not found -let registry = null; -try { - const registryPath = path.join(__dirname, '..', 'specs', 'chain-registry.json'); - if (fs.existsSync(registryPath)) { - registry = JSON.parse(fs.readFileSync(registryPath, 'utf8')); - } -} catch (error) { - // Registry not available - dependency validation will be skipped -} - -class ChainValidator { - constructor(registry) { - this.registry = registry; - this.errors = []; - this.warnings = []; - } - - validate(chain) { - this.errors = []; - this.warnings = []; - - this.validateSinglePlanning(chain); - this.validateCompatiblePairs(chain); - this.validateTestingPosition(chain); - this.validateReviewPosition(chain); - this.validateBugfixStandalone(chain); - this.validateDependencies(chain); - this.validateNoRedundancy(chain); - this.validateCommandExistence(chain); - - return { - valid: this.errors.length === 0, - errors: this.errors, - warnings: this.warnings - }; - } - - validateSinglePlanning(chain) { - const planningCommands = chain.filter(cmd => - ['plan', 'lite-plan', 'multi-cli-plan', 'tdd-plan'].includes(cmd) - ); - - if (planningCommands.length > 1) { - this.errors.push({ - rule: 'Single Planning Command', - message: `Too many planning commands: ${planningCommands.join(', ')}`, - severity: 'error' - }); - } - } - - validateCompatiblePairs(chain) { - const compatibility = { - 'lite-plan': ['lite-execute'], - 'multi-cli-plan': ['lite-execute', 'execute'], - 'plan': ['execute'], - 'tdd-plan': ['execute'] - }; - - const planningCmd = chain.find(cmd => - ['plan', 'lite-plan', 'multi-cli-plan', 'tdd-plan'].includes(cmd) - ); - - const executionCmd = chain.find(cmd => - ['execute', 'lite-execute'].includes(cmd) - ); - - if (planningCmd && executionCmd) { - const compatible = compatibility[planningCmd] || []; - if (!compatible.includes(executionCmd)) { - this.errors.push({ - rule: 'Compatible Pairs', - message: `${planningCmd} incompatible with ${executionCmd}`, - fix: `Use ${planningCmd} with ${compatible.join(' or ')}`, - severity: 'error' - }); - } - } - } - - validateTestingPosition(chain) { - const executionIdx = chain.findIndex(cmd => - ['execute', 'lite-execute', 'develop-with-file'].includes(cmd) - ); - - const testingIdx = chain.findIndex(cmd => - ['test-cycle-execute', 'tdd-verify', 'test-gen', 'test-fix-gen'].includes(cmd) - ); - - if (testingIdx !== -1 && executionIdx !== -1 && executionIdx > testingIdx) { - this.errors.push({ - rule: 'Testing After Execution', - message: 'Testing commands must come after execution', - severity: 'error' - }); - } - - if (testingIdx !== -1 && executionIdx === -1) { - const hasTestGen = chain.some(cmd => ['test-gen', 'test-fix-gen'].includes(cmd)); - if (!hasTestGen) { - this.warnings.push({ - rule: 'Testing After Execution', - message: 'test-cycle-execute without execution context - needs test-gen or execute first', - severity: 'warning' - }); - } - } - } - - validateReviewPosition(chain) { - const executionIdx = chain.findIndex(cmd => - ['execute', 'lite-execute'].includes(cmd) - ); - - const reviewIdx = chain.findIndex(cmd => - cmd.includes('review') - ); - - if (reviewIdx !== -1 && executionIdx !== -1 && executionIdx > reviewIdx) { - this.errors.push({ - rule: 'Review After Changes', - message: 'Review commands must come after execution', - severity: 'error' - }); - } - - if (reviewIdx !== -1 && executionIdx === -1) { - const isModuleReview = chain[reviewIdx] === 'review-module-cycle'; - if (!isModuleReview) { - this.warnings.push({ - rule: 'Review After Changes', - message: 'Review without execution - needs git changes to review', - severity: 'warning' - }); - } - } - } - - validateBugfixStandalone(chain) { - if (chain.includes('lite-fix')) { - const others = chain.filter(cmd => cmd !== 'lite-fix'); - if (others.length > 0) { - this.errors.push({ - rule: 'BugFix Standalone', - message: 'lite-fix must be standalone, cannot combine with other commands', - fix: 'Use lite-fix alone OR use plan + execute for larger changes', - severity: 'error' - }); - } - } - } - - validateDependencies(chain) { - // Skip if registry not available - if (!this.registry || !this.registry.commands) { - return; - } - - for (let i = 0; i < chain.length; i++) { - const cmd = chain[i]; - const cmdMeta = this.registry.commands[cmd]; - - if (!cmdMeta) continue; - - const deps = cmdMeta.dependencies || []; - const depsOptional = cmdMeta.dependencies_optional || false; - - if (deps.length > 0 && !depsOptional) { - const hasDependency = deps.some(dep => { - const depIdx = chain.indexOf(dep); - return depIdx !== -1 && depIdx < i; - }); - - if (!hasDependency) { - this.errors.push({ - rule: 'Dependency Satisfaction', - message: `${cmd} requires ${deps.join(' or ')} before it`, - severity: 'error' - }); - } - } - } - } - - validateNoRedundancy(chain) { - const seen = new Set(); - const duplicates = []; - - for (const cmd of chain) { - if (seen.has(cmd)) { - duplicates.push(cmd); - } - seen.add(cmd); - } - - if (duplicates.length > 0) { - this.errors.push({ - rule: 'No Redundant Commands', - message: `Duplicate commands: ${duplicates.join(', ')}`, - severity: 'error' - }); - } - } - - validateCommandExistence(chain) { - // Skip if registry not available - if (!this.registry || !this.registry.commands) { - return; - } - - for (const cmd of chain) { - if (!this.registry.commands[cmd]) { - this.errors.push({ - rule: 'Command Existence', - message: `Unknown command: ${cmd}`, - severity: 'error' - }); - } - } - } -} - -function main() { - const args = process.argv.slice(2); - - if (args.length === 0) { - console.log('Usage:'); - console.log(' chain-validate.js ...'); - console.log(' chain-validate.js --json "cmd1,cmd2,cmd3"'); - console.log(' chain-validate.js --file chain.json'); - process.exit(1); - } - - let chain; - - if (args[0] === '--json') { - chain = args[1].split(',').map(s => s.trim()); - } else if (args[0] === '--file') { - const filePath = args[1]; - - // SEC-001: 路径遍历验证 - 只允许访问工作目录下的文件 - const resolvedPath = path.resolve(filePath); - const workDir = path.resolve('.'); - if (!resolvedPath.startsWith(workDir)) { - console.error('Error: File path must be within current working directory'); - process.exit(1); - } - - // CORR-001: JSON 解析错误处理 - let fileContent; - try { - fileContent = JSON.parse(fs.readFileSync(resolvedPath, 'utf8')); - } catch (error) { - console.error(`Error: Failed to parse JSON file ${filePath}: ${error.message}`); - process.exit(1); - } - - // CORR-002: 嵌套属性 null 检查 - chain = fileContent.chain || fileContent.steps?.map(s => s.command) || []; - if (chain.length === 0) { - console.error('Error: No valid chain found in file (expected "chain" array or "steps" with "command" fields)'); - process.exit(1); - } - } else { - chain = args; - } - - const validator = new ChainValidator(registry); - const result = validator.validate(chain); - - console.log('\n=== Chain Validation Report ===\n'); - console.log('Chain:', chain.join(' → ')); - console.log(''); - - if (result.valid) { - console.log('✓ Chain is valid!\n'); - } else { - console.log('✗ Chain has errors:\n'); - result.errors.forEach(err => { - console.log(` [${err.rule}] ${err.message}`); - if (err.fix) { - console.log(` Fix: ${err.fix}`); - } - }); - console.log(''); - } - - if (result.warnings.length > 0) { - console.log('⚠ Warnings:\n'); - result.warnings.forEach(warn => { - console.log(` [${warn.rule}] ${warn.message}`); - }); - console.log(''); - } - - process.exit(result.valid ? 0 : 1); -} - -if (require.main === module) { - main(); -} - -module.exports = { ChainValidator }; diff --git a/.claude/skills/ccw-coordinator/tools/command-registry.cjs b/.claude/skills/ccw-coordinator/tools/command-registry.cjs deleted file mode 100644 index 8bf54774..00000000 --- a/.claude/skills/ccw-coordinator/tools/command-registry.cjs +++ /dev/null @@ -1,255 +0,0 @@ -#!/usr/bin/env node - -/** - * Command Registry Tool - * - * 功能: - * 1. 根据命令名称查找并提取 YAML 头 - * 2. 从全局 .claude/commands/workflow 目录读取 - * 3. 支持按需提取(不是全量扫描) - */ - -const fs = require('fs'); -const path = require('path'); -const os = require('os'); - -class CommandRegistry { - constructor(commandDir = null) { - // 优先使用传入的目录 - if (commandDir) { - this.commandDir = commandDir; - } else { - // 自动查找 .claude/commands/workflow - this.commandDir = this.findCommandDir(); - } - this.cache = {}; - } - - /** - * 自动查找 .claude/commands/workflow 目录 - * 支持: 项目相对路径、用户 home 目录 - */ - findCommandDir() { - // 1. 尝试相对于当前工作目录 - const relativePath = path.join('.claude', 'commands', 'workflow'); - if (fs.existsSync(relativePath)) { - return path.resolve(relativePath); - } - - // 2. 尝试用户 home 目录 - const homeDir = os.homedir(); - const homeCommandDir = path.join(homeDir, '.claude', 'commands', 'workflow'); - if (fs.existsSync(homeCommandDir)) { - return homeCommandDir; - } - - // 未找到时返回 null,后续操作会失败并提示 - return null; - } - - /** - * 解析 YAML 头 (简化版本) - * - * 限制: - * - 只支持简单的 key: value 对 (单行值) - * - 不支持多行值、嵌套对象、复杂列表 - * - allowed-tools 字段支持逗号分隔的字符串,自动转为数组 - * - * 示例: - * --- - * name: lite-plan - * description: "Lightweight planning workflow" - * allowed-tools: Read, Write, Bash - * --- - */ - parseYamlHeader(content) { - // 处理 Windows 行结尾 (\r\n) - const match = content.match(/^---[\r\n]+([\s\S]*?)[\r\n]+---/); - if (!match) return null; - - const yamlContent = match[1]; - const result = {}; - - try { - const lines = yamlContent.split(/[\r\n]+/); - for (const line of lines) { - const trimmed = line.trim(); - if (!trimmed || trimmed.startsWith('#')) continue; // 跳过空行和注释 - - const colonIndex = trimmed.indexOf(':'); - if (colonIndex === -1) continue; - - const key = trimmed.substring(0, colonIndex).trim(); - const value = trimmed.substring(colonIndex + 1).trim(); - - if (!key) continue; // 跳过无效行 - - // 去除引号 (单引号或双引号) - let cleanValue = value.replace(/^["']|["']$/g, ''); - - // allowed-tools 字段特殊处理:转为数组 - // 支持格式: "Read, Write, Bash" 或 "Read,Write,Bash" - if (key === 'allowed-tools') { - cleanValue = Array.isArray(cleanValue) - ? cleanValue - : cleanValue.split(',').map(t => t.trim()).filter(t => t); - } - - result[key] = cleanValue; - } - } catch (error) { - console.error('YAML parsing error:', error.message); - return null; - } - - return result; - } - - /** - * 获取单个命令的元数据 - * @param {string} commandName 命令名称 (e.g., "lite-plan" 或 "/workflow:lite-plan") - * @returns {object|null} 命令信息或 null - */ - getCommand(commandName) { - if (!this.commandDir) { - console.error('ERROR: .claude/commands/workflow 目录未找到'); - return null; - } - - // 标准化命令名称 - const normalized = commandName.startsWith('/workflow:') - ? commandName.substring('/workflow:'.length) - : commandName; - - // 检查缓存 - if (this.cache[normalized]) { - return this.cache[normalized]; - } - - // 读取命令文件 - const filePath = path.join(this.commandDir, `${normalized}.md`); - if (!fs.existsSync(filePath)) { - return null; - } - - try { - const content = fs.readFileSync(filePath, 'utf-8'); - const header = this.parseYamlHeader(content); - - if (header && header.name) { - const result = { - name: header.name, - command: `/workflow:${header.name}`, - description: header.description || '', - argumentHint: header['argument-hint'] || '', - allowedTools: Array.isArray(header['allowed-tools']) - ? header['allowed-tools'] - : (header['allowed-tools'] ? [header['allowed-tools']] : []), - filePath: filePath - }; - - // 缓存结果 - this.cache[normalized] = result; - return result; - } - } catch (error) { - console.error(`读取命令失败 ${filePath}:`, error.message); - } - - return null; - } - - /** - * 批量获取多个命令的元数据 - * @param {array} commandNames 命令名称数组 - * @returns {object} 命令信息映射 - */ - getCommands(commandNames) { - const result = {}; - - for (const name of commandNames) { - const cmd = this.getCommand(name); - if (cmd) { - result[cmd.command] = cmd; - } - } - - return result; - } - - /** - * 获取所有命令的名称和描述 - * @returns {object} 命令名称和描述的映射 - */ - getAllCommandsSummary() { - const result = {}; - const commandDir = this.commandDir; - - if (!commandDir) { - return result; - } - - try { - const files = fs.readdirSync(commandDir); - - for (const file of files) { - if (!file.endsWith('.md')) continue; - - const filePath = path.join(commandDir, file); - const stat = fs.statSync(filePath); - - if (stat.isDirectory()) continue; - - try { - const content = fs.readFileSync(filePath, 'utf-8'); - const header = this.parseYamlHeader(content); - - if (header && header.name) { - const commandName = `/workflow:${header.name}`; - result[commandName] = { - name: header.name, - description: header.description || '' - }; - } - } catch (error) { - // 跳过读取失败的文件 - continue; - } - } - } catch (error) { - // 目录读取失败 - return result; - } - - return result; - } - - /** - * 生成注册表 JSON - */ - toJSON(commands = null) { - const data = commands || this.cache; - return JSON.stringify(data, null, 2); - } -} - -// CLI 模式 -if (require.main === module) { - const args = process.argv.slice(2); - - if (args.length === 0 || args[0] === '--all') { - // 获取所有命令的名称和描述 - const registry = new CommandRegistry(); - const commands = registry.getAllCommandsSummary(); - console.log(JSON.stringify(commands, null, 2)); - process.exit(0); - } - - const registry = new CommandRegistry(); - const commands = registry.getCommands(args); - - console.log(JSON.stringify(commands, null, 2)); -} - -module.exports = CommandRegistry; - diff --git a/.claude/skills/ccw/SKILL.md b/.claude/skills/ccw/SKILL.md deleted file mode 100644 index 8c4be337..00000000 --- a/.claude/skills/ccw/SKILL.md +++ /dev/null @@ -1,522 +0,0 @@ ---- -name: ccw -description: Stateless workflow orchestrator. Auto-selects optimal workflow based on task intent. Triggers "ccw", "workflow". -allowed-tools: Task(*), SlashCommand(*), AskUserQuestion(*), Read(*), Bash(*), Grep(*), TodoWrite(*) ---- - -# CCW - Claude Code Workflow Orchestrator - -无状态工作流协调器,根据任务意图自动选择最优工作流。 - -## Workflow System Overview - -CCW 提供两个工作流系统:**Main Workflow** 和 **Issue Workflow**,协同覆盖完整的软件开发生命周期。 - -``` -┌─────────────────────────────────────────────────────────────────────────────┐ -│ Main Workflow │ -│ │ -│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ -│ │ Level 1 │ → │ Level 2 │ → │ Level 3 │ → │ Level 4 │ │ -│ │ Rapid │ │ Lightweight │ │ Standard │ │ Brainstorm │ │ -│ │ │ │ │ │ │ │ │ │ -│ │ lite-lite- │ │ lite-plan │ │ plan │ │ brainstorm │ │ -│ │ lite │ │ lite-fix │ │ tdd-plan │ │ :auto- │ │ -│ │ │ │ multi-cli- │ │ test-fix- │ │ parallel │ │ -│ │ │ │ plan │ │ gen │ │ ↓ │ │ -│ │ │ │ │ │ │ │ plan │ │ -│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │ -│ │ -│ Complexity: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━▶ │ -│ Low High │ -└─────────────────────────────────────────────────────────────────────────────┘ - │ - │ After development - ▼ -┌─────────────────────────────────────────────────────────────────────────────┐ -│ Issue Workflow │ -│ │ -│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ -│ │ Accumulate │ → │ Plan │ → │ Execute │ │ -│ │ Discover & │ │ Batch │ │ Parallel │ │ -│ │ Collect │ │ Planning │ │ Execution │ │ -│ └──────────────┘ └──────────────┘ └──────────────┘ │ -│ │ -│ Supplementary role: Maintain main branch stability, worktree isolation │ -└─────────────────────────────────────────────────────────────────────────────┘ -``` - -## Architecture - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ CCW Orchestrator (CLI-Enhanced + Requirement Analysis) │ -├─────────────────────────────────────────────────────────────────┤ -│ Phase 1 │ Input Analysis (rule-based, fast path) │ -│ Phase 1.5 │ CLI Classification (semantic, smart path) │ -│ Phase 1.75 │ Requirement Clarification (clarity < 2) │ -│ Phase 2 │ Level Selection (intent → level → workflow) │ -│ Phase 2.5 │ CLI Action Planning (high complexity) │ -│ Phase 3 │ User Confirmation (optional) │ -│ Phase 4 │ TODO Tracking Setup │ -│ Phase 5 │ Execution Loop │ -└─────────────────────────────────────────────────────────────────┘ -``` - -## Level Quick Reference - -| Level | Name | Workflows | Artifacts | Execution | -|-------|------|-----------|-----------|-----------| -| **1** | Rapid | `lite-lite-lite` | None | Direct execute | -| **2** | Lightweight | `lite-plan`, `lite-fix`, `multi-cli-plan` | Memory/Lightweight files | → `lite-execute` | -| **3** | Standard | `plan`, `tdd-plan`, `test-fix-gen` | Session persistence | → `execute` / `test-cycle-execute` | -| **4** | Brainstorm | `brainstorm:auto-parallel` → `plan` | Multi-role analysis + Session | → `execute` | -| **-** | Issue | `discover` → `plan` → `queue` → `execute` | Issue records | Worktree isolation (optional) | - -## Workflow Selection Decision Tree - -``` -Start - │ - ├─ Is it post-development maintenance? - │ ├─ Yes → Issue Workflow - │ └─ No ↓ - │ - ├─ Are requirements clear? - │ ├─ Uncertain → Level 4 (brainstorm:auto-parallel) - │ └─ Clear ↓ - │ - ├─ Need persistent Session? - │ ├─ Yes → Level 3 (plan / tdd-plan / test-fix-gen) - │ └─ No ↓ - │ - ├─ Need multi-perspective / solution comparison? - │ ├─ Yes → Level 2 (multi-cli-plan) - │ └─ No ↓ - │ - ├─ Is it a bug fix? - │ ├─ Yes → Level 2 (lite-fix) - │ └─ No ↓ - │ - ├─ Need planning? - │ ├─ Yes → Level 2 (lite-plan) - │ └─ No → Level 1 (lite-lite-lite) -``` - -## Intent Classification - -### Priority Order (with Level Mapping) - -| Priority | Intent | Patterns | Level | Flow | -|----------|--------|----------|-------|------| -| 1 | bugfix/hotfix | `urgent,production,critical` + bug | L2 | `bugfix.hotfix` | -| 1 | bugfix | `fix,bug,error,crash,fail` | L2 | `bugfix.standard` | -| 2 | issue batch | `issues,batch` + `fix,resolve` | Issue | `issue` | -| 3 | exploration | `不确定,explore,研究,what if` | L4 | `full` | -| 3 | multi-perspective | `多视角,权衡,比较方案,cross-verify` | L2 | `multi-cli-plan` | -| 4 | quick-task | `快速,简单,small,quick` + feature | L1 | `lite-lite-lite` | -| 5 | ui design | `ui,design,component,style` | L3/L4 | `ui` | -| 6 | tdd | `tdd,test-driven,先写测试` | L3 | `tdd` | -| 7 | test-fix | `测试失败,test fail,fix test` | L3 | `test-fix-gen` | -| 8 | review | `review,审查,code review` | L3 | `review-fix` | -| 9 | documentation | `文档,docs,readme` | L2 | `docs` | -| 99 | feature | complexity-based | L2/L3 | `rapid`/`coupled` | - -### Quick Selection Guide - -| Scenario | Recommended Workflow | Level | -|----------|---------------------|-------| -| Quick fixes, config adjustments | `lite-lite-lite` | 1 | -| Clear single-module features | `lite-plan → lite-execute` | 2 | -| Bug diagnosis and fix | `lite-fix` | 2 | -| Production emergencies | `lite-fix --hotfix` | 2 | -| Technology selection, solution comparison | `multi-cli-plan → lite-execute` | 2 | -| Multi-module changes, refactoring | `plan → verify → execute` | 3 | -| Test-driven development | `tdd-plan → execute → tdd-verify` | 3 | -| Test failure fixes | `test-fix-gen → test-cycle-execute` | 3 | -| New features, architecture design | `brainstorm:auto-parallel → plan → execute` | 4 | -| Post-development issue fixes | Issue Workflow | - | - -### Complexity Assessment - -```javascript -function assessComplexity(text) { - let score = 0 - if (/refactor|重构|migrate|迁移|architect|架构|system|系统/.test(text)) score += 2 - if (/multiple|多个|across|跨|all|所有|entire|整个/.test(text)) score += 2 - if (/integrate|集成|api|database|数据库/.test(text)) score += 1 - if (/security|安全|performance|性能|scale|扩展/.test(text)) score += 1 - return score >= 4 ? 'high' : score >= 2 ? 'medium' : 'low' -} -``` - -| Complexity | Flow | -|------------|------| -| high | `coupled` (plan → verify → execute) | -| medium/low | `rapid` (lite-plan → lite-execute) | - -### Dimension Extraction (WHAT/WHERE/WHY/HOW) - -从用户输入提取四个维度,用于需求澄清和工作流选择: - -| 维度 | 提取内容 | 示例模式 | -|------|----------|----------| -| **WHAT** | action + target | `创建/修复/重构/优化/分析` + 目标对象 | -| **WHERE** | scope + paths | `file/module/system` + 文件路径 | -| **WHY** | goal + motivation | `为了.../因为.../目的是...` | -| **HOW** | constraints + preferences | `必须.../不要.../应该...` | - -**Clarity Score** (0-3): -- +0.5: 有明确 action -- +0.5: 有具体 target -- +0.5: 有文件路径 -- +0.5: scope 不是 unknown -- +0.5: 有明确 goal -- +0.5: 有约束条件 -- -0.5: 包含不确定词 (`不知道/maybe/怎么`) - -### Requirement Clarification - -当 `clarity_score < 2` 时触发需求澄清: - -```javascript -if (dimensions.clarity_score < 2) { - const questions = generateClarificationQuestions(dimensions) - // 生成问题:目标是什么? 范围是什么? 有什么约束? - AskUserQuestion({ questions }) -} -``` - -**澄清问题类型**: -- 目标不明确 → "你想要对什么进行操作?" -- 范围不明确 → "操作的范围是什么?" -- 目的不明确 → "这个操作的主要目标是什么?" -- 复杂操作 → "有什么特殊要求或限制?" - -## TODO Tracking Protocol - -### CRITICAL: Append-Only Rule - -CCW 创建的 Todo **必须附加到现有列表**,不能覆盖用户的其他 Todo。 - -### Implementation - -```javascript -// 1. 使用 CCW 前缀隔离工作流 todo -const prefix = `CCW:${flowName}` - -// 2. 创建新 todo 时使用前缀格式 -TodoWrite({ - todos: [ - ...existingNonCCWTodos, // 保留用户的 todo - { content: `${prefix}: [1/N] /command:step1`, status: "in_progress", activeForm: "..." }, - { content: `${prefix}: [2/N] /command:step2`, status: "pending", activeForm: "..." } - ] -}) - -// 3. 更新状态时只修改匹配前缀的 todo -``` - -### Todo Format - -``` -CCW:{flow}: [{N}/{Total}] /command:name -``` - -### Visual Example - -``` -✓ CCW:rapid: [1/2] /workflow:lite-plan -→ CCW:rapid: [2/2] /workflow:lite-execute - 用户自己的 todo(保留不动) -``` - -### Status Management - -- 开始工作流:创建所有步骤 todo,第一步 `in_progress` -- 完成步骤:当前步骤 `completed`,下一步 `in_progress` -- 工作流结束:所有 CCW todo 标记 `completed` - -## Execution Flow - -```javascript -// 1. Check explicit command -if (input.startsWith('/workflow:') || input.startsWith('/issue:')) { - SlashCommand(input) - return -} - -// 2. Classify intent -const intent = classifyIntent(input) // See command.json intent_rules - -// 3. Select flow -const flow = selectFlow(intent) // See command.json flows - -// 4. Create todos with CCW prefix -createWorkflowTodos(flow) - -// 5. Dispatch first command -SlashCommand(flow.steps[0].command, args: input) -``` - -## CLI Tool Integration - -CCW 在特定条件下自动注入 CLI 调用: - -| Condition | CLI Inject | -|-----------|------------| -| 大量代码上下文 (≥50k chars) | `gemini --mode analysis` | -| 高复杂度任务 | `gemini --mode analysis` | -| Bug 诊断 | `gemini --mode analysis` | -| 多任务执行 (≥3 tasks) | `codex --mode write` | - -### CLI Enhancement Phases - -**Phase 1.5: CLI-Assisted Classification** - -当规则匹配不明确时,使用 CLI 辅助分类: - -| 触发条件 | 说明 | -|----------|------| -| matchCount < 2 | 多个意图模式匹配 | -| complexity = high | 高复杂度任务 | -| input > 100 chars | 长输入需要语义理解 | - -**Phase 2.5: CLI-Assisted Action Planning** - -高复杂度任务的工作流优化: - -| 触发条件 | 说明 | -|----------|------| -| complexity = high | 高复杂度任务 | -| steps >= 3 | 多步骤工作流 | -| input > 200 chars | 复杂需求描述 | - -CLI 可返回建议:`use_default` | `modify` (调整步骤) | `upgrade` (升级工作流) - -## Continuation Commands - -工作流执行中的用户控制命令: - -| 命令 | 作用 | -|------|------| -| `continue` | 继续执行下一步 | -| `skip` | 跳过当前步骤 | -| `abort` | 终止工作流 | -| `/workflow:*` | 切换到指定命令 | -| 自然语言 | 重新分析意图 | - -## Workflow Flow Details - -### Issue Workflow (Main Workflow 补充机制) - -Issue Workflow 是 Main Workflow 的**补充机制**,专注于开发后的持续维护。 - -#### 设计理念 - -| 方面 | Main Workflow | Issue Workflow | -|------|---------------|----------------| -| **用途** | 主要开发周期 | 开发后维护 | -| **时机** | 功能开发阶段 | 主工作流完成后 | -| **范围** | 完整功能实现 | 针对性修复/增强 | -| **并行性** | 依赖分析 → Agent 并行 | Worktree 隔离 (可选) | -| **分支模型** | 当前分支工作 | 可使用隔离的 worktree | - -#### 为什么 Main Workflow 不自动使用 Worktree? - -**依赖分析已解决并行性问题**: -1. 规划阶段 (`/workflow:plan`) 执行依赖分析 -2. 自动识别任务依赖和关键路径 -3. 划分为**并行组**(独立任务)和**串行链**(依赖任务) -4. Agent 并行执行独立任务,无需文件系统隔离 - -#### 两阶段生命周期 - -``` -┌─────────────────────────────────────────────────────────────────────┐ -│ Phase 1: Accumulation (积累阶段) │ -│ │ -│ Triggers: 任务完成后的 review、代码审查发现、测试失败 │ -│ │ -│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ -│ │ discover │ │ discover- │ │ new │ │ -│ │ Auto-find │ │ by-prompt │ │ Manual │ │ -│ └────────────┘ └────────────┘ └────────────┘ │ -│ │ -│ 持续积累 issues 到待处理队列 │ -└─────────────────────────────────────────────────────────────────────┘ - │ - │ 积累足够后 - ▼ -┌─────────────────────────────────────────────────────────────────────┐ -│ Phase 2: Batch Resolution (批量解决阶段) │ -│ │ -│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ -│ │ plan │ ──→ │ queue │ ──→ │ execute │ │ -│ │ --all- │ │ Optimize │ │ Parallel │ │ -│ │ pending │ │ order │ │ execution │ │ -│ └────────────┘ └────────────┘ └────────────┘ │ -│ │ -│ 支持 worktree 隔离,保持主分支稳定 │ -└─────────────────────────────────────────────────────────────────────┘ -``` - -#### 与 Main Workflow 的协作 - -``` -开发迭代循环 -┌─────────────────────────────────────────────────────────────────────┐ -│ │ -│ ┌─────────┐ ┌─────────┐ │ -│ │ Feature │ ──→ Main Workflow ──→ Done ──→│ Review │ │ -│ │ Request │ (Level 1-4) └────┬────┘ │ -│ └─────────┘ │ │ -│ ▲ │ 发现 Issues │ -│ │ ▼ │ -│ │ ┌─────────┐ │ -│ 继续 │ │ Issue │ │ -│ 新功能│ │ Workflow│ │ -│ │ └────┬────┘ │ -│ │ ┌──────────────────────────────┘ │ -│ │ │ 修复完成 │ -│ │ ▼ │ -│ ┌────┴────┐◀────── │ -│ │ Main │ Merge │ -│ │ Branch │ back │ -│ └─────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────────────┘ -``` - -#### 命令列表 - -**积累阶段:** -```bash -/issue:discover # 多视角自动发现 -/issue:discover-by-prompt # 基于提示发现 -/issue:new # 手动创建 -``` - -**批量解决阶段:** -```bash -/issue:plan --all-pending # 批量规划所有待处理 -/issue:queue # 生成优化执行队列 -/issue:execute # 并行执行 -``` - -### lite-lite-lite vs multi-cli-plan - -| 维度 | lite-lite-lite | multi-cli-plan | -|------|---------------|----------------| -| **产物** | 无文件 | IMPL_PLAN.md + plan.json + synthesis.json | -| **状态** | 无状态 | 持久化 session | -| **CLI选择** | 自动分析任务类型选择 | 配置驱动 | -| **迭代** | 通过 AskUser | 多轮收敛 | -| **执行** | 直接执行 | 通过 lite-execute | -| **适用** | 快速修复、简单功能 | 复杂多步骤实现 | - -**选择指南**: -- 任务清晰、改动范围小 → `lite-lite-lite` -- 需要多视角分析、复杂架构 → `multi-cli-plan` - -### multi-cli-plan vs lite-plan - -| 维度 | multi-cli-plan | lite-plan | -|------|---------------|-----------| -| **上下文** | ACE 语义搜索 | 手动文件模式 | -| **分析** | 多 CLI 交叉验证 | 单次规划 | -| **迭代** | 多轮直到收敛 | 单轮 | -| **置信度** | 高 (共识驱动) | 中 (单一视角) | -| **适用** | 需要多视角的复杂任务 | 直接明确的实现 | - -**选择指南**: -- 需求明确、路径清晰 → `lite-plan` -- 需要权衡、多方案比较 → `multi-cli-plan` - -## Artifact Flow Protocol - -工作流产出的自动流转机制,支持不同格式产出间的意图提取和完成度判断。 - -### 产出格式 - -| 命令 | 产出位置 | 格式 | 关键字段 | -|------|----------|------|----------| -| `/workflow:lite-plan` | memory://plan | structured_plan | tasks, files, dependencies | -| `/workflow:plan` | .workflow/{session}/IMPL_PLAN.md | markdown_plan | phases, tasks, risks | -| `/workflow:execute` | execution_log.json | execution_report | completed_tasks, errors | -| `/workflow:test-cycle-execute` | test_results.json | test_report | pass_rate, failures, coverage | -| `/workflow:review-session-cycle` | review_report.md | review_report | findings, severity_counts | - -### 意图提取 (Intent Extraction) - -流转到下一步时,自动提取关键信息: - -``` -plan → execute: - 提取: tasks (未完成), priority_order, files_to_modify, context_summary - -execute → test: - 提取: modified_files, test_scope (推断), pending_verification - -test → fix: - 条件: pass_rate < 0.95 - 提取: failures, error_messages, affected_files, suggested_fixes - -review → fix: - 条件: critical > 0 OR high > 3 - 提取: findings (critical/high), fix_priority, affected_files -``` - -### 完成度判断 - -**Test 完成度路由**: -``` -pass_rate >= 0.95 AND coverage >= 0.80 → complete -pass_rate >= 0.95 AND coverage < 0.80 → add_more_tests -pass_rate >= 0.80 → fix_failures_then_continue -pass_rate < 0.80 → major_fix_required -``` - -**Review 完成度路由**: -``` -critical == 0 AND high <= 3 → complete_or_optional_fix -critical > 0 → mandatory_fix -high > 3 → recommended_fix -``` - -### 流转决策模式 - -**plan_execute_test**: -``` -plan → execute → test - ↓ (if test fail) - extract_failures → fix → test (max 3 iterations) - ↓ (if still fail) - manual_intervention -``` - -**iterative_improvement**: -``` -execute → test → fix → test → ... - loop until: pass_rate >= 0.95 OR iterations >= 3 -``` - -### 使用示例 - -```javascript -// 执行完成后,根据产出决定下一步 -const result = await execute(plan) - -// 提取意图流转到测试 -const testContext = extractIntent('execute_to_test', result) -// testContext = { modified_files, test_scope, pending_verification } - -// 测试完成后,根据完成度决定路由 -const testResult = await test(testContext) -const nextStep = evaluateCompletion('test', testResult) -// nextStep = 'fix_failures_then_continue' if pass_rate = 0.85 -``` - -## Reference - -- [command.json](command.json) - 命令元数据、Flow 定义、意图规则、Artifact Flow diff --git a/.claude/skills/ccw/command.json b/.claude/skills/ccw/command.json deleted file mode 100644 index 35b6c520..00000000 --- a/.claude/skills/ccw/command.json +++ /dev/null @@ -1,641 +0,0 @@ -{ - "_metadata": { - "version": "2.0.0", - "description": "Unified CCW command index with capabilities, flows, and intent rules" - }, - - "capabilities": { - "explore": { - "description": "Codebase exploration and context gathering", - "commands": ["/workflow:init", "/workflow:tools:gather", "/memory:load"], - "agents": ["cli-explore-agent", "context-search-agent"] - }, - "brainstorm": { - "description": "Multi-perspective analysis and ideation", - "commands": ["/workflow:brainstorm:auto-parallel", "/workflow:brainstorm:artifacts", "/workflow:brainstorm:synthesis"], - "roles": ["product-manager", "system-architect", "ux-expert", "data-architect", "api-designer"] - }, - "plan": { - "description": "Task planning and decomposition", - "commands": ["/workflow:lite-plan", "/workflow:plan", "/workflow:tdd-plan", "/task:create", "/task:breakdown"], - "agents": ["cli-lite-planning-agent", "action-planning-agent"] - }, - "verify": { - "description": "Plan and quality verification", - "commands": ["/workflow:plan-verify", "/workflow:tdd-verify"] - }, - "execute": { - "description": "Task execution and implementation", - "commands": ["/workflow:lite-execute", "/workflow:execute", "/task:execute"], - "agents": ["code-developer", "cli-execution-agent", "universal-executor"] - }, - "bugfix": { - "description": "Bug diagnosis and fixing", - "commands": ["/workflow:lite-fix"], - "agents": ["code-developer"] - }, - "test": { - "description": "Test generation and execution", - "commands": ["/workflow:test-gen", "/workflow:test-fix-gen", "/workflow:test-cycle-execute"], - "agents": ["test-fix-agent"] - }, - "review": { - "description": "Code review and quality analysis", - "commands": ["/workflow:review-session-cycle", "/workflow:review-module-cycle", "/workflow:review", "/workflow:review-fix"] - }, - "issue": { - "description": "Issue lifecycle management - discover, accumulate, batch resolve", - "commands": ["/issue:new", "/issue:discover", "/issue:discover-by-prompt", "/issue:plan", "/issue:queue", "/issue:execute", "/issue:manage"], - "agents": ["issue-plan-agent", "issue-queue-agent", "cli-explore-agent"], - "lifecycle": { - "accumulation": { - "description": "任务完成后进行需求扩展、bug分析、测试发现", - "triggers": ["post-task review", "code review findings", "test failures"], - "commands": ["/issue:discover", "/issue:discover-by-prompt", "/issue:new"] - }, - "batch_resolution": { - "description": "积累的issue集中规划和并行执行", - "flow": ["plan", "queue", "execute"], - "commands": ["/issue:plan --all-pending", "/issue:queue", "/issue:execute"] - } - } - }, - "ui-design": { - "description": "UI design and prototyping", - "commands": ["/workflow:ui-design:explore-auto", "/workflow:ui-design:imitate-auto", "/workflow:ui-design:design-sync"], - "agents": ["ui-design-agent"] - }, - "memory": { - "description": "Documentation and knowledge management", - "commands": ["/memory:docs", "/memory:update-related", "/memory:update-full", "/memory:skill-memory"], - "agents": ["doc-generator", "memory-bridge"] - } - }, - - "flows": { - "_level_guide": { - "L1": "Rapid - No artifacts, direct execution", - "L2": "Lightweight - Memory/lightweight files, → lite-execute", - "L3": "Standard - Session persistence, → execute/test-cycle-execute", - "L4": "Brainstorm - Multi-role analysis + Session, → execute" - }, - "lite-lite-lite": { - "name": "Ultra-Rapid Execution", - "level": "L1", - "description": "零文件 + 自动CLI选择 + 语义描述 + 直接执行", - "complexity": ["low"], - "artifacts": "none", - "steps": [ - { "phase": "clarify", "description": "需求澄清 (AskUser if needed)" }, - { "phase": "auto-select", "description": "任务分析 → 自动选择CLI组合" }, - { "phase": "multi-cli", "description": "并行多CLI分析" }, - { "phase": "decision", "description": "展示结果 → AskUser决策" }, - { "phase": "execute", "description": "直接执行 (无中间文件)" } - ], - "cli_hints": { - "analysis": { "tool": "auto", "mode": "analysis", "parallel": true }, - "execution": { "tool": "auto", "mode": "write" } - }, - "estimated_time": "10-30 min" - }, - "rapid": { - "name": "Rapid Iteration", - "level": "L2", - "description": "内存规划 + 直接执行", - "complexity": ["low", "medium"], - "artifacts": "memory://plan", - "steps": [ - { "command": "/workflow:lite-plan", "optional": false, "auto_continue": true }, - { "command": "/workflow:lite-execute", "optional": false } - ], - "cli_hints": { - "explore_phase": { "tool": "gemini", "mode": "analysis", "trigger": "needs_exploration" }, - "execution": { "tool": "codex", "mode": "write", "trigger": "complexity >= medium" } - }, - "estimated_time": "15-45 min" - }, - "multi-cli-plan": { - "name": "Multi-CLI Collaborative Planning", - "level": "L2", - "description": "ACE上下文 + 多CLI协作分析 + 迭代收敛 + 计划生成", - "complexity": ["medium", "high"], - "artifacts": ".workflow/.multi-cli-plan/{session}/", - "steps": [ - { "command": "/workflow:multi-cli-plan", "optional": false, "phases": [ - "context_gathering: ACE语义搜索", - "multi_cli_discussion: cli-discuss-agent多轮分析", - "present_options: 展示解决方案", - "user_decision: 用户选择", - "plan_generation: cli-lite-planning-agent生成计划" - ]}, - { "command": "/workflow:lite-execute", "optional": false } - ], - "vs_lite_plan": { - "context": "ACE semantic search vs Manual file patterns", - "analysis": "Multi-CLI cross-verification vs Single-pass planning", - "iteration": "Multiple rounds until convergence vs Single round", - "confidence": "High (consensus-based) vs Medium (single perspective)", - "best_for": "Complex tasks needing multiple perspectives vs Straightforward implementations" - }, - "agents": ["cli-discuss-agent", "cli-lite-planning-agent"], - "cli_hints": { - "discussion": { "tools": ["gemini", "codex", "claude"], "mode": "analysis", "parallel": true }, - "planning": { "tool": "gemini", "mode": "analysis" } - }, - "estimated_time": "30-90 min" - }, - "coupled": { - "name": "Standard Planning", - "level": "L3", - "description": "完整规划 + 验证 + 执行", - "complexity": ["medium", "high"], - "artifacts": ".workflow/active/{session}/", - "steps": [ - { "command": "/workflow:plan", "optional": false }, - { "command": "/workflow:plan-verify", "optional": false, "auto_continue": true }, - { "command": "/workflow:execute", "optional": false }, - { "command": "/workflow:review", "optional": true } - ], - "cli_hints": { - "pre_analysis": { "tool": "gemini", "mode": "analysis", "trigger": "always" }, - "execution": { "tool": "codex", "mode": "write", "trigger": "always" } - }, - "estimated_time": "2-4 hours" - }, - "full": { - "name": "Full Exploration (Brainstorm)", - "level": "L4", - "description": "头脑风暴 + 规划 + 执行", - "complexity": ["high"], - "artifacts": ".workflow/active/{session}/.brainstorming/", - "steps": [ - { "command": "/workflow:brainstorm:auto-parallel", "optional": false, "confirm_before": true }, - { "command": "/workflow:plan", "optional": false }, - { "command": "/workflow:plan-verify", "optional": true, "auto_continue": true }, - { "command": "/workflow:execute", "optional": false } - ], - "cli_hints": { - "role_analysis": { "tool": "gemini", "mode": "analysis", "trigger": "always", "parallel": true }, - "execution": { "tool": "codex", "mode": "write", "trigger": "task_count >= 3" } - }, - "estimated_time": "1-3 hours" - }, - "bugfix": { - "name": "Bug Fix", - "level": "L2", - "description": "智能诊断 + 修复 (5 phases)", - "complexity": ["low", "medium"], - "artifacts": ".workflow/.lite-fix/{bug-slug}-{date}/", - "variants": { - "standard": [{ "command": "/workflow:lite-fix", "optional": false }], - "hotfix": [{ "command": "/workflow:lite-fix --hotfix", "optional": false }] - }, - "phases": [ - "Phase 1: Bug Analysis & Diagnosis (severity pre-assessment)", - "Phase 2: Clarification (optional, AskUserQuestion)", - "Phase 3: Fix Planning (Low/Medium → Claude, High/Critical → cli-lite-planning-agent)", - "Phase 4: Confirmation & Selection", - "Phase 5: Execute (→ lite-execute --mode bugfix)" - ], - "cli_hints": { - "diagnosis": { "tool": "gemini", "mode": "analysis", "trigger": "always" }, - "fix": { "tool": "codex", "mode": "write", "trigger": "severity >= medium" } - }, - "estimated_time": "10-30 min" - }, - "issue": { - "name": "Issue Lifecycle", - "level": "Supplementary", - "description": "发现积累 → 批量规划 → 队列优化 → 并行执行 (Main Workflow 补充机制)", - "complexity": ["medium", "high"], - "artifacts": ".workflow/.issues/", - "purpose": "Post-development continuous maintenance, maintain main branch stability", - "phases": { - "accumulation": { - "description": "项目迭代中持续发现和积累issue", - "commands": ["/issue:discover", "/issue:discover-by-prompt", "/issue:new"], - "trigger": "post-task, code-review, test-failure" - }, - "resolution": { - "description": "集中规划和执行积累的issue", - "steps": [ - { "command": "/issue:plan --all-pending", "optional": false }, - { "command": "/issue:queue", "optional": false }, - { "command": "/issue:execute", "optional": false } - ] - } - }, - "worktree_support": { - "description": "可选的 worktree 隔离,保持主分支稳定", - "use_case": "主开发完成后的 issue 修复" - }, - "cli_hints": { - "discovery": { "tool": "gemini", "mode": "analysis", "trigger": "perspective_analysis", "parallel": true }, - "solution_generation": { "tool": "gemini", "mode": "analysis", "trigger": "always", "parallel": true }, - "batch_execution": { "tool": "codex", "mode": "write", "trigger": "always" } - }, - "estimated_time": "1-4 hours" - }, - "tdd": { - "name": "Test-Driven Development", - "level": "L3", - "description": "TDD规划 + 执行 + 验证 (6 phases)", - "complexity": ["medium", "high"], - "artifacts": ".workflow/active/{session}/", - "steps": [ - { "command": "/workflow:tdd-plan", "optional": false }, - { "command": "/workflow:plan-verify", "optional": true, "auto_continue": true }, - { "command": "/workflow:execute", "optional": false }, - { "command": "/workflow:tdd-verify", "optional": false } - ], - "tdd_structure": { - "description": "Each IMPL task contains complete internal Red-Green-Refactor cycle", - "meta": "tdd_workflow: true", - "flow_control": "implementation_approach contains 3 steps (red/green/refactor)" - }, - "cli_hints": { - "test_strategy": { "tool": "gemini", "mode": "analysis", "trigger": "always" }, - "red_green_refactor": { "tool": "codex", "mode": "write", "trigger": "always" } - }, - "estimated_time": "1-3 hours" - }, - "test-fix": { - "name": "Test Fix Generation", - "level": "L3", - "description": "测试修复生成 + 执行循环 (5 phases)", - "complexity": ["medium", "high"], - "artifacts": ".workflow/active/WFS-test-{session}/", - "dual_mode": { - "session_mode": { "input": "WFS-xxx", "context_source": "Source session summaries" }, - "prompt_mode": { "input": "Text/file path", "context_source": "Direct codebase analysis" } - }, - "steps": [ - { "command": "/workflow:test-fix-gen", "optional": false }, - { "command": "/workflow:test-cycle-execute", "optional": false } - ], - "task_structure": [ - "IMPL-001.json (test understanding & generation)", - "IMPL-001.5-review.json (quality gate)", - "IMPL-002.json (test execution & fix cycle)" - ], - "cli_hints": { - "analysis": { "tool": "gemini", "mode": "analysis", "trigger": "always" }, - "fix_cycle": { "tool": "codex", "mode": "write", "trigger": "pass_rate < 0.95" } - }, - "estimated_time": "1-2 hours" - }, - "ui": { - "name": "UI-First Development", - "level": "L3/L4", - "description": "UI设计 + 规划 + 执行", - "complexity": ["medium", "high"], - "artifacts": ".workflow/active/{session}/", - "variants": { - "explore": [ - { "command": "/workflow:ui-design:explore-auto", "optional": false }, - { "command": "/workflow:ui-design:design-sync", "optional": false, "auto_continue": true }, - { "command": "/workflow:plan", "optional": false }, - { "command": "/workflow:execute", "optional": false } - ], - "imitate": [ - { "command": "/workflow:ui-design:imitate-auto", "optional": false }, - { "command": "/workflow:ui-design:design-sync", "optional": false, "auto_continue": true }, - { "command": "/workflow:plan", "optional": false }, - { "command": "/workflow:execute", "optional": false } - ] - }, - "estimated_time": "2-4 hours" - }, - "review-fix": { - "name": "Review and Fix", - "level": "L3", - "description": "多维审查 + 自动修复", - "complexity": ["medium"], - "artifacts": ".workflow/active/{session}/review_report.md", - "steps": [ - { "command": "/workflow:review-session-cycle", "optional": false }, - { "command": "/workflow:review-fix", "optional": true } - ], - "cli_hints": { - "multi_dimension_review": { "tool": "gemini", "mode": "analysis", "trigger": "always", "parallel": true }, - "auto_fix": { "tool": "codex", "mode": "write", "trigger": "findings_count >= 3" } - }, - "estimated_time": "30-90 min" - }, - "docs": { - "name": "Documentation", - "level": "L2", - "description": "批量文档生成", - "complexity": ["low", "medium"], - "variants": { - "incremental": [{ "command": "/memory:update-related", "optional": false }], - "full": [ - { "command": "/memory:docs", "optional": false }, - { "command": "/workflow:execute", "optional": false } - ] - }, - "estimated_time": "15-60 min" - } - }, - - "intent_rules": { - "_level_mapping": { - "description": "Intent → Level → Flow mapping guide", - "L1": ["lite-lite-lite"], - "L2": ["rapid", "bugfix", "multi-cli-plan", "docs"], - "L3": ["coupled", "tdd", "test-fix", "review-fix", "ui"], - "L4": ["full"], - "Supplementary": ["issue"] - }, - "bugfix": { - "priority": 1, - "level": "L2", - "variants": { - "hotfix": { - "patterns": ["hotfix", "urgent", "production", "critical", "emergency", "紧急", "生产环境", "线上"], - "flow": "bugfix.hotfix" - }, - "standard": { - "patterns": ["fix", "bug", "error", "issue", "crash", "broken", "fail", "wrong", "修复", "错误", "崩溃"], - "flow": "bugfix.standard" - } - } - }, - "issue_batch": { - "priority": 2, - "level": "Supplementary", - "patterns": { - "batch": ["issues", "batch", "queue", "多个", "批量"], - "action": ["fix", "resolve", "处理", "解决"] - }, - "require_both": true, - "flow": "issue" - }, - "exploration": { - "priority": 3, - "level": "L4", - "patterns": ["不确定", "不知道", "explore", "研究", "分析一下", "怎么做", "what if", "探索"], - "flow": "full" - }, - "multi_perspective": { - "priority": 3, - "level": "L2", - "patterns": ["多视角", "权衡", "比较方案", "cross-verify", "多CLI", "协作分析"], - "flow": "multi-cli-plan" - }, - "quick_task": { - "priority": 4, - "level": "L1", - "patterns": ["快速", "简单", "small", "quick", "simple", "trivial", "小改动"], - "flow": "lite-lite-lite" - }, - "ui_design": { - "priority": 5, - "level": "L3/L4", - "patterns": ["ui", "界面", "design", "设计", "component", "组件", "style", "样式", "layout", "布局"], - "variants": { - "imitate": { "triggers": ["参考", "模仿", "像", "类似"], "flow": "ui.imitate" }, - "explore": { "triggers": [], "flow": "ui.explore" } - } - }, - "tdd": { - "priority": 6, - "level": "L3", - "patterns": ["tdd", "test-driven", "测试驱动", "先写测试", "test first"], - "flow": "tdd" - }, - "test_fix": { - "priority": 7, - "level": "L3", - "patterns": ["测试失败", "test fail", "fix test", "test error", "pass rate", "coverage gap"], - "flow": "test-fix" - }, - "review": { - "priority": 8, - "level": "L3", - "patterns": ["review", "审查", "检查代码", "code review", "质量检查"], - "flow": "review-fix" - }, - "documentation": { - "priority": 9, - "level": "L2", - "patterns": ["文档", "documentation", "docs", "readme"], - "variants": { - "incremental": { "triggers": ["更新", "增量"], "flow": "docs.incremental" }, - "full": { "triggers": ["全部", "完整"], "flow": "docs.full" } - } - }, - "feature": { - "priority": 99, - "complexity_map": { - "high": { "level": "L3", "flow": "coupled" }, - "medium": { "level": "L2", "flow": "rapid" }, - "low": { "level": "L1", "flow": "lite-lite-lite" } - } - } - }, - - "complexity_indicators": { - "high": { - "threshold": 4, - "patterns": { - "architecture": { "keywords": ["refactor", "重构", "migrate", "迁移", "architect", "架构", "system", "系统"], "weight": 2 }, - "multi_module": { "keywords": ["multiple", "多个", "across", "跨", "all", "所有", "entire", "整个"], "weight": 2 }, - "integration": { "keywords": ["integrate", "集成", "api", "database", "数据库"], "weight": 1 }, - "quality": { "keywords": ["security", "安全", "performance", "性能", "scale", "扩展"], "weight": 1 } - } - }, - "medium": { "threshold": 2 }, - "low": { "threshold": 0 } - }, - - "cli_tools": { - "gemini": { - "strengths": ["超长上下文", "深度分析", "架构理解", "执行流追踪"], - "triggers": ["分析", "理解", "设计", "架构", "诊断"], - "mode": "analysis" - }, - "qwen": { - "strengths": ["代码模式识别", "多维度分析"], - "triggers": ["评估", "对比", "验证"], - "mode": "analysis" - }, - "codex": { - "strengths": ["精确代码生成", "自主执行"], - "triggers": ["实现", "重构", "修复", "生成"], - "mode": "write" - } - }, - - "cli_injection_rules": { - "context_gathering": { "trigger": "file_read >= 50k OR module_count >= 5", "inject": "gemini --mode analysis" }, - "pre_planning_analysis": { "trigger": "complexity === high", "inject": "gemini --mode analysis" }, - "debug_diagnosis": { "trigger": "intent === bugfix AND root_cause_unclear", "inject": "gemini --mode analysis" }, - "code_review": { "trigger": "step === review", "inject": "gemini --mode analysis" }, - "implementation": { "trigger": "step === execute AND task_count >= 3", "inject": "codex --mode write" } - }, - - "artifact_flow": { - "_description": "定义工作流产出的格式、意图提取和流转规则", - - "outputs": { - "/workflow:lite-plan": { - "artifact": "memory://plan", - "format": "structured_plan", - "fields": ["tasks", "files", "dependencies", "approach"] - }, - "/workflow:plan": { - "artifact": ".workflow/{session}/IMPL_PLAN.md", - "format": "markdown_plan", - "fields": ["phases", "tasks", "dependencies", "risks", "test_strategy"] - }, - "/workflow:multi-cli-plan": { - "artifact": ".workflow/.multi-cli-plan/{session}/", - "format": "multi_file", - "files": ["IMPL_PLAN.md", "plan.json", "synthesis.json"], - "fields": ["consensus", "divergences", "recommended_approach", "tasks"] - }, - "/workflow:lite-execute": { - "artifact": "git_changes", - "format": "code_diff", - "fields": ["modified_files", "added_files", "deleted_files", "build_status"] - }, - "/workflow:execute": { - "artifact": ".workflow/{session}/execution_log.json", - "format": "execution_report", - "fields": ["completed_tasks", "pending_tasks", "errors", "warnings"] - }, - "/workflow:test-cycle-execute": { - "artifact": ".workflow/{session}/test_results.json", - "format": "test_report", - "fields": ["pass_rate", "failures", "coverage", "duration"] - }, - "/workflow:review-session-cycle": { - "artifact": ".workflow/{session}/review_report.md", - "format": "review_report", - "fields": ["findings", "severity_counts", "recommendations"] - }, - "/workflow:lite-fix": { - "artifact": "git_changes", - "format": "fix_report", - "fields": ["root_cause", "fix_applied", "files_modified", "verification_status"] - } - }, - - "intent_extraction": { - "plan_to_execute": { - "from": ["lite-plan", "plan", "multi-cli-plan"], - "to": ["lite-execute", "execute"], - "extract": { - "tasks": "$.tasks[] | filter(status != 'completed')", - "priority_order": "$.tasks | sort_by(priority)", - "files_to_modify": "$.tasks[].files | flatten | unique", - "dependencies": "$.dependencies", - "context_summary": "$.approach OR $.recommended_approach" - } - }, - "execute_to_test": { - "from": ["lite-execute", "execute"], - "to": ["test-cycle-execute", "test-fix-gen"], - "extract": { - "modified_files": "$.modified_files", - "test_scope": "infer_from($.modified_files)", - "build_status": "$.build_status", - "pending_verification": "$.completed_tasks | needs_test" - } - }, - "test_to_fix": { - "from": ["test-cycle-execute"], - "to": ["lite-fix", "review-fix"], - "condition": "$.pass_rate < 0.95", - "extract": { - "failures": "$.failures", - "error_messages": "$.failures[].message", - "affected_files": "$.failures[].file", - "suggested_fixes": "$.failures[].suggested_fix" - } - }, - "review_to_fix": { - "from": ["review-session-cycle", "review-module-cycle"], - "to": ["review-fix"], - "condition": "$.severity_counts.critical > 0 OR $.severity_counts.high > 3", - "extract": { - "findings": "$.findings | filter(severity in ['critical', 'high'])", - "fix_priority": "$.findings | group_by(category) | sort_by(severity)", - "affected_files": "$.findings[].file | unique" - } - } - }, - - "completion_criteria": { - "plan": { - "required": ["has_tasks", "has_files"], - "optional": ["has_tests", "no_blocking_risks"], - "threshold": 0.8, - "routing": { - "complete": "proceed_to_execute", - "incomplete": "clarify_requirements" - } - }, - "execute": { - "required": ["all_tasks_attempted", "no_critical_errors"], - "optional": ["build_passes", "lint_passes"], - "threshold": 1.0, - "routing": { - "complete": "proceed_to_test_or_review", - "partial": "continue_execution", - "failed": "diagnose_and_retry" - } - }, - "test": { - "metrics": { - "pass_rate": { "target": 0.95, "minimum": 0.80 }, - "coverage": { "target": 0.80, "minimum": 0.60 } - }, - "routing": { - "pass_rate >= 0.95 AND coverage >= 0.80": "complete", - "pass_rate >= 0.95 AND coverage < 0.80": "add_more_tests", - "pass_rate >= 0.80": "fix_failures_then_continue", - "pass_rate < 0.80": "major_fix_required" - } - }, - "review": { - "metrics": { - "critical_findings": { "target": 0, "maximum": 0 }, - "high_findings": { "target": 0, "maximum": 3 } - }, - "routing": { - "critical == 0 AND high <= 3": "complete_or_optional_fix", - "critical > 0": "mandatory_fix", - "high > 3": "recommended_fix" - } - } - }, - - "flow_decisions": { - "_description": "根据产出完成度决定下一步", - "patterns": { - "plan_execute_test": { - "sequence": ["plan", "execute", "test"], - "on_test_fail": { - "action": "extract_failures_and_fix", - "max_iterations": 3, - "fallback": "manual_intervention" - } - }, - "plan_execute_review": { - "sequence": ["plan", "execute", "review"], - "on_review_issues": { - "action": "prioritize_and_fix", - "auto_fix_threshold": "severity < high" - } - }, - "iterative_improvement": { - "sequence": ["execute", "test", "fix"], - "loop_until": "pass_rate >= 0.95 OR iterations >= 3", - "on_loop_exit": "report_status" - } - } - } - } -} diff --git a/ccw/src/tools/command-registry.test.ts b/ccw/src/tools/command-registry.test.ts new file mode 100644 index 00000000..f3b58127 --- /dev/null +++ b/ccw/src/tools/command-registry.test.ts @@ -0,0 +1,669 @@ +/** + * CommandRegistry Tests + * + * Test coverage: + * - YAML header parsing + * - Command metadata extraction + * - Directory detection (relative and home) + * - Caching mechanism + * - Batch operations + * - Categorization + * - Error handling + */ + +import { CommandRegistry, createCommandRegistry, getAllCommandsSync, getCommandSync } from './command-registry'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as os from 'os'; + +// Mock fs module +jest.mock('fs'); +jest.mock('os'); + +describe('CommandRegistry', () => { + const mockReadFileSync = fs.readFileSync as jest.MockedFunction; + const mockExistsSync = fs.existsSync as jest.MockedFunction; + const mockReaddirSync = fs.readdirSync as jest.MockedFunction; + const mockStatSync = fs.statSync as jest.MockedFunction; + const mockHomedir = os.homedir as jest.MockedFunction; + + // Sample YAML headers + const sampleLitePlanYaml = `--- +name: lite-plan +description: Quick planning for simple features +argument-hint: "\"feature description\"" +allowed-tools: Task(*), Read(*), Write(*), Bash(*) +--- + +# Content here`; + + const sampleExecuteYaml = `--- +name: execute +description: Execute implementation from plan +argument-hint: "--resume-session=\"WFS-xxx\"" +allowed-tools: Task(*), Bash(*) +--- + +# Content here`; + + const sampleTestYaml = `--- +name: test-cycle-execute +description: Run tests and fix failures +argument-hint: "--session=\"WFS-xxx\"" +allowed-tools: Task(*), Bash(*) +--- + +# Content here`; + + const sampleReviewYaml = `--- +name: review +description: Code review workflow +argument-hint: "--session=\"WFS-xxx\"" +allowed-tools: Task(*), Read(*) +--- + +# Content here`; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('constructor & directory detection', () => { + it('should use provided command directory', () => { + const customDir = '/custom/path'; + const registry = new CommandRegistry(customDir); + + expect((registry as any).commandDir).toBe(customDir); + }); + + it('should auto-detect relative .claude/commands/workflow directory', () => { + mockExistsSync.mockImplementation((path: string) => { + return path === '.claude/commands/workflow'; + }); + + const registry = new CommandRegistry(); + + expect((registry as any).commandDir).toBe('.claude/commands/workflow'); + expect(mockExistsSync).toHaveBeenCalledWith('.claude/commands/workflow'); + }); + + it('should auto-detect home directory ~/.claude/commands/workflow', () => { + mockExistsSync.mockImplementation((checkPath: string) => { + return checkPath === path.join('/home/user', '.claude', 'commands', 'workflow'); + }); + mockHomedir.mockReturnValue('/home/user'); + + const registry = new CommandRegistry(); + + expect((registry as any).commandDir).toBe( + path.join('/home/user', '.claude', 'commands', 'workflow') + ); + }); + + it('should return null if no command directory found', () => { + mockExistsSync.mockReturnValue(false); + mockHomedir.mockReturnValue('/home/user'); + + const registry = new CommandRegistry(); + + expect((registry as any).commandDir).toBeNull(); + }); + }); + + describe('parseYamlHeader', () => { + it('should parse simple YAML header with Unix line endings', () => { + const yaml = `--- +name: test-command +description: Test description +argument-hint: "\"test\"" +allowed-tools: Task(*), Read(*) +--- + +Content here`; + + const registry = new CommandRegistry('/fake/path'); + const result = (registry as any).parseYamlHeader(yaml); + + expect(result).toEqual({ + name: 'test-command', + description: 'Test description', + 'argument-hint': '"test"', + 'allowed-tools': 'Task(*), Read(*)' + }); + }); + + it('should parse YAML header with Windows line endings (\\r\\n)', () => { + const yaml = `---\r\nname: test-command\r\ndescription: Test\r\n---`; + + const registry = new CommandRegistry('/fake/path'); + const result = (registry as any).parseYamlHeader(yaml); + + expect(result).toEqual({ + name: 'test-command', + description: 'Test' + }); + }); + + it('should handle quoted values', () => { + const yaml = `--- +name: "cmd" +description: 'double quoted' +---`; + + const registry = new CommandRegistry('/fake/path'); + const result = (registry as any).parseYamlHeader(yaml); + + expect(result).toEqual({ + name: 'cmd', + description: 'double quoted' + }); + }); + + it('should parse allowed-tools and trim spaces', () => { + const yaml = `--- +name: test +allowed-tools: Task(*), Read(*) , Write(*), Bash(*) +---`; + + const registry = new CommandRegistry('/fake/path'); + const result = (registry as any).parseYamlHeader(yaml); + + expect(result['allowed-tools']).toBe('Task(*), Read(*), Write(*), Bash(*)'); + }); + + it('should skip comments and empty lines', () => { + const yaml = `--- +# This is a comment +name: test-command + +# Another comment +description: Test + +---`; + + const registry = new CommandRegistry('/fake/path'); + const result = (registry as any).parseYamlHeader(yaml); + + expect(result).toEqual({ + name: 'test-command', + description: 'Test' + }); + }); + + it('should return null for missing YAML markers', () => { + const yaml = `name: test-command +description: Test`; + + const registry = new CommandRegistry('/fake/path'); + const result = (registry as any).parseYamlHeader(yaml); + + expect(result).toBeNull(); + }); + + it('should return null for malformed YAML', () => { + const yaml = `--- +invalid yaml content without colons +---`; + + const registry = new CommandRegistry('/fake/path'); + const result = (registry as any).parseYamlHeader(yaml); + + expect(result).toEqual({}); + }); + }); + + describe('getCommand', () => { + it('should get command metadata by name', () => { + const cmdDir = '/workflows'; + mockExistsSync.mockImplementation((checkPath: string) => { + return checkPath === path.join(cmdDir, 'lite-plan.md'); + }); + mockReadFileSync.mockReturnValue(sampleLitePlanYaml); + + const registry = new CommandRegistry(cmdDir); + const result = registry.getCommand('lite-plan'); + + expect(result).toEqual({ + name: 'lite-plan', + command: '/workflow:lite-plan', + description: 'Quick planning for simple features', + argumentHint: '"feature description"', + allowedTools: ['Task(*)', 'Read(*)', 'Write(*)', 'Bash(*)'], + filePath: path.join(cmdDir, 'lite-plan.md') + }); + }); + + it('should normalize /workflow: prefix', () => { + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(true); + mockReadFileSync.mockReturnValue(sampleLitePlanYaml); + + const registry = new CommandRegistry(cmdDir); + const result = registry.getCommand('/workflow:lite-plan'); + + expect(result?.name).toBe('lite-plan'); + }); + + it('should use cache for repeated requests', () => { + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(true); + mockReadFileSync.mockReturnValue(sampleLitePlanYaml); + + const registry = new CommandRegistry(cmdDir); + + registry.getCommand('lite-plan'); + registry.getCommand('lite-plan'); + + // readFileSync should only be called once due to cache + expect(mockReadFileSync).toHaveBeenCalledTimes(1); + }); + + it('should return null if command file not found', () => { + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(false); + + const registry = new CommandRegistry(cmdDir); + const result = registry.getCommand('nonexistent'); + + expect(result).toBeNull(); + }); + + it('should return null if no command directory', () => { + mockExistsSync.mockReturnValue(false); + mockHomedir.mockReturnValue('/home/user'); + + const registry = new CommandRegistry(); + const result = registry.getCommand('lite-plan'); + + expect(result).toBeNull(); + }); + + it('should return null if YAML header is invalid', () => { + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(true); + mockReadFileSync.mockReturnValue('No YAML header here'); + + const registry = new CommandRegistry(cmdDir); + const result = registry.getCommand('lite-plan'); + + expect(result).toBeNull(); + }); + + it('should parse allowedTools correctly', () => { + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(true); + mockReadFileSync.mockReturnValue(sampleExecuteYaml); + + const registry = new CommandRegistry(cmdDir); + const result = registry.getCommand('execute'); + + expect(result?.allowedTools).toEqual(['Task(*)', 'Bash(*)']); + }); + + it('should handle empty allowedTools', () => { + const yaml = `--- +name: minimal-cmd +description: Minimal command +---`; + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(true); + mockReadFileSync.mockReturnValue(yaml); + + const registry = new CommandRegistry(cmdDir); + const result = registry.getCommand('minimal-cmd'); + + expect(result?.allowedTools).toEqual([]); + }); + }); + + describe('getCommands', () => { + it('should get multiple commands', () => { + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(true); + mockReadFileSync.mockImplementation((filePath: string) => { + if (filePath.includes('lite-plan')) return sampleLitePlanYaml; + if (filePath.includes('execute')) return sampleExecuteYaml; + return ''; + }); + + const registry = new CommandRegistry(cmdDir); + const result = registry.getCommands(['lite-plan', 'execute', 'nonexistent']); + + expect(result.size).toBe(2); + expect(result.has('/workflow:lite-plan')).toBe(true); + expect(result.has('/workflow:execute')).toBe(true); + }); + + it('should skip nonexistent commands', () => { + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(false); + + const registry = new CommandRegistry(cmdDir); + const result = registry.getCommands(['nonexistent1', 'nonexistent2']); + + expect(result.size).toBe(0); + }); + }); + + describe('getAllCommandsSummary', () => { + it('should get all commands summary', () => { + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(true); + mockReaddirSync.mockReturnValue(['lite-plan.md', 'execute.md', 'test.md'] as any); + mockStatSync.mockReturnValue({ isDirectory: () => false } as any); + mockReadFileSync.mockImplementation((filePath: string) => { + if (filePath.includes('lite-plan')) return sampleLitePlanYaml; + if (filePath.includes('execute')) return sampleExecuteYaml; + if (filePath.includes('test')) return sampleTestYaml; + return ''; + }); + + const registry = new CommandRegistry(cmdDir); + const result = registry.getAllCommandsSummary(); + + expect(result.size).toBe(3); + expect(result.get('/workflow:lite-plan')).toEqual({ + name: 'lite-plan', + description: 'Quick planning for simple features' + }); + }); + + it('should skip directories', () => { + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(true); + mockReaddirSync.mockReturnValue(['file.md', 'directory'] as any); + mockStatSync.mockImplementation((filePath: string) => ({ + isDirectory: () => filePath.includes('directory') + } as any)); + mockReadFileSync.mockReturnValue(sampleLitePlanYaml); + + const registry = new CommandRegistry(cmdDir); + const result = registry.getAllCommandsSummary(); + + // Only file.md should be processed + expect(mockReadFileSync).toHaveBeenCalledTimes(1); + }); + + it('should skip files with invalid YAML headers', () => { + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(true); + mockReaddirSync.mockReturnValue(['valid.md', 'invalid.md'] as any); + mockStatSync.mockReturnValue({ isDirectory: () => false } as any); + mockReadFileSync.mockImplementation((filePath: string) => { + if (filePath.includes('valid')) return sampleLitePlanYaml; + return 'No YAML header'; + }); + + const registry = new CommandRegistry(cmdDir); + const result = registry.getAllCommandsSummary(); + + expect(result.size).toBe(1); + }); + + it('should return empty map if no command directory', () => { + mockExistsSync.mockReturnValue(false); + mockHomedir.mockReturnValue('/home/user'); + + const registry = new CommandRegistry(); + const result = registry.getAllCommandsSummary(); + + expect(result.size).toBe(0); + }); + + it('should handle directory read errors gracefully', () => { + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(true); + mockReaddirSync.mockImplementation(() => { + throw new Error('Permission denied'); + }); + + const registry = new CommandRegistry(cmdDir); + const result = registry.getAllCommandsSummary(); + + expect(result.size).toBe(0); + }); + }); + + describe('getAllCommandsByCategory', () => { + it('should categorize commands by name patterns', () => { + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(true); + mockReaddirSync.mockReturnValue(['lite-plan.md', 'execute.md', 'test-cycle-execute.md', 'review.md'] as any); + mockStatSync.mockReturnValue({ isDirectory: () => false } as any); + mockReadFileSync.mockImplementation((filePath: string) => { + if (filePath.includes('lite-plan')) return sampleLitePlanYaml; + if (filePath.includes('execute')) return sampleExecuteYaml; + if (filePath.includes('test')) return sampleTestYaml; + if (filePath.includes('review')) return sampleReviewYaml; + return ''; + }); + + const registry = new CommandRegistry(cmdDir); + const result = registry.getAllCommandsByCategory(); + + expect(result.planning.length).toBe(1); + expect(result.execution.length).toBe(1); + expect(result.testing.length).toBe(1); + expect(result.review.length).toBe(1); + expect(result.other.length).toBe(0); + + expect(result.planning[0].name).toBe('lite-plan'); + expect(result.execution[0].name).toBe('execute'); + }); + + it('should handle commands matching multiple patterns', () => { + const yamlMultiMatch = `--- +name: test-plan +description: TDD planning +allowed-tools: Task(*) +---`; + + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(true); + mockReaddirSync.mockReturnValue(['test-plan.md'] as any); + mockStatSync.mockReturnValue({ isDirectory: () => false } as any); + mockReadFileSync.mockReturnValue(yamlMultiMatch); + + const registry = new CommandRegistry(cmdDir); + const result = registry.getAllCommandsByCategory(); + + // Should match 'plan' pattern (planning) + expect(result.planning.length).toBe(1); + }); + }); + + describe('toJSON', () => { + it('should serialize cached commands to JSON', () => { + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(true); + mockReadFileSync.mockReturnValue(sampleLitePlanYaml); + + const registry = new CommandRegistry(cmdDir); + registry.getCommand('lite-plan'); + + const json = registry.toJSON(); + + expect(json['/workflow:lite-plan']).toEqual({ + name: 'lite-plan', + command: '/workflow:lite-plan', + description: 'Quick planning for simple features', + argumentHint: '"feature description"', + allowedTools: ['Task(*)', 'Read(*)', 'Write(*)', 'Bash(*)'], + filePath: path.join(cmdDir, 'lite-plan.md') + }); + }); + + it('should only include cached commands', () => { + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(true); + mockReadFileSync.mockImplementation((filePath: string) => { + if (filePath.includes('lite-plan')) return sampleLitePlanYaml; + return sampleExecuteYaml; + }); + + const registry = new CommandRegistry(cmdDir); + registry.getCommand('lite-plan'); + // Don't call getCommand for 'execute' + + const json = registry.toJSON(); + + expect(Object.keys(json).length).toBe(1); + expect(json['/workflow:lite-plan']).toBeDefined(); + expect(json['/workflow:execute']).toBeUndefined(); + }); + }); + + describe('exported functions', () => { + it('createCommandRegistry should create new instance', () => { + mockExistsSync.mockReturnValue(true); + + const registry = createCommandRegistry('/custom/path'); + + expect((registry as any).commandDir).toBe('/custom/path'); + }); + + it('getAllCommandsSync should return all commands', () => { + mockExistsSync.mockReturnValue(true); + mockReaddirSync.mockReturnValue(['lite-plan.md'] as any); + mockStatSync.mockReturnValue({ isDirectory: () => false } as any); + mockReadFileSync.mockReturnValue(sampleLitePlanYaml); + mockHomedir.mockReturnValue('/home/user'); + + const result = getAllCommandsSync(); + + expect(result.size).toBeGreaterThanOrEqual(1); + }); + + it('getCommandSync should return specific command', () => { + mockExistsSync.mockReturnValue(true); + mockReadFileSync.mockReturnValue(sampleLitePlanYaml); + mockHomedir.mockReturnValue('/home/user'); + + const result = getCommandSync('lite-plan'); + + expect(result?.name).toBe('lite-plan'); + }); + }); + + describe('edge cases', () => { + it('should handle file read errors', () => { + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(true); + mockReadFileSync.mockImplementation(() => { + throw new Error('File read error'); + }); + + const registry = new CommandRegistry(cmdDir); + const result = registry.getCommand('lite-plan'); + + expect(result).toBeNull(); + }); + + it('should handle YAML parsing errors', () => { + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(true); + // Return something that will cause parsing to fail + mockReadFileSync.mockReturnValue('---\ninvalid: : : yaml\n---'); + + const registry = new CommandRegistry(cmdDir); + const result = registry.getCommand('lite-plan'); + + // Should return null since name is not in result + expect(result).toBeNull(); + }); + + it('should handle empty command directory', () => { + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(true); + mockReaddirSync.mockReturnValue([] as any); + + const registry = new CommandRegistry(cmdDir); + const result = registry.getAllCommandsSummary(); + + expect(result.size).toBe(0); + }); + + it('should handle non-md files in command directory', () => { + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(true); + mockReaddirSync.mockReturnValue(['lite-plan.md', 'readme.txt', '.gitignore'] as any); + mockStatSync.mockReturnValue({ isDirectory: () => false } as any); + mockReadFileSync.mockReturnValue(sampleLitePlanYaml); + + const registry = new CommandRegistry(cmdDir); + const result = registry.getAllCommandsSummary(); + + expect(result.size).toBe(1); + }); + }); + + describe('integration tests', () => { + it('should work with full workflow', () => { + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(true); + mockReaddirSync.mockReturnValue(['lite-plan.md', 'execute.md', 'test-cycle-execute.md'] as any); + mockStatSync.mockReturnValue({ isDirectory: () => false } as any); + mockReadFileSync.mockImplementation((filePath: string) => { + if (filePath.includes('lite-plan')) return sampleLitePlanYaml; + if (filePath.includes('execute')) return sampleExecuteYaml; + if (filePath.includes('test')) return sampleTestYaml; + return ''; + }); + + const registry = new CommandRegistry(cmdDir); + + // Get all summary + const summary = registry.getAllCommandsSummary(); + expect(summary.size).toBe(3); + + // Get by category + const byCategory = registry.getAllCommandsByCategory(); + expect(byCategory.planning.length).toBe(1); + expect(byCategory.execution.length).toBe(1); + expect(byCategory.testing.length).toBe(1); + + // Get specific command + const cmd = registry.getCommand('lite-plan'); + expect(cmd?.name).toBe('lite-plan'); + + // Get multiple commands + const multiple = registry.getCommands(['lite-plan', 'execute']); + expect(multiple.size).toBe(2); + + // Convert to JSON + const json = registry.toJSON(); + expect(Object.keys(json).length).toBeGreaterThan(0); + }); + + it('should maintain cache across operations', () => { + const cmdDir = '/workflows'; + mockExistsSync.mockReturnValue(true); + mockReaddirSync.mockReturnValue(['lite-plan.md', 'execute.md'] as any); + mockStatSync.mockReturnValue({ isDirectory: () => false } as any); + mockReadFileSync.mockImplementation((filePath: string) => { + if (filePath.includes('lite-plan')) return sampleLitePlanYaml; + return sampleExecuteYaml; + }); + + const registry = new CommandRegistry(cmdDir); + + // First call + registry.getCommand('lite-plan'); + const initialCallCount = mockReadFileSync.mock.calls.length; + + // getAllCommandsSummary will read all files + registry.getAllCommandsSummary(); + const afterSummaryCallCount = mockReadFileSync.mock.calls.length; + + // Second getCommand should use cache + registry.getCommand('lite-plan'); + const finalCallCount = mockReadFileSync.mock.calls.length; + + // lite-plan.md should only be read twice: + // 1. Initial getCommand + // 2. getAllCommandsSummary (must read all files) + // Not again in second getCommand due to cache + expect(finalCallCount).toBe(afterSummaryCallCount); + }); + }); +});