feat: Add comprehensive tests for CCW Loop System flow state

- Implemented loop control tasks in JSON format for testing.
- Created comprehensive test scripts for loop flow and standalone tests.
- Developed a shell script to automate the testing of the entire loop system flow, including mock endpoints and state transitions.
- Added error handling and execution history tests to ensure robustness.
- Established variable substitution and success condition evaluations in tests.
- Set up cleanup and workspace management for test environments.
This commit is contained in:
catlog22
2026-01-22 10:13:00 +08:00
parent d9f1d14d5e
commit 60eab98782
37 changed files with 12347 additions and 917 deletions

View File

@@ -0,0 +1,303 @@
# CCW Loop Skill
无状态迭代开发循环工作流,支持开发 (Develop)、调试 (Debug)、验证 (Validate) 三个阶段,每个阶段都有独立的文件记录进展。
## Overview
CCW Loop 是一个自主模式 (Autonomous) 的 Skill通过文件驱动的无状态循环帮助开发者系统化地完成开发任务。
### 核心特性
1. **无状态循环**: 每次执行从文件读取状态,不依赖内存
2. **文件驱动**: 所有进度记录在 Markdown 文件中,可审计、可回顾
3. **Gemini 辅助**: 关键决策点使用 CLI 工具进行深度分析
4. **可恢复**: 任何时候中断后可继续
5. **双模式**: 支持交互式和自动循环
### 三大阶段
- **Develop**: 任务分解 → 代码实现 → 进度记录
- **Debug**: 假设生成 → 证据收集 → 根因分析 → 修复验证
- **Validate**: 测试执行 → 覆盖率检查 → 质量评估
## Installation
已包含在 `.claude/skills/ccw-loop/`,无需额外安装。
## Usage
### 基本用法
```bash
# 启动新循环
/ccw-loop "实现用户认证功能"
# 继续现有循环
/ccw-loop --resume LOOP-auth-2026-01-22
# 自动循环模式
/ccw-loop --auto "修复登录bug并添加测试"
```
### 交互式流程
```
1. 启动: /ccw-loop "任务描述"
2. 初始化: 自动分析任务并生成子任务列表
3. 显示菜单:
- 📝 继续开发 (Develop)
- 🔍 开始调试 (Debug)
- ✅ 运行验证 (Validate)
- 📊 查看详情 (Status)
- 🏁 完成循环 (Complete)
- 🚪 退出 (Exit)
4. 执行选择的动作
5. 重复步骤 3-4 直到完成
```
### 自动循环流程
```
Develop (所有任务) → Debug (如有需要) → Validate → 完成
```
## Directory Structure
```
.workflow/.loop/{session-id}/
├── meta.json # 会话元数据 (不可修改)
├── state.json # 当前状态 (每次更新)
├── summary.md # 完成报告 (结束时生成)
├── develop/
│ ├── progress.md # 开发进度时间线
│ ├── tasks.json # 任务列表
│ └── changes.log # 代码变更日志 (NDJSON)
├── debug/
│ ├── understanding.md # 理解演变文档
│ ├── hypotheses.json # 假设历史
│ └── debug.log # 调试日志 (NDJSON)
└── validate/
├── validation.md # 验证报告
├── test-results.json # 测试结果
└── coverage.json # 覆盖率数据
```
## Action Reference
| Action | 描述 | 触发条件 |
|--------|------|----------|
| action-init | 初始化会话 | 首次启动 |
| action-menu | 显示操作菜单 | 交互模式下每次循环 |
| action-develop-with-file | 执行开发任务 | 有待处理任务 |
| action-debug-with-file | 假设驱动调试 | 需要调试 |
| action-validate-with-file | 运行测试验证 | 需要验证 |
| action-complete | 完成并生成报告 | 所有任务完成 |
详细说明见 [specs/action-catalog.md](specs/action-catalog.md)
## CLI Integration
CCW Loop 在关键决策点集成 CLI 工具:
### 任务分解 (action-init)
```bash
ccw cli -p "PURPOSE: 分解开发任务..."
--tool gemini
--mode analysis
--rule planning-breakdown-task-steps
```
### 代码实现 (action-develop)
```bash
ccw cli -p "PURPOSE: 实现功能代码..."
--tool gemini
--mode write
--rule development-implement-feature
```
### 假设生成 (action-debug - 探索)
```bash
ccw cli -p "PURPOSE: Generate debugging hypotheses..."
--tool gemini
--mode analysis
--rule analysis-diagnose-bug-root-cause
```
### 证据分析 (action-debug - 分析)
```bash
ccw cli -p "PURPOSE: Analyze debug log evidence..."
--tool gemini
--mode analysis
--rule analysis-diagnose-bug-root-cause
```
### 质量评估 (action-validate)
```bash
ccw cli -p "PURPOSE: Analyze test results and coverage..."
--tool gemini
--mode analysis
--rule analysis-review-code-quality
```
## State Management
### State Schema
参见 [phases/state-schema.md](phases/state-schema.md)
### State Transitions
```
pending → running → completed
user_exit
failed
```
### State Recovery
如果 `state.json` 损坏,可从其他文件重建:
- develop/tasks.json → develop.*
- debug/hypotheses.json → debug.*
- validate/test-results.json → validate.*
## Examples
### Example 1: 功能开发
```bash
# 1. 启动循环
/ccw-loop "Add user profile page"
# 2. 系统初始化,生成任务:
# - task-001: Create profile component
# - task-002: Add API endpoints
# - task-003: Implement tests
# 3. 选择 "继续开发"
# → 执行 task-001 (Gemini 辅助实现)
# → 更新 progress.md
# 4. 重复开发直到所有任务完成
# 5. 选择 "运行验证"
# → 运行测试
# → 检查覆盖率
# → 生成 validation.md
# 6. 选择 "完成循环"
# → 生成 summary.md
# → 询问是否扩展为 Issue
```
### Example 2: Bug 修复
```bash
# 1. 启动循环
/ccw-loop "Fix login timeout issue"
# 2. 选择 "开始调试"
# → 输入 bug 描述: "Login times out after 30s"
# → Gemini 生成假设 (H1, H2, H3)
# → 添加 NDJSON 日志
# → 提示复现 bug
# 3. 复现 bug (在应用中操作)
# 4. 再次选择 "开始调试"
# → 解析 debug.log
# → Gemini 分析证据
# → H2 确认为根因
# → 生成修复代码
# → 更新 understanding.md
# 5. 选择 "运行验证"
# → 测试通过
# 6. 完成
```
## Templates
- [progress-template.md](templates/progress-template.md): 开发进度文档模板
- [understanding-template.md](templates/understanding-template.md): 调试理解文档模板
- [validation-template.md](templates/validation-template.md): 验证报告模板
## Specifications
- [loop-requirements.md](specs/loop-requirements.md): 循环需求规范
- [action-catalog.md](specs/action-catalog.md): 动作目录
## Integration
### Dashboard Integration
CCW Loop 与 Dashboard Loop Monitor 集成:
- Dashboard 创建 Loop → 触发此 Skill
- state.json → Dashboard 实时显示
- 任务列表双向同步
- 控制按钮映射到 actions
### Issue System Integration
完成后可扩展为 Issue:
- 维度: test, enhance, refactor, doc
- 自动调用 `/issue:new`
- 上下文自动填充
## Error Handling
| 情况 | 处理 |
|------|------|
| Session 不存在 | 创建新会话 |
| state.json 损坏 | 从文件重建 |
| CLI 工具失败 | 回退到手动模式 |
| 测试失败 | 循环回到 develop/debug |
| >10 迭代 | 警告用户,建议拆分 |
## Limitations
1. **单会话限制**: 同一时间只能有一个活跃会话
2. **迭代限制**: 建议不超过 10 次迭代
3. **CLI 依赖**: 部分功能依赖 Gemini CLI 可用性
4. **测试框架**: 需要 package.json 中定义测试脚本
## Troubleshooting
### Q: 如何查看当前会话状态?
A: 在菜单中选择 "查看详情 (Status)"
### Q: 如何恢复中断的会话?
A: 使用 `--resume` 参数:
```bash
/ccw-loop --resume LOOP-xxx-2026-01-22
```
### Q: 如果 CLI 工具失败怎么办?
A: Skill 会自动降级到手动模式,提示用户手动输入
### Q: 如何添加自定义 action
A: 参见 [specs/action-catalog.md](specs/action-catalog.md) 的 "Action Extensions" 部分
## Contributing
添加新功能:
1. 创建 action 文件在 `phases/actions/`
2. 更新 orchestrator 决策逻辑
3. 添加到 action-catalog.md
4. 更新 action-menu.md
## License
MIT
---
**Version**: 1.0.0
**Last Updated**: 2026-01-22
**Author**: CCW Team

View File

@@ -0,0 +1,259 @@
---
name: ccw-loop
description: Stateless iterative development loop workflow with documented progress. Supports develop, debug, and validate phases with file-based state tracking. Triggers on "ccw-loop", "dev loop", "development loop", "开发循环", "迭代开发".
allowed-tools: Task(*), AskUserQuestion(*), Read(*), Grep(*), Glob(*), Bash(*), Edit(*), Write(*), TodoWrite(*)
---
# CCW Loop - Stateless Iterative Development Workflow
无状态迭代开发循环工作流,支持开发 (develop)、调试 (debug)、验证 (validate) 三个阶段,每个阶段都有独立的文件记录进展。
## Arguments
| Arg | Required | Description |
|-----|----------|-------------|
| task | No | Task description (for new loop, mutually exclusive with --loop-id) |
| --loop-id | No | Existing loop ID to continue (from API or previous session) |
| --auto | No | Auto-cycle mode (develop → debug → validate → complete) |
## Unified Architecture (API + Skill Integration)
```
┌─────────────────────────────────────────────────────────────────┐
│ Dashboard (UI) │
│ [Create] [Start] [Pause] [Resume] [Stop] [View Progress] │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ loop-v2-routes.ts (Control Plane) │
│ │
│ State: .loop/{loopId}.json (MASTER) │
│ Tasks: .loop/{loopId}.tasks.jsonl │
│ │
│ /start → Trigger ccw-loop skill with --loop-id │
│ /pause → Set status='paused' (skill checks before action) │
│ /stop → Set status='failed' (skill terminates) │
│ /resume → Set status='running' (skill continues) │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ ccw-loop Skill (Execution Plane) │
│ │
│ Reads/Writes: .loop/{loopId}.json (unified state) │
│ Writes: .loop/{loopId}.progress/* (progress files) │
│ │
│ BEFORE each action: │
│ → Check status: paused/stopped → exit gracefully │
│ → running → continue with action │
│ │
│ Actions: init → develop → debug → validate → complete │
└─────────────────────────────────────────────────────────────────┘
```
## Key Design Principles
1. **统一状态**: API 和 Skill 共享 `.loop/{loopId}.json` 状态文件
2. **控制信号**: Skill 每个 Action 前检查 status 字段 (paused/stopped)
3. **文件驱动**: 所有进度、理解、结果都记录在 `.loop/{loopId}.progress/`
4. **可恢复**: 任何时候可以继续之前的循环 (`--loop-id`)
5. **双触发**: 支持 API 触发 (`--loop-id`) 和直接调用 (task description)
6. **Gemini 辅助**: 使用 CLI 工具进行深度分析和假设验证
## Execution Modes
### Mode 1: Interactive (交互式)
用户手动选择每个动作,适合复杂任务。
```
用户 → 选择动作 → 执行 → 查看结果 → 选择下一动作
```
### Mode 2: Auto-Loop (自动循环)
按预设顺序自动执行,适合标准开发流程。
```
Develop → Debug → Validate → (如有问题) → Develop → ...
```
## Session Structure (Unified Location)
```
.loop/
├── {loopId}.json # 主状态文件 (API + Skill 共享)
├── {loopId}.tasks.jsonl # 任务列表 (API 管理)
└── {loopId}.progress/ # Skill 进度文件
├── develop.md # 开发进度记录
├── debug.md # 理解演变文档
├── validate.md # 验证报告
├── changes.log # 代码变更日志 (NDJSON)
└── debug.log # 调试日志 (NDJSON)
```
## Directory Setup
```javascript
// loopId 来源:
// 1. API 触发时: 从 --loop-id 参数获取
// 2. 直接调用时: 生成新的 loop-v2-{timestamp}-{random}
const loopId = args['--loop-id'] || generateLoopId()
const loopFile = `.loop/${loopId}.json`
const progressDir = `.loop/${loopId}.progress`
// 创建进度目录
Bash(`mkdir -p "${progressDir}"`)
```
## Action Catalog
| Action | Purpose | Output Files | CLI Integration |
|--------|---------|--------------|-----------------|
| [action-init](phases/actions/action-init.md) | 初始化循环会话 | meta.json, state.json | - |
| [action-develop-with-file](phases/actions/action-develop-with-file.md) | 开发任务执行 | progress.md, tasks.json | gemini --mode write |
| [action-debug-with-file](phases/actions/action-debug-with-file.md) | 假设驱动调试 | understanding.md, hypotheses.json | gemini --mode analysis |
| [action-validate-with-file](phases/actions/action-validate-with-file.md) | 测试与验证 | validation.md, test-results.json | gemini --mode analysis |
| [action-complete](phases/actions/action-complete.md) | 完成循环 | summary.md | - |
| [action-menu](phases/actions/action-menu.md) | 显示操作菜单 | - | - |
## Usage
```bash
# 启动新循环 (直接调用)
/ccw-loop "实现用户认证功能"
# 继续现有循环 (API 触发或手动恢复)
/ccw-loop --loop-id loop-v2-20260122-abc123
# 自动循环模式
/ccw-loop --auto "修复登录bug并添加测试"
# API 触发自动循环
/ccw-loop --loop-id loop-v2-20260122-abc123 --auto
```
## Execution Flow
```
┌─────────────────────────────────────────────────────────────────┐
│ /ccw-loop [<task> | --loop-id <id>] [--auto] │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 1. Parameter Detection: │
│ ├─ IF --loop-id provided: │
│ │ ├─ Read .loop/{loopId}.json │
│ │ ├─ Validate status === 'running' │
│ │ └─ Continue from skill_state.current_action │
│ └─ ELSE (task description): │
│ ├─ Generate new loopId │
│ ├─ Create .loop/{loopId}.json │
│ └─ Initialize with action-init │
│ │
│ 2. Orchestrator Loop: │
│ ├─ Read state from .loop/{loopId}.json │
│ ├─ Check control signals: │
│ │ ├─ status === 'paused' → Exit (wait for resume) │
│ │ ├─ status === 'failed' → Exit with error │
│ │ └─ status === 'running' → Continue │
│ ├─ Show menu / auto-select next action │
│ ├─ Execute action │
│ ├─ Update .loop/{loopId}.progress/{action}.md │
│ ├─ Update .loop/{loopId}.json (skill_state) │
│ └─ Loop or exit based on user choice / completion │
│ │
│ 3. Action Execution: │
│ ├─ BEFORE: checkControlSignals() → exit if paused/stopped │
│ ├─ Develop: Plan → Implement → Document progress │
│ ├─ Debug: Hypothesize → Instrument → Analyze → Fix │
│ ├─ Validate: Test → Check → Report │
│ └─ AFTER: Update skill_state in .loop/{loopId}.json │
│ │
│ 4. Termination: │
│ ├─ Control signal: paused (graceful exit, wait resume) │
│ ├─ Control signal: stopped (failed state) │
│ ├─ User exits (interactive mode) │
│ ├─ All tasks completed (status → completed) │
│ └─ Max iterations reached │
│ │
└─────────────────────────────────────────────────────────────────┘
```
## Reference Documents
| Document | Purpose |
|----------|---------|
| [phases/orchestrator.md](phases/orchestrator.md) | 编排器:状态读取 + 动作选择 |
| [phases/state-schema.md](phases/state-schema.md) | 状态结构定义 |
| [specs/loop-requirements.md](specs/loop-requirements.md) | 循环需求规范 |
| [specs/action-catalog.md](specs/action-catalog.md) | 动作目录 |
| [templates/progress-template.md](templates/progress-template.md) | 进度文档模板 |
| [templates/understanding-template.md](templates/understanding-template.md) | 理解文档模板 |
## Integration with Loop Monitor (Dashboard)
此 Skill 与 CCW Dashboard 的 Loop Monitor 实现 **控制平面 + 执行平面** 分离架构:
### Control Plane (Dashboard/API → loop-v2-routes.ts)
1. **创建循环**: `POST /api/loops/v2` → 创建 `.loop/{loopId}.json`
2. **启动执行**: `POST /api/loops/v2/:loopId/start` → 触发 `/ccw-loop --loop-id {loopId} --auto`
3. **暂停执行**: `POST /api/loops/v2/:loopId/pause` → 设置 `status='paused'` (Skill 下次检查时退出)
4. **恢复执行**: `POST /api/loops/v2/:loopId/resume` → 设置 `status='running'` → 重新触发 Skill
5. **停止执行**: `POST /api/loops/v2/:loopId/stop` → 设置 `status='failed'`
### Execution Plane (ccw-loop Skill)
1. **读取状态**: 从 `.loop/{loopId}.json` 读取 API 设置的状态
2. **检查控制**: 每个 Action 前检查 `status` 字段
3. **执行动作**: develop → debug → validate → complete
4. **更新进度**: 写入 `.loop/{loopId}.progress/*.md` 和更新 `skill_state`
5. **状态同步**: Dashboard 通过读取 `.loop/{loopId}.json` 获取进度
## CLI Integration Points
### Develop Phase
```bash
ccw cli -p "PURPOSE: Implement {task}...
TASK: • Analyze requirements • Write code • Update progress
MODE: write
CONTEXT: @progress.md @tasks.json
EXPECTED: Implementation + updated progress.md
" --tool gemini --mode write --rule development-implement-feature
```
### Debug Phase
```bash
ccw cli -p "PURPOSE: Generate debugging hypotheses...
TASK: • Analyze error • Generate hypotheses • Add instrumentation
MODE: analysis
CONTEXT: @understanding.md @debug.log
EXPECTED: Hypotheses + instrumentation plan
" --tool gemini --mode analysis --rule analysis-diagnose-bug-root-cause
```
### Validate Phase
```bash
ccw cli -p "PURPOSE: Validate implementation...
TASK: • Run tests • Check coverage • Verify requirements
MODE: analysis
CONTEXT: @validation.md @test-results.json
EXPECTED: Validation report
" --tool gemini --mode analysis --rule analysis-review-code-quality
```
## Error Handling
| Situation | Action |
|-----------|--------|
| Session not found | Create new session |
| State file corrupted | Rebuild from file contents |
| CLI tool fails | Fallback to manual analysis |
| Tests fail | Loop back to develop/debug |
| >10 iterations | Warn user, suggest break |
## Post-Completion Expansion
完成后询问用户是否扩展为 issue (test/enhance/refactor/doc),选中项调用 `/issue:new "{summary} - {dimension}"`

