feat: Add orchestrator template and roles for executor and planner

- Created a new orchestrator template for Codex skill design, detailing structure and execution phases.
- Introduced the executor role with responsibilities for task execution, including routing to backends and handling implementation.
- Added the planner role for requirement breakdown, issue creation, and task dispatching, ensuring a structured planning process.
This commit is contained in:
catlog22
2026-02-16 00:17:15 +08:00
parent dc03862ca7
commit a4fff6a591
36 changed files with 4168 additions and 2589 deletions

View File

@@ -0,0 +1,353 @@
---
name: codex-skill-designer
description: Meta-skill for designing Codex-native skills with subagent orchestration (spawn_agent/wait/send_input/close_agent). Supports new skill creation and Claude→Codex conversion. Triggers on "design codex skill", "create codex skill", "codex skill designer", "convert to codex".
allowed-tools: Task, AskUserQuestion, TodoWrite, Read, Write, Edit, Bash, Glob, Grep
---
# Codex Skill Designer
Meta-skill for creating Codex-native skills that use the subagent API (`spawn_agent`/`wait`/`send_input`/`close_agent`). Generates complete skill packages with orchestrator coordination and agent role definitions.
## Architecture Overview
```
┌──────────────────────────────────────────────────────────────┐
│ Codex Skill Designer │
│ → Analyze requirements → Design orchestrator → Design agents│
└───────────────┬──────────────────────────────────────────────┘
┌───────────┼───────────┬───────────┐
↓ ↓ ↓ ↓
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ Phase 1 │ │ Phase 2 │ │ Phase 3 │ │ Phase 4 │
│ Require │ │ Orch │ │ Agent │ │ Valid │
│ Analysis│ │ Design │ │ Design │ │ & Integ │
└─────────┘ └─────────┘ └─────────┘ └─────────┘
↓ ↓ ↓ ↓
codexSkill orchestrator agents/ Complete
Config .md generated *.md skill pkg
```
## Target Output Structure
The skill this meta-skill produces follows this structure:
### Mode A: Structured Skill Package (multi-agent orchestration)
```
.codex/skills/{skill-name}/
├── orchestrator.md # Main Codex orchestrator
│ ├── Frontmatter (name, description)
│ ├── Architecture (spawn/wait/close flow)
│ ├── Agent Registry (role → path mapping)
│ ├── Phase Execution (spawn_agent patterns)
│ ├── Result Aggregation (wait + merge)
│ └── Lifecycle Management (close_agent cleanup)
├── agents/ # Skill-specific agent definitions
│ ├── {agent-1}.md # → deploy to ~/.codex/agents/
│ └── {agent-2}.md # → deploy to ~/.codex/agents/
└── phases/ # [Optional] Phase execution detail
├── 01-{phase}.md
└── 02-{phase}.md
```
### Mode B: Single Prompt (simple or self-contained skills)
```
~/.codex/prompts/{skill-name}.md # Self-contained Codex prompt
```
## Key Design Principles — Codex-Native Patterns
### Pattern 1: Explicit Lifecycle Management
Every agent has a complete lifecycle: `spawn_agent``wait` → [`send_input`] → `close_agent`.
```javascript
// Standard lifecycle
const agentId = spawn_agent({ message: taskMessage })
const result = wait({ ids: [agentId], timeout_ms: 300000 })
// [Optional: send_input for multi-round]
close_agent({ id: agentId })
```
**Key Rules**:
- Use `wait()` to get results, NEVER depend on `close_agent` return
- `close_agent` is irreversible — no further `wait`/`send_input` possible
- Delay `close_agent` until certain no more interaction is needed
### Pattern 2: Role Loading via Path Reference
Codex subagents cannot auto-load roles. Use MANDATORY FIRST STEPS pattern:
```javascript
spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/{agent-type}.md (MUST read first)
2. Read: .workflow/project-tech.json
3. Read: .workflow/project-guidelines.json
## TASK CONTEXT
${taskContext}
## DELIVERABLES
${deliverables}
`
})
```
### Pattern 3: Parallel Fan-out with Batch Wait
Multiple independent agents → batch `wait({ ids: [...] })`:
```javascript
const agentIds = tasks.map(task =>
spawn_agent({ message: buildTaskMessage(task) })
)
const results = wait({ ids: agentIds, timeout_ms: 600000 })
agentIds.forEach(id => close_agent({ id }))
```
### Pattern 4: Deep Interaction (send_input Multi-round)
Single agent, multi-phase with context preservation:
```javascript
const agent = spawn_agent({ message: explorePrompt })
const round1 = wait({ ids: [agent] })
// Continue with clarification
send_input({ id: agent, message: clarificationAnswers })
const round2 = wait({ ids: [agent] })
close_agent({ id: agent }) // Only after all rounds complete
```
### Pattern 5: Two-Phase Workflow (Clarify → Execute)
```
Phase 1: spawn_agent → output Open Questions only
Phase 2: send_input (answers) → output full solution
```
### Pattern 6: Structured Output Template
All agents produce uniform output:
```text
Summary:
- One-sentence completion status
Findings:
- Finding 1: specific description
- Finding 2: specific description
Proposed changes:
- File: path/to/file
- Change: specific modification
- Risk: potential impact
Tests:
- New/updated test cases needed
- Test commands to run
Open questions:
1. Question needing clarification
2. Question needing clarification
```
## Execution Flow
```
Phase 1: Requirements Analysis
└─ Ref: phases/01-requirements-analysis.md
├─ Input: text description / Claude skill / requirements doc / existing codex prompt
└─ Output: codexSkillConfig (agents, phases, patterns, interaction model)
Phase 2: Orchestrator Design
└─ Ref: phases/02-orchestrator-design.md
├─ Input: codexSkillConfig
└─ Output: .codex/skills/{name}/orchestrator.md (or ~/.codex/prompts/{name}.md)
Phase 3: Agent Design
└─ Ref: phases/03-agent-design.md
├─ Input: codexSkillConfig + source content
└─ Output: .codex/skills/{name}/agents/*.md + optional phases/*.md
Phase 4: Validation & Delivery
└─ Ref: phases/04-validation.md
└─ Output: Validated skill package + deployment instructions
```
**Phase Reference Documents** (read on-demand when phase executes):
| Phase | Document | Purpose |
|-------|----------|---------|
| 1 | [phases/01-requirements-analysis.md](phases/01-requirements-analysis.md) | Analyze inputs, determine skill config |
| 2 | [phases/02-orchestrator-design.md](phases/02-orchestrator-design.md) | Generate Codex-native orchestrator |
| 3 | [phases/03-agent-design.md](phases/03-agent-design.md) | Generate agent roles & command patterns |
| 4 | [phases/04-validation.md](phases/04-validation.md) | Validate structure, patterns, quality |
## Input Sources
| Source | Description | Example |
|--------|-------------|---------|
| **Text description** | User describes desired Codex skill | "Create a 3-agent code review skill for Codex" |
| **Claude skill** | Convert existing Claude skill to Codex | `.claude/skills/workflow-plan/SKILL.md` |
| **Requirements doc** | Structured requirements file | `requirements.md` with agents/phases/outputs |
| **Existing Codex prompt** | Refactor/enhance a Codex prompt | `~/.codex/prompts/plan.md` |
## Conversion Mode (Claude → Codex)
When source is a Claude skill, apply conversion rules:
| Claude Pattern | Codex Equivalent |
|----------------|-----------------|
| `Task({ subagent_type, prompt })` | `spawn_agent({ message })` + `wait()` |
| `Task({ run_in_background: false })` | `spawn_agent()` + immediate `wait()` |
| `Task({ resume: agentId })` | `send_input({ id: agentId })` |
| `TaskOutput({ task_id, block })` | `wait({ ids: [id], timeout_ms })` |
| Automatic agent cleanup | Explicit `close_agent({ id })` |
| `subagent_type` auto-loads role | MANDATORY FIRST STEPS role path |
| Multiple parallel `Task()` calls | Multiple `spawn_agent()` + batch `wait({ ids })` |
**Full conversion spec**: Ref: specs/conversion-rules.md
## Data Flow
```
Phase 1 → codexSkillConfig:
{
name, description, outputMode (structured|single),
agents: [{ name, role_file, responsibility, patterns }],
phases: [{ name, agents_involved, interaction_model }],
parallelSplits: [{ strategy, agents }],
conversionSource: null | { type, path }
}
Phase 2 → orchestrator.md:
Generated Codex orchestrator with spawn/wait/close patterns
Phase 3 → agents/*.md:
Per-agent role definitions with Codex-native conventions
Phase 4 → validated package:
Structural completeness + pattern compliance + quality score
```
## TodoWrite Pattern
```
Phase starts:
→ Sub-tasks ATTACHED to TodoWrite (in_progress + pending)
→ Designer executes sub-tasks sequentially
Phase ends:
→ Sub-tasks COLLAPSED back to high-level summary (completed)
→ Next phase begins
```
## Interactive Preference Collection
Collect preferences via AskUserQuestion before dispatching to phases:
```javascript
const prefResponse = AskUserQuestion({
questions: [
{
question: "What is the output mode for this Codex skill?",
header: "Output Mode",
multiSelect: false,
options: [
{ label: "Structured Package (Recommended)", description: "Multi-file: orchestrator.md + agents/*.md + phases/*.md" },
{ label: "Single Prompt", description: "Self-contained ~/.codex/prompts/{name}.md" }
]
},
{
question: "What is the input source?",
header: "Input Source",
multiSelect: false,
options: [
{ label: "Text Description", description: "Describe the desired Codex skill in natural language" },
{ label: "Claude Skill (Convert)", description: "Convert existing .claude/skills/ to Codex-native" },
{ label: "Requirements Doc", description: "Structured requirements file" },
{ label: "Existing Codex Prompt", description: "Refactor/enhance existing ~/.codex/prompts/" }
]
}
]
})
const workflowPreferences = {
outputMode: prefResponse["Output Mode"].includes("Structured") ? "structured" : "single",
inputSource: prefResponse["Input Source"]
}
```
## Specification Documents
Read specs on-demand for pattern guidance:
| Spec | Document | Purpose |
|------|----------|---------|
| Agent Patterns | [specs/codex-agent-patterns.md](specs/codex-agent-patterns.md) | Core Codex subagent API patterns |
| Conversion Rules | [specs/conversion-rules.md](specs/conversion-rules.md) | Claude → Codex mapping rules |
| Quality Standards | [specs/quality-standards.md](specs/quality-standards.md) | Quality gates & validation criteria |
## Generation Templates
Apply templates during generation:
| Template | Document | Purpose |
|----------|----------|---------|
| Orchestrator | [templates/orchestrator-template.md](templates/orchestrator-template.md) | Codex orchestrator output template |
| Agent Role | [templates/agent-role-template.md](templates/agent-role-template.md) | Agent role definition template |
| Command Patterns | [templates/command-pattern-template.md](templates/command-pattern-template.md) | Pre-built Codex command patterns |
## Error Handling
| Scenario | Resolution |
|----------|------------|
| Source Claude skill has unsupported patterns | Log warning, provide manual conversion guidance |
| Agent role file path conflict | Append skill-name prefix to agent file |
| Output directory exists | Ask user: overwrite or new name |
| Validation score < 70% | Block delivery, report issues |
## Post-Phase Updates
After each phase, update accumulated state:
```javascript
// After Phase 1
codexSkillConfig = { ...requirements analysis output }
// After Phase 2
generatedFiles.orchestrator = "path/to/orchestrator.md"
// After Phase 3
generatedFiles.agents = ["path/to/agent1.md", "path/to/agent2.md"]
generatedFiles.phases = ["path/to/phase1.md"] // optional
// After Phase 4
validationResult = { score, issues, passed }
```
## Coordinator Checklist
### Pre-Phase Actions
- [ ] Verify input source exists and is readable
- [ ] Collect preferences via AskUserQuestion
- [ ] Read relevant specs based on input source
### Post-Phase Actions
- [ ] Verify phase output completeness
- [ ] Update TodoWrite status
- [ ] Pass accumulated state to next phase
### Final Delivery
- [ ] All generated files written to target directory
- [ ] Deployment instructions provided
- [ ] Agent files include `~/.codex/agents/` deployment paths

View File

@@ -0,0 +1,167 @@
# Phase 1: Requirements Analysis
Analyze input source and extract Codex skill configuration.
## Objective
- Parse input source (text / Claude skill / requirements doc / Codex prompt)
- Identify agents, phases, interaction patterns
- Determine output mode (structured package vs single prompt)
- Produce codexSkillConfig for downstream phases
## Pre-Requisites
Read specification documents based on input source:
- **Always**: Read `specs/codex-agent-patterns.md` for available patterns
- **Claude conversion**: Also read `specs/conversion-rules.md`
- **Quality reference**: Read `specs/quality-standards.md` for target criteria
## Execution
### Step 1.1: Input Source Detection
```javascript
// Determine input type from workflowPreferences
const inputSource = workflowPreferences.inputSource
if (inputSource.includes("Claude Skill")) {
// Read source Claude skill
const sourceSkillPath = AskUserQuestion({
questions: [{
question: "Path to the Claude skill to convert?",
header: "Skill Path",
multiSelect: false,
options: [
{ label: "Browse", description: "I'll provide the path" }
]
}]
})
// Read SKILL.md + phases/*.md from source
const skillContent = Read(sourceSkillPath)
const phaseFiles = Glob(`${sourceSkillDir}/phases/*.md`)
} else if (inputSource.includes("Text Description")) {
// Collect description via user interaction
} else if (inputSource.includes("Requirements Doc")) {
// Read requirements file
} else if (inputSource.includes("Existing Codex")) {
// Read existing Codex prompt for refactoring
}
```
### Step 1.2: Skill Structure Extraction
For each input type, extract:
**From Text Description**:
```javascript
const codexSkillConfig = {
name: extractSkillName(userDescription),
description: extractDescription(userDescription),
outputMode: workflowPreferences.outputMode,
agents: inferAgents(userDescription),
phases: inferPhases(userDescription),
parallelSplits: inferParallelism(userDescription),
interactionModel: inferInteractionModel(userDescription),
conversionSource: null
}
```
**From Claude Skill** (conversion):
```javascript
// Parse Claude SKILL.md
const claudeConfig = {
phases: extractPhases(skillContent),
agents: extractTaskCalls(skillContent), // Find Task() invocations
dataFlow: extractDataFlow(skillContent),
todoPattern: extractTodoPattern(skillContent),
resumePatterns: findResumePatterns(skillContent) // For send_input mapping
}
const codexSkillConfig = {
name: claudeConfig.name,
description: claudeConfig.description,
outputMode: workflowPreferences.outputMode,
agents: claudeConfig.agents.map(a => ({
name: a.subagent_type,
role_file: mapToCodexRolePath(a.subagent_type),
responsibility: a.description,
patterns: determinePatterns(a)
})),
phases: claudeConfig.phases.map(p => ({
name: p.name,
agents_involved: p.agentCalls.map(a => a.subagent_type),
interaction_model: hasResume(p) ? "deep_interaction" : "standard"
})),
parallelSplits: detectParallelPatterns(claudeConfig),
conversionSource: { type: "claude_skill", path: sourceSkillPath }
}
```
### Step 1.3: Agent Inventory Check
Verify agent roles exist in `~/.codex/agents/`:
```javascript
const existingAgents = Glob("~/.codex/agents/*.md")
const requiredAgents = codexSkillConfig.agents.map(a => a.role_file)
const missingAgents = requiredAgents.filter(r =>
!existingAgents.includes(r)
)
if (missingAgents.length > 0) {
// Mark as "needs new agent role definition"
codexSkillConfig.newAgentDefinitions = missingAgents
}
```
### Step 1.4: Interaction Model Selection
Based on agent relationships, select interaction patterns:
| Pattern | Condition | Result |
|---------|-----------|--------|
| **Standard** | Single agent, single task | `spawn → wait → close` |
| **Parallel Fan-out** | Multiple independent agents | `spawn[] → batch wait → close[]` |
| **Deep Interaction** | Multi-phase with context | `spawn → wait → send_input → wait → close` |
| **Two-Phase** | Needs clarification first | `spawn(clarify) → wait → send_input(answers) → wait → close` |
| **Pipeline** | Sequential agent chain | `spawn(A) → wait → spawn(B, with A result) → wait → close` |
```javascript
codexSkillConfig.phases.forEach(phase => {
if (phase.agents_involved.length > 1) {
phase.interaction_model = "parallel_fanout"
} else if (phase.interaction_model === "deep_interaction") {
// Already set from resume pattern detection
} else {
phase.interaction_model = "standard"
}
})
```
### Step 1.5: User Confirmation
Present extracted configuration for user review:
```javascript
AskUserQuestion({
questions: [{
question: `Skill "${codexSkillConfig.name}" will have ${codexSkillConfig.agents.length} agent(s) and ${codexSkillConfig.phases.length} phase(s). ${codexSkillConfig.newAgentDefinitions?.length || 0} new agent definitions needed. Proceed?`,
header: "Confirm",
multiSelect: false,
options: [
{ label: "Proceed", description: "Generate Codex skill package" },
{ label: "Adjust", description: "Modify configuration first" }
]
}]
})
```
## Output
- **Variable**: `codexSkillConfig` — complete skill configuration
- **TodoWrite**: Mark Phase 1 completed, Phase 2 in_progress
## Next Phase
Return to orchestrator, then auto-continue to [Phase 2: Orchestrator Design](02-orchestrator-design.md).

View File

@@ -0,0 +1,291 @@
# Phase 2: Orchestrator Design
Generate the main Codex orchestrator document using codexSkillConfig.
## Objective
- Generate orchestrator.md (structured mode) or {skill-name}.md (single mode)
- Apply Codex-native patterns: spawn_agent, wait, send_input, close_agent
- Include agent registry, phase execution, lifecycle management
- Preserve source content faithfully when converting from Claude
## Pre-Requisites
- Read `templates/orchestrator-template.md` for output structure
- Read `specs/codex-agent-patterns.md` for pattern reference
- If converting: Read `specs/conversion-rules.md` for mapping rules
## Execution
### Step 2.1: Determine Output Path
```javascript
const outputPath = codexSkillConfig.outputMode === "structured"
? `.codex/skills/${codexSkillConfig.name}/orchestrator.md`
: `~/.codex/prompts/${codexSkillConfig.name}.md`
```
### Step 2.2: Generate Frontmatter
```markdown
---
name: {{skill_name}}
description: {{description}}
agents: {{agent_count}}
phases: {{phase_count}}
output_template: structured # or "open_questions" for clarification-first
---
```
### Step 2.3: Generate Architecture Diagram
Map phases and agents to ASCII flow:
```javascript
// For parallel fan-out:
const diagram = `
┌──────────────────────────────────────────┐
${codexSkillConfig.name} Orchestrator │
└──────────────┬───────────────────────────┘
┌───────────┼───────────┬────────────┐
↓ ↓ ↓ ↓
┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐
│Agent1│ │Agent2│ │Agent3│ │AgentN│
│spawn │ │spawn │ │spawn │ │spawn │
└──┬───┘ └──┬───┘ └──┬───┘ └──┬───┘
└──────────┼───────────┘ │
↓ │
batch wait({ids}) ←──────────┘
Aggregate Results
close_agent (all)
`
```
### Step 2.4: Generate Agent Registry
```javascript
const agentRegistry = codexSkillConfig.agents.map(agent => ({
name: agent.name,
role_file: agent.role_file, // e.g., ~/.codex/agents/cli-explore-agent.md
responsibility: agent.responsibility,
is_new: agent.role_file.startsWith('.codex/skills/') // skill-specific new agent
}))
```
Output as registry table in orchestrator:
```markdown
## Agent Registry
| Agent | Role File | Responsibility | Status |
|-------|-----------|----------------|--------|
{{#each agents}}
| `{{name}}` | `{{role_file}}` | {{responsibility}} | {{#if is_new}}NEW{{else}}existing{{/if}} |
{{/each}}
```
### Step 2.5: Generate Phase Execution Blocks
For each phase in codexSkillConfig.phases, generate the appropriate pattern:
**Standard Pattern** (single agent, single task):
```javascript
// Phase N: {{phase.name}}
const agentId = spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: {{agent.role_file}} (MUST read first)
2. Read: .workflow/project-tech.json
3. Read: .workflow/project-guidelines.json
---
Goal: {{phase.goal}}
Scope:
- 可做: {{phase.scope.include}}
- 不可做: {{phase.scope.exclude}}
Context:
{{phase.context}}
Deliverables:
- {{phase.deliverables}}
Quality bar:
- {{phase.quality_criteria}}
`
})
const result = wait({ ids: [agentId], timeout_ms: {{phase.timeout_ms || 300000}} })
close_agent({ id: agentId })
```
**Parallel Fan-out Pattern** (multiple independent agents):
```javascript
// Phase N: {{phase.name}} (Parallel)
const agentIds = {{phase.agents}}.map(agentConfig => {
return spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ${agentConfig.role_file} (MUST read first)
2. Read: .workflow/project-tech.json
---
Goal: ${agentConfig.specific_goal}
Scope: ${agentConfig.scope}
Deliverables: ${agentConfig.deliverables}
`
})
})
// Batch wait for all agents
const results = wait({
ids: agentIds,
timeout_ms: {{phase.timeout_ms || 600000}}
})
// Handle timeout
if (results.timed_out) {
const completed = agentIds.filter(id => results.status[id].completed)
const pending = agentIds.filter(id => !results.status[id].completed)
// Decision: continue waiting or use partial results
}
// Aggregate results
const aggregated = agentIds.map(id => results.status[id].completed)
// Cleanup
agentIds.forEach(id => close_agent({ id }))
```
**Deep Interaction Pattern** (multi-round with send_input):
```javascript
// Phase N: {{phase.name}} (Deep Interaction)
const agent = spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: {{agent.role_file}} (MUST read first)
---
### Phase A: {{phase.initial_goal}}
Goal: {{phase.initial_goal}}
Output: Findings + Open Questions (if any)
Output format for questions:
\`\`\`
CLARIFICATION_NEEDED:
Q1: [question] | Options: [A, B, C] | Recommended: [A]
\`\`\`
### Phase B: {{phase.followup_goal}}
Trigger: Receive answers via send_input
Output: Complete deliverable
`
})
// Round 1: Initial exploration
const round1 = wait({ ids: [agent], timeout_ms: {{phase.timeout_ms || 600000}} })
// Check for clarification needs
const needsClarification = round1.status[agent].completed.includes('CLARIFICATION_NEEDED')
if (needsClarification) {
// Collect user answers (orchestrator responsibility)
const answers = collectUserAnswers(round1)
// Continue interaction
send_input({
id: agent,
message: `
## CLARIFICATION ANSWERS
${answers}
## NEXT STEP
Proceed with Phase B: {{phase.followup_goal}}
`
})
const round2 = wait({ ids: [agent], timeout_ms: {{phase.timeout_ms || 900000}} })
}
close_agent({ id: agent })
```
**Pipeline Pattern** (sequential agent chain):
```javascript
// Phase N: {{phase.name}} (Pipeline)
// Stage 1
const agent1 = spawn_agent({ message: stage1Prompt })
const result1 = wait({ ids: [agent1] })
close_agent({ id: agent1 })
// Stage 2 (uses Stage 1 output)
const agent2 = spawn_agent({
message: `
## TASK ASSIGNMENT
...
## PREVIOUS STAGE OUTPUT
${result1.status[agent1].completed}
...
`
})
const result2 = wait({ ids: [agent2] })
close_agent({ id: agent2 })
```
### Step 2.6: Generate Lifecycle Management Section
```markdown
## Lifecycle Management
### Timeout Handling
| Timeout | Action |
|---------|--------|
| Agent completes within timeout | Process result, close_agent |
| Agent times out (partial) | Option 1: continue wait / Option 2: send_input to urge convergence / Option 3: close_agent and use partial |
| All agents timeout | Log warning, retry with extended timeout or abort |
### Cleanup Protocol
After ALL phases complete or on error:
1. Verify all agent IDs have been closed
2. Report any agents still running
3. Force close remaining agents
\`\`\`javascript
const allAgentIds = [] // accumulated during execution
allAgentIds.forEach(id => {
try { close_agent({ id }) } catch { /* already closed */ }
})
\`\`\`
```
### Step 2.7: Write Orchestrator File
Apply template from `templates/orchestrator-template.md` with generated content.
Write the complete orchestrator to the output path.
## Output
- **File**: `{outputPath}` — generated Codex orchestrator
- **Variable**: `generatedFiles.orchestrator` = outputPath
- **TodoWrite**: Mark Phase 2 completed, Phase 3 in_progress
## Next Phase
Return to orchestrator, then auto-continue to [Phase 3: Agent Design](03-agent-design.md).

