claude-code-workflow 6.3.36 → 6.3.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/workflow/lite-execute.md +2 -0
- package/.claude/commands/workflow/lite-fix.md +108 -9
- package/.claude/skills/ccw-loop/README.md +303 -0
- package/.claude/skills/ccw-loop/SKILL.md +259 -0
- package/.claude/skills/ccw-loop/phases/actions/action-complete.md +320 -0
- package/.claude/skills/ccw-loop/phases/actions/action-debug-with-file.md +485 -0
- package/.claude/skills/ccw-loop/phases/actions/action-develop-with-file.md +365 -0
- package/.claude/skills/ccw-loop/phases/actions/action-init.md +200 -0
- package/.claude/skills/ccw-loop/phases/actions/action-menu.md +192 -0
- package/.claude/skills/ccw-loop/phases/actions/action-validate-with-file.md +307 -0
- package/.claude/skills/ccw-loop/phases/orchestrator.md +486 -0
- package/.claude/skills/ccw-loop/phases/state-schema.md +474 -0
- package/.claude/skills/ccw-loop/specs/action-catalog.md +300 -0
- package/.claude/skills/ccw-loop/specs/loop-requirements.md +192 -0
- package/.claude/skills/ccw-loop/templates/progress-template.md +175 -0
- package/.claude/skills/ccw-loop/templates/understanding-template.md +303 -0
- package/.claude/skills/ccw-loop/templates/validation-template.md +258 -0
- package/.codex/agents/action-planning-agent.md +885 -0
- package/.codex/agents/ccw-loop-executor.md +260 -0
- package/.codex/agents/cli-discuss-agent.md +391 -0
- package/.codex/agents/cli-execution-agent.md +333 -0
- package/.codex/agents/cli-explore-agent.md +186 -0
- package/.codex/agents/cli-lite-planning-agent.md +736 -0
- package/.codex/agents/cli-planning-agent.md +562 -0
- package/.codex/agents/code-developer.md +408 -0
- package/.codex/agents/conceptual-planning-agent.md +321 -0
- package/.codex/agents/context-search-agent.md +585 -0
- package/.codex/agents/debug-explore-agent.md +436 -0
- package/.codex/agents/doc-generator.md +334 -0
- package/.codex/agents/issue-plan-agent.md +417 -0
- package/.codex/agents/issue-queue-agent.md +311 -0
- package/.codex/agents/memory-bridge.md +96 -0
- package/.codex/agents/test-context-search-agent.md +402 -0
- package/.codex/agents/test-fix-agent.md +359 -0
- package/.codex/agents/ui-design-agent.md +595 -0
- package/.codex/agents/universal-executor.md +135 -0
- package/.codex/prompts/issue-discover-by-prompt.md +364 -0
- package/.codex/prompts/issue-discover.md +261 -0
- package/.codex/prompts/issue-execute.md +10 -0
- package/.codex/prompts/issue-new.md +285 -0
- package/.codex/prompts/issue-plan.md +161 -63
- package/.codex/prompts/issue-queue.md +298 -288
- package/.codex/prompts/lite-execute.md +627 -133
- package/.codex/prompts/lite-fix.md +670 -0
- package/.codex/prompts/lite-plan-a.md +337 -0
- package/.codex/prompts/lite-plan-b.md +485 -0
- package/.codex/prompts/{lite-plan.md → lite-plan-c.md} +601 -469
- package/.codex/skills/ccw-loop/README.md +171 -0
- package/.codex/skills/ccw-loop/SKILL.md +349 -0
- package/.codex/skills/ccw-loop/phases/actions/action-complete.md +269 -0
- package/.codex/skills/ccw-loop/phases/actions/action-debug.md +286 -0
- package/.codex/skills/ccw-loop/phases/actions/action-develop.md +183 -0
- package/.codex/skills/ccw-loop/phases/actions/action-init.md +164 -0
- package/.codex/skills/ccw-loop/phases/actions/action-menu.md +205 -0
- package/.codex/skills/ccw-loop/phases/actions/action-validate.md +250 -0
- package/.codex/skills/ccw-loop/phases/orchestrator.md +416 -0
- package/.codex/skills/ccw-loop/phases/state-schema.md +388 -0
- package/.codex/skills/ccw-loop/specs/action-catalog.md +182 -0
- package/.codex/skills/ccw-loop-b/README.md +102 -0
- package/.codex/skills/ccw-loop-b/SKILL.md +322 -0
- package/.codex/skills/ccw-loop-b/phases/orchestrator.md +257 -0
- package/.codex/skills/ccw-loop-b/phases/state-schema.md +181 -0
- package/ccw/dist/cli.d.ts.map +1 -1
- package/ccw/dist/cli.js +12 -1
- package/ccw/dist/cli.js.map +1 -1
- package/ccw/dist/commands/cli.d.ts.map +1 -1
- package/ccw/dist/commands/cli.js +14 -1
- package/ccw/dist/commands/cli.js.map +1 -1
- package/ccw/dist/commands/install.d.ts.map +1 -1
- package/ccw/dist/commands/install.js +38 -7
- package/ccw/dist/commands/install.js.map +1 -1
- package/ccw/dist/commands/issue.d.ts +3 -0
- package/ccw/dist/commands/issue.d.ts.map +1 -1
- package/ccw/dist/commands/issue.js +107 -0
- package/ccw/dist/commands/issue.js.map +1 -1
- package/ccw/dist/commands/loop.d.ts +10 -0
- package/ccw/dist/commands/loop.d.ts.map +1 -0
- package/ccw/dist/commands/loop.js +289 -0
- package/ccw/dist/commands/loop.js.map +1 -0
- package/ccw/dist/commands/upgrade.js +1 -1
- package/ccw/dist/commands/upgrade.js.map +1 -1
- package/ccw/dist/config/litellm-api-config-manager.d.ts.map +1 -1
- package/ccw/dist/config/litellm-api-config-manager.js +3 -2
- package/ccw/dist/config/litellm-api-config-manager.js.map +1 -1
- package/ccw/dist/core/dashboard-generator.d.ts.map +1 -1
- package/ccw/dist/core/dashboard-generator.js +4 -1
- package/ccw/dist/core/dashboard-generator.js.map +1 -1
- package/ccw/dist/core/memory-embedder-bridge.d.ts.map +1 -1
- package/ccw/dist/core/memory-embedder-bridge.js +2 -5
- package/ccw/dist/core/memory-embedder-bridge.js.map +1 -1
- package/ccw/dist/core/routes/claude-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/claude-routes.js +5 -3
- package/ccw/dist/core/routes/claude-routes.js.map +1 -1
- package/ccw/dist/core/routes/cli-routes.d.ts +6 -0
- package/ccw/dist/core/routes/cli-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/cli-routes.js +42 -13
- package/ccw/dist/core/routes/cli-routes.js.map +1 -1
- package/ccw/dist/core/routes/cli-settings-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/cli-settings-routes.js +44 -0
- package/ccw/dist/core/routes/cli-settings-routes.js.map +1 -1
- package/ccw/dist/core/routes/codexlens/config-handlers.d.ts.map +1 -1
- package/ccw/dist/core/routes/codexlens/config-handlers.js +7 -6
- package/ccw/dist/core/routes/codexlens/config-handlers.js.map +1 -1
- package/ccw/dist/core/routes/codexlens/semantic-handlers.d.ts.map +1 -1
- package/ccw/dist/core/routes/codexlens/semantic-handlers.js +5 -4
- package/ccw/dist/core/routes/codexlens/semantic-handlers.js.map +1 -1
- package/ccw/dist/core/routes/core-memory-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/core-memory-routes.js +4 -2
- package/ccw/dist/core/routes/core-memory-routes.js.map +1 -1
- package/ccw/dist/core/routes/files-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/files-routes.js +4 -2
- package/ccw/dist/core/routes/files-routes.js.map +1 -1
- package/ccw/dist/core/routes/graph-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/graph-routes.js +17 -2
- package/ccw/dist/core/routes/graph-routes.js.map +1 -1
- package/ccw/dist/core/routes/issue-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/issue-routes.js +280 -33
- package/ccw/dist/core/routes/issue-routes.js.map +1 -1
- package/ccw/dist/core/routes/loop-routes.d.ts +24 -0
- package/ccw/dist/core/routes/loop-routes.d.ts.map +1 -0
- package/ccw/dist/core/routes/loop-routes.js +334 -0
- package/ccw/dist/core/routes/loop-routes.js.map +1 -0
- package/ccw/dist/core/routes/loop-v2-routes.d.ts +44 -0
- package/ccw/dist/core/routes/loop-v2-routes.d.ts.map +1 -0
- package/ccw/dist/core/routes/loop-v2-routes.js +1260 -0
- package/ccw/dist/core/routes/loop-v2-routes.js.map +1 -0
- package/ccw/dist/core/routes/memory-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/memory-routes.js +2 -1
- package/ccw/dist/core/routes/memory-routes.js.map +1 -1
- package/ccw/dist/core/routes/system-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/system-routes.js +3 -2
- package/ccw/dist/core/routes/system-routes.js.map +1 -1
- package/ccw/dist/core/routes/task-routes.d.ts +12 -0
- package/ccw/dist/core/routes/task-routes.d.ts.map +1 -0
- package/ccw/dist/core/routes/task-routes.js +321 -0
- package/ccw/dist/core/routes/task-routes.js.map +1 -0
- package/ccw/dist/core/routes/test-loop-routes.d.ts +11 -0
- package/ccw/dist/core/routes/test-loop-routes.d.ts.map +1 -0
- package/ccw/dist/core/routes/test-loop-routes.js +298 -0
- package/ccw/dist/core/routes/test-loop-routes.js.map +1 -0
- package/ccw/dist/core/server.d.ts.map +1 -1
- package/ccw/dist/core/server.js +47 -5
- package/ccw/dist/core/server.js.map +1 -1
- package/ccw/dist/core/websocket.d.ts +59 -0
- package/ccw/dist/core/websocket.d.ts.map +1 -1
- package/ccw/dist/core/websocket.js +34 -0
- package/ccw/dist/core/websocket.js.map +1 -1
- package/ccw/dist/tools/claude-cli-tools.d.ts +40 -0
- package/ccw/dist/tools/claude-cli-tools.d.ts.map +1 -1
- package/ccw/dist/tools/claude-cli-tools.js +119 -0
- package/ccw/dist/tools/claude-cli-tools.js.map +1 -1
- package/ccw/dist/tools/codex-lens-lsp.d.ts.map +1 -1
- package/ccw/dist/tools/codex-lens-lsp.js +2 -5
- package/ccw/dist/tools/codex-lens-lsp.js.map +1 -1
- package/ccw/dist/tools/codex-lens.d.ts.map +1 -1
- package/ccw/dist/tools/codex-lens.js +22 -32
- package/ccw/dist/tools/codex-lens.js.map +1 -1
- package/ccw/dist/tools/litellm-client.d.ts +6 -0
- package/ccw/dist/tools/litellm-client.d.ts.map +1 -1
- package/ccw/dist/tools/litellm-client.js +15 -2
- package/ccw/dist/tools/litellm-client.js.map +1 -1
- package/ccw/dist/tools/loop-manager.d.ts +84 -0
- package/ccw/dist/tools/loop-manager.d.ts.map +1 -0
- package/ccw/dist/tools/loop-manager.js +425 -0
- package/ccw/dist/tools/loop-manager.js.map +1 -0
- package/ccw/dist/tools/loop-state-manager.d.ts +47 -0
- package/ccw/dist/tools/loop-state-manager.d.ts.map +1 -0
- package/ccw/dist/tools/loop-state-manager.js +149 -0
- package/ccw/dist/tools/loop-state-manager.js.map +1 -0
- package/ccw/dist/tools/loop-task-manager.d.ts +149 -0
- package/ccw/dist/tools/loop-task-manager.d.ts.map +1 -0
- package/ccw/dist/tools/loop-task-manager.js +270 -0
- package/ccw/dist/tools/loop-task-manager.js.map +1 -0
- package/ccw/dist/tools/native-session-discovery.d.ts.map +1 -1
- package/ccw/dist/tools/native-session-discovery.js +35 -7
- package/ccw/dist/tools/native-session-discovery.js.map +1 -1
- package/ccw/dist/types/index.d.ts +1 -0
- package/ccw/dist/types/index.d.ts.map +1 -1
- package/ccw/dist/types/index.js +1 -0
- package/ccw/dist/types/index.js.map +1 -1
- package/ccw/dist/types/loop.d.ts +257 -0
- package/ccw/dist/types/loop.d.ts.map +1 -0
- package/ccw/dist/types/loop.js +17 -0
- package/ccw/dist/types/loop.js.map +1 -0
- package/ccw/dist/utils/codexlens-path.d.ts +36 -0
- package/ccw/dist/utils/codexlens-path.d.ts.map +1 -0
- package/ccw/dist/utils/codexlens-path.js +56 -0
- package/ccw/dist/utils/codexlens-path.js.map +1 -0
- package/ccw/dist/utils/uv-manager.d.ts.map +1 -1
- package/ccw/dist/utils/uv-manager.js +3 -2
- package/ccw/dist/utils/uv-manager.js.map +1 -1
- package/ccw/src/cli.ts +13 -1
- package/ccw/src/commands/cli.ts +14 -1
- package/ccw/src/commands/install.ts +50 -7
- package/ccw/src/commands/issue.ts +119 -0
- package/ccw/src/commands/loop.ts +344 -0
- package/ccw/src/commands/upgrade.ts +1 -1
- package/ccw/src/config/litellm-api-config-manager.ts +3 -2
- package/ccw/src/core/dashboard-generator.ts +4 -1
- package/ccw/src/core/memory-embedder-bridge.ts +2 -6
- package/ccw/src/core/routes/claude-routes.ts +5 -3
- package/ccw/src/core/routes/cli-routes.ts +48 -16
- package/ccw/src/core/routes/cli-settings-routes.ts +47 -0
- package/ccw/src/core/routes/codexlens/config-handlers.ts +7 -6
- package/ccw/src/core/routes/codexlens/semantic-handlers.ts +5 -4
- package/ccw/src/core/routes/core-memory-routes.ts +4 -2
- package/ccw/src/core/routes/files-routes.ts +4 -2
- package/ccw/src/core/routes/graph-routes.ts +18 -2
- package/ccw/src/core/routes/issue-routes.ts +308 -33
- package/ccw/src/core/routes/loop-routes.ts +386 -0
- package/ccw/src/core/routes/loop-v2-routes.ts +1470 -0
- package/ccw/src/core/routes/memory-routes.ts +2 -1
- package/ccw/src/core/routes/system-routes.ts +3 -2
- package/ccw/src/core/routes/task-routes.ts +361 -0
- package/ccw/src/core/routes/test-loop-routes.ts +312 -0
- package/ccw/src/core/server.ts +49 -5
- package/ccw/src/core/websocket.ts +104 -0
- package/ccw/src/templates/dashboard-css/02-session.css +2 -0
- package/ccw/src/templates/dashboard-css/04-lite-tasks.css +103 -1
- package/ccw/src/templates/dashboard-css/12-cli-legacy.css +56 -0
- package/ccw/src/templates/dashboard-css/32-issue-manager.css +32 -0
- package/ccw/src/templates/dashboard-css/33-cli-stream-viewer.css +55 -0
- package/ccw/src/templates/dashboard-css/36-loop-monitor.css +1896 -0
- package/ccw/src/templates/dashboard-css/36-loop-monitor.css.backup +1877 -0
- package/ccw/src/templates/dashboard-js/components/cli-history.js +48 -48
- package/ccw/src/templates/dashboard-js/components/cli-status.js +64 -3
- package/ccw/src/templates/dashboard-js/components/cli-stream-viewer.js +251 -110
- package/ccw/src/templates/dashboard-js/components/navigation.js +16 -0
- package/ccw/src/templates/dashboard-js/components/notifications.js +22 -0
- package/ccw/src/templates/dashboard-js/components/version-check.js +38 -0
- package/ccw/src/templates/dashboard-js/i18n.js +601 -1
- package/ccw/src/templates/dashboard-js/state.js +2 -0
- package/ccw/src/templates/dashboard-js/views/cli-manager.js +4 -3
- package/ccw/src/templates/dashboard-js/views/issue-manager.js +183 -1
- package/ccw/src/templates/dashboard-js/views/lite-tasks.js +55 -11
- package/ccw/src/templates/dashboard-js/views/loop-monitor.js +3345 -0
- package/ccw/src/templates/dashboard.html +68 -4
- package/ccw/src/tools/claude-cli-tools.ts +143 -0
- package/ccw/src/tools/codex-lens-lsp.ts +2 -5
- package/ccw/src/tools/codex-lens.ts +27 -38
- package/ccw/src/tools/litellm-client.ts +16 -2
- package/ccw/src/tools/loop-manager.ts +519 -0
- package/ccw/src/tools/loop-state-manager.ts +173 -0
- package/ccw/src/tools/loop-task-manager.ts +391 -0
- package/ccw/src/tools/native-session-discovery.ts +38 -7
- package/ccw/src/types/index.ts +1 -0
- package/ccw/src/types/loop.ts +316 -0
- package/ccw/src/utils/codexlens-path.ts +60 -0
- package/ccw/src/utils/uv-manager.ts +3 -2
- package/package.json +1 -1
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# Action: Menu
|
|
2
|
+
|
|
3
|
+
显示交互式操作菜单,让用户选择下一步操作。
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
- 显示当前状态摘要
|
|
8
|
+
- 提供操作选项
|
|
9
|
+
- 接收用户选择
|
|
10
|
+
- 返回下一个动作
|
|
11
|
+
|
|
12
|
+
## Preconditions
|
|
13
|
+
|
|
14
|
+
- [ ] state.initialized === true
|
|
15
|
+
- [ ] state.status === 'running'
|
|
16
|
+
|
|
17
|
+
## Execution
|
|
18
|
+
|
|
19
|
+
### Step 1: 生成状态摘要
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()
|
|
23
|
+
|
|
24
|
+
// 开发进度
|
|
25
|
+
const developProgress = state.develop.total_count > 0
|
|
26
|
+
? `${state.develop.completed_count}/${state.develop.total_count} (${(state.develop.completed_count / state.develop.total_count * 100).toFixed(0)}%)`
|
|
27
|
+
: '未开始'
|
|
28
|
+
|
|
29
|
+
// 调试状态
|
|
30
|
+
const debugStatus = state.debug.confirmed_hypothesis
|
|
31
|
+
? `✅ 已确认根因`
|
|
32
|
+
: state.debug.iteration > 0
|
|
33
|
+
? `🔍 迭代 ${state.debug.iteration}`
|
|
34
|
+
: '未开始'
|
|
35
|
+
|
|
36
|
+
// 验证状态
|
|
37
|
+
const validateStatus = state.validate.passed
|
|
38
|
+
? `✅ 通过`
|
|
39
|
+
: state.validate.test_results.length > 0
|
|
40
|
+
? `❌ ${state.validate.failed_tests.length} 个失败`
|
|
41
|
+
: '未运行'
|
|
42
|
+
|
|
43
|
+
const statusSummary = `
|
|
44
|
+
═══════════════════════════════════════════════════════════
|
|
45
|
+
CCW Loop - ${state.session_id}
|
|
46
|
+
═══════════════════════════════════════════════════════════
|
|
47
|
+
|
|
48
|
+
任务: ${state.task_description}
|
|
49
|
+
迭代: ${state.iteration_count}
|
|
50
|
+
|
|
51
|
+
┌─────────────────────────────────────────────────────┐
|
|
52
|
+
│ 开发 (Develop) │ ${developProgress.padEnd(20)} │
|
|
53
|
+
│ 调试 (Debug) │ ${debugStatus.padEnd(20)} │
|
|
54
|
+
│ 验证 (Validate) │ ${validateStatus.padEnd(20)} │
|
|
55
|
+
└─────────────────────────────────────────────────────┘
|
|
56
|
+
|
|
57
|
+
═══════════════════════════════════════════════════════════
|
|
58
|
+
`
|
|
59
|
+
|
|
60
|
+
console.log(statusSummary)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Step 2: 显示操作选项
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
const options = [
|
|
67
|
+
{
|
|
68
|
+
label: "📝 继续开发 (Develop)",
|
|
69
|
+
description: state.develop.completed_count < state.develop.total_count
|
|
70
|
+
? `执行下一个开发任务`
|
|
71
|
+
: "所有任务已完成,可添加新任务",
|
|
72
|
+
action: "action-develop-with-file"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
label: "🔍 开始调试 (Debug)",
|
|
76
|
+
description: state.debug.iteration > 0
|
|
77
|
+
? "继续假设驱动调试"
|
|
78
|
+
: "开始新的调试会话",
|
|
79
|
+
action: "action-debug-with-file"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
label: "✅ 运行验证 (Validate)",
|
|
83
|
+
description: "运行测试并检查覆盖率",
|
|
84
|
+
action: "action-validate-with-file"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
label: "📊 查看详情 (Status)",
|
|
88
|
+
description: "查看详细进度和文件",
|
|
89
|
+
action: "action-status"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
label: "🏁 完成循环 (Complete)",
|
|
93
|
+
description: "结束当前循环",
|
|
94
|
+
action: "action-complete"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
label: "🚪 退出 (Exit)",
|
|
98
|
+
description: "保存状态并退出",
|
|
99
|
+
action: "exit"
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
|
|
103
|
+
const response = await AskUserQuestion({
|
|
104
|
+
questions: [{
|
|
105
|
+
question: "选择下一步操作:",
|
|
106
|
+
header: "操作",
|
|
107
|
+
multiSelect: false,
|
|
108
|
+
options: options.map(o => ({
|
|
109
|
+
label: o.label,
|
|
110
|
+
description: o.description
|
|
111
|
+
}))
|
|
112
|
+
}]
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
const selectedLabel = response["操作"]
|
|
116
|
+
const selectedOption = options.find(o => o.label === selectedLabel)
|
|
117
|
+
const nextAction = selectedOption?.action || 'action-menu'
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Step 3: 处理特殊选项
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
if (nextAction === 'exit') {
|
|
124
|
+
console.log('\n保存状态并退出...')
|
|
125
|
+
return {
|
|
126
|
+
stateUpdates: {
|
|
127
|
+
status: 'user_exit'
|
|
128
|
+
},
|
|
129
|
+
continue: false,
|
|
130
|
+
message: '会话已保存,使用 --resume 可继续'
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (nextAction === 'action-status') {
|
|
135
|
+
// 显示详细状态
|
|
136
|
+
const sessionFolder = `.workflow/.loop/${state.session_id}`
|
|
137
|
+
|
|
138
|
+
console.log('\n=== 开发进度 ===')
|
|
139
|
+
const progress = Read(`${sessionFolder}/develop/progress.md`)
|
|
140
|
+
console.log(progress?.substring(0, 500) + '...')
|
|
141
|
+
|
|
142
|
+
console.log('\n=== 调试状态 ===')
|
|
143
|
+
if (state.debug.hypotheses.length > 0) {
|
|
144
|
+
state.debug.hypotheses.forEach(h => {
|
|
145
|
+
console.log(` ${h.id}: ${h.status} - ${h.description.substring(0, 50)}...`)
|
|
146
|
+
})
|
|
147
|
+
} else {
|
|
148
|
+
console.log(' 尚未开始调试')
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
console.log('\n=== 验证结果 ===')
|
|
152
|
+
if (state.validate.test_results.length > 0) {
|
|
153
|
+
const latest = state.validate.test_results[state.validate.test_results.length - 1]
|
|
154
|
+
console.log(` 最近运行: ${latest.timestamp}`)
|
|
155
|
+
console.log(` 通过率: ${latest.summary.pass_rate}%`)
|
|
156
|
+
} else {
|
|
157
|
+
console.log(' 尚未运行验证')
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// 返回菜单
|
|
161
|
+
return {
|
|
162
|
+
stateUpdates: {},
|
|
163
|
+
continue: true,
|
|
164
|
+
nextAction: 'action-menu',
|
|
165
|
+
message: ''
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## State Updates
|
|
171
|
+
|
|
172
|
+
```javascript
|
|
173
|
+
return {
|
|
174
|
+
stateUpdates: {
|
|
175
|
+
// 不更新状态,仅返回下一个动作
|
|
176
|
+
},
|
|
177
|
+
continue: true,
|
|
178
|
+
nextAction: nextAction,
|
|
179
|
+
message: `执行: ${selectedOption?.label || nextAction}`
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Error Handling
|
|
184
|
+
|
|
185
|
+
| Error Type | Recovery |
|
|
186
|
+
|------------|----------|
|
|
187
|
+
| 用户取消 | 返回菜单 |
|
|
188
|
+
| 无效选择 | 重新显示菜单 |
|
|
189
|
+
|
|
190
|
+
## Next Actions
|
|
191
|
+
|
|
192
|
+
根据用户选择动态决定下一个动作。
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
# Action: Validate With File
|
|
2
|
+
|
|
3
|
+
运行测试并验证实现,记录结果到 validation.md,支持 Gemini 辅助分析测试覆盖率和质量。
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
执行测试验证流程,包括:
|
|
8
|
+
- 运行单元测试
|
|
9
|
+
- 运行集成测试
|
|
10
|
+
- 检查代码覆盖率
|
|
11
|
+
- 生成验证报告
|
|
12
|
+
- 分析失败原因
|
|
13
|
+
|
|
14
|
+
## Preconditions
|
|
15
|
+
|
|
16
|
+
- [ ] state.initialized === true
|
|
17
|
+
- [ ] state.status === 'running'
|
|
18
|
+
- [ ] state.develop.completed_count > 0 || state.debug.confirmed_hypothesis !== null
|
|
19
|
+
|
|
20
|
+
## Session Setup
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()
|
|
24
|
+
|
|
25
|
+
const sessionFolder = `.workflow/.loop/${state.session_id}`
|
|
26
|
+
const validateFolder = `${sessionFolder}/validate`
|
|
27
|
+
const validationPath = `${validateFolder}/validation.md`
|
|
28
|
+
const testResultsPath = `${validateFolder}/test-results.json`
|
|
29
|
+
const coveragePath = `${validateFolder}/coverage.json`
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Execution
|
|
35
|
+
|
|
36
|
+
### Step 1: 运行测试
|
|
37
|
+
|
|
38
|
+
```javascript
|
|
39
|
+
console.log('\n运行测试...')
|
|
40
|
+
|
|
41
|
+
// 检测测试框架
|
|
42
|
+
const packageJson = JSON.parse(Read('package.json'))
|
|
43
|
+
const testScript = packageJson.scripts?.test || 'npm test'
|
|
44
|
+
|
|
45
|
+
// 运行测试并捕获输出
|
|
46
|
+
const testResult = await Bash({
|
|
47
|
+
command: testScript,
|
|
48
|
+
timeout: 300000 // 5分钟
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
// 解析测试输出
|
|
52
|
+
const testResults = parseTestOutput(testResult.stdout)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Step 2: 检查覆盖率
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
// 运行覆盖率检查
|
|
59
|
+
let coverageData = null
|
|
60
|
+
|
|
61
|
+
if (packageJson.scripts?.['test:coverage']) {
|
|
62
|
+
const coverageResult = await Bash({
|
|
63
|
+
command: 'npm run test:coverage',
|
|
64
|
+
timeout: 300000
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
// 解析覆盖率报告
|
|
68
|
+
coverageData = parseCoverageReport(coverageResult.stdout)
|
|
69
|
+
|
|
70
|
+
Write(coveragePath, JSON.stringify(coverageData, null, 2))
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Step 3: Gemini 辅助分析
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
ccw cli -p "
|
|
78
|
+
PURPOSE: Analyze test results and coverage
|
|
79
|
+
Success criteria: Identify quality issues and suggest improvements
|
|
80
|
+
|
|
81
|
+
TASK:
|
|
82
|
+
• Analyze test execution results
|
|
83
|
+
• Review code coverage metrics
|
|
84
|
+
• Identify missing test cases
|
|
85
|
+
• Suggest quality improvements
|
|
86
|
+
• Verify requirements coverage
|
|
87
|
+
|
|
88
|
+
MODE: analysis
|
|
89
|
+
|
|
90
|
+
CONTEXT:
|
|
91
|
+
@${testResultsPath}
|
|
92
|
+
@${coveragePath}
|
|
93
|
+
@${sessionFolder}/develop/progress.md
|
|
94
|
+
|
|
95
|
+
EXPECTED:
|
|
96
|
+
- Quality assessment report
|
|
97
|
+
- Failed tests analysis
|
|
98
|
+
- Coverage gaps identification
|
|
99
|
+
- Improvement recommendations
|
|
100
|
+
- Pass/Fail decision with rationale
|
|
101
|
+
|
|
102
|
+
CONSTRAINTS: Evidence-based quality assessment
|
|
103
|
+
" --tool gemini --mode analysis --rule analysis-review-code-quality
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Step 4: 生成验证报告
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
const timestamp = getUtc8ISOString()
|
|
110
|
+
const iteration = (state.validate.test_results?.length || 0) + 1
|
|
111
|
+
|
|
112
|
+
const validationReport = `# Validation Report
|
|
113
|
+
|
|
114
|
+
**Session ID**: ${state.session_id}
|
|
115
|
+
**Task**: ${state.task_description}
|
|
116
|
+
**Validated**: ${timestamp}
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Iteration ${iteration} - Validation Run
|
|
121
|
+
|
|
122
|
+
### Test Execution Summary
|
|
123
|
+
|
|
124
|
+
| Metric | Value |
|
|
125
|
+
|--------|-------|
|
|
126
|
+
| Total Tests | ${testResults.total} |
|
|
127
|
+
| Passed | ${testResults.passed} |
|
|
128
|
+
| Failed | ${testResults.failed} |
|
|
129
|
+
| Skipped | ${testResults.skipped} |
|
|
130
|
+
| Duration | ${testResults.duration_ms}ms |
|
|
131
|
+
| **Pass Rate** | **${(testResults.passed / testResults.total * 100).toFixed(1)}%** |
|
|
132
|
+
|
|
133
|
+
### Coverage Report
|
|
134
|
+
|
|
135
|
+
${coverageData ? `
|
|
136
|
+
| File | Statements | Branches | Functions | Lines |
|
|
137
|
+
|------|------------|----------|-----------|-------|
|
|
138
|
+
${coverageData.files.map(f => `| ${f.path} | ${f.statements}% | ${f.branches}% | ${f.functions}% | ${f.lines}% |`).join('\n')}
|
|
139
|
+
|
|
140
|
+
**Overall Coverage**: ${coverageData.overall.statements}%
|
|
141
|
+
` : '_No coverage data available_'}
|
|
142
|
+
|
|
143
|
+
### Failed Tests
|
|
144
|
+
|
|
145
|
+
${testResults.failed > 0 ? `
|
|
146
|
+
${testResults.failures.map(f => `
|
|
147
|
+
#### ${f.test_name}
|
|
148
|
+
|
|
149
|
+
- **Suite**: ${f.suite}
|
|
150
|
+
- **Error**: ${f.error_message}
|
|
151
|
+
- **Stack**:
|
|
152
|
+
\`\`\`
|
|
153
|
+
${f.stack_trace}
|
|
154
|
+
\`\`\`
|
|
155
|
+
`).join('\n')}
|
|
156
|
+
` : '_All tests passed_'}
|
|
157
|
+
|
|
158
|
+
### Gemini Quality Analysis
|
|
159
|
+
|
|
160
|
+
${geminiAnalysis}
|
|
161
|
+
|
|
162
|
+
### Recommendations
|
|
163
|
+
|
|
164
|
+
${recommendations.map(r => `- ${r}`).join('\n')}
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Validation Decision
|
|
169
|
+
|
|
170
|
+
**Result**: ${testResults.passed === testResults.total ? '✅ PASS' : '❌ FAIL'}
|
|
171
|
+
|
|
172
|
+
**Rationale**: ${validationDecision}
|
|
173
|
+
|
|
174
|
+
${testResults.passed !== testResults.total ? `
|
|
175
|
+
### Next Actions
|
|
176
|
+
|
|
177
|
+
1. Review failed tests
|
|
178
|
+
2. Debug failures using action-debug-with-file
|
|
179
|
+
3. Fix issues and re-run validation
|
|
180
|
+
` : `
|
|
181
|
+
### Next Actions
|
|
182
|
+
|
|
183
|
+
1. Consider code review
|
|
184
|
+
2. Prepare for deployment
|
|
185
|
+
3. Update documentation
|
|
186
|
+
`}
|
|
187
|
+
`
|
|
188
|
+
|
|
189
|
+
// 写入验证报告
|
|
190
|
+
Write(validationPath, validationReport)
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Step 5: 保存测试结果
|
|
194
|
+
|
|
195
|
+
```javascript
|
|
196
|
+
const testResultsData = {
|
|
197
|
+
iteration,
|
|
198
|
+
timestamp,
|
|
199
|
+
summary: {
|
|
200
|
+
total: testResults.total,
|
|
201
|
+
passed: testResults.passed,
|
|
202
|
+
failed: testResults.failed,
|
|
203
|
+
skipped: testResults.skipped,
|
|
204
|
+
pass_rate: (testResults.passed / testResults.total * 100).toFixed(1),
|
|
205
|
+
duration_ms: testResults.duration_ms
|
|
206
|
+
},
|
|
207
|
+
tests: testResults.tests,
|
|
208
|
+
failures: testResults.failures,
|
|
209
|
+
coverage: coverageData?.overall || null
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
Write(testResultsPath, JSON.stringify(testResultsData, null, 2))
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## State Updates
|
|
218
|
+
|
|
219
|
+
```javascript
|
|
220
|
+
const validationPassed = testResults.failed === 0 && testResults.passed > 0
|
|
221
|
+
|
|
222
|
+
return {
|
|
223
|
+
stateUpdates: {
|
|
224
|
+
validate: {
|
|
225
|
+
test_results: [...(state.validate.test_results || []), testResultsData],
|
|
226
|
+
coverage: coverageData?.overall.statements || null,
|
|
227
|
+
passed: validationPassed,
|
|
228
|
+
failed_tests: testResults.failures.map(f => f.test_name),
|
|
229
|
+
last_run_at: getUtc8ISOString()
|
|
230
|
+
},
|
|
231
|
+
last_action: 'action-validate-with-file'
|
|
232
|
+
},
|
|
233
|
+
continue: true,
|
|
234
|
+
message: validationPassed
|
|
235
|
+
? `验证通过 ✅\n测试: ${testResults.passed}/${testResults.total}\n覆盖率: ${coverageData?.overall.statements || 'N/A'}%`
|
|
236
|
+
: `验证失败 ❌\n失败: ${testResults.failed}/${testResults.total}\n建议进入调试模式`
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Test Output Parsers
|
|
241
|
+
|
|
242
|
+
### Jest/Vitest Parser
|
|
243
|
+
|
|
244
|
+
```javascript
|
|
245
|
+
function parseJestOutput(stdout) {
|
|
246
|
+
const testPattern = /Tests:\s+(\d+) passed.*?(\d+) failed.*?(\d+) total/
|
|
247
|
+
const match = stdout.match(testPattern)
|
|
248
|
+
|
|
249
|
+
return {
|
|
250
|
+
total: parseInt(match[3]),
|
|
251
|
+
passed: parseInt(match[1]),
|
|
252
|
+
failed: parseInt(match[2]),
|
|
253
|
+
// ... parse individual test results
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Pytest Parser
|
|
259
|
+
|
|
260
|
+
```javascript
|
|
261
|
+
function parsePytestOutput(stdout) {
|
|
262
|
+
const summaryPattern = /(\d+) passed.*?(\d+) failed.*?(\d+) error/
|
|
263
|
+
// ... implementation
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Error Handling
|
|
268
|
+
|
|
269
|
+
| Error Type | Recovery |
|
|
270
|
+
|------------|----------|
|
|
271
|
+
| Tests don't run | 检查测试脚本配置,提示用户 |
|
|
272
|
+
| All tests fail | 建议进入 debug 模式 |
|
|
273
|
+
| Coverage tool missing | 跳过覆盖率检查,仅运行测试 |
|
|
274
|
+
| Timeout | 增加超时时间或拆分测试 |
|
|
275
|
+
|
|
276
|
+
## Validation Report Template
|
|
277
|
+
|
|
278
|
+
参考 [templates/validation-template.md](../../templates/validation-template.md)
|
|
279
|
+
|
|
280
|
+
## CLI Integration
|
|
281
|
+
|
|
282
|
+
### 质量分析
|
|
283
|
+
```bash
|
|
284
|
+
ccw cli -p "PURPOSE: Analyze test results and coverage...
|
|
285
|
+
TASK: • Review results • Identify gaps • Suggest improvements
|
|
286
|
+
MODE: analysis
|
|
287
|
+
CONTEXT: @test-results.json @coverage.json
|
|
288
|
+
EXPECTED: Quality assessment
|
|
289
|
+
" --tool gemini --mode analysis --rule analysis-review-code-quality
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### 测试生成 (如覆盖率低)
|
|
293
|
+
```bash
|
|
294
|
+
ccw cli -p "PURPOSE: Generate missing test cases...
|
|
295
|
+
TASK: • Analyze uncovered code • Write tests
|
|
296
|
+
MODE: write
|
|
297
|
+
CONTEXT: @coverage.json @src/**/*
|
|
298
|
+
EXPECTED: Test code
|
|
299
|
+
" --tool gemini --mode write --rule development-generate-tests
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## Next Actions (Hints)
|
|
303
|
+
|
|
304
|
+
- 验证通过: `action-complete` (完成循环)
|
|
305
|
+
- 验证失败: `action-debug-with-file` (调试失败测试)
|
|
306
|
+
- 覆盖率低: `action-develop-with-file` (添加测试)
|
|
307
|
+
- 用户选择: `action-menu` (返回菜单)
|