View File

@@ -0,0 +1,320 @@
# Action: Complete
完成 CCW Loop 会话,生成总结报告。
## Purpose
- 生成完成报告
- 汇总所有阶段成果
- 提供后续建议
- 询问是否扩展为 Issue
## Preconditions
- [ ] state.initialized === true
- [ ] state.status === 'running'
## Execution
### Step 1: 汇总统计
```javascript
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()
const sessionFolder = `.workflow/.loop/${state.session_id}`
const stats = {
// 时间统计
duration: Date.now() - new Date(state.created_at).getTime(),
iterations: state.iteration_count,
// 开发统计
develop: {
total_tasks: state.develop.total_count,
completed_tasks: state.develop.completed_count,
completion_rate: state.develop.total_count > 0
? (state.develop.completed_count / state.develop.total_count * 100).toFixed(1)
: 0
},
// 调试统计
debug: {
iterations: state.debug.iteration,
hypotheses_tested: state.debug.hypotheses.length,
root_cause_found: state.debug.confirmed_hypothesis !== null
},
// 验证统计
validate: {
runs: state.validate.test_results.length,
passed: state.validate.passed,
coverage: state.validate.coverage,
failed_tests: state.validate.failed_tests.length
}
}
console.log('\n生成完成报告...')
```
### Step 2: 生成总结报告
```javascript
const summaryReport = `# CCW Loop Session Summary
**Session ID**: ${state.session_id}
**Task**: ${state.task_description}
**Started**: ${state.created_at}
**Completed**: ${getUtc8ISOString()}
**Duration**: ${formatDuration(stats.duration)}
---
## Executive Summary
${state.validate.passed
? '✅ **任务成功完成** - 所有测试通过,验证成功'
: state.develop.completed_count === state.develop.total_count
? '⚠️ **开发完成,验证未通过** - 需要进一步调试'
: '⏸️ **任务部分完成** - 仍有待处理项'}
---
## Development Phase
| Metric | Value |
|--------|-------|
| Total Tasks | ${stats.develop.total_tasks} |
| Completed | ${stats.develop.completed_tasks} |
| Completion Rate | ${stats.develop.completion_rate}% |
### Completed Tasks
${state.develop.tasks.filter(t => t.status === 'completed').map(t => `
- ✅ ${t.description}
- Files: ${t.files_changed?.join(', ') || 'N/A'}
- Completed: ${t.completed_at}
`).join('\n')}
### Pending Tasks
${state.develop.tasks.filter(t => t.status !== 'completed').map(t => `
- ⏳ ${t.description}
`).join('\n') || '_None_'}
---
## Debug Phase
| Metric | Value |
|--------|-------|
| Iterations | ${stats.debug.iterations} |
| Hypotheses Tested | ${stats.debug.hypotheses_tested} |
| Root Cause Found | ${stats.debug.root_cause_found ? 'Yes' : 'No'} |
${stats.debug.root_cause_found ? `
### Confirmed Root Cause
**${state.debug.confirmed_hypothesis}**: ${state.debug.hypotheses.find(h => h.id === state.debug.confirmed_hypothesis)?.description || 'N/A'}
` : ''}
### Hypothesis Summary
${state.debug.hypotheses.map(h => `
- **${h.id}**: ${h.status.toUpperCase()}
- ${h.description}
`).join('\n') || '_No hypotheses tested_'}
---
## Validation Phase
| Metric | Value |
|--------|-------|
| Test Runs | ${stats.validate.runs} |
| Status | ${stats.validate.passed ? 'PASSED' : 'FAILED'} |
| Coverage | ${stats.validate.coverage || 'N/A'}% |
| Failed Tests | ${stats.validate.failed_tests} |
${stats.validate.failed_tests > 0 ? `
### Failed Tests
${state.validate.failed_tests.map(t => `- ❌ ${t}`).join('\n')}
` : ''}
---
## Files Modified
${listModifiedFiles(sessionFolder)}
---
## Key Learnings
${state.debug.iteration > 0 ? `
### From Debugging
${extractLearnings(state.debug.hypotheses)}
` : ''}
---
## Recommendations
${generateRecommendations(stats, state)}
---
## Session Artifacts
| File | Description |
|------|-------------|
| \`develop/progress.md\` | Development progress timeline |
| \`develop/tasks.json\` | Task list with status |
| \`debug/understanding.md\` | Debug exploration and learnings |
| \`debug/hypotheses.json\` | Hypothesis history |
| \`validate/validation.md\` | Validation report |
| \`validate/test-results.json\` | Test execution results |
---
*Generated by CCW Loop at ${getUtc8ISOString()}*
`
Write(`${sessionFolder}/summary.md`, summaryReport)
console.log(`\n报告已保存: ${sessionFolder}/summary.md`)
```
### Step 3: 询问后续扩展
```javascript
console.log('\n' + '═'.repeat(60))
console.log(' 任务已完成')
console.log('═'.repeat(60))
const expansionResponse = await AskUserQuestion({
questions: [{
question: "是否将发现扩展为 Issue",
header: "扩展选项",
multiSelect: true,
options: [
{ label: "测试 (Test)", description: "添加更多测试用例" },
{ label: "增强 (Enhance)", description: "功能增强建议" },
{ label: "重构 (Refactor)", description: "代码重构建议" },
{ label: "文档 (Doc)", description: "文档更新需求" },
{ label: "否,直接完成", description: "不创建 Issue" }
]
}]
})
const selectedExpansions = expansionResponse["扩展选项"]
if (selectedExpansions && !selectedExpansions.includes("否,直接完成")) {
for (const expansion of selectedExpansions) {
const dimension = expansion.split(' ')[0].toLowerCase()
const issueSummary = `${state.task_description} - ${dimension}`
console.log(`\n创建 Issue: ${issueSummary}`)
// 调用 /issue:new 创建 issue
await Bash({
command: `/issue:new "${issueSummary}"`,
run_in_background: false
})
}
}
```
### Step 4: 最终输出
```javascript
console.log(`
═══════════════════════════════════════════════════════════
✅ CCW Loop 会话完成
═══════════════════════════════════════════════════════════
会话 ID: ${state.session_id}
用时: ${formatDuration(stats.duration)}
迭代: ${stats.iterations}
开发: ${stats.develop.completed_tasks}/${stats.develop.total_tasks} 任务完成
调试: ${stats.debug.iterations} 次迭代
验证: ${stats.validate.passed ? '通过 ✅' : '未通过 ❌'}
报告: ${sessionFolder}/summary.md
═══════════════════════════════════════════════════════════
`)
```
## State Updates
```javascript
return {
stateUpdates: {
status: 'completed',
completed_at: getUtc8ISOString(),
summary: stats
},
continue: false,
message: `会话 ${state.session_id} 已完成`
}
```
## Helper Functions
```javascript
function formatDuration(ms) {
const seconds = Math.floor(ms / 1000)
const minutes = Math.floor(seconds / 60)
const hours = Math.floor(minutes / 60)
if (hours > 0) {
return `${hours}h ${minutes % 60}m`
} else if (minutes > 0) {
return `${minutes}m ${seconds % 60}s`
} else {
return `${seconds}s`
}
}
function generateRecommendations(stats, state) {
const recommendations = []
if (stats.develop.completion_rate < 100) {
recommendations.push('- 完成剩余开发任务')
}
if (!stats.validate.passed) {
recommendations.push('- 修复失败的测试')
}
if (stats.validate.coverage && stats.validate.coverage < 80) {
recommendations.push(`- 提高测试覆盖率 (当前: ${stats.validate.coverage}%)`)
}
if (stats.debug.iterations > 3 && !stats.debug.root_cause_found) {
recommendations.push('- 考虑代码重构以简化调试')
}
if (recommendations.length === 0) {
recommendations.push('- 考虑代码审查')
recommendations.push('- 更新相关文档')
recommendations.push('- 准备部署')
}
return recommendations.join('\n')
}
```
## Error Handling
| Error Type | Recovery |
|------------|----------|
| 报告生成失败 | 显示基本统计,跳过文件写入 |
| Issue 创建失败 | 记录错误,继续完成 |
## Next Actions
- 无 (终止状态)
- 如需继续: 使用 `ccw-loop --resume {session-id}` 重新打开会话

View File

@@ -0,0 +1,485 @@
# Action: Debug With File
假设驱动调试,记录理解演变到 understanding.md支持 Gemini 辅助分析和假设生成。
## Purpose
执行假设驱动的调试流程,包括:
- 定位错误源
- 生成可测试假设
- 添加 NDJSON 日志
- 分析日志证据
- 纠正错误理解
- 应用修复
## Preconditions
- [ ] state.initialized === true
- [ ] state.status === 'running'
## Session Setup
```javascript
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()
const sessionFolder = `.workflow/.loop/${state.session_id}`
const debugFolder = `${sessionFolder}/debug`
const understandingPath = `${debugFolder}/understanding.md`
const hypothesesPath = `${debugFolder}/hypotheses.json`
const debugLogPath = `${debugFolder}/debug.log`
```
---
## Mode Detection
```javascript
// 自动检测模式
const understandingExists = fs.existsSync(understandingPath)
const logHasContent = fs.existsSync(debugLogPath) && fs.statSync(debugLogPath).size > 0
const debugMode = logHasContent ? 'analyze' : (understandingExists ? 'continue' : 'explore')
console.log(`Debug mode: ${debugMode}`)
```
---
## Explore Mode (首次调试)
### Step 1.1: 定位错误源
```javascript
if (debugMode === 'explore') {
// 询问用户 bug 描述
const bugInput = await AskUserQuestion({
questions: [{
question: "请描述遇到的 bug 或错误信息:",
header: "Bug 描述",
multiSelect: false,
options: [
{ label: "手动输入", description: "输入错误描述或堆栈" },
{ label: "从测试失败", description: "从验证阶段的失败测试中获取" }
]
}]
})
const bugDescription = bugInput["Bug 描述"]
// 提取关键词并搜索
const searchResults = await Task({
subagent_type: 'Explore',
run_in_background: false,
prompt: `Search codebase for error patterns related to: ${bugDescription}`
})
// 分析搜索结果,识别受影响的位置
const affectedLocations = analyzeSearchResults(searchResults)
}
```
### Step 1.2: 记录初始理解
```javascript
// 创建 understanding.md
const initialUnderstanding = `# Understanding Document
**Session ID**: ${state.session_id}
**Bug Description**: ${bugDescription}
**Started**: ${getUtc8ISOString()}
---
## Exploration Timeline
### Iteration 1 - Initial Exploration (${getUtc8ISOString()})
#### Current Understanding
Based on bug description and initial code search:
- Error pattern: ${errorPattern}
- Affected areas: ${affectedLocations.map(l => l.file).join(', ')}
- Initial hypothesis: ${initialThoughts}
#### Evidence from Code Search
${searchResults.map(r => `
**Keyword: "${r.keyword}"**
- Found in: ${r.files.join(', ')}
- Key findings: ${r.insights}
`).join('\n')}
#### Next Steps
- Generate testable hypotheses
- Add instrumentation
- Await reproduction
---
## Current Consolidated Understanding
${initialConsolidatedUnderstanding}
`
Write(understandingPath, initialUnderstanding)
```
### Step 1.3: Gemini 辅助假设生成
```bash
ccw cli -p "
PURPOSE: Generate debugging hypotheses for: ${bugDescription}
Success criteria: Testable hypotheses with clear evidence criteria
TASK:
• Analyze error pattern and code search results
• Identify 3-5 most likely root causes
• For each hypothesis, specify:
- What might be wrong
- What evidence would confirm/reject it
- Where to add instrumentation
• Rank by likelihood
MODE: analysis
CONTEXT: @${understandingPath} | Search results in understanding.md
EXPECTED:
- Structured hypothesis list (JSON format)
- Each hypothesis with: id, description, testable_condition, logging_point, evidence_criteria
- Likelihood ranking (1=most likely)
CONSTRAINTS: Focus on testable conditions
" --tool gemini --mode analysis --rule analysis-diagnose-bug-root-cause
```
### Step 1.4: 保存假设
```javascript
const hypotheses = {
iteration: 1,
timestamp: getUtc8ISOString(),
bug_description: bugDescription,
hypotheses: [
{
id: "H1",
description: "...",
testable_condition: "...",
logging_point: "file.ts:func:42",
evidence_criteria: {
confirm: "...",
reject: "..."
},
likelihood: 1,
status: "pending"
}
// ...
],
gemini_insights: "...",
corrected_assumptions: []
}
Write(hypothesesPath, JSON.stringify(hypotheses, null, 2))
```
### Step 1.5: 添加 NDJSON 日志
```javascript
// 为每个假设添加日志点
for (const hypothesis of hypotheses.hypotheses) {
const [file, func, line] = hypothesis.logging_point.split(':')
const logStatement = `console.log(JSON.stringify({
hid: "${hypothesis.id}",
ts: Date.now(),
func: "${func}",
data: { /* 相关数据 */ }
}))`
// 使用 Edit 工具添加日志
// ...
}
```
---
## Analyze Mode (有日志后)
### Step 2.1: 解析调试日志
```javascript
if (debugMode === 'analyze') {
// 读取 NDJSON 日志
const logContent = Read(debugLogPath)
const entries = logContent.split('\n')
.filter(l => l.trim())
.map(l => JSON.parse(l))
// 按假设分组
const byHypothesis = groupBy(entries, 'hid')
}
```
### Step 2.2: Gemini 辅助证据分析
```bash
ccw cli -p "
PURPOSE: Analyze debug log evidence to validate/correct hypotheses for: ${bugDescription}
Success criteria: Clear verdict per hypothesis + corrected understanding
TASK:
• Parse log entries by hypothesis
• Evaluate evidence against expected criteria
• Determine verdict: confirmed | rejected | inconclusive
• Identify incorrect assumptions from previous understanding
• Suggest corrections to understanding
MODE: analysis
CONTEXT:
@${debugLogPath}
@${understandingPath}
@${hypothesesPath}
EXPECTED:
- Per-hypothesis verdict with reasoning
- Evidence summary
- List of incorrect assumptions with corrections
- Updated consolidated understanding
- Root cause if confirmed, or next investigation steps
CONSTRAINTS: Evidence-based reasoning only, no speculation
" --tool gemini --mode analysis --rule analysis-diagnose-bug-root-cause
```
### Step 2.3: 更新理解文档
```javascript
// 追加新迭代到 understanding.md
const iteration = state.debug.iteration + 1
const analysisEntry = `
### Iteration ${iteration} - Evidence Analysis (${getUtc8ISOString()})
#### Log Analysis Results
${results.map(r => `
**${r.id}**: ${r.verdict.toUpperCase()}
- Evidence: ${JSON.stringify(r.evidence)}
- Reasoning: ${r.reason}
`).join('\n')}
#### Corrected Understanding
Previous misunderstandings identified and corrected:
${corrections.map(c => `
- ~~${c.wrong}~~ → ${c.corrected}
- Why wrong: ${c.reason}
- Evidence: ${c.evidence}
`).join('\n')}
#### New Insights
${newInsights.join('\n- ')}
#### Gemini Analysis
${geminiAnalysis}
${confirmedHypothesis ? `
#### Root Cause Identified
**${confirmedHypothesis.id}**: ${confirmedHypothesis.description}
Evidence supporting this conclusion:
${confirmedHypothesis.supportingEvidence}
` : `
#### Next Steps
${nextSteps}
`}
---
## Current Consolidated Understanding (Updated)
### What We Know
- ${validUnderstanding1}
- ${validUnderstanding2}
### What Was Disproven
- ~~${wrongAssumption}~~ (Evidence: ${disproofEvidence})
### Current Investigation Focus
${currentFocus}
### Remaining Questions
- ${openQuestion1}
- ${openQuestion2}
`
const existingContent = Read(understandingPath)
Write(understandingPath, existingContent + analysisEntry)
```
### Step 2.4: 更新假设状态
```javascript
const hypothesesData = JSON.parse(Read(hypothesesPath))
// 更新假设状态
hypothesesData.hypotheses = hypothesesData.hypotheses.map(h => ({
...h,
status: results.find(r => r.id === h.id)?.verdict || h.status,
evidence: results.find(r => r.id === h.id)?.evidence || h.evidence,
verdict_reason: results.find(r => r.id === h.id)?.reason || h.verdict_reason
}))
hypothesesData.iteration++
hypothesesData.timestamp = getUtc8ISOString()
Write(hypothesesPath, JSON.stringify(hypothesesData, null, 2))
```
---
## Fix & Verification
### Step 3.1: 应用修复
```javascript
if (confirmedHypothesis) {
console.log(`\n根因确认: ${confirmedHypothesis.description}`)
console.log('准备应用修复...')
// 使用 Gemini 生成修复代码
const fixPrompt = `
PURPOSE: Fix the identified root cause
Root Cause: ${confirmedHypothesis.description}
Evidence: ${confirmedHypothesis.supportingEvidence}
TASK:
• Generate fix code
• Ensure backward compatibility
• Add tests if needed
MODE: write
CONTEXT: @${confirmedHypothesis.logging_point.split(':')[0]}
EXPECTED: Fixed code + verification steps
`
await Bash({
command: `ccw cli -p "${fixPrompt}" --tool gemini --mode write --rule development-debug-runtime-issues`,
run_in_background: false
})
}
```
### Step 3.2: 记录解决方案
```javascript
const resolutionEntry = `
### Resolution (${getUtc8ISOString()})
#### Fix Applied
- Modified files: ${modifiedFiles.join(', ')}
- Fix description: ${fixDescription}
- Root cause addressed: ${rootCause}
#### Verification Results
${verificationResults}
#### Lessons Learned
1. ${lesson1}
2. ${lesson2}
#### Key Insights for Future
- ${insight1}
- ${insight2}
`
const existingContent = Read(understandingPath)
Write(understandingPath, existingContent + resolutionEntry)
```
### Step 3.3: 清理日志
```javascript
// 移除调试日志
// (可选,根据用户选择)
```
---
## State Updates
```javascript
return {
stateUpdates: {
debug: {
current_bug: bugDescription,
hypotheses: hypothesesData.hypotheses,
confirmed_hypothesis: confirmedHypothesis?.id || null,
iteration: hypothesesData.iteration,
last_analysis_at: getUtc8ISOString(),
understanding_updated: true
},
last_action: 'action-debug-with-file'
},
continue: true,
message: confirmedHypothesis
? `根因确认: ${confirmedHypothesis.description}\n修复已应用,请验证`
: `分析完成,需要更多证据\n请复现 bug 后再次执行`
}
```
## Error Handling
| Error Type | Recovery |
|------------|----------|
| 空 debug.log | 提示用户复现 bug |
| 所有假设被否定 | 使用 Gemini 生成新假设 |
| 修复无效 | 记录失败尝试,迭代 |
| >5 迭代 | 建议升级到 /workflow:lite-fix |
| Gemini 不可用 | 回退到手动分析 |
## Understanding Document Template
参考 [templates/understanding-template.md](../../templates/understanding-template.md)
## CLI Integration
### 假设生成
```bash
ccw cli -p "PURPOSE: Generate debugging hypotheses..." --tool gemini --mode analysis --rule analysis-diagnose-bug-root-cause
```
### 证据分析
```bash
ccw cli -p "PURPOSE: Analyze debug log evidence..." --tool gemini --mode analysis --rule analysis-diagnose-bug-root-cause
```
### 生成修复
```bash
ccw cli -p "PURPOSE: Fix the identified root cause..." --tool gemini --mode write --rule development-debug-runtime-issues
```
## Next Actions (Hints)
- 根因确认: `action-validate-with-file` (验证修复)
- 需要更多证据: 等待用户复现,再次执行此动作
- 所有假设否定: 重新执行此动作生成新假设
- 用户选择: `action-menu` (返回菜单)

View File

@@ -0,0 +1,365 @@
# Action: Develop With File
增量开发任务执行,记录进度到 progress.md支持 Gemini 辅助实现。
## Purpose
执行开发任务并记录进度,包括:
- 分析任务需求
- 使用 Gemini/CLI 实现代码
- 记录代码变更
- 更新进度文档
## Preconditions
- [ ] state.status === 'running'
- [ ] state.skill_state !== null
- [ ] state.skill_state.develop.tasks.some(t => t.status === 'pending')
## Session Setup (Unified Location)
```javascript
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()
// 统一位置: .loop/{loopId}
const loopId = state.loop_id
const loopFile = `.loop/${loopId}.json`
const progressDir = `.loop/${loopId}.progress`
const progressPath = `${progressDir}/develop.md`
const changesLogPath = `${progressDir}/changes.log`
```
---
## Execution
### Step 0: Check Control Signals (CRITICAL)
```javascript
/**
* CRITICAL: 每个 Action 必须在开始时检查控制信号
* 如果 API 设置了 paused/stoppedSkill 应立即退出
*/
function checkControlSignals(loopId) {
const state = JSON.parse(Read(`.loop/${loopId}.json`))
switch (state.status) {
case 'paused':
console.log('⏸️ Loop paused by API. Exiting action.')
return { continue: false, reason: 'paused' }
case 'failed':
console.log('⏹️ Loop stopped by API. Exiting action.')
return { continue: false, reason: 'stopped' }
case 'running':
return { continue: true, reason: 'running' }
default:
return { continue: false, reason: 'unknown_status' }
}
}
// Execute check
const control = checkControlSignals(loopId)
if (!control.continue) {
return {
skillStateUpdates: { current_action: null },
continue: false,
message: `Action terminated: ${control.reason}`
}
}
```
### Step 1: 加载任务列表
```javascript
// 读取任务列表 (从 skill_state)
let tasks = state.skill_state?.develop?.tasks || []
// 如果任务列表为空,询问用户创建
if (tasks.length === 0) {
// 使用 Gemini 分析任务描述,生成任务列表
const analysisPrompt = `
PURPOSE: 分析开发任务并分解为可执行步骤
Success: 生成 3-7 个具体、可验证的子任务
TASK:
• 分析任务描述: ${state.task_description}
• 识别关键功能点
• 分解为独立子任务
• 为每个子任务指定工具和模式
MODE: analysis
CONTEXT: @package.json @src/**/*.ts | Memory: 项目结构
EXPECTED:
JSON 格式:
{
"tasks": [
{
"id": "task-001",
"description": "任务描述",
"tool": "gemini",
"mode": "write",
"files": ["src/xxx.ts"]
}
]
}
`
const result = await Task({
subagent_type: 'cli-execution-agent',
run_in_background: false,
prompt: `Execute Gemini CLI with prompt: ${analysisPrompt}`
})
tasks = JSON.parse(result).tasks
}
// 找到第一个待处理任务
const currentTask = tasks.find(t => t.status === 'pending')
if (!currentTask) {
return {
skillStateUpdates: {
develop: { ...state.skill_state.develop, current_task: null }
},
continue: true,
message: '所有开发任务已完成'
}
}
```
### Step 2: 执行开发任务
```javascript
console.log(`\n执行任务: ${currentTask.description}`)
// 更新任务状态
currentTask.status = 'in_progress'
// 使用 Gemini 实现
const implementPrompt = `
PURPOSE: 实现开发任务
Task: ${currentTask.description}
Success criteria: 代码实现完成,测试通过
TASK:
• 分析现有代码结构
• 实现功能代码
• 添加必要的类型定义
• 确保代码风格一致
MODE: write
CONTEXT: @${currentTask.files?.join(' @') || 'src/**/*.ts'}
EXPECTED:
- 完整的代码实现
- 代码变更列表
- 简要实现说明
CONSTRAINTS: 遵循现有代码风格 | 不破坏现有功能
`
const implementResult = await Bash({
command: `ccw cli -p "${implementPrompt}" --tool gemini --mode write --rule development-implement-feature`,
run_in_background: false
})
// 记录代码变更
const timestamp = getUtc8ISOString()
const changeEntry = {
timestamp,
task_id: currentTask.id,
description: currentTask.description,
files_changed: currentTask.files || [],
result: 'success'
}
// 追加到 changes.log (NDJSON 格式)
const changesContent = Read(changesLogPath) || ''
Write(changesLogPath, changesContent + JSON.stringify(changeEntry) + '\n')
```
### Step 3: 更新进度文档
```javascript
const timestamp = getUtc8ISOString()
const iteration = state.develop.completed_count + 1
// 读取现有进度文档
let progressContent = Read(progressPath) || ''
// 如果是新文档,添加头部
if (!progressContent) {
progressContent = `# Development Progress
**Session ID**: ${state.session_id}
**Task**: ${state.task_description}
**Started**: ${timestamp}
---
## Progress Timeline
`
}
// 追加本次进度
const progressEntry = `
### Iteration ${iteration} - ${currentTask.description} (${timestamp})
#### Task Details
- **ID**: ${currentTask.id}
- **Tool**: ${currentTask.tool}
- **Mode**: ${currentTask.mode}
#### Implementation Summary
${implementResult.summary || '实现完成'}
#### Files Changed
${currentTask.files?.map(f => `- \`${f}\``).join('\n') || '- No files specified'}
#### Status: COMPLETED
---
`
Write(progressPath, progressContent + progressEntry)
// 更新任务状态
currentTask.status = 'completed'
currentTask.completed_at = timestamp
```
### Step 4: 更新任务列表文件
```javascript
// 更新 tasks.json
const updatedTasks = tasks.map(t =>
t.id === currentTask.id ? currentTask : t
)
Write(tasksPath, JSON.stringify(updatedTasks, null, 2))
```
## State Updates
```javascript
return {
stateUpdates: {
develop: {
tasks: updatedTasks,
current_task_id: null,
completed_count: state.develop.completed_count + 1,
total_count: updatedTasks.length,
last_progress_at: getUtc8ISOString()
},
last_action: 'action-develop-with-file'
},
continue: true,
message: `任务完成: ${currentTask.description}\n进度: ${state.develop.completed_count + 1}/${updatedTasks.length}`
}
```
## Error Handling
| Error Type | Recovery |
|------------|----------|
| Gemini CLI 失败 | 提示用户手动实现,记录到 progress.md |
| 文件写入失败 | 重试一次,失败则记录错误 |
| 任务解析失败 | 询问用户手动输入任务 |
## Progress Document Template
```markdown
# Development Progress
**Session ID**: LOOP-xxx-2026-01-22
**Task**: 实现用户认证功能
**Started**: 2026-01-22T10:00:00+08:00
---
## Progress Timeline
### Iteration 1 - 分析登录组件 (2026-01-22T10:05:00+08:00)
#### Task Details
- **ID**: task-001
- **Tool**: gemini
- **Mode**: analysis
#### Implementation Summary
分析了现有登录组件结构,识别了需要修改的文件和依赖关系。
#### Files Changed
- `src/components/Login.tsx`
- `src/hooks/useAuth.ts`
#### Status: COMPLETED
---
### Iteration 2 - 实现登录 API (2026-01-22T10:15:00+08:00)
...
---
## Current Statistics
| Metric | Value |
|--------|-------|
| Total Tasks | 5 |
| Completed | 2 |
| In Progress | 1 |
| Pending | 2 |
| Progress | 40% |
---
## Next Steps
- [ ] 完成剩余任务
- [ ] 运行测试
- [ ] 代码审查
```
## CLI Integration
### 任务分析
```bash
ccw cli -p "PURPOSE: 分解开发任务为子任务
TASK: • 分析任务描述 • 识别功能点 • 生成任务列表
MODE: analysis
CONTEXT: @package.json @src/**/*
EXPECTED: JSON 任务列表
" --tool gemini --mode analysis --rule planning-breakdown-task-steps
```
### 代码实现
```bash
ccw cli -p "PURPOSE: 实现功能代码
TASK: • 分析需求 • 编写代码 • 添加类型
MODE: write
CONTEXT: @src/xxx.ts
EXPECTED: 完整实现
" --tool gemini --mode write --rule development-implement-feature
```
## Next Actions (Hints)
- 所有任务完成: `action-debug-with-file` (开始调试)
- 任务失败: `action-develop-with-file` (重试或下一个任务)
- 用户选择: `action-menu` (返回菜单)