View File

@@ -0,0 +1,277 @@
# Phase 3: Agent Design
Generate agent role definitions and optional phase execution detail files.
## Objective
- Generate agent role files for `~/.codex/agents/` or `.codex/skills/{name}/agents/`
- Apply Codex-native conventions (MANDATORY FIRST STEPS, structured output)
- Preserve source content when converting from Claude
- Generate optional phase detail files for complex orchestrations
## Pre-Requisites
- Read `templates/agent-role-template.md` for role file structure
- Read `templates/command-pattern-template.md` for pre-built command patterns
- Read `specs/codex-agent-patterns.md` for API patterns
## Execution
### Step 3.1: Identify Agents to Generate
```javascript
// From codexSkillConfig
const agentsToGenerate = codexSkillConfig.agents.filter(a =>
a.role_file.startsWith('.codex/skills/') // new skill-specific agents
|| codexSkillConfig.newAgentDefinitions?.includes(a.role_file)
)
// Existing agents (already in ~/.codex/agents/) — skip generation
const existingAgents = codexSkillConfig.agents.filter(a =>
!agentsToGenerate.includes(a)
)
```
### Step 3.2: Generate Agent Role Files
For each agent to generate, apply the agent-role-template:
```javascript
for (const agent of agentsToGenerate) {
const roleContent = applyTemplate('templates/agent-role-template.md', {
agent_name: agent.name,
description: agent.responsibility,
capabilities: agent.capabilities || inferCapabilities(agent),
execution_process: agent.workflow || inferWorkflow(agent),
output_format: codexSkillConfig.outputTemplate || "structured",
key_reminders: generateReminders(agent)
})
const outputPath = agent.role_file.startsWith('~/')
? agent.role_file
: `.codex/skills/${codexSkillConfig.name}/agents/${agent.name}.md`
Write(outputPath, roleContent)
generatedFiles.agents.push(outputPath)
}
```
### Step 3.3: Agent Role File Content Structure
Each generated agent role file follows this structure:
```markdown
---
name: {{agent_name}}
description: |
{{description}}
color: {{color}}
skill: {{parent_skill_name}}
---
# {{agent_display_name}}
{{description_paragraph}}
## Core Capabilities
1. **{{capability_1}}**: {{description}}
2. **{{capability_2}}**: {{description}}
3. **{{capability_3}}**: {{description}}
## Execution Process
### Step 1: Context Loading
- Read role-specific configuration files
- Load project context (.workflow/project-tech.json)
- Understand task scope from TASK ASSIGNMENT
### Step 2: {{primary_action}}
{{primary_action_detail}}
### Step 3: {{secondary_action}}
{{secondary_action_detail}}
### Step 4: Output Delivery
Produce structured output following the template:
\`\`\`text
Summary:
- {{summary_format}}
Findings:
- {{findings_format}}
Proposed changes:
- {{changes_format}}
Tests:
- {{tests_format}}
Open questions:
- {{questions_format}}
\`\`\`
## Key Reminders
**ALWAYS**:
- Read role definition file as FIRST action
- Follow structured output template
- Stay within assigned scope
- Report open questions instead of guessing
**NEVER**:
- Modify files outside assigned scope
- Skip role definition loading
- Produce unstructured output
- Make assumptions about unclear requirements
```
### Step 3.4: Conversion from Claude Agent Definitions
When converting from Claude skill, extract agent behavior from:
1. **Task() prompts**: The `prompt` parameter contains the agent's task instructions
2. **Phase files**: Phase execution detail contains the full agent interaction
3. **subagent_type**: Maps to existing `~/.codex/agents/` roles
```javascript
// For each Task() call found in Claude source
for (const taskCall of claudeConfig.agents) {
const existingRole = roleMapping[taskCall.subagent_type]
if (existingRole) {
// Map to existing Codex agent — no new file needed
// Just reference in orchestrator's MANDATORY FIRST STEPS
codexSkillConfig.agents.push({
name: taskCall.subagent_type,
role_file: `~/.codex/agents/${taskCall.subagent_type}.md`,
responsibility: taskCall.description,
is_new: false
})
} else {
// Extract agent behavior from Claude prompt and create new role
const newRole = extractRoleFromPrompt(taskCall.prompt)
// Generate new role file
}
}
```
### Step 3.5: Command Pattern Selection
For agents that need specific command patterns, select from pre-built templates:
| Pattern | Use When | Template |
|---------|----------|----------|
| **Explore** | Agent needs codebase exploration | Parallel fan-out spawn_agent |
| **Analyze** | Agent performs multi-perspective analysis | Parallel spawn + merge |
| **Implement** | Agent writes code | Sequential spawn + validate |
| **Validate** | Agent runs tests | Iterative spawn + send_input fix cycle |
| **Review** | Agent reviews code/artifacts | Parallel spawn + aggregate |
| **Deep Interact** | Agent needs multi-round conversation | spawn + wait + send_input loop |
| **Two-Phase** | Agent needs clarification first | spawn(clarify) + send_input(execute) |
Read `templates/command-pattern-template.md` for full pattern implementations.
### Step 3.6: Generate Phase Detail Files (Optional)
For structured mode with complex phases, generate phase detail files:
```javascript
if (codexSkillConfig.outputMode === "structured") {
for (const phase of codexSkillConfig.phases) {
if (phase.complexity === "high" || phase.agents_involved.length > 2) {
const phaseContent = generatePhaseDetail(phase, codexSkillConfig)
const phasePath = `.codex/skills/${codexSkillConfig.name}/phases/${phase.index}-${phase.slug}.md`
Write(phasePath, phaseContent)
generatedFiles.phases.push(phasePath)
}
}
}
```
Phase detail structure:
```markdown
# Phase {{N}}: {{Phase Name}}
{{One-sentence description}}
## Agents Involved
| Agent | Role | Interaction Model |
|-------|------|-------------------|
{{#each phase.agents}}
| {{name}} | {{role_file}} | {{interaction_model}} |
{{/each}}
## Execution
### spawn_agent Configuration
\`\`\`javascript
const agent = spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: {{role_file}} (MUST read first)
...
---
Goal: {{goal}}
Scope: {{scope}}
Context: {{context}}
Deliverables: {{deliverables}}
Quality bar: {{quality}}
`
})
\`\`\`
### Wait & Result Processing
\`\`\`javascript
const result = wait({ ids: [agent], timeout_ms: {{timeout}} })
// Process: {{result_processing}}
close_agent({ id: agent })
\`\`\`
## Output
- **Result**: {{output_description}}
- **Passed to**: Phase {{N+1}}
```
### Step 3.7: Deployment Mapping
Generate deployment instructions:
```javascript
const deploymentMap = {
// Existing agents — no action needed
existing: existingAgents.map(a => ({
name: a.name,
path: a.role_file,
action: "already deployed"
})),
// New agents — need deployment
new: agentsToGenerate.map(a => ({
name: a.name,
sourcePath: `.codex/skills/${codexSkillConfig.name}/agents/${a.name}.md`,
targetPath: `~/.codex/agents/${a.name}.md`,
action: "copy to ~/.codex/agents/"
}))
}
```
## Output
- **Files**: `generatedFiles.agents[]` — agent role files
- **Files**: `generatedFiles.phases[]` — optional phase detail files
- **Variable**: `deploymentMap` — deployment instructions
- **TodoWrite**: Mark Phase 3 completed, Phase 4 in_progress
## Next Phase
Return to orchestrator, then auto-continue to [Phase 4: Validation & Delivery](04-validation.md).

View File

