mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-03-02 15:23:19 +08:00
feat(idaw): add CLI-assisted analysis for pre-task context and error recovery
- Pre-task context analysis via gemini for bugfix/complex tasks - CLI-assisted error diagnosis before retry on skill failure - Consistent implementation across run.md and resume.md
This commit is contained in:
@@ -237,6 +237,25 @@ for (let taskIdx = 0; taskIdx < remainingTasks.length; taskIdx++) {
|
|||||||
console.log(`\n--- [${taskIdx + 1}/${remainingTasks.length}] ${task.id}: ${task.title} ---`);
|
console.log(`\n--- [${taskIdx + 1}/${remainingTasks.length}] ${task.id}: ${task.title} ---`);
|
||||||
console.log(`Chain: ${chain.join(' → ')}`);
|
console.log(`Chain: ${chain.join(' → ')}`);
|
||||||
|
|
||||||
|
// ━━━ Pre-Task CLI Context Analysis (for complex/bugfix tasks) ━━━
|
||||||
|
if (['bugfix', 'bugfix-hotfix', 'feature-complex'].includes(resolvedType)) {
|
||||||
|
console.log(` Pre-analysis: gathering context for ${resolvedType} task...`);
|
||||||
|
const affectedFiles = (task.context?.affected_files || []).join(', ');
|
||||||
|
const preAnalysisPrompt = `PURPOSE: Pre-analyze codebase context for IDAW task before execution.
|
||||||
|
TASK: • Understand current state of: ${affectedFiles || 'files related to: ' + task.title} • Identify dependencies and risk areas • Note existing patterns to follow
|
||||||
|
MODE: analysis
|
||||||
|
CONTEXT: @**/*
|
||||||
|
EXPECTED: Brief context summary (affected modules, dependencies, risk areas) in 3-5 bullet points
|
||||||
|
CONSTRAINTS: Keep concise | Focus on execution-relevant context`;
|
||||||
|
const preAnalysis = Bash(`ccw cli -p '${preAnalysisPrompt.replace(/'/g, "'\\''")}' --tool gemini --mode analysis 2>&1 || echo "Pre-analysis skipped"`);
|
||||||
|
task.execution.skill_results.push({
|
||||||
|
skill: 'cli-pre-analysis',
|
||||||
|
status: 'completed',
|
||||||
|
context_summary: preAnalysis?.substring(0, 500),
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Execute skill chain
|
// Execute skill chain
|
||||||
let previousResult = null;
|
let previousResult = null;
|
||||||
let taskFailed = false;
|
let taskFailed = false;
|
||||||
@@ -245,6 +264,8 @@ for (let taskIdx = 0; taskIdx < remainingTasks.length; taskIdx++) {
|
|||||||
const skillName = chain[skillIdx];
|
const skillName = chain[skillIdx];
|
||||||
const skillArgs = assembleSkillArgs(skillName, task, previousResult, autoYes, skillIdx === 0);
|
const skillArgs = assembleSkillArgs(skillName, task, previousResult, autoYes, skillIdx === 0);
|
||||||
|
|
||||||
|
console.log(` [${skillIdx + 1}/${chain.length}] ${skillName}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = Skill({ skill: skillName, args: skillArgs });
|
const result = Skill({ skill: skillName, args: skillArgs });
|
||||||
previousResult = result;
|
previousResult = result;
|
||||||
@@ -254,13 +275,31 @@ for (let taskIdx = 0; taskIdx < remainingTasks.length; taskIdx++) {
|
|||||||
timestamp: new Date().toISOString()
|
timestamp: new Date().toISOString()
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Retry once
|
// ━━━ CLI-Assisted Error Recovery ━━━
|
||||||
|
console.log(` Diagnosing failure: ${skillName}...`);
|
||||||
|
const diagnosisPrompt = `PURPOSE: Diagnose why skill "${skillName}" failed during IDAW task execution.
|
||||||
|
TASK: • Analyze error: ${String(error).substring(0, 300)} • Check affected files: ${(task.context?.affected_files || []).join(', ') || 'unknown'} • Identify root cause • Suggest fix strategy
|
||||||
|
MODE: analysis
|
||||||
|
CONTEXT: @**/* | Memory: IDAW task ${task.id}: ${task.title}
|
||||||
|
EXPECTED: Root cause + actionable fix recommendation (1-2 sentences)
|
||||||
|
CONSTRAINTS: Focus on actionable diagnosis`;
|
||||||
|
const diagnosisResult = Bash(`ccw cli -p '${diagnosisPrompt.replace(/'/g, "'\\''")}' --tool gemini --mode analysis --rule analysis-diagnose-bug-root-cause 2>&1 || echo "CLI diagnosis unavailable"`);
|
||||||
|
|
||||||
|
task.execution.skill_results.push({
|
||||||
|
skill: `cli-diagnosis:${skillName}`,
|
||||||
|
status: 'completed',
|
||||||
|
diagnosis: diagnosisResult?.substring(0, 500),
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
|
});
|
||||||
|
|
||||||
|
// Retry with diagnosis context
|
||||||
|
console.log(` Retry with diagnosis: ${skillName}`);
|
||||||
try {
|
try {
|
||||||
const retryResult = Skill({ skill: skillName, args: skillArgs });
|
const retryResult = Skill({ skill: skillName, args: skillArgs });
|
||||||
previousResult = retryResult;
|
previousResult = retryResult;
|
||||||
task.execution.skill_results.push({
|
task.execution.skill_results.push({
|
||||||
skill: skillName,
|
skill: skillName,
|
||||||
status: 'completed-retry',
|
status: 'completed-retry-with-diagnosis',
|
||||||
timestamp: new Date().toISOString()
|
timestamp: new Date().toISOString()
|
||||||
});
|
});
|
||||||
} catch (retryError) {
|
} catch (retryError) {
|
||||||
@@ -278,7 +317,7 @@ for (let taskIdx = 0; taskIdx < remainingTasks.length; taskIdx++) {
|
|||||||
|
|
||||||
const answer = AskUserQuestion({
|
const answer = AskUserQuestion({
|
||||||
questions: [{
|
questions: [{
|
||||||
question: `${skillName} failed: ${String(retryError).substring(0, 100)}`,
|
question: `${skillName} failed after CLI diagnosis + retry: ${String(retryError).substring(0, 100)}`,
|
||||||
header: 'Error',
|
header: 'Error',
|
||||||
multiSelect: false,
|
multiSelect: false,
|
||||||
options: [
|
options: [
|
||||||
|
|||||||
@@ -231,6 +231,25 @@ for (let taskIdx = 0; taskIdx < tasks.length; taskIdx++) {
|
|||||||
console.log(`\n--- [${taskIdx + 1}/${tasks.length}] ${task.id}: ${task.title} ---`);
|
console.log(`\n--- [${taskIdx + 1}/${tasks.length}] ${task.id}: ${task.title} ---`);
|
||||||
console.log(`Chain: ${chain.join(' → ')}`);
|
console.log(`Chain: ${chain.join(' → ')}`);
|
||||||
|
|
||||||
|
// ━━━ Pre-Task CLI Context Analysis (for complex/bugfix tasks) ━━━
|
||||||
|
if (['bugfix', 'bugfix-hotfix', 'feature-complex'].includes(resolvedType)) {
|
||||||
|
console.log(` Pre-analysis: gathering context for ${resolvedType} task...`);
|
||||||
|
const affectedFiles = (task.context?.affected_files || []).join(', ');
|
||||||
|
const preAnalysisPrompt = `PURPOSE: Pre-analyze codebase context for IDAW task before execution.
|
||||||
|
TASK: • Understand current state of: ${affectedFiles || 'files related to: ' + task.title} • Identify dependencies and risk areas • Note existing patterns to follow
|
||||||
|
MODE: analysis
|
||||||
|
CONTEXT: @**/*
|
||||||
|
EXPECTED: Brief context summary (affected modules, dependencies, risk areas) in 3-5 bullet points
|
||||||
|
CONSTRAINTS: Keep concise | Focus on execution-relevant context`;
|
||||||
|
const preAnalysis = Bash(`ccw cli -p '${preAnalysisPrompt.replace(/'/g, "'\\''")}' --tool gemini --mode analysis 2>&1 || echo "Pre-analysis skipped"`);
|
||||||
|
task.execution.skill_results.push({
|
||||||
|
skill: 'cli-pre-analysis',
|
||||||
|
status: 'completed',
|
||||||
|
context_summary: preAnalysis?.substring(0, 500),
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Execute each skill in chain
|
// Execute each skill in chain
|
||||||
let previousResult = null;
|
let previousResult = null;
|
||||||
let taskFailed = false;
|
let taskFailed = false;
|
||||||
@@ -250,18 +269,36 @@ for (let taskIdx = 0; taskIdx < tasks.length; taskIdx++) {
|
|||||||
timestamp: new Date().toISOString()
|
timestamp: new Date().toISOString()
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Retry once
|
// ━━━ CLI-Assisted Error Recovery ━━━
|
||||||
console.log(` Retry: ${skillName} (first attempt failed)`);
|
// Step 1: Invoke CLI diagnosis (auto-invoke trigger: self-repair fails)
|
||||||
|
console.log(` Diagnosing failure: ${skillName}...`);
|
||||||
|
const diagnosisPrompt = `PURPOSE: Diagnose why skill "${skillName}" failed during IDAW task execution.
|
||||||
|
TASK: • Analyze error: ${String(error).substring(0, 300)} • Check affected files: ${(task.context?.affected_files || []).join(', ') || 'unknown'} • Identify root cause • Suggest fix strategy
|
||||||
|
MODE: analysis
|
||||||
|
CONTEXT: @**/* | Memory: IDAW task ${task.id}: ${task.title}
|
||||||
|
EXPECTED: Root cause + actionable fix recommendation (1-2 sentences)
|
||||||
|
CONSTRAINTS: Focus on actionable diagnosis`;
|
||||||
|
const diagnosisResult = Bash(`ccw cli -p '${diagnosisPrompt.replace(/'/g, "'\\''")}' --tool gemini --mode analysis --rule analysis-diagnose-bug-root-cause 2>&1 || echo "CLI diagnosis unavailable"`);
|
||||||
|
|
||||||
|
task.execution.skill_results.push({
|
||||||
|
skill: `cli-diagnosis:${skillName}`,
|
||||||
|
status: 'completed',
|
||||||
|
diagnosis: diagnosisResult?.substring(0, 500),
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
|
});
|
||||||
|
|
||||||
|
// Step 2: Retry with diagnosis context
|
||||||
|
console.log(` Retry with diagnosis: ${skillName}`);
|
||||||
try {
|
try {
|
||||||
const retryResult = Skill({ skill: skillName, args: skillArgs });
|
const retryResult = Skill({ skill: skillName, args: skillArgs });
|
||||||
previousResult = retryResult;
|
previousResult = retryResult;
|
||||||
task.execution.skill_results.push({
|
task.execution.skill_results.push({
|
||||||
skill: skillName,
|
skill: skillName,
|
||||||
status: 'completed-retry',
|
status: 'completed-retry-with-diagnosis',
|
||||||
timestamp: new Date().toISOString()
|
timestamp: new Date().toISOString()
|
||||||
});
|
});
|
||||||
} catch (retryError) {
|
} catch (retryError) {
|
||||||
// Failed after retry
|
// Step 3: Failed after CLI-assisted retry
|
||||||
task.execution.skill_results.push({
|
task.execution.skill_results.push({
|
||||||
skill: skillName,
|
skill: skillName,
|
||||||
status: 'failed',
|
status: 'failed',
|
||||||
@@ -275,7 +312,7 @@ for (let taskIdx = 0; taskIdx < tasks.length; taskIdx++) {
|
|||||||
} else {
|
} else {
|
||||||
const answer = AskUserQuestion({
|
const answer = AskUserQuestion({
|
||||||
questions: [{
|
questions: [{
|
||||||
question: `${skillName} failed: ${String(retryError).substring(0, 100)}. How to proceed?`,
|
question: `${skillName} failed after CLI diagnosis + retry: ${String(retryError).substring(0, 100)}. How to proceed?`,
|
||||||
header: 'Error',
|
header: 'Error',
|
||||||
multiSelect: false,
|
multiSelect: false,
|
||||||
options: [
|
options: [
|
||||||
@@ -443,6 +480,48 @@ function formatDuration(ms) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## CLI-Assisted Analysis
|
||||||
|
|
||||||
|
IDAW integrates `ccw cli` (Gemini) for intelligent analysis at two key points:
|
||||||
|
|
||||||
|
### Pre-Task Context Analysis
|
||||||
|
|
||||||
|
For `bugfix`, `bugfix-hotfix`, and `feature-complex` tasks, IDAW automatically invokes CLI analysis **before** executing the skill chain to gather codebase context:
|
||||||
|
|
||||||
|
```
|
||||||
|
Task starts → CLI pre-analysis (gemini) → Context gathered → Skill chain executes
|
||||||
|
```
|
||||||
|
|
||||||
|
- Identifies dependencies and risk areas
|
||||||
|
- Notes existing patterns to follow
|
||||||
|
- Results stored in `task.execution.skill_results` as `cli-pre-analysis`
|
||||||
|
|
||||||
|
### Error Recovery with CLI Diagnosis
|
||||||
|
|
||||||
|
When a skill fails, instead of blind retry, IDAW uses CLI-assisted diagnosis:
|
||||||
|
|
||||||
|
```
|
||||||
|
Skill fails → CLI diagnosis (gemini, analysis-diagnose-bug-root-cause)
|
||||||
|
→ Root cause identified → Retry with diagnosis context
|
||||||
|
→ Still fails → Skip (autoYes) or Ask user (interactive)
|
||||||
|
```
|
||||||
|
|
||||||
|
- Uses `--rule analysis-diagnose-bug-root-cause` template
|
||||||
|
- Diagnosis results stored in `task.execution.skill_results` as `cli-diagnosis:{skill}`
|
||||||
|
- Follows CLAUDE.md auto-invoke trigger pattern: "self-repair fails → invoke CLI analysis"
|
||||||
|
|
||||||
|
### Execution Flow (with CLI analysis)
|
||||||
|
|
||||||
|
```
|
||||||
|
Phase 4 Main Loop (per task):
|
||||||
|
├─ [bugfix/complex only] CLI pre-analysis → context summary
|
||||||
|
├─ Skill 1: execute
|
||||||
|
│ ├─ Success → next skill
|
||||||
|
│ └─ Failure → CLI diagnosis → retry → success/fail
|
||||||
|
├─ Skill 2: execute ...
|
||||||
|
└─ Phase 5: git checkpoint
|
||||||
|
```
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
Reference in New Issue
Block a user