mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-12 02:37:45 +08:00
Add lightweight interactive planning workflows: Lite-Plan-B and Lite-Plan-C
- Introduced Lite-Plan-B for hybrid mode planning with multi-agent parallel exploration and primary agent merge/clarify/plan capabilities. - Added Lite-Plan-C for Codex subagent orchestration, featuring intelligent task analysis, parallel exploration, and adaptive planning based on task complexity. - Both workflows include detailed execution processes, session setup, and structured output formats for exploration and planning results.
This commit is contained in:
@@ -1,189 +1,683 @@
|
||||
---
|
||||
description: Execute tasks sequentially from plan.json file
|
||||
argument-hint: FILE=<path>
|
||||
description: Execute tasks based on in-memory plan, prompt description, or file content (Codex Subagent Version)
|
||||
argument-hint: "[--in-memory] [\"task description\"|file-path]"
|
||||
---
|
||||
|
||||
# Workflow Lite-Execute (Codex Version)
|
||||
# Workflow Lite-Execute Command (Codex Subagent Version)
|
||||
|
||||
## Core Principle
|
||||
## Overview
|
||||
|
||||
**Serial Execution**: Execute tasks ONE BY ONE in order. Complete current task fully before moving to next. Continue until ALL tasks complete.
|
||||
Flexible task execution command with **optimized Codex subagent orchestration**. Supports three input modes: in-memory plan (from lite-plan), direct prompt description, or file content.
|
||||
|
||||
## Input
|
||||
**Core Optimizations:**
|
||||
- **Batch Parallel Execution**: `spawn_agent × N → wait({ ids: [...] })` for independent tasks
|
||||
- **Context Preservation**: Primary executor retained for follow-ups via `send_input()`
|
||||
- **Unified Prompt Builder**: Same template for both Agent and CLI executors
|
||||
- **Explicit Lifecycle**: `spawn_agent → wait → [send_input] → close_agent`
|
||||
|
||||
Read plan file at `$FILE` path (e.g., `.workflow/.lite-plan/session-id/plan.json`)
|
||||
**Core capabilities:**
|
||||
- Multi-mode input (in-memory plan, prompt description, or file path)
|
||||
- Execution orchestration via Codex subagents with full context
|
||||
- Live progress tracking via TodoWrite at batch level
|
||||
- Optional code review with selected tool (Gemini, Codex, or custom)
|
||||
- Context continuity across multiple executions
|
||||
- Intelligent format detection (Enhanced Task JSON vs plain text)
|
||||
|
||||
## Autonomous Execution Loop
|
||||
|
||||
```
|
||||
WHILE tasks remain:
|
||||
1. Read plan.json → Get task list
|
||||
2. Find FIRST task with status != "completed"
|
||||
3. IF task.depends_on exists:
|
||||
- Check all dependencies completed
|
||||
- IF not met → Skip, find next eligible task
|
||||
4. Execute current task fully
|
||||
5. Mark task completed in plan.json
|
||||
6. Output progress: "[X/N] Task completed: {title}"
|
||||
7. CONTINUE to next task (DO NOT STOP)
|
||||
|
||||
WHEN all tasks completed:
|
||||
Output final summary
|
||||
```
|
||||
|
||||
## Step-by-Step Execution
|
||||
|
||||
### Step 1: Load Plan
|
||||
## Usage
|
||||
|
||||
### Command Syntax
|
||||
```bash
|
||||
cat $FILE
|
||||
/workflow:lite-execute [FLAGS] <INPUT>
|
||||
|
||||
# Flags
|
||||
--in-memory Use plan from memory (called by lite-plan)
|
||||
|
||||
# Arguments
|
||||
<input> Task description string, or path to file (required)
|
||||
```
|
||||
|
||||
Parse JSON, extract:
|
||||
- `summary`: Overall goal
|
||||
- `tasks[]`: Task list with status
|
||||
## Input Modes
|
||||
|
||||
### Step 2: Find Next Task
|
||||
### Mode 1: In-Memory Plan
|
||||
|
||||
**Trigger**: Called by lite-plan after Phase 4 approval with `--in-memory` flag
|
||||
|
||||
**Input Source**: `executionContext` global variable set by lite-plan
|
||||
|
||||
**Behavior**:
|
||||
- Skip execution method selection (already set by lite-plan)
|
||||
- Directly proceed to execution with full context
|
||||
- All planning artifacts available (exploration, clarifications, plan)
|
||||
|
||||
### Mode 2: Prompt Description
|
||||
|
||||
**Trigger**: User calls with task description string
|
||||
|
||||
**Input**: Simple task description (e.g., "Add unit tests for auth module")
|
||||
|
||||
**Behavior**:
|
||||
- Store prompt as `originalUserInput`
|
||||
- Create simple execution plan from prompt
|
||||
- AskUserQuestion: Select execution method (Agent/Codex/Auto)
|
||||
- AskUserQuestion: Select code review tool (Skip/Gemini/Codex/Other)
|
||||
- Proceed to execution with `originalUserInput` included
|
||||
|
||||
### Mode 3: File Content
|
||||
|
||||
**Trigger**: User calls with file path
|
||||
|
||||
**Input**: Path to file containing task description or plan.json
|
||||
|
||||
**Behavior**:
|
||||
- Read file and detect format (plan.json vs plain text)
|
||||
- If plan.json: Use `planObject` directly
|
||||
- If plain text: Treat as prompt (same as Mode 2)
|
||||
|
||||
## Execution Process
|
||||
|
||||
```
|
||||
Input Parsing:
|
||||
└─ Decision (mode detection):
|
||||
├─ --in-memory flag → Mode 1: Load executionContext → Skip user selection
|
||||
├─ Ends with .md/.json/.txt → Mode 3: Read file → Detect format
|
||||
│ ├─ Valid plan.json → Use planObject → User selects method + review
|
||||
│ └─ Not plan.json → Treat as prompt → User selects method + review
|
||||
└─ Other → Mode 2: Prompt description → User selects method + review
|
||||
|
||||
Execution (Codex Subagent Pattern):
|
||||
├─ Step 1: Initialize result tracking (previousExecutionResults = [])
|
||||
├─ Step 2: Task grouping & batch creation
|
||||
│ ├─ Extract explicit depends_on (no inference)
|
||||
│ ├─ Group: independent tasks → single parallel batch
|
||||
│ └─ Group: dependent tasks → sequential phases
|
||||
├─ Step 3: Launch execution (spawn_agent × N → wait → close)
|
||||
│ ├─ Phase 1: All independent tasks (spawn_agent × N → batch wait)
|
||||
│ └─ Phase 2+: Dependent tasks (sequential spawn_agent → wait → close)
|
||||
├─ Step 4: Track progress (TodoWrite updates per batch)
|
||||
└─ Step 5: Code review (if codeReviewTool ≠ "Skip")
|
||||
|
||||
Output:
|
||||
└─ Execution complete with results in previousExecutionResults[]
|
||||
```
|
||||
|
||||
## Implementation
|
||||
|
||||
### Step 1: Initialize Execution Tracking
|
||||
|
||||
```javascript
|
||||
// Find first non-completed task with met dependencies
|
||||
for (task of tasks) {
|
||||
if (task.status === "completed") continue
|
||||
if (task.depends_on?.every(dep => getTask(dep).status === "completed")) {
|
||||
return task // Execute this one
|
||||
}
|
||||
// Initialize result tracking
|
||||
previousExecutionResults = []
|
||||
|
||||
// In-Memory Mode: Echo execution strategy
|
||||
if (executionContext) {
|
||||
console.log(`
|
||||
## Execution Strategy (from lite-plan)
|
||||
|
||||
- **Method**: ${executionContext.executionMethod}
|
||||
- **Review**: ${executionContext.codeReviewTool}
|
||||
- **Tasks**: ${executionContext.planObject.tasks.length}
|
||||
- **Complexity**: ${executionContext.planObject.complexity}
|
||||
${executionContext.executorAssignments ? `- **Assignments**: ${JSON.stringify(executionContext.executorAssignments)}` : ''}
|
||||
`)
|
||||
}
|
||||
return null // All done
|
||||
```
|
||||
|
||||
### Step 3: Execute Task
|
||||
### Step 2: Task Grouping & Batch Creation
|
||||
|
||||
For current task, perform:
|
||||
```javascript
|
||||
// Use explicit depends_on from plan.json (no inference)
|
||||
function extractDependencies(tasks) {
|
||||
const taskIdToIndex = {}
|
||||
tasks.forEach((t, i) => { taskIdToIndex[t.id] = i })
|
||||
|
||||
```markdown
|
||||
## Executing: [task.title]
|
||||
return tasks.map((task, i) => {
|
||||
const deps = (task.depends_on || [])
|
||||
.map(depId => taskIdToIndex[depId])
|
||||
.filter(idx => idx !== undefined && idx < i)
|
||||
return { ...task, taskIndex: i, dependencies: deps }
|
||||
})
|
||||
}
|
||||
|
||||
**Scope**: `[task.scope]` (module/feature level)
|
||||
**Action**: [task.action]
|
||||
// Group into batches: maximize parallel execution
|
||||
function createExecutionBatches(tasks, executionMethod) {
|
||||
const tasksWithDeps = extractDependencies(tasks)
|
||||
const processed = new Set()
|
||||
const batches = []
|
||||
|
||||
// Phase 1: All independent tasks → single parallel batch
|
||||
const independentTasks = tasksWithDeps.filter(t => t.dependencies.length === 0)
|
||||
if (independentTasks.length > 0) {
|
||||
independentTasks.forEach(t => processed.add(t.taskIndex))
|
||||
batches.push({
|
||||
method: executionMethod,
|
||||
executionType: "parallel",
|
||||
groupId: "P1",
|
||||
taskSummary: independentTasks.map(t => t.title).join(' | '),
|
||||
tasks: independentTasks
|
||||
})
|
||||
}
|
||||
|
||||
// Phase 2+: Dependent tasks → sequential batches
|
||||
let remaining = tasksWithDeps.filter(t => !processed.has(t.taskIndex))
|
||||
|
||||
while (remaining.length > 0) {
|
||||
const ready = remaining.filter(t =>
|
||||
t.dependencies.every(d => processed.has(d))
|
||||
)
|
||||
|
||||
if (ready.length === 0) {
|
||||
console.warn('Circular dependency detected, forcing remaining tasks')
|
||||
ready.push(...remaining)
|
||||
}
|
||||
|
||||
ready.forEach(t => processed.add(t.taskIndex))
|
||||
batches.push({
|
||||
method: executionMethod,
|
||||
executionType: ready.length > 1 ? "parallel" : "sequential",
|
||||
groupId: `P${batches.length + 1}`,
|
||||
taskSummary: ready.map(t => t.title).join(' | '),
|
||||
tasks: ready
|
||||
})
|
||||
|
||||
remaining = remaining.filter(t => !processed.has(t.taskIndex))
|
||||
}
|
||||
|
||||
return batches
|
||||
}
|
||||
|
||||
const executionBatches = createExecutionBatches(planObject.tasks, executionMethod)
|
||||
|
||||
TodoWrite({
|
||||
todos: executionBatches.map(b => ({
|
||||
content: `${b.executionType === "parallel" ? "⚡" : "→"} [${b.groupId}] (${b.tasks.length} tasks)`,
|
||||
status: "pending",
|
||||
activeForm: `Executing ${b.groupId}`
|
||||
}))
|
||||
})
|
||||
```
|
||||
|
||||
### Step 3: Launch Execution (Codex Subagent Pattern)
|
||||
|
||||
#### Executor Resolution
|
||||
|
||||
```javascript
|
||||
// Get executor for task (task-level > global)
|
||||
function getTaskExecutor(task) {
|
||||
const assignments = executionContext?.executorAssignments || {}
|
||||
if (assignments[task.id]) {
|
||||
return assignments[task.id].executor // 'gemini' | 'codex' | 'agent'
|
||||
}
|
||||
// Fallback: global executionMethod mapping
|
||||
const method = executionContext?.executionMethod || 'Auto'
|
||||
if (method === 'Agent') return 'agent'
|
||||
if (method === 'Codex') return 'codex'
|
||||
// Auto: based on complexity
|
||||
return planObject.complexity === 'Low' ? 'agent' : 'codex'
|
||||
}
|
||||
```
|
||||
|
||||
#### Unified Task Prompt Builder
|
||||
|
||||
```javascript
|
||||
function buildExecutionPrompt(batch) {
|
||||
const formatTask = (t) => `
|
||||
## ${t.title}
|
||||
|
||||
**Scope**: \`${t.scope}\` | **Action**: ${t.action}
|
||||
|
||||
### Modification Points
|
||||
For each point in task.modification_points:
|
||||
- **File**: [point.file]
|
||||
- **Target**: [point.target] (function/class/line range)
|
||||
- **Change**: [point.change]
|
||||
${t.modification_points.map(p => `- **${p.file}** → \`${p.target}\`: ${p.change}`).join('\n')}
|
||||
|
||||
### Implementation
|
||||
[Follow task.implementation steps]
|
||||
${t.rationale ? `
|
||||
### Why this approach
|
||||
${t.rationale.chosen_approach}
|
||||
${t.rationale.decision_factors?.length > 0 ? `\nKey factors: ${t.rationale.decision_factors.join(', ')}` : ''}
|
||||
` : ''}
|
||||
|
||||
### Reference Pattern
|
||||
- Pattern: [task.reference.pattern]
|
||||
- Files: [task.reference.files]
|
||||
- Examples: [task.reference.examples]
|
||||
### How to do it
|
||||
${t.description}
|
||||
|
||||
### Acceptance Criteria
|
||||
- [ ] [criterion 1]
|
||||
- [ ] [criterion 2]
|
||||
```
|
||||
${t.implementation.map(step => `- ${step}`).join('\n')}
|
||||
|
||||
**Execute all modification points. Verify all acceptance criteria.**
|
||||
### Reference
|
||||
- Pattern: ${t.reference?.pattern || 'N/A'}
|
||||
- Files: ${t.reference?.files?.join(', ') || 'N/A'}
|
||||
|
||||
### Step 4: Mark Completed
|
||||
### Done when
|
||||
${t.acceptance.map(c => `- [ ] ${c}`).join('\n')}`
|
||||
|
||||
Update task status in plan.json:
|
||||
```json
|
||||
{
|
||||
"id": "task-id",
|
||||
"status": "completed" // Change from "pending"
|
||||
const sections = []
|
||||
|
||||
if (originalUserInput) sections.push(`## Goal\n${originalUserInput}`)
|
||||
|
||||
sections.push(`## Tasks\n${batch.tasks.map(formatTask).join('\n\n---\n')}`)
|
||||
|
||||
// Context
|
||||
const context = []
|
||||
if (previousExecutionResults.length > 0) {
|
||||
context.push(`### Previous Work\n${previousExecutionResults.map(r => `- ${r.tasksSummary}: ${r.status}`).join('\n')}`)
|
||||
}
|
||||
if (clarificationContext) {
|
||||
context.push(`### Clarifications\n${Object.entries(clarificationContext).map(([q, a]) => `- ${q}: ${a}`).join('\n')}`)
|
||||
}
|
||||
context.push(`### Project Guidelines\n@.workflow/project-guidelines.json`)
|
||||
if (context.length > 0) sections.push(`## Context\n${context.join('\n\n')}`)
|
||||
|
||||
sections.push(`Complete each task according to its "Done when" checklist.`)
|
||||
|
||||
return sections.join('\n\n')
|
||||
}
|
||||
```
|
||||
|
||||
### Step 5: Continue
|
||||
#### Parallel Batch Execution (Codex Pattern)
|
||||
|
||||
**DO NOT STOP. Immediately proceed to Step 2 to find next task.**
|
||||
```javascript
|
||||
// ==================== CODEX SUBAGENT PATTERN ====================
|
||||
|
||||
Output progress:
|
||||
```
|
||||
✓ [2/5] Completed: [task.title]
|
||||
→ Next: [next_task.title]
|
||||
```
|
||||
async function executeBatch(batch) {
|
||||
const executor = getTaskExecutor(batch.tasks[0])
|
||||
|
||||
if (executor === 'agent') {
|
||||
return executeWithAgent(batch)
|
||||
} else {
|
||||
return executeWithCLI(batch, executor)
|
||||
}
|
||||
}
|
||||
|
||||
## Task Format Reference
|
||||
// Option A: Agent Execution (spawn_agent pattern)
|
||||
async function executeWithAgent(batch) {
|
||||
// Step 1: Spawn agents for parallel execution (role file read by agent itself)
|
||||
const executionAgents = batch.tasks.map((task, index) => {
|
||||
return spawn_agent({
|
||||
message: `
|
||||
## TASK ASSIGNMENT
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "T1",
|
||||
"title": "Implement auth validation",
|
||||
"scope": "src/auth/",
|
||||
"action": "Create|Update|Implement|Refactor|Add|Delete|Configure|Test|Fix",
|
||||
"description": "What to implement (1-2 sentences)",
|
||||
"modification_points": [
|
||||
{
|
||||
"file": "src/auth/validator.ts",
|
||||
"target": "validateToken:45-60",
|
||||
"change": "Add expiry check"
|
||||
},
|
||||
{
|
||||
"file": "src/auth/middleware.ts",
|
||||
"target": "authMiddleware",
|
||||
"change": "Call new validator"
|
||||
### Execution Context
|
||||
- **Batch ID**: ${batch.groupId}
|
||||
- **Task Index**: ${index + 1} of ${batch.tasks.length}
|
||||
- **Execution Type**: ${batch.executionType}
|
||||
|
||||
### Task Content
|
||||
${buildExecutionPrompt({ ...batch, tasks: [task] })}
|
||||
|
||||
### MANDATORY FIRST STEPS (Agent Execute)
|
||||
1. **Read role definition**: ~/.codex/agents/code-developer.md (MUST read first)
|
||||
2. Read: .workflow/project-tech.json (technology context)
|
||||
3. Read: .workflow/project-guidelines.json (constraints)
|
||||
4. Understand existing patterns before modifying
|
||||
|
||||
### Quality Standards
|
||||
- Follow existing code patterns
|
||||
- Maintain backward compatibility
|
||||
- No unnecessary changes beyond scope
|
||||
|
||||
### Deliverables
|
||||
- Implement task according to "Done when" checklist
|
||||
- Return: Brief completion summary with files modified
|
||||
`
|
||||
})
|
||||
})
|
||||
|
||||
// Step 3: Batch wait for all agents
|
||||
const results = wait({
|
||||
ids: executionAgents,
|
||||
timeout_ms: 900000 // 15 minutes per batch
|
||||
})
|
||||
|
||||
// Step 4: Collect results
|
||||
const batchResult = {
|
||||
executionId: `[${batch.groupId}]`,
|
||||
status: results.timed_out ? 'partial' : 'completed',
|
||||
tasksSummary: batch.taskSummary,
|
||||
completionSummary: '',
|
||||
keyOutputs: '',
|
||||
notes: ''
|
||||
}
|
||||
|
||||
executionAgents.forEach((agentId, index) => {
|
||||
if (results.status[agentId].completed) {
|
||||
batchResult.completionSummary += `Task ${index + 1}: ${results.status[agentId].completed}\n`
|
||||
}
|
||||
],
|
||||
"implementation": ["step 1", "step 2", "...max 7 steps"],
|
||||
"reference": {
|
||||
"pattern": "pattern name",
|
||||
"files": ["example1.ts"],
|
||||
"examples": "specific guidance"
|
||||
},
|
||||
"acceptance": ["criterion 1", "criterion 2"],
|
||||
"depends_on": ["T0"],
|
||||
"status": "pending|completed"
|
||||
})
|
||||
|
||||
// Step 5: Cleanup all agents
|
||||
executionAgents.forEach(id => close_agent({ id }))
|
||||
|
||||
return batchResult
|
||||
}
|
||||
|
||||
// Option B: CLI Execution (ccw cli)
|
||||
async function executeWithCLI(batch, executor) {
|
||||
const sessionId = executionContext?.session?.id || 'standalone'
|
||||
const fixedExecutionId = `${sessionId}-${batch.groupId}`
|
||||
|
||||
const cli_command = `ccw cli -p "${buildExecutionPrompt(batch)}" --tool ${executor} --mode write --id ${fixedExecutionId}`
|
||||
|
||||
// Execute in background
|
||||
Bash({
|
||||
command: cli_command,
|
||||
run_in_background: true
|
||||
})
|
||||
|
||||
// STOP HERE - CLI executes in background, task hook will notify on completion
|
||||
return {
|
||||
executionId: `[${batch.groupId}]`,
|
||||
status: 'in_progress',
|
||||
tasksSummary: batch.taskSummary,
|
||||
fixedCliId: fixedExecutionId
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Key Fields**:
|
||||
- `scope`: Module/feature level path (prefer over single file)
|
||||
- `modification_points[]`: All files to modify with precise targets
|
||||
- `target`: Function/class/line range (e.g., `validateToken:45-60`)
|
||||
#### Execution Flow
|
||||
|
||||
## Execution Rules
|
||||
```javascript
|
||||
// ==================== MAIN EXECUTION FLOW ====================
|
||||
|
||||
1. **Never stop mid-workflow** - Continue until all tasks complete
|
||||
2. **One task at a time** - Fully complete before moving on
|
||||
3. **Respect dependencies** - Skip blocked tasks, return later
|
||||
4. **Update status immediately** - Mark completed right after finishing
|
||||
5. **Self-verify** - Check acceptance criteria before marking done
|
||||
const parallelBatches = executionBatches.filter(b => b.executionType === "parallel")
|
||||
const sequentialBatches = executionBatches.filter(b => b.executionType === "sequential")
|
||||
|
||||
## Final Summary
|
||||
// Phase 1: Launch all parallel batches (Codex batch wait advantage)
|
||||
if (parallelBatches.length > 0) {
|
||||
TodoWrite({
|
||||
todos: executionBatches.map(b => ({
|
||||
status: b.executionType === "parallel" ? "in_progress" : "pending"
|
||||
}))
|
||||
})
|
||||
|
||||
// Spawn all parallel batch agents at once (role file read by agent itself)
|
||||
const allParallelAgents = []
|
||||
const batchToAgents = new Map()
|
||||
|
||||
for (const batch of parallelBatches) {
|
||||
const executor = getTaskExecutor(batch.tasks[0])
|
||||
|
||||
if (executor === 'agent') {
|
||||
const agents = batch.tasks.map((task, index) => spawn_agent({
|
||||
message: `
|
||||
## TASK: ${task.title}
|
||||
${buildExecutionPrompt({ ...batch, tasks: [task] })}
|
||||
|
||||
When ALL tasks completed:
|
||||
### MANDATORY FIRST STEPS (Agent Execute)
|
||||
1. **Read role definition**: ~/.codex/agents/code-developer.md (MUST read first)
|
||||
2. Read: .workflow/project-tech.json
|
||||
3. Read: .workflow/project-guidelines.json
|
||||
`
|
||||
}))
|
||||
|
||||
allParallelAgents.push(...agents)
|
||||
batchToAgents.set(batch.groupId, agents)
|
||||
}
|
||||
}
|
||||
|
||||
// Single batch wait for ALL parallel agents (KEY CODEX ADVANTAGE)
|
||||
if (allParallelAgents.length > 0) {
|
||||
const parallelResults = wait({
|
||||
ids: allParallelAgents,
|
||||
timeout_ms: 900000
|
||||
})
|
||||
|
||||
// Collect results per batch
|
||||
for (const batch of parallelBatches) {
|
||||
const agents = batchToAgents.get(batch.groupId) || []
|
||||
const batchResult = {
|
||||
executionId: `[${batch.groupId}]`,
|
||||
status: 'completed',
|
||||
tasksSummary: batch.taskSummary,
|
||||
completionSummary: agents.map((id, i) =>
|
||||
parallelResults.status[id]?.completed || 'incomplete'
|
||||
).join('\n')
|
||||
}
|
||||
previousExecutionResults.push(batchResult)
|
||||
}
|
||||
|
||||
// Cleanup all parallel agents
|
||||
allParallelAgents.forEach(id => close_agent({ id }))
|
||||
}
|
||||
|
||||
TodoWrite({
|
||||
todos: executionBatches.map(b => ({
|
||||
status: parallelBatches.includes(b) ? "completed" : "pending"
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
```markdown
|
||||
## Execution Complete
|
||||
|
||||
**Plan**: $FILE
|
||||
**Total Tasks**: N
|
||||
**All Completed**: Yes
|
||||
|
||||
### Results
|
||||
| # | Task | Status |
|
||||
|---|------|--------|
|
||||
| 1 | [title] | ✓ |
|
||||
| 2 | [title] | ✓ |
|
||||
|
||||
### Files Modified
|
||||
- `path/file1.ts`
|
||||
- `path/file2.ts`
|
||||
|
||||
### Summary
|
||||
[Brief description of what was accomplished]
|
||||
// Phase 2: Execute sequential batches one by one
|
||||
for (const batch of sequentialBatches) {
|
||||
TodoWrite({
|
||||
todos: executionBatches.map(b => ({
|
||||
status: b === batch ? "in_progress" : (processed.has(b) ? "completed" : "pending")
|
||||
}))
|
||||
})
|
||||
|
||||
const result = await executeBatch(batch)
|
||||
previousExecutionResults.push(result)
|
||||
|
||||
TodoWrite({
|
||||
todos: executionBatches.map(b => ({
|
||||
status: "completed" /* or "pending" for remaining */
|
||||
}))
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4: Progress Tracking
|
||||
|
||||
Progress tracked at batch level. Icons: ⚡ (parallel), → (sequential)
|
||||
|
||||
### Step 5: Code Review (Optional)
|
||||
|
||||
**Skip Condition**: Only run if `codeReviewTool ≠ "Skip"`
|
||||
|
||||
```javascript
|
||||
// ==================== CODE REVIEW (CODEX PATTERN) ====================
|
||||
|
||||
if (codeReviewTool !== 'Skip') {
|
||||
console.log(`
|
||||
## Code Review
|
||||
|
||||
Starting ${codeReviewTool} review...
|
||||
`)
|
||||
|
||||
const reviewPrompt = `
|
||||
PURPOSE: Code review for implemented changes against plan acceptance criteria
|
||||
TASK: • Verify plan acceptance criteria • Check verification requirements • Analyze code quality • Identify issues
|
||||
MODE: analysis
|
||||
CONTEXT: @**/* @${executionContext.session.artifacts.plan} | Memory: Review lite-execute changes
|
||||
EXPECTED: Quality assessment with: acceptance verification, issue identification, recommendations
|
||||
CONSTRAINTS: Focus on plan acceptance criteria | analysis=READ-ONLY
|
||||
`
|
||||
|
||||
if (codeReviewTool === 'Agent Review') {
|
||||
// Spawn review agent (role file read by agent itself)
|
||||
const reviewAgent = spawn_agent({
|
||||
message: `
|
||||
## TASK: Code Review
|
||||
|
||||
${reviewPrompt}
|
||||
|
||||
### MANDATORY FIRST STEPS (Agent Execute)
|
||||
1. **Read role definition**: ~/.codex/agents/code-developer.md (MUST read first)
|
||||
2. Read plan artifact: ${executionContext.session.artifacts.plan}
|
||||
${executionContext.session.artifacts.explorations?.map(e => `3. Read exploration: ${e.path}`).join('\n') || ''}
|
||||
|
||||
### Review Focus
|
||||
1. Verify each acceptance criterion from plan.tasks[].acceptance
|
||||
2. Check verification requirements (unit_tests, success_metrics)
|
||||
3. Validate plan adherence and risk mitigations
|
||||
4. Identify any issues or improvements needed
|
||||
|
||||
### Output Format
|
||||
Summary: [overall assessment]
|
||||
Acceptance: [criterion 1: ✓/✗, criterion 2: ✓/✗, ...]
|
||||
Issues: [list of issues if any]
|
||||
Recommendations: [suggestions]
|
||||
`
|
||||
})
|
||||
|
||||
const reviewResult = wait({
|
||||
ids: [reviewAgent],
|
||||
timeout_ms: 600000
|
||||
})
|
||||
|
||||
console.log(`
|
||||
### Review Complete
|
||||
|
||||
${reviewResult.status[reviewAgent].completed}
|
||||
`)
|
||||
|
||||
close_agent({ id: reviewAgent })
|
||||
|
||||
} else if (codeReviewTool === 'Gemini Review') {
|
||||
// CLI-based review
|
||||
Bash({
|
||||
command: `ccw cli -p "${reviewPrompt}" --tool gemini --mode analysis`,
|
||||
run_in_background: true
|
||||
})
|
||||
// Wait for hook callback
|
||||
|
||||
} else if (codeReviewTool === 'Codex Review') {
|
||||
// Git-aware review
|
||||
Bash({
|
||||
command: `ccw cli --tool codex --mode review --uncommitted`,
|
||||
run_in_background: true
|
||||
})
|
||||
// Wait for hook callback
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 6: Update Development Index
|
||||
|
||||
```javascript
|
||||
// After all executions complete
|
||||
const projectJsonPath = '.workflow/project-tech.json'
|
||||
if (fileExists(projectJsonPath)) {
|
||||
const projectJson = JSON.parse(Read(projectJsonPath))
|
||||
|
||||
if (!projectJson.development_index) {
|
||||
projectJson.development_index = { feature: [], enhancement: [], bugfix: [], refactor: [], docs: [] }
|
||||
}
|
||||
|
||||
function detectCategory(text) {
|
||||
text = text.toLowerCase()
|
||||
if (/\b(fix|bug|error|issue|crash)\b/.test(text)) return 'bugfix'
|
||||
if (/\b(refactor|cleanup|reorganize)\b/.test(text)) return 'refactor'
|
||||
if (/\b(doc|readme|comment)\b/.test(text)) return 'docs'
|
||||
if (/\b(add|new|create|implement)\b/.test(text)) return 'feature'
|
||||
return 'enhancement'
|
||||
}
|
||||
|
||||
const category = detectCategory(`${planObject.summary} ${planObject.approach}`)
|
||||
const entry = {
|
||||
title: planObject.summary.slice(0, 60),
|
||||
date: new Date().toISOString().split('T')[0],
|
||||
description: planObject.approach.slice(0, 100),
|
||||
status: previousExecutionResults.every(r => r.status === 'completed') ? 'completed' : 'partial',
|
||||
session_id: executionContext?.session?.id || null
|
||||
}
|
||||
|
||||
projectJson.development_index[category].push(entry)
|
||||
Write(projectJsonPath, JSON.stringify(projectJson, null, 2))
|
||||
|
||||
console.log(`✓ Development index: [${category}] ${entry.title}`)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Codex vs Claude Comparison (for this workflow)
|
||||
|
||||
| Aspect | Claude Code Task | Codex Subagent |
|
||||
|--------|------------------|----------------|
|
||||
| **Creation** | `Task({ subagent_type, prompt })` | `spawn_agent({ message: task })` |
|
||||
| **Role Loading** | Auto via `subagent_type` | Agent reads `~/.codex/agents/*.md` in MANDATORY FIRST STEPS |
|
||||
| **Parallel Wait** | Multiple `Task()` calls | **Batch `wait({ ids: [...] })`** |
|
||||
| **Result Retrieval** | Sync return or `TaskOutput` | `wait({ ids }).status[id].completed` |
|
||||
| **Follow-up** | `resume` parameter | `send_input({ id, message })` |
|
||||
| **Cleanup** | Automatic | **Explicit `close_agent({ id })`** |
|
||||
|
||||
**Codex Advantages for lite-execute**:
|
||||
- True parallel execution with batch `wait` for all independent tasks
|
||||
- Single wait call for multiple agents (reduced orchestration overhead)
|
||||
- Fine-grained lifecycle control for complex task graphs
|
||||
|
||||
---
|
||||
|
||||
## Data Structures
|
||||
|
||||
### executionContext (Input - Mode 1)
|
||||
|
||||
```javascript
|
||||
{
|
||||
planObject: {
|
||||
summary: string,
|
||||
approach: string,
|
||||
tasks: [...],
|
||||
estimated_time: string,
|
||||
recommended_execution: string,
|
||||
complexity: string
|
||||
},
|
||||
clarificationContext: {...} | null,
|
||||
executionMethod: "Agent" | "Codex" | "Auto",
|
||||
codeReviewTool: "Skip" | "Gemini Review" | "Codex Review" | string,
|
||||
originalUserInput: string,
|
||||
executorAssignments: {
|
||||
[taskId]: { executor: "gemini" | "codex" | "agent", reason: string }
|
||||
},
|
||||
session: {
|
||||
id: string,
|
||||
folder: string,
|
||||
artifacts: {
|
||||
explorations: [{angle, path}],
|
||||
plan: string
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### executionResult (Output)
|
||||
|
||||
```javascript
|
||||
{
|
||||
executionId: string, // e.g., "[P1]", "[S1]"
|
||||
status: "completed" | "partial" | "failed",
|
||||
tasksSummary: string,
|
||||
completionSummary: string,
|
||||
keyOutputs: string,
|
||||
notes: string,
|
||||
fixedCliId: string | null // For CLI resume capability
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
|
||||
| Situation | Action |
|
||||
|-----------|--------|
|
||||
| File not found | Error and stop |
|
||||
| Task blocked (deps not met) | Skip, try next task |
|
||||
| All remaining tasks blocked | Report circular dependency |
|
||||
| Task execution error | Report error, mark failed, continue to next |
|
||||
| Acceptance criteria not met | Retry or report, then continue |
|
||||
| Error | Resolution |
|
||||
|-------|------------|
|
||||
| spawn_agent failure | Fallback to CLI execution |
|
||||
| wait() timeout | Use completed results, log partial status |
|
||||
| Agent crash | Collect partial output, offer retry |
|
||||
| CLI execution failure | Use fixed ID for resume |
|
||||
| Circular dependency | Force remaining tasks with warning |
|
||||
| Missing executionContext | Error: "No execution context found" |
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
**Codex-Specific**:
|
||||
- Pass role file path in MANDATORY FIRST STEPS (agent reads itself)
|
||||
- Use batch `wait({ ids: [...] })` for parallel tasks
|
||||
- Delay `close_agent` until all interactions complete
|
||||
- Track `fixedCliId` for resume capability
|
||||
|
||||
**General**:
|
||||
- Task Grouping: Based on explicit depends_on only
|
||||
- Execution: All independent tasks launch via single batch wait
|
||||
- Progress: TodoWrite at batch level (⚡ parallel, → sequential)
|
||||
|
||||
---
|
||||
|
||||
**Now execute the lite-execute workflow**
|
||||
|
||||
Reference in New Issue
Block a user