View File

@@ -0,0 +1,200 @@
# Action: Initialize
初始化 CCW Loop 会话,创建目录结构和初始状态。
## Purpose
- 创建会话目录结构
- 初始化状态文件
- 分析任务描述生成初始任务列表
- 准备执行环境
## Preconditions
- [ ] state.status === 'pending'
- [ ] state.initialized === false
## Execution
### Step 1: 创建目录结构
```javascript
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()
const taskSlug = state.task_description.toLowerCase().replace(/[^a-z0-9]+/g, '-').substring(0, 30)
const dateStr = getUtc8ISOString().substring(0, 10)
const sessionId = `LOOP-${taskSlug}-${dateStr}`
const sessionFolder = `.workflow/.loop/${sessionId}`
Bash(`mkdir -p "${sessionFolder}/develop"`)
Bash(`mkdir -p "${sessionFolder}/debug"`)
Bash(`mkdir -p "${sessionFolder}/validate"`)
console.log(`Session created: ${sessionId}`)
console.log(`Location: ${sessionFolder}`)
```
### Step 2: 创建元数据文件
```javascript
const meta = {
session_id: sessionId,
task_description: state.task_description,
created_at: getUtc8ISOString(),
mode: state.mode || 'interactive'
}
Write(`${sessionFolder}/meta.json`, JSON.stringify(meta, null, 2))
```
### Step 3: 分析任务生成开发任务列表
```javascript
// 使用 Gemini 分析任务描述
console.log('\n分析任务描述...')
const analysisPrompt = `
PURPOSE: 分析开发任务并分解为可执行步骤
Success: 生成 3-7 个具体、可验证的子任务
TASK:
• 分析任务描述: ${state.task_description}
• 识别关键功能点
• 分解为独立子任务
• 为每个子任务指定工具和模式
MODE: analysis
CONTEXT: @package.json @src/**/*.ts (如存在)
EXPECTED:
JSON 格式:
{
"tasks": [
{
"id": "task-001",
"description": "任务描述",
"tool": "gemini",
"mode": "write",
"priority": 1
}
],
"estimated_complexity": "low|medium|high",
"key_files": ["file1.ts", "file2.ts"]
}
CONSTRAINTS: 生成实际可执行的任务
`
const result = await Bash({
command: `ccw cli -p "${analysisPrompt}" --tool gemini --mode analysis --rule planning-breakdown-task-steps`,
run_in_background: false
})
const analysis = JSON.parse(result.stdout)
const tasks = analysis.tasks.map((t, i) => ({
...t,
id: t.id || `task-${String(i + 1).padStart(3, '0')}`,
status: 'pending',
created_at: getUtc8ISOString(),
completed_at: null,
files_changed: []
}))
// 保存任务列表
Write(`${sessionFolder}/develop/tasks.json`, JSON.stringify(tasks, null, 2))
```
### Step 4: 初始化进度文档
```javascript
const progressInitial = `# Development Progress
**Session ID**: ${sessionId}
**Task**: ${state.task_description}
**Started**: ${getUtc8ISOString()}
**Estimated Complexity**: ${analysis.estimated_complexity}
---
## Task List
${tasks.map((t, i) => `${i + 1}. [ ] ${t.description}`).join('\n')}
## Key Files
${analysis.key_files?.map(f => `- \`${f}\``).join('\n') || '- To be determined'}
---
## Progress Timeline
`
Write(`${sessionFolder}/develop/progress.md`, progressInitial)
```
### Step 5: 显示初始化结果
```javascript
console.log(`\n✅ 会话初始化完成`)
console.log(`\n任务列表 (${tasks.length} 项):`)
tasks.forEach((t, i) => {
console.log(` ${i + 1}. ${t.description} [${t.tool}/${t.mode}]`)
})
console.log(`\n预估复杂度: ${analysis.estimated_complexity}`)
console.log(`\n执行 'develop' 开始开发,或 'menu' 查看更多选项`)
```
## State Updates
```javascript
return {
stateUpdates: {
session_id: sessionId,
status: 'running',
initialized: true,
develop: {
tasks: tasks,
current_task_id: null,
completed_count: 0,
total_count: tasks.length,
last_progress_at: null
},
debug: {
current_bug: null,
hypotheses: [],
confirmed_hypothesis: null,
iteration: 0,
last_analysis_at: null,
understanding_updated: false
},
validate: {
test_results: [],
coverage: null,
passed: false,
failed_tests: [],
last_run_at: null
},
context: {
estimated_complexity: analysis.estimated_complexity,
key_files: analysis.key_files
}
},
continue: true,
message: `会话 ${sessionId} 已初始化\n${tasks.length} 个开发任务待执行`
}
```
## Error Handling
| Error Type | Recovery |
|------------|----------|
| 目录创建失败 | 检查权限,重试 |
| Gemini 分析失败 | 提示用户手动输入任务 |
| 任务解析失败 | 使用默认任务列表 |
## Next Actions
- 成功: `action-menu` (显示操作菜单) 或 `action-develop-with-file` (直接开始开发)
- 失败: 报错退出

