mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-28 09:23:08 +08:00
Migrated to D:/ccw-skill-hub/skills/: - project-analyze - copyright-docs - software-manual
6.8 KiB
6.8 KiB
Command: deep-analyze
CLI Fan-out deep analysis. Splits findings into 2 domain groups, runs parallel CLI agents for root cause / impact / optimization enrichment.
When to Use
- Phase 3 of Reviewer, when
deep_analysis.length > 0 - Requires
deep_analysis[]array andsessionFolderfrom Phase 2
Trigger conditions:
- REV-* task in Phase 3 with at least 1 finding triaged for deep analysis
Strategy
Delegation Mode
Mode: CLI Fan-out (max 2 parallel agents, analysis only)
Tool Fallback Chain
gemini (primary) -> qwen (fallback) -> codex (fallback)
Group Split
Group A: Security + Correctness findings -> 1 CLI agent
Group B: Performance + Maintainability findings -> 1 CLI agent
If either group empty -> skip that agent (run single agent only)
Execution Steps
Step 1: Split Findings into Groups
const groupA = deep_analysis.filter(f =>
f.dimension === 'security' || f.dimension === 'correctness'
)
const groupB = deep_analysis.filter(f =>
f.dimension === 'performance' || f.dimension === 'maintainability'
)
// Collect all affected files for CLI context
const collectFiles = (group) => [...new Set(
group.map(f => f.location?.file).filter(Boolean)
)]
const filesA = collectFiles(groupA)
const filesB = collectFiles(groupB)
Step 2: Build CLI Prompts
function buildPrompt(group, groupLabel, affectedFiles) {
const findingsJson = JSON.stringify(group, null, 2)
const filePattern = affectedFiles.length <= 20
? affectedFiles.map(f => `@${f}`).join(' ')
: '@**/*.{ts,tsx,js,jsx,py,go,java,rs}'
return `PURPOSE: Deep analysis of ${groupLabel} code findings -- root cause, impact, optimization suggestions.
TASK:
- For each finding: trace root cause (independent issue or symptom of another finding?)
- Identify findings sharing the same root cause -> mark related_findings with their IDs
- Assess impact scope and affected files (blast_radius: function/module/system)
- Propose fix strategy (minimal fix vs refactor) with tradeoff analysis
- Identify fix dependencies (which findings must be fixed first?)
- For each finding add these enrichment fields:
root_cause: { description: string, related_findings: string[], is_symptom: boolean }
impact: { scope: "low"|"medium"|"high", affected_files: string[], blast_radius: string }
optimization: { approach: string, alternative: string, tradeoff: string }
fix_strategy: "minimal" | "refactor" | "skip"
fix_complexity: "low" | "medium" | "high"
fix_dependencies: string[] (finding IDs that must be fixed first)
MODE: analysis
CONTEXT: ${filePattern}
Findings to analyze:
${findingsJson}
EXPECTED: Respond with ONLY a JSON array. Each element is the original finding object with the 6 enrichment fields added. Preserve ALL original fields exactly.
CONSTRAINTS: Preserve original finding fields | Only add enrichment fields | Return raw JSON array only | No markdown wrapping`
}
const promptA = groupA.length > 0
? buildPrompt(groupA, 'Security + Correctness', filesA) : null
const promptB = groupB.length > 0
? buildPrompt(groupB, 'Performance + Maintainability', filesB) : null
Step 3: Execute CLI Agents (Parallel)
function runCli(prompt) {
const tools = ['gemini', 'qwen', 'codex']
for (const tool of tools) {
try {
const out = Bash(
`ccw cli -p "${prompt.replace(/"/g, '\\"')}" --tool ${tool} --mode analysis --rule analysis-diagnose-bug-root-cause`,
{ timeout: 300000 }
)
return out
} catch { continue }
}
return null // All tools failed
}
// Run both groups -- if both present, execute via Bash run_in_background for parallelism
let resultA = null, resultB = null
if (promptA && promptB) {
// Both groups: run in parallel
// Group A in background
Bash(`ccw cli -p "${promptA.replace(/"/g, '\\"')}" --tool gemini --mode analysis --rule analysis-diagnose-bug-root-cause > "${sessionFolder}/review/_groupA.txt" 2>&1`,
{ run_in_background: true, timeout: 300000 })
// Group B synchronous (blocks until done)
resultB = runCli(promptB)
// Wait for Group A to finish, then read output
Bash(`sleep 5`) // Brief wait if B finished faster
try { resultA = Read(`${sessionFolder}/review/_groupA.txt`) } catch {}
// If background failed, try synchronous fallback
if (!resultA) resultA = runCli(promptA)
} else if (promptA) {
resultA = runCli(promptA)
} else if (promptB) {
resultB = runCli(promptB)
}
Step 4: Parse & Merge Results
function parseCliOutput(output) {
if (!output) return []
try {
const match = output.match(/\[[\s\S]*\]/)
if (!match) return []
const parsed = JSON.parse(match[0])
// Validate enrichment fields exist
return parsed.filter(f => f.id && f.dimension).map(f => ({
...f,
root_cause: f.root_cause || { description: 'Unknown', related_findings: [], is_symptom: false },
impact: f.impact || { scope: 'medium', affected_files: [f.location?.file].filter(Boolean), blast_radius: 'module' },
optimization: f.optimization || { approach: f.suggested_fix || '', alternative: '', tradeoff: '' },
fix_strategy: ['minimal', 'refactor', 'skip'].includes(f.fix_strategy) ? f.fix_strategy : 'minimal',
fix_complexity: ['low', 'medium', 'high'].includes(f.fix_complexity) ? f.fix_complexity : 'medium',
fix_dependencies: Array.isArray(f.fix_dependencies) ? f.fix_dependencies : []
}))
} catch { return [] }
}
const enrichedA = parseCliOutput(resultA)
const enrichedB = parseCliOutput(resultB)
// Merge: CLI-enriched findings replace originals, unenriched originals kept as fallback
const enrichedMap = new Map()
for (const f of [...enrichedA, ...enrichedB]) enrichedMap.set(f.id, f)
const enrichedFindings = deep_analysis.map(f =>
enrichedMap.get(f.id) || {
...f,
root_cause: { description: 'Analysis unavailable', related_findings: [], is_symptom: false },
impact: { scope: 'medium', affected_files: [f.location?.file].filter(Boolean), blast_radius: 'unknown' },
optimization: { approach: f.suggested_fix || '', alternative: '', tradeoff: '' },
fix_strategy: 'minimal',
fix_complexity: 'medium',
fix_dependencies: []
}
)
// Write output
Write(`${sessionFolder}/review/enriched-findings.json`, JSON.stringify(enrichedFindings, null, 2))
// Cleanup temp files
Bash(`rm -f "${sessionFolder}/review/_groupA.txt" "${sessionFolder}/review/_groupB.txt"`)
Error Handling
| Scenario | Resolution |
|---|---|
| gemini CLI fails | Fallback to qwen, then codex |
| All CLI tools fail for a group | Use original findings with default enrichment |
| CLI output not valid JSON | Attempt regex extraction, else use defaults |
| Background task hangs | Synchronous fallback after timeout |
| One group fails, other succeeds | Merge partial results with defaults |
| Invalid enrichment fields | Apply defaults for missing/invalid fields |