@@ -0,0 +1,254 @@
# Phase 4: Validation & Delivery
Validate the generated Codex skill package and deliver to target location.
## Objective
- Verify structural completeness of all generated files
- Validate Codex pattern compliance (lifecycle, role loading, output format)
- Score quality against standards
- Deploy to target location with instructions
## Pre-Requisites
- Read `specs/quality-standards.md` for validation criteria
- Access `generatedFiles` from previous phases
- Access `codexSkillConfig` for expected structure
## Execution
### Step 4.1: Structural Completeness Check
```javascript
const structuralChecks = {
// Orchestrator exists
orchestrator: {
exists: fileExists(generatedFiles.orchestrator),
hasFrontmatter: checkFrontmatter(generatedFiles.orchestrator),
hasArchitecture: checkSection(generatedFiles.orchestrator, "Architecture"),
hasAgentRegistry: checkSection(generatedFiles.orchestrator, "Agent Registry"),
hasPhaseExecution: checkSection(generatedFiles.orchestrator, "Phase"),
hasLifecycleManagement: checkSection(generatedFiles.orchestrator, "Lifecycle"),
hasTimeoutHandling: checkSection(generatedFiles.orchestrator, "Timeout"),
passed: 0, total: 7
},
// Agent files exist and are well-formed
agents: codexSkillConfig.agents.map(agent => ({
name: agent.name,
exists: fileExists(agent.role_file) || fileExists(generatedFiles.agents.find(f => f.includes(agent.name))),
hasFrontmatter: checkFrontmatter(agentFile),
hasCapabilities: checkSection(agentFile, "Core Capabilities"),
hasExecution: checkSection(agentFile, "Execution Process"),
hasReminders: checkSection(agentFile, "Key Reminders"),
passed: 0, total: 5
})),
// Phase files (if structured mode)
phases: generatedFiles.phases?.map(phasePath => ({
path: phasePath,
exists: fileExists(phasePath),
hasAgentTable: checkSection(phasePath, "Agents Involved"),
hasSpawnConfig: checkSection(phasePath, "spawn_agent"),
hasWaitProcessing: checkSection(phasePath, "Wait"),
passed: 0, total: 4
})) || []
}
// Count passes
let totalPassed = 0, totalChecks = 0
// ... count logic
```
### Step 4.2: Codex Pattern Compliance
Verify all Codex-native patterns are correctly applied:
```javascript
const patternChecks = {
// Lifecycle: every spawn has a close
lifecycle: {
spawnCount: countPattern(orchestratorContent, /spawn_agent/g),
closeCount: countPattern(orchestratorContent, /close_agent/g),
balanced: spawnCount <= closeCount, // close >= spawn (batch close is OK)
description: "Every spawn_agent must have matching close_agent"
},
// Role loading: MANDATORY FIRST STEPS present
roleLoading: {
hasPattern: orchestratorContent.includes("MANDATORY FIRST STEPS"),
allAgentsReferenced: codexSkillConfig.agents.every(a =>
orchestratorContent.includes(a.role_file)
),
usesPathNotInline: !orchestratorContent.includes("## ROLE DEFINITION"),
description: "Role files loaded via path reference, not inline content"
},
// Wait pattern: uses wait() not close_agent for results
waitPattern: {
usesWaitForResults: countPattern(orchestratorContent, /wait\(\s*\{/) > 0,
noCloseForResults: !hasPatternSequence(orchestratorContent, "close_agent", "result"),
description: "Results obtained via wait(), not close_agent"
},
// Batch wait: parallel agents use batch wait
batchWait: {
applicable: codexSkillConfig.parallelSplits?.length > 0,
usesBatchIds: orchestratorContent.includes("ids: [") ||
orchestratorContent.includes("ids: agentIds"),
description: "Parallel agents use batch wait({ ids: [...] })"
},
// Timeout handling: timeout_ms specified
timeout: {
hasTimeout: orchestratorContent.includes("timeout_ms"),
hasTimeoutHandling: orchestratorContent.includes("timed_out"),
description: "Timeout specified and timeout scenarios handled"
},
// Structured output: agents produce uniform output
structuredOutput: {
hasSummary: agentContents.every(c => c.includes("Summary:")),
hasDeliverables: agentContents.every(c => c.includes("Deliverables") || c.includes("Findings")),
description: "All agents produce structured output template"
},
// No Claude patterns: no Task(), no TaskOutput(), no resume
noClaudePatterns: {
noTask: !orchestratorContent.includes("Task("),
noTaskOutput: !orchestratorContent.includes("TaskOutput("),
noResume: !orchestratorContent.includes("resume:") && !orchestratorContent.includes("resume ="),
description: "No Claude-specific patterns remain"
}
}
const patternScore = calculatePatternScore(patternChecks)
```
### Step 4.3: Content Quality Check
```javascript
const qualityChecks = {
// Orchestrator quality
orchestratorQuality: {
hasDescription: orchestratorContent.length > 500,
hasCodeBlocks: countPattern(orchestratorContent, /```/g) >= 4,
hasErrorHandling: orchestratorContent.includes("Error") || orchestratorContent.includes("error"),
noPlaceholders: !orchestratorContent.includes("{{") || !orchestratorContent.includes("TODO"),
description: "Orchestrator is complete and production-ready"
},
// Agent quality
agentQuality: agentContents.map(content => ({
hasSubstantiveContent: content.length > 300,
hasActionableSteps: countPattern(content, /Step \d/g) >= 2,
hasOutputFormat: content.includes("Output") || content.includes("Deliverables"),
noPlaceholders: !content.includes("{{") || !content.includes("TODO")
})),
// Conversion quality (if applicable)
conversionQuality: codexSkillConfig.conversionSource ? {
allTasksConverted: true, // verify all Claude Task() calls are mapped
noLostFunctionality: true, // verify no features dropped
interactionPreserved: true // verify resume → send_input mapping
} : null
}
const qualityScore = calculateQualityScore(qualityChecks)
```
### Step 4.4: Quality Gate
```javascript
const overallScore = (
structuralScore * 0.30 +
patternScore * 0.40 +
qualityScore * 0.30
)
const verdict = overallScore >= 80 ? "PASS" :
overallScore >= 60 ? "REVIEW" : "FAIL"
```
| Verdict | Score | Action |
|---------|-------|--------|
| **PASS** | >= 80% | Deliver to target location |
| **REVIEW** | 60-79% | Report issues, ask user to proceed or fix |
| **FAIL** | < 60% | Block delivery, list critical issues |
### Step 4.5: Validation Report
```javascript
const validationReport = {
skill: codexSkillConfig.name,
outputMode: codexSkillConfig.outputMode,
scores: {
structural: structuralScore,
pattern: patternScore,
quality: qualityScore,
overall: overallScore
},
verdict: verdict,
issues: collectIssues(structuralChecks, patternChecks, qualityChecks),
generatedFiles: generatedFiles,
deploymentMap: deploymentMap
}
```
### Step 4.6: Delivery
If verdict is PASS or user approves REVIEW:
```javascript
// For structured mode — files already in .codex/skills/{name}/
// Report deployment instructions for agent files
const deploymentInstructions = `
## Deployment Instructions
### Generated Files
${generatedFiles.orchestrator}
${generatedFiles.agents.join('\n')}
${generatedFiles.phases?.join('\n') || '(no phase files)'}
### Agent Deployment
${deploymentMap.new.map(a =>
`Copy: ${a.sourcePath}${a.targetPath}`
).join('\n')}
### Existing Agents (no action needed)
${deploymentMap.existing.map(a =>
`${a.name}: ${a.path}`
).join('\n')}
### Usage
Invoke the generated orchestrator via Codex:
- Read the orchestrator.md and follow its phase execution
- Or register as a Codex prompt in ~/.codex/prompts/
### Validation Score
Overall: ${overallScore}% (${verdict})
- Structural: ${structuralScore}%
- Pattern Compliance: ${patternScore}%
- Content Quality: ${qualityScore}%
`
```
### Step 4.7: Final Summary to User
Present:
1. Generated file list with paths
2. Validation scores
3. Deployment instructions
4. Any issues or warnings
5. Next steps (e.g., "test the skill by running the orchestrator")
## Output
- **Report**: Validation report with scores
- **Deployment**: Instructions for agent file deployment
- **TodoWrite**: Mark Phase 4 completed
## Completion
Skill package generation complete. All files written and validated.

View File

@@ -0,0 +1,406 @@
# Codex Agent Patterns
Core Codex subagent API patterns reference for skill generation.
## Purpose
| Phase | Usage |
|-------|-------|
| Phase 0 | Read to understand available Codex patterns |
| Phase 2 | Reference when generating orchestrator patterns |
| Phase 3 | Reference when designing agent interactions |
---
## 1. API Reference
### 1.1 spawn_agent
Creates a new subagent with independent context.
```javascript
const agentId = spawn_agent({
message: "task message", // Required: task assignment
agent_type: "type" // Optional: preset baseline
})
// Returns: agent_id (string)
```
**Key Facts**:
- Each agent has isolated context (no shared state)
- `agent_type` selects preset behavior baseline
- Role definition must be loaded via MANDATORY FIRST STEPS
- Returns immediately — use `wait()` for results
### 1.2 wait
Retrieves results from one or more agents.
```javascript
const result = wait({
ids: [agentId1, agentId2], // Required: agent IDs to wait for
timeout_ms: 300000 // Optional: max wait time (ms)
})
// Returns: { timed_out: boolean, status: { [id]: { completed: string } } }
```
**Key Facts**:
- Primary result retrieval method (NOT close_agent)
- Supports batch wait for multiple agents
- `timed_out: true` means some agents haven't finished — can re-wait
- Can be called multiple times on same agent
### 1.3 send_input
Continues interaction with an active agent.
```javascript
send_input({
id: agentId, // Required: target agent
message: "follow-up", // Required: continuation message
interrupt: false // Optional: interrupt current processing
})
```
**Key Facts**:
- Agent must NOT be closed
- Preserves full conversation context
- Use for: clarification answers, phase transitions, iterative refinement
- `interrupt: true` — use with caution (stops current processing)
### 1.4 close_agent
Permanently terminates an agent.
```javascript
close_agent({ id: agentId })
```
**Key Facts**:
- Irreversible — no further wait/send_input possible
- Do NOT use to retrieve results (use wait instead)
- Delay until certain no more interaction needed
- Call for ALL agents at end of workflow (cleanup)
## 2. Interaction Patterns
### 2.1 Standard (Single Agent, Single Task)
```
spawn_agent → wait → close_agent
```
**Use When**: Simple, one-shot tasks with clear deliverables.
```javascript
const agent = spawn_agent({ message: taskPrompt })
const result = wait({ ids: [agent], timeout_ms: 300000 })
close_agent({ id: agent })
```
### 2.2 Parallel Fan-out (Multiple Independent Agents)
```
spawn_agent × N → batch wait({ ids: [...] }) → close_agent × N
```
**Use When**: Multiple independent tasks that can run concurrently.
```javascript
const agents = tasks.map(t => spawn_agent({ message: buildPrompt(t) }))
const results = wait({ ids: agents, timeout_ms: 600000 })
// Aggregate results
const merged = agents.map(id => results.status[id].completed)
// Cleanup all
agents.forEach(id => close_agent({ id }))
```
**Split Strategies**:
| Strategy | Description | Example |
|----------|-------------|---------|
| By responsibility | Each agent has different role | Research / Plan / Test |
| By module | Each agent handles different code area | auth / api / database |
| By perspective | Each agent analyzes from different angle | security / performance / maintainability |
### 2.3 Deep Interaction (Multi-round with send_input)
```
spawn_agent → wait (round 1) → send_input → wait (round 2) → ... → close_agent
```
**Use When**: Tasks needing iterative refinement or multi-phase execution within single agent context.
```javascript
const agent = spawn_agent({ message: initialPrompt })
// Round 1
const r1 = wait({ ids: [agent], timeout_ms: 300000 })
// Round 2 (refine based on r1)
send_input({ id: agent, message: refinementPrompt })
const r2 = wait({ ids: [agent], timeout_ms: 300000 })
// Round 3 (finalize)
send_input({ id: agent, message: finalizationPrompt })
const r3 = wait({ ids: [agent], timeout_ms: 300000 })
close_agent({ id: agent })
```
### 2.4 Two-Phase (Clarify → Execute)
```
spawn_agent → wait (questions) → send_input (answers) → wait (solution) → close_agent
```
**Use When**: Complex tasks where requirements need clarification before execution.
```javascript
const agent = spawn_agent({
message: `
## TASK ASSIGNMENT
...
### Phase A: Exploration & Clarification
Output findings + Open Questions (CLARIFICATION_NEEDED format)
### Phase B: Full Solution (after receiving answers)
Output complete deliverable
`
})
// Phase A
const exploration = wait({ ids: [agent], timeout_ms: 600000 })
if (exploration.status[agent].completed.includes('CLARIFICATION_NEEDED')) {
// Collect answers
const answers = getUserAnswers(exploration)
// Phase B
send_input({
id: agent,
message: `## CLARIFICATION ANSWERS\n${answers}\n\n## PROCEED\nGenerate full solution.`
})
const solution = wait({ ids: [agent], timeout_ms: 900000 })
}
close_agent({ id: agent })
```
### 2.5 Pipeline (Sequential Agent Chain)
```
spawn(A) → wait(A) → close(A) → spawn(B, with A's output) → wait(B) → close(B)
```
**Use When**: Tasks where each stage depends on the previous stage's output.
```javascript
// Stage 1: Research
const researcher = spawn_agent({ message: researchPrompt })
const research = wait({ ids: [researcher] })
close_agent({ id: researcher })
// Stage 2: Plan (uses research output)
const planner = spawn_agent({
message: `${planPrompt}\n\n## RESEARCH CONTEXT\n${research.status[researcher].completed}`
})
const plan = wait({ ids: [planner] })
close_agent({ id: planner })
// Stage 3: Execute (uses plan output)
const executor = spawn_agent({
message: `${executePrompt}\n\n## PLAN\n${plan.status[planner].completed}`
})
const execution = wait({ ids: [executor] })
close_agent({ id: executor })
```
### 2.6 Merged Exploration (Explore + Clarify + Plan in Single Agent)
```
spawn(dual-role) → wait(explore) → send_input(clarify) → wait(plan) → close
```
**Use When**: Exploration and planning are tightly coupled and benefit from shared context.
**Advantages over Pipeline**:
- 60-80% fewer agent creations
- No context loss between phases
- Higher result consistency
```javascript
const agent = spawn_agent({
message: `
## DUAL ROLE ASSIGNMENT
### Role A: Explorer
Explore codebase, identify patterns, generate questions
### Role B: Planner (activated after clarification)
Generate implementation plan based on exploration + answers
### Phase 1: Explore
Output: Findings + CLARIFICATION_NEEDED questions
### Phase 2: Plan (triggered by send_input)
Output: plan.json
`
})
const explore = wait({ ids: [agent] })
// ... handle clarification ...
send_input({ id: agent, message: answers })
const plan = wait({ ids: [agent] })
close_agent({ id: agent })
```
## 3. Message Design
### 3.1 TASK ASSIGNMENT Structure
```text
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/{agent-type}.md (MUST read first)
2. Read: .workflow/project-tech.json
3. Read: .workflow/project-guidelines.json
---
Goal: One-sentence objective
Scope:
- Include: allowed operations
- Exclude: forbidden operations
- Directory: target paths
- Dependencies: dependency constraints
Context:
- Key paths: relevant file paths
- Current state: system status
- Constraints: must-follow rules
Deliverables:
- Output structured following template
Quality bar:
- Criterion 1
- Criterion 2
```
### 3.2 Structured Output Template
```text
Summary:
- One-sentence completion status
Findings:
- Finding 1: description
- Finding 2: description
Proposed changes:
- File: path/to/file
- Change: modification detail
- Risk: impact assessment
Tests:
- Test cases needed
- Commands to run
Open questions:
1. Unresolved question 1
2. Unresolved question 2
```
### 3.3 Clarification Format
```text
CLARIFICATION_NEEDED:
Q1: [question] | Options: [A, B, C] | Recommended: [A]
Q2: [question] | Options: [A, B] | Recommended: [B]
```
## 4. Error Handling
### 4.1 Timeout
```javascript
const result = wait({ ids: [agent], timeout_ms: 30000 })
if (result.timed_out) {
// Option 1: Continue waiting
const retry = wait({ ids: [agent], timeout_ms: 60000 })
// Option 2: Urge convergence
send_input({ id: agent, message: "Please wrap up and output current findings." })
const urged = wait({ ids: [agent], timeout_ms: 30000 })
// Option 3: Abort
close_agent({ id: agent })
}
```
### 4.2 Agent Recovery (post close_agent)
```javascript
// Cannot recover closed agent — must recreate
const newAgent = spawn_agent({
message: `${originalPrompt}\n\n## PREVIOUS ATTEMPT OUTPUT\n${previousOutput}`
})
```
### 4.3 Partial Results (parallel fan-out)
```javascript
const results = wait({ ids: agents, timeout_ms: 300000 })
const completed = agents.filter(id => results.status[id]?.completed)
const pending = agents.filter(id => !results.status[id]?.completed)
if (completed.length >= Math.ceil(agents.length * 0.7)) {
// 70%+ complete — proceed with partial results
pending.forEach(id => close_agent({ id }))
}
```
## 5. Role Loading
### 5.1 Path Reference Pattern (Recommended)
```javascript
spawn_agent({
message: `
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/${agentType}.md (MUST read first)
...
`
})
```
**Why**: Keeps message lean, agent loads its own role context.
### 5.2 Role Mapping
| Agent Type | Role File |
|------------|-----------|
| cli-explore-agent | ~/.codex/agents/cli-explore-agent.md |
| cli-lite-planning-agent | ~/.codex/agents/cli-lite-planning-agent.md |
| code-developer | ~/.codex/agents/code-developer.md |
| context-search-agent | ~/.codex/agents/context-search-agent.md |
| debug-explore-agent | ~/.codex/agents/debug-explore-agent.md |
| doc-generator | ~/.codex/agents/doc-generator.md |
| action-planning-agent | ~/.codex/agents/action-planning-agent.md |
| test-fix-agent | ~/.codex/agents/test-fix-agent.md |
| universal-executor | ~/.codex/agents/universal-executor.md |
| tdd-developer | ~/.codex/agents/tdd-developer.md |
| ui-design-agent | ~/.codex/agents/ui-design-agent.md |
## 6. Design Principles
1. **Delay close_agent**: Only close when certain no more interaction needed
2. **Batch wait over sequential**: Use `wait({ ids: [...] })` for parallel agents
3. **Merge phases when context-dependent**: Use send_input over new agents
4. **Structured output always**: Enforce uniform output template
5. **Minimal message size**: Pass role file paths, not inline content
6. **Explicit lifecycle**: Every spawn must have a close (balanced)
7. **Timeout handling**: Always specify timeout_ms, always handle timed_out

View File

@@ -0,0 +1,228 @@
# Claude → Codex Conversion Rules
Comprehensive mapping rules for converting Claude Code skills to Codex-native skills.
## Purpose
| Phase | Usage |
|-------|-------|
| Phase 1 | Reference when analyzing Claude source skill |
| Phase 2 | Apply when generating Codex orchestrator |
| Phase 3 | Apply when converting agent definitions |
---
## 1. API Mapping
### 1.1 Core API Conversion
| Claude Pattern | Codex Equivalent | Notes |
|----------------|-----------------|-------|
| `Task({ subagent_type, prompt })` | `spawn_agent({ message })` + `wait()` | Split create and result retrieval |
| `Task({ run_in_background: false })` | `spawn_agent()` + immediate `wait()` | Synchronous equivalent |
| `Task({ run_in_background: true })` | `spawn_agent()` (wait later) | Deferred wait |
| `Task({ resume: agentId })` | `send_input({ id: agentId })` | Agent must not be closed |
| `TaskOutput({ task_id, block: true })` | `wait({ ids: [id] })` | Blocking wait |
| `TaskOutput({ task_id, block: false })` | `wait({ ids: [id], timeout_ms: 1000 })` | Polling with short timeout |
| Agent auto-cleanup | `close_agent({ id })` | Must be explicit |
### 1.2 Parallel Task Conversion
**Claude**:
```javascript
// Multiple Task() calls in single message (parallel)
const result1 = Task({ subagent_type: "agent-a", prompt: promptA })
const result2 = Task({ subagent_type: "agent-b", prompt: promptB })
const result3 = Task({ subagent_type: "agent-c", prompt: promptC })
```
**Codex**:
```javascript
// Explicit parallel: spawn all, then batch wait
const idA = spawn_agent({ message: promptA_with_role })
const idB = spawn_agent({ message: promptB_with_role })
const idC = spawn_agent({ message: promptC_with_role })
const results = wait({ ids: [idA, idB, idC], timeout_ms: 600000 })
// Process results
const resultA = results.status[idA].completed
const resultB = results.status[idB].completed
const resultC = results.status[idC].completed
// Cleanup
;[idA, idB, idC].forEach(id => close_agent({ id }))
```
### 1.3 Resume/Continue Conversion
**Claude**:
```javascript
// Resume a previous agent
Task({ subagent_type: "agent-a", resume: previousAgentId, prompt: "Continue..." })
```
**Codex**:
```javascript
// send_input to continue (agent must still be alive)
send_input({
id: previousAgentId,
message: "Continue..."
})
const continued = wait({ ids: [previousAgentId] })
```
### 1.4 TaskOutput Polling Conversion
**Claude**:
```javascript
while (!done) {
const output = TaskOutput({ task_id: id, block: false })
if (output.status === 'completed') done = true
sleep(1000)
}
```
**Codex**:
```javascript
let result = wait({ ids: [id], timeout_ms: 30000 })
while (result.timed_out) {
result = wait({ ids: [id], timeout_ms: 30000 })
}
```
## 2. Role Loading Conversion
### 2.1 subagent_type → MANDATORY FIRST STEPS
**Claude**: Role automatically loaded via `subagent_type` parameter.
**Codex**: Role must be explicitly loaded by agent as first action.
**Conversion**:
```javascript
// Claude
Task({
subagent_type: "cli-explore-agent",
prompt: "Explore the codebase for authentication patterns"
})
// Codex
spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/cli-explore-agent.md (MUST read first)
2. Read: .workflow/project-tech.json
3. Read: .workflow/project-guidelines.json
---
Goal: Explore the codebase for authentication patterns
Deliverables: Structured findings following output template
`
})
```
### 2.2 Role Mapping Table
| Claude subagent_type | Codex Role Path |
|----------------------|-----------------|
| `Explore` | `~/.codex/agents/cli-explore-agent.md` |
| `Plan` | `~/.codex/agents/cli-lite-planning-agent.md` |
| `code-developer` | `~/.codex/agents/code-developer.md` |
| `context-search-agent` | `~/.codex/agents/context-search-agent.md` |
| `debug-explore-agent` | `~/.codex/agents/debug-explore-agent.md` |
| `doc-generator` | `~/.codex/agents/doc-generator.md` |
| `action-planning-agent` | `~/.codex/agents/action-planning-agent.md` |
| `test-fix-agent` | `~/.codex/agents/test-fix-agent.md` |
| `universal-executor` | `~/.codex/agents/universal-executor.md` |
| `tdd-developer` | `~/.codex/agents/tdd-developer.md` |
| `general-purpose` | `~/.codex/agents/universal-executor.md` |
| `Bash` | Direct shell execution (no agent needed) |
| `haiku` / `sonnet` / `opus` | Model selection via agent_type parameter |
## 3. Structural Conversion
### 3.1 SKILL.md → orchestrator.md
| Claude SKILL.md Section | Codex orchestrator.md Section |
|--------------------------|-------------------------------|
| Frontmatter (name, description, allowed-tools) | Frontmatter (name, description, agents, phases) |
| Architecture Overview | Architecture Overview (spawn/wait/close flow) |
| Execution Flow (Ref: markers) | Phase Execution (spawn_agent code blocks) |
| Data Flow (variables, files) | Data Flow (wait results, context passing) |
| TodoWrite Pattern | update_plan tracking (Codex convention) |
| Interactive Preference Collection | User interaction via orchestrator prompts |
| Error Handling | Timeout + Lifecycle error handling |
| Phase Reference Documents table | Agent Registry + Phase detail files |
### 3.2 Phase Files → Phase Detail or Inline
**Simple phases** (single agent, no branching): Inline in orchestrator.md
**Complex phases** (multi-agent, conditional): Separate `phases/0N-{name}.md`
### 3.3 Pattern-Level Conversion
| Claude Pattern | Codex Pattern |
|----------------|---------------|
| Orchestrator + Progressive Loading | Orchestrator + Agent Registry + on-demand phase loading |
| TodoWrite Attachment/Collapse | update_plan pending → in_progress → completed |
| Inter-Phase Data Flow (variables) | wait() result passing between phases |
| Conditional Phase Execution | if/else on wait() results |
| Direct Phase Handoff (Read phase doc) | Inline execution or separate phase files |
| AskUserQuestion | Direct user interaction in orchestrator |
## 4. Content Preservation Rules
When converting Claude skills:
1. **Agent prompts**: Preserve task descriptions, goals, scope, deliverables VERBATIM
2. **Bash commands**: Preserve all shell commands unchanged
3. **Code blocks**: Preserve implementation code unchanged
4. **Validation logic**: Preserve quality checks and success criteria
5. **Error handling**: Convert to Codex timeout/lifecycle patterns, preserve intent
**Transform** (structure changes):
- `Task()` calls → `spawn_agent()` + `wait()` + `close_agent()`
- `subagent_type` → MANDATORY FIRST STEPS role path
- Synchronous returns → Explicit `wait()` calls
- Auto-cleanup → Explicit `close_agent()` calls
**Preserve** (content unchanged):
- Task descriptions and goals
- Scope definitions
- Quality criteria
- File paths and patterns
- Shell commands
- Business logic
## 5. Anti-Patterns to Avoid
| Anti-Pattern | Why | Correct Pattern |
|-------------|-----|-----------------|
| Using close_agent for results | Returns are unreliable | Use wait() for results |
| Inline role content in message | Bloats message, wastes tokens | Pass role file path in MANDATORY FIRST STEPS |
| Early close_agent before potential follow-up | Cannot resume closed agent | Delay close until certain no more interaction |
| Sequential wait for parallel agents | Wasted time | Batch wait({ ids: [...] }) |
| No timeout_ms | Indefinite hang risk | Always specify timeout_ms |
| No timed_out handling | Silent failures | Always check result.timed_out |
| Claude Task() remaining in output | Runtime incompatibility | Convert all Task() to spawn_agent |
| Claude resume: in output | Runtime incompatibility | Convert to send_input() |
## 6. Conversion Checklist
Before delivering converted skill:
- [ ] All `Task()` calls converted to `spawn_agent()` + `wait()` + `close_agent()`
- [ ] All `subagent_type` mapped to MANDATORY FIRST STEPS role paths
- [ ] All `resume` converted to `send_input()`
- [ ] All `TaskOutput` polling converted to `wait()` with timeout
- [ ] No Claude-specific patterns remain (Task, TaskOutput, resume, subagent_type)
- [ ] Timeout handling added for all `wait()` calls
- [ ] Lifecycle balanced (spawn count ≤ close count)
- [ ] Structured output template enforced for all agents
- [ ] Agent prompts/goals/scope preserved verbatim
- [ ] Error handling converted to Codex patterns

View File

@@ -0,0 +1,163 @@
# Quality Standards
Quality criteria and validation gates for generated Codex skills.
## Purpose
| Phase | Usage |
|-------|-------|
| Phase 3 | Reference during generation |
| Phase 4 | Apply during validation |
---
## 1. Quality Dimensions
### 1.1 Structural Completeness (30%)
| Check | Weight | Criteria |
|-------|--------|----------|
| Orchestrator exists | 5 | File present at expected path |
| Frontmatter valid | 3 | Contains name, description |
| Architecture diagram | 3 | ASCII flow showing spawn/wait/close |
| Agent Registry | 4 | Table with all agents, role paths, responsibilities |
| Phase Execution blocks | 5 | Code blocks for each phase with spawn/wait/close |
| Lifecycle Management | 5 | Timeout handling + cleanup protocol |
| Agent files complete | 5 | All new agent roles have complete role files |
**Scoring**: Each check passes (full weight) or fails (0). Total = sum / max.
### 1.2 Pattern Compliance (40%)
| Check | Weight | Criteria |
|-------|--------|----------|
| Lifecycle balanced | 6 | Every spawn_agent has matching close_agent |
| Role loading correct | 6 | MANDATORY FIRST STEPS pattern used (not inline content) |
| Wait for results | 5 | wait() used for results (not close_agent) |
| Batch wait for parallel | 5 | Parallel agents use wait({ ids: [...] }) |
| Timeout specified | 4 | All wait() calls have timeout_ms |
| Timeout handled | 4 | timed_out checked after every wait() |
| Structured output | 5 | Agents produce Summary/Findings/Changes/Tests/Questions |
| No Claude patterns | 5 | No Task(), TaskOutput(), resume: remaining |
**Scoring**: Each check passes (full weight) or fails (0). Total = sum / max.
### 1.3 Content Quality (30%)
| Check | Weight | Criteria |
|-------|--------|----------|
| Orchestrator substantive | 4 | Content > 500 chars, not boilerplate |
| Code blocks present | 3 | >= 4 code blocks with executable patterns |
| Error handling | 3 | Timeout + recovery + partial results handling |
| No placeholders | 4 | No `{{...}}` or `TODO` remaining in output |
| Agent roles substantive | 4 | Each agent role > 300 chars with actionable steps |
| Output format defined | 3 | Structured output template in each agent |
| Goals/scope clear | 4 | Every spawn_agent has Goal + Scope + Deliverables |
| Conversion faithful | 5 | Source content preserved (if converting) |
**Scoring**: Each check passes (full weight) or fails (0). Total = sum / max.
## 2. Quality Gates
| Verdict | Score | Action |
|---------|-------|--------|
| **PASS** | >= 80% | Deliver to target location |
| **REVIEW** | 60-79% | Report issues, user decides |
| **FAIL** | < 60% | Block delivery, list critical issues |
### 2.1 Critical Failures (Auto-FAIL)
These issues force FAIL regardless of overall score:
1. **No orchestrator file** — skill has no entry point
2. **Task() calls in output** — runtime incompatible with Codex
3. **No agent registry** — agents cannot be identified
4. **Missing close_agent** — resource leak risk
5. **Inline role content** — violates Codex pattern (message bloat)
### 2.2 Warnings (Non-blocking)
1. **Missing timeout handling** — degraded reliability
2. **No error handling section** — reduced robustness
3. **Placeholder text remaining** — needs manual completion
4. **Phase files missing** — acceptable for simple skills
## 3. Validation Process
### 3.1 Automated Checks
```javascript
function validateSkill(generatedFiles, codexSkillConfig) {
const checks = []
// Structural
checks.push(checkFileExists(generatedFiles.orchestrator))
checks.push(checkFrontmatter(generatedFiles.orchestrator))
checks.push(checkSection(generatedFiles.orchestrator, "Architecture"))
checks.push(checkSection(generatedFiles.orchestrator, "Agent Registry"))
// ...
// Pattern compliance
const content = Read(generatedFiles.orchestrator)
checks.push(checkBalancedLifecycle(content))
checks.push(checkRoleLoading(content))
checks.push(checkWaitPattern(content))
// ...
// Content quality
checks.push(checkNoPlaceholders(content))
checks.push(checkSubstantiveContent(content))
// ...
// Critical failures
const criticals = checkCriticalFailures(content, generatedFiles)
if (criticals.length > 0) return { verdict: "FAIL", criticals }
// Score
const score = calculateWeightedScore(checks)
const verdict = score >= 80 ? "PASS" : score >= 60 ? "REVIEW" : "FAIL"
return { score, verdict, checks, issues: checks.filter(c => !c.passed) }
}
```
### 3.2 Manual Review Points
For REVIEW verdict, highlight these for user attention:
1. Agent role completeness — are all capabilities covered?
2. Interaction model appropriateness — right pattern for use case?
3. Timeout values — appropriate for expected task duration?
4. Scope definitions — clear boundaries for each agent?
5. Output format — suitable for downstream consumers?
## 4. Scoring Formula
```
Overall = Structural × 0.30 + PatternCompliance × 0.40 + ContentQuality × 0.30
```
Pattern compliance weighted highest because Codex runtime correctness is critical.
## 5. Quality Improvement Guidance
### Low Structural Score
- Add missing sections to orchestrator
- Create missing agent role files
- Add frontmatter to all files
### Low Pattern Score
- Add MANDATORY FIRST STEPS to all spawn_agent messages
- Replace inline role content with path references
- Add close_agent for every spawn_agent
- Add timeout_ms and timed_out handling to all wait calls
- Remove any remaining Claude patterns
### Low Content Score
- Expand agent role definitions with more specific steps
- Add concrete Goal/Scope/Deliverables to spawn messages
- Replace placeholders with actual content
- Add error handling for each phase

View File

@@ -0,0 +1,215 @@
# Agent Role Template
Template for generating per-agent role definition files.
## Purpose
| Phase | Usage |
|-------|-------|
| Phase 0 | Read to understand agent role file structure |
| Phase 3 | Apply with agent-specific content |
---
## Template
```markdown
---
name: {{agent_name}}
description: |
{{description}}
color: {{color}}
skill: {{parent_skill_name}}
---
# {{agent_display_name}}
{{description_paragraph}}
## Core Capabilities
{{#each capabilities}}
{{@index}}. **{{this.name}}**: {{this.description}}
{{/each}}
## Execution Process
### Step 1: Context Loading
**MANDATORY**: Execute these steps FIRST before any other action.
1. Read this role definition file (already done if you're reading this)
2. Read: `.workflow/project-tech.json` — understand project technology stack
3. Read: `.workflow/project-guidelines.json` — understand project conventions
4. Parse the TASK ASSIGNMENT from the spawn message for:
- **Goal**: What to achieve
- **Scope**: What's allowed and forbidden
- **Context**: Relevant background information
- **Deliverables**: Expected output format
- **Quality bar**: Success criteria
### Step 2: {{primary_action_name}}
{{primary_action_detail}}
\`\`\`javascript
// {{primary_action_description}}
{{primary_action_code}}
\`\`\`
### Step 3: {{secondary_action_name}}
{{secondary_action_detail}}
\`\`\`javascript
// {{secondary_action_description}}
{{secondary_action_code}}
\`\`\`
### Step 4: Output Delivery
Produce structured output following this EXACT template:
\`\`\`text
Summary:
- One-sentence completion summary
Findings:
- Finding 1: [specific description with file:line references]
- Finding 2: [specific description]
Proposed changes:
- File: [path/to/file]
- Change: [specific modification description]
- Risk: [low/medium/high] - [impact description]
Tests:
- Test cases: [list of needed test cases]
- Commands: [test commands to verify]
Open questions:
1. [Question needing clarification, if any]
2. [Question needing clarification, if any]
\`\`\`
**Important**: If there are open questions that block progress, prepend output with:
\`\`\`
CLARIFICATION_NEEDED:
Q1: [question] | Options: [A, B, C] | Recommended: [A]
Q2: [question] | Options: [A, B] | Recommended: [B]
\`\`\`
## Key Reminders
**ALWAYS**:
- Read role definition file as FIRST action (Step 1)
- Follow structured output template EXACTLY
- Stay within the assigned Scope boundaries
- Include file:line references in Findings
- Report open questions via CLARIFICATION_NEEDED format
- Provide actionable, specific deliverables
**NEVER**:
- Modify files outside the assigned Scope
- Skip context loading (Step 1)
- Produce unstructured or free-form output
- Make assumptions about unclear requirements (ask instead)
- Exceed the defined Quality bar without explicit approval
- Ignore the Goal/Scope/Deliverables from TASK ASSIGNMENT
## Error Handling
| Scenario | Action |
|----------|--------|
| Cannot access required file | Report in Open questions, continue with available data |
| Task scope unclear | Output CLARIFICATION_NEEDED, provide best-effort findings |
| Unexpected error | Report error details in Summary, include partial results |
| Quality bar not achievable | Report gap in Summary, explain constraints |
```
---
## Template Variants by Responsibility Type
### Exploration Agent
**Step 2**: Codebase Discovery
```javascript
// Search for relevant code patterns
const files = Glob("src/**/*.{ts,js,tsx,jsx}")
const matches = Grep(targetPattern, files)
// Trace call chains, identify entry points
```
**Step 3**: Pattern Analysis
```javascript
// Analyze discovered patterns
// Cross-reference with project conventions
// Identify similar implementations
```
### Implementation Agent
**Step 2**: Code Implementation
```javascript
// Implement changes according to plan
// Follow existing code patterns
// Maintain backward compatibility
```
**Step 3**: Self-Validation
```javascript
// Run relevant tests
// Check for syntax/type errors
// Verify changes match acceptance criteria
```
### Analysis Agent
**Step 2**: Multi-Dimensional Analysis
```javascript
// Analyze from assigned perspective (security/perf/quality/etc.)
// Collect evidence with file:line references
// Classify findings by severity
```
**Step 3**: Recommendation Generation
```javascript
// Propose fixes for each finding
// Assess risk and effort
// Prioritize by impact
```
### Testing Agent
**Step 2**: Test Design
```javascript
// Identify test scenarios from requirements
// Design test cases with expected results
// Map to test frameworks
```
**Step 3**: Test Execution & Validation
```javascript
// Run tests
// Collect pass/fail results
// Iterate on failures
```
---
## Variable Reference
| Variable | Source | Description |
|----------|--------|-------------|
| `{{agent_name}}` | config.name | Agent identifier (lowercase, hyphenated) |
| `{{agent_display_name}}` | Derived from name | Human-readable title |
| `{{description}}` | config.description | Short description (1-3 lines) |
| `{{description_paragraph}}` | config.description | Full paragraph description |
| `{{color}}` | Auto-assigned | Terminal color for output |
| `{{parent_skill_name}}` | codexSkillConfig.name | Parent skill identifier |
| `{{capabilities}}` | Inferred from responsibility | Array of capability objects |
| `{{primary_action_name}}` | Derived from responsibility | Step 2 title |
| `{{primary_action_detail}}` | Generated or from source | Step 2 content |
| `{{secondary_action_name}}` | Derived from responsibility | Step 3 title |
| `{{secondary_action_detail}}` | Generated or from source | Step 3 content |

View File

@@ -0,0 +1,414 @@
# Command Pattern Template
Pre-built Codex command patterns for common agent interaction scenarios.
## Purpose
| Phase | Usage |
|-------|-------|
| Phase 0 | Read to understand available command patterns |
| Phase 2 | Select appropriate patterns for orchestrator |
| Phase 3 | Apply patterns to agent definitions |
---
## Pattern 1: Explore (Parallel Fan-out)
**Use When**: Multi-angle codebase exploration needed.
```javascript
// ==================== Explore Pattern ====================
// Step 1: Define exploration angles
const angles = ["architecture", "dependencies", "patterns", "testing"]
// Step 2: Create parallel exploration agents
const agents = angles.map(angle =>
spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/cli-explore-agent.md (MUST read first)
2. Read: .workflow/project-tech.json
---
Goal: Execute ${angle} exploration for ${task_description}
Scope:
- Include: All source files relevant to ${angle}
- Exclude: node_modules, dist, build artifacts
Context:
- Task: ${task_description}
- Angle: ${angle}
Deliverables:
- Structured findings following output template
- File:line references for key discoveries
- Open questions for unclear areas
Quality bar:
- At least 3 relevant files identified
- Findings backed by concrete evidence
`
})
)
// Step 3: Batch wait
const results = wait({ ids: agents, timeout_ms: 600000 })
// Step 4: Aggregate
const findings = agents.map((id, i) => ({
angle: angles[i],
result: results.status[id].completed
}))
// Step 5: Cleanup
agents.forEach(id => close_agent({ id }))
```
## Pattern 2: Analyze (Multi-Perspective)
**Use When**: Code analysis from multiple dimensions needed.
```javascript
// ==================== Analyze Pattern ====================
const perspectives = [
{ name: "security", focus: "OWASP Top 10, injection, auth bypass" },
{ name: "performance", focus: "O(n²), memory leaks, blocking I/O" },
{ name: "maintainability", focus: "complexity, coupling, duplication" }
]
const agents = perspectives.map(p =>
spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/cli-explore-agent.md (MUST read first)
---
Goal: Analyze ${targetModule} from ${p.name} perspective
Focus: ${p.focus}
Scope:
- Include: ${targetPaths}
- Exclude: Test files, generated code
Deliverables:
- Severity-classified findings (Critical/High/Medium/Low)
- File:line references for each finding
- Remediation recommendations
Quality bar:
- Every finding must have evidence (code reference)
- Remediation must be actionable
`
})
)
const results = wait({ ids: agents, timeout_ms: 600000 })
// Merge findings by severity
const merged = {
critical: [], high: [], medium: [], low: []
}
agents.forEach((id, i) => {
const parsed = parseFindings(results.status[id].completed)
Object.keys(merged).forEach(sev => merged[sev].push(...(parsed[sev] || [])))
})
agents.forEach(id => close_agent({ id }))
```
## Pattern 3: Implement (Sequential Delegation)
**Use When**: Code implementation following a plan.
```javascript
// ==================== Implement Pattern ====================
const implementAgent = spawn_agent({
message: `
## TASK ASSIGNMENT
### 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
---
Goal: Implement ${featureDescription}
Scope:
- Include: ${targetPaths}
- Exclude: Unrelated modules
- Constraints: No breaking changes, follow existing patterns
Context:
- Plan: ${planContent}
- Dependencies: ${dependencies}
- Existing patterns: ${patterns}
Deliverables:
- Working implementation following plan
- Updated/new test files
- Summary of changes with file:line references
Quality bar:
- All existing tests pass
- New code follows project conventions
- No TypeScript errors
- Backward compatible
`
})
const result = wait({ ids: [implementAgent], timeout_ms: 900000 })
// Check for open questions (might need clarification)
if (result.status[implementAgent].completed.includes('CLARIFICATION_NEEDED')) {
// Handle clarification via send_input
const answers = getUserAnswers(result)
send_input({ id: implementAgent, message: `## ANSWERS\n${answers}\n\n## CONTINUE\nProceed with implementation.` })
const final = wait({ ids: [implementAgent], timeout_ms: 900000 })
}
close_agent({ id: implementAgent })
```
## Pattern 4: Validate (Test-Fix Cycle)
**Use When**: Running tests and fixing failures iteratively.
```javascript
// ==================== Validate Pattern ====================
const validateAgent = spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/test-fix-agent.md (MUST read first)
---
Goal: Validate ${component} — run tests, fix failures, iterate
Scope:
- Include: ${testPaths}
- Exclude: Unrelated test suites
Context:
- Recent changes: ${changedFiles}
- Test framework: ${testFramework}
Deliverables:
- All tests passing (or documented blocked tests)
- Fix summary with file:line references
- Coverage report
Quality bar:
- Pass rate >= 95%
- No new test regressions
- Max 5 fix iterations
`
})
const round1 = wait({ ids: [validateAgent], timeout_ms: 600000 })
// Check if more iterations needed
let iteration = 1
while (
iteration < 5 &&
round1.status[validateAgent].completed.includes('TESTS_FAILING')
) {
send_input({
id: validateAgent,
message: `## ITERATION ${iteration + 1}\nContinue fixing remaining failures. Focus on:\n${remainingFailures}`
})
const roundN = wait({ ids: [validateAgent], timeout_ms: 300000 })
iteration++
}
close_agent({ id: validateAgent })
```
## Pattern 5: Review (Multi-Dimensional)
**Use When**: Code review from multiple dimensions.
```javascript
// ==================== Review Pattern ====================
const dimensions = [
{ name: "correctness", agent: "cli-explore-agent" },
{ name: "security", agent: "cli-explore-agent" },
{ name: "performance", agent: "cli-explore-agent" },
{ name: "style", agent: "cli-explore-agent" }
]
const agents = dimensions.map(d =>
spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/${d.agent}.md (MUST read first)
---
Goal: Review ${targetCode} for ${d.name}
Scope: ${changedFiles}
Deliverables: Findings with severity, file:line, remediation
`
})
)
const results = wait({ ids: agents, timeout_ms: 600000 })
// Aggregate review findings
const review = {
approved: true,
findings: [],
blockers: []
}
agents.forEach((id, i) => {
const parsed = parseReview(results.status[id].completed)
review.findings.push(...parsed.findings)
if (parsed.blockers.length > 0) {
review.approved = false
review.blockers.push(...parsed.blockers)
}
})
agents.forEach(id => close_agent({ id }))
```
## Pattern 6: Deep Interact (Merged Explore + Plan)
**Use When**: Exploration and planning are tightly coupled.
```javascript
// ==================== Deep Interact Pattern ====================
const agent = spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/cli-explore-agent.md (MUST read first)
2. **Also read**: ~/.codex/agents/cli-lite-planning-agent.md (dual role)
---
### Phase A: Exploration
Goal: Explore codebase for ${task_description}
Output: Structured findings + CLARIFICATION_NEEDED questions (if any)
### Phase B: Planning (activated after clarification)
Goal: Generate implementation plan based on exploration + answers
Output: Structured plan following plan schema
Deliverables:
- Phase A: exploration findings (Summary/Findings/Open questions)
- Phase B: implementation plan (after receiving clarification answers)
`
})
// Phase A: Exploration
const exploration = wait({ ids: [agent], timeout_ms: 600000 })
if (exploration.status[agent].completed.includes('CLARIFICATION_NEEDED')) {
const answers = getUserAnswers(exploration)
// Phase B: Planning (same agent, preserved context)
send_input({
id: agent,
message: `
## CLARIFICATION ANSWERS
${answers}
## PROCEED TO PHASE B
Generate implementation plan based on your exploration findings and these answers.
`
})
const plan = wait({ ids: [agent], timeout_ms: 900000 })
}
close_agent({ id: agent })
```
## Pattern 7: Two-Phase (Clarify → Execute)
**Use When**: Task requires explicit clarification before execution.
```javascript
// ==================== Two-Phase Pattern ====================
// Phase 1: Clarification
const agent = spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/${agentType}.md (MUST read first)
---
### PHASE: CLARIFICATION ONLY
Goal: Understand ${task_description} and identify unclear points
Output ONLY:
1. Your understanding of the task (2-3 sentences)
2. CLARIFICATION_NEEDED questions (if any)
3. Recommended approach (1-2 sentences)
DO NOT execute any changes yet.
`
})
const clarification = wait({ ids: [agent], timeout_ms: 300000 })
// Collect user confirmation/answers
const userResponse = processUserInput(clarification)
// Phase 2: Execution
send_input({
id: agent,
message: `
## USER CONFIRMATION
${userResponse}
## PROCEED TO EXECUTION
Now execute the task with full implementation.
Output: Complete deliverable following structured output template.
`
})
const execution = wait({ ids: [agent], timeout_ms: 900000 })
close_agent({ id: agent })
```
---
## Pattern Selection Guide
| Scenario | Recommended Pattern | Reason |
|----------|-------------------|--------|
| Explore codebase from N angles | Pattern 1: Explore | Parallel fan-out, independent angles |
| Analyze code quality | Pattern 2: Analyze | Multi-perspective, severity classification |
| Implement from plan | Pattern 3: Implement | Sequential, plan-driven |
| Run tests + fix | Pattern 4: Validate | Iterative send_input loop |
| Code review | Pattern 5: Review | Multi-dimensional, aggregated verdict |
| Explore then plan | Pattern 6: Deep Interact | Context preservation, merged phases |
| Complex/unclear task | Pattern 7: Two-Phase | Clarify first, reduce rework |
| Simple one-shot task | Standard (no pattern) | spawn → wait → close |