View File

@@ -0,0 +1,192 @@
# Action: Menu
显示交互式操作菜单,让用户选择下一步操作。
## Purpose
- 显示当前状态摘要
- 提供操作选项
- 接收用户选择
- 返回下一个动作
## Preconditions
- [ ] state.initialized === true
- [ ] state.status === 'running'
## Execution
### Step 1: 生成状态摘要
```javascript
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()
// 开发进度
const developProgress = state.develop.total_count > 0
? `${state.develop.completed_count}/${state.develop.total_count} (${(state.develop.completed_count / state.develop.total_count * 100).toFixed(0)}%)`
: '未开始'
// 调试状态
const debugStatus = state.debug.confirmed_hypothesis
? `✅ 已确认根因`
: state.debug.iteration > 0
? `🔍 迭代 ${state.debug.iteration}`
: '未开始'
// 验证状态
const validateStatus = state.validate.passed
? `✅ 通过`
: state.validate.test_results.length > 0
? `${state.validate.failed_tests.length} 个失败`
: '未运行'
const statusSummary = `
═══════════════════════════════════════════════════════════
CCW Loop - ${state.session_id}
═══════════════════════════════════════════════════════════
任务: ${state.task_description}
迭代: ${state.iteration_count}
┌─────────────────────────────────────────────────────┐
│ 开发 (Develop) │ ${developProgress.padEnd(20)}
│ 调试 (Debug) │ ${debugStatus.padEnd(20)}
│ 验证 (Validate) │ ${validateStatus.padEnd(20)}
└─────────────────────────────────────────────────────┘
═══════════════════════════════════════════════════════════
`
console.log(statusSummary)
```
### Step 2: 显示操作选项
```javascript
const options = [
{
label: "📝 继续开发 (Develop)",
description: state.develop.completed_count < state.develop.total_count
? `执行下一个开发任务`
: "所有任务已完成,可添加新任务",
action: "action-develop-with-file"
},
{
label: "🔍 开始调试 (Debug)",
description: state.debug.iteration > 0
? "继续假设驱动调试"
: "开始新的调试会话",
action: "action-debug-with-file"
},
{
label: "✅ 运行验证 (Validate)",
description: "运行测试并检查覆盖率",
action: "action-validate-with-file"
},
{
label: "📊 查看详情 (Status)",
description: "查看详细进度和文件",
action: "action-status"
},
{
label: "🏁 完成循环 (Complete)",
description: "结束当前循环",
action: "action-complete"
},
{
label: "🚪 退出 (Exit)",
description: "保存状态并退出",
action: "exit"
}
]
const response = await AskUserQuestion({
questions: [{
question: "选择下一步操作:",
header: "操作",
multiSelect: false,
options: options.map(o => ({
label: o.label,
description: o.description
}))
}]
})
const selectedLabel = response["操作"]
const selectedOption = options.find(o => o.label === selectedLabel)
const nextAction = selectedOption?.action || 'action-menu'
```
### Step 3: 处理特殊选项
```javascript
if (nextAction === 'exit') {
console.log('\n保存状态并退出...')
return {
stateUpdates: {
status: 'user_exit'
},
continue: false,
message: '会话已保存,使用 --resume 可继续'
}
}
if (nextAction === 'action-status') {
// 显示详细状态
const sessionFolder = `.workflow/.loop/${state.session_id}`
console.log('\n=== 开发进度 ===')
const progress = Read(`${sessionFolder}/develop/progress.md`)
console.log(progress?.substring(0, 500) + '...')
console.log('\n=== 调试状态 ===')
if (state.debug.hypotheses.length > 0) {
state.debug.hypotheses.forEach(h => {
console.log(` ${h.id}: ${h.status} - ${h.description.substring(0, 50)}...`)
})
} else {
console.log(' 尚未开始调试')
}
console.log('\n=== 验证结果 ===')
if (state.validate.test_results.length > 0) {
const latest = state.validate.test_results[state.validate.test_results.length - 1]
console.log(` 最近运行: ${latest.timestamp}`)
console.log(` 通过率: ${latest.summary.pass_rate}%`)
} else {
console.log(' 尚未运行验证')
}
// 返回菜单
return {
stateUpdates: {},
continue: true,
nextAction: 'action-menu',
message: ''
}
}
```
## State Updates
```javascript
return {
stateUpdates: {
// 不更新状态,仅返回下一个动作
},
continue: true,
nextAction: nextAction,
message: `执行: ${selectedOption?.label || nextAction}`
}
```
## Error Handling
| Error Type | Recovery |
|------------|----------|
| 用户取消 | 返回菜单 |
| 无效选择 | 重新显示菜单 |
## Next Actions
根据用户选择动态决定下一个动作。

View File

