Files
Claude-Code-Workflow/.codex/skills/ccw-loop/SKILL.md
catlog22 b9f17f0fcf fix: Add required 'name' field to Codex skill YAML frontmatter
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.
2026-01-23 12:38:45 +08:00

12 KiB
Raw Blame History

name, description, argument-hint
name description argument-hint
CCW Loop 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", "开发循环", "迭代开发". 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 并行: 主协调器 + 多 workerwait({ 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

// 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)

// ==================== 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 Initialize loop session meta.json, state.json First run
action-develop Execute development task progress.md, tasks.json Has pending tasks
action-debug Hypothesis-driven debug understanding.md, hypotheses.json Needs debugging
action-validate Test and validate validation.md, test-results.json Needs validation
action-complete Complete loop summary.md All done
action-menu Display action menu - Interactive mode

Usage

# 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 Orchestrator: state reading + action selection
phases/state-schema.md State structure definition
specs/loop-requirements.md Loop requirements specification
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