View File

@@ -0,0 +1,306 @@
# Orchestrator Template
Template for the generated Codex orchestrator document.
## Purpose
| Phase | Usage |
|-------|-------|
| Phase 0 | Read to understand orchestrator output structure |
| Phase 2 | Apply with skill-specific content |
---
## Template
```markdown
---
name: {{skill_name}}
description: |
{{description}}
agents: {{agent_count}}
phases: {{phase_count}}
---
# {{skill_display_name}}
{{one_paragraph_description}}
## Architecture Overview
\`\`\`
{{architecture_diagram}}
\`\`\`
## Agent Registry
| Agent | Role File | Responsibility | New/Existing |
|-------|-----------|----------------|--------------|
{{#each agents}}
| `{{this.name}}` | `{{this.role_file}}` | {{this.responsibility}} | {{this.status}} |
{{/each}}
## Phase Execution
{{#each phases}}
### Phase {{this.index}}: {{this.name}}
{{this.description}}
{{#if this.is_parallel}}
#### Parallel Fan-out
\`\`\`javascript
// Create parallel agents
const agentIds = [
{{#each this.agents}}
spawn_agent({
message: \`
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: {{this.role_file}} (MUST read first)
2. Read: .workflow/project-tech.json
3. Read: .workflow/project-guidelines.json
---
Goal: {{this.goal}}
Scope:
- Include: {{this.scope_include}}
- Exclude: {{this.scope_exclude}}
Context:
{{this.context}}
Deliverables:
{{this.deliverables}}
Quality bar:
{{this.quality_bar}}
\`
}),
{{/each}}
]
// Batch wait
const results = wait({
ids: agentIds,
timeout_ms: {{this.timeout_ms}}
})
// Handle timeout
if (results.timed_out) {
const completed = agentIds.filter(id => results.status[id]?.completed)
const pending = agentIds.filter(id => !results.status[id]?.completed)
// Use completed results, log pending
}
// Aggregate results
const phaseResults = agentIds.map(id => results.status[id].completed)
// Cleanup
agentIds.forEach(id => close_agent({ id }))
\`\`\`
{{/if}}
{{#if this.is_standard}}
#### Standard Execution
\`\`\`javascript
const agentId = spawn_agent({
message: \`
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: {{this.agent.role_file}} (MUST read first)
2. Read: .workflow/project-tech.json
3. Read: .workflow/project-guidelines.json
---
Goal: {{this.goal}}
Scope:
- Include: {{this.scope_include}}
- Exclude: {{this.scope_exclude}}
Context:
{{this.context}}
Deliverables:
{{this.deliverables}}
Quality bar:
{{this.quality_bar}}
\`
})
const result = wait({ ids: [agentId], timeout_ms: {{this.timeout_ms}} })
if (result.timed_out) {
// Timeout handling: continue wait or urge convergence
send_input({ id: agentId, message: "Please finalize and output current findings." })
const retry = wait({ ids: [agentId], timeout_ms: 60000 })
}
close_agent({ id: agentId })
\`\`\`
{{/if}}
{{#if this.is_deep_interaction}}
#### Deep Interaction (Multi-round)
\`\`\`javascript
const agent = spawn_agent({
message: \`
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: {{this.agent.role_file}} (MUST read first)
---
### Phase A: {{this.initial_goal}}
Output: Findings + Open Questions (CLARIFICATION_NEEDED format)
### Phase B: {{this.followup_goal}} (after clarification)
Output: Complete deliverable
\`
})
// Round 1: Initial exploration
const round1 = wait({ ids: [agent], timeout_ms: {{this.timeout_ms}} })
// Check for clarification needs
if (round1.status[agent].completed.includes('CLARIFICATION_NEEDED')) {
// Parse questions, collect user answers
const answers = collectUserAnswers(round1.status[agent].completed)
// Round 2: Continue with answers
send_input({
id: agent,
message: \`
## CLARIFICATION ANSWERS
\${answers}
## NEXT STEP
Proceed with Phase B.
\`
})
const round2 = wait({ ids: [agent], timeout_ms: {{this.followup_timeout_ms}} })
}
close_agent({ id: agent })
\`\`\`
{{/if}}
{{#if this.is_pipeline}}
#### Pipeline (Sequential Chain)
\`\`\`javascript
{{#each this.stages}}
// Stage {{this.index}}: {{this.name}}
const stage{{this.index}}Agent = spawn_agent({
message: \`
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: {{this.role_file}} (MUST read first)
---
Goal: {{this.goal}}
{{#if this.previous_output}}
## PREVIOUS STAGE OUTPUT
\${stage{{this.previous_index}}Result}
{{/if}}
Deliverables: {{this.deliverables}}
\`
})
const stage{{this.index}}Result = wait({ ids: [stage{{this.index}}Agent], timeout_ms: {{this.timeout_ms}} })
close_agent({ id: stage{{this.index}}Agent })
{{/each}}
\`\`\`
{{/if}}
{{/each}}
## Result Aggregation
\`\`\`javascript
// Merge results from all phases
const finalResult = {
{{#each phases}}
phase{{this.index}}: phase{{this.index}}Results,
{{/each}}
}
// Output summary
console.log(\`
## Skill Execution Complete
{{#each phases}}
### Phase {{this.index}}: {{this.name}}
Status: \${phase{{this.index}}Results.status}
{{/each}}
\`)
\`\`\`
## Lifecycle Management
### Timeout Handling
| Timeout Scenario | Action |
|-----------------|--------|
| Single agent timeout | send_input to urge convergence, retry wait |
| Parallel partial timeout | Use completed results if >= 70%, close pending |
| All agents timeout | Log error, abort with partial state |
### Cleanup Protocol
\`\`\`javascript
// Track all agents created during execution
const allAgentIds = []
// ... (agents added during phase execution) ...
// Final cleanup (end of orchestrator or on error)
allAgentIds.forEach(id => {
try { close_agent({ id }) } catch { /* already closed */ }
})
\`\`\`
## Error Handling
| Scenario | Resolution |
|----------|------------|
| Agent produces invalid output | Retry with clarified instructions via send_input |
| Agent timeout | Urge convergence, retry, or abort |
| Missing role file | Log error, skip agent or use fallback |
| Partial results | Proceed with available data, log gaps |
```
---
## Variable Reference
| Variable | Source | Description |
|----------|--------|-------------|
| `{{skill_name}}` | codexSkillConfig.name | Skill identifier |
| `{{skill_display_name}}` | Derived from name | Human-readable title |
| `{{description}}` | codexSkillConfig.description | Skill description |
| `{{agent_count}}` | codexSkillConfig.agents.length | Number of agents |
| `{{phase_count}}` | codexSkillConfig.phases.length | Number of phases |
| `{{architecture_diagram}}` | Generated from phase/agent topology | ASCII flow diagram |
| `{{agents}}` | codexSkillConfig.agents | Array of agent configs |
| `{{phases}}` | codexSkillConfig.phases | Array of phase configs |
| `{{phases[].is_parallel}}` | phase.interaction_model === "parallel_fanout" | Boolean |
| `{{phases[].is_standard}}` | phase.interaction_model === "standard" | Boolean |
| `{{phases[].is_deep_interaction}}` | phase.interaction_model === "deep_interaction" | Boolean |
| `{{phases[].is_pipeline}}` | phase.interaction_model === "pipeline" | Boolean |
| `{{phases[].timeout_ms}}` | Phase-specific timeout | Default: 300000 |