@@ -0,0 +1,307 @@
# Action: Validate With File
运行测试并验证实现,记录结果到 validation.md支持 Gemini 辅助分析测试覆盖率和质量。
## Purpose
执行测试验证流程,包括:
- 运行单元测试
- 运行集成测试
- 检查代码覆盖率
- 生成验证报告
- 分析失败原因
## Preconditions
- [ ] state.initialized === true
- [ ] state.status === 'running'
- [ ] state.develop.completed_count > 0 || state.debug.confirmed_hypothesis !== null
## Session Setup
```javascript
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()
const sessionFolder = `.workflow/.loop/${state.session_id}`
const validateFolder = `${sessionFolder}/validate`
const validationPath = `${validateFolder}/validation.md`
const testResultsPath = `${validateFolder}/test-results.json`
const coveragePath = `${validateFolder}/coverage.json`
```
---
## Execution
### Step 1: 运行测试
```javascript
console.log('\n运行测试...')
// 检测测试框架
const packageJson = JSON.parse(Read('package.json'))
const testScript = packageJson.scripts?.test || 'npm test'
// 运行测试并捕获输出
const testResult = await Bash({
command: testScript,
timeout: 300000 // 5分钟
})
// 解析测试输出
const testResults = parseTestOutput(testResult.stdout)
```
### Step 2: 检查覆盖率
```javascript
// 运行覆盖率检查
let coverageData = null
if (packageJson.scripts?.['test:coverage']) {
const coverageResult = await Bash({
command: 'npm run test:coverage',
timeout: 300000
})
// 解析覆盖率报告
coverageData = parseCoverageReport(coverageResult.stdout)
Write(coveragePath, JSON.stringify(coverageData, null, 2))
}
```
### Step 3: Gemini 辅助分析
```bash
ccw cli -p "
PURPOSE: Analyze test results and coverage
Success criteria: Identify quality issues and suggest improvements
TASK:
• Analyze test execution results
• Review code coverage metrics
• Identify missing test cases
• Suggest quality improvements
• Verify requirements coverage
MODE: analysis
CONTEXT:
@${testResultsPath}
@${coveragePath}
@${sessionFolder}/develop/progress.md
EXPECTED:
- Quality assessment report
- Failed tests analysis
- Coverage gaps identification
- Improvement recommendations
- Pass/Fail decision with rationale
CONSTRAINTS: Evidence-based quality assessment
" --tool gemini --mode analysis --rule analysis-review-code-quality
```
### Step 4: 生成验证报告
```javascript
const timestamp = getUtc8ISOString()
const iteration = (state.validate.test_results?.length || 0) + 1
const validationReport = `# Validation Report
**Session ID**: ${state.session_id}
**Task**: ${state.task_description}
**Validated**: ${timestamp}
---
## Iteration ${iteration} - Validation Run
### Test Execution Summary
| Metric | Value |
|--------|-------|
| Total Tests | ${testResults.total} |
| Passed | ${testResults.passed} |
| Failed | ${testResults.failed} |
| Skipped | ${testResults.skipped} |
| Duration | ${testResults.duration_ms}ms |
| **Pass Rate** | **${(testResults.passed / testResults.total * 100).toFixed(1)}%** |
### Coverage Report
${coverageData ? `
| File | Statements | Branches | Functions | Lines |
|------|------------|----------|-----------|-------|
${coverageData.files.map(f => `| ${f.path} | ${f.statements}% | ${f.branches}% | ${f.functions}% | ${f.lines}% |`).join('\n')}
**Overall Coverage**: ${coverageData.overall.statements}%
` : '_No coverage data available_'}
### Failed Tests
${testResults.failed > 0 ? `
${testResults.failures.map(f => `
#### ${f.test_name}
- **Suite**: ${f.suite}
- **Error**: ${f.error_message}
- **Stack**:
\`\`\`
${f.stack_trace}
\`\`\`
`).join('\n')}
` : '_All tests passed_'}
### Gemini Quality Analysis
${geminiAnalysis}
### Recommendations
${recommendations.map(r => `- ${r}`).join('\n')}
---
## Validation Decision
**Result**: ${testResults.passed === testResults.total ? '✅ PASS' : '❌ FAIL'}
**Rationale**: ${validationDecision}
${testResults.passed !== testResults.total ? `
### Next Actions
1. Review failed tests
2. Debug failures using action-debug-with-file
3. Fix issues and re-run validation
` : `
### Next Actions
1. Consider code review
2. Prepare for deployment
3. Update documentation
`}
`
// 写入验证报告
Write(validationPath, validationReport)
```
### Step 5: 保存测试结果
```javascript
const testResultsData = {
iteration,
timestamp,
summary: {
total: testResults.total,
passed: testResults.passed,
failed: testResults.failed,
skipped: testResults.skipped,
pass_rate: (testResults.passed / testResults.total * 100).toFixed(1),
duration_ms: testResults.duration_ms
},
tests: testResults.tests,
failures: testResults.failures,
coverage: coverageData?.overall || null
}
Write(testResultsPath, JSON.stringify(testResultsData, null, 2))
```
---
## State Updates
```javascript
const validationPassed = testResults.failed === 0 && testResults.passed > 0
return {
stateUpdates: {
validate: {
test_results: [...(state.validate.test_results || []), testResultsData],
coverage: coverageData?.overall.statements || null,
passed: validationPassed,
failed_tests: testResults.failures.map(f => f.test_name),
last_run_at: getUtc8ISOString()
},
last_action: 'action-validate-with-file'
},
continue: true,
message: validationPassed
? `验证通过 ✅\n测试: ${testResults.passed}/${testResults.total}\n覆盖率: ${coverageData?.overall.statements || 'N/A'}%`
: `验证失败 ❌\n失败: ${testResults.failed}/${testResults.total}\n建议进入调试模式`
}
```
## Test Output Parsers
### Jest/Vitest Parser
```javascript
function parseJestOutput(stdout) {
const testPattern = /Tests:\s+(\d+) passed.*?(\d+) failed.*?(\d+) total/
const match = stdout.match(testPattern)
return {
total: parseInt(match[3]),
passed: parseInt(match[1]),
failed: parseInt(match[2]),
// ... parse individual test results
}
}
```
### Pytest Parser
```javascript
function parsePytestOutput(stdout) {
const summaryPattern = /(\d+) passed.*?(\d+) failed.*?(\d+) error/
// ... implementation
}
```
## Error Handling
| Error Type | Recovery |
|------------|----------|
| Tests don't run | 检查测试脚本配置,提示用户 |
| All tests fail | 建议进入 debug 模式 |
| Coverage tool missing | 跳过覆盖率检查,仅运行测试 |
| Timeout | 增加超时时间或拆分测试 |
## Validation Report Template
参考 [templates/validation-template.md](../../templates/validation-template.md)
## CLI Integration
### 质量分析
```bash
ccw cli -p "PURPOSE: Analyze test results and coverage...
TASK: • Review results • Identify gaps • Suggest improvements
MODE: analysis
CONTEXT: @test-results.json @coverage.json
EXPECTED: Quality assessment
" --tool gemini --mode analysis --rule analysis-review-code-quality
```
### 测试生成 (如覆盖率低)
```bash
ccw cli -p "PURPOSE: Generate missing test cases...
TASK: • Analyze uncovered code • Write tests
MODE: write
CONTEXT: @coverage.json @src/**/*
EXPECTED: Test code
" --tool gemini --mode write --rule development-generate-tests
```
## Next Actions (Hints)
- 验证通过: `action-complete` (完成循环)
- 验证失败: `action-debug-with-file` (调试失败测试)
- 覆盖率低: `action-develop-with-file` (添加测试)
- 用户选择: `action-menu` (返回菜单)

View File

@@ -0,0 +1,486 @@
# Orchestrator
根据当前状态选择并执行下一个动作,实现无状态循环工作流。与 API (loop-v2-routes.ts) 协作实现控制平面/执行平面分离。
## Role
检查控制信号 → 读取文件状态 → 选择动作 → 执行 → 更新文件 → 循环,直到完成或被外部暂停/停止。
## State Management (Unified Location)
### 读取状态
```javascript
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()
/**
* 读取循环状态 (统一位置)
* @param loopId - Loop ID (e.g., "loop-v2-20260122-abc123")
*/
function readLoopState(loopId) {
const stateFile = `.loop/${loopId}.json`
if (!fs.existsSync(stateFile)) {
return null
}
const state = JSON.parse(Read(stateFile))
return state
}
```
### 更新状态
```javascript
/**
* 更新循环状态 (只更新 skill_state 部分,不修改 API 字段)
* @param loopId - Loop ID
* @param updates - 更新内容 (skill_state 字段)
*/
function updateLoopState(loopId, updates) {
const stateFile = `.loop/${loopId}.json`
const currentState = readLoopState(loopId)
if (!currentState) {
throw new Error(`Loop state not found: ${loopId}`)
}
// 只更新 skill_state 和 updated_at
const newState = {
...currentState,
updated_at: getUtc8ISOString(),
skill_state: {
...currentState.skill_state,
...updates
}
}
Write(stateFile, JSON.stringify(newState, null, 2))
return newState
}
```
### 创建新循环状态 (直接调用时)
```javascript
/**
* 创建新的循环状态 (仅在直接调用时使用API 触发时状态已存在)
*/
function createLoopState(loopId, taskDescription) {
const stateFile = `.loop/${loopId}.json`
const now = getUtc8ISOString()
const state = {
// API 兼容字段
loop_id: loopId,
title: taskDescription.substring(0, 100),
description: taskDescription,
max_iterations: 10,
status: 'running', // 直接调用时设为 running
current_iteration: 0,
created_at: now,
updated_at: now,
// Skill 扩展字段
skill_state: null // 由 action-init 初始化
}
// 确保目录存在
Bash(`mkdir -p ".loop"`)
Bash(`mkdir -p ".loop/${loopId}.progress"`)
Write(stateFile, JSON.stringify(state, null, 2))
return state
}
```
## Control Signal Checking
```javascript
/**
* 检查 API 控制信号
* 必须在每个 Action 开始前调用
* @returns { continue: boolean, reason: string }
*/
function checkControlSignals(loopId) {
const state = readLoopState(loopId)
if (!state) {
return { continue: false, reason: 'state_not_found' }
}
switch (state.status) {
case 'paused':
// API 暂停了循环Skill 应退出等待 resume
console.log(`⏸️ Loop paused by API. Waiting for resume...`)
return { continue: false, reason: 'paused' }
case 'failed':
// API 停止了循环 (用户手动停止)
console.log(`⏹️ Loop stopped by API.`)
return { continue: false, reason: 'stopped' }
case 'completed':
// 已完成
console.log(`✅ Loop already completed.`)
return { continue: false, reason: 'completed' }
case 'created':
// API 创建但未启动 (不应该走到这里)
console.log(`⚠️ Loop not started by API.`)
return { continue: false, reason: 'not_started' }
case 'running':
// 正常继续
return { continue: true, reason: 'running' }
default:
console.log(`⚠️ Unknown status: ${state.status}`)
return { continue: false, reason: 'unknown_status' }
}
}
```
## Decision Logic
```javascript
/**
* 选择下一个 Action (基于 skill_state)
*/
function selectNextAction(state, mode = 'interactive') {
const skillState = state.skill_state
// 1. 终止条件检查 (API status)
if (state.status === 'completed') return null
if (state.status === 'failed') return null
if (state.current_iteration >= state.max_iterations) {
console.warn(`已达到最大迭代次数 (${state.max_iterations})`)
return 'action-complete'
}
// 2. 初始化检查
if (!skillState || !skillState.current_action) {
return 'action-init'
}
// 3. 模式判断
if (mode === 'interactive') {
return 'action-menu' // 显示菜单让用户选择
}
// 4. 自动模式:基于状态自动选择
if (mode === 'auto') {
// 按优先级develop → debug → validate
// 如果有待开发任务
const hasPendingDevelop = skillState.develop?.tasks?.some(t => t.status === 'pending')
if (hasPendingDevelop) {
return 'action-develop-with-file'
}
// 如果开发完成但未调试
if (skillState.last_action === 'action-develop-with-file') {
const needsDebug = skillState.develop?.completed < skillState.develop?.total
if (needsDebug) {
return 'action-debug-with-file'
}
}
// 如果调试完成但未验证
if (skillState.last_action === 'action-debug-with-file' ||
skillState.debug?.confirmed_hypothesis) {
return 'action-validate-with-file'
}
// 如果验证失败,回到开发
if (skillState.last_action === 'action-validate-with-file') {
if (!skillState.validate?.passed) {
return 'action-develop-with-file'
}
}
// 全部通过,完成
if (skillState.validate?.passed && !hasPendingDevelop) {
return 'action-complete'
}
// 默认:开发
return 'action-develop-with-file'
}
// 5. 默认完成
return 'action-complete'
}
```
## Execution Loop
```javascript
/**
* 运行编排器
* @param options.loopId - 现有 Loop ID (API 触发时)
* @param options.task - 任务描述 (直接调用时)
* @param options.mode - 'interactive' | 'auto'
*/
async function runOrchestrator(options = {}) {
const { loopId: existingLoopId, task, mode = 'interactive' } = options
console.log('=== CCW Loop Orchestrator Started ===')
// 1. 确定 loopId
let loopId
let state
if (existingLoopId) {
// API 触发:使用现有 loopId
loopId = existingLoopId
state = readLoopState(loopId)
if (!state) {
console.error(`Loop not found: ${loopId}`)
return { status: 'error', message: 'Loop not found' }
}
console.log(`Resuming loop: ${loopId}`)
console.log(`Status: ${state.status}`)
} else if (task) {
// 直接调用:创建新 loopId
const timestamp = getUtc8ISOString().replace(/[-:]/g, '').split('.')[0]
const random = Math.random().toString(36).substring(2, 10)
loopId = `loop-v2-${timestamp}-${random}`
console.log(`Creating new loop: ${loopId}`)
console.log(`Task: ${task}`)
state = createLoopState(loopId, task)
} else {
console.error('Either --loop-id or task description is required')
return { status: 'error', message: 'Missing loopId or task' }
}
const progressDir = `.loop/${loopId}.progress`
// 2. 主循环
let iteration = state.current_iteration || 0
while (iteration < state.max_iterations) {
iteration++
// ========================================
// CRITICAL: Check control signals first
// ========================================
const control = checkControlSignals(loopId)
if (!control.continue) {
console.log(`\n🛑 Loop terminated: ${control.reason}`)
break
}
// 重新读取状态 (可能被 API 更新)
state = readLoopState(loopId)
console.log(`\n[Iteration ${iteration}] Status: ${state.status}`)
// 选择下一个动作
const actionId = selectNextAction(state, mode)
if (!actionId) {
console.log('No action selected, terminating.')
break
}
console.log(`[Iteration ${iteration}] Executing: ${actionId}`)
// 更新 current_iteration
state = {
...state,
current_iteration: iteration,
updated_at: getUtc8ISOString()
}
Write(`.loop/${loopId}.json`, JSON.stringify(state, null, 2))
// 执行动作
try {
const actionPromptFile = `.claude/skills/ccw-loop/phases/actions/${actionId}.md`
if (!fs.existsSync(actionPromptFile)) {
console.error(`Action file not found: ${actionPromptFile}`)
continue
}
const actionPrompt = Read(actionPromptFile)
// 构建 Agent 提示
const agentPrompt = `
[LOOP CONTEXT]
Loop ID: ${loopId}
State File: .loop/${loopId}.json
Progress Dir: ${progressDir}
[CURRENT STATE]
${JSON.stringify(state, null, 2)}
[ACTION INSTRUCTIONS]
${actionPrompt}
[TASK]
You are executing ${actionId} for loop: ${state.title || state.description}
[CONTROL SIGNALS]
Before executing, check if status is still 'running'.
If status is 'paused' or 'failed', exit gracefully.
[RETURN]
Return JSON with:
- skillStateUpdates: Object with skill_state fields to update
- continue: Boolean indicating if loop should continue
- message: String with user message
`
const result = await Task({
subagent_type: 'universal-executor',
run_in_background: false,
description: `Execute ${actionId}`,
prompt: agentPrompt
})
// 解析结果
const actionResult = JSON.parse(result)
// 更新状态 (只更新 skill_state)
updateLoopState(loopId, {
current_action: null,
last_action: actionId,
completed_actions: [
...(state.skill_state?.completed_actions || []),
actionId
],
...actionResult.skillStateUpdates
})
// 显示消息
if (actionResult.message) {
console.log(`\n${actionResult.message}`)
}
// 检查是否继续
if (actionResult.continue === false) {
console.log('Action requested termination.')
break
}
} catch (error) {
console.error(`Error executing ${actionId}: ${error.message}`)
// 错误处理
updateLoopState(loopId, {
current_action: null,
errors: [
...(state.skill_state?.errors || []),
{
action: actionId,
message: error.message,
timestamp: getUtc8ISOString()
}
]
})
}
}
if (iteration >= state.max_iterations) {
console.log(`\n⚠️ Reached maximum iterations (${state.max_iterations})`)
console.log('Consider breaking down the task or taking a break.')
}
console.log('\n=== CCW Loop Orchestrator Finished ===')
// 返回最终状态
const finalState = readLoopState(loopId)
return {
status: finalState.status,
loop_id: loopId,
iterations: iteration,
final_state: finalState
}
}
```
## Action Catalog
| Action | Purpose | Preconditions | Effects |
|--------|---------|---------------|---------|
| [action-init](actions/action-init.md) | 初始化会话 | status=pending | initialized=true |
| [action-menu](actions/action-menu.md) | 显示操作菜单 | initialized=true | 用户选择下一动作 |
| [action-develop-with-file](actions/action-develop-with-file.md) | 开发任务 | initialized=true | 更新 progress.md |
| [action-debug-with-file](actions/action-debug-with-file.md) | 假设调试 | initialized=true | 更新 understanding.md |
| [action-validate-with-file](actions/action-validate-with-file.md) | 测试验证 | initialized=true | 更新 validation.md |
| [action-complete](actions/action-complete.md) | 完成循环 | validation_passed=true | status=completed |
## Termination Conditions
1. **API 暂停**: `state.status === 'paused'` (Skill 退出,等待 resume)
2. **API 停止**: `state.status === 'failed'` (Skill 终止)
3. **任务完成**: `state.status === 'completed'`
4. **迭代限制**: `state.current_iteration >= state.max_iterations`
5. **Action 请求终止**: `actionResult.continue === false`
## Error Recovery
| Error Type | Recovery Strategy |
|------------|-------------------|
| 动作执行失败 | 记录错误,增加 error_count继续下一动作 |
| 状态文件损坏 | 从其他文件重建状态 (progress.md, understanding.md 等) |
| 用户中止 | 保存当前状态,允许 --resume 恢复 |
| CLI 工具失败 | 回退到手动分析模式 |
## Mode Strategies
### Interactive Mode (默认)
每次显示菜单,让用户选择动作:
```
当前状态: 开发中
可用操作:
1. 继续开发 (develop)
2. 开始调试 (debug)
3. 运行验证 (validate)
4. 查看进度 (status)
5. 退出 (exit)
请选择:
```
### Auto Mode (自动循环)
按预设流程自动执行:
```
Develop → Debug → Validate →
↓ (如验证失败)
Develop (修复) → Debug → Validate → 完成
```
## State Machine (API Status)
```mermaid
stateDiagram-v2
[*] --> created: API creates loop
created --> running: API /start → Trigger Skill
running --> paused: API /pause → Set status
running --> completed: action-complete
running --> failed: API /stop OR error
paused --> running: API /resume → Re-trigger Skill
completed --> [*]
failed --> [*]
note right of paused
Skill checks status before each action
If paused, Skill exits gracefully
end note
note right of running
Skill executes: init → develop → debug → validate
end note
```

View File

@@ -0,0 +1,474 @@
# State Schema
CCW Loop 的状态结构定义(统一版本)。
## 状态文件
**位置**: `.loop/{loopId}.json` (统一位置API + Skill 共享)
**旧版本位置** (仅向后兼容): `.workflow/.loop/{session-id}/state.json`
## 结构定义
### 统一状态接口 (Unified Loop State)
```typescript
/**
* Unified Loop State - API 和 Skill 共享的状态结构
* API (loop-v2-routes.ts) 拥有状态的主控权
* Skill (ccw-loop) 读取和更新此状态
*/
interface LoopState {
// =====================================================
// API FIELDS (from loop-v2-routes.ts)
// 这些字段由 API 管理Skill 只读
// =====================================================
loop_id: string // Loop ID, e.g., "loop-v2-20260122-abc123"
title: string // Loop 标题
description: string // Loop 描述
max_iterations: number // 最大迭代次数
status: 'created' | 'running' | 'paused' | 'completed' | 'failed'
current_iteration: number // 当前迭代次数
created_at: string // 创建时间 (ISO8601)
updated_at: string // 最后更新时间 (ISO8601)
completed_at?: string // 完成时间 (ISO8601)
failure_reason?: string // 失败原因
// =====================================================
// SKILL EXTENSION FIELDS
// 这些字段由 Skill 管理API 只读
// =====================================================
skill_state?: {
// 当前执行动作
current_action: 'init' | 'develop' | 'debug' | 'validate' | 'complete' | null
last_action: string | null
completed_actions: string[]
mode: 'interactive' | 'auto'
// === 开发阶段 ===
develop: {
total: number
completed: number
current_task?: string
tasks: DevelopTask[]
last_progress_at: string | null
}
// === 调试阶段 ===
debug: {
active_bug?: string
hypotheses_count: number
hypotheses: Hypothesis[]
confirmed_hypothesis: string | null
iteration: number
last_analysis_at: string | null
}
// === 验证阶段 ===
validate: {
pass_rate: number // 测试通过率 (0-100)
coverage: number // 覆盖率 (0-100)
test_results: TestResult[]
passed: boolean
failed_tests: string[]
last_run_at: string | null
}
// === 错误追踪 ===
errors: Array<{
action: string
message: string
timestamp: string
}>
}
}
interface DevelopTask {
id: string
description: string
tool: 'gemini' | 'qwen' | 'codex' | 'bash'
mode: 'analysis' | 'write'
status: 'pending' | 'in_progress' | 'completed' | 'failed'
files_changed: string[]
created_at: string
completed_at: string | null
}
interface Hypothesis {
id: string // H1, H2, ...
description: string
testable_condition: string
logging_point: string
evidence_criteria: {
confirm: string
reject: string
}
likelihood: number // 1 = 最可能
status: 'pending' | 'confirmed' | 'rejected' | 'inconclusive'
evidence: Record<string, any> | null
verdict_reason: string | null
}
interface TestResult {
test_name: string
suite: string
status: 'passed' | 'failed' | 'skipped'
duration_ms: number
error_message: string | null
stack_trace: string | null
}
```
## 初始状态
### 由 API 创建时 (Dashboard 触发)
```json
{
"loop_id": "loop-v2-20260122-abc123",
"title": "Implement user authentication",
"description": "Add login/logout functionality",
"max_iterations": 10,
"status": "created",
"current_iteration": 0,
"created_at": "2026-01-22T10:00:00+08:00",
"updated_at": "2026-01-22T10:00:00+08:00"
}
```
### 由 Skill 初始化后 (action-init)
```json
{
"loop_id": "loop-v2-20260122-abc123",
"title": "Implement user authentication",
"description": "Add login/logout functionality",
"max_iterations": 10,
"status": "running",
"current_iteration": 0,
"created_at": "2026-01-22T10:00:00+08:00",
"updated_at": "2026-01-22T10:00:05+08:00",
"skill_state": {
"current_action": "init",
"last_action": null,
"completed_actions": [],
"mode": "auto",
"develop": {
"total": 3,
"completed": 0,
"current_task": null,
"tasks": [
{ "id": "task-001", "description": "Create auth component", "status": "pending" }
],
"last_progress_at": null
},
"debug": {
"active_bug": null,
"hypotheses_count": 0,
"hypotheses": [],
"confirmed_hypothesis": null,
"iteration": 0,
"last_analysis_at": null
},
"validate": {
"pass_rate": 0,
"coverage": 0,
"test_results": [],
"passed": false,
"failed_tests": [],
"last_run_at": null
},
"errors": []
}
}
```
## 控制信号检查 (Control Signals)
Skill 在每个 Action 开始前必须检查控制信号:
```javascript
/**
* 检查 API 控制信号
* @returns { continue: boolean, action: 'pause_exit' | 'stop_exit' | 'continue' }
*/
function checkControlSignals(loopId) {
const state = JSON.parse(Read(`.loop/${loopId}.json`))
switch (state.status) {
case 'paused':
// API 暂停了循环Skill 应退出等待 resume
return { continue: false, action: 'pause_exit' }
case 'failed':
// API 停止了循环 (用户手动停止)
return { continue: false, action: 'stop_exit' }
case 'running':
// 正常继续
return { continue: true, action: 'continue' }
default:
// 异常状态
return { continue: false, action: 'stop_exit' }
}
}
```
### 在 Action 中使用
```markdown
## Execution
### Step 1: Check Control Signals
\`\`\`javascript
const control = checkControlSignals(loopId)
if (!control.continue) {
// 输出退出原因
console.log(`Loop ${control.action}: status = ${state.status}`)
// 如果是 pause_exit保存当前进度
if (control.action === 'pause_exit') {
updateSkillState(loopId, { current_action: 'paused' })
}
return // 退出 Action
}
\`\`\`
### Step 2: Execute Action Logic
...
```
## 状态转换规则
### 1. 初始化 (action-init)
```javascript
// Skill 初始化后
{
// API 字段更新
status: 'created' 'running', // 或保持 'running' 如果 API 已设置
updated_at: timestamp,
// Skill 字段初始化
skill_state: {
current_action: 'init',
mode: 'auto',
develop: {
tasks: [...parsed_tasks],
total: N,
completed: 0
}
}
}
```
### 2. 开发进行中 (action-develop-with-file)
```javascript
// 开发任务执行后
{
updated_at: timestamp,
current_iteration: state.current_iteration + 1,
skill_state: {
current_action: 'develop',
last_action: 'action-develop-with-file',
completed_actions: [...state.skill_state.completed_actions, 'action-develop-with-file'],
develop: {
current_task: 'task-xxx',
completed: N+1,
last_progress_at: timestamp
}
}
}
```
### 3. 调试进行中 (action-debug-with-file)
```javascript
// 调试执行后
{
updated_at: timestamp,
current_iteration: state.current_iteration + 1,
skill_state: {
current_action: 'debug',
last_action: 'action-debug-with-file',
debug: {
active_bug: '...',
hypotheses_count: N,
hypotheses: [...new_hypotheses],
iteration: N+1,
last_analysis_at: timestamp
}
}
}
```
### 4. 验证完成 (action-validate-with-file)
```javascript
// 验证执行后
{
updated_at: timestamp,
current_iteration: state.current_iteration + 1,
skill_state: {
current_action: 'validate',
last_action: 'action-validate-with-file',
validate: {
test_results: [...results],
pass_rate: 95.5,
coverage: 85.0,
passed: true | false,
failed_tests: ['test1', 'test2'],
last_run_at: timestamp
}
}
}
```
### 5. 完成 (action-complete)
```javascript
// 循环完成后
{
status: 'running' 'completed',
completed_at: timestamp,
updated_at: timestamp,
skill_state: {
current_action: 'complete',
last_action: 'action-complete'
}
}
```
## 状态派生字段
以下字段可从状态计算得出,不需要存储:
```javascript
// 开发完成度
const developProgress = state.develop.total_count > 0
? (state.develop.completed_count / state.develop.total_count) * 100
: 0
// 是否有待开发任务
const hasPendingDevelop = state.develop.tasks.some(t => t.status === 'pending')
// 调试是否完成
const debugCompleted = state.debug.confirmed_hypothesis !== null
// 验证是否通过
const validationPassed = state.validate.passed && state.validate.test_results.length > 0
// 整体进度
const overallProgress = (
(developProgress * 0.5) +
(debugCompleted ? 25 : 0) +
(validationPassed ? 25 : 0)
)
```
## 文件同步
### 统一位置 (Unified Location)
状态与文件的对应关系:
| 状态字段 | 同步文件 | 同步时机 |
|----------|----------|----------|
| 整个 LoopState | `.loop/{loopId}.json` | 每次状态变更 (主文件) |
| `skill_state.develop` | `.loop/{loopId}.progress/develop.md` | 每次开发操作后 |
| `skill_state.debug` | `.loop/{loopId}.progress/debug.md` | 每次调试操作后 |
| `skill_state.validate` | `.loop/{loopId}.progress/validate.md` | 每次验证操作后 |
| 代码变更日志 | `.loop/{loopId}.progress/changes.log` | 每次文件修改 (NDJSON) |
| 调试日志 | `.loop/{loopId}.progress/debug.log` | 每次调试日志 (NDJSON) |
### 文件结构示例
```
.loop/
├── loop-v2-20260122-abc123.json # 主状态文件 (API + Skill)
├── loop-v2-20260122-abc123.tasks.jsonl # 任务列表 (API 管理)
└── loop-v2-20260122-abc123.progress/ # Skill 进度文件
├── develop.md # 开发进度
├── debug.md # 调试理解
├── validate.md # 验证报告
├── changes.log # 代码变更 (NDJSON)
└── debug.log # 调试日志 (NDJSON)
```
## 状态恢复
如果主状态文件 `.loop/{loopId}.json` 损坏,可以从进度文件重建 skill_state:
```javascript
function rebuildSkillStateFromProgress(loopId) {
const progressDir = `.loop/${loopId}.progress`
// 尝试从进度文件解析状态
const skill_state = {
develop: parseProgressFile(`${progressDir}/develop.md`),
debug: parseProgressFile(`${progressDir}/debug.md`),
validate: parseProgressFile(`${progressDir}/validate.md`)
}
return skill_state
}
// 解析进度 Markdown 文件
function parseProgressFile(filePath) {
const content = Read(filePath)
if (!content) return null
// 从 Markdown 表格和结构中提取数据
// ... implementation
}
```
### 恢复策略
1. **API 字段**: 无法恢复 - 需要从 API 重新获取或用户手动输入
2. **skill_state 字段**: 可以从 `.progress/` 目录的 Markdown 文件解析
3. **任务列表**: 从 `.loop/{loopId}.tasks.jsonl` 恢复
## 状态验证
```javascript
function validateState(state) {
const errors = []
// 必需字段
if (!state.session_id) errors.push('Missing session_id')
if (!state.task_description) errors.push('Missing task_description')
// 状态一致性
if (state.initialized && state.status === 'pending') {
errors.push('Inconsistent: initialized but status is pending')
}
if (state.status === 'completed' && !state.validate.passed) {
errors.push('Inconsistent: completed but validation not passed')
}
// 开发任务一致性
const completedTasks = state.develop.tasks.filter(t => t.status === 'completed').length
if (completedTasks !== state.develop.completed_count) {
errors.push('Inconsistent: completed_count mismatch')
}
return { valid: errors.length === 0, errors }
}
```

