mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-12 02:37:45 +08:00
Convert parallel multi-agent/multi-CLI workflows to Codex-compatible serial execution:
- brainstorm-with-file: Parallel Creative/Pragmatic/Systematic perspectives → Serial CLI execution
- analyze-with-file: cli-explore-agent + parallel CLI → Native tools (Glob/Grep/Read) + serial Gemini CLI
- collaborative-plan-with-file: Parallel sub-agents → Serial domain planning loop
- unified-execute-with-file: DAG-based parallel wave execution → Serial task-by-task execution
Key Technical Changes:
- YAML header: Remove 'name' and 'allowed-tools' fields
- Variables: $ARGUMENTS → $TOPIC/$TASK/$PLAN
- Task agents: Task() calls → ccw cli commands with --tool flag
- Parallel execution: Parallel Task/Bash calls → Sequential loops
- Session format: Match existing Codex prompt structure
Pattern: For multi-step workflows, use explicit wait points with "⏳ Wait for completion before proceeding"
12 KiB
12 KiB
description, argument-hint
| description | argument-hint |
|---|---|
| Universal execution engine for consuming planning/brainstorm/analysis output. Serial task execution with progress tracking. Codex-optimized. | PLAN="<path>" [--auto-commit] [--dry-run] |
Codex Unified-Execute-With-File Prompt
Overview
Universal execution engine consuming any planning output and executing tasks serially with progress tracking.
Core workflow: Load Plan → Parse Tasks → Execute Sequentially → Track Progress → Verify
Target Plan
$PLAN
Parameters:
--auto-commit: Auto-commit after each task (conventional commits)--dry-run: Simulate execution without making changes
Execution Process
Session Initialization:
├─ Detect or load plan file
├─ Parse tasks from plan (JSON, Markdown, or other formats)
├─ Build task dependency graph
└─ Validate for cycles and feasibility
Pre-Execution:
├─ Analyze plan structure
├─ Identify modification targets (files)
├─ Check file conflicts and feasibility
└─ Generate execution strategy
Serial Execution (Task by Task):
├─ For each task:
│ ├─ Extract task context
│ ├─ Load previous task outputs
│ ├─ Route to Codex CLI for execution
│ ├─ Track progress in execution.md
│ ├─ Auto-commit if enabled
│ └─ Next task
└─ Complete all tasks
Post-Execution:
├─ Generate execution summary
├─ Record completion status
├─ Identify any failures
└─ Suggest next steps
Output:
├─ .workflow/.execution/{session-id}/execution.md (overview + timeline)
├─ .workflow/.execution/{session-id}/execution-events.md (detailed log)
└─ Git commits (if --auto-commit enabled)
Output Structure
.workflow/.execution/EXEC-{slug}-{date}/
├── execution.md # Plan overview + task table + timeline
└── execution-events.md # ⭐ Unified log (all executions) - SINGLE SOURCE OF TRUTH
Implementation Details
Session Setup
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()
// Resolve plan path
let planPath = "$PLAN"
if (!fs.existsSync(planPath)) {
// Auto-detect from common locations
const candidates = [
'.workflow/IMPL_PLAN.md',
'.workflow/.planning/*/plan-note.md',
'.workflow/.brainstorm/*/synthesis.json',
'.workflow/.analysis/*/conclusions.json'
]
planPath = autoDetectPlan(candidates)
}
// Create session
const planSlug = path.basename(planPath).replace(/[^a-z0-9-]/g, '').substring(0, 30)
const dateStr = getUtc8ISOString().substring(0, 10)
const randomId = Math.random().toString(36).substring(7)
const sessionId = `EXEC-${planSlug}-${dateStr}-${randomId}`
const sessionFolder = `.workflow/.execution/${sessionId}`
const executionPath = `${sessionFolder}/execution.md`
const eventsPath = `${sessionFolder}/execution-events.md`
bash(`mkdir -p ${sessionFolder}`)
Phase 1: Plan Detection & Parsing
Step 1.1: Load Plan File
// Detect plan format and parse
let tasks = []
if (planPath.endsWith('.json')) {
// JSON plan (from lite-plan, collaborative-plan, etc.)
const planJson = JSON.parse(Read(planPath))
tasks = parsePlanJson(planJson)
} else if (planPath.endsWith('.md')) {
// Markdown plan (IMPL_PLAN.md, plan-note.md, etc.)
const planMd = Read(planPath)
tasks = parsePlanMarkdown(planMd)
} else if (planPath.endsWith('synthesis.json')) {
// Brainstorm synthesis
const synthesis = JSON.parse(Read(planPath))
tasks = convertSynthesisToTasks(synthesis)
} else if (planPath.endsWith('conclusions.json')) {
// Analysis conclusions
const conclusions = JSON.parse(Read(planPath))
tasks = convertConclusionsToTasks(conclusions)
} else {
throw new Error(`Unsupported plan format: ${planPath}`)
}
Step 1.2: Build Execution Order
// Handle task dependencies
const depGraph = buildDependencyGraph(tasks)
// Validate: no cycles
validateNoCycles(depGraph)
// Calculate execution order (simple topological sort)
const executionOrder = topologicalSort(depGraph, tasks)
// In Codex: serial execution, no parallel waves
console.log(`Total tasks: ${tasks.length}`)
console.log(`Execution order: ${executionOrder.map(t => t.id).join(' → ')}`)
Step 1.3: Generate execution.md
# 执行计划
**Session**: ${sessionId}
**Plan Source**: ${planPath}
**Started**: ${getUtc8ISOString()}
---
## 计划概览
| 字段 | 值 |
|------|-----|
| 总任务数 | ${tasks.length} |
| 计划来源 | ${planPath} |
| 执行模式 | ${dryRun ? '模拟' : '实际'} |
| 自动提交 | ${autoCommit ? '启用' : '禁用'} |
---
## 任务列表
| ID | 标题 | 复杂度 | 依赖 | 状态 |
|----|------|--------|-------|-------|
${tasks.map(t => `| ${t.id} | ${t.title} | ${t.complexity || 'medium'} | ${t.depends_on?.join(',') || '-'} | ⏳ |`).join('\n')}
---
## 执行时间线
*(更新于 execution-events.md)*
---
Phase 2: Pre-Execution Analysis
Step 2.1: Feasibility Check
const issues = []
// Check file conflicts
const fileMap = new Map()
for (const task of tasks) {
for (const file of task.files_to_modify || []) {
if (!fileMap.has(file)) fileMap.set(file, [])
fileMap.get(file).push(task.id)
}
}
for (const [file, taskIds] of fileMap.entries()) {
if (taskIds.length > 1) {
// Sequential modification of same file
console.log(`⚠️ Sequential modification: ${file} (${taskIds.join(' → ')})`)
}
}
// Check missing dependencies
for (const task of tasks) {
for (const depId of task.depends_on || []) {
if (!tasks.find(t => t.id === depId)) {
issues.push(`Task ${task.id} depends on missing ${depId}`)
}
}
}
if (issues.length > 0) {
console.log(`⚠️ Issues found:\n${issues.map(i => `- ${i}`).join('\n')}`)
}
Phase 3: Serial Task Execution
Step 3.1: Execute Tasks Sequentially
const executionLog = []
const taskResults = new Map()
for (const task of executionOrder) {
console.log(`\n📋 Executing: ${task.id} - ${task.title}`)
const eventRecord = {
timestamp: getUtc8ISOString(),
task_id: task.id,
task_title: task.title,
status: 'in_progress',
notes: []
}
try {
// Load context from previous tasks
const priorOutputs = executionOrder
.slice(0, executionOrder.indexOf(task))
.map(t => taskResults.get(t.id))
.filter(Boolean)
const context = {
task: task,
prior_outputs: priorOutputs,
plan_source: planPath
}
// Execute task via Codex CLI
if (dryRun) {
console.log(`[DRY RUN] ${task.id}`)
eventRecord.status = 'completed'
eventRecord.notes.push('Dry run - no changes made')
} else {
await executeTaskViaCLI(task, context)
eventRecord.status = 'completed'
// Auto-commit if enabled
if (autoCommit) {
commitTask(task)
eventRecord.notes.push(`✅ Committed: ${task.id}`)
}
}
} catch (error) {
eventRecord.status = 'failed'
eventRecord.error = error.message
eventRecord.notes.push(`❌ Error: ${error.message}`)
console.log(`❌ Failed: ${task.id}`)
}
executionLog.push(eventRecord)
updateExecutionEvents(eventsPath, executionLog)
updateExecutionMd(executionPath, task, eventRecord)
}
Step 3.2: Execute Task via CLI
CLI Call (synchronous):
ccw cli -p "
PURPOSE: Execute task '${task.id}: ${task.title}' from plan
Success: Task completed as specified in plan
TASK DETAILS:
- ID: ${task.id}
- Title: ${task.title}
- Description: ${task.description}
- Complexity: ${task.complexity}
- Estimated Effort: ${task.effort}
REQUIRED CHANGES:
${task.files_to_modify?.map(f => `- \`${f.path}\`: ${f.summary}`).join('\n')}
PRIOR CONTEXT:
${priorOutputs.map(p => `- ${p.task_id}: ${p.notes.join('; ')}`).join('\n')}
TASK ACTIONS:
${task.actions?.map((a, i) => `${i+1}. ${a}`).join('\n')}
MODE: write
CONTEXT: @**/* | Plan Source: ${planPath} | Task: ${task.id}
EXPECTED:
- Modifications implemented as specified
- Code follows project conventions
- No test failures introduced
- All required files updated
CONSTRAINTS: Exactly as specified in plan | No additional scope
" --tool codex --mode write
Step 3.3: Track Progress
function updateExecutionEvents(eventsPath, log) {
const eventsMd = `# 执行日志
**Session**: ${sessionId}
**更新**: ${getUtc8ISOString()}
---
## 事件时间线
${log.map((e, i) => `
### 事件 ${i+1}: ${e.task_id}
**时间**: ${e.timestamp}
**任务**: ${e.task_title}
**状态**: ${e.status === 'completed' ? '✅' : e.status === 'failed' ? '❌' : '⏳'}
**笔记**:
${e.notes.map(n => `- ${n}`).join('\n')}
${e.error ? `**错误**: ${e.error}` : ''}
`).join('\n')}
---
## 统计
- **总数**: ${log.length}
- **完成**: ${log.filter(e => e.status === 'completed').length}
- **失败**: ${log.filter(e => e.status === 'failed').length}
- **进行中**: ${log.filter(e => e.status === 'in_progress').length}
`
Write(eventsPath, eventsMd)
}
function updateExecutionMd(mdPath, task, record) {
const content = Read(mdPath)
// Update task status in table
const updated = content.replace(
new RegExp(`\\| ${task.id} \\|.*\\| ⏳ \\|`),
`| ${task.id} | ... | ... | ... | ${record.status === 'completed' ? '✅' : '❌'} |`
)
Write(mdPath, updated)
}
Phase 4: Completion
Step 4.1: Generate Summary
const completed = executionLog.filter(e => e.status === 'completed').length
const failed = executionLog.filter(e => e.status === 'failed').length
const summary = `
# 执行完成
**Session**: ${sessionId}
**完成时间**: ${getUtc8ISOString()}
## 结果
| 指标 | 数值 |
|------|------|
| 总任务 | ${executionLog.length} |
| 成功 | ${completed} ✅ |
| 失败 | ${failed} ❌ |
| 成功率 | ${Math.round(completed / executionLog.length * 100)}% |
## 后续步骤
${failed > 0 ? `
### ❌ 修复失败的任务
\`\`\`bash
# 检查失败详情
cat ${eventsPath}
# 重新执行失败任务
${executionLog.filter(e => e.status === 'failed').map(e => `# ${e.task_id}`).join('\n')}
\`\`\`
` : `
### ✅ 执行完成
所有任务已成功完成!
`}
## 提交日志
${executionLog.filter(e => e.notes.some(n => n.includes('Committed'))).map(e => `- ${e.task_id}: ✅`).join('\n')}
`
Write(executionPath, summary)
Step 4.2: Report Results
console.log(`
✅ 执行完成: ${sessionId}
成功: ${completed}/${executionLog.length}
${failed > 0 ? `失败: ${failed}` : '无失败'}
📁 详情: ${eventsPath}
`)
Configuration
Task Format Detection
Supports multiple plan formats:
| Format | Source | Parser |
|---|---|---|
| JSON | lite-plan, collaborative-plan | parsePlanJson() |
| Markdown | IMPL_PLAN.md, plan-note.md | parsePlanMarkdown() |
| JSON synthesis | Brainstorm session | convertSynthesisToTasks() |
| JSON conclusions | Analysis session | convertConclusionsToTasks() |
Auto-Commit Format
Conventional Commits:
{type}({scope}): {description}
{task_id}: {task_title}
Files: {list of modified files}
Error Handling
| Error | Resolution |
|---|---|
| Plan not found | Use explicit --plan flag or check .workflow/ |
| Unsupported format | Verify plan file format matches supported types |
| Task execution fails | Check execution-events.md for details |
| Dependency missing | Verify plan completeness |
Execution Modes
| Mode | Behavior |
|---|---|
| Normal | Execute tasks sequentially, auto-commit disabled |
| --auto-commit | Execute + commit each task |
| --dry-run | Simulate execution, no changes |
Usage
# Load and execute plan
PLAN="path/to/plan.json" \
--auto-commit
# Dry run first
PLAN="path/to/plan.json" \
--dry-run
# Auto-detect plan
# (searches .workflow/ for recent plans)
Now execute unified-execute-with-file for: $PLAN