claude-code-workflow 6.3.26 → 6.3.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/CLAUDE.md +7 -1
- package/.claude/agents/action-planning-agent.md +1 -0
- package/.claude/agents/cli-discuss-agent.md +391 -0
- package/.claude/agents/cli-execution-agent.md +2 -0
- package/.claude/agents/cli-explore-agent.md +2 -1
- package/.claude/agents/cli-lite-planning-agent.md +1 -0
- package/.claude/agents/cli-planning-agent.md +1 -0
- package/.claude/agents/code-developer.md +1 -0
- package/.claude/agents/conceptual-planning-agent.md +2 -0
- package/.claude/agents/context-search-agent.md +1 -0
- package/.claude/agents/debug-explore-agent.md +2 -0
- package/.claude/agents/doc-generator.md +1 -0
- package/.claude/agents/issue-plan-agent.md +2 -1
- package/.claude/agents/issue-queue-agent.md +2 -1
- package/.claude/agents/memory-bridge.md +2 -0
- package/.claude/agents/test-context-search-agent.md +2 -0
- package/.claude/agents/test-fix-agent.md +1 -0
- package/.claude/agents/ui-design-agent.md +2 -0
- package/.claude/agents/universal-executor.md +1 -0
- package/.claude/commands/issue/execute.md +141 -163
- package/.claude/commands/workflow/lite-lite-lite.md +798 -0
- package/.claude/commands/workflow/multi-cli-plan.md +510 -0
- package/.claude/skills/ccw/SKILL.md +262 -372
- package/.claude/skills/ccw/command.json +547 -0
- package/.claude/skills/ccw-help/SKILL.md +46 -107
- package/.claude/skills/ccw-help/command.json +511 -0
- package/.claude/skills/skill-tuning/SKILL.md +303 -0
- package/.claude/skills/skill-tuning/phases/actions/action-abort.md +164 -0
- package/.claude/skills/skill-tuning/phases/actions/action-analyze-requirements.md +406 -0
- package/.claude/skills/skill-tuning/phases/actions/action-apply-fix.md +206 -0
- package/.claude/skills/skill-tuning/phases/actions/action-complete.md +195 -0
- package/.claude/skills/skill-tuning/phases/actions/action-diagnose-agent.md +317 -0
- package/.claude/skills/skill-tuning/phases/actions/action-diagnose-context.md +243 -0
- package/.claude/skills/skill-tuning/phases/actions/action-diagnose-dataflow.md +318 -0
- package/.claude/skills/skill-tuning/phases/actions/action-diagnose-docs.md +299 -0
- package/.claude/skills/skill-tuning/phases/actions/action-diagnose-memory.md +269 -0
- package/.claude/skills/skill-tuning/phases/actions/action-diagnose-token-consumption.md +200 -0
- package/.claude/skills/skill-tuning/phases/actions/action-gemini-analysis.md +322 -0
- package/.claude/skills/skill-tuning/phases/actions/action-generate-report.md +228 -0
- package/.claude/skills/skill-tuning/phases/actions/action-init.md +149 -0
- package/.claude/skills/skill-tuning/phases/actions/action-propose-fixes.md +317 -0
- package/.claude/skills/skill-tuning/phases/actions/action-verify.md +222 -0
- package/.claude/skills/skill-tuning/phases/orchestrator.md +377 -0
- package/.claude/skills/skill-tuning/phases/state-schema.md +378 -0
- package/.claude/skills/skill-tuning/specs/category-mappings.json +284 -0
- package/.claude/skills/skill-tuning/specs/dimension-mapping.md +212 -0
- package/.claude/skills/skill-tuning/specs/problem-taxonomy.md +318 -0
- package/.claude/skills/skill-tuning/specs/quality-gates.md +263 -0
- package/.claude/skills/skill-tuning/specs/skill-authoring-principles.md +189 -0
- package/.claude/skills/skill-tuning/specs/tuning-strategies.md +1537 -0
- package/.claude/skills/skill-tuning/templates/diagnosis-report.md +153 -0
- package/.claude/skills/skill-tuning/templates/fix-proposal.md +204 -0
- package/.claude/workflows/cli-templates/schemas/multi-cli-discussion-schema.json +421 -0
- package/.claude/workflows/cli-tools-usage.md +0 -41
- package/ccw/dist/core/auth/csrf-middleware.d.ts.map +1 -1
- package/ccw/dist/core/auth/csrf-middleware.js +3 -1
- package/ccw/dist/core/auth/csrf-middleware.js.map +1 -1
- package/ccw/dist/core/data-aggregator.d.ts +2 -0
- package/ccw/dist/core/data-aggregator.d.ts.map +1 -1
- package/ccw/dist/core/data-aggregator.js +5 -2
- package/ccw/dist/core/data-aggregator.js.map +1 -1
- package/ccw/dist/core/lite-scanner.d.ts +2 -1
- package/ccw/dist/core/lite-scanner.d.ts.map +1 -1
- package/ccw/dist/core/lite-scanner.js +295 -6
- package/ccw/dist/core/lite-scanner.js.map +1 -1
- package/ccw/dist/core/routes/codexlens/config-handlers.d.ts.map +1 -1
- package/ccw/dist/core/routes/codexlens/config-handlers.js +5 -5
- package/ccw/dist/core/routes/codexlens/config-handlers.js.map +1 -1
- package/ccw/dist/core/routes/session-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/session-routes.js +166 -48
- package/ccw/dist/core/routes/session-routes.js.map +1 -1
- package/ccw/dist/core/routes/system-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/system-routes.js +87 -0
- package/ccw/dist/core/routes/system-routes.js.map +1 -1
- package/ccw/dist/core/server.js +2 -2
- package/ccw/dist/core/server.js.map +1 -1
- package/ccw/scripts/IMPLEMENTATION-SUMMARY.md +226 -0
- package/ccw/scripts/QUICK-REFERENCE.md +135 -0
- package/ccw/scripts/README-memory-embedder.md +157 -0
- package/ccw/scripts/__pycache__/memory_embedder.cpython-313.pyc +0 -0
- package/ccw/scripts/__pycache__/test_memory_embedder.cpython-313-pytest-8.4.2.pyc +0 -0
- package/ccw/scripts/memory-embedder-example.ts +184 -0
- package/ccw/scripts/memory_embedder.py +428 -0
- package/ccw/scripts/test_memory_embedder.py +245 -0
- package/ccw/src/core/auth/csrf-middleware.ts +3 -1
- package/ccw/src/core/data-aggregator.ts +7 -2
- package/ccw/src/core/lite-scanner.ts +440 -6
- package/ccw/src/core/routes/codexlens/config-handlers.ts +12 -9
- package/ccw/src/core/routes/session-routes.ts +201 -48
- package/ccw/src/core/routes/system-routes.ts +102 -0
- package/ccw/src/core/server.ts +2 -2
- package/ccw/src/templates/dashboard-css/01-base.css +8 -0
- package/ccw/src/templates/dashboard-css/02-session.css +81 -0
- package/ccw/src/templates/dashboard-css/04-lite-tasks.css +2442 -0
- package/ccw/src/templates/dashboard-css/21-cli-toolmgmt.css +157 -0
- package/ccw/src/templates/dashboard-css/32-issue-manager.css +23 -0
- package/ccw/src/templates/dashboard-js/components/cli-stream-viewer.js +38 -4
- package/ccw/src/templates/dashboard-js/components/hook-manager.js +38 -13
- package/ccw/src/templates/dashboard-js/components/navigation.js +24 -4
- package/ccw/src/templates/dashboard-js/i18n.js +194 -6
- package/ccw/src/templates/dashboard-js/views/api-settings.js +32 -0
- package/ccw/src/templates/dashboard-js/views/claude-manager.js +44 -3
- package/ccw/src/templates/dashboard-js/views/cli-manager.js +303 -31
- package/ccw/src/templates/dashboard-js/views/history.js +44 -6
- package/ccw/src/templates/dashboard-js/views/home.js +1 -0
- package/ccw/src/templates/dashboard-js/views/issue-manager.js +54 -7
- package/ccw/src/templates/dashboard-js/views/lite-tasks.js +1817 -4
- package/ccw/src/templates/dashboard.html +5 -0
- package/package.json +2 -1
- package/.claude/skills/ccw/index/command-capabilities.json +0 -127
- package/.claude/skills/ccw/index/intent-rules.json +0 -136
- package/.claude/skills/ccw/index/workflow-chains.json +0 -451
- package/.claude/skills/ccw/phases/actions/bugfix.md +0 -218
- package/.claude/skills/ccw/phases/actions/coupled.md +0 -194
- package/.claude/skills/ccw/phases/actions/docs.md +0 -93
- package/.claude/skills/ccw/phases/actions/full.md +0 -154
- package/.claude/skills/ccw/phases/actions/issue.md +0 -201
- package/.claude/skills/ccw/phases/actions/rapid.md +0 -104
- package/.claude/skills/ccw/phases/actions/review-fix.md +0 -84
- package/.claude/skills/ccw/phases/actions/tdd.md +0 -66
- package/.claude/skills/ccw/phases/actions/ui.md +0 -79
- package/.claude/skills/ccw/phases/orchestrator.md +0 -435
- package/.claude/skills/ccw/specs/intent-classification.md +0 -336
- package/.claude/skills/ccw-help/index/all-agents.json +0 -82
- package/.claude/skills/ccw-help/index/all-commands.json +0 -882
- package/.claude/skills/ccw-help/index/by-category.json +0 -914
- package/.claude/skills/ccw-help/index/by-use-case.json +0 -896
- package/.claude/skills/ccw-help/index/command-relationships.json +0 -160
- package/.claude/skills/ccw-help/index/essential-commands.json +0 -112
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# Action: Verify Applied Fixes
|
|
2
|
+
|
|
3
|
+
Verify that applied fixes resolved the targeted issues.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
- Re-run relevant diagnostics
|
|
8
|
+
- Compare before/after issue counts
|
|
9
|
+
- Update verification status
|
|
10
|
+
- Determine if more iterations needed
|
|
11
|
+
|
|
12
|
+
## Preconditions
|
|
13
|
+
|
|
14
|
+
- [ ] state.status === 'running'
|
|
15
|
+
- [ ] state.applied_fixes.length > 0
|
|
16
|
+
- [ ] Some applied_fixes have verification_result === 'pending'
|
|
17
|
+
|
|
18
|
+
## Execution
|
|
19
|
+
|
|
20
|
+
```javascript
|
|
21
|
+
async function execute(state, workDir) {
|
|
22
|
+
console.log('Verifying applied fixes...');
|
|
23
|
+
|
|
24
|
+
const appliedFixes = state.applied_fixes.filter(f => f.verification_result === 'pending');
|
|
25
|
+
|
|
26
|
+
if (appliedFixes.length === 0) {
|
|
27
|
+
return {
|
|
28
|
+
stateUpdates: {},
|
|
29
|
+
outputFiles: [],
|
|
30
|
+
summary: 'No fixes pending verification'
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const verificationResults = [];
|
|
35
|
+
|
|
36
|
+
for (const fix of appliedFixes) {
|
|
37
|
+
const proposedFix = state.proposed_fixes.find(f => f.id === fix.fix_id);
|
|
38
|
+
|
|
39
|
+
if (!proposedFix) {
|
|
40
|
+
verificationResults.push({
|
|
41
|
+
fix_id: fix.fix_id,
|
|
42
|
+
result: 'fail',
|
|
43
|
+
reason: 'Fix definition not found'
|
|
44
|
+
});
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Determine which diagnosis to re-run based on fix strategy
|
|
49
|
+
const strategyToDiagnosis = {
|
|
50
|
+
'context_summarization': 'context',
|
|
51
|
+
'sliding_window': 'context',
|
|
52
|
+
'structured_state': 'context',
|
|
53
|
+
'path_reference': 'context',
|
|
54
|
+
'constraint_injection': 'memory',
|
|
55
|
+
'checkpoint_restore': 'memory',
|
|
56
|
+
'goal_embedding': 'memory',
|
|
57
|
+
'state_constraints_field': 'memory',
|
|
58
|
+
'state_centralization': 'dataflow',
|
|
59
|
+
'schema_enforcement': 'dataflow',
|
|
60
|
+
'field_normalization': 'dataflow',
|
|
61
|
+
'transactional_updates': 'dataflow',
|
|
62
|
+
'error_wrapping': 'agent',
|
|
63
|
+
'result_validation': 'agent',
|
|
64
|
+
'orchestrator_refactor': 'agent',
|
|
65
|
+
'flatten_nesting': 'agent'
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const diagnosisType = strategyToDiagnosis[proposedFix.strategy];
|
|
69
|
+
|
|
70
|
+
// For now, do a lightweight verification
|
|
71
|
+
// Full implementation would re-run the specific diagnosis
|
|
72
|
+
|
|
73
|
+
// Check if the fix was actually applied (look for markers)
|
|
74
|
+
const targetPath = state.target_skill.path;
|
|
75
|
+
const fixMarker = `Applied fix ${fix.fix_id}`;
|
|
76
|
+
|
|
77
|
+
let fixFound = false;
|
|
78
|
+
const allFiles = Glob(`${targetPath}/**/*.md`);
|
|
79
|
+
|
|
80
|
+
for (const file of allFiles) {
|
|
81
|
+
const content = Read(file);
|
|
82
|
+
if (content.includes(fixMarker)) {
|
|
83
|
+
fixFound = true;
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (fixFound) {
|
|
89
|
+
// Verify by checking if original issues still exist
|
|
90
|
+
const relatedIssues = proposedFix.issue_ids;
|
|
91
|
+
const originalIssueCount = relatedIssues.length;
|
|
92
|
+
|
|
93
|
+
// Simplified verification: assume fix worked if marker present
|
|
94
|
+
// Real implementation would re-run diagnosis patterns
|
|
95
|
+
|
|
96
|
+
verificationResults.push({
|
|
97
|
+
fix_id: fix.fix_id,
|
|
98
|
+
result: 'pass',
|
|
99
|
+
reason: `Fix applied successfully, addressing ${originalIssueCount} issues`,
|
|
100
|
+
issues_resolved: relatedIssues
|
|
101
|
+
});
|
|
102
|
+
} else {
|
|
103
|
+
verificationResults.push({
|
|
104
|
+
fix_id: fix.fix_id,
|
|
105
|
+
result: 'fail',
|
|
106
|
+
reason: 'Fix marker not found in target files'
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Update applied fixes with verification results
|
|
112
|
+
const updatedAppliedFixes = state.applied_fixes.map(fix => {
|
|
113
|
+
const result = verificationResults.find(v => v.fix_id === fix.fix_id);
|
|
114
|
+
if (result) {
|
|
115
|
+
return {
|
|
116
|
+
...fix,
|
|
117
|
+
verification_result: result.result
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
return fix;
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// Calculate new quality score
|
|
124
|
+
const passedFixes = verificationResults.filter(v => v.result === 'pass').length;
|
|
125
|
+
const totalFixes = verificationResults.length;
|
|
126
|
+
const verificationRate = totalFixes > 0 ? (passedFixes / totalFixes) * 100 : 100;
|
|
127
|
+
|
|
128
|
+
// Recalculate issues (remove resolved ones)
|
|
129
|
+
const resolvedIssueIds = verificationResults
|
|
130
|
+
.filter(v => v.result === 'pass')
|
|
131
|
+
.flatMap(v => v.issues_resolved || []);
|
|
132
|
+
|
|
133
|
+
const remainingIssues = state.issues.filter(i => !resolvedIssueIds.includes(i.id));
|
|
134
|
+
|
|
135
|
+
// Recalculate quality score
|
|
136
|
+
const weights = { critical: 25, high: 15, medium: 5, low: 1 };
|
|
137
|
+
const deductions = remainingIssues.reduce((sum, issue) =>
|
|
138
|
+
sum + (weights[issue.severity] || 0), 0);
|
|
139
|
+
const newHealthScore = Math.max(0, 100 - deductions);
|
|
140
|
+
|
|
141
|
+
// Determine new quality gate
|
|
142
|
+
const remainingCritical = remainingIssues.filter(i => i.severity === 'critical').length;
|
|
143
|
+
const remainingHigh = remainingIssues.filter(i => i.severity === 'high').length;
|
|
144
|
+
const newQualityGate = remainingCritical === 0 && remainingHigh <= 2 && newHealthScore >= 60
|
|
145
|
+
? 'pass'
|
|
146
|
+
: newHealthScore >= 40 ? 'review' : 'fail';
|
|
147
|
+
|
|
148
|
+
// Increment iteration count
|
|
149
|
+
const newIterationCount = state.iteration_count + 1;
|
|
150
|
+
|
|
151
|
+
// Ask user if they want to continue
|
|
152
|
+
let continueIteration = false;
|
|
153
|
+
if (newQualityGate !== 'pass' && newIterationCount < state.max_iterations) {
|
|
154
|
+
const continueResponse = await AskUserQuestion({
|
|
155
|
+
questions: [{
|
|
156
|
+
question: `Verification complete. Quality gate: ${newQualityGate}. Continue with another iteration?`,
|
|
157
|
+
header: 'Continue',
|
|
158
|
+
multiSelect: false,
|
|
159
|
+
options: [
|
|
160
|
+
{ label: 'Yes', description: `Run iteration ${newIterationCount + 1}` },
|
|
161
|
+
{ label: 'No', description: 'Finish with current state' }
|
|
162
|
+
]
|
|
163
|
+
}]
|
|
164
|
+
});
|
|
165
|
+
continueIteration = continueResponse['Continue'] === 'Yes';
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// If continuing, reset diagnosis for re-evaluation
|
|
169
|
+
const diagnosisReset = continueIteration ? {
|
|
170
|
+
'diagnosis.context': null,
|
|
171
|
+
'diagnosis.memory': null,
|
|
172
|
+
'diagnosis.dataflow': null,
|
|
173
|
+
'diagnosis.agent': null
|
|
174
|
+
} : {};
|
|
175
|
+
|
|
176
|
+
return {
|
|
177
|
+
stateUpdates: {
|
|
178
|
+
applied_fixes: updatedAppliedFixes,
|
|
179
|
+
issues: remainingIssues,
|
|
180
|
+
quality_score: newHealthScore,
|
|
181
|
+
quality_gate: newQualityGate,
|
|
182
|
+
iteration_count: newIterationCount,
|
|
183
|
+
...diagnosisReset,
|
|
184
|
+
issues_by_severity: {
|
|
185
|
+
critical: remainingIssues.filter(i => i.severity === 'critical').length,
|
|
186
|
+
high: remainingIssues.filter(i => i.severity === 'high').length,
|
|
187
|
+
medium: remainingIssues.filter(i => i.severity === 'medium').length,
|
|
188
|
+
low: remainingIssues.filter(i => i.severity === 'low').length
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
outputFiles: [],
|
|
192
|
+
summary: `Verified ${totalFixes} fixes: ${passedFixes} passed. Score: ${newHealthScore}, Gate: ${newQualityGate}, Iteration: ${newIterationCount}`
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## State Updates
|
|
198
|
+
|
|
199
|
+
```javascript
|
|
200
|
+
return {
|
|
201
|
+
stateUpdates: {
|
|
202
|
+
applied_fixes: [...updatedWithVerificationResults],
|
|
203
|
+
issues: [...remainingIssues],
|
|
204
|
+
quality_score: newScore,
|
|
205
|
+
quality_gate: newGate,
|
|
206
|
+
iteration_count: iteration + 1
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Error Handling
|
|
212
|
+
|
|
213
|
+
| Error Type | Recovery |
|
|
214
|
+
|------------|----------|
|
|
215
|
+
| Re-diagnosis fails | Mark as 'inconclusive' |
|
|
216
|
+
| File access error | Skip file verification |
|
|
217
|
+
|
|
218
|
+
## Next Actions
|
|
219
|
+
|
|
220
|
+
- If quality_gate === 'pass': action-complete
|
|
221
|
+
- If user chose to continue: restart diagnosis cycle
|
|
222
|
+
- If max_iterations reached: action-complete
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
# Orchestrator
|
|
2
|
+
|
|
3
|
+
Autonomous orchestrator for skill-tuning workflow. Reads current state and selects the next action based on diagnosis progress and quality gates.
|
|
4
|
+
|
|
5
|
+
## Role
|
|
6
|
+
|
|
7
|
+
Drive the tuning workflow by:
|
|
8
|
+
1. Reading current session state
|
|
9
|
+
2. Selecting the appropriate next action
|
|
10
|
+
3. Executing the action via sub-agent
|
|
11
|
+
4. Updating state with results
|
|
12
|
+
5. Repeating until termination conditions met
|
|
13
|
+
|
|
14
|
+
## State Management
|
|
15
|
+
|
|
16
|
+
### Read State
|
|
17
|
+
|
|
18
|
+
```javascript
|
|
19
|
+
const state = JSON.parse(Read(`${workDir}/state.json`));
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Update State
|
|
23
|
+
|
|
24
|
+
```javascript
|
|
25
|
+
function updateState(updates) {
|
|
26
|
+
const state = JSON.parse(Read(`${workDir}/state.json`));
|
|
27
|
+
const newState = {
|
|
28
|
+
...state,
|
|
29
|
+
...updates,
|
|
30
|
+
updated_at: new Date().toISOString()
|
|
31
|
+
};
|
|
32
|
+
Write(`${workDir}/state.json`, JSON.stringify(newState, null, 2));
|
|
33
|
+
return newState;
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Decision Logic
|
|
38
|
+
|
|
39
|
+
```javascript
|
|
40
|
+
function selectNextAction(state) {
|
|
41
|
+
// === Termination Checks ===
|
|
42
|
+
|
|
43
|
+
// User exit
|
|
44
|
+
if (state.status === 'user_exit') return null;
|
|
45
|
+
|
|
46
|
+
// Completed
|
|
47
|
+
if (state.status === 'completed') return null;
|
|
48
|
+
|
|
49
|
+
// Error limit exceeded
|
|
50
|
+
if (state.error_count >= state.max_errors) {
|
|
51
|
+
return 'action-abort';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Max iterations exceeded
|
|
55
|
+
if (state.iteration_count >= state.max_iterations) {
|
|
56
|
+
return 'action-complete';
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// === Action Selection ===
|
|
60
|
+
|
|
61
|
+
// 1. Not initialized yet
|
|
62
|
+
if (state.status === 'pending') {
|
|
63
|
+
return 'action-init';
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// 1.5. Requirement analysis (在 init 后,diagnosis 前)
|
|
67
|
+
if (state.status === 'running' &&
|
|
68
|
+
state.completed_actions.includes('action-init') &&
|
|
69
|
+
!state.completed_actions.includes('action-analyze-requirements')) {
|
|
70
|
+
return 'action-analyze-requirements';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// 1.6. 如果需求分析发现歧义需要澄清,暂停等待用户
|
|
74
|
+
if (state.requirement_analysis?.status === 'needs_clarification') {
|
|
75
|
+
return null; // 等待用户澄清后继续
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// 1.7. 如果需求分析覆盖度不足,优先触发 Gemini 深度分析
|
|
79
|
+
if (state.requirement_analysis?.coverage?.status === 'unsatisfied' &&
|
|
80
|
+
!state.completed_actions.includes('action-gemini-analysis')) {
|
|
81
|
+
return 'action-gemini-analysis';
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// 2. Check if Gemini analysis is requested or needed
|
|
85
|
+
if (shouldTriggerGeminiAnalysis(state)) {
|
|
86
|
+
return 'action-gemini-analysis';
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// 3. Check if Gemini analysis is running
|
|
90
|
+
if (state.gemini_analysis?.status === 'running') {
|
|
91
|
+
// Wait for Gemini analysis to complete
|
|
92
|
+
return null; // Orchestrator will be re-triggered when CLI completes
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 4. Run diagnosis in order (only if not completed)
|
|
96
|
+
const diagnosisOrder = ['context', 'memory', 'dataflow', 'agent', 'docs', 'token_consumption'];
|
|
97
|
+
|
|
98
|
+
for (const diagType of diagnosisOrder) {
|
|
99
|
+
if (state.diagnosis[diagType] === null) {
|
|
100
|
+
// Check if user wants to skip this diagnosis
|
|
101
|
+
if (!state.focus_areas.length || state.focus_areas.includes(diagType)) {
|
|
102
|
+
return `action-diagnose-${diagType}`;
|
|
103
|
+
}
|
|
104
|
+
// For docs diagnosis, also check 'all' focus_area
|
|
105
|
+
if (diagType === 'docs' && state.focus_areas.includes('all')) {
|
|
106
|
+
return 'action-diagnose-docs';
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// 5. All diagnosis complete, generate report if not done
|
|
112
|
+
const allDiagnosisComplete = diagnosisOrder.every(
|
|
113
|
+
d => state.diagnosis[d] !== null || !state.focus_areas.includes(d)
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
if (allDiagnosisComplete && !state.completed_actions.includes('action-generate-report')) {
|
|
117
|
+
return 'action-generate-report';
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 6. Report generated, propose fixes if not done
|
|
121
|
+
if (state.completed_actions.includes('action-generate-report') &&
|
|
122
|
+
state.proposed_fixes.length === 0 &&
|
|
123
|
+
state.issues.length > 0) {
|
|
124
|
+
return 'action-propose-fixes';
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// 7. Fixes proposed, check if user wants to apply
|
|
128
|
+
if (state.proposed_fixes.length > 0 && state.pending_fixes.length > 0) {
|
|
129
|
+
return 'action-apply-fix';
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// 8. Fixes applied, verify
|
|
133
|
+
if (state.applied_fixes.length > 0 &&
|
|
134
|
+
state.applied_fixes.some(f => f.verification_result === 'pending')) {
|
|
135
|
+
return 'action-verify';
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// 9. Quality gate check
|
|
139
|
+
if (state.quality_gate === 'pass') {
|
|
140
|
+
return 'action-complete';
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// 10. More iterations needed
|
|
144
|
+
if (state.iteration_count < state.max_iterations &&
|
|
145
|
+
state.quality_gate !== 'pass' &&
|
|
146
|
+
state.issues.some(i => i.severity === 'critical' || i.severity === 'high')) {
|
|
147
|
+
// Reset diagnosis for re-evaluation
|
|
148
|
+
return 'action-diagnose-context'; // Start new iteration
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// 11. Default: complete
|
|
152
|
+
return 'action-complete';
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* 判断是否需要触发 Gemini CLI 分析
|
|
157
|
+
*/
|
|
158
|
+
function shouldTriggerGeminiAnalysis(state) {
|
|
159
|
+
// 已完成 Gemini 分析,不再触发
|
|
160
|
+
if (state.gemini_analysis?.status === 'completed') {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// 用户显式请求
|
|
165
|
+
if (state.gemini_analysis_requested === true) {
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// 发现 critical 问题且未进行深度分析
|
|
170
|
+
if (state.issues.some(i => i.severity === 'critical') &&
|
|
171
|
+
!state.completed_actions.includes('action-gemini-analysis')) {
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// 用户指定了需要 Gemini 分析的 focus_areas
|
|
176
|
+
const geminiAreas = ['architecture', 'prompt', 'performance', 'custom'];
|
|
177
|
+
if (state.focus_areas.some(area => geminiAreas.includes(area))) {
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// 标准诊断完成但问题未得到解决,需要深度分析
|
|
182
|
+
const diagnosisComplete = ['context', 'memory', 'dataflow', 'agent', 'docs'].every(
|
|
183
|
+
d => state.diagnosis[d] !== null
|
|
184
|
+
);
|
|
185
|
+
if (diagnosisComplete &&
|
|
186
|
+
state.issues.length > 0 &&
|
|
187
|
+
state.iteration_count > 0 &&
|
|
188
|
+
!state.completed_actions.includes('action-gemini-analysis')) {
|
|
189
|
+
// 第二轮迭代如果问题仍存在,触发 Gemini 分析
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Execution Loop
|
|
198
|
+
|
|
199
|
+
```javascript
|
|
200
|
+
async function runOrchestrator(workDir) {
|
|
201
|
+
console.log('=== Skill Tuning Orchestrator Started ===');
|
|
202
|
+
|
|
203
|
+
let iteration = 0;
|
|
204
|
+
const MAX_LOOP_ITERATIONS = 50; // Safety limit
|
|
205
|
+
|
|
206
|
+
while (iteration < MAX_LOOP_ITERATIONS) {
|
|
207
|
+
iteration++;
|
|
208
|
+
|
|
209
|
+
// 1. Read current state
|
|
210
|
+
const state = JSON.parse(Read(`${workDir}/state.json`));
|
|
211
|
+
console.log(`[Loop ${iteration}] Status: ${state.status}, Action: ${state.current_action}`);
|
|
212
|
+
|
|
213
|
+
// 2. Select next action
|
|
214
|
+
const actionId = selectNextAction(state);
|
|
215
|
+
|
|
216
|
+
if (!actionId) {
|
|
217
|
+
console.log('No action selected, terminating orchestrator.');
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
console.log(`[Loop ${iteration}] Executing: ${actionId}`);
|
|
222
|
+
|
|
223
|
+
// 3. Update state: current action
|
|
224
|
+
// FIX CTX-001: sliding window for action_history (keep last 10)
|
|
225
|
+
updateState({
|
|
226
|
+
current_action: actionId,
|
|
227
|
+
action_history: [...state.action_history, {
|
|
228
|
+
action: actionId,
|
|
229
|
+
started_at: new Date().toISOString(),
|
|
230
|
+
completed_at: null,
|
|
231
|
+
result: null,
|
|
232
|
+
output_files: []
|
|
233
|
+
}].slice(-10) // Sliding window: prevent unbounded growth
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// 4. Execute action
|
|
237
|
+
try {
|
|
238
|
+
const actionPrompt = Read(`phases/actions/${actionId}.md`);
|
|
239
|
+
// FIX CTX-003: Pass state path + key fields only instead of full state
|
|
240
|
+
const stateKeyInfo = {
|
|
241
|
+
status: state.status,
|
|
242
|
+
iteration_count: state.iteration_count,
|
|
243
|
+
issues_by_severity: state.issues_by_severity,
|
|
244
|
+
quality_gate: state.quality_gate,
|
|
245
|
+
current_action: state.current_action,
|
|
246
|
+
completed_actions: state.completed_actions,
|
|
247
|
+
user_issue_description: state.user_issue_description,
|
|
248
|
+
target_skill: { name: state.target_skill.name, path: state.target_skill.path }
|
|
249
|
+
};
|
|
250
|
+
const stateKeyJson = JSON.stringify(stateKeyInfo, null, 2);
|
|
251
|
+
|
|
252
|
+
const result = await Task({
|
|
253
|
+
subagent_type: 'universal-executor',
|
|
254
|
+
run_in_background: false,
|
|
255
|
+
prompt: `
|
|
256
|
+
[CONTEXT]
|
|
257
|
+
You are executing action "${actionId}" for skill-tuning workflow.
|
|
258
|
+
Work directory: ${workDir}
|
|
259
|
+
|
|
260
|
+
[STATE KEY INFO]
|
|
261
|
+
${stateKeyJson}
|
|
262
|
+
|
|
263
|
+
[FULL STATE PATH]
|
|
264
|
+
${workDir}/state.json
|
|
265
|
+
(Read full state from this file if you need additional fields)
|
|
266
|
+
|
|
267
|
+
[ACTION INSTRUCTIONS]
|
|
268
|
+
${actionPrompt}
|
|
269
|
+
|
|
270
|
+
[OUTPUT REQUIREMENT]
|
|
271
|
+
After completing the action:
|
|
272
|
+
1. Write any output files to the work directory
|
|
273
|
+
2. Return a JSON object with:
|
|
274
|
+
- stateUpdates: object with state fields to update
|
|
275
|
+
- outputFiles: array of files created
|
|
276
|
+
- summary: brief description of what was done
|
|
277
|
+
`
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// 5. Parse result and update state
|
|
281
|
+
let actionResult;
|
|
282
|
+
try {
|
|
283
|
+
actionResult = JSON.parse(result);
|
|
284
|
+
} catch (e) {
|
|
285
|
+
actionResult = {
|
|
286
|
+
stateUpdates: {},
|
|
287
|
+
outputFiles: [],
|
|
288
|
+
summary: result
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// 6. Update state: action complete
|
|
293
|
+
const updatedHistory = [...state.action_history];
|
|
294
|
+
updatedHistory[updatedHistory.length - 1] = {
|
|
295
|
+
...updatedHistory[updatedHistory.length - 1],
|
|
296
|
+
completed_at: new Date().toISOString(),
|
|
297
|
+
result: 'success',
|
|
298
|
+
output_files: actionResult.outputFiles || []
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
updateState({
|
|
302
|
+
current_action: null,
|
|
303
|
+
completed_actions: [...state.completed_actions, actionId],
|
|
304
|
+
action_history: updatedHistory,
|
|
305
|
+
...actionResult.stateUpdates
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
console.log(`[Loop ${iteration}] Completed: ${actionId}`);
|
|
309
|
+
|
|
310
|
+
} catch (error) {
|
|
311
|
+
console.log(`[Loop ${iteration}] Error in ${actionId}: ${error.message}`);
|
|
312
|
+
|
|
313
|
+
// Error handling
|
|
314
|
+
// FIX CTX-002: sliding window for errors (keep last 5)
|
|
315
|
+
updateState({
|
|
316
|
+
current_action: null,
|
|
317
|
+
errors: [...state.errors, {
|
|
318
|
+
action: actionId,
|
|
319
|
+
message: error.message,
|
|
320
|
+
timestamp: new Date().toISOString(),
|
|
321
|
+
recoverable: true
|
|
322
|
+
}].slice(-5), // Sliding window: prevent unbounded growth
|
|
323
|
+
error_count: state.error_count + 1
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
console.log('=== Skill Tuning Orchestrator Finished ===');
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## Action Catalog
|
|
333
|
+
|
|
334
|
+
| Action | Purpose | Preconditions | Effects |
|
|
335
|
+
|--------|---------|---------------|---------|
|
|
336
|
+
| [action-init](actions/action-init.md) | Initialize tuning session | status === 'pending' | Creates work dirs, backup, sets status='running' |
|
|
337
|
+
| [action-analyze-requirements](actions/action-analyze-requirements.md) | Analyze user requirements | init completed | Sets requirement_analysis, optimizes focus_areas |
|
|
338
|
+
| [action-diagnose-context](actions/action-diagnose-context.md) | Analyze context explosion | status === 'running' | Sets diagnosis.context |
|
|
339
|
+
| [action-diagnose-memory](actions/action-diagnose-memory.md) | Analyze long-tail forgetting | status === 'running' | Sets diagnosis.memory |
|
|
340
|
+
| [action-diagnose-dataflow](actions/action-diagnose-dataflow.md) | Analyze data flow issues | status === 'running' | Sets diagnosis.dataflow |
|
|
341
|
+
| [action-diagnose-agent](actions/action-diagnose-agent.md) | Analyze agent coordination | status === 'running' | Sets diagnosis.agent |
|
|
342
|
+
| [action-diagnose-docs](actions/action-diagnose-docs.md) | Analyze documentation structure | status === 'running', focus includes 'docs' | Sets diagnosis.docs |
|
|
343
|
+
| [action-gemini-analysis](actions/action-gemini-analysis.md) | Deep analysis via Gemini CLI | User request OR critical issues | Sets gemini_analysis, adds issues |
|
|
344
|
+
| [action-generate-report](actions/action-generate-report.md) | Generate consolidated report | All diagnoses complete | Creates tuning-report.md |
|
|
345
|
+
| [action-propose-fixes](actions/action-propose-fixes.md) | Generate fix proposals | Report generated, issues > 0 | Sets proposed_fixes |
|
|
346
|
+
| [action-apply-fix](actions/action-apply-fix.md) | Apply selected fix | pending_fixes > 0 | Updates applied_fixes |
|
|
347
|
+
| [action-verify](actions/action-verify.md) | Verify applied fixes | applied_fixes with pending verification | Updates verification_result |
|
|
348
|
+
| [action-complete](actions/action-complete.md) | Finalize session | quality_gate='pass' OR max_iterations | Sets status='completed' |
|
|
349
|
+
| [action-abort](actions/action-abort.md) | Abort on errors | error_count >= max_errors | Sets status='failed' |
|
|
350
|
+
|
|
351
|
+
## Termination Conditions
|
|
352
|
+
|
|
353
|
+
- `status === 'completed'`: Normal completion
|
|
354
|
+
- `status === 'user_exit'`: User requested exit
|
|
355
|
+
- `status === 'failed'`: Unrecoverable error
|
|
356
|
+
- `requirement_analysis.status === 'needs_clarification'`: Waiting for user clarification (暂停,非终止)
|
|
357
|
+
- `error_count >= max_errors`: Too many errors (default: 3)
|
|
358
|
+
- `iteration_count >= max_iterations`: Max iterations reached (default: 5)
|
|
359
|
+
- `quality_gate === 'pass'`: All quality criteria met
|
|
360
|
+
|
|
361
|
+
## Error Recovery
|
|
362
|
+
|
|
363
|
+
| Error Type | Recovery Strategy |
|
|
364
|
+
|------------|-------------------|
|
|
365
|
+
| Action execution failed | Retry up to 3 times, then skip |
|
|
366
|
+
| State parse error | Restore from backup |
|
|
367
|
+
| File write error | Retry with alternative path |
|
|
368
|
+
| User abort | Save state and exit gracefully |
|
|
369
|
+
|
|
370
|
+
## User Interaction Points
|
|
371
|
+
|
|
372
|
+
The orchestrator pauses for user input at these points:
|
|
373
|
+
|
|
374
|
+
1. **action-init**: Confirm target skill and describe issue
|
|
375
|
+
2. **action-propose-fixes**: Select which fixes to apply
|
|
376
|
+
3. **action-verify**: Review verification results, decide to continue or stop
|
|
377
|
+
4. **action-complete**: Review final summary
|