View File

@@ -0,0 +1,300 @@
# Action Catalog
CCW Loop 所有可用动作的目录和说明。
## Available Actions
| Action | Purpose | Preconditions | Effects | CLI Integration |
|--------|---------|---------------|---------|-----------------|
| [action-init](../phases/actions/action-init.md) | 初始化会话 | status=pending, initialized=false | status→running, initialized→true, 创建目录和任务列表 | Gemini 任务分解 |
| [action-menu](../phases/actions/action-menu.md) | 显示操作菜单 | initialized=true, status=running | 返回用户选择的动作 | - |
| [action-develop-with-file](../phases/actions/action-develop-with-file.md) | 执行开发任务 | initialized=true, pending tasks > 0 | 更新 progress.md, 完成一个任务 | Gemini 代码实现 |
| [action-debug-with-file](../phases/actions/action-debug-with-file.md) | 假设驱动调试 | initialized=true | 更新 understanding.md, hypotheses.json | Gemini 假设生成和证据分析 |
| [action-validate-with-file](../phases/actions/action-validate-with-file.md) | 运行测试验证 | initialized=true, develop > 0 or debug confirmed | 更新 validation.md, test-results.json | Gemini 质量分析 |
| [action-complete](../phases/actions/action-complete.md) | 完成循环 | initialized=true | status→completed, 生成 summary.md | - |
## Action Dependencies Graph
```mermaid
graph TD
START([用户启动 /ccw-loop]) --> INIT[action-init]
INIT --> MENU[action-menu]
MENU --> DEVELOP[action-develop-with-file]
MENU --> DEBUG[action-debug-with-file]
MENU --> VALIDATE[action-validate-with-file]
MENU --> STATUS[action-status]
MENU --> COMPLETE[action-complete]
MENU --> EXIT([退出])
DEVELOP --> MENU
DEBUG --> MENU
VALIDATE --> MENU
STATUS --> MENU
COMPLETE --> END([结束])
EXIT --> END
style INIT fill:#e1f5fe
style MENU fill:#fff3e0
style DEVELOP fill:#e8f5e9
style DEBUG fill:#fce4ec
style VALIDATE fill:#f3e5f5
style COMPLETE fill:#c8e6c9
```
## Action Execution Matrix
### Interactive Mode
| State | Auto-Selected Action | User Options |
|-------|---------------------|--------------|
| pending | action-init | - |
| running, !initialized | action-init | - |
| running, initialized | action-menu | All actions |
### Auto Mode
| Condition | Selected Action |
|-----------|----------------|
| pending_develop_tasks > 0 | action-develop-with-file |
| last_action=develop, !debug_completed | action-debug-with-file |
| last_action=debug, !validation_completed | action-validate-with-file |
| validation_failed | action-develop-with-file (fix) |
| validation_passed, no pending | action-complete |
## Action Inputs/Outputs
### action-init
**Inputs**:
- state.task_description
- User input (optional)
**Outputs**:
- meta.json
- state.json (初始化)
- develop/tasks.json
- develop/progress.md
**State Changes**:
```javascript
{
status: 'pending' 'running',
initialized: false true,
develop.tasks: [] [task1, task2, ...]
}
```
### action-develop-with-file
**Inputs**:
- state.develop.tasks
- User selection (如有多个待处理任务)
**Outputs**:
- develop/progress.md (追加)
- develop/tasks.json (更新)
- develop/changes.log (追加)
**State Changes**:
```javascript
{
develop.current_task_id: null 'task-xxx' null,
develop.completed_count: N N+1,
last_action: X 'action-develop-with-file'
}
```
### action-debug-with-file
**Inputs**:
- Bug description (用户输入或从测试失败获取)
- debug.log (如已有)
**Outputs**:
- debug/understanding.md (追加)
- debug/hypotheses.json (更新)
- Code changes (添加日志或修复)
**State Changes**:
```javascript
{
debug.current_bug: null 'bug description',
debug.hypotheses: [...updated],
debug.iteration: N N+1,
debug.confirmed_hypothesis: null 'H1' (如确认)
}
```
### action-validate-with-file
**Inputs**:
- 测试脚本 (从 package.json)
- 覆盖率工具 (可选)
**Outputs**:
- validate/validation.md (追加)
- validate/test-results.json (更新)
- validate/coverage.json (更新)
**State Changes**:
```javascript
{
validate.test_results: [...new results],
validate.coverage: null 85.5,
validate.passed: false true,
validate.failed_tests: ['test1', 'test2'] []
}
```
### action-complete
**Inputs**:
- state (完整状态)
- User choices (扩展选项)
**Outputs**:
- summary.md
- Issues (如选择扩展)
**State Changes**:
```javascript
{
status: 'running' 'completed',
completed_at: null timestamp
}
```
## Action Sequences
### Typical Happy Path
```
action-init
→ action-develop-with-file (task 1)
→ action-develop-with-file (task 2)
→ action-develop-with-file (task 3)
→ action-validate-with-file
→ PASS
→ action-complete
```
### Debug Iteration Path
```
action-init
→ action-develop-with-file (task 1)
→ action-validate-with-file
→ FAIL
→ action-debug-with-file (探索)
→ action-debug-with-file (分析)
→ Root cause found
→ action-validate-with-file
→ PASS
→ action-complete
```
### Multi-Iteration Path
```
action-init
→ action-develop-with-file (task 1)
→ action-debug-with-file
→ action-develop-with-file (task 2)
→ action-validate-with-file
→ FAIL
→ action-debug-with-file
→ action-validate-with-file
→ PASS
→ action-complete
```
## Error Scenarios
### CLI Tool Failure
```
action-develop-with-file
→ Gemini CLI fails
→ Fallback to manual implementation
→ Prompt user for code
→ Continue
```
### Test Failure
```
action-validate-with-file
→ Tests fail
→ Record failed tests
→ Suggest action-debug-with-file
→ User chooses debug or manual fix
```
### Max Iterations Reached
```
state.iteration_count >= 10
→ Warning message
→ Suggest break or task split
→ Allow continue or exit
```
## Action Extensions
### Adding New Actions
To add a new action:
1. Create `phases/actions/action-{name}.md`
2. Define preconditions, execution, state updates
3. Add to this catalog
4. Update orchestrator.md decision logic
5. Add to action-menu.md options
### Action Template
```markdown
# Action: {Name}
{Brief description}
## Purpose
{Detailed purpose}
## Preconditions
- [ ] condition1
- [ ] condition2
## Execution
### Step 1: {Step Name}
\`\`\`javascript
// code
\`\`\`
## State Updates
\`\`\`javascript
return {
stateUpdates: {
// updates
},
continue: true,
message: "..."
}
\`\`\`
## Error Handling
| Error Type | Recovery |
|------------|----------|
| ... | ... |
## Next Actions (Hints)
- condition: next_action
```

