mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-11 02:33:51 +08:00
According to OpenAI Codex skill specification, SKILL.md files must have both 'name' and 'description' fields in YAML frontmatter. Added missing 'name' field to all three skills: - CCW Loop - CCW Loop-B - Parallel Dev Cycle Also enhanced ccw-loop description with Chinese trigger keywords for better multi-language support.
351 lines
12 KiB
Markdown
351 lines
12 KiB
Markdown
---
|
||
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", "开发循环", "迭代开发".
|
||
argument-hint: TASK="<task description>" [--loop-id=<id>] [--auto]
|
||
---
|
||
|
||
# CCW Loop - Codex Stateless Iterative Development Workflow
|
||
|
||
Stateless iterative development loop using Codex subagent pattern. Supports develop, debug, and validate phases with file-based state tracking.
|
||
|
||
## 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 (Codex Subagent Pattern)
|
||
|
||
```
|
||
+-------------------------------------------------------------+
|
||
| Dashboard (UI) |
|
||
| [Create] [Start] [Pause] [Resume] [Stop] [View Progress] |
|
||
+-------------------------------------------------------------+
|
||
|
|
||
v
|
||
+-------------------------------------------------------------+
|
||
| loop-v2-routes.ts (Control Plane) |
|
||
| |
|
||
| State: .workflow/.loop/{loopId}.json (MASTER) |
|
||
| Tasks: .workflow/.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) |
|
||
+-------------------------------------------------------------+
|
||
|
|
||
v
|
||
+-------------------------------------------------------------+
|
||
| ccw-loop Skill (Execution Plane) |
|
||
| |
|
||
| Codex Pattern: spawn_agent -> wait -> send_input -> close |
|
||
| |
|
||
| Reads/Writes: .workflow/.loop/{loopId}.json (unified state) |
|
||
| Writes: .workflow/.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 (Codex Adaptation)
|
||
|
||
1. **Unified State**: API and Skill share `.workflow/.loop/{loopId}.json` state file
|
||
2. **Control Signals**: Skill checks status field before each action (paused/stopped)
|
||
3. **File-Driven**: All progress documented in `.workflow/.loop/{loopId}.progress/`
|
||
4. **Resumable**: Continue any loop with `--loop-id`
|
||
5. **Dual Trigger**: Supports API trigger (`--loop-id`) and direct call (task description)
|
||
6. **Single Agent Deep Interaction**: Use send_input for multi-phase execution instead of multiple agents
|
||
|
||
## Subagent 机制
|
||
|
||
### 核心 API
|
||
|
||
| API | 作用 |
|
||
|-----|------|
|
||
| `spawn_agent({ message })` | 创建 subagent,返回 `agent_id` |
|
||
| `wait({ ids, timeout_ms })` | 等待结果(唯一取结果入口) |
|
||
| `send_input({ id, message })` | 继续交互/追问 |
|
||
| `close_agent({ id })` | 关闭回收(不可逆) |
|
||
|
||
### 可用模式
|
||
|
||
- **单 Agent 深度交互**: 一个 agent 多阶段,`send_input` 继续
|
||
- **多 Agent 并行**: 主协调器 + 多 worker,`wait({ ids: [...] })` 批量等待
|
||
- **混合模式**: 按需组合
|
||
|
||
## Execution Modes
|
||
|
||
### Mode 1: Interactive
|
||
|
||
User manually selects each action, suitable for complex tasks.
|
||
|
||
```
|
||
User -> Select action -> Execute -> View results -> Select next action
|
||
```
|
||
|
||
### Mode 2: Auto-Loop
|
||
|
||
Automatic execution in preset order, suitable for standard development flow.
|
||
|
||
```
|
||
Develop -> Debug -> Validate -> (if issues) -> Develop -> ...
|
||
```
|
||
|
||
## Session Structure (Unified Location)
|
||
|
||
```
|
||
.workflow/.loop/
|
||
+-- {loopId}.json # Master state file (API + Skill shared)
|
||
+-- {loopId}.tasks.jsonl # Task list (API managed)
|
||
+-- {loopId}.progress/ # Skill progress files
|
||
+-- develop.md # Development progress timeline
|
||
+-- debug.md # Understanding evolution document
|
||
+-- validate.md # Validation report
|
||
+-- changes.log # Code changes log (NDJSON)
|
||
+-- debug.log # Debug log (NDJSON)
|
||
```
|
||
|
||
## Implementation (Codex Subagent Pattern)
|
||
|
||
### Session Setup
|
||
|
||
```javascript
|
||
// Helper: Get UTC+8 (China Standard Time) ISO string
|
||
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()
|
||
|
||
// loopId source:
|
||
// 1. API trigger: from --loop-id parameter
|
||
// 2. Direct call: generate new loop-v2-{timestamp}-{random}
|
||
|
||
const loopId = args['--loop-id'] || (() => {
|
||
const timestamp = getUtc8ISOString().replace(/[-:]/g, '').split('.')[0]
|
||
const random = Math.random().toString(36).substring(2, 10)
|
||
return `loop-v2-${timestamp}-${random}`
|
||
})()
|
||
|
||
const loopFile = `.workflow/.loop/${loopId}.json`
|
||
const progressDir = `.workflow/.loop/${loopId}.progress`
|
||
|
||
// Create progress directory
|
||
mkdir -p "${progressDir}"
|
||
```
|
||
|
||
### Main Execution Flow (Single Agent Deep Interaction)
|
||
|
||
```javascript
|
||
// ==================== CODEX CCW-LOOP: SINGLE AGENT ORCHESTRATOR ====================
|
||
|
||
// Step 1: Read or create initial state
|
||
let state = null
|
||
if (existingLoopId) {
|
||
state = JSON.parse(Read(`.workflow/.loop/${loopId}.json`))
|
||
if (!state) {
|
||
console.error(`Loop not found: ${loopId}`)
|
||
return
|
||
}
|
||
} else {
|
||
state = createInitialState(loopId, taskDescription)
|
||
Write(`.workflow/.loop/${loopId}.json`, JSON.stringify(state, null, 2))
|
||
}
|
||
|
||
// Step 2: Create orchestrator agent (single agent handles all phases)
|
||
const agent = spawn_agent({
|
||
message: `
|
||
## TASK ASSIGNMENT
|
||
|
||
### MANDATORY FIRST STEPS (Agent Execute)
|
||
1. **Read role definition**: ~/.codex/agents/ccw-loop-executor.md (MUST read first)
|
||
2. Read: .workflow/project-tech.json
|
||
3. Read: .workflow/project-guidelines.json
|
||
|
||
---
|
||
|
||
## LOOP CONTEXT
|
||
|
||
- **Loop ID**: ${loopId}
|
||
- **State File**: .workflow/.loop/${loopId}.json
|
||
- **Progress Dir**: ${progressDir}
|
||
- **Mode**: ${mode} // 'interactive' or 'auto'
|
||
|
||
## CURRENT STATE
|
||
|
||
${JSON.stringify(state, null, 2)}
|
||
|
||
## TASK DESCRIPTION
|
||
|
||
${taskDescription}
|
||
|
||
## EXECUTION INSTRUCTIONS
|
||
|
||
You are executing CCW Loop orchestrator. Your job:
|
||
|
||
1. **Check Control Signals**
|
||
- Read .workflow/.loop/${loopId}.json
|
||
- If status === 'paused' -> Output "PAUSED" and stop
|
||
- If status === 'failed' -> Output "STOPPED" and stop
|
||
- If status === 'running' -> Continue
|
||
|
||
2. **Select Next Action**
|
||
Based on skill_state:
|
||
- If not initialized -> Execute INIT
|
||
- If mode === 'interactive' -> Output MENU and wait for input
|
||
- If mode === 'auto' -> Auto-select based on state
|
||
|
||
3. **Execute Action**
|
||
- Follow action instructions from ~/.codex/skills/ccw-loop/phases/actions/
|
||
- Update progress files in ${progressDir}/
|
||
- Update state in .workflow/.loop/${loopId}.json
|
||
|
||
4. **Output Format**
|
||
\`\`\`
|
||
ACTION_RESULT:
|
||
- action: {action_name}
|
||
- status: success | failed | needs_input
|
||
- message: {user message}
|
||
- state_updates: {JSON of skill_state updates}
|
||
|
||
NEXT_ACTION_NEEDED: {action_name} | WAITING_INPUT | COMPLETED | PAUSED
|
||
\`\`\`
|
||
|
||
## FIRST ACTION
|
||
|
||
${!state.skill_state ? 'Execute: INIT' : mode === 'auto' ? 'Auto-select next action' : 'Show MENU'}
|
||
`
|
||
})
|
||
|
||
// Step 3: Main orchestration loop
|
||
let iteration = 0
|
||
const maxIterations = state.max_iterations || 10
|
||
|
||
while (iteration < maxIterations) {
|
||
iteration++
|
||
|
||
// Wait for agent output
|
||
const result = wait({ ids: [agent], timeout_ms: 600000 })
|
||
const output = result.status[agent].completed
|
||
|
||
// Parse action result
|
||
const actionResult = parseActionResult(output)
|
||
|
||
// Handle different outcomes
|
||
switch (actionResult.next_action) {
|
||
case 'COMPLETED':
|
||
case 'PAUSED':
|
||
case 'STOPPED':
|
||
close_agent({ id: agent })
|
||
return actionResult
|
||
|
||
case 'WAITING_INPUT':
|
||
// Interactive mode: display menu, get user choice
|
||
const userChoice = await displayMenuAndGetChoice(actionResult)
|
||
|
||
// Send user choice back to agent
|
||
send_input({
|
||
id: agent,
|
||
message: `
|
||
## USER INPUT RECEIVED
|
||
|
||
Action selected: ${userChoice.action}
|
||
${userChoice.data ? `Additional data: ${JSON.stringify(userChoice.data)}` : ''}
|
||
|
||
## EXECUTE SELECTED ACTION
|
||
|
||
Follow instructions for: ${userChoice.action}
|
||
Update state and progress files accordingly.
|
||
`
|
||
})
|
||
break
|
||
|
||
default:
|
||
// Auto mode: agent continues to next action
|
||
// Check if we need to prompt for continuation
|
||
if (actionResult.next_action && actionResult.next_action !== 'NONE') {
|
||
send_input({
|
||
id: agent,
|
||
message: `
|
||
## CONTINUE EXECUTION
|
||
|
||
Previous action completed: ${actionResult.action}
|
||
Result: ${actionResult.status}
|
||
|
||
## EXECUTE NEXT ACTION
|
||
|
||
Continue with: ${actionResult.next_action}
|
||
`
|
||
})
|
||
}
|
||
}
|
||
|
||
// Update iteration count in state
|
||
const currentState = JSON.parse(Read(`.workflow/.loop/${loopId}.json`))
|
||
currentState.current_iteration = iteration
|
||
currentState.updated_at = getUtc8ISOString()
|
||
Write(`.workflow/.loop/${loopId}.json`, JSON.stringify(currentState, null, 2))
|
||
}
|
||
|
||
// Step 4: Cleanup
|
||
close_agent({ id: agent })
|
||
```
|
||
|
||
## Action Catalog
|
||
|
||
| Action | Purpose | Output Files | Trigger |
|
||
|--------|---------|--------------|---------|
|
||
| [action-init](phases/actions/action-init.md) | Initialize loop session | meta.json, state.json | First run |
|
||
| [action-develop](phases/actions/action-develop.md) | Execute development task | progress.md, tasks.json | Has pending tasks |
|
||
| [action-debug](phases/actions/action-debug.md) | Hypothesis-driven debug | understanding.md, hypotheses.json | Needs debugging |
|
||
| [action-validate](phases/actions/action-validate.md) | Test and validate | validation.md, test-results.json | Needs validation |
|
||
| [action-complete](phases/actions/action-complete.md) | Complete loop | summary.md | All done |
|
||
| [action-menu](phases/actions/action-menu.md) | Display action menu | - | Interactive mode |
|
||
|
||
## Usage
|
||
|
||
```bash
|
||
# Start new loop (direct call)
|
||
/ccw-loop TASK="Implement user authentication"
|
||
|
||
# Continue existing loop (API trigger or manual resume)
|
||
/ccw-loop --loop-id=loop-v2-20260122-abc123
|
||
|
||
# Auto-cycle mode
|
||
/ccw-loop --auto TASK="Fix login bug and add tests"
|
||
|
||
# API triggered auto-cycle
|
||
/ccw-loop --loop-id=loop-v2-20260122-abc123 --auto
|
||
```
|
||
|
||
## Reference Documents
|
||
|
||
| Document | Purpose |
|
||
|----------|---------|
|
||
| [phases/orchestrator.md](phases/orchestrator.md) | Orchestrator: state reading + action selection |
|
||
| [phases/state-schema.md](phases/state-schema.md) | State structure definition |
|
||
| [specs/loop-requirements.md](specs/loop-requirements.md) | Loop requirements specification |
|
||
| [specs/action-catalog.md](specs/action-catalog.md) | Action catalog |
|
||
|
||
## Error Handling
|
||
|
||
| Situation | Action |
|
||
|-----------|--------|
|
||
| Session not found | Create new session |
|
||
| State file corrupted | Rebuild from file contents |
|
||
| Agent timeout | send_input to request convergence |
|
||
| Agent unexpectedly closed | Re-spawn, paste previous output |
|
||
| Tests fail | Loop back to develop/debug |
|
||
| >10 iterations | Warn user, suggest break |
|
||
|
||
## Codex Best Practices Applied
|
||
|
||
1. **Role Path Passing**: Agent reads role file itself (no content embedding)
|
||
2. **Single Agent Deep Interaction**: Use send_input for multi-phase instead of multiple agents
|
||
3. **Delayed close_agent**: Only close after confirming no more interaction needed
|
||
4. **Context Reuse**: Same agent maintains all exploration context automatically
|
||
5. **Explicit wait()**: Always use wait({ ids }) to get results, not close_agent
|