View File

@@ -89,6 +89,36 @@ if (issueIds.length === 0) {
// Auto-detect mode
const mode = detectMode(issueIds, explicitMode)
// Execution method selection (for BUILD phase)
const execSelection = AskUserQuestion({
questions: [
{
question: "选择代码执行方式:",
header: "Execution",
multiSelect: false,
options: [
{ label: "Agent", description: "code-developer agent同步适合简单任务" },
{ label: "Codex", description: "Codex CLI后台适合复杂任务" },
{ label: "Gemini", description: "Gemini CLI后台适合分析类任务" },
{ label: "Auto", description: "根据 solution task_count 自动选择(默认)" }
]
},
{
question: "实现后是否进行代码审查?",
header: "Code Review",
multiSelect: false,
options: [
{ label: "Skip", description: "不审查" },
{ label: "Gemini Review", description: "Gemini CLI 审查" },
{ label: "Codex Review", description: "Git-aware review--uncommitted" }
]
}
]
})
const executionMethod = execSelection.Execution || 'Auto'
const codeReviewTool = execSelection['Code Review'] || 'Skip'
```
**Mode Auto-Detection**:
@@ -171,7 +201,7 @@ for (const issueId of issueIds) {
TaskCreate({
subject: `BUILD-001: Implement solution for ${issueId}`,
description: `Implement solution for issue ${issueId}. Load via ccw issue detail <item-id>, execute tasks, report via ccw issue done.`,
description: `Implement solution for issue ${issueId}. Load via ccw issue detail <item-id>, execute tasks, report via ccw issue done.\nexecution_method: ${executionMethod}\ncode_review: ${codeReviewTool}`,
activeForm: `Implementing ${issueId}`,
owner: "implementer",
addBlockedBy: [marshalId]
@@ -215,7 +245,7 @@ for (const issueId of issueIds) {
TaskCreate({
subject: `BUILD-001: Implement solution for ${issueId}`,
description: `Implement approved solution for issue ${issueId}.`,
description: `Implement approved solution for issue ${issueId}.\nexecution_method: ${executionMethod}\ncode_review: ${codeReviewTool}`,
activeForm: `Implementing ${issueId}`,
owner: "implementer",
addBlockedBy: [marshalId]
@@ -282,6 +312,9 @@ const marshalId = TaskCreate({
})
// BUILD tasks created dynamically after MARSHAL completes (based on DAG)
// Each BUILD-* task description MUST include:
// execution_method: ${executionMethod}
// code_review: ${codeReviewTool}
```
### Phase 4: Coordination Loop

View File

@@ -160,6 +160,43 @@ if (mode === 'spec-only' || mode === 'full-lifecycle') {
Simple tasks can skip clarification.
#### Execution Method Selection (impl/full-lifecycle modes)
When mode includes implementation, select execution backend before team creation:
```javascript
if (mode === 'impl-only' || mode === 'full-lifecycle') {
const execSelection = AskUserQuestion({
questions: [
{
question: "选择代码执行方式:",
header: "Execution",
multiSelect: false,
options: [
{ label: "Agent", description: "code-developer agent同步适合简单任务" },
{ label: "Codex", description: "Codex CLI后台适合复杂任务" },
{ label: "Gemini", description: "Gemini CLI后台适合分析类任务" },
{ label: "Auto", description: "根据任务复杂度自动选择(默认)" }
]
},
{
question: "实现后是否进行代码审查?",
header: "Code Review",
multiSelect: false,
options: [
{ label: "Skip", description: "不审查Reviewer 角色独立负责)" },
{ label: "Gemini Review", description: "Gemini CLI 审查" },
{ label: "Codex Review", description: "Git-aware review--uncommitted" }
]
}
]
})
var executionMethod = execSelection.Execution || 'Auto'
var codeReviewTool = execSelection['Code Review'] || 'Skip'
}
```
### Phase 2: Create Team + Spawn Workers
```javascript
@@ -277,7 +314,7 @@ TaskCreate({ subject: "PLAN-001: 探索和规划实现", description: `${taskDes
TaskUpdate({ taskId: planId, owner: "planner" })
// IMPL-001 (blockedBy PLAN-001)
TaskCreate({ subject: "IMPL-001: 实现已批准的计划", description: `${taskDescription}\n\nSession: ${sessionFolder}\nPlan: ${sessionFolder}/plan/plan.json`, activeForm: "实现中" })
TaskCreate({ subject: "IMPL-001: 实现已批准的计划", description: `${taskDescription}\n\nSession: ${sessionFolder}\nPlan: ${sessionFolder}/plan/plan.json\nexecution_method: ${executionMethod || 'Auto'}\ncode_review: ${codeReviewTool || 'Skip'}`, activeForm: "实现中" })
TaskUpdate({ taskId: implId, owner: "executor", addBlockedBy: [planId] })
// TEST-001 (blockedBy IMPL-001)

View File

@@ -1,12 +1,12 @@
# Role: executor
Code implementation following approved plans. Reads plan files, implements changes, self-validates, and reports completion.
Code implementation following approved plans. Reads plan files, routes to selected execution backend (Agent/Codex/Gemini), self-validates, and reports completion.
## Role Identity
- **Name**: `executor`
- **Task Prefix**: `IMPL-*`
- **Responsibility**: Load plan → Implement code → Self-validate → Report completion
- **Responsibility**: Load plan → Route to backend → Implement code → Self-validate → Report completion
- **Communication**: SendMessage to coordinator only
## Message Types
@@ -40,6 +40,35 @@ When `mcp__ccw-tools__team_msg` MCP is unavailable:
Bash(`ccw team log --team "${teamName}" --from "executor" --to "coordinator" --type "impl_complete" --summary "IMPL-001 complete: 5 files changed" --json`)
```
## Execution Backends
| Backend | Tool | Invocation | Mode |
|---------|------|------------|------|
| `agent` | code-developer subagent | `Task({ subagent_type: "code-developer" })` | 同步 |
| `codex` | Codex CLI | `ccw cli --tool codex --mode write` | 后台 |
| `gemini` | Gemini CLI | `ccw cli --tool gemini --mode write` | 后台 |
## Execution Method Resolution
从 IMPL-* 任务 description 中解析执行方式coordinator 在创建任务时已写入):
```javascript
function resolveExecutor(taskDesc, taskCount) {
const methodMatch = taskDesc.match(/execution_method:\s*(Agent|Codex|Gemini|Auto)/i)
const method = methodMatch ? methodMatch[1] : 'Auto'
if (method.toLowerCase() === 'auto') {
return taskCount <= 3 ? 'agent' : 'codex'
}
return method.toLowerCase() // 'agent' | 'codex' | 'gemini'
}
function resolveCodeReview(taskDesc) {
const reviewMatch = taskDesc.match(/code_review:\s*(\S+)/i)
return reviewMatch ? reviewMatch[1] : 'Skip'
}
```
## Execution (5-Phase)
### Phase 1: Task & Plan Loading
@@ -69,6 +98,10 @@ if (!planPath) {
}
const plan = JSON.parse(Read(planPath))
// Resolve execution method
const executor = resolveExecutor(task.description, plan.task_count || plan.task_ids?.length || 0)
const codeReview = resolveCodeReview(task.description)
```
### Phase 2: Task Grouping
@@ -103,7 +136,7 @@ const planTasks = plan.task_ids.map(id => JSON.parse(Read(`${planPath.replace('p
const batches = createBatches(planTasks)
```
### Phase 3: Code Implementation
### Phase 3: Code Implementation (Multi-Backend Routing)
```javascript
// Unified Task Prompt Builder
@@ -130,33 +163,55 @@ ${(planTask.convergence?.criteria || []).map(c => `- [ ] ${c}`).join('\n')}
`
}
function buildBatchPrompt(batch) {
const taskPrompts = batch.tasks.map(buildExecutionPrompt).join('\n\n---\n')
return `## Goal\n${plan.summary}\n\n## Tasks\n${taskPrompts}\n\n## Context\n### Project Guidelines\n@.workflow/project-guidelines.json\n\nComplete each task according to its "Done when" checklist.`
}
const changedFiles = []
const sessionId = task.description.match(/TLS-[\w-]+/)?.[0] || 'lifecycle'
for (const batch of batches) {
if (batch.tasks.length === 1 && isSimpleTask(batch.tasks[0])) {
// Simple task: direct file editing
const batchPrompt = buildBatchPrompt(batch)
const batchId = `${sessionId}-B${batches.indexOf(batch) + 1}`
if (batch.tasks.length === 1 && isSimpleTask(batch.tasks[0]) && executor === 'agent') {
// Simple task + Agent mode: direct file editing
const t = batch.tasks[0]
for (const f of (t.files || [])) {
const content = Read(f.path)
Edit({ file_path: f.path, old_string: "...", new_string: "..." })
changedFiles.push(f.path)
}
} else {
// Complex task(s): delegate to code-developer sub-agent
const prompt = batch.tasks.map(buildExecutionPrompt).join('\n\n---\n')
} else if (executor === 'agent') {
// Agent execution (synchronous)
Task({
subagent_type: "code-developer",
run_in_background: false,
description: batch.tasks.map(t => t.title).join(' | '),
prompt: `## Goal\n${plan.summary}\n\n## Tasks\n${prompt}\n\n## Context\n### Project Guidelines\n@.workflow/project-guidelines.json\n\nComplete each task according to its "Done when" checklist.`
prompt: batchPrompt
})
batch.tasks.forEach(t => (t.files || []).forEach(f => changedFiles.push(f.path)))
} else if (executor === 'codex') {
// Codex CLI execution (background)
Bash(
`ccw cli -p "${batchPrompt}" --tool codex --mode write --id ${batchId}`,
{ run_in_background: true }
)
// STOP — CLI 后台执行,等待 task hook callback
batch.tasks.forEach(t => (t.files || []).forEach(f => changedFiles.push(f.path)))
} else if (executor === 'gemini') {
// Gemini CLI execution (background)
Bash(
`ccw cli -p "${batchPrompt}" --tool gemini --mode write --id ${batchId}`,
{ run_in_background: true }
)
// STOP — CLI 后台执行,等待 task hook callback
batch.tasks.forEach(t => (t.files || []).forEach(f => changedFiles.push(f.path)))
}
// Progress update
mcp__ccw-tools__team_msg({ operation: "log", team: teamName, from: "executor", to: "coordinator", type: "impl_progress", summary: `Batch完成: ${changedFiles.length}个文件已变更` })
mcp__ccw-tools__team_msg({ operation: "log", team: teamName, from: "executor", to: "coordinator", type: "impl_progress", summary: `Batch完成 (${executor}): ${changedFiles.length}个文件已变更` })
}
function isSimpleTask(task) {
@@ -183,6 +238,22 @@ const testFiles = changedFiles
.map(f => f.replace(/\/src\//, '/tests/').replace(/\.(ts|js)$/, '.test.$1'))
.filter(f => Bash(`test -f ${f} && echo exists || true`).includes('exists'))
if (testFiles.length > 0) Bash(`npx jest ${testFiles.join(' ')} --passWithNoTests 2>&1 || true`)
// Optional: Code review (if configured by coordinator)
if (codeReview !== 'Skip') {
if (codeReview === 'Gemini Review' || codeReview === 'Gemini') {
Bash(`ccw cli -p "PURPOSE: Code review for IMPL changes against plan convergence criteria
TASK: • Verify convergence criteria • Check test coverage • Analyze code quality
MODE: analysis
CONTEXT: @**/* | Memory: Review lifecycle IMPL execution
EXPECTED: Quality assessment with issue identification
CONSTRAINTS: analysis=READ-ONLY" --tool gemini --mode analysis --id ${sessionId}-review`,
{ run_in_background: true })
} else if (codeReview === 'Codex Review' || codeReview === 'Codex') {
Bash(`ccw cli --tool codex --mode review --uncommitted`,
{ run_in_background: true })
}
}
```
### Phase 5: Report to Coordinator
@@ -192,7 +263,7 @@ mcp__ccw-tools__team_msg({
operation: "log", team: teamName,
from: "executor", to: "coordinator",
type: "impl_complete",
summary: `IMPL完成: ${[...new Set(changedFiles)].length}个文件变更, syntax=${hasSyntaxErrors ? 'errors' : 'clean'}`
summary: `IMPL完成 (${executor}): ${[...new Set(changedFiles)].length}个文件变更, syntax=${hasSyntaxErrors ? 'errors' : 'clean'}`
})
SendMessage({
@@ -201,6 +272,8 @@ SendMessage({
content: `## Implementation Complete
**Task**: ${task.subject}
**Executor**: ${executor}
**Code Review**: ${codeReview}
### Changed Files
${[...new Set(changedFiles)].map(f => '- ' + f).join('\n')}
@@ -211,9 +284,10 @@ ${acceptanceStatus.map(t => '**' + t.title + '**: ' + (t.criteria.every(c => c.m
### Validation
- Syntax: ${hasSyntaxErrors ? 'Has errors (attempted fix)' : 'Clean'}
- Tests: ${testFiles.length > 0 ? 'Ran' : 'N/A'}
${executor !== 'agent' ? `- CLI Resume ID: ${sessionId}-B*` : ''}
Implementation is ready for testing and review.`,
summary: `IMPL complete: ${[...new Set(changedFiles)].length} files changed`
summary: `IMPL complete (${executor}): ${[...new Set(changedFiles)].length} files changed`
})
TaskUpdate({ taskId: task.id, status: 'completed' })
@@ -227,8 +301,11 @@ TaskUpdate({ taskId: task.id, status: 'completed' })
|----------|------------|
| No IMPL-* tasks available | Idle, wait for coordinator assignment |
| Plan file not found | Notify coordinator, request plan location |
| Unknown execution_method | Fallback to `agent` with warning |
| Syntax errors after implementation | Attempt auto-fix, report remaining errors |
| Sub-agent failure | Retry once, then attempt direct implementation |
| Agent (code-developer) failure | Retry once, then attempt direct implementation |
| CLI (Codex/Gemini) failure | Provide resume command with fixed ID, report error |
| CLI timeout | Use fixed ID `${sessionId}-B*` for resume |
| File conflict / merge issue | Notify coordinator, request guidance |
| Test failures in self-validation | Report in completion message, let tester handle |
| Circular dependencies in plan | Execute in plan order, ignore dependency chain |

View File

@@ -180,6 +180,83 @@ Final: planner 发送 all_planned → executor 完成剩余 EXEC-* → 结束
- executor 持续轮询并消费可用的 EXEC-* 任务
- 当 planner 发送 `all_planned` 消息后executor 完成所有剩余任务即可结束
## Execution Method Selection
在编排模式或直接调用 executor 前,**必须先确定执行方式**。支持 3 种执行后端:
| Executor | 后端 | 适用场景 |
|----------|------|----------|
| `agent` | code-developer subagent | 简单任务、同步执行 |
| `codex` | `ccw cli --tool codex --mode write` | 复杂任务、后台执行 |
| `gemini` | `ccw cli --tool gemini --mode write` | 分析类任务、后台执行 |
### 选择逻辑
```javascript
const autoYes = args.includes('--auto') || args.includes('-y')
const explicitExec = args.match(/--exec[=\s]+(agent|codex|gemini|auto)/i)?.[1]
let executionConfig
if (explicitExec) {
// 显式指定
executionConfig = {
executionMethod: explicitExec.charAt(0).toUpperCase() + explicitExec.slice(1),
codeReviewTool: "Skip"
}
} else if (autoYes) {
// Auto 模式:默认 Agent + Skip review
executionConfig = { executionMethod: "Auto", codeReviewTool: "Skip" }
} else {
// 交互选择
executionConfig = AskUserQuestion({
questions: [
{
question: "选择执行方式:",
header: "Execution",
multiSelect: false,
options: [
{ label: "Agent", description: "code-developer agent同步适合简单任务" },
{ label: "Codex", description: "Codex CLI后台适合复杂任务" },
{ label: "Gemini", description: "Gemini CLI后台适合分析类任务" },
{ label: "Auto", description: "根据任务复杂度自动选择" }
]
},
{
question: "执行后是否进行代码审查?",
header: "Code Review",
multiSelect: false,
options: [
{ label: "Skip", description: "不审查" },
{ label: "Gemini Review", description: "Gemini CLI 审查" },
{ label: "Codex Review", description: "Git-aware review--uncommitted" },
{ label: "Agent Review", description: "当前 agent 审查" }
]
}
]
})
}
// Auto 解析:根据 solution task_count 决定
function resolveExecutor(taskCount) {
if (executionConfig.executionMethod === 'Auto') {
return taskCount <= 3 ? 'agent' : 'codex'
}
return executionConfig.executionMethod.toLowerCase()
}
```
### 通过 args 指定
```bash
# 显式指定
Skill(skill="team-planex", args="--exec=codex ISS-xxx")
Skill(skill="team-planex", args="--exec=agent --text '简单功能'")
# Auto 模式(跳过交互)
Skill(skill="team-planex", args="-y --text '添加日志'")
```
## Orchestration Mode
当不带 `--role` 调用时SKILL.md 进入轻量编排模式:
@@ -195,7 +272,10 @@ const planMatch = args.match(/--plan\s+(\S+)/)
let plannerInput = args // 透传给 planner
// 3. 创建初始 PLAN-* 任务
// 3. 执行方式选择(见上方 Execution Method Selection
// executionConfig 已确定: { executionMethod, codeReviewTool }
// 4. 创建初始 PLAN-* 任务
TaskCreate({
subject: "PLAN-001: 初始规划",
description: `规划任务。输入: ${plannerInput}`,
@@ -203,7 +283,7 @@ TaskCreate({
owner: "planner"
})
// 4. Spawn planner agent
// 5. Spawn planner agent
Task({
subagent_type: "general-purpose",
team_name: teamName,
@@ -212,10 +292,17 @@ Task({
当你收到 PLAN-* 任务时,调用 Skill(skill="team-planex", args="--role=planner") 执行。
当前输入: ${plannerInput}
## 执行配置
executor 的执行方式已确定: ${executionConfig.executionMethod}
创建 EXEC-* 任务时,在 description 中包含:
execution_method: ${executionConfig.executionMethod}
code_review: ${executionConfig.codeReviewTool}
## 角色准则(强制)
- 你只能处理 PLAN-* 前缀的任务
- 所有输出必须带 [planner] 标识前缀
- 完成每个 wave 后立即创建 EXEC-* 任务供 executor 消费
- EXEC-* 任务 description 中必须包含 execution_method 字段
## 消息总线(必须)
每次 SendMessage 前,先调用 mcp__ccw-tools__team_msg 记录。
@@ -227,7 +314,7 @@ Task({
4. TaskUpdate completed → 检查下一个任务`
})
// 5. Spawn executor agent
// 6. Spawn executor agent
Task({
subagent_type: "general-purpose",
team_name: teamName,
@@ -235,9 +322,15 @@ Task({
prompt: `你是 team "${teamName}" 的 EXECUTOR。
当你收到 EXEC-* 任务时,调用 Skill(skill="team-planex", args="--role=executor") 执行。
## 执行配置
默认执行方式: ${executionConfig.executionMethod}
代码审查: ${executionConfig.codeReviewTool}
(每个 EXEC-* 任务 description 中可能包含 execution_method 覆盖)
## 角色准则(强制)
- 你只能处理 EXEC-* 前缀的任务
- 所有输出必须带 [executor] 标识前缀
- 根据 execution_method 选择执行后端Agent/Codex/Gemini
- 每个 solution 完成后通知 planner
## 消息总线(必须)

View File

@@ -0,0 +1,402 @@
# Role: executor
加载 solution → 根据 execution_method 路由到对应后端Agent/Codex/Gemini→ 测试验证 → 提交。支持多种 CLI 执行后端,执行方式在 skill 启动前已确定(见 SKILL.md Execution Method Selection
## Role Identity
- **Name**: `executor`
- **Task Prefix**: `EXEC-*`
- **Responsibility**: Code implementation (solution → route to backend → test → commit)
- **Communication**: SendMessage to planner only
- **Output Tag**: `[executor]`
## Role Boundaries
### MUST
- 仅处理 `EXEC-*` 前缀的任务
- 所有输出必须带 `[executor]` 标识
- 按照 EXEC-* 任务中的 `execution_method` 字段选择执行后端
- 每个 issue 完成后通知 planner
- 持续轮询新的 EXEC-* 任务planner 可能随时创建新 wave
### MUST NOT
- ❌ 创建 issueplanner 职责)
- ❌ 修改 solution 或 queueplanner 职责)
- ❌ 调用 issue-plan-agent 或 issue-queue-agent
- ❌ 直接与用户交互AskUserQuestion
- ❌ 为 planner 创建 PLAN-* 任务
## Message Types
| Type | Direction | Trigger | Description |
|------|-----------|---------|-------------|
| `impl_complete` | executor → planner | Implementation and tests pass | 单个 issue 实现完成 |
| `impl_failed` | executor → planner | Implementation failed after retries | 实现失败 |
| `wave_done` | executor → planner | All EXEC tasks in a wave completed | 整个 wave 完成 |
| `error` | executor → planner | Blocking error | 执行错误 |
## Toolbox
### Execution Backends
| Backend | Tool | Invocation | Mode |
|---------|------|------------|------|
| `agent` | code-developer subagent | `Task({ subagent_type: "code-developer" })` | 同步 |
| `codex` | Codex CLI | `ccw cli --tool codex --mode write` | 后台 |
| `gemini` | Gemini CLI | `ccw cli --tool gemini --mode write` | 后台 |
### Direct Capabilities
| Tool | Purpose |
|------|---------|
| `Read` | 读取 solution plan 和队列文件 |
| `Write` | 写入实现产物 |
| `Edit` | 编辑源代码 |
| `Bash` | 运行测试、git 操作、CLI 调用 |
### CLI Capabilities
| CLI Command | Purpose |
|-------------|---------|
| `ccw issue status <id> --json` | 查看 issue 状态 |
| `ccw issue solutions <id> --json` | 加载 bound solution |
| `ccw issue update <id> --status in-progress` | 更新 issue 状态为进行中 |
| `ccw issue update <id> --status resolved` | 标记 issue 已解决 |
## Execution Method Resolution
从 EXEC-* 任务的 description 中解析执行方式:
```javascript
// 从任务描述中解析 execution_method
function resolveExecutor(taskDesc, solutionTaskCount) {
const methodMatch = taskDesc.match(/execution_method:\s*(Agent|Codex|Gemini|Auto)/i)
const method = methodMatch ? methodMatch[1] : 'Auto'
if (method.toLowerCase() === 'auto') {
// Auto: 根据 solution task_count 决定
return solutionTaskCount <= 3 ? 'agent' : 'codex'
}
return method.toLowerCase() // 'agent' | 'codex' | 'gemini'
}
// 从任务描述中解析 code_review 配置
function resolveCodeReview(taskDesc) {
const reviewMatch = taskDesc.match(/code_review:\s*(\S+)/i)
return reviewMatch ? reviewMatch[1] : 'Skip'
}
```
## Execution Prompt Builder
统一的 prompt 构建,所有后端共用:
```javascript
function buildExecutionPrompt(issueId, solution) {
return `
## Issue
ID: ${issueId}
Title: ${solution.bound.title || 'N/A'}
## Solution Plan
${JSON.stringify(solution.bound, null, 2)}
## Implementation Requirements
1. Follow the solution plan tasks in order
2. Write clean, minimal code following existing patterns
3. Run tests after each significant change
4. Ensure all existing tests still pass
5. Do NOT over-engineer — implement exactly what the solution specifies
## Quality Checklist
- [ ] All solution tasks implemented
- [ ] No TypeScript/linting errors
- [ ] Existing tests pass
- [ ] New tests added where appropriate
- [ ] No security vulnerabilities introduced
## Project Guidelines
@.workflow/project-guidelines.json
`
}
```
## Execution (5-Phase)
### Phase 1: Task Discovery
```javascript
const tasks = TaskList()
const myTasks = tasks.filter(t =>
t.subject.startsWith('EXEC-') &&
t.owner === 'executor' &&
t.status === 'pending' &&
t.blockedBy.length === 0
)
if (myTasks.length === 0) return // idle — wait for planner to create EXEC tasks
const task = TaskGet({ taskId: myTasks[0].id })
TaskUpdate({ taskId: task.id, status: 'in_progress' })
```
### Phase 2: Load Solution & Resolve Executor
```javascript
// Extract issue ID from task description
const issueIdMatch = task.description.match(/ISS-\d{8}-\d{6}/)
const issueId = issueIdMatch ? issueIdMatch[0] : null
if (!issueId) {
mcp__ccw-tools__team_msg({
operation: "log", team: "planex", from: "executor", to: "planner",
type: "error",
summary: "[executor] No issue ID found in task"
})
SendMessage({
type: "message", recipient: "planner",
content: "## [executor] Error\nNo issue ID in task description",
summary: "[executor] error: no issue ID"
})
TaskUpdate({ taskId: task.id, status: 'completed' })
return
}
// Load solution plan
const solJson = Bash(`ccw issue solutions ${issueId} --json`)
const solution = JSON.parse(solJson)
if (!solution.bound) {
mcp__ccw-tools__team_msg({
operation: "log", team: "planex", from: "executor", to: "planner",
type: "error",
summary: `[executor] No bound solution for ${issueId}`
})
SendMessage({
type: "message", recipient: "planner",
content: `## [executor] Error\nNo bound solution for ${issueId}`,
summary: `[executor] error: no solution for ${issueId}`
})
TaskUpdate({ taskId: task.id, status: 'completed' })
return
}
// Resolve execution method from task description
const taskCount = solution.bound.task_count || solution.bound.tasks?.length || 0
const executor = resolveExecutor(task.description, taskCount)
const codeReview = resolveCodeReview(task.description)
// Update issue status
Bash(`ccw issue update ${issueId} --status in-progress`)
```
### Phase 3: Implementation (Multi-Backend Routing)
根据 `executor` 变量路由到对应后端:
#### Option A: Agent Execution (`executor === 'agent'`)
同步调用 code-developer subagent适合简单任务task_count ≤ 3
```javascript
if (executor === 'agent') {
const implResult = Task({
subagent_type: "code-developer",
run_in_background: false,
description: `Implement solution for ${issueId}`,
prompt: buildExecutionPrompt(issueId, solution)
})
}
```
#### Option B: Codex CLI Execution (`executor === 'codex'`)
后台调用 Codex CLI适合复杂任务。使用固定 ID 支持 resume。
```javascript
if (executor === 'codex') {
const fixedId = `planex-${issueId}`
Bash(
`ccw cli -p "${buildExecutionPrompt(issueId, solution)}" --tool codex --mode write --id ${fixedId}`,
{ run_in_background: true }
)
// STOP — CLI 后台执行,等待 task hook callback 通知完成
// 失败时 resume:
// ccw cli -p "Continue implementation" --resume ${fixedId} --tool codex --mode write --id ${fixedId}-retry
}
```
#### Option C: Gemini CLI Execution (`executor === 'gemini'`)
后台调用 Gemini CLI适合需要分析的复合任务。
```javascript
if (executor === 'gemini') {
const fixedId = `planex-${issueId}`
Bash(
`ccw cli -p "${buildExecutionPrompt(issueId, solution)}" --tool gemini --mode write --id ${fixedId}`,
{ run_in_background: true }
)
// STOP — CLI 后台执行,等待 task hook callback 通知完成
}
```
### Phase 4: Verify & Commit
```javascript
// Detect test command from package.json or project config
let testCmd = 'npm test'
try {
const pkgJson = JSON.parse(Read('package.json'))
if (pkgJson.scripts?.test) testCmd = 'npm test'
else if (pkgJson.scripts?.['test:unit']) testCmd = 'npm run test:unit'
} catch {
// Fallback: try common test runners
}
// Verify implementation
const testResult = Bash(`${testCmd} 2>&1 || echo "TEST_FAILED"`)
const testPassed = !testResult.includes('TEST_FAILED') && !testResult.includes('FAIL')
if (!testPassed) {
// Implementation failed — report to planner
mcp__ccw-tools__team_msg({
operation: "log", team: "planex", from: "executor", to: "planner",
type: "impl_failed",
summary: `[executor] Tests failing for ${issueId} after implementation (via ${executor})`
})
SendMessage({
type: "message", recipient: "planner",
content: `## [executor] Implementation Failed
**Issue**: ${issueId}
**Executor**: ${executor}
**Status**: Tests failing after implementation
**Test Output** (truncated):
${testResult.slice(0, 500)}
**Action**: May need solution revision or manual intervention.
${executor !== 'agent' ? `**Resume**: \`ccw cli -p "Fix failing tests" --resume planex-${issueId} --tool ${executor} --mode write --id planex-${issueId}-fix\`` : ''}`,
summary: `[executor] impl_failed: ${issueId} (${executor})`
})
TaskUpdate({ taskId: task.id, status: 'completed' })
return
}
// Optional: Code review (if configured)
if (codeReview !== 'Skip') {
executeCodeReview(codeReview, issueId)
}
// Update issue status to resolved
Bash(`ccw issue update ${issueId} --status resolved`)
```
### Code Review (Optional)
```javascript
function executeCodeReview(reviewTool, issueId) {
const reviewPrompt = `PURPOSE: Code review for ${issueId} implementation against solution plan
TASK: • Verify solution convergence criteria • Check test coverage • Analyze code quality • Identify issues
MODE: analysis
CONTEXT: @**/* | Memory: Review planex execution for ${issueId}
EXPECTED: Quality assessment with issue identification and recommendations
CONSTRAINTS: Focus on solution adherence and code quality | analysis=READ-ONLY`
if (reviewTool === 'Gemini Review') {
Bash(`ccw cli -p "${reviewPrompt}" --tool gemini --mode analysis --id planex-review-${issueId}`,
{ run_in_background: true })
} else if (reviewTool === 'Codex Review') {
// Codex review: --uncommitted flag only (no prompt with target flags)
Bash(`ccw cli --tool codex --mode review --uncommitted`,
{ run_in_background: true })
} else if (reviewTool === 'Agent Review') {
// Current agent performs review inline
// Read solution convergence criteria and verify against implementation
}
}
```
### Phase 5: Report + Loop
```javascript
mcp__ccw-tools__team_msg({
operation: "log",
team: "planex",
from: "executor",
to: "planner",
type: "impl_complete",
summary: `[executor] Implementation complete for ${issueId} via ${executor}, tests passing`
})
SendMessage({
type: "message",
recipient: "planner",
content: `## [executor] Implementation Complete
**Issue**: ${issueId}
**Executor**: ${executor}
**Solution**: ${solution.bound.id}
**Code Review**: ${codeReview}
**Status**: All tests passing
**Issue Status**: Updated to resolved`,
summary: `[executor] EXEC complete: ${issueId} (${executor})`
})
TaskUpdate({ taskId: task.id, status: 'completed' })
// Check for next EXEC-* task (may include new wave tasks from planner)
const nextTasks = TaskList().filter(t =>
t.subject.startsWith('EXEC-') &&
t.owner === 'executor' &&
t.status === 'pending' &&
t.blockedBy.length === 0
)
if (nextTasks.length > 0) {
// Continue with next task → back to Phase 1
} else {
// Check if planner has sent all_planned signal
// If yes and no more tasks → send wave_done and exit
mcp__ccw-tools__team_msg({
operation: "log",
team: "planex",
from: "executor",
to: "planner",
type: "wave_done",
summary: "[executor] All EXEC tasks completed"
})
SendMessage({
type: "message",
recipient: "planner",
content: `## [executor] All Tasks Done
All EXEC-* tasks have been completed. Pipeline finished.`,
summary: "[executor] wave_done: all complete"
})
}
```
## Error Handling
| Scenario | Resolution |
|----------|------------|
| No EXEC-* tasks available | Idle, wait for planner to create tasks |
| Solution plan not found | Report error to planner |
| Unknown execution_method | Fallback to `agent` with warning |
| Agent (code-developer) failure | Retry once, then report impl_failed |
| CLI (Codex/Gemini) failure | Provide resume command with fixed ID, report impl_failed |
| CLI timeout | Use fixed ID `planex-{issueId}` for resume |
| Tests failing after implementation | Report impl_failed with test output + resume info |
| Issue status update failure | Log warning, continue with report |
| Dependency not yet complete | Wait — task is blocked by blockedBy |
| All tasks done but planner still planning | Send wave_done, then idle for more |

View File

@@ -0,0 +1,373 @@
# Role: planner
需求拆解 → issue 创建 → 方案设计 → 队列编排 → EXEC 任务派发。内部调用 issue-plan-agent 和 issue-queue-agent并通过 Wave Pipeline 持续推进。planner 同时承担 lead 角色(无独立 coordinator
## Role Identity
- **Name**: `planner`
- **Task Prefix**: `PLAN-*`
- **Responsibility**: Planning lead (requirement → issues → solutions → queue → dispatch)
- **Communication**: SendMessage to executor; 需要时 AskUserQuestion
- **Output Tag**: `[planner]`
## Role Boundaries
### MUST
- 仅处理 `PLAN-*` 前缀的任务
- 所有输出必须带 `[planner]` 标识
- 完成每个 wave 的 queue 后**立即创建 EXEC-\* 任务**
- 不等待 executor 完成当前 wave直接进入下一 wave 规划
### MUST NOT
- ❌ 直接编写/修改业务代码executor 职责)
- ❌ 调用 code-developer agent
- ❌ 运行项目测试
- ❌ git commit 代码变更
## Message Types
| Type | Direction | Trigger | Description |
|------|-----------|---------|-------------|
| `wave_ready` | planner → executor | Wave queue 完成 + EXEC 任务已创建 | 新 wave 可执行 |
| `queue_ready` | planner → executor | 单个 issue 的 queue 就绪 | 增量通知 |
| `all_planned` | planner → executor | 所有 wave 规划完毕 | 最终信号 |
| `error` | planner → executor | 阻塞性错误 | 规划失败 |
## Toolbox
### Subagent Capabilities
| Agent Type | Purpose |
|------------|---------|
| `issue-plan-agent` | Closed-loop planning: ACE exploration + solution generation + binding |
| `issue-queue-agent` | Solution ordering + conflict detection → execution queue |
### CLI Capabilities
| CLI Command | Purpose |
|-------------|---------|
| `ccw issue new --text '...' --json` | 从文本创建 issue |
| `ccw issue status <id> --json` | 查看 issue 状态 |
| `ccw issue solutions <id> --json` | 查看已绑定 solution |
| `ccw issue bind <id> <sol-id>` | 绑定 solution 到 issue |
### Skill Capabilities
| Skill | Purpose |
|-------|---------|
| `Skill(skill="issue:new", args="--text '...'")` | 从文本创建 issue |
## Execution (5-Phase)
### Phase 1: Task Discovery
```javascript
const tasks = TaskList()
const myTasks = tasks.filter(t =>
t.subject.startsWith('PLAN-') &&
t.owner === 'planner' &&
t.status === 'pending' &&
t.blockedBy.length === 0
)
if (myTasks.length === 0) return // idle
const task = TaskGet({ taskId: myTasks[0].id })
TaskUpdate({ taskId: task.id, status: 'in_progress' })
```
### Phase 2: Input Parsing
解析任务描述中的输入类型,确定处理方式。
```javascript
const desc = task.description
const args = "$ARGUMENTS"
// 1) 已有 Issue IDs
const issueIds = (desc + ' ' + args).match(/ISS-\d{8}-\d{6}/g) || []
// 2) 文本输入
const textMatch = (desc + ' ' + args).match(/--text\s+['"]([^'"]+)['"]/)
const inputText = textMatch ? textMatch[1] : null
// 3) Plan 文件输入
const planMatch = (desc + ' ' + args).match(/--plan\s+(\S+)/)
const planFile = planMatch ? planMatch[1] : null
// Determine input type
let inputType = 'unknown'
if (issueIds.length > 0) inputType = 'issue_ids'
else if (inputText) inputType = 'text'
else if (planFile) inputType = 'plan_file'
else {
// 任务描述本身可能就是需求文本
inputType = 'text_from_description'
}
```
### Phase 3: Issue Processing Pipeline
根据输入类型执行不同的处理路径:
#### Path A: 文本输入 → 创建 Issue
```javascript
if (inputType === 'text' || inputType === 'text_from_description') {
const text = inputText || desc
// 使用 issue:new skill 创建 issue
Skill(skill="issue:new", args=`--text '${text}'`)
// 获取新创建的 issue ID
// issue:new 会输出创建的 issue ID
// 将其加入 issueIds 列表
issueIds.push(newIssueId)
}
```
#### Path B: Plan 文件 → 批量创建 Issues
```javascript
if (inputType === 'plan_file') {
const planContent = Read(planFile)
// 解析 Plan 文件中的 Phase/步骤
// 每个 Phase 或独立步骤创建一个 issue
const phases = parsePlanPhases(planContent)
for (const phase of phases) {
Skill(skill="issue:new", args=`--text '${phase.title}: ${phase.description}'`)
issueIds.push(newIssueId)
}
}
```
#### Path C: Issue IDs → 直接进入规划
Issue IDs 已就绪,直接进入 solution 规划。
#### Wave 规划(所有路径汇聚)
将 issueIds 按波次分组规划:
```javascript
const projectRoot = Bash('cd . && pwd').trim()
// 按批次分组(每 wave 最多 5 个 issues
const WAVE_SIZE = 5
const waves = []
for (let i = 0; i < issueIds.length; i += WAVE_SIZE) {
waves.push(issueIds.slice(i, i + WAVE_SIZE))
}
let waveNum = 0
for (const waveIssues of waves) {
waveNum++
// Step 1: 调用 issue-plan-agent 生成 solutions
const planResult = Task({
subagent_type: "issue-plan-agent",
run_in_background: false,
description: `Plan solutions for wave ${waveNum}`,
prompt: `
issue_ids: ${JSON.stringify(waveIssues)}
project_root: "${projectRoot}"
## Requirements
- Generate solutions for each issue
- Auto-bind single solutions
- For multiple solutions, select the most pragmatic one
`
})
// Step 2: 调用 issue-queue-agent 形成 queue
const queueResult = Task({
subagent_type: "issue-queue-agent",
run_in_background: false,
description: `Form queue for wave ${waveNum}`,
prompt: `
issue_ids: ${JSON.stringify(waveIssues)}
project_root: "${projectRoot}"
## Requirements
- Order solutions by dependency (DAG)
- Detect conflicts between solutions
- Output execution queue
`
})
// Step 3: → Phase 4 (Wave Dispatch)
}
```
### Phase 4: Wave Dispatch
每个 wave 的 queue 完成后,**立即创建 EXEC-\* 任务**供 executor 消费。
```javascript
// Read the generated queue
const queuePath = `.workflow/issues/queue/execution-queue.json`
const queue = JSON.parse(Read(queuePath))
// Create EXEC-* tasks from queue entries
const execTasks = []
for (const entry of queue.queue) {
const execTask = TaskCreate({
subject: `EXEC-W${waveNum}-${entry.issue_id}: 实现 ${entry.title || entry.issue_id}`,
description: `## 执行任务
**Wave**: ${waveNum}
**Issue**: ${entry.issue_id}
**Solution**: ${entry.solution_id}
**Priority**: ${entry.priority || 'normal'}
**Dependencies**: ${entry.depends_on?.join(', ') || 'none'}
加载 solution plan 并实现代码。完成后运行测试、提交。`,
activeForm: `实现 ${entry.issue_id}`,
owner: "executor"
})
execTasks.push(execTask)
}
// Set up dependency chains between EXEC tasks (based on queue DAG)
for (const entry of queue.queue) {
if (entry.depends_on?.length > 0) {
const thisTask = execTasks.find(t => t.subject.includes(entry.issue_id))
const depTasks = entry.depends_on.map(depId =>
execTasks.find(t => t.subject.includes(depId))
).filter(Boolean)
if (thisTask && depTasks.length > 0) {
TaskUpdate({
taskId: thisTask.id,
addBlockedBy: depTasks.map(t => t.id)
})
}
}
}
// Notify executor: wave ready
mcp__ccw-tools__team_msg({
operation: "log",
team: "planex",
from: "planner",
to: "executor",
type: "wave_ready",
summary: `[planner] Wave ${waveNum} ready: ${execTasks.length} EXEC tasks created`
})
SendMessage({
type: "message",
recipient: "executor",
content: `## [planner] Wave ${waveNum} Ready
**Issues**: ${waveIssues.join(', ')}
**EXEC Tasks Created**: ${execTasks.length}
**Queue**: ${queuePath}
Executor 可以开始实现。`,
summary: `[planner] wave_ready: wave ${waveNum}`
})
// 不等待 executor 完成,继续下一 wave → back to Phase 3 loop
```
### Phase 5: Report + Finalize
所有 wave 规划完毕后,发送最终信号。
```javascript
// All waves planned
mcp__ccw-tools__team_msg({
operation: "log",
team: "planex",
from: "planner",
to: "executor",
type: "all_planned",
summary: `[planner] All ${waveNum} waves planned, ${issueIds.length} issues total`
})
SendMessage({
type: "message",
recipient: "executor",
content: `## [planner] All Waves Planned
**Total Waves**: ${waveNum}
**Total Issues**: ${issueIds.length}
**Status**: 所有规划完毕,等待 executor 完成剩余 EXEC-* 任务
Pipeline 完成后请 executor 发送 wave_done 确认。`,
summary: `[planner] all_planned: ${waveNum} waves, ${issueIds.length} issues`
})
TaskUpdate({ taskId: task.id, status: 'completed' })
// Check for next PLAN-* task (e.g., user added more requirements)
const nextTasks = TaskList().filter(t =>
t.subject.startsWith('PLAN-') &&
t.owner === 'planner' &&
t.status === 'pending' &&
t.blockedBy.length === 0
)
if (nextTasks.length > 0) {
// Continue with next task → back to Phase 1
}
```
## Plan File Parsing
解析 Plan 文件为 phases 列表:
```javascript
function parsePlanPhases(planContent) {
const phases = []
// 匹配 ## Phase N: Title 或 ## Step N: Title 或 ### N. Title
const phaseRegex = /^#{2,3}\s+(?:Phase|Step|阶段)\s*\d*[:.]\s*(.+?)$/gm
let match
let lastIndex = 0
let lastTitle = null
while ((match = phaseRegex.exec(planContent)) !== null) {
if (lastTitle !== null) {
const description = planContent.slice(lastIndex, match.index).trim()
phases.push({ title: lastTitle, description })
}
lastTitle = match[1].trim()
lastIndex = match.index + match[0].length
}
// Last phase
if (lastTitle !== null) {
const description = planContent.slice(lastIndex).trim()
phases.push({ title: lastTitle, description })
}
// Fallback: 如果没有匹配到 Phase 结构,将整个内容作为单个 issue
if (phases.length === 0) {
const titleMatch = planContent.match(/^#\s+(.+)$/m)
phases.push({
title: titleMatch ? titleMatch[1] : 'Plan Implementation',
description: planContent.slice(0, 500)
})
}
return phases
}
```
## Error Handling
| Scenario | Resolution |
|----------|------------|
| No PLAN-* tasks available | Idle, wait for orchestrator |
| Issue creation failure | Retry once with simplified text, then report error |
| issue-plan-agent failure | Retry once, then report error and skip to next issue |
| issue-queue-agent failure | Retry once, then create EXEC tasks without DAG ordering |
| Plan file not found | Report error with expected path |
| Empty input (no issues, no text, no plan) | AskUserQuestion for clarification |
| Wave partially failed | Report partial success, continue with successful issues |