View File

@@ -0,0 +1,192 @@
# Loop Requirements Specification
CCW Loop 的核心需求和约束定义。
## Core Requirements
### 1. 无状态循环
**Requirement**: 每次执行从文件读取状态,执行后写回文件,不依赖内存状态。
**Rationale**: 支持随时中断和恢复,状态持久化。
**Validation**:
- [ ] 每个 action 开始时从文件读取状态
- [ ] 每个 action 结束时将状态写回文件
- [ ] 无全局变量或内存状态依赖
### 2. 文件驱动进度
**Requirement**: 所有进度、理解、验证结果都记录在专用 Markdown 文件中。
**Rationale**: 可审计、可回顾、团队可见。
**Validation**:
- [ ] develop/progress.md 记录开发进度
- [ ] debug/understanding.md 记录理解演变
- [ ] validate/validation.md 记录验证结果
- [ ] 所有文件使用 Markdown 格式,易读
### 3. CLI 工具集成
**Requirement**: 关键决策点使用 Gemini/CLI 进行深度分析。
**Rationale**: 利用 LLM 能力提高质量。
**Validation**:
- [ ] 任务分解使用 Gemini
- [ ] 假设生成使用 Gemini
- [ ] 证据分析使用 Gemini
- [ ] 质量评估使用 Gemini
### 4. 用户控制循环
**Requirement**: 支持交互式和自动循环两种模式,用户可随时介入。
**Rationale**: 灵活性,适应不同场景。
**Validation**:
- [ ] 交互模式:每步显示菜单
- [ ] 自动模式:按预设流程执行
- [ ] 用户可随时退出
- [ ] 状态可恢复
### 5. 可恢复性
**Requirement**: 任何时候中断后,可以从上次位置继续。
**Rationale**: 长时间任务支持,意外中断恢复。
**Validation**:
- [ ] 状态保存在 state.json
- [ ] 使用 --resume 可继续
- [ ] 历史记录完整保留
## Quality Standards
### Completeness
| Dimension | Threshold |
|-----------|-----------|
| 进度文档完整性 | 每个任务都有记录 |
| 理解文档演变 | 每次迭代都有更新 |
| 验证报告详尽 | 包含所有测试结果 |
### Consistency
| Dimension | Threshold |
|-----------|-----------|
| 文件格式一致 | 所有 Markdown 文件使用相同模板 |
| 状态同步一致 | state.json 与文件内容匹配 |
| 时间戳格式 | 统一使用 ISO8601 格式 |
### Usability
| Dimension | Threshold |
|-----------|-----------|
| 菜单易用性 | 选项清晰,描述准确 |
| 进度可见性 | 随时可查看当前状态 |
| 错误提示 | 错误消息清晰,提供恢复建议 |
## Constraints
### 1. 文件结构约束
```
.workflow/.loop/{session-id}/
├── meta.json # 只写一次,不再修改
├── state.json # 每次 action 后更新
├── develop/
│ ├── progress.md # 只追加,不删除
│ ├── tasks.json # 任务状态更新
│ └── changes.log # NDJSON 格式,只追加
├── debug/
│ ├── understanding.md # 只追加,记录时间线
│ ├── hypotheses.json # 更新假设状态
│ └── debug.log # NDJSON 格式
└── validate/
├── validation.md # 每次验证追加
├── test-results.json # 累积测试结果
└── coverage.json # 最新覆盖率
```
### 2. 命名约束
- Session ID: `LOOP-{slug}-{YYYY-MM-DD}`
- Task ID: `task-{NNN}` (三位数字)
- Hypothesis ID: `H{N}` (单字母+数字)
### 3. 状态转换约束
```
pending → running → completed
user_exit
failed
```
Only allow: `pending→running`, `running→completed/user_exit/failed`
### 4. 错误限制约束
- 最大错误次数: 3
- 超过 3 次错误 → 自动终止
- 每次错误 → 记录到 state.errors[]
### 5. 迭代限制约束
- 最大迭代次数: 10 (警告)
- 超过 10 次 → 警告用户,但不强制停止
- 建议拆分任务或休息
## Integration Requirements
### 1. Dashboard 集成
**Requirement**: 与 CCW Dashboard Loop Monitor 无缝集成。
**Specification**:
- Dashboard 创建 Loop → 调用此 Skill
- state.json → Dashboard 实时显示
- 任务列表双向同步
- 状态控制按钮映射到 actions
### 2. Issue 系统集成
**Requirement**: 完成后可扩展为 Issue。
**Specification**:
- 支持维度: test, enhance, refactor, doc
- 调用 `/issue:new "{summary} - {dimension}"`
- 自动填充上下文
### 3. CLI 工具集成
**Requirement**: 使用 CCW CLI 工具进行分析和实现。
**Specification**:
- 任务分解: `--rule planning-breakdown-task-steps`
- 代码实现: `--rule development-implement-feature`
- 根因分析: `--rule analysis-diagnose-bug-root-cause`
- 质量评估: `--rule analysis-review-code-quality`
## Non-Functional Requirements
### Performance
- Session 初始化: < 5s
- Action 执行: < 30s (不含 CLI 调用)
- 状态读写: < 1s
### Reliability
- 状态文件损坏恢复: 支持从其他文件重建
- CLI 工具失败降级: 回退到手动模式
- 错误重试: 支持一次自动重试
### Maintainability
- 文档化: 所有 action 都有清晰说明
- 模块化: 每个 action 独立可测
- 可扩展: 易于添加新 action

View File

@@ -0,0 +1,175 @@
# Progress Document Template
开发进度文档的标准模板。
## Template Structure
```markdown
# Development Progress
**Session ID**: {{session_id}}
**Task**: {{task_description}}
**Started**: {{started_at}}
**Estimated Complexity**: {{complexity}}
---
## Task List
{{#each tasks}}
{{@index}}. [{{#if completed}}x{{else}} {{/if}}] {{description}}
{{/each}}
## Key Files
{{#each key_files}}
- `{{this}}`
{{/each}}
---
## Progress Timeline
{{#each iterations}}
### Iteration {{@index}} - {{task_name}} ({{timestamp}})
#### Task Details
- **ID**: {{task_id}}
- **Tool**: {{tool}}
- **Mode**: {{mode}}
#### Implementation Summary
{{summary}}
#### Files Changed
{{#each files_changed}}
- `{{this}}`
{{/each}}
#### Status: {{status}}
---
{{/each}}
## Current Statistics
| Metric | Value |
|--------|-------|
| Total Tasks | {{total_tasks}} |
| Completed | {{completed_tasks}} |
| In Progress | {{in_progress_tasks}} |
| Pending | {{pending_tasks}} |
| Progress | {{progress_percentage}}% |
---
## Next Steps
{{#each next_steps}}
- [ ] {{this}}
{{/each}}
```
## Template Variables
| Variable | Type | Source | Description |
|----------|------|--------|-------------|
| `session_id` | string | state.session_id | 会话 ID |
| `task_description` | string | state.task_description | 任务描述 |
| `started_at` | string | state.created_at | 开始时间 |
| `complexity` | string | state.context.estimated_complexity | 预估复杂度 |
| `tasks` | array | state.develop.tasks | 任务列表 |
| `key_files` | array | state.context.key_files | 关键文件 |
| `iterations` | array | 从文件解析 | 迭代历史 |
| `total_tasks` | number | state.develop.total_count | 总任务数 |
| `completed_tasks` | number | state.develop.completed_count | 已完成数 |
## Usage Example
```javascript
const progressTemplate = Read('.claude/skills/ccw-loop/templates/progress-template.md')
function renderProgress(state) {
let content = progressTemplate
// 替换简单变量
content = content.replace('{{session_id}}', state.session_id)
content = content.replace('{{task_description}}', state.task_description)
content = content.replace('{{started_at}}', state.created_at)
content = content.replace('{{complexity}}', state.context?.estimated_complexity || 'unknown')
// 替换任务列表
const taskList = state.develop.tasks.map((t, i) => {
const checkbox = t.status === 'completed' ? 'x' : ' '
return `${i + 1}. [${checkbox}] ${t.description}`
}).join('\n')
content = content.replace('{{#each tasks}}...{{/each}}', taskList)
// 替换统计
content = content.replace('{{total_tasks}}', state.develop.total_count)
content = content.replace('{{completed_tasks}}', state.develop.completed_count)
// ...
return content
}
```
## Section Templates
### Task Entry
```markdown
### Iteration {{N}} - {{task_name}} ({{timestamp}})
#### Task Details
- **ID**: {{task_id}}
- **Tool**: {{tool}}
- **Mode**: {{mode}}
#### Implementation Summary
{{summary}}
#### Files Changed
{{#each files}}
- `{{this}}`
{{/each}}
#### Status: COMPLETED
---
```
### Statistics Table
```markdown
## Current Statistics
| Metric | Value |
|--------|-------|
| Total Tasks | {{total}} |
| Completed | {{completed}} |
| In Progress | {{in_progress}} |
| Pending | {{pending}} |
| Progress | {{percentage}}% |
```
### Next Steps
```markdown
## Next Steps
{{#if all_completed}}
- [ ] Run validation tests
- [ ] Code review
- [ ] Update documentation
{{else}}
- [ ] Complete remaining {{pending}} tasks
- [ ] Review completed work
{{/if}}
```

