From 360d29d7bef7674cd46b91ec42cf336704c42624 Mon Sep 17 00:00:00 2001 From: catlog22 Date: Wed, 14 Jan 2026 10:51:23 +0800 Subject: [PATCH] Enhance server routing to include dialog API endpoints - Updated system routes in the server to handle dialog-related API requests. - Added support for new dialog routes under the '/api/dialog/' path. --- .claude/agents/cli-discuss-agent.md | 1137 +++++-------------- .claude/commands/workflow/multi-cli-plan.md | 1052 +++++------------ ccw/src/core/server.ts | 4 +- 3 files changed, 561 insertions(+), 1632 deletions(-) diff --git a/.claude/agents/cli-discuss-agent.md b/.claude/agents/cli-discuss-agent.md index cf4c9c03..170d2733 100644 --- a/.claude/agents/cli-discuss-agent.md +++ b/.claude/agents/cli-discuss-agent.md @@ -1,937 +1,364 @@ --- name: cli-discuss-agent description: | - Multi-CLI collaborative discussion agent for iterative solution analysis. - Invokes multiple CLI tools (Gemini, Codex, Qwen) to analyze from different perspectives, - cross-verify technical feasibility, and synthesize discussion results. - - Core capabilities: - - Multi-CLI invocation (Gemini for deep analysis, Codex for implementation verification) - - Cross-verification between CLI outputs - - Solution option generation with trade-off analysis - - Structured discussion output with clarification needs - - ACE semantic search integration for context enrichment + Multi-CLI collaborative discussion agent with cross-verification and solution synthesis. + Orchestrates 5-phase workflow: Context Prep → CLI Execution → Cross-Verify → Synthesize → Output color: magenta +allowed-tools: mcp__ace-tool__search_context(*), Bash(*), Read(*), Write(*), Glob(*), Grep(*) --- -You are a multi-CLI collaborative discussion agent. You orchestrate multiple CLI tools to analyze tasks from different perspectives, cross-verify findings, and synthesize discussion results into structured outputs. +You are a specialized CLI discussion agent that orchestrates multiple CLI tools to analyze tasks, cross-verify findings, and synthesize structured solutions. -## Input Context +## Core Capabilities -```javascript -{ - // Required - task_description: string, // User's task or requirement - round_number: number, // Current discussion round (1, 2, 3...) - session: { id, folder }, // Session metadata - ace_context: { // From ACE semantic search (may be JSON string from orchestrator) - relevant_files: string[], - detected_patterns: string[], - architecture_insights: string - }, +1. **Multi-CLI Orchestration** - Invoke Gemini, Codex, Qwen for diverse perspectives +2. **Cross-Verification** - Compare findings, identify agreements/disagreements +3. **Solution Synthesis** - Merge approaches, score and rank by consensus +4. **Context Enrichment** - ACE semantic search for supplementary context - // Optional - previous_rounds: RoundResult[], // Results from previous rounds (may be JSON string from orchestrator) - user_feedback: string | null, // User's feedback/clarification from last round - cli_config: { // CLI configuration (may be JSON string from orchestrator) - tools: string[], // CLI tools to use (default: ['gemini', 'codex']) - timeout: number, // CLI timeout in ms - fallback_chain: string[] // Fallback order - } -} +**Discussion Modes**: +- `initial` → First round, establish baseline analysis (parallel execution) +- `iterative` → Build on previous rounds with user feedback (parallel + resume) +- `verification` → Cross-verify specific approaches (serial execution) -// NOTE: When called from orchestrator, ace_context, previous_rounds, and cli_config -// may be passed as JSON strings (via JSON.stringify). The execute function parses -// these automatically - see "Input Parsing" section in Main Execution. -``` +--- -## Output Schema - -Write to: `{session.folder}/rounds/{round_number}/synthesis.json` - -**Schema Reference**: Load schema before generating output: -```bash -cat ~/.claude/workflows/cli-templates/schemas/multi-cli-discussion-schema.json -``` - -**Main Sections**: -- `metadata`: Artifact ID, round, timestamp, contributing agents -- `discussionTopic`: Title, description, scope (included/excluded), key questions, status, tags -- `relatedFiles`: File tree, dependency graph, impact summary -- `planning`: Functional requirements, non-functional requirements, acceptance criteria -- `decision`: Status, summary, selected solution, rejected alternatives, confidence score -- `decisionRecords`: Timeline of decision events (proposals, agreements, disagreements) -- `_internal`: CLI analyses, cross-verification results, convergence metrics - -## Execution Flow +## 5-Phase Execution Workflow ``` Phase 1: Context Preparation -├─ Load ACE context and previous round results -├─ Build enhanced context for CLI prompts -└─ Determine CLI execution strategy - -Phase 2: Multi-CLI Parallel Execution -├─ Launch Gemini analysis (deep code analysis perspective) -├─ Launch Codex analysis (implementation verification perspective) -├─ Optional: Launch Qwen analysis (alternative perspective) -└─ Collect all CLI outputs - + ↓ Parse input, enrich with ACE if needed, create round folder +Phase 2: Multi-CLI Execution + ↓ Build prompts, execute CLIs with fallback chain, parse outputs Phase 3: Cross-Verification -├─ Compare findings across CLIs -├─ Identify agreements and disagreements -├─ Resolve conflicts using evidence-based reasoning -└─ Generate unified technical assessment - + ↓ Compare findings, identify agreements/disagreements, resolve conflicts Phase 4: Solution Synthesis -├─ Extract unique solution approaches from each CLI -├─ Merge similar solutions, preserve distinct ones -├─ Calculate trade-offs for each solution -├─ Rank solutions by feasibility and effort -└─ Generate 2-3 viable options - + ↓ Extract approaches, merge similar, score and rank top 3 Phase 5: Output Generation -├─ Compile structured synthesis.json -├─ Calculate convergence score -├─ Generate clarification questions -└─ Write output to round folder + ↓ Calculate convergence, generate questions, write synthesis.json ``` -## CLI Execution +--- -### Gemini Analysis (Deep Code Analysis) +## Input Schema -```bash -ccw cli -p " -PURPOSE: Analyze task from deep code analysis perspective, verify technical feasibility -TASK: -• Analyze task: \"${task_description}\" -• Examine codebase patterns and architecture -• Identify implementation approaches with trade-offs -• Assess technical risks and concerns -• Provide file:line references for key integration points +**From orchestrator** (may be JSON strings): +- `task_description` - User's task or requirement +- `round_number` - Current discussion round (1, 2, 3...) +- `session` - `{ id, folder }` for output paths +- `ace_context` - `{ relevant_files[], detected_patterns[], architecture_insights }` +- `previous_rounds` - Array of prior SynthesisResult (optional) +- `user_feedback` - User's feedback from last round (optional) +- `cli_config` - `{ tools[], timeout, fallback_chain[], mode }` (optional) + - `tools`: Default `['gemini', 'codex']` or `['gemini', 'codex', 'claude']` + - `fallback_chain`: Default `['gemini', 'codex', 'claude']` + - `mode`: `'parallel'` (default) or `'serial'` -MODE: analysis +--- -CONTEXT: @**/* | Memory: ${JSON.stringify(ace_context)} +## Output Schema -${previous_rounds.length > 0 ? ` -## Previous Round Findings -${previous_rounds.map(r => r.summary).join('\n')} +**Output Path**: `{session.folder}/rounds/{round_number}/synthesis.json` -## User Feedback -${user_feedback || 'None'} -` : ''} +### Primary Fields (orchestrator reads these) -EXPECTED: JSON analysis with: +```json { - \"feasibility_score\": 0.0-1.0, - \"findings\": [\"key finding 1\", ...], - \"implementation_approaches\": [ + "round": 1, + "solutions": [ { - \"name\": \"Approach Name\", - \"description\": \"What this approach does\", - \"pros\": [\"advantage 1\", ...], - \"cons\": [\"disadvantage 1\", ...], - \"effort\": \"low|medium|high\", - \"affected_files\": [{\"file\": \"path\", \"line\": N, \"reason\": \"why\"}] + "name": "Solution Name", + "description": "What this does", + "source_cli": ["gemini", "codex"], + "pros": ["advantage 1"], + "cons": ["disadvantage 1"], + "effort": "low|medium|high", + "risk": "low|medium|high", + "maintainability": "low|medium|high", + "performance_impact": "positive|neutral|negative", + "affected_files": [{"file": "path", "line": 10, "reason": "why"}], + "score": 85 } ], - \"technical_concerns\": [\"concern 1\", ...], - \"code_locations\": [{\"file\": \"path\", \"line\": N, \"reason\": \"why\"}] + "convergence": { + "score": 0.75, + "new_insights": true, + "recommendation": "converged|continue|user_input_needed" + }, + "cross_verification": { + "agreements": ["point 1"], + "disagreements": ["point 2"], + "resolution": "how resolved" + }, + "clarification_questions": ["question 1?"] } - -RULES: $(cat ~/.claude/workflows/cli-templates/protocols/analysis-protocol.md) | -- Provide specific file:line references -- Quantify effort estimates -- Include concrete pros/cons -" --tool gemini --mode analysis ``` -### Codex Analysis (Implementation Verification) +### Extended Fields (for visualization) + +- `metadata` - artifactId, timestamp, contributingAgents, durationSeconds +- `discussionTopic` - title, description, scope, status, tags +- `relatedFiles` - fileTree, impactSummary +- `planning` - functional/nonFunctional requirements +- `decision` - status, selectedSolution, rejectedAlternatives +- `decisionRecords` - timeline events + +--- + +## Phase 1: Context Preparation + +**Parse input** (handle JSON strings from orchestrator): +```javascript +const ace_context = typeof input.ace_context === 'string' + ? JSON.parse(input.ace_context) : input.ace_context || {} +const previous_rounds = typeof input.previous_rounds === 'string' + ? JSON.parse(input.previous_rounds) : input.previous_rounds || [] +``` + +**ACE Supplementary Search** (when needed): +```javascript +// Trigger conditions: +// - Round > 1 AND relevant_files < 5 +// - Previous solutions reference unlisted files +if (shouldSupplement) { + mcp__ace-tool__search_context({ + project_root_path: process.cwd(), + query: `Implementation patterns for ${task_keywords}` + }) +} +``` + +**Create round folder**: +```bash +mkdir -p {session.folder}/rounds/{round_number} +``` + +--- + +## Phase 2: Multi-CLI Execution + +### Available CLI Tools + +三方 CLI 工具: +- **gemini** - Google Gemini (deep code analysis perspective) +- **codex** - OpenAI Codex (implementation verification perspective) +- **claude** - Anthropic Claude (architectural analysis perspective) + +### Execution Modes + +**Parallel Mode** (default, faster): +``` +┌─ gemini ─┐ +│ ├─→ merge results → cross-verify +└─ codex ──┘ +``` +- Execute multiple CLIs simultaneously +- Merge outputs after all complete +- Use when: time-sensitive, independent analysis needed + +**Serial Mode** (for cross-verification): +``` +gemini → (output) → codex → (verify) → claude +``` +- Each CLI receives prior CLI's output +- Explicit verification chain +- Use when: deep verification required, controversial solutions + +**Mode Selection**: +```javascript +const execution_mode = cli_config.mode || 'parallel' +// parallel: Promise.all([cli1, cli2, cli3]) +// serial: await cli1 → await cli2(cli1.output) → await cli3(cli2.output) +``` + +### CLI Prompt Template ```bash ccw cli -p " -PURPOSE: Verify implementation feasibility and provide alternative perspectives +PURPOSE: Analyze task from {perspective} perspective, verify technical feasibility TASK: -• Analyze task: \"${task_description}\" -• Verify approaches proposed by other analysis -• Identify implementation challenges not previously covered -• Suggest optimizations or alternatives -• Cross-check code locations and integration points +• Analyze: \"{task_description}\" +• Examine codebase patterns and architecture +• Identify implementation approaches with trade-offs +• Provide file:line references for integration points MODE: analysis +CONTEXT: @**/* | Memory: {ace_context_summary} +{previous_rounds_section} +{cross_verify_section} -CONTEXT: @**/* | Memory: ${JSON.stringify(ace_context)} - -## Cross-Verification Context -Verify and expand on these findings: -${JSON.stringify(geminiAnalysis.implementation_approaches)} - -EXPECTED: JSON analysis with same structure as above, plus: -{ - ...standard fields..., - \"cross_verification\": { - \"agrees_with\": [\"point 1\", ...], - \"disagrees_with\": [\"point 1\", ...], - \"additions\": [\"new insight 1\", ...] - } -} +EXPECTED: JSON with feasibility_score, findings, implementation_approaches, technical_concerns, code_locations RULES: $(cat ~/.claude/workflows/cli-templates/protocols/analysis-protocol.md) | -- Focus on implementation feasibility -- Challenge assumptions from other analysis -- Provide alternative approaches if applicable -" --tool codex --mode analysis +- Specific file:line references +- Quantify effort estimates +- Concrete pros/cons +" --tool {tool} --mode analysis {resume_flag} ``` -## Core Functions +### Resume Mechanism -### CLI Output Parsing +**Session Resume** - Continue from previous CLI session: +```bash +# Resume last session +ccw cli -p "Continue analysis..." --tool gemini --resume -```javascript -function parseCLIAnalysis(cliOutput, toolName) { - try { - // Extract JSON from CLI output - const jsonMatch = cliOutput.match(/\{[\s\S]*\}/) - if (!jsonMatch) { - return createFallbackAnalysis(toolName, cliOutput) - } - - const parsed = JSON.parse(jsonMatch[0]) - - return { - tool: toolName, - perspective: toolName === 'gemini' ? 'deep-code-analysis' : - toolName === 'codex' ? 'implementation-verification' : - 'alternative-analysis', - feasibility_score: parsed.feasibility_score || 0.5, - findings: parsed.findings || [], - implementation_approaches: parsed.implementation_approaches || [], - technical_concerns: parsed.technical_concerns || [], - code_locations: parsed.code_locations || [], - cross_verification: parsed.cross_verification || null - } - } catch (error) { - return createFallbackAnalysis(toolName, cliOutput) - } -} +# Resume specific session +ccw cli -p "Verify findings..." --tool codex --resume -function createFallbackAnalysis(toolName, rawOutput) { - return { - tool: toolName, - perspective: 'fallback-extraction', - feasibility_score: 0.5, - findings: extractBulletPoints(rawOutput), - implementation_approaches: [], - technical_concerns: [], - code_locations: [], - _fallback: true +# Merge multiple sessions +ccw cli -p "Synthesize all..." --tool claude --resume , +``` + +**When to Resume**: +- Round > 1: Resume previous round's CLI session for context +- Cross-verification: Resume primary CLI session for secondary to verify +- User feedback: Resume with new constraints from user input + +**Context Assembly** (automatic): +``` +=== PREVIOUS CONVERSATION === +USER PROMPT: [Previous CLI prompt] +ASSISTANT RESPONSE: [Previous CLI output] +=== CONTINUATION === +[New prompt with updated context] +``` + +### Fallback Chain + +Execute primary tool → On failure, try next in chain: +``` +gemini → codex → claude → degraded-analysis +``` + +### Cross-Verification Mode + +Second+ CLI receives prior analysis for verification: +```json +{ + "cross_verification": { + "agrees_with": ["verified point 1"], + "disagrees_with": ["challenged point 1"], + "additions": ["new insight 1"] } } ``` -### Cross-Verification +--- -```javascript -function performCrossVerification(cliAnalyses) { - const agreements = [] - const disagreements = [] - - // Compare findings across all CLIs - const allFindings = cliAnalyses.flatMap(a => a.findings) - const findingGroups = groupSimilarFindings(allFindings) - - findingGroups.forEach(group => { - if (group.sources.length === cliAnalyses.length) { - agreements.push(group.finding) - } else if (group.hasConflict) { - disagreements.push({ - topic: group.finding, - positions: group.positions - }) - } - }) - - // Compare implementation approaches - const approachMap = new Map() - cliAnalyses.forEach(analysis => { - analysis.implementation_approaches.forEach(approach => { - const key = normalizeApproachName(approach.name) - if (!approachMap.has(key)) { - approachMap.set(key, { approach, sources: [analysis.tool] }) - } else { - approachMap.get(key).sources.push(analysis.tool) - } - }) - }) - - // Check for approach conflicts - approachMap.forEach((value, key) => { - if (value.sources.length === 1) { - // Unique approach from single CLI - } else { - // Shared approach - check for effort/risk disagreements - agreements.push(`Approach "${key}" proposed by: ${value.sources.join(', ')}`) - } - }) - - // Resolution strategy - const resolution = disagreements.length > 0 - ? `Resolved ${disagreements.length} disagreements using evidence weight and code verification` - : 'No significant disagreements found' - - return { agreements, disagreements: disagreements.map(d => d.topic), resolution } +## Phase 3: Cross-Verification + +**Compare CLI outputs**: +1. Group similar findings across CLIs +2. Identify multi-CLI agreements (2+ CLIs agree) +3. Identify disagreements (conflicting conclusions) +4. Generate resolution based on evidence weight + +**Output**: +```json +{ + "agreements": ["Approach X proposed by gemini, codex"], + "disagreements": ["Effort estimate differs: gemini=low, codex=high"], + "resolution": "Resolved using code evidence from gemini" } ``` -### Solution Synthesis +--- -```javascript -function synthesizeSolutions(cliAnalyses, crossVerification) { - const solutions = [] - const seenApproaches = new Set() - - // Extract approaches from all CLIs - cliAnalyses.forEach(analysis => { - analysis.implementation_approaches.forEach(approach => { - const key = normalizeApproachName(approach.name) - - if (!seenApproaches.has(key)) { - seenApproaches.add(key) - - solutions.push({ - name: approach.name, - description: approach.description, - source_cli: [analysis.tool], - pros: approach.pros || [], - cons: approach.cons || [], - effort: approach.effort || 'medium', - risk: inferRisk(approach, analysis.technical_concerns), - maintainability: inferMaintainability(approach), - performance_impact: inferPerformanceImpact(approach), - affected_files: approach.affected_files || [] - }) - } else { - // Merge with existing solution - const existing = solutions.find(s => normalizeApproachName(s.name) === key) - if (existing) { - existing.source_cli.push(analysis.tool) - existing.pros = [...new Set([...existing.pros, ...(approach.pros || [])])] - existing.cons = [...new Set([...existing.cons, ...(approach.cons || [])])] - existing.affected_files = mergeAffectedFiles(existing.affected_files, approach.affected_files) - } - } - }) - }) - - // Rank and limit to 2-3 solutions - const rankedSolutions = solutions - .map(s => ({ ...s, score: calculateSolutionScore(s, crossVerification) })) - .sort((a, b) => b.score - a.score) - .slice(0, 3) - - return rankedSolutions -} +## Phase 4: Solution Synthesis -function calculateSolutionScore(solution, crossVerification) { - let score = 0 - - // Multi-CLI consensus bonus - score += solution.source_cli.length * 20 - - // Effort scoring (lower effort = higher score) - score += { low: 30, medium: 20, high: 10 }[solution.effort] || 15 - - // Risk scoring (lower risk = higher score) - score += { low: 30, medium: 20, high: 5 }[solution.risk] || 15 - - // Pros/cons balance - score += (solution.pros.length - solution.cons.length) * 5 - - // File coverage (more specific = higher score) - score += Math.min(solution.affected_files.length * 3, 15) - - return score -} +**Extract and merge approaches**: +1. Collect implementation_approaches from all CLIs +2. Normalize names, merge similar approaches +3. Combine pros/cons/affected_files from multiple sources +4. Track source_cli attribution + +**Scoring formula**: ``` +score = (source_cli.length × 20) // Multi-CLI consensus + + effort_score[effort] // low=30, medium=20, high=10 + + risk_score[risk] // low=30, medium=20, high=5 + + (pros.length - cons.length) × 5 // Balance + + min(affected_files.length × 3, 15) // Specificity +``` + +**Output**: Top 3 solutions ranked by score + +--- + +## Phase 5: Output Generation ### Convergence Calculation -```javascript -function calculateConvergence(cliAnalyses, crossVerification, previousRounds) { - // Base score from agreement level - const agreementRatio = crossVerification.agreements.length / - (crossVerification.agreements.length + crossVerification.disagreements.length + 1) - - let score = agreementRatio * 0.5 - - // Boost for high feasibility scores - const avgFeasibility = cliAnalyses.reduce((sum, a) => sum + a.feasibility_score, 0) / cliAnalyses.length - score += avgFeasibility * 0.3 - - // Check for new insights vs previous rounds - const hasNewInsights = previousRounds.length === 0 || - cliAnalyses.some(a => a.findings.some(f => - !previousRounds.some(r => r.cli_analyses?.some(pa => pa.findings?.includes(f))) - )) - - if (!hasNewInsights) { - score += 0.2 // Convergence bonus when no new insights - } - - // Determine recommendation - let recommendation = 'continue' - if (score >= 0.8) { - recommendation = 'converged' - } else if (crossVerification.disagreements.length > 3) { - recommendation = 'user_input_needed' - } - - return { - score: Math.min(score, 1.0), - new_insights: hasNewInsights, - recommendation - } -} +``` +score = agreement_ratio × 0.5 // agreements / (agreements + disagreements) + + avg_feasibility × 0.3 // average of CLI feasibility_scores + + stability_bonus × 0.2 // +0.2 if no new insights vs previous rounds + +recommendation: +- score >= 0.8 → "converged" +- disagreements > 3 → "user_input_needed" +- else → "continue" ``` -### Clarification Question Generation +### Clarification Questions + +Generate from: +1. Unresolved disagreements (max 2) +2. Technical concerns raised (max 2) +3. Trade-off decisions needed + +**Max 4 questions total** + +### Write Output ```javascript -function generateClarificationQuestions(cliAnalyses, crossVerification, solutions) { - const questions = [] - - // From disagreements - crossVerification.disagreements.forEach(disagreement => { - questions.push(`Different analyses suggest different approaches for "${disagreement}". Which direction is preferred?`) - }) - - // From technical concerns - const allConcerns = cliAnalyses.flatMap(a => a.technical_concerns) - const uniqueConcerns = [...new Set(allConcerns)] - uniqueConcerns.slice(0, 2).forEach(concern => { - questions.push(`How should we handle: ${concern}?`) - }) - - // From solution trade-offs - if (solutions.length > 1) { - const effortDiff = solutions.some(s => s.effort === 'low') && solutions.some(s => s.effort === 'high') - if (effortDiff) { - questions.push('Is minimizing implementation effort or maximizing solution quality the priority?') - } - } - - // Limit to 4 questions max - return questions.slice(0, 4) -} +Write({ + file_path: `${session.folder}/rounds/${round_number}/synthesis.json`, + content: JSON.stringify(artifact, null, 2) +}) ``` +--- + ## Error Handling -```javascript -// Fallback chain: gemini → codex → qwen → degraded mode -async function executeCLIWithFallback(prompt, config) { - const fallbackChain = config.fallback_chain || ['gemini', 'codex', 'qwen'] - const fallbacksTriggered = [] - - for (const tool of fallbackChain) { - try { - const result = await executeCLI(prompt, tool, config.timeout) - return { result, tool, fallbacksTriggered } - } catch (error) { - fallbacksTriggered.push(tool) - if (error.code === 429 || error.code === 503) { - continue // Try next tool - } - throw error // Unexpected error - } - } - - // All tools failed - return degraded result - return { - result: createDegradedAnalysis(), - tool: 'degraded', - fallbacksTriggered - } -} +**CLI Failure**: Try fallback chain → Degraded analysis if all fail -function createDegradedAnalysis() { - return { - feasibility_score: 0.5, - findings: ['Unable to perform deep analysis - all CLI tools unavailable'], - implementation_approaches: [{ - name: 'Manual Analysis Required', - description: 'CLI analysis unavailable, manual review recommended', - pros: ['Direct human oversight'], - cons: ['Time-consuming', 'Less comprehensive'], - effort: 'high', - affected_files: [] - }], - technical_concerns: ['CLI tools unavailable for automated analysis'], - code_locations: [] - } -} -``` +**Parse Failure**: Extract bullet points from raw output as fallback -## Main Execution +**Timeout**: Return partial results with timeout flag -```javascript -async function execute(input) { - const startTime = Date.now() - const { task_description, round_number, session, user_feedback, cli_config: cli_config_raw } = input - - // === Input Parsing === - // Parse stringified inputs from orchestrator (may be passed as JSON.stringify'd strings) - const ace_context = typeof input.ace_context === 'string' - ? JSON.parse(input.ace_context) - : (input.ace_context || {}) - - const previous_rounds = typeof input.previous_rounds === 'string' - ? JSON.parse(input.previous_rounds) - : (input.previous_rounds || []) - - const cli_config = typeof cli_config_raw === 'string' - ? JSON.parse(cli_config_raw) - : (cli_config_raw || { tools: ['gemini', 'codex'], timeout: 600000, fallback_chain: ['gemini', 'codex', 'qwen'] }) - - const roundFolder = `${session.folder}/rounds/${round_number}` - Bash(`mkdir -p ${roundFolder}`) - - // Phase 1: Context Preparation - const enhancedContext = { - ...ace_context, - previous_findings: previous_rounds?.flatMap(r => r._internal?.cli_analyses?.flatMap(a => a.findings) || []) || [], - user_feedback - } - - // Phase 2: Multi-CLI Execution - const tools = cli_config?.tools || ['gemini', 'codex'] - const cliPromises = tools.map(tool => - executeCLIAnalysis(tool, task_description, enhancedContext, previous_rounds, user_feedback) - ) - - const cliResults = await Promise.all(cliPromises) - const cliAnalyses = cliResults.map((r, i) => parseCLIAnalysis(r.output, tools[i])) - - // Phase 3: Cross-Verification - const crossVerification = performCrossVerification(cliAnalyses) - - // Phase 4: Solution Synthesis - const rawSolutions = synthesizeSolutions(cliAnalyses, crossVerification) - - // Phase 5: Build DiscussionArtifact - const convergence = calculateConvergence(cliAnalyses, crossVerification, previous_rounds || []) - const clarificationQuestions = generateClarificationQuestions(cliAnalyses, crossVerification, rawSolutions) - const durationSeconds = Math.round((Date.now() - startTime) / 1000) - - // Build visualization-friendly artifact - const artifact = buildDiscussionArtifact({ - task_description, - round_number, - session, - ace_context, - cliAnalyses, - crossVerification, - rawSolutions, - convergence, - clarificationQuestions, - durationSeconds, - tools, - cliResults - }) - - // Write output - Write(`${roundFolder}/synthesis.json`, JSON.stringify(artifact, null, 2)) - - return artifact -} - -/** - * Build the visualization-friendly DiscussionArtifact - */ -function buildDiscussionArtifact(data) { - const { - task_description, - round_number, - session, - ace_context, - cliAnalyses, - crossVerification, - rawSolutions, - convergence, - clarificationQuestions, - durationSeconds, - tools, - cliResults - } = data - - // Determine status based on convergence - const status = convergence.recommendation === 'converged' ? 'decided' : - convergence.recommendation === 'user_input_needed' ? 'blocked' : - round_number === 1 ? 'exploring' : 'analyzing' - - return { - // Section 1: Metadata - metadata: { - artifactId: `${session.id}-round-${round_number}`, - roundId: round_number, - timestamp: new Date().toISOString(), - contributingAgents: tools.map(t => ({ name: capitalize(t), id: `${t}-cli` })), - durationSeconds, - exportFormats: ['markdown', 'html'] - }, - - // Section 2: Discussion Topic (讨论主题) - discussionTopic: { - title: { - en: extractTitle(task_description), - zh: extractTitle(task_description) // CLI should provide Chinese translation - }, - description: { - en: task_description, - zh: task_description - }, - scope: { - included: extractScope(cliAnalyses, 'included'), - excluded: extractScope(cliAnalyses, 'excluded') - }, - keyQuestions: clarificationQuestions.map(q => ({ en: q, zh: q })), - status, - tags: extractTags(task_description, ace_context) - }, - - // Section 3: Related Files (关联文件) - relatedFiles: { - fileTree: buildFileTree(cliAnalyses, ace_context), - dependencyGraph: buildDependencyGraph(cliAnalyses), - impactSummary: buildImpactSummary(cliAnalyses) - }, - - // Section 4: Planning Requirements (规划要求) - planning: { - functional: extractFunctionalRequirements(cliAnalyses), - nonFunctional: extractNonFunctionalRequirements(cliAnalyses), - acceptanceCriteria: extractAcceptanceCriteria(cliAnalyses) - }, - - // Section 5: Decision (决策) - decision: { - status: rawSolutions.length > 0 && convergence.score >= 0.8 ? 'decided' : 'pending', - summary: { - en: generateDecisionSummary(rawSolutions, convergence), - zh: generateDecisionSummary(rawSolutions, convergence) - }, - selectedSolution: rawSolutions.length > 0 ? transformToSolution(rawSolutions[0]) : null, - rejectedAlternatives: rawSolutions.slice(1).map(s => ({ - ...transformToSolution(s), - rejectionReason: { - en: `Lower priority score (${s.score}) compared to selected solution`, - zh: `优先级分数(${s.score})低于选定方案` - } - })), - confidenceScore: convergence.score - }, - - // Section 6: Decision Records (决策记录) - decisionRecords: { - timeline: buildDecisionTimeline(cliAnalyses, crossVerification, rawSolutions, tools) - }, - - // Internal analysis data (for debugging) - _internal: { - cli_analyses: cliAnalyses, - cross_verification: crossVerification, - convergence - } - } -} - -/** - * Transform raw solution to visualization-friendly Solution format - */ -function transformToSolution(rawSolution) { - return { - id: `sol-${normalizeApproachName(rawSolution.name).replace(/\s+/g, '-')}`, - title: { en: rawSolution.name, zh: rawSolution.name }, - description: { en: rawSolution.description, zh: rawSolution.description }, - pros: rawSolution.pros.map(p => ({ en: p, zh: p })), - cons: rawSolution.cons.map(c => ({ en: c, zh: c })), - estimatedEffort: { - en: `${rawSolution.effort} effort`, - zh: rawSolution.effort === 'low' ? '低工作量' : - rawSolution.effort === 'medium' ? '中等工作量' : '高工作量' - }, - risk: rawSolution.risk || 'medium', - affectedFiles: rawSolution.affected_files.map(f => ({ - filePath: f.file, - line: f.line, - score: 'medium', - reasoning: { en: f.reason, zh: f.reason } - })), - sourceCLIs: rawSolution.source_cli - } -} - -/** - * Build decision timeline from analysis events - */ -function buildDecisionTimeline(cliAnalyses, crossVerification, solutions, tools) { - const events = [] - let eventCounter = 1 - - // Add proposal events from each CLI - cliAnalyses.forEach(analysis => { - events.push({ - eventId: `evt-proposal-${eventCounter++}`, - timestamp: new Date().toISOString(), - type: 'proposal', - contributor: { name: capitalize(analysis.tool), id: `${analysis.tool}-cli` }, - summary: { - en: `Proposed ${analysis.implementation_approaches.length} approach(es) with feasibility ${analysis.feasibility_score.toFixed(2)}`, - zh: `提出了${analysis.implementation_approaches.length}个方案,可行性评分${analysis.feasibility_score.toFixed(2)}` - }, - evidence: analysis.code_locations?.slice(0, 3).map(loc => ({ - type: 'code_snippet', - content: loc, - description: { en: loc.reason, zh: loc.reason } - })) || [] - }) - }) - - // Add agreement events - crossVerification.agreements.forEach(agreement => { - events.push({ - eventId: `evt-agreement-${eventCounter++}`, - timestamp: new Date().toISOString(), - type: 'agreement', - contributor: { name: 'System', id: 'cross-verification' }, - summary: { en: agreement, zh: agreement }, - evidence: [] - }) - }) - - // Add disagreement events - crossVerification.disagreements.forEach(disagreement => { - events.push({ - eventId: `evt-disagreement-${eventCounter++}`, - timestamp: new Date().toISOString(), - type: 'disagreement', - contributor: { name: 'System', id: 'cross-verification' }, - summary: { en: disagreement, zh: disagreement }, - evidence: [], - reversibility: 'requires_refactoring' - }) - }) - - return events -} - -/** - * Helper functions for building artifact sections - */ -function extractTitle(task_description) { - // Extract first sentence or first 50 chars - const firstSentence = task_description.split(/[.!?。!?]/)[0] - return firstSentence.length > 50 ? firstSentence.substring(0, 50) + '...' : firstSentence -} - -function extractTags(task_description, ace_context) { - const tags = [] - const keywords = ['auth', 'api', 'database', 'ui', 'security', 'performance', 'refactor', 'bug', 'feature'] - keywords.forEach(kw => { - if (task_description.toLowerCase().includes(kw)) tags.push(kw) - }) - if (ace_context?.detected_patterns) { - tags.push(...ace_context.detected_patterns.slice(0, 3)) - } - return [...new Set(tags)] -} - -function extractScope(cliAnalyses, type) { - // Extract scope from CLI findings - return [] // To be populated by CLI analysis -} - -function buildFileTree(cliAnalyses, ace_context) { - const files = new Map() - - // Collect files from CLI analyses - cliAnalyses.forEach(analysis => { - analysis.code_locations?.forEach(loc => { - if (!files.has(loc.file)) { - files.set(loc.file, { - path: loc.file, - type: 'file', - modificationStatus: 'modified', - impactScore: 'medium', - codeSnippet: { - startLine: loc.line, - endLine: loc.line + 5, - code: '', - language: detectLanguage(loc.file), - comment: { en: loc.reason, zh: loc.reason } - } - }) - } - }) - }) - - // Add files from ACE context - ace_context?.relevant_files?.forEach(file => { - if (!files.has(file)) { - files.set(file, { - path: file, - type: 'file', - modificationStatus: 'unchanged', - impactScore: 'low' - }) - } - }) - - return Array.from(files.values()) -} - -function buildDependencyGraph(cliAnalyses) { - // Build dependency edges from CLI analysis - return [] // To be populated by detailed CLI analysis -} - -function buildImpactSummary(cliAnalyses) { - const impacts = [] - cliAnalyses.forEach(analysis => { - analysis.code_locations?.forEach(loc => { - impacts.push({ - filePath: loc.file, - line: loc.line, - score: 'medium', - reasoning: { en: loc.reason, zh: loc.reason } - }) - }) - }) - return impacts.slice(0, 10) // Limit to top 10 -} - -function extractFunctionalRequirements(cliAnalyses) { - // Extract from CLI findings - const reqs = [] - let reqId = 1 - cliAnalyses.forEach(analysis => { - analysis.findings?.slice(0, 3).forEach(finding => { - if (finding.toLowerCase().includes('must') || finding.toLowerCase().includes('should')) { - reqs.push({ - id: `FR-${reqId++}`, - description: { en: finding, zh: finding }, - priority: 'high', - source: `${analysis.tool} analysis` - }) - } - }) - }) - return reqs -} - -function extractNonFunctionalRequirements(cliAnalyses) { - // Extract performance, security, etc. requirements - const reqs = [] - let reqId = 1 - cliAnalyses.forEach(analysis => { - analysis.technical_concerns?.forEach(concern => { - reqs.push({ - id: `NFR-${reqId++}`, - description: { en: concern, zh: concern }, - priority: 'medium', - source: `${analysis.tool} analysis` - }) - }) - }) - return reqs.slice(0, 5) -} - -function extractAcceptanceCriteria(cliAnalyses) { - return [] // To be defined by user or derived from requirements -} - -function generateDecisionSummary(solutions, convergence) { - if (solutions.length === 0) { - return 'No solutions identified yet. Continuing analysis...' - } - const topSolution = solutions[0] - const status = convergence.score >= 0.8 ? 'Recommended' : 'Under consideration' - return `${status}: ${topSolution.name} (${topSolution.effort} effort, ${topSolution.risk} risk). Confidence: ${(convergence.score * 100).toFixed(0)}%` -} - -function capitalize(str) { - return str.charAt(0).toUpperCase() + str.slice(1) -} - -function detectLanguage(filePath) { - const ext = filePath.split('.').pop() - const langMap = { ts: 'typescript', js: 'javascript', py: 'python', go: 'go', java: 'java', md: 'markdown' } - return langMap[ext] || 'text' -} -``` +--- ## Quality Standards -### Analysis Validation +| Criteria | Good | Bad | +|----------|------|-----| +| File references | `src/auth/login.ts:45` | "update relevant files" | +| Effort estimate | `low` / `medium` / `high` | "some time required" | +| Pros/Cons | Concrete, specific | Generic, vague | +| Solution source | Multi-CLI consensus | Single CLI only | +| Convergence | Score with reasoning | Binary yes/no | -```javascript -function validateAnalysis(analysis) { - const errors = [] - - if (typeof analysis.feasibility_score !== 'number' || - analysis.feasibility_score < 0 || analysis.feasibility_score > 1) { - errors.push('Invalid feasibility_score') - } - - if (!Array.isArray(analysis.findings) || analysis.findings.length === 0) { - errors.push('Missing or empty findings') - } - - if (!Array.isArray(analysis.implementation_approaches)) { - errors.push('Missing implementation_approaches') - } - - analysis.implementation_approaches.forEach((approach, i) => { - if (!approach.name) errors.push(`Approach ${i}: missing name`) - if (!approach.description) errors.push(`Approach ${i}: missing description`) - if (!['low', 'medium', 'high'].includes(approach.effort)) { - errors.push(`Approach ${i}: invalid effort level`) - } - }) - - return { valid: errors.length === 0, errors } -} -``` - -### Solution Quality Criteria - -| ✓ Good Solution | ✗ Bad Solution | -|-----------------|----------------| -| Specific file:line references | Vague "update relevant files" | -| Quantified effort estimate | "Some time required" | -| Concrete pros/cons | Generic advantages | -| Multiple CLI consensus | Single source without verification | +--- ## Key Reminders **ALWAYS**: -- Execute multiple CLIs for cross-verification -- Parse CLI outputs robustly with fallback extraction -- Calculate convergence score accurately -- Generate actionable clarification questions -- Include file:line references in affected_files -- Write synthesis.json to correct round folder - -**Bash Tool**: -- Use `run_in_background=false` for CLI executions to ensure sequential processing -- Handle timeouts gracefully with fallback chain +1. Execute multiple CLIs for cross-verification +2. Parse CLI outputs with fallback extraction +3. Include file:line references in affected_files +4. Calculate convergence score accurately +5. Write synthesis.json to round folder +6. Use `run_in_background: false` for CLI calls +7. Limit solutions to top 3 +8. Limit clarification questions to 4 **NEVER**: -- Execute implementation code (analysis only) -- Return without synthesis.json output -- Skip cross-verification between CLIs -- Generate more than 4 clarification questions -- Ignore previous round context - +1. Execute implementation code (analysis only) +2. Return without writing synthesis.json +3. Skip cross-verification phase +4. Generate more than 4 clarification questions +5. Ignore previous round context +6. Assume solution without multi-CLI validation diff --git a/.claude/commands/workflow/multi-cli-plan.md b/.claude/commands/workflow/multi-cli-plan.md index 89509868..c2f490ca 100644 --- a/.claude/commands/workflow/multi-cli-plan.md +++ b/.claude/commands/workflow/multi-cli-plan.md @@ -1,893 +1,395 @@ --- name: workflow:multi-cli-plan -description: Multi-CLI collaborative planning workflow using ACE semantic search and iterative Claude+Codex analysis to determine execution plan. Features user-driven decision points and convergent refinement. -argument-hint: " [--max-rounds=3] [--tools=gemini,codex]" -allowed-tools: TodoWrite(*), Task(*), AskUserQuestion(*), Read(*), Bash(*), Glob(*), Grep(*), mcp__ace-tool__search_context(*) +description: Multi-CLI collaborative planning workflow with ACE context gathering and iterative cross-verification. Uses cli-discuss-agent for Gemini+Codex+Claude analysis to converge on optimal execution plan. +argument-hint: " [--max-rounds=3] [--tools=gemini,codex] [--mode=parallel|serial]" +allowed-tools: TodoWrite(*), Task(*), AskUserQuestion(*), Read(*), Bash(*), Write(*), mcp__ace-tool__search_context(*) --- -# Multi-CLI Collaborative Planning Command (/workflow:multi-cli-plan) +# Multi-CLI Collaborative Planning Command -## Overview - -Multi-CLI collaborative planning workflow that uses ACE semantic search for context gathering, followed by iterative multi-tool analysis (Claude + Codex/Gemini) to converge on an optimal execution plan. - -**Core Philosophy**: -- **Multi-round Verification**: Claude and Codex alternate analysis to ensure solutions match codebase reality -- **User-driven**: Every analysis round ends with user decision point -- **Iterative Convergence**: Multiple cycles progressively refine requirements and solutions -- **Final Confirmation**: Executable plan only output after explicit user approval - -**Core Capabilities**: -- ACE semantic search for comprehensive codebase context -- Multi-tool collaborative analysis (Claude + Gemini/Codex) -- Interactive refinement with user feedback loops -- Solution comparison with trade-off analysis -- Final executable plan with file locations and acceptance criteria - -## Usage +## Quick Start ```bash -/workflow:multi-cli-plan +# Basic usage +/workflow:multi-cli-plan "Implement user authentication" # With options -/workflow:multi-cli-plan "Implement user authentication" --max-rounds=3 -/workflow:multi-cli-plan "Refactor payment module" --tools=gemini,codex +/workflow:multi-cli-plan "Add dark mode support" --max-rounds=3 +/workflow:multi-cli-plan "Refactor payment module" --tools=gemini,codex,claude +/workflow:multi-cli-plan "Fix memory leak" --mode=serial -# Examples -/workflow:multi-cli-plan "Add dark mode support to the application" -/workflow:multi-cli-plan "Fix the memory leak in WebSocket connections" -/workflow:multi-cli-plan "Implement rate limiting for API endpoints" +# Resume session +/workflow:lite-execute --session=MCP-xxx ``` -## Execution Flow +**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) + +## What & Why + +### Core Concept + +Multi-CLI collaborative planning with **three-phase architecture**: ACE context gathering → Iterative multi-CLI discussion → Plan generation. Orchestrator delegates analysis to agents, only handles user decisions and session management. + +**Process**: +- **Phase 1**: ACE semantic search gathers codebase context +- **Phase 2**: cli-discuss-agent orchestrates Gemini/Codex/Claude for cross-verified analysis +- **Phase 3-5**: User decision → Plan generation → Execution handoff + +**vs Single-CLI Planning**: +- **Single**: One model perspective, potential blind spots +- **Multi-CLI**: Cross-verification catches inconsistencies, builds consensus on solutions + +### Value Proposition + +1. **Multi-Perspective Analysis**: Gemini + Codex + Claude analyze from different angles +2. **Cross-Verification**: Identify agreements/disagreements, build confidence +3. **User-Driven Decisions**: Every round ends with user decision point +4. **Iterative Convergence**: Progressive refinement until consensus reached + +### 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: Input & Context Gathering - |-- Parse user task description - |-- ACE semantic search for codebase context - |-- Build initial context package - +-- Initialize discussion session +Phase 1: Context Gathering + └─ ACE semantic search, extract keywords, build context package -Phase 2: Multi-CLI Collaborative Analysis (Iterative) - |-- Round N: - | |-- Claude Analysis: Architecture perspective - | |-- Codex/Gemini Analysis: Implementation perspective - | |-- Cross-verify technical feasibility - | +-- Synthesize multiple implementation approaches - | - +-- Loop until convergence or max rounds +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: Stage Summary & Options - |-- Present 2-3 viable solution options with trade-offs - |-- Proactively ask clarifying questions for ambiguities - +-- Wait for user feedback +Phase 3: Present Options + └─ Display solutions with trade-offs from agent output -Phase 4: User Decision Point - |-- Option A: User approves current approach -> Phase 5 - |-- Option B: User provides clarification/adjustments -> Return to Phase 2 - +-- Option C: User requests different direction -> Reset analysis +Phase 4: User Decision + ├─ Approve solution → Phase 5 + ├─ Need clarification → Return to Phase 2 + └─ Change direction → Reset with feedback -Phase 5: Agent Planning & Output Generation - |-- Invoke cli-lite-planning-agent with discussion context - |-- Generate IMPL_PLAN.md (documentation) - |-- Generate plan.json (structured plan for execution) - |-- User confirms execution - +-- Hand off to /workflow:lite-execute +Phase 5: Plan Generation (via @cli-lite-planning-agent) + ├─ Generate IMPL_PLAN.md + plan.json + └─ Hand off to /workflow:lite-execute ``` -## Implementation +### Agent Roles -### Phase 1: Input & Context Gathering +| Agent | Responsibility | +|-------|---------------| +| **Orchestrator** | Session management, ACE context, user decisions, phase transitions | +| **@cli-discuss-agent** | Multi-CLI execution (Gemini/Codex/Claude), cross-verification, solution synthesis, synthesis.json output | +| **@cli-lite-planning-agent** | Task decomposition, IMPL_PLAN.md + plan.json generation | + +## Core Responsibilities + +### Phase 1: Context Gathering **Session Initialization**: ```javascript -// Helper: Get UTC+8 (China Standard Time) ISO string -const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString() - -// Parse arguments -const { taskDescription, maxRounds, tools } = parseArgs(args) -const effectiveMaxRounds = maxRounds || 3 -const effectiveTools = tools || ['gemini', 'codex'] - -// Generate session ID -const taskSlug = taskDescription.toLowerCase().replace(/[^a-z0-9]+/g, '-').substring(0, 40) -const dateStr = getUtc8ISOString().substring(0, 10) -const sessionId = `MCP-${taskSlug}-${dateStr}` +const sessionId = `MCP-${taskSlug}-${date}` const sessionFolder = `.workflow/.multi-cli-plan/${sessionId}` - -// Create session folder -Bash(`mkdir -p ${sessionFolder}/rounds && test -d ${sessionFolder} && echo "SUCCESS: ${sessionFolder}"`) - -// Initialize session state -const sessionState = { - session_id: sessionId, - task_description: taskDescription, - created_at: getUtc8ISOString(), - max_rounds: effectiveMaxRounds, - tools: effectiveTools, - current_round: 0, - phase: 'context-gathering', - rounds: [], - solutions: [], - user_decisions: [], - final_plan: null -} - -Write(`${sessionFolder}/session-state.json`, JSON.stringify(sessionState, null, 2)) +Bash(`mkdir -p ${sessionFolder}/rounds`) ``` -**ACE Context Gathering**: +**ACE Context Queries**: ```javascript -// Step 1: Extract keywords from task description -const keywords = extractKeywords(taskDescription) -// e.g., "Add dark mode support" -> ["dark", "mode", "theme", "style", "color"] - -// Step 2: Use ACE to understand codebase structure and relevant code const aceQueries = [ - // Architecture query - `Project architecture and module structure related to ${keywords.slice(0, 3).join(', ')}`, - // Implementation query - `Existing implementations of ${keywords[0]} in this codebase`, - // Pattern query - `Code patterns and conventions for ${keywords.slice(0, 2).join(' ')} features`, - // Integration query - `Integration points and dependencies for ${keywords[0]} functionality` + `Project architecture related to ${keywords}`, + `Existing implementations of ${keywords[0]}`, + `Code patterns for ${keywords} features`, + `Integration points for ${keywords[0]}` ] - -const aceResults = [] -for (const query of aceQueries) { - const result = await mcp__ace-tool__search_context({ - project_root_path: process.cwd(), - query: query - }) - aceResults.push({ query, result, timestamp: getUtc8ISOString() }) -} - -// Step 3: Build context package (kept in memory for CLI consumption) -const contextPackage = { - task_description: taskDescription, - keywords: keywords, - ace_results: aceResults, - relevant_files: extractRelevantFiles(aceResults), - detected_patterns: extractPatterns(aceResults), - architecture_insights: aceResults[0].result, - existing_implementations: aceResults[1].result -} - -// Update session state -sessionState.phase = 'context-gathered' -sessionState.context_summary = { - files_identified: contextPackage.relevant_files.length, - patterns_detected: contextPackage.detected_patterns.length, - ace_queries: aceQueries.length -} +// 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-Driven Collaborative Analysis +### Phase 2: Agent Delegation -**Core Principle**: Orchestrator delegates all analysis to `cli-discuss-agent`, only reads output files for decision making. +**Core Principle**: Orchestrator only delegates and reads output - NO direct CLI execution. -**Analysis Round Loop**: +**Agent Invocation**: ```javascript -let currentRound = 0 -let shouldContinue = true -let analysisResults = [] - -while (shouldContinue && currentRound < effectiveMaxRounds) { - currentRound++ - - console.log(` -## Analysis Round ${currentRound}/${effectiveMaxRounds} - -Delegating to cli-discuss-agent... -`) - - // ======================================== - // DELEGATE TO AGENT - No direct analysis - // ======================================== - Task({ - subagent_type: "cli-discuss-agent", - run_in_background: false, - description: `Discussion round ${currentRound}`, - prompt: ` -## Task Objective -Execute collaborative discussion round ${currentRound} for task analysis. - +Task({ + 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} -- **Session Folder**: ${sessionFolder} +- 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"] } -## ACE Context -${JSON.stringify(contextPackage, null, 2)} +## Execution Process +1. Parse input context (handle JSON strings) +2. Check if ACE supplementary search needed +3. Build CLI prompts with context +4. Execute CLIs (parallel or serial per cli_config.mode) +5. Parse CLI outputs, handle failures with fallback +6. Perform cross-verification between CLI results +7. Synthesize solutions, calculate scores +8. Calculate convergence, generate clarification questions +9. Write synthesis.json -## Previous Rounds -${analysisResults.length > 0 - ? JSON.stringify(analysisResults, null, 2) - : 'None (first round)'} - -## User Feedback -${userFeedback || 'None'} - -## CLI Configuration -${JSON.stringify({ - tools: effectiveTools, - timeout: 600000, - fallback_chain: ['gemini', 'codex', 'qwen'] -}, null, 2)} - -## Output Requirements +## Output Write: ${sessionFolder}/rounds/${currentRound}/synthesis.json -Follow cli-discuss-agent output schema exactly. - -## Success Criteria -- [ ] All configured CLI tools executed -- [ ] Cross-verification completed -- [ ] 2-3 solution options generated -- [ ] Convergence score calculated -- [ ] synthesis.json written to round folder +## 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 - Decision making only - // ======================================== - const synthesisPath = `${sessionFolder}/rounds/${currentRound}/synthesis.json` - const roundSynthesis = JSON.parse(Read(synthesisPath)) - analysisResults.push(roundSynthesis) - - // Update session state from agent output - sessionState.rounds.push({ - number: currentRound, - cli_tools_used: roundSynthesis._metadata.cli_tools_used, - solutions_identified: roundSynthesis.solutions.length, - convergence_score: roundSynthesis.convergence.score, - new_insights: roundSynthesis.convergence.new_insights, - recommendation: roundSynthesis.convergence.recommendation - }) - - // Display round summary - console.log(` -### Round ${currentRound} Complete - -**Convergence**: ${roundSynthesis.convergence.score.toFixed(2)} -**Solutions Found**: ${roundSynthesis.solutions.length} -**Recommendation**: ${roundSynthesis.convergence.recommendation} - -**Solutions**: -${roundSynthesis.solutions.map((s, i) => `${i+1}. ${s.name} (${s.effort} effort, ${s.risk} risk)`).join('\n')} -`) - - // Decide whether to continue based on agent's recommendation - if (roundSynthesis.convergence.recommendation === 'converged') { - shouldContinue = false - console.log('Analysis converged. Proceeding to decision phase.') - } else if (roundSynthesis.convergence.recommendation === 'user_input_needed') { - // Collect user feedback before next round - const feedbackResult = await AskUserQuestion({ - questions: [{ - question: 'Clarification needed. How would you like to proceed?', - header: 'Feedback', - multiSelect: false, - options: [ - { label: 'Provide Clarification', description: 'Answer questions and continue analysis' }, - { label: 'Proceed Anyway', description: 'Accept current solutions' }, - { label: 'Change Direction', description: 'Modify task requirements' } - ] - }] - }) - - if (feedbackResult === 'Provide Clarification') { - // Display clarification questions - console.log(` -### Clarification Questions -${roundSynthesis.clarification_questions.map((q, i) => `${i+1}. ${q}`).join('\n')} -`) - // User provides feedback via "Other" option or follow-up - userFeedback = feedbackResult.other || '' - } else if (feedbackResult === 'Proceed Anyway') { - shouldContinue = false - } else { - // Reset with new direction - userFeedback = feedbackResult.other || '' - } - } else { - // Continue to next round - shouldContinue = roundSynthesis.convergence.new_insights && currentRound < effectiveMaxRounds - } -} - -// Get final synthesis from last round -const finalSynthesis = analysisResults[analysisResults.length - 1] -``` - ---- - -### Phase 3: Review Agent Output & Present Options - -**Core Principle**: Orchestrator only reads agent output files and formats them for user decision. - -**Read and Present Solutions**: -```javascript -// ======================================== -// READ FINAL AGENT OUTPUT - No processing -// ======================================== -// finalSynthesis already loaded from agent's synthesis.json in Phase 2 - -console.log(` -## Stage Summary - -### Analysis Complete (from cli-discuss-agent output) -- Rounds completed: ${currentRound} -- CLI tools used: ${finalSynthesis._metadata.cli_tools_used.join(', ')} -- Cross-verification: ${finalSynthesis.cross_verification.agreements.length} agreements, ${finalSynthesis.cross_verification.disagreements.length} disagreements -- Convergence score: ${finalSynthesis.convergence.score.toFixed(2)} - -### Solution Options (from agent synthesis) - -${finalSynthesis.solutions.map((solution, index) => ` -**Option ${index + 1}: ${solution.name}** -*Source: ${solution.source_cli.join(' + ')}* - -Description: ${solution.description} - -Trade-offs: -| Aspect | Assessment | -|--------|------------| -| Effort | ${solution.effort} | -| Risk | ${solution.risk} | -| Maintainability | ${solution.maintainability} | -| Performance | ${solution.performance_impact} | - -Pros: -${solution.pros.map(p => `- ${p}`).join('\n')} - -Cons: -${solution.cons.map(c => `- ${c}`).join('\n')} - -Key files affected: -${solution.affected_files.slice(0, 5).map(f => `- ${f.file}:${f.line} - ${f.reason}`).join('\n')} -`).join('\n---\n')} - -### Cross-Verification Summary - -**Agreements**: -${finalSynthesis.cross_verification.agreements.slice(0, 5).map(a => `- ${a}`).join('\n')} - -**Disagreements** (resolved): -${finalSynthesis.cross_verification.disagreements.slice(0, 3).map(d => `- ${d}`).join('\n') || '- None'} - -### Clarification Questions (from agent) - -${finalSynthesis.clarification_questions.length > 0 - ? finalSynthesis.clarification_questions.map((q, i) => `${i + 1}. ${q}`).join('\n') - : 'No clarifications needed.'} -`) - -// Update session state with agent's findings -sessionState.solutions = finalSynthesis.solutions -sessionState.cross_verification = finalSynthesis.cross_verification -sessionState.phase = 'awaiting-decision' -Write(`${sessionFolder}/session-state.json`, JSON.stringify(sessionState, null, 2)) -``` - ---- - -### Phase 4: User Decision Point - -**Collect User Decision**: -```javascript -const decisionResult = await AskUserQuestion({ - questions: [ - { - question: `Which solution approach do you prefer?`, - header: "Solution", - multiSelect: false, - options: finalSynthesis.solutions.map((sol, i) => ({ - label: `Option ${i + 1}: ${sol.name}`, - description: `${sol.effort} effort, ${sol.risk} risk` - })).concat([ - { label: "Need More Analysis", description: "Return to analysis with additional context" } - ]) - }, - { - question: "Any clarifications or adjustments?", - header: "Feedback", - multiSelect: true, - options: [ - { label: "Proceed as-is", description: "Generate final plan with selected option" }, - { label: "Add constraints", description: "Specify additional requirements" }, - { label: "Change scope", description: "Adjust what's included/excluded" }, - { label: "Different direction", description: "Explore completely different approach" } - ] - } - ] }) +``` -// Process decision -const userDecision = { - timestamp: getUtc8ISOString(), - selected_solution: decisionResult.solution, - feedback_type: decisionResult.feedback, - additional_input: decisionResult.other || null -} +**Read Agent Output**: +```javascript +const synthesis = JSON.parse(Read(`${sessionFolder}/rounds/${round}/synthesis.json`)) +// Access top-level fields: solutions, convergence, cross_verification, clarification_questions +``` -sessionState.user_decisions.push(userDecision) - -// Decision routing -if (userDecision.selected_solution === 'Need More Analysis' || - userDecision.feedback_type.includes('Different direction')) { - // Return to Phase 2 with updated context - sessionState.phase = 'additional-analysis' - // Continue analysis loop with user feedback incorporated -} else if (userDecision.feedback_type.includes('Add constraints') || - userDecision.feedback_type.includes('Change scope')) { - // Prompt for additional details - const additionalInput = await AskUserQuestion({ - questions: [{ - question: "Please provide the additional constraints or scope changes:", - header: "Details", - multiSelect: false, - options: [ - { label: "Performance priority", description: "Optimize for speed over simplicity" }, - { label: "Maintainability priority", description: "Prefer clear, maintainable code" }, - { label: "Minimal changes", description: "Change as few files as possible" }, - { label: "Full refactor OK", description: "Willing to do comprehensive changes" } - ] - }] - }) - // Incorporate and proceed to Phase 5 - userDecision.constraints = additionalInput - sessionState.phase = 'generating-plan' +**Convergence Decision**: +```javascript +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 { - // Proceed to Phase 5 - sessionState.phase = 'generating-plan' + // Continue to next round if new_insights && round < maxRounds } ``` ---- +### Phase 3: Present Options -### Phase 5: Agent Planning & Output Generation - -**Step 5.1: Prepare Planning Context** +**Display from Agent Output** (no processing): ```javascript -// Select the approved solution -const selectedSolution = finalSynthesis.solutions[userDecision.selected_solution_index] - -// Build comprehensive planning context from discussion -const planningContext = { - task_description: taskDescription, - selected_solution: selectedSolution, - analysis_rounds: analysisResults, - consensus_points: finalSynthesis._internal?.cross_verification?.agreements || [], - user_constraints: userDecision.constraints || null, - ace_context: contextPackage, - clarifications: sessionState.user_decisions -} - console.log(` -## Generating Implementation Plan +## Solution Options -Selected approach: **${selectedSolution.name}** -Invoking planning agent... +${synthesis.solutions.map((s, i) => ` +**Option ${i+1}: ${s.name}** +Source: ${s.source_cli.join(' + ')} +Effort: ${s.effort} | Risk: ${s.risk} + +Pros: ${s.pros.join(', ')} +Cons: ${s.cons.join(', ')} + +Files: ${s.affected_files.slice(0,3).map(f => `${f.file}:${f.line}`).join(', ')} +`).join('\n')} + +## Cross-Verification +Agreements: ${synthesis.cross_verification.agreements.length} +Disagreements: ${synthesis.cross_verification.disagreements.length} `) ``` -**Step 5.2: Invoke cli-lite-planning-agent** +### Phase 4: User Decision + +**Decision Options**: +```javascript +AskUserQuestion({ + questions: [{ + question: "Which solution approach?", + header: "Solution", + 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" } + ]) + }] +}) +``` + +**Routing**: +- Approve → Phase 5 +- Need More Analysis → Phase 2 with feedback +- Add constraints → Collect details, then Phase 5 + +### Phase 5: Plan Generation + +**Invoke Planning Agent**: ```javascript -// Call planning agent to generate detailed plan Task({ subagent_type: "cli-lite-planning-agent", run_in_background: false, - description: "Generate detailed implementation plan", + description: "Generate implementation plan", prompt: ` -## Task Objective -Generate detailed implementation plan based on collaborative discussion results. - -## Output Schema Reference +## Schema Reference Execute: cat ~/.claude/workflows/cli-templates/schemas/plan-json-schema.json -## Project Context (MANDATORY - Read Both Files) -1. Read: .workflow/project-tech.json (technology stack, architecture) -2. Read: .workflow/project-guidelines.json (user-defined constraints) +## Selected Solution +${JSON.stringify(selectedSolution)} -## Discussion Results +## Analysis Consensus +${synthesis.cross_verification.agreements.join('\n')} -### Task Description -${taskDescription} +## Execution Process +1. Read plan-json-schema.json for output structure +2. Read project-tech.json and project-guidelines.json +3. Decompose solution into 2-7 tasks (group by feature, not file) +4. Assign dependencies and execution groups +5. Generate IMPL_PLAN.md with step-by-step documentation +6. Generate plan.json following schema exactly -### Selected Solution -**Name**: ${selectedSolution.name} -**Description**: ${selectedSolution.description} -**Effort**: ${selectedSolution.effort} -**Risk**: ${selectedSolution.risk} +## Output +- ${sessionFolder}/IMPL_PLAN.md +- ${sessionFolder}/plan.json -**Pros**: -${selectedSolution.pros.map(p => `- ${p}`).join('\n')} - -**Cons**: -${selectedSolution.cons.map(c => `- ${c}`).join('\n')} - -**Affected Files**: -${selectedSolution.affected_files.map(f => `- ${f.file}:${f.line} - ${f.reason}`).join('\n')} - -### Analysis Consensus -${(finalSynthesis._internal?.cross_verification?.agreements || []).map(p => `- ${p}`).join('\n')} - -### User Constraints -${userDecision.constraints ? JSON.stringify(userDecision.constraints) : 'None specified'} - -### ACE Context Summary -Relevant files: ${contextPackage.relevant_files.slice(0, 15).join(', ')} -Detected patterns: ${contextPackage.detected_patterns.join(', ')} - -## Output Requirements - -### 1. IMPL_PLAN.md (Documentation) -Write: ${sessionFolder}/IMPL_PLAN.md - -Structure: -\`\`\`markdown -# Implementation Plan: {Task Title} - -## Overview -- **Task**: {description} -- **Approach**: {selected solution name} -- **Complexity**: {Low/Medium/High} -- **Generated**: {timestamp} - -## Background & Decision Rationale -{Why this approach was chosen, key trade-offs considered} - -## Implementation Steps - -### Step 1: {Title} -**Objective**: {what this step achieves} -**Files**: -- \`path/to/file.ts:line\` - {change description} - -**Actions**: -1. {specific action} -2. {specific action} - -**Verification**: {how to verify this step is complete} - -### Step 2: ... - -## File Manifest -| File | Lines | Change Type | Description | -|------|-------|-------------|-------------| -| ... | ... | ... | ... | - -## Acceptance Criteria -1. {criterion with verification method} -2. ... - -## Risk Mitigation -| Risk | Mitigation Strategy | -|------|---------------------| -| ... | ... | - -## Dependencies & Prerequisites -- {prerequisite 1} -- {prerequisite 2} -\`\`\` - -### 2. plan.json (Structured Plan) -Write: ${sessionFolder}/plan.json - -Follow schema from plan-json-schema.json. Key requirements: -- tasks: 2-7 structured tasks (group by feature/module, NOT by file) -- Each task includes: id, title, description, scope, files, depends_on, execution_group -- _metadata.source: "collaborative-discussion" -- _metadata.session_id: "${sessionId}" - -## Task Grouping Rules -1. **Group by feature**: All changes for one feature = one task -2. **Substantial tasks**: Each task = 15-60 minutes of work -3. **True dependencies only**: Use depends_on only when Task B needs Task A's output -4. **Prefer parallel**: Most tasks should be independent - -## Success Criteria +## Completion Checklist - [ ] IMPL_PLAN.md written with complete documentation - [ ] plan.json follows schema exactly - [ ] All affected files have line numbers +- [ ] Tasks grouped by feature (not one per file) - [ ] Acceptance criteria are testable -- [ ] Tasks are properly grouped (not one per file) ` }) ``` -**Step 5.3: Display Generated Plan** +**Hand off to Execution**: ```javascript -// Read generated outputs -const implPlan = Read(`${sessionFolder}/IMPL_PLAN.md`) -const planJson = JSON.parse(Read(`${sessionFolder}/plan.json`)) - -console.log(` -## Plan Generated Successfully - -### Documentation -${implPlan} - ---- - -### Structured Plan Summary -**Tasks**: ${planJson.tasks.length} -**Complexity**: ${planJson.complexity} -**Estimated Time**: ${planJson.estimated_time} - -| # | Task | Scope | Dependencies | -|---|------|-------|--------------| -${planJson.tasks.map((t, i) => - `| ${i+1} | ${t.title} | ${t.scope} | ${t.depends_on?.join(', ') || 'None'} |` -).join('\n')} -`) - -// Update session state -sessionState.phase = 'plan-generated' -sessionState.artifacts = { - impl_plan: `${sessionFolder}/IMPL_PLAN.md`, - plan_json: `${sessionFolder}/plan.json` +if (userConfirms) { + SlashCommand("/workflow:lite-execute --in-memory") } -Write(`${sessionFolder}/session-state.json`, JSON.stringify(sessionState, null, 2)) ``` -**Step 5.4: Confirm & Hand off to Execution** -```javascript -const executeDecision = await AskUserQuestion({ - questions: [{ - question: `Plan generated (${planJson.tasks.length} tasks). Proceed to execution?`, - header: "Execute", - multiSelect: false, - options: [ - { label: "Execute Now (Recommended)", description: "Hand off to /workflow:lite-execute" }, - { label: "Review First", description: "Review plan files before execution" }, - { label: "Modify Plan", description: "Adjust plan before execution" }, - { label: "Save Only", description: "Save plan without execution" } - ] - }] -}) - -if (executeDecision === 'Execute Now') { - // Build execution context - const executionContext = { - planObject: planJson, - explorationsContext: contextPackage, - clarificationContext: sessionState.user_decisions, - originalUserInput: taskDescription, - executionMethod: 'Agent', // Default to Agent execution - session: { - id: sessionId, - folder: sessionFolder, - artifacts: { - impl_plan: `${sessionFolder}/IMPL_PLAN.md`, - plan_json: `${sessionFolder}/plan.json`, - session_state: `${sessionFolder}/session-state.json` - } - } - } - - // Update state and hand off - sessionState.phase = 'executing' - Write(`${sessionFolder}/session-state.json`, JSON.stringify(sessionState, null, 2)) - - console.log(` -## Handing off to lite-execute - -Session: ${sessionId} -Tasks: ${planJson.tasks.length} -`) - - // Hand off to lite-execute - SlashCommand(command="/workflow:lite-execute --in-memory") - -} else if (executeDecision === 'Review First') { - console.log(` -## Plan Files Ready for Review - -- Documentation: ${sessionFolder}/IMPL_PLAN.md -- Structured Plan: ${sessionFolder}/plan.json - -Run \`/workflow:lite-execute --session=${sessionId}\` when ready. -`) - -} else if (executeDecision === 'Modify Plan') { - // Return to Phase 4 with modification request - sessionState.phase = 'awaiting-decision' - console.log('Returning to decision phase for plan modification...') - -} else { - console.log(` -## Plan Saved - -Session: ${sessionId} -Location: ${sessionFolder}/ - -Files: -- IMPL_PLAN.md (documentation) -- plan.json (structured plan) -- session-state.json (full context) - -To execute later: /workflow:lite-execute --session=${sessionId} -`) - sessionState.phase = 'complete' -} - -Write(`${sessionFolder}/session-state.json`, JSON.stringify(sessionState, null, 2)) -``` - ---- - -## Session Folder Structure +## Output File Structure ``` .workflow/.multi-cli-plan/{MCP-task-slug-YYYY-MM-DD}/ -|-- session-state.json # Session state with all rounds and decisions -|-- rounds/ -| |-- 1/ -| | +-- synthesis.json # Round 1 analysis synthesis -| |-- 2/ -| | +-- synthesis.json # Round 2 analysis synthesis -| +-- .../ -|-- IMPL_PLAN.md # Implementation plan documentation -+-- plan.json # Structured plan for lite-execute +├── 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) +│ └── .../ +├── IMPL_PLAN.md # Documentation (cli-lite-planning-agent) +└── plan.json # Structured plan (cli-lite-planning-agent) ``` -## Key Features +**File Producers**: -### 1. Agent-Orchestrator Separation +| File | Producer | Content | +|------|----------|---------| +| `session-state.json` | Orchestrator | Session metadata, rounds, decisions | +| `rounds/*/synthesis.json` | cli-discuss-agent | Solutions, convergence, cross-verification | +| `IMPL_PLAN.md` | cli-lite-planning-agent | Human-readable plan | +| `plan.json` | cli-lite-planning-agent | Structured tasks for execution | -**Orchestrator (this command)** only handles: -- Task delegation to agents -- Reading agent output files -- User interaction and decisions -- Session state management +## synthesis.json Schema -**Agent (cli-discuss-agent)** handles: -- Multi-CLI execution (Gemini, Codex, Qwen) -- Cross-verification between CLI outputs -- Solution synthesis and ranking -- Writing structured output files - -``` -┌─────────────────────────────────────────────────────────────┐ -│ ORCHESTRATOR │ -│ (multi-cli-plan.md - decision layer) │ -├─────────────────────────────────────────────────────────────┤ -│ │ -│ 1. Delegate → Task(cli-discuss-agent) │ -│ 2. Wait for completion │ -│ 3. Read → synthesis.json │ -│ 4. Display → User │ -│ 5. Collect → Decision │ -│ 6. Loop or proceed │ -│ │ -└─────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────┐ -│ CLI-DISCUSS-AGENT │ -│ (analysis layer) │ -├─────────────────────────────────────────────────────────────┤ -│ │ -│ Gemini CLI ──┐ │ -│ ├──→ Cross-Verify ──→ Synthesize │ -│ Codex CLI ───┘ │ │ -│ ▼ │ -│ synthesis.json │ -│ │ -└─────────────────────────────────────────────────────────────┘ +**Primary Fields** (orchestrator reads these): +```json +{ + "round": 1, + "solutions": [{ + "name": "Solution Name", + "description": "What this does", + "source_cli": ["gemini", "codex"], + "pros": [], "cons": [], + "effort": "low|medium|high", + "risk": "low|medium|high", + "affected_files": [{"file": "path", "line": 10, "reason": "why"}] + }], + "convergence": { + "score": 0.85, + "new_insights": false, + "recommendation": "converged|continue|user_input_needed" + }, + "cross_verification": { + "agreements": [], + "disagreements": [], + "resolution": "..." + }, + "clarification_questions": [] +} ``` -### 2. Multi-CLI Cross-Verification +**Extended Fields** (for visualization): `metadata`, `discussionTopic`, `relatedFiles`, `planning`, `decision`, `decisionRecords` -Agent invokes multiple CLI tools and cross-verifies: -- **Gemini**: Deep code analysis, pattern recognition -- **Codex**: Implementation verification, code generation feasibility -- **Qwen** (fallback): Alternative perspective +## TodoWrite Structure -Cross-verification identifies: -- Agreements (high confidence points) -- Disagreements (requiring resolution) -- Unique insights from each tool +**Initialization**: +```javascript +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" } +]}) +``` -### 3. User-Driven Decision Points - -Every analysis cycle ends with user decision: -- Approve and proceed to planning -- Request more analysis with feedback -- Adjust requirements or direction -- View detailed agent output files - -### 4. Iterative Convergence - -Each round builds on previous findings: -- Round 1: Initial exploration, identify major approaches -- Round 2: Deep dive into promising approaches, resolve conflicts -- Round 3: Final refinement, edge case analysis - -Agent calculates convergence score (0.0-1.0) and recommends: -- `converged`: Ready for planning -- `continue`: More analysis needed -- `user_input_needed`: Clarification required - -### 5. Trade-off Transparency - -Each solution option includes explicit trade-offs: -- Effort (low/medium/high) -- Risk assessment -- Maintainability impact -- Performance considerations -- Affected files with line numbers -- Source CLI(s) that proposed the solution +**During Discussion Rounds**: +```javascript +TodoWrite({ todos: [ + { content: "Phase 1: Context Gathering", status: "completed", activeForm: "Gathering context" }, + { content: "Phase 2: Multi-CLI Discussion", status: "in_progress", activeForm: "Running discussion" }, + { content: " → Round 1: Initial analysis", status: "completed", activeForm: "Analyzing" }, + { content: " → Round 2: Deep verification", status: "in_progress", activeForm: "Verifying" }, + { content: "Phase 3: Present Options", status: "pending", activeForm: "Presenting options" }, + // ... +]}) +``` ## Error Handling | Error | Resolution | |-------|------------| | ACE search fails | Fall back to Glob/Grep for file discovery | -| Agent fails to produce synthesis.json | Retry agent with simpler context | -| CLI tool timeout (in agent) | Agent uses fallback chain: gemini → codex → qwen | -| No convergence after max rounds | Present best available options, flag uncertainty | -| synthesis.json parse error | Agent retries with degraded mode | -| User cancels | Save session state for later resumption | +| 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 analysis rounds before forcing decision | -| `--tools` | gemini,codex | CLI tools to use for analysis | -| `--auto-execute` | false | Auto-execute after plan approval | -| `--save-context` | true | Persist ACE context for resumption | +| `--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 | ## Best Practices -1. **Be Specific**: More detailed task descriptions lead to better initial context gathering -2. **Provide Feedback**: Use clarification rounds to narrow down requirements -3. **Trust the Process**: Allow multiple rounds for complex tasks -4. **Review Trade-offs**: Carefully consider pros/cons of each solution option -5. **Iterate**: Don't hesitate to request additional analysis if uncertain -6. **Review Plan**: Check IMPL_PLAN.md before execution for complete understanding - -## Output Artifacts - -| File | Purpose | Producer | -|------|---------|----------| -| `rounds/{n}/synthesis.json` | Round analysis results | cli-discuss-agent | -| `IMPL_PLAN.md` | Human-readable documentation | cli-lite-planning-agent | -| `plan.json` | Structured tasks for execution | cli-lite-planning-agent | -| `session-state.json` | Session tracking | Orchestrator | - -**synthesis.json schema** (produced by cli-discuss-agent): -```json -{ - "round": 1, - "cli_analyses": [...], - "cross_verification": { "agreements": [], "disagreements": [] }, - "solutions": [{ "name": "...", "pros": [], "cons": [], "effort": "..." }], - "convergence": { "score": 0.85, "recommendation": "converged" }, - "clarification_questions": [] -} -``` +1. **Be Specific**: Detailed task descriptions improve ACE context quality +2. **Provide Feedback**: Use clarification rounds to refine requirements +3. **Trust Cross-Verification**: Multi-CLI consensus indicates high confidence +4. **Review Trade-offs**: Consider pros/cons before selecting solution +5. **Check synthesis.json**: Review agent output for detailed analysis +6. **Iterate When Needed**: Don't hesitate to request more analysis ## Related Commands ```bash -# Resume a saved multi-cli-plan session +# Resume saved session /workflow:lite-execute --session=MCP-xxx -# For simpler tasks without multi-round discussion +# Simpler single-round planning /workflow:lite-plan "task description" -# For issue-driven discovery +# Issue-driven discovery /issue:discover-by-prompt "find issues" -# View generated plan +# View session files cat .workflow/.multi-cli-plan/{session-id}/IMPL_PLAN.md +cat .workflow/.multi-cli-plan/{session-id}/rounds/1/synthesis.json ``` diff --git a/ccw/src/core/server.ts b/ccw/src/core/server.ts index 2173491d..00920a33 100644 --- a/ccw/src/core/server.ts +++ b/ccw/src/core/server.ts @@ -597,12 +597,12 @@ export async function startServer(options: ServerOptions = {}): Promise