- Multi-CLI Collaborative Planning
- Auto Mode
- When
- workflowPreferences.autoYes
- is true: Auto-approve plan, use recommended solution and execution method (Agent, Skip review).
- Context Source
-
- ACE semantic search + Multi-CLI analysis
- Output Directory
- :
- .workflow/.multi-cli-plan/{session-id}/
- Default Max Rounds
-
- 3 (convergence may complete earlier)
- CLI Tools
-
- @cli-discuss-agent (analysis), @cli-lite-planning-agent (plan generation)
- Execution
-
- Auto-hands off to workflow-lite-execute after plan approval
- Orchestrator Boundary (CRITICAL)
- ONLY command
- for multi-CLI collaborative planning
- Manages: Session state, user decisions, agent delegation, phase transitions
- Delegates: CLI execution to @cli-discuss-agent, plan generation to @cli-lite-planning-agent
- Execution Flow
- Phase 1: Context Gathering
- └─ ACE semantic search, extract keywords, build context package
- Phase 2: Multi-CLI Discussion (Iterative, via @cli-discuss-agent)
- ├─ Round N: Agent executes Gemini + Codex + Claude
- ├─ Cross-verify findings, synthesize solutions
- ├─ Write synthesis.json to rounds/{N}/
- └─ Loop until convergence or max rounds
- Phase 3: Present Options
- └─ Display solutions with trade-offs from agent output
- Phase 4: User Decision
- ├─ Select solution approach
- ├─ Select execution method (Agent/Codex/Auto)
- ├─ Select code review tool (Skip/Gemini/Codex/Agent)
- └─ Route:
- ├─ Approve → Phase 5
- ├─ Need More Analysis → Return to Phase 2
- └─ Cancel → Save session
- Phase 5: Plan Generation & Execution Handoff
- ├─ Generate plan.json + .task/*.json (via @cli-lite-planning-agent, two-layer output)
- ├─ Build executionContext with user selections and taskFiles
- └─ Execute via workflow-lite-execute
- Agent Roles
- Agent
- Responsibility
- Orchestrator
- Session management, ACE context, user decisions, phase transitions, executionContext assembly
- @cli-discuss-agent
- Multi-CLI execution (Gemini/Codex/Claude), cross-verification, solution synthesis, synthesis.json output
- @cli-lite-planning-agent
- Task decomposition, two-layer output: plan.json (overview with task_ids[]) + .task/*.json (task files)
- Core Responsibilities
- Phase 1: Context Gathering
- Session Initialization
- :
- const
- sessionId
- =
- `
- MCP-
- ${
- taskSlug
- }
- -
- ${
- date
- }
- `
- const
- sessionFolder
- =
- `
- .workflow/.multi-cli-plan/
- ${
- sessionId
- }
- `
- Bash
- (
- `
- mkdir -p
- ${
- sessionFolder
- }
- /rounds
- `
- )
- ACE Context Queries
- :
- const
- aceQueries
- =
- [
- `
- Project architecture related to
- ${
- keywords
- }
- `
- ,
- `
- Existing implementations of
- ${
- keywords
- [
- 0
- ]
- }
- `
- ,
- `
- Code patterns for
- ${
- keywords
- }
- features
- `
- ,
- `
- Integration points for
- ${
- keywords
- [
- 0
- ]
- }
- `
- ]
- // Execute via mcp__ace-tool__search_context
- Context Package
- (passed to agent):
- relevant_files[]
- - Files identified by ACE
- detected_patterns[]
- - Code patterns found
- architecture_insights
- - Structure understanding
- Phase 2: Agent Delegation
- Core Principle
- Orchestrator only delegates and reads output — NO direct CLI execution. CLI calls MUST use
Bash
with
run_in_background: true
, wait for hook callback, do NOT use
TaskOutput
polling.
Agent Invocation
:
Agent
(
{
subagent_type
:
"cli-discuss-agent"
,
run_in_background
:
false
,
description
:
Discussion round ${ currentRound }, prompt : `
Input Context
- task_description: ${ taskDescription }
- round_number: ${ currentRound }
- session: { id: " ${ sessionId } ", folder: " ${ sessionFolder } " }
- ace_context: ${ JSON . stringify ( contextPackage ) }
- previous_rounds: ${ JSON . stringify ( analysisResults ) }
- user_feedback: ${ userFeedback || 'None' }
- cli_config: { tools: ["gemini", "codex"], mode: "parallel", fallback_chain: ["gemini", "codex", "claude"] }
Execution Process
- Parse input context (handle JSON strings)
- Check if ACE supplementary search needed
- Build CLI prompts with context
- Execute CLIs (parallel or serial per cli_config.mode)
- Parse CLI outputs, handle failures with fallback
- Perform cross-verification between CLI results
- Synthesize solutions, calculate scores
- Calculate convergence, generate clarification questions
- Write synthesis.json
Output
Write: ${ sessionFolder } /rounds/ ${ currentRound } /synthesis.json
Completion Checklist
- [ ] All configured CLI tools executed (or fallback triggered)
- [ ] Cross-verification completed with agreements/disagreements
- [ ] 2-3 solutions generated with file:line references
- [ ] Convergence score calculated (0.0-1.0)
- [ ] synthesis.json written with all Primary Fields
} ) Read Agent Output : const synthesis = JSON . parse ( Read (${ sessionFolder } /rounds/ ${ round } /synthesis.json) ) // Access top-level fields: solutions, convergence, cross_verification, clarification_questions Convergence Decision : if ( synthesis . convergence . recommendation === 'converged' ) { // Proceed to Phase 3 } else if ( synthesis . convergence . recommendation === 'user_input_needed' ) { // Collect user feedback, return to Phase 2 } else { // Continue to next round if new_insights && round < maxRounds } Phase 3: Present Options Display solutions from synthesis.solutions[] showing: name, source CLIs, effort/risk, pros/cons, affected files ( file:line ). Also show cross-verification agreements/disagreements count. Phase 4: User Decision AskUserQuestion ( { questions : [ { question : "Which solution approach?" , header : "Solution" , multiSelect : false , options : solutions . map ( ( s , i ) => ( { label :Option ${ i + 1 } : ${ s . name }, description :${ s . effort } effort, ${ s . risk } risk} ) ) . concat ( [ { label : "Need More Analysis" , description : "Return to Phase 2" } ] ) } , { question : "Execution method:" , header : "Execution" , multiSelect : false , options : [ { label : "Agent" , description : "@code-developer agent" } , { label : "Codex" , description : "codex CLI tool" } , { label : "Auto" , description : "Auto-select based on complexity" } ] } , { question : "Code review after execution?" , header : "Review" , multiSelect : false , options : [ { label : "Skip" , description : "No review" } , { label : "Gemini Review" , description : "Gemini CLI tool" } , { label : "Codex Review" , description : "codex review --uncommitted" } , { label : "Agent Review" , description : "Current agent review" } ] } ] } ) Routing : Approve + execution method → Phase 5 Need More Analysis → Phase 2 with feedback Cancel → Save session for resumption TodoWrite Update (Phase 4 Decision) : const executionLabel = userSelection . execution_method // "Agent" / "Codex" / "Auto" TodoWrite ( { todos : [ { content : "Phase 1: Context Gathering" , status : "completed" , activeForm : "Gathering context" } , { content : "Phase 2: Multi-CLI Discussion" , status : "completed" , activeForm : "Running discussion" } , { content : "Phase 3: Present Options" , status : "completed" , activeForm : "Presenting options" } , { content :Phase 4: User Decision [ ${ executionLabel } ], status : "completed" , activeForm : "Decision recorded" } , { content :Phase 5: Plan Generation [ ${ executionLabel } ], status : "in_progress" , activeForm :Generating plan [ ${ executionLabel } ]} ] } ) Phase 5: Plan Generation & Execution Handoff Step 1: Build Context-Package (Orchestrator responsibility): const contextPackage = { solution : { name : selectedSolution . name , source_cli : selectedSolution . source_cli , feasibility : selectedSolution . feasibility , effort : selectedSolution . effort , risk : selectedSolution . risk , summary : selectedSolution . summary } , implementation_plan : selectedSolution . implementation_plan , dependencies : selectedSolution . dependencies || { internal : [ ] , external : [ ] } , technical_concerns : selectedSolution . technical_concerns || [ ] , consensus : { agreements : synthesis . cross_verification . agreements , resolved_conflicts : synthesis . cross_verification . resolution } , constraints : userConstraints || [ ] , task_description : taskDescription , session_id : sessionId } Write (${ sessionFolder } /context-package.json, JSON . stringify ( contextPackage , null , 2 ) ) Step 2: Invoke Planning Agent : Agent ( { subagent_type : "cli-lite-planning-agent" , run_in_background : false , description : "Generate implementation plan" , prompt :
Schema Reference
Execute: cat ~/.ccw/workflows/cli-templates/schemas/plan-overview-base-schema.json Execute: cat ~/.ccw/workflows/cli-templates/schemas/task-schema.json
Output Format: Two-Layer Structure
- plan.json: Overview with task_ids[] referencing .task/ files (NO tasks[] array)
- .task/TASK-*.json: Independent task files following task-schema.json plan.json required: summary, approach, task_ids, task_count, _metadata (with plan_type) Task files required: id, title, description, depends_on, convergence (with criteria[]) Task fields: files[].change (not modification_points), convergence.criteria (not acceptance), test (not verification)
Context-Package (from orchestrator)
${ JSON . stringify ( contextPackage , null , 2 ) }
Execution Process
- Read plan-overview-base-schema.json + task-schema.json for output structure
- Read project-tech.json and specs/*.md
- Parse context-package fields:
- solution: name, feasibility, summary
- implementation_plan: tasks[], execution_flow, milestones
- dependencies: internal[], external[]
- technical_concerns: risks/blockers
- consensus: agreements, resolved_conflicts
- constraints: user requirements
- Use implementation_plan.tasks[] as task foundation
- Preserve task dependencies (depends_on) and execution_flow
- Expand tasks with convergence.criteria (testable completion conditions)
- Create .task/ directory and write individual TASK-*.json files
- Generate plan.json with task_ids[] referencing .task/ files
Output
- ${ sessionFolder } /plan.json (overview with task_ids[]) - ${ sessionFolder } /.task/TASK-*.json (independent task files)
Completion Checklist
- [ ] plan.json has task_ids[] and task_count (NO embedded tasks[])
- [ ] .task/*.json files preserve task dependencies from implementation_plan
- [ ] Task execution order follows execution_flow
- [ ] Key_points reflected in task descriptions
- [ ] User constraints applied to implementation
- [ ] convergence.criteria are testable
- [ ] plan.json follows plan-overview-base-schema.json
- [ ] Task files follow task-schema.json
} ) Step 3: Build executionContext : const plan = JSON . parse ( Read (${ sessionFolder } /plan.json) ) const taskFiles = plan . task_ids . map ( id =>${ sessionFolder } /.task/ ${ id } .json) // Build executionContext (same structure as lite-plan) executionContext = { planObject : plan , taskFiles : taskFiles , // Paths to .task/*.json files (two-layer format) explorationsContext : null , // Multi-CLI doesn't use exploration files explorationAngles : [ ] , explorationManifest : null , clarificationContext : null , // Store user feedback from Phase 2 if exists executionMethod : userSelection . execution_method , // From Phase 4 codeReviewTool : userSelection . code_review_tool , // From Phase 4 originalUserInput : taskDescription , executorAssignments : null , session : { id : sessionId , folder : sessionFolder , artifacts : { explorations : [ ] , // No explorations in multi-CLI workflow explorations_manifest : null , plan :${ sessionFolder } /plan.json, task_dir : plan . task_ids ?${ sessionFolder } /.task/: null , synthesis_rounds : Array . from ( { length : currentRound } , ( _ , i ) =>${ sessionFolder } /rounds/ ${ i + 1 } /synthesis.json) , context_package :${ sessionFolder } /context-package.json ` } } } Step 4: Hand off to Execution : Skill ( { skill : "workflow-lite-execute" , args : "--in-memory" } ) // executionContext is passed via global variable to workflow-lite-execute (Mode 1: In-Memory Plan) synthesis.json Schema { "round" : 1 , "solutions" : [ { "name" : "Solution Name" , "source_cli" : [ "gemini" , "codex" ] , "feasibility" : 0.85 , "effort" : "low|medium|high" , "risk" : "low|medium|high" , "summary" : "Brief analysis summary" , "implementation_plan" : { "approach" : "High-level technical approach" , "tasks" : [ { "id" : "T1" , "name" : "Task" , "depends_on" : [ ] , "files" : [ ] , "key_point" : "..." } ] , "execution_flow" : "T1 → T2 → T3" , "milestones" : [ "Checkpoint 1" , "Checkpoint 2" ] } , "dependencies" : { "internal" : [ ] , "external" : [ ] } , "technical_concerns" : [ "Risk 1" , "Blocker 2" ] } ] , "convergence" : { "score" : 0.85 , "new_insights" : false , "recommendation" : "converged|continue|user_input_needed" } , "cross_verification" : { "agreements" : [ ] , "disagreements" : [ ] , "resolution" : "..." } , "clarification_questions" : [ ] } TodoWrite Pattern Initialization (Phase 1 start): TodoWrite ( { todos : [ { content : "Phase 1: Context Gathering" , status : "in_progress" , activeForm : "Gathering context" } , { content : "Phase 2: Multi-CLI Discussion" , status : "pending" , activeForm : "Running discussion" } , { content : "Phase 3: Present Options" , status : "pending" , activeForm : "Presenting options" } , { content : "Phase 4: User Decision" , status : "pending" , activeForm : "Awaiting decision" } , { content : "Phase 5: Plan Generation" , status : "pending" , activeForm : "Generating plan" } ] } ) Output File Structure .workflow/.multi-cli-plan/{MCP-task-slug-YYYY-MM-DD}/ ├── session-state.json # Session tracking (orchestrator) ├── rounds/ │ ├── 1/synthesis.json # Round 1 analysis (cli-discuss-agent) │ ├── 2/synthesis.json # Round 2 analysis (cli-discuss-agent) │ └── .../ ├── context-package.json # Extracted context for planning (orchestrator) ├── plan.json # Plan overview with task_ids[] (NO embedded tasks[]) └── .task/ # Independent task files ├── TASK-001.json # Task file following task-schema.json ├── TASK-002.json └── ... Error Handling Error Resolution ACE search fails Fall back to Glob/Grep for file discovery Agent fails Retry once, then present partial results CLI timeout (in agent) Agent uses fallback: gemini → codex → claude No convergence Present best options, flag uncertainty synthesis.json parse error Request agent retry User cancels Save session for later resumption Configuration Flag Default Description --max-rounds 3 Maximum discussion rounds --tools gemini,codex CLI tools for analysis --mode parallel Execution mode: parallel or serial --auto-execute false Auto-execute after approval