View File

@@ -0,0 +1,303 @@
# Understanding Document Template
调试理解演变文档的标准模板。
## Template Structure
```markdown
# Understanding Document
**Session ID**: {{session_id}}
**Bug Description**: {{bug_description}}
**Started**: {{started_at}}
---
## Exploration Timeline
{{#each iterations}}
### Iteration {{number}} - {{title}} ({{timestamp}})
{{#if is_exploration}}
#### Current Understanding
Based on bug description and initial code search:
- Error pattern: {{error_pattern}}
- Affected areas: {{affected_areas}}
- Initial hypothesis: {{initial_thoughts}}
#### Evidence from Code Search
{{#each search_results}}
**Keyword: "{{keyword}}"**
- Found in: {{files}}
- Key findings: {{insights}}
{{/each}}
{{/if}}
{{#if has_hypotheses}}
#### Hypotheses Generated (Gemini-Assisted)
{{#each hypotheses}}
**{{id}}** (Likelihood: {{likelihood}}): {{description}}
- Logging at: {{logging_point}}
- Testing: {{testable_condition}}
- Evidence to confirm: {{confirm_criteria}}
- Evidence to reject: {{reject_criteria}}
{{/each}}
**Gemini Insights**: {{gemini_insights}}
{{/if}}
{{#if is_analysis}}
#### Log Analysis Results
{{#each results}}
**{{id}}**: {{verdict}}
- Evidence: {{evidence}}
- Reasoning: {{reason}}
{{/each}}
#### Corrected Understanding
Previous misunderstandings identified and corrected:
{{#each corrections}}
- ~~{{wrong}}~~ → {{corrected}}
- Why wrong: {{reason}}
- Evidence: {{evidence}}
{{/each}}
#### New Insights
{{#each insights}}
- {{this}}
{{/each}}
#### Gemini Analysis
{{gemini_analysis}}
{{/if}}
{{#if root_cause_found}}
#### Root Cause Identified
**{{hypothesis_id}}**: {{description}}
Evidence supporting this conclusion:
{{supporting_evidence}}
{{else}}
#### Next Steps
{{next_steps}}
{{/if}}
---
{{/each}}
## Current Consolidated Understanding
### What We Know
{{#each valid_understandings}}
- {{this}}
{{/each}}
### What Was Disproven
{{#each disproven}}
- ~~{{assumption}}~~ (Evidence: {{evidence}})
{{/each}}
### Current Investigation Focus
{{current_focus}}
### Remaining Questions
{{#each questions}}
- {{this}}
{{/each}}
```
## Template Variables
| Variable | Type | Source | Description |
|----------|------|--------|-------------|
| `session_id` | string | state.session_id | 会话 ID |
| `bug_description` | string | state.debug.current_bug | Bug 描述 |
| `iterations` | array | 从文件解析 | 迭代历史 |
| `hypotheses` | array | state.debug.hypotheses | 假设列表 |
| `valid_understandings` | array | 从 Gemini 分析 | 有效理解 |
| `disproven` | array | 从假设状态 | 被否定的假设 |
## Section Templates
### Exploration Section
```markdown
### Iteration {{N}} - Initial Exploration ({{timestamp}})
#### Current Understanding
Based on bug description and initial code search:
- Error pattern: {{pattern}}
- Affected areas: {{areas}}
- Initial hypothesis: {{thoughts}}
#### Evidence from Code Search
{{#each search_results}}
**Keyword: "{{keyword}}"**
- Found in: {{files}}
- Key findings: {{insights}}
{{/each}}
#### Next Steps
- Generate testable hypotheses
- Add instrumentation
- Await reproduction
```
### Hypothesis Section
```markdown
#### Hypotheses Generated (Gemini-Assisted)
| ID | Description | Likelihood | Status |
|----|-------------|------------|--------|
{{#each hypotheses}}
| {{id}} | {{description}} | {{likelihood}} | {{status}} |
{{/each}}
**Details:**
{{#each hypotheses}}
**{{id}}**: {{description}}
- Logging at: `{{logging_point}}`
- Testing: {{testable_condition}}
- Confirm: {{evidence_criteria.confirm}}
- Reject: {{evidence_criteria.reject}}
{{/each}}
```
### Analysis Section
```markdown
### Iteration {{N}} - Evidence Analysis ({{timestamp}})
#### Log Analysis Results
{{#each results}}
**{{id}}**: **{{verdict}}**
- Evidence: \`{{evidence}}\`
- Reasoning: {{reason}}
{{/each}}
#### Corrected Understanding
| Previous Assumption | Corrected To | Reason |
|---------------------|--------------|--------|
{{#each corrections}}
| ~~{{wrong}}~~ | {{corrected}} | {{reason}} |
{{/each}}
#### Gemini Analysis
{{gemini_analysis}}
```
### Consolidated Understanding Section
```markdown
## Current Consolidated Understanding
### What We Know
{{#each valid}}
- {{this}}
{{/each}}
### What Was Disproven
{{#each disproven}}
- ~~{{this.assumption}}~~ (Evidence: {{this.evidence}})
{{/each}}
### Current Investigation Focus
{{focus}}
### Remaining Questions
{{#each questions}}
- {{this}}
{{/each}}
```
### Resolution Section
```markdown
### Resolution ({{timestamp}})
#### Fix Applied
- Modified files: {{files}}
- Fix description: {{description}}
- Root cause addressed: {{root_cause}}
#### Verification Results
{{verification}}
#### Lessons Learned
{{#each lessons}}
{{@index}}. {{this}}
{{/each}}
#### Key Insights for Future
{{#each insights}}
- {{this}}
{{/each}}
```
## Consolidation Rules
更新 "Current Consolidated Understanding" 时遵循以下规则:
1. **简化被否定项**: 移到 "What Was Disproven",只保留单行摘要
2. **保留有效见解**: 将确认的发现提升到 "What We Know"
3. **避免重复**: 不在合并部分重复时间线细节
4. **关注当前状态**: 描述现在知道什么,而不是过程
5. **保留关键纠正**: 保留重要的 wrong→right 转换供学习
## Anti-Patterns
**错误示例 (冗余)**:
```markdown
## Current Consolidated Understanding
In iteration 1 we thought X, but in iteration 2 we found Y, then in iteration 3...
Also we checked A and found B, and then we checked C...
```
**正确示例 (精简)**:
```markdown
## Current Consolidated Understanding
### What We Know
- Error occurs during runtime update, not initialization
- Config value is None (not missing key)
### What Was Disproven
- ~~Initialization error~~ (Timing evidence)
- ~~Missing key hypothesis~~ (Key exists)
### Current Investigation Focus
Why is config value None during update?
```

View File

@@ -0,0 +1,258 @@
# Validation Report Template
验证报告的标准模板。
## Template Structure
```markdown
# Validation Report
**Session ID**: {{session_id}}
**Task**: {{task_description}}
**Validated**: {{timestamp}}
---
## Iteration {{iteration}} - Validation Run
### Test Execution Summary
| Metric | Value |
|--------|-------|
| Total Tests | {{total_tests}} |
| Passed | {{passed_tests}} |
| Failed | {{failed_tests}} |
| Skipped | {{skipped_tests}} |
| Duration | {{duration}}ms |
| **Pass Rate** | **{{pass_rate}}%** |
### Coverage Report
{{#if has_coverage}}
| File | Statements | Branches | Functions | Lines |
|------|------------|----------|-----------|-------|
{{#each coverage_files}}
| {{path}} | {{statements}}% | {{branches}}% | {{functions}}% | {{lines}}% |
{{/each}}
**Overall Coverage**: {{overall_coverage}}%
{{else}}
_No coverage data available_
{{/if}}
### Failed Tests
{{#if has_failures}}
{{#each failures}}
#### {{test_name}}
- **Suite**: {{suite}}
- **Error**: {{error_message}}
- **Stack**:
\`\`\`
{{stack_trace}}
\`\`\`
{{/each}}
{{else}}
_All tests passed_
{{/if}}
### Gemini Quality Analysis
{{gemini_analysis}}
### Recommendations
{{#each recommendations}}
- {{this}}
{{/each}}
---
## Validation Decision
**Result**: {{#if passed}}✅ PASS{{else}}❌ FAIL{{/if}}
**Rationale**: {{rationale}}
{{#if not_passed}}
### Next Actions
1. Review failed tests
2. Debug failures using action-debug-with-file
3. Fix issues and re-run validation
{{else}}
### Next Actions
1. Consider code review
2. Prepare for deployment
3. Update documentation
{{/if}}
```
## Template Variables
| Variable | Type | Source | Description |
|----------|------|--------|-------------|
| `session_id` | string | state.session_id | 会话 ID |
| `task_description` | string | state.task_description | 任务描述 |
| `timestamp` | string | 当前时间 | 验证时间 |
| `iteration` | number | 从文件计算 | 验证迭代次数 |
| `total_tests` | number | 测试输出 | 总测试数 |
| `passed_tests` | number | 测试输出 | 通过数 |
| `failed_tests` | number | 测试输出 | 失败数 |
| `pass_rate` | number | 计算得出 | 通过率 |
| `coverage_files` | array | 覆盖率报告 | 文件覆盖率 |
| `failures` | array | 测试输出 | 失败测试详情 |
| `gemini_analysis` | string | Gemini CLI | 质量分析 |
| `recommendations` | array | Gemini CLI | 建议列表 |
## Section Templates
### Test Summary
```markdown
### Test Execution Summary
| Metric | Value |
|--------|-------|
| Total Tests | {{total}} |
| Passed | {{passed}} |
| Failed | {{failed}} |
| Skipped | {{skipped}} |
| Duration | {{duration}}ms |
| **Pass Rate** | **{{rate}}%** |
```
### Coverage Table
```markdown
### Coverage Report
| File | Statements | Branches | Functions | Lines |
|------|------------|----------|-----------|-------|
{{#each files}}
| `{{path}}` | {{statements}}% | {{branches}}% | {{functions}}% | {{lines}}% |
{{/each}}
**Overall Coverage**: {{overall}}%
**Coverage Thresholds**:
- ✅ Good: ≥ 80%
- ⚠️ Warning: 60-79%
- ❌ Poor: < 60%
```
### Failed Test Details
```markdown
### Failed Tests
{{#each failures}}
#### ❌ {{test_name}}
| Field | Value |
|-------|-------|
| Suite | {{suite}} |
| Error | {{error_message}} |
| Duration | {{duration}}ms |
**Stack Trace**:
\`\`\`
{{stack_trace}}
\`\`\`
**Possible Causes**:
{{#each possible_causes}}
- {{this}}
{{/each}}
---
{{/each}}
```
### Quality Analysis
```markdown
### Gemini Quality Analysis
#### Code Quality Assessment
| Dimension | Score | Status |
|-----------|-------|--------|
| Correctness | {{correctness}}/10 | {{correctness_status}} |
| Completeness | {{completeness}}/10 | {{completeness_status}} |
| Reliability | {{reliability}}/10 | {{reliability_status}} |
| Maintainability | {{maintainability}}/10 | {{maintainability_status}} |
#### Key Findings
{{#each findings}}
- **{{severity}}**: {{description}}
{{/each}}
#### Recommendations
{{#each recommendations}}
{{@index}}. {{this}}
{{/each}}
```
### Decision Section
```markdown
## Validation Decision
**Result**: {{#if passed}}✅ PASS{{else}}❌ FAIL{{/if}}
**Rationale**:
{{rationale}}
**Confidence Level**: {{confidence}}
### Decision Matrix
| Criteria | Status | Weight | Score |
|----------|--------|--------|-------|
| All tests pass | {{tests_pass}} | 40% | {{tests_score}} |
| Coverage ≥ 80% | {{coverage_pass}} | 30% | {{coverage_score}} |
| No critical issues | {{no_critical}} | 20% | {{critical_score}} |
| Quality analysis pass | {{quality_pass}} | 10% | {{quality_score}} |
| **Total** | | 100% | **{{total_score}}** |
**Threshold**: 70% to pass
### Next Actions
{{#if passed}}
1. ✅ Code review (recommended)
2. ✅ Update documentation
3. ✅ Prepare for deployment
{{else}}
1. ❌ Review failed tests
2. ❌ Debug failures
3. ❌ Fix issues and re-run
{{/if}}
```
## Historical Comparison
```markdown
## Validation History
| Iteration | Date | Pass Rate | Coverage | Status |
|-----------|------|-----------|----------|--------|
{{#each history}}
| {{iteration}} | {{date}} | {{pass_rate}}% | {{coverage}}% | {{status}} |
{{/each}}
### Trend Analysis
{{#if improving}}
📈 **Improving**: Pass rate increased from {{previous_rate}}% to {{current_rate}}%
{{else if declining}}
📉 **Declining**: Pass rate decreased from {{previous_rate}}% to {{current_rate}}%
{{else}}
➡️ **Stable**: Pass rate remains at {{current_rate}}%
{{/if}}
```