| name | ccw |
| description | Intelligent coordinator — classify intent via structured extraction (action × object × style), map to skill chain, execute wave-by-wave via spawn_agents_on_csv. Barrier skills trigger coordinator-side artifact analysis between waves to dynamically assemble subsequent skill_call args. Each wave can be 1 or N parallel tasks. |
| argument-hint | "intent text" [-y] [-c|--continue] [--dry-run] [--chain <name>] |
| allowed-tools | spawn_agents_on_csv, Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion |
Auto Mode
When -y or --yes: Skip clarification and confirmation prompts. Pass -y through to each step's skill invocation.
CCW
Usage
$ccw "implement user authentication with JWT"
$ccw -y "refactor the payment module"
$ccw --continue
$ccw --dry-run "add rate limiting to API endpoints"
$ccw --chain feature "add dark mode toggle"
Flags:
-y, --yes — Auto mode: skip all prompts; propagate -y to each skill
--continue — Resume latest paused session from last incomplete wave
--dry-run — Display planned chain without executing
--chain <name> — Force a specific chain (skips intent classification)
Session state: .workflow/.ccw-coordinate/{session-id}/
Core Output: tasks.csv (master) + wave-{N}-results.csv (per wave) + context.md (report)
Overview
Wave-based pipeline coordinator. The coordinator loop builds one wave CSV at a time, calls spawn_agents_on_csv, then performs coordinator-side artifact analysis before assembling the next wave. Barrier skills produce artifacts (plan.json, analysis results, etc.) that the coordinator reads to dynamically resolve args for subsequent steps.
Intent → Structured Extract → Resolve Chain → [Wave Loop]:
(action×object×style) (chainMap)
┌─────────────────────────────────────────────────┐
│ 1. Identify next wave (1 or N parallel steps) │
│ 2. Build wave-{N}.csv with skill_call per row │
│ 3. spawn_agents_on_csv(wave-{N}.csv) │
│ 4. Read wave-{N}-results.csv │
│ 5. If barrier skill: analyze artifacts, │
│ update context for subsequent steps │
│ 6. Merge into master tasks.csv │
└─────────────────────────────────────────────────┘
→ Report
Barrier Skills
Skills that produce artifacts requiring coordinator-side analysis before the next wave can be assembled. After a barrier skill completes, the coordinator reads its output and updates the execution context.
| Skill | Artifacts to Read | Context Updates |
|---|
analyze-with-file | .workflow/.analysis/ANL-*/conclusions.json | analysis_dir, gaps, phase |
brainstorm-with-file | .workflow/.brainstorm/*/ | brainstorm_dir, features |
workflow-plan | .workflow/active/WFS-*/workflow-session.json | plan_dir, task_count |
workflow-lite-planex | .workflow/.lite-plan/*/plan.json | plan_dir, task_count |
spec-generator | .workflow/.spec/*/ | spec_session_id |
roadmap-with-file | .workflow/.roadmap/*/roadmap.md | roadmap_dir |
workflow-tdd-plan | .workflow/.tdd-plan/*/ | tdd_plan_dir |
issue-discover | .workflow/.issues/*/ | issue_dir, issue_count |
debug-with-file | .workflow/.debug/*/ | debug_dir, findings |
Non-barrier skills (can be grouped into multi-task waves): workflow-execute, workflow-test-fix-cycle, review-cycle, clean, investigate, security-audit, ship, parallel-dev-cycle, brainstorm, all team-* skills
Phase 1: Structured Intent Extraction
Extract a structured intent tuple using LLM semantic understanding, then route deterministically via an action × object matrix.
Extract structured intent from user input:
{
"action": "<from action enum>",
"object": "<from object enum>",
"scope": "<module/file/area or null>",
"style": "<from style enum>",
"urgency": "<low | normal | high>"
}
Action enum:
| action | Semantic meaning |
|---|
create | Build something new — feature, project, component, spec |
fix | Repair something broken — fix bug, resolve error, patch |
analyze | Understand deeply — analyze, investigate, discuss, explore concept |
plan | Design approach — plan, break down, roadmap, decompose |
execute | Implement planned work — execute, implement, develop |
explore | Open-ended discovery — brainstorm, ideate, creative thinking |
debug | Diagnose failures — debug, diagnose, troubleshoot |
test | Run or create tests — test, generate test, TDD |
review | Evaluate code quality — review, code review |
refactor | Restructure code — refactor, clean up, tech debt |
convert | Bridge between workflows — convert brainstorm to issue |
Object enum:
| object | Meaning |
|---|
feature | New functionality or enhancement |
bug | Defect, error, broken behavior |
issue | Issue-tracker item for batch/structured management |
code | Source code in general |
test | Tests, test suite, test coverage |
spec | Specification, PRD, product requirements |
doc | Documentation |
ui | User interface, design, component |
performance | Performance characteristics |
security | Security concerns |
architecture | System architecture, design decisions |
project | Entire project (greenfield) |
team | Team-based execution |
Style enum:
| style | Meaning |
|---|
quick | Fast, lightweight, minimal ceremony |
documented | With file artifacts, discussion docs |
collaborative | Multi-agent, multi-perspective |
structured | Formal planning, spec-driven, phased |
iterative | Cycle-based, self-iterating with reflection |
tdd | Test-driven development |
default | No specific style preference |
Chain Map
Routing via detectTaskType(intent) → chain name → skill list.
Task Type Detection (action × object × style matrix)
function detectTaskType(intent) {
const { action, object, style, urgency } = intent;
if (urgency === 'high' && (action === 'fix' || object === 'bug')) return 'bugfix-hotfix';
if (style === 'tdd') return 'tdd';
if (style === 'collaborative' && action === 'plan') return 'collaborative-plan';
if (style === 'collaborative' && action === 'analyze') return 'analyze-wave';
if (style === 'collaborative' && action !== 'plan') return 'multi-cli';
if (style === 'iterative' && object === 'test') return 'integration-test';
if (style === 'iterative' && action === 'refactor') return 'refactor';
const matrix = {
'create': { 'project': 'greenfield', 'feature': 'feature', 'spec': 'spec-driven', : , : , : , : , : },
: { : , : , : , : , : , : },
:{ : , : , : , : , : },
:{ : , : , : , : },
: { : , : , : , : },
:{ : , : },
: { : style === ? : , : style === ? : },
: { : , : , : , : },
: { : },
:{ : },
:{ : , : },
};
(action === && style === && .(rawInput)) ;
(.(rawInput)) ;
(object === ) ;
(.(rawInput)) ;
actionMap = matrix[action];
(!actionMap) ;
actionMap[object] || actionMap[] || ;
}
Available Skills Inventory
Skills with SKILL.md (spawn_agents_on_csv native):
analyze-with-file, brainstorm, brainstorm-with-file, clean, csv-wave-pipeline, debug-with-file, issue-discover, parallel-dev-cycle, project-documentation-workflow, review-cycle, roadmap-with-file, spec-generator, workflow-execute, workflow-lite-planex, workflow-plan, workflow-tdd-plan, workflow-test-fix-cycle, team-planex, team-coordinate, team-lifecycle-v4, team-issue, team-review, team-testing, team-quality-assurance, team-tech-debt, team-perf-opt, team-arch-opt, team-brainstorm, team-ultra-analyze, team-uidesign, team-ui-polish, team-ux-improve, team-visual-a11y, team-frontend, team-frontend-debug, team-interactive-craft, team-motion-design, team-roadmap-dev
Skills with orchestrator.md (phase-based):
investigate, security-audit, ship, memory-capture
Chain Definitions (task_type → skill sequence)
All $skill-name references below correspond to actual .codex/skills/{skill-name}/ directories.
[B] = barrier skill (solo wave, coordinator analyzes artifacts after)
| task_type | Chain name | Steps (skills, in order) |
|---|
bugfix-hotfix | bugfix.hotfix | $workflow-lite-planex --hotfix |
bugfix | bugfix.standard | $investigate → $workflow-lite-planex --bugfix [B] → $workflow-test-fix-cycle |
feature (low) | rapid | $workflow-lite-planex [B] → $workflow-test-fix-cycle |
feature (high) | coupled | $workflow-plan [B] → $workflow-execute → $review-cycle → $workflow-test-fix-cycle |
greenfield | greenfield | $brainstorm-with-file [B] → $workflow-plan [B] → $workflow-execute → $workflow-test-fix-cycle |
brainstorm | brainstorm-to-plan | $brainstorm-with-file [B] → $workflow-plan [B] → $workflow-execute → $workflow-test-fix-cycle |
brainstorm-to-issue | brainstorm-to-issue | $brainstorm-with-file [B] → $parallel-dev-cycle |
debug-file | debug-with-file | $debug-with-file |
debug | investigate | $investigate |
analyze-file | analyze-to-plan | $analyze-with-file [B] → $workflow-lite-planex |
collaborative-plan | collaborative-plan | $brainstorm-with-file [B] → $workflow-execute |
roadmap | roadmap | $roadmap-with-file [B] → $team-planex |
spec-driven | spec-driven | $spec-generator [B] → $workflow-plan [B] → $workflow-execute → $workflow-test-fix-cycle |
tdd | tdd |
Implementation
Session Initialization
const dateStr = new Date().toISOString().substring(0, 10).replace(/-/g, '')
const timeStr = new Date().toISOString().substring(11, 19).replace(/:/g, '')
const sessionId = `CCW-${dateStr}-${timeStr}`
const sessionDir = `.workflow/.ccw-coordinate/${sessionId}`
Bash(`mkdir -p ${sessionDir}`)
Phase 1: Resolve Intent and Chain
--continue mode: Glob .workflow/.ccw-coordinate/CCW-*/state.json sorted by name desc; load the most recent; resume from first pending wave.
Fresh mode:
- Read
.workflow/state.json for project context (current_phase, workflow_name)
- If
--chain is given, use it directly
- Otherwise, extract structured intent
{action, object, scope, style, urgency} from user input using LLM semantic understanding
- Route via
detectTaskType(intent) matrix to get task_type
- Assess complexity (
low|medium|high) for complexity-adaptive routing
- If no confident classification and not
AUTO_YES: ask one clarifying question via AskUserQuestion
- Resolve the chain's skill list from Chain Definitions
- Write
state.json:
Write(`${sessionDir}/state.json`, JSON.stringify({
id: sessionId,
intent,
structured_intent: { action, object, scope, style, urgency },
task_type,
complexity,
chain: resolvedChain,
auto_yes: AUTO_YES,
status: "in_progress",
started_at: new Date().toISOString(),
context: {
phase: resolvedPhase,
plan_dir: null,
analysis_dir: null,
brainstorm_dir: null,
spec_session_id: null,
roadmap_dir: null,
tdd_plan_dir: null,
issue_dir: null,
debug_dir: null,
gaps: null
},
waves: [],
steps: CHAIN_STEPS[resolvedChain].map((skill, i) => ({
step_n: i + 1,
skill: skill.cmd,
args: skill.args ?? '',
is_barrier: .(skill.),
: ,
:
}))
}, , ))
--dry-run: Display the chain plan and stop.
Chain: <resolvedChain>
Type: <task_type> | Complexity: <complexity>
Steps:
1. $<cmd> <args> [BARRIER]
2. $<cmd> <args>
3. $<cmd> <args>
User confirmation (skip if AUTO_YES): Display the plan above and prompt Proceed? (yes/no).
Phase 2: Wave Execution Loop
The coordinator iterates over pending steps, grouping them into waves and executing one wave at a time.
Wave Grouping Rules
- A barrier skill is always alone in its wave (wave size = 1)
- Consecutive non-barrier skills with no inter-dependencies are grouped into one wave (wave size = N)
- After a barrier wave completes → coordinator analyzes artifacts → updates context → re-assembles subsequent step args
Per-Wave Execution
let waveNum = 0;
while (state.steps.some(s => s.status === 'pending')) {
waveNum++;
const waveSteps = buildNextWave(state.steps);
const waveCsv = waveSteps.map((step, i) => ({
id: String(step.step_n),
skill_call: buildSkillCall(step, state.context),
topic: `Chain "${state.chain}" step ${step.step_n}/${state.steps.length}`
}));
const csvContent = 'id,skill_call,topic\n' + waveCsv.map(r =>
`"${r.id}","${r.skill_call.replace(/"/g, '""')}","${r.topic}"`
).join('\n');
Write(`${sessionDir}/wave-${waveNum}.csv`, csvContent);
// 4. Execute wave
spawn_agents_on_csv({
csv_path: `${sessionDir}/wave-${waveNum}.csv`,
id_column: "id",
instruction: WAVE_INSTRUCTION,
max_workers: waveSteps.length > 1 ? waveSteps.length : 1,
max_runtime_seconds: 1800,
output_csv_path: `${sessionDir}/wave-${waveNum}-results.csv`,
output_schema: RESULT_SCHEMA
});
// 5. Read results, update step status
const results = readCSV(`${sessionDir}/wave-${waveNum}-results.csv${sessionDir}/state.json${sessionDir}/state.json
Instruction Template
你是 CSV job 子 agent。
先原样执行这一段技能调用:
{skill_call}
然后基于结果完成这一行任务说明:
{topic}
限制:
- 不要修改 .workflow/.ccw-coordinate/ 下的 state 文件
- skill 内部有自己的 session 管理,按 skill SKILL.md 执行即可
最后必须调用 `report_agent_job_result`,返回 JSON:
{"status":"completed|failed","skill_call":"{skill_call}","summary":"一句话结果","artifacts":"产物路径或空字符串","error":"失败原因或空字符串"}
Result Schema
const RESULT_SCHEMA = {
type: "object",
properties: {
status: { type: "string", enum: ["completed", "failed"] },
skill_call: { type: "string" },
summary: { type: "string" },
artifacts: { type: "string" },
error: { type: "string" }
},
required: ["status", "skill_call", "summary", "artifacts", "error"]
};
Barrier Analysis Logic
After a barrier skill completes, the coordinator reads its artifacts and updates state.context:
const BARRIER_SKILLS = new Set([
'analyze-with-file', 'brainstorm-with-file', 'workflow-plan',
'workflow-lite-planex', 'spec-generator', 'roadmap-with-file',
'workflow-tdd-plan', 'issue-discover', 'debug-with-file'
]);
function analyzeBarrierArtifacts(step, result, ctx) {
const artifactPath = result.artifacts;
switch (step.skill) {
case 'analyze-with-file':
const analysisFiles = Glob('.workflow/.analysis/ANL-*/conclusions.json');
const latest = analysisFiles.sort().pop();
if (latest) {
const conclusions = JSON.parse(Read(latest));
ctx.analysis_dir = latest.replace('/conclusions.json', '');
ctx.gaps = conclusions.gaps ?? null;
if (!ctx.phase) ctx.phase = conclusions.phase ?? null;
}
break;
:
ctx. = artifactPath;
;
:
wfSessions = ();
latestWf = wfSessions.().();
(latestWf) {
session = .((latestWf));
ctx. = latestWf.(, );
ctx. = session.?. ?? ;
}
;
:
litePlans = ();
latestPlan = litePlans.().();
(latestPlan) {
ctx. = latestPlan.(, );
ctx. = .((latestPlan)).?. ?? ;
}
;
:
ctx. = artifactPath;
;
:
ctx. = artifactPath;
;
:
ctx. = artifactPath;
;
:
ctx. = artifactPath;
;
:
ctx. = artifactPath;
ctx. = result.;
;
}
}
Skill Call Assembly
The coordinator builds each skill_call with resolved context — sub-agents just execute verbatim:
const AUTO_FLAG_MAP = {
'brainstorm-with-file': '-y',
'analyze-with-file': '-y',
'debug-with-file': '-y',
'workflow-plan': '-y',
'workflow-lite-planex': '-y',
'workflow-execute': '-y',
'workflow-test-fix-cycle': '-y',
'workflow-tdd-plan': '-y',
'spec-generator': '-y',
'roadmap-with-file': '-y',
'issue-discover': '-y',
'parallel-dev-cycle': '-y',
'review-cycle': '-y',
'clean': '-y',
'brainstorm': '-y',
'csv-wave-pipeline': '-y',
};
function buildSkillCall(step, ctx) {
let args = (step.args ?? '')
.replace(/{intent}/g, state.intent ?? '')
.replace(/{phase}/g, ctx.phase ?? '')
.replace(/{plan_dir}/g, ctx.plan_dir ?? '')
.(, ctx. ?? )
.(, ctx. ?? )
.(, ctx. ?? )
.(, ctx. ?? )
.(, ctx. ?? )
.(, ctx. ?? )
.(, ctx. ?? );
(!args.()) args = ;
(state.) {
flag = [step.];
(flag && !args.(flag)) args = args ? : flag;
}
.();
}
() {
pending = steps.( s. === );
(!pending.) [];
first = pending[];
(.(first.)) [first];
wave = [first];
( i = ; i < pending.; i++) {
(.(pending[i].)) ;
wave.(pending[i]);
}
wave;
}
Phase 3: Completion Report
state.status = state.steps.every(s => s.status === 'completed') ? 'completed' : state.status;
state.completed_at = new Date().toISOString();
Write(`${sessionDir}/state.json`, JSON.stringify(state, null, 2));
Generate context.md:
# CCW Coordinate Report — {chain}
## Summary
- Session: {sessionId}
- Chain: {chain}
- Type: {task_type} | Complexity: {complexity}
- Waves: {waveNum} executed
- Steps: {completed}/{total} completed
## Wave Results
### Wave {N} (barrier: {skill})
| Step | Skill Call | Status | Summary |
|------|-----------|--------|---------|
| {step_n} | {skill_call} | {status} | {summary} |
Artifacts: {artifacts}
Context update: {what changed}
Display:
=== CCW COORDINATE COMPLETE ===
Session: <sessionId>
Chain: <chain>
Type: <task_type> | Complexity: <complexity>
Waves: <N> executed
Steps: <completed>/<total>
WAVE RESULTS:
[W1] $analyze-with-file -y → ✓ found 3 gaps [BARRIER]
[W2] $workflow-lite-planex -y → ✓ 12 tasks planned [BARRIER]
[W3] $workflow-test-fix-cycle -y → ✓ all tests pass
State: .workflow/.ccw-coordinate/<sessionId>/state.json
Resume: $ccw --continue
CSV Schema
wave-{N}.csv (Per-Wave Input)
id,skill_call,topic
"1","$analyze-with-file ""fix auth"" -y","Chain ""bugfix.standard"" step 1/3"
| Column | Description |
|---|
id | Step number from chain (string) |
skill_call | Full skill invocation assembled by coordinator with resolved context |
topic | Brief description for the agent |
tasks.csv (Master State)
id,skill,args,wave_n,status,findings,artifacts,error
Accumulated across all waves. Updated after each wave completes.
Error Handling
| Code | Severity | Condition | Recovery |
|---|
| E001 | error | Intent unclassifiable after clarification | Default to feature chain (rapid) |
| E002 | error | --chain value not in chain map | List valid chains, abort |
| E003 | error | Wave timeout (max_runtime_seconds) | Mark step failed, abort chain |
| E004 | error | Barrier artifact not found | Retry wave once, then abort |
| E005 | error | --continue: no session found | List sessions, prompt |
| W001 | warning | Barrier artifact partial | Continue with available context |
Core Rules
- Start Immediately: Init session dir and write
state.json before any wave
- Wave-by-wave: Never start wave N+1 before wave N results are read and analyzed
- Barrier = solo wave: A barrier skill always executes alone; coordinator analyzes its artifacts before proceeding
- Non-barriers can parallel: Consecutive non-barrier skills in the same wave execute with
max_workers = N
- Coordinator owns context: Sub-agents never read prior results — coordinator assembles the full
skill_call with resolved args
- Simple instruction: Sub-agent instruction is minimal — just "execute {skill_call}, report result"
- Abort on failure: Failed step → mark remaining as skipped → report
- State.json tracks waves: Each wave is recorded with step IDs and results for resume
- Dry-run is read-only: Display chain with [BARRIER] markers, no execution
- Resume from wave:
--continue finds last completed wave and resumes from next pending step
- Semantic Routing: Use LLM structured extraction (
action × object × style) not regex for intent classification