mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-12 02:37:45 +08:00
Add orchestration loop phase and workflow execution skill
- Implemented Phase 2: Orchestration Loop for CCW Loop, including executor agent spawning, main loop execution, and iteration management. - Introduced helper functions for action result parsing and user interaction. - Created new skill: workflow-execute, coordinating agent execution for workflow tasks with automatic session discovery, parallel task processing, and status tracking. - Defined execution flow, key design principles, and error handling strategies for the workflow execution process.
This commit is contained in:
@@ -1,309 +1,436 @@
|
||||
---
|
||||
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]
|
||||
name: ccw-loop
|
||||
description: Stateless iterative development loop with single-agent deep interaction. Supports develop, debug, validate phases with file-based state tracking. Triggers on "ccw-loop", "dev loop", "development loop", "开发循环", "迭代开发".
|
||||
allowed-tools: Task, AskUserQuestion, TodoWrite, Read, Write, Edit, Bash, Glob, Grep
|
||||
---
|
||||
|
||||
# CCW Loop - Codex Stateless Iterative Development Workflow
|
||||
# CCW Loop - Stateless Iterative Development Workflow
|
||||
|
||||
Stateless iterative development loop using Codex subagent pattern. Supports develop, debug, and validate phases with file-based state tracking.
|
||||
Stateless iterative development loop using Codex single-agent deep interaction pattern. One agent handles all phases (develop → debug → validate → complete) via `send_input`, with file-based state tracking and Dashboard integration.
|
||||
|
||||
## 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)
|
||||
## Architecture Overview
|
||||
|
||||
```
|
||||
+-------------------------------------------------------------+
|
||||
| Dashboard (UI) |
|
||||
| [Create] [Start] [Pause] [Resume] [Stop] [View Progress] |
|
||||
| [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 |
|
||||
| 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) |
|
||||
| /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 |
|
||||
| Single Agent Deep Interaction: |
|
||||
| spawn_agent -> wait -> send_input -> ... -> close_agent |
|
||||
| |
|
||||
| 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 |
|
||||
| Actions: INIT -> DEVELOP -> DEBUG -> VALIDATE -> COMPLETE |
|
||||
+-------------------------------------------------------------+
|
||||
```
|
||||
|
||||
## Key Design Principles (Codex Adaptation)
|
||||
## Key Design Principles
|
||||
|
||||
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
|
||||
1. **Single Agent Deep Interaction**: One agent handles entire loop lifecycle via `send_input` (no multi-agent overhead)
|
||||
2. **Unified State**: API and Skill share `.workflow/.loop/{loopId}.json` state file
|
||||
3. **Control Signals**: Skill checks `status` field before each action (paused/stopped → graceful exit)
|
||||
4. **File-Driven Progress**: All progress documented in `.workflow/.loop/{loopId}.progress/`
|
||||
5. **Resumable**: Continue any loop with `--loop-id`
|
||||
6. **Dual Trigger**: Supports API trigger (`--loop-id`) and direct call (task description)
|
||||
|
||||
## Subagent 机制
|
||||
## Arguments
|
||||
|
||||
### 核心 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: [...] })` 批量等待
|
||||
- **混合模式**: 按需组合
|
||||
| Arg | Required | Description |
|
||||
|-----|----------|-------------|
|
||||
| TASK | One of TASK or --loop-id | Task description (for new loop) |
|
||||
| --loop-id | One of TASK or --loop-id | Existing loop ID to continue |
|
||||
| --auto | No | Auto-cycle mode (develop → debug → validate → complete) |
|
||||
|
||||
## Execution Modes
|
||||
|
||||
### Mode 1: Interactive
|
||||
|
||||
User manually selects each action, suitable for complex tasks.
|
||||
User manually selects each action via menu.
|
||||
|
||||
```
|
||||
User -> Select action -> Execute -> View results -> Select next action
|
||||
User -> MENU -> Select action -> Execute -> View results -> MENU -> ...
|
||||
```
|
||||
|
||||
### Mode 2: Auto-Loop
|
||||
|
||||
Automatic execution in preset order, suitable for standard development flow.
|
||||
Automatic execution using `selectNextAction` logic.
|
||||
|
||||
```
|
||||
Develop -> Debug -> Validate -> (if issues) -> Develop -> ...
|
||||
INIT -> DEVELOP -> ... -> VALIDATE -> (if fail) -> DEBUG -> VALIDATE -> COMPLETE
|
||||
```
|
||||
|
||||
## Session Structure (Unified Location)
|
||||
## Execution Flow
|
||||
|
||||
```
|
||||
Input Parsing:
|
||||
└─ Parse arguments (TASK | --loop-id + --auto)
|
||||
└─ Convert to structured context (loopId, state, progressDir)
|
||||
|
||||
Phase 1: Session Initialization
|
||||
└─ Ref: phases/01-session-init.md
|
||||
├─ Create new loop OR resume existing loop
|
||||
├─ Initialize state file and directory structure
|
||||
└─ Output: loopId, state, progressDir
|
||||
|
||||
Phase 2: Orchestration Loop
|
||||
└─ Ref: phases/02-orchestration-loop.md
|
||||
├─ Spawn single executor agent
|
||||
├─ Main while loop: wait → parse → dispatch → send_input
|
||||
├─ Handle: COMPLETED / PAUSED / STOPPED / WAITING_INPUT / next action
|
||||
├─ Update iteration count per cycle
|
||||
└─ close_agent on exit
|
||||
```
|
||||
|
||||
**Phase Reference Documents** (read on-demand when phase executes):
|
||||
|
||||
| Phase | Document | Purpose |
|
||||
|-------|----------|---------|
|
||||
| 1 | [phases/01-session-init.md](phases/01-session-init.md) | Argument parsing, state creation/resume, directory init |
|
||||
| 2 | [phases/02-orchestration-loop.md](phases/02-orchestration-loop.md) | Agent spawn, main loop, result parsing, send_input dispatch |
|
||||
|
||||
## Data Flow
|
||||
|
||||
```
|
||||
User Input (TASK | --loop-id + --auto)
|
||||
↓
|
||||
[Parse Arguments]
|
||||
↓ loopId, state, progressDir
|
||||
|
||||
Phase 1: Session Initialization
|
||||
↓ loopId, state (initialized/resumed), progressDir
|
||||
|
||||
Phase 2: Orchestration Loop
|
||||
↓ spawn agent → [INIT] → wait → parse
|
||||
↓
|
||||
┌─── Main Loop (while iteration < max) ──────────┐
|
||||
│ wait() → parseActionResult(output) │
|
||||
│ ├─ COMPLETED → close_agent, return │
|
||||
│ ├─ PAUSED → close_agent, return │
|
||||
│ ├─ STOPPED → close_agent, return │
|
||||
│ ├─ WAITING_INPUT → collect input → send_input │
|
||||
│ └─ next_action → send_input(continue) │
|
||||
│ Update iteration in state file │
|
||||
└──────────────────────────────────────────────────┘
|
||||
↓
|
||||
close_agent → return finalState
|
||||
```
|
||||
|
||||
## Session Structure
|
||||
|
||||
```
|
||||
.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)
|
||||
├── {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)
|
||||
├── hypotheses.json # Debug hypotheses tracking
|
||||
├── test-results.json # Test execution results
|
||||
├── coverage.json # Coverage data
|
||||
└── summary.md # Completion summary
|
||||
```
|
||||
|
||||
## Implementation (Codex Subagent Pattern)
|
||||
## State Management
|
||||
|
||||
### Session Setup
|
||||
Master state file: `.workflow/.loop/{loopId}.json`
|
||||
|
||||
```javascript
|
||||
// Helper: Get UTC+8 (China Standard Time) ISO string
|
||||
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()
|
||||
```json
|
||||
{
|
||||
"loop_id": "loop-v2-20260122T100000-abc123",
|
||||
"title": "Task title",
|
||||
"description": "Full task description",
|
||||
"max_iterations": 10,
|
||||
"status": "created | running | paused | completed | failed | user_exit",
|
||||
"current_iteration": 0,
|
||||
"created_at": "ISO8601",
|
||||
"updated_at": "ISO8601",
|
||||
"completed_at": "ISO8601 (optional)",
|
||||
"failure_reason": "string (optional)",
|
||||
|
||||
// loopId source:
|
||||
// 1. API trigger: from --loop-id parameter
|
||||
// 2. Direct call: generate new loop-v2-{timestamp}-{random}
|
||||
"skill_state": {
|
||||
"current_action": "init | develop | debug | validate | complete | null",
|
||||
"last_action": "string | null",
|
||||
"completed_actions": [],
|
||||
"mode": "interactive | auto",
|
||||
|
||||
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}`
|
||||
})()
|
||||
"develop": {
|
||||
"total": 0, "completed": 0, "current_task": null,
|
||||
"tasks": [{ "id": "task-001", "description": "...", "tool": "gemini", "mode": "write", "status": "pending", "files_changed": [], "created_at": "ISO8601", "completed_at": null }],
|
||||
"last_progress_at": null
|
||||
},
|
||||
|
||||
const loopFile = `.workflow/.loop/${loopId}.json`
|
||||
const progressDir = `.workflow/.loop/${loopId}.progress`
|
||||
"debug": {
|
||||
"active_bug": null, "hypotheses_count": 0,
|
||||
"hypotheses": [{ "id": "H1", "description": "...", "testable_condition": "...", "logging_point": "file:func:line", "evidence_criteria": { "confirm": "...", "reject": "..." }, "likelihood": 1, "status": "pending", "evidence": null, "verdict_reason": null }],
|
||||
"confirmed_hypothesis": null, "iteration": 0, "last_analysis_at": null
|
||||
},
|
||||
|
||||
// Create progress directory
|
||||
mkdir -p "${progressDir}"
|
||||
```
|
||||
"validate": {
|
||||
"pass_rate": 0, "coverage": 0,
|
||||
"test_results": [{ "test_name": "...", "suite": "...", "status": "passed | failed | skipped", "duration_ms": 0, "error_message": null, "stack_trace": null }],
|
||||
"passed": false, "failed_tests": [], "last_run_at": null
|
||||
},
|
||||
|
||||
### Main Execution Flow (Single Agent Deep Interaction)
|
||||
"errors": [{ "action": "...", "message": "...", "timestamp": "ISO8601" }],
|
||||
|
||||
```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
|
||||
"summary": { "duration": 0, "iterations": 0, "develop": {}, "debug": {}, "validate": {} }
|
||||
}
|
||||
} 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 })
|
||||
```
|
||||
|
||||
**Control Signal Checking**: Agent checks `state.status` before every action:
|
||||
- `running` → continue
|
||||
- `paused` → exit gracefully, wait for resume
|
||||
- `failed` → terminate
|
||||
- Other → stop
|
||||
|
||||
**Recovery**: If state corrupted, rebuild `skill_state` from `.progress/` markdown files and logs.
|
||||
|
||||
## 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 |
|
||||
| Action | Purpose | Preconditions | Output Files | Trigger |
|
||||
|--------|---------|---------------|--------------|---------|
|
||||
| [INIT](actions/action-init.md) | Initialize session | status=running, skill_state=null | develop.md, state.json | First run |
|
||||
| [DEVELOP](actions/action-develop.md) | Execute dev task | pending tasks > 0 | develop.md, changes.log | Has pending tasks |
|
||||
| [DEBUG](actions/action-debug.md) | Hypothesis debug | needs debugging | debug.md, debug.log | Test failures |
|
||||
| [VALIDATE](actions/action-validate.md) | Run tests | needs validation | validate.md, test-results.json | After develop/debug |
|
||||
| [COMPLETE](actions/action-complete.md) | Finish loop | all done | summary.md | All tasks done |
|
||||
| [MENU](actions/action-menu.md) | Display menu | interactive mode | - | Interactive mode |
|
||||
|
||||
### Action Flow
|
||||
|
||||
```
|
||||
spawn_agent (ccw-loop-executor)
|
||||
|
|
||||
v
|
||||
+-------+
|
||||
| INIT | (if skill_state is null)
|
||||
+-------+
|
||||
|
|
||||
v
|
||||
+-------+ send_input
|
||||
| MENU | <------------- (user selection in interactive mode)
|
||||
+-------+
|
||||
|
|
||||
+---+---+---+---+
|
||||
| | | | |
|
||||
v v v v v
|
||||
DEV DBG VAL CMP EXIT
|
||||
|
|
||||
v
|
||||
wait() -> get result
|
||||
|
|
||||
v
|
||||
[Loop continues via send_input]
|
||||
|
|
||||
v
|
||||
close_agent()
|
||||
```
|
||||
|
||||
### Action Dependencies
|
||||
|
||||
| Action | Depends On | Leads To |
|
||||
|--------|------------|----------|
|
||||
| INIT | - | MENU or DEVELOP |
|
||||
| MENU | INIT | User selection |
|
||||
| DEVELOP | INIT | DEVELOP, DEBUG, VALIDATE |
|
||||
| DEBUG | INIT | DEVELOP, VALIDATE |
|
||||
| VALIDATE | DEVELOP or DEBUG | COMPLETE, DEBUG, DEVELOP |
|
||||
| COMPLETE | - | Terminal |
|
||||
|
||||
### Action Sequences
|
||||
|
||||
```
|
||||
Happy Path (Auto): INIT → DEVELOP → DEVELOP → VALIDATE (pass) → COMPLETE
|
||||
Debug Iteration: INIT → DEVELOP → VALIDATE (fail) → DEBUG → VALIDATE (pass) → COMPLETE
|
||||
Interactive Path: INIT → MENU → DEVELOP → MENU → VALIDATE → MENU → COMPLETE
|
||||
```
|
||||
|
||||
## Auto Mode Selection Logic
|
||||
|
||||
```javascript
|
||||
function selectNextAction(state) {
|
||||
const skillState = state.skill_state
|
||||
|
||||
// 1. Terminal conditions
|
||||
if (state.status === 'completed') return null
|
||||
if (state.status === 'failed') return null
|
||||
if (state.current_iteration >= state.max_iterations) return 'COMPLETE'
|
||||
|
||||
// 2. Initialization check
|
||||
if (!skillState) return 'INIT'
|
||||
|
||||
// 3. Auto selection based on state
|
||||
const hasPendingDevelop = skillState.develop.tasks.some(t => t.status === 'pending')
|
||||
|
||||
if (hasPendingDevelop) return 'DEVELOP'
|
||||
|
||||
if (skillState.last_action === 'DEVELOP') {
|
||||
if (skillState.develop.completed < skillState.develop.total) return 'DEBUG'
|
||||
}
|
||||
|
||||
if (skillState.last_action === 'DEBUG' || skillState.debug.confirmed_hypothesis) {
|
||||
return 'VALIDATE'
|
||||
}
|
||||
|
||||
if (skillState.last_action === 'VALIDATE') {
|
||||
if (!skillState.validate.passed) return 'DEVELOP'
|
||||
}
|
||||
|
||||
if (skillState.validate.passed && !hasPendingDevelop) return 'COMPLETE'
|
||||
|
||||
return 'DEVELOP'
|
||||
}
|
||||
```
|
||||
|
||||
## Coordination Protocol
|
||||
|
||||
### Agent → Orchestrator (ACTION_RESULT)
|
||||
|
||||
Every action MUST output:
|
||||
|
||||
```
|
||||
ACTION_RESULT:
|
||||
- action: {ACTION_NAME}
|
||||
- status: success | failed | needs_input
|
||||
- message: {user-facing message}
|
||||
- state_updates: { ... }
|
||||
|
||||
FILES_UPDATED:
|
||||
- {file_path}: {description}
|
||||
|
||||
NEXT_ACTION_NEEDED: {ACTION_NAME} | WAITING_INPUT | COMPLETED | PAUSED
|
||||
```
|
||||
|
||||
### Orchestrator → Agent (send_input)
|
||||
|
||||
Auto mode continuation:
|
||||
|
||||
```
|
||||
## CONTINUE EXECUTION
|
||||
|
||||
Previous action completed: {action}
|
||||
Result: {status}
|
||||
|
||||
## EXECUTE NEXT ACTION
|
||||
|
||||
Continue with: {next_action}
|
||||
Read action instructions and execute.
|
||||
Output ACTION_RESULT when complete.
|
||||
```
|
||||
|
||||
Interactive mode user input:
|
||||
|
||||
```
|
||||
## USER INPUT RECEIVED
|
||||
|
||||
Action selected: {action}
|
||||
|
||||
## EXECUTE SELECTED ACTION
|
||||
|
||||
Read action instructions and execute: {action}
|
||||
Update state and progress files accordingly.
|
||||
Output ACTION_RESULT when complete.
|
||||
```
|
||||
|
||||
### Codex Subagent API
|
||||
|
||||
| API | Purpose |
|
||||
|-----|---------|
|
||||
| `spawn_agent({ message })` | Create subagent, returns `agent_id` |
|
||||
| `wait({ ids, timeout_ms })` | Wait for results (only way to get output) |
|
||||
| `send_input({ id, message })` | Continue interaction / follow-up |
|
||||
| `close_agent({ id })` | Close and reclaim (irreversible) |
|
||||
|
||||
**Rules**: Single agent for entire loop. `send_input` for multi-phase. `close_agent` only after confirming no more interaction needed.
|
||||
|
||||
## TodoWrite Pattern
|
||||
|
||||
### Phase-Level Tracking (Attached)
|
||||
|
||||
```json
|
||||
[
|
||||
{"content": "Phase 1: Session Initialization", "status": "completed"},
|
||||
{"content": "Phase 2: Orchestration Loop", "status": "in_progress"},
|
||||
{"content": " → Action: INIT", "status": "completed"},
|
||||
{"content": " → Action: DEVELOP (task 1/3)", "status": "in_progress"},
|
||||
{"content": " → Action: VALIDATE", "status": "pending"},
|
||||
{"content": " → Action: COMPLETE", "status": "pending"}
|
||||
]
|
||||
```
|
||||
|
||||
### Iteration Tracking (Collapsed)
|
||||
|
||||
```json
|
||||
[
|
||||
{"content": "Phase 1: Session Initialization", "status": "completed"},
|
||||
{"content": "Iteration 1: DEVELOP x3 + VALIDATE (pass)", "status": "completed"},
|
||||
{"content": "Phase 2: COMPLETE", "status": "in_progress"}
|
||||
]
|
||||
```
|
||||
|
||||
## Core Rules
|
||||
|
||||
1. **Start Immediately**: First action is TodoWrite initialization, then Phase 1 execution
|
||||
2. **Progressive Phase Loading**: Read phase docs ONLY when that phase is about to execute
|
||||
3. **Parse Every Output**: Extract ACTION_RESULT from agent output for next decision
|
||||
4. **Auto-Continue**: After each action, execute next pending action automatically (auto mode)
|
||||
5. **Track Progress**: Update TodoWrite dynamically with attachment/collapse pattern
|
||||
6. **Single Writer**: Orchestrator updates master state file; agent writes to progress files
|
||||
7. **File References**: Pass file paths between orchestrator and agent, not content
|
||||
8. **DO NOT STOP**: Continuous execution until COMPLETED, PAUSED, STOPPED, or max iterations
|
||||
|
||||
## Error Handling
|
||||
|
||||
| Error Type | Recovery |
|
||||
|------------|----------|
|
||||
| Agent timeout | send_input requesting convergence, then retry |
|
||||
| State corrupted | Rebuild from progress markdown files and logs |
|
||||
| Agent closed unexpectedly | Re-spawn with previous output in message |
|
||||
| Action failed | Log error, continue or prompt user |
|
||||
| Tests fail | Loop back to DEVELOP or DEBUG |
|
||||
| Max iterations reached | Generate summary with remaining issues documented |
|
||||
| Session not found | Create new session |
|
||||
|
||||
## Coordinator Checklist
|
||||
|
||||
### Before Each Phase
|
||||
|
||||
- [ ] Read phase reference document
|
||||
- [ ] Check current state for dependencies
|
||||
- [ ] Update TodoWrite with phase tasks
|
||||
|
||||
### After Each Phase
|
||||
|
||||
- [ ] Parse agent outputs (ACTION_RESULT)
|
||||
- [ ] Update master state file (iteration count, updated_at)
|
||||
- [ ] Collapse TodoWrite sub-tasks
|
||||
- [ ] Determine next action (continue / iterate / complete)
|
||||
|
||||
## Reference Documents
|
||||
|
||||
| Document | Purpose |
|
||||
|----------|---------|
|
||||
| [actions/](actions/) | Action definitions (INIT, DEVELOP, DEBUG, VALIDATE, COMPLETE, MENU) |
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -311,40 +438,12 @@ close_agent({ id: agent })
|
||||
# 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"
|
||||
|
||||
# Continue existing loop
|
||||
/ccw-loop --loop-id=loop-v2-20260122-abc123
|
||||
|
||||
# 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
|
||||
|
||||
Reference in New Issue
Block a user