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,243 @@
|
|
|
1
|
+
# Action: Diagnose Context Explosion
|
|
2
|
+
|
|
3
|
+
Analyze target skill for context explosion issues - token accumulation and multi-turn dialogue bloat.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
- Detect patterns that cause context growth
|
|
8
|
+
- Identify multi-turn accumulation points
|
|
9
|
+
- Find missing context compression mechanisms
|
|
10
|
+
- Measure potential token waste
|
|
11
|
+
|
|
12
|
+
## Preconditions
|
|
13
|
+
|
|
14
|
+
- [ ] state.status === 'running'
|
|
15
|
+
- [ ] state.target_skill.path is set
|
|
16
|
+
- [ ] 'context' in state.focus_areas OR state.focus_areas is empty
|
|
17
|
+
|
|
18
|
+
## Detection Patterns
|
|
19
|
+
|
|
20
|
+
### Pattern 1: Unbounded History Accumulation
|
|
21
|
+
|
|
22
|
+
```regex
|
|
23
|
+
# Patterns that suggest history accumulation
|
|
24
|
+
/\bhistory\b.*\.push\b/
|
|
25
|
+
/\bmessages\b.*\.concat\b/
|
|
26
|
+
/\bconversation\b.*\+=\b/
|
|
27
|
+
/\bappend.*context\b/i
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Pattern 2: Full Content Passing
|
|
31
|
+
|
|
32
|
+
```regex
|
|
33
|
+
# Patterns that pass full content instead of references
|
|
34
|
+
/Read\([^)]+\).*\+.*Read\(/
|
|
35
|
+
/JSON\.stringify\(.*state\)/ # Full state serialization
|
|
36
|
+
/\$\{.*content\}/ # Template literal with full content
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Pattern 3: Missing Summarization
|
|
40
|
+
|
|
41
|
+
```regex
|
|
42
|
+
# Absence of compression/summarization
|
|
43
|
+
# Check for lack of: summarize, compress, truncate, slice
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Pattern 4: Agent Return Bloat
|
|
47
|
+
|
|
48
|
+
```regex
|
|
49
|
+
# Agent returning full content instead of path + summary
|
|
50
|
+
/return\s*\{[^}]*content:/
|
|
51
|
+
/return.*JSON\.stringify/
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Execution
|
|
55
|
+
|
|
56
|
+
```javascript
|
|
57
|
+
async function execute(state, workDir) {
|
|
58
|
+
const skillPath = state.target_skill.path;
|
|
59
|
+
const startTime = Date.now();
|
|
60
|
+
const issues = [];
|
|
61
|
+
const evidence = [];
|
|
62
|
+
|
|
63
|
+
console.log(`Diagnosing context explosion in ${skillPath}...`);
|
|
64
|
+
|
|
65
|
+
// 1. Scan all phase files
|
|
66
|
+
const phaseFiles = Glob(`${skillPath}/phases/**/*.md`);
|
|
67
|
+
|
|
68
|
+
for (const file of phaseFiles) {
|
|
69
|
+
const content = Read(file);
|
|
70
|
+
const relativePath = file.replace(skillPath + '/', '');
|
|
71
|
+
|
|
72
|
+
// Check Pattern 1: History accumulation
|
|
73
|
+
const historyPatterns = [
|
|
74
|
+
/history\s*[.=].*push|concat|append/gi,
|
|
75
|
+
/messages\s*=\s*\[.*\.\.\..*messages/gi,
|
|
76
|
+
/conversation.*\+=/gi
|
|
77
|
+
];
|
|
78
|
+
|
|
79
|
+
for (const pattern of historyPatterns) {
|
|
80
|
+
const matches = content.match(pattern);
|
|
81
|
+
if (matches) {
|
|
82
|
+
issues.push({
|
|
83
|
+
id: `CTX-${issues.length + 1}`,
|
|
84
|
+
type: 'context_explosion',
|
|
85
|
+
severity: 'high',
|
|
86
|
+
location: { file: relativePath },
|
|
87
|
+
description: 'Unbounded history accumulation detected',
|
|
88
|
+
evidence: matches.slice(0, 3),
|
|
89
|
+
root_cause: 'History/messages array grows without bounds',
|
|
90
|
+
impact: 'Token count increases linearly with iterations',
|
|
91
|
+
suggested_fix: 'Implement sliding window or summarization'
|
|
92
|
+
});
|
|
93
|
+
evidence.push({
|
|
94
|
+
file: relativePath,
|
|
95
|
+
pattern: 'history_accumulation',
|
|
96
|
+
context: matches[0],
|
|
97
|
+
severity: 'high'
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Check Pattern 2: Full content passing
|
|
103
|
+
const contentPatterns = [
|
|
104
|
+
/Read\s*\([^)]+\)\s*[\+,]/g,
|
|
105
|
+
/JSON\.stringify\s*\(\s*state\s*\)/g,
|
|
106
|
+
/\$\{[^}]*content[^}]*\}/g
|
|
107
|
+
];
|
|
108
|
+
|
|
109
|
+
for (const pattern of contentPatterns) {
|
|
110
|
+
const matches = content.match(pattern);
|
|
111
|
+
if (matches) {
|
|
112
|
+
issues.push({
|
|
113
|
+
id: `CTX-${issues.length + 1}`,
|
|
114
|
+
type: 'context_explosion',
|
|
115
|
+
severity: 'medium',
|
|
116
|
+
location: { file: relativePath },
|
|
117
|
+
description: 'Full content passed instead of reference',
|
|
118
|
+
evidence: matches.slice(0, 3),
|
|
119
|
+
root_cause: 'Entire file/state content included in prompts',
|
|
120
|
+
impact: 'Unnecessary token consumption',
|
|
121
|
+
suggested_fix: 'Pass file paths and summaries instead of full content'
|
|
122
|
+
});
|
|
123
|
+
evidence.push({
|
|
124
|
+
file: relativePath,
|
|
125
|
+
pattern: 'full_content_passing',
|
|
126
|
+
context: matches[0],
|
|
127
|
+
severity: 'medium'
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Check Pattern 3: Missing summarization
|
|
133
|
+
const hasSummarization = /summariz|compress|truncat|slice.*context/i.test(content);
|
|
134
|
+
const hasLongPrompts = content.length > 5000;
|
|
135
|
+
|
|
136
|
+
if (hasLongPrompts && !hasSummarization) {
|
|
137
|
+
issues.push({
|
|
138
|
+
id: `CTX-${issues.length + 1}`,
|
|
139
|
+
type: 'context_explosion',
|
|
140
|
+
severity: 'medium',
|
|
141
|
+
location: { file: relativePath },
|
|
142
|
+
description: 'Long phase file without summarization mechanism',
|
|
143
|
+
evidence: [`File length: ${content.length} chars`],
|
|
144
|
+
root_cause: 'No context compression for large content',
|
|
145
|
+
impact: 'Potential token overflow in long sessions',
|
|
146
|
+
suggested_fix: 'Add context summarization before passing to agents'
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Check Pattern 4: Agent return bloat
|
|
151
|
+
const returnPatterns = /return\s*\{[^}]*(?:content|full_output|complete_result):/g;
|
|
152
|
+
const returnMatches = content.match(returnPatterns);
|
|
153
|
+
if (returnMatches) {
|
|
154
|
+
issues.push({
|
|
155
|
+
id: `CTX-${issues.length + 1}`,
|
|
156
|
+
type: 'context_explosion',
|
|
157
|
+
severity: 'high',
|
|
158
|
+
location: { file: relativePath },
|
|
159
|
+
description: 'Agent returns full content instead of path+summary',
|
|
160
|
+
evidence: returnMatches.slice(0, 3),
|
|
161
|
+
root_cause: 'Agent output includes complete content',
|
|
162
|
+
impact: 'Context bloat when orchestrator receives full output',
|
|
163
|
+
suggested_fix: 'Return {output_file, summary} instead of {content}'
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// 2. Calculate severity
|
|
169
|
+
const criticalCount = issues.filter(i => i.severity === 'critical').length;
|
|
170
|
+
const highCount = issues.filter(i => i.severity === 'high').length;
|
|
171
|
+
const severity = criticalCount > 0 ? 'critical' :
|
|
172
|
+
highCount > 2 ? 'high' :
|
|
173
|
+
highCount > 0 ? 'medium' :
|
|
174
|
+
issues.length > 0 ? 'low' : 'none';
|
|
175
|
+
|
|
176
|
+
// 3. Write diagnosis result
|
|
177
|
+
const diagnosisResult = {
|
|
178
|
+
status: 'completed',
|
|
179
|
+
issues_found: issues.length,
|
|
180
|
+
severity: severity,
|
|
181
|
+
execution_time_ms: Date.now() - startTime,
|
|
182
|
+
details: {
|
|
183
|
+
patterns_checked: [
|
|
184
|
+
'history_accumulation',
|
|
185
|
+
'full_content_passing',
|
|
186
|
+
'missing_summarization',
|
|
187
|
+
'agent_return_bloat'
|
|
188
|
+
],
|
|
189
|
+
patterns_matched: evidence.map(e => e.pattern),
|
|
190
|
+
evidence: evidence,
|
|
191
|
+
recommendations: [
|
|
192
|
+
issues.length > 0 ? 'Implement context summarization agent' : null,
|
|
193
|
+
highCount > 0 ? 'Add sliding window for conversation history' : null,
|
|
194
|
+
evidence.some(e => e.pattern === 'full_content_passing')
|
|
195
|
+
? 'Refactor to pass file paths instead of content' : null
|
|
196
|
+
].filter(Boolean)
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
Write(`${workDir}/diagnosis/context-diagnosis.json`,
|
|
201
|
+
JSON.stringify(diagnosisResult, null, 2));
|
|
202
|
+
|
|
203
|
+
return {
|
|
204
|
+
stateUpdates: {
|
|
205
|
+
'diagnosis.context': diagnosisResult,
|
|
206
|
+
issues: [...state.issues, ...issues],
|
|
207
|
+
'issues_by_severity.critical': state.issues_by_severity.critical + criticalCount,
|
|
208
|
+
'issues_by_severity.high': state.issues_by_severity.high + highCount
|
|
209
|
+
},
|
|
210
|
+
outputFiles: [`${workDir}/diagnosis/context-diagnosis.json`],
|
|
211
|
+
summary: `Context diagnosis: ${issues.length} issues found (severity: ${severity})`
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## State Updates
|
|
217
|
+
|
|
218
|
+
```javascript
|
|
219
|
+
return {
|
|
220
|
+
stateUpdates: {
|
|
221
|
+
'diagnosis.context': {
|
|
222
|
+
status: 'completed',
|
|
223
|
+
issues_found: <count>,
|
|
224
|
+
severity: '<critical|high|medium|low|none>',
|
|
225
|
+
// ... full diagnosis result
|
|
226
|
+
},
|
|
227
|
+
issues: [...existingIssues, ...newIssues]
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Error Handling
|
|
233
|
+
|
|
234
|
+
| Error Type | Recovery |
|
|
235
|
+
|------------|----------|
|
|
236
|
+
| File read error | Skip file, log warning |
|
|
237
|
+
| Pattern matching error | Use fallback patterns |
|
|
238
|
+
| Write error | Retry to alternative path |
|
|
239
|
+
|
|
240
|
+
## Next Actions
|
|
241
|
+
|
|
242
|
+
- Success: action-diagnose-memory (or next in focus_areas)
|
|
243
|
+
- Skipped: If 'context' not in focus_areas
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
# Action: Diagnose Data Flow Issues
|
|
2
|
+
|
|
3
|
+
Analyze target skill for data flow disruption - state inconsistencies and format variations.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
- Detect inconsistent data formats between phases
|
|
8
|
+
- Identify scattered state storage
|
|
9
|
+
- Find missing data contracts
|
|
10
|
+
- Measure state transition integrity
|
|
11
|
+
|
|
12
|
+
## Preconditions
|
|
13
|
+
|
|
14
|
+
- [ ] state.status === 'running'
|
|
15
|
+
- [ ] state.target_skill.path is set
|
|
16
|
+
- [ ] 'dataflow' in state.focus_areas OR state.focus_areas is empty
|
|
17
|
+
|
|
18
|
+
## Detection Patterns
|
|
19
|
+
|
|
20
|
+
### Pattern 1: Multiple Storage Locations
|
|
21
|
+
|
|
22
|
+
```regex
|
|
23
|
+
# Data written to multiple paths without centralization
|
|
24
|
+
/Write\s*\(\s*[`'"][^`'"]+[`'"]/g
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Pattern 2: Inconsistent Field Names
|
|
28
|
+
|
|
29
|
+
```regex
|
|
30
|
+
# Same concept with different names: title/name, id/identifier
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Pattern 3: Missing Schema Validation
|
|
34
|
+
|
|
35
|
+
```regex
|
|
36
|
+
# Absence of validation before state write
|
|
37
|
+
# Look for lack of: validate, schema, check, verify
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Pattern 4: Format Transformation Without Normalization
|
|
41
|
+
|
|
42
|
+
```regex
|
|
43
|
+
# Direct JSON.parse without error handling or normalization
|
|
44
|
+
/JSON\.parse\([^)]+\)(?!\s*\|\|)/
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Execution
|
|
48
|
+
|
|
49
|
+
```javascript
|
|
50
|
+
async function execute(state, workDir) {
|
|
51
|
+
const skillPath = state.target_skill.path;
|
|
52
|
+
const startTime = Date.now();
|
|
53
|
+
const issues = [];
|
|
54
|
+
const evidence = [];
|
|
55
|
+
|
|
56
|
+
console.log(`Diagnosing data flow in ${skillPath}...`);
|
|
57
|
+
|
|
58
|
+
// 1. Collect all Write operations to map data storage
|
|
59
|
+
const allFiles = Glob(`${skillPath}/**/*.md`);
|
|
60
|
+
const writeLocations = [];
|
|
61
|
+
const readLocations = [];
|
|
62
|
+
|
|
63
|
+
for (const file of allFiles) {
|
|
64
|
+
const content = Read(file);
|
|
65
|
+
const relativePath = file.replace(skillPath + '/', '');
|
|
66
|
+
|
|
67
|
+
// Find Write operations
|
|
68
|
+
const writeMatches = content.matchAll(/Write\s*\(\s*[`'"]([^`'"]+)[`'"]/g);
|
|
69
|
+
for (const match of writeMatches) {
|
|
70
|
+
writeLocations.push({
|
|
71
|
+
file: relativePath,
|
|
72
|
+
target: match[1],
|
|
73
|
+
isStateFile: match[1].includes('state.json') || match[1].includes('config.json')
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Find Read operations
|
|
78
|
+
const readMatches = content.matchAll(/Read\s*\(\s*[`'"]([^`'"]+)[`'"]/g);
|
|
79
|
+
for (const match of readMatches) {
|
|
80
|
+
readLocations.push({
|
|
81
|
+
file: relativePath,
|
|
82
|
+
source: match[1]
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// 2. Check for scattered state storage
|
|
88
|
+
const stateTargets = writeLocations
|
|
89
|
+
.filter(w => w.isStateFile)
|
|
90
|
+
.map(w => w.target);
|
|
91
|
+
|
|
92
|
+
const uniqueStateFiles = [...new Set(stateTargets)];
|
|
93
|
+
|
|
94
|
+
if (uniqueStateFiles.length > 2) {
|
|
95
|
+
issues.push({
|
|
96
|
+
id: `DF-${issues.length + 1}`,
|
|
97
|
+
type: 'dataflow_break',
|
|
98
|
+
severity: 'high',
|
|
99
|
+
location: { file: 'multiple' },
|
|
100
|
+
description: `State stored in ${uniqueStateFiles.length} different locations`,
|
|
101
|
+
evidence: uniqueStateFiles.slice(0, 5),
|
|
102
|
+
root_cause: 'No centralized state management',
|
|
103
|
+
impact: 'State inconsistency between phases',
|
|
104
|
+
suggested_fix: 'Centralize state to single state.json with state manager'
|
|
105
|
+
});
|
|
106
|
+
evidence.push({
|
|
107
|
+
file: 'multiple',
|
|
108
|
+
pattern: 'scattered_state',
|
|
109
|
+
context: uniqueStateFiles.join(', '),
|
|
110
|
+
severity: 'high'
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// 3. Check for inconsistent field naming
|
|
115
|
+
const fieldNamePatterns = {
|
|
116
|
+
'name_vs_title': [/\.name\b/, /\.title\b/],
|
|
117
|
+
'id_vs_identifier': [/\.id\b/, /\.identifier\b/],
|
|
118
|
+
'status_vs_state': [/\.status\b/, /\.state\b/],
|
|
119
|
+
'error_vs_errors': [/\.error\b/, /\.errors\b/]
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const fieldUsage = {};
|
|
123
|
+
|
|
124
|
+
for (const file of allFiles) {
|
|
125
|
+
const content = Read(file);
|
|
126
|
+
const relativePath = file.replace(skillPath + '/', '');
|
|
127
|
+
|
|
128
|
+
for (const [patternName, patterns] of Object.entries(fieldNamePatterns)) {
|
|
129
|
+
for (const pattern of patterns) {
|
|
130
|
+
if (pattern.test(content)) {
|
|
131
|
+
if (!fieldUsage[patternName]) fieldUsage[patternName] = [];
|
|
132
|
+
fieldUsage[patternName].push({
|
|
133
|
+
file: relativePath,
|
|
134
|
+
pattern: pattern.toString()
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
for (const [patternName, usages] of Object.entries(fieldUsage)) {
|
|
142
|
+
const uniquePatterns = [...new Set(usages.map(u => u.pattern))];
|
|
143
|
+
if (uniquePatterns.length > 1) {
|
|
144
|
+
issues.push({
|
|
145
|
+
id: `DF-${issues.length + 1}`,
|
|
146
|
+
type: 'dataflow_break',
|
|
147
|
+
severity: 'medium',
|
|
148
|
+
location: { file: 'multiple' },
|
|
149
|
+
description: `Inconsistent field naming: ${patternName.replace('_vs_', ' vs ')}`,
|
|
150
|
+
evidence: usages.slice(0, 3).map(u => `${u.file}: ${u.pattern}`),
|
|
151
|
+
root_cause: 'Same concept referred to with different field names',
|
|
152
|
+
impact: 'Data may be lost during field access',
|
|
153
|
+
suggested_fix: `Standardize to single field name, add normalization function`
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// 4. Check for missing schema validation
|
|
159
|
+
for (const file of allFiles) {
|
|
160
|
+
const content = Read(file);
|
|
161
|
+
const relativePath = file.replace(skillPath + '/', '');
|
|
162
|
+
|
|
163
|
+
// Find JSON.parse without validation
|
|
164
|
+
const unsafeParses = content.match(/JSON\.parse\s*\([^)]+\)(?!\s*\?\?|\s*\|\|)/g);
|
|
165
|
+
const hasValidation = /validat|schema|type.*check/i.test(content);
|
|
166
|
+
|
|
167
|
+
if (unsafeParses && unsafeParses.length > 0 && !hasValidation) {
|
|
168
|
+
issues.push({
|
|
169
|
+
id: `DF-${issues.length + 1}`,
|
|
170
|
+
type: 'dataflow_break',
|
|
171
|
+
severity: 'medium',
|
|
172
|
+
location: { file: relativePath },
|
|
173
|
+
description: 'JSON parsing without validation',
|
|
174
|
+
evidence: unsafeParses.slice(0, 2),
|
|
175
|
+
root_cause: 'No schema validation after parsing',
|
|
176
|
+
impact: 'Invalid data may propagate through phases',
|
|
177
|
+
suggested_fix: 'Add schema validation after JSON.parse'
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// 5. Check state schema if exists
|
|
183
|
+
const stateSchemaFile = Glob(`${skillPath}/phases/state-schema.md`)[0];
|
|
184
|
+
if (stateSchemaFile) {
|
|
185
|
+
const schemaContent = Read(stateSchemaFile);
|
|
186
|
+
|
|
187
|
+
// Check for type definitions
|
|
188
|
+
const hasTypeScript = /interface\s+\w+|type\s+\w+\s*=/i.test(schemaContent);
|
|
189
|
+
const hasValidationFunction = /function\s+validate|validateState/i.test(schemaContent);
|
|
190
|
+
|
|
191
|
+
if (hasTypeScript && !hasValidationFunction) {
|
|
192
|
+
issues.push({
|
|
193
|
+
id: `DF-${issues.length + 1}`,
|
|
194
|
+
type: 'dataflow_break',
|
|
195
|
+
severity: 'low',
|
|
196
|
+
location: { file: 'phases/state-schema.md' },
|
|
197
|
+
description: 'Type definitions without runtime validation',
|
|
198
|
+
evidence: ['TypeScript interfaces defined but no validation function'],
|
|
199
|
+
root_cause: 'Types are compile-time only, not enforced at runtime',
|
|
200
|
+
impact: 'Schema violations may occur at runtime',
|
|
201
|
+
suggested_fix: 'Add validateState() function using Zod or manual checks'
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
} else if (state.target_skill.execution_mode === 'autonomous') {
|
|
205
|
+
issues.push({
|
|
206
|
+
id: `DF-${issues.length + 1}`,
|
|
207
|
+
type: 'dataflow_break',
|
|
208
|
+
severity: 'high',
|
|
209
|
+
location: { file: 'phases/' },
|
|
210
|
+
description: 'Autonomous skill missing state-schema.md',
|
|
211
|
+
evidence: ['No state schema definition found'],
|
|
212
|
+
root_cause: 'State structure undefined for orchestrator',
|
|
213
|
+
impact: 'Inconsistent state handling across actions',
|
|
214
|
+
suggested_fix: 'Create phases/state-schema.md with explicit type definitions'
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// 6. Check read-write alignment
|
|
219
|
+
const writtenFiles = new Set(writeLocations.map(w => w.target));
|
|
220
|
+
const readFiles = new Set(readLocations.map(r => r.source));
|
|
221
|
+
|
|
222
|
+
const writtenButNotRead = [...writtenFiles].filter(f =>
|
|
223
|
+
!readFiles.has(f) && !f.includes('output') && !f.includes('report')
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
if (writtenButNotRead.length > 0) {
|
|
227
|
+
issues.push({
|
|
228
|
+
id: `DF-${issues.length + 1}`,
|
|
229
|
+
type: 'dataflow_break',
|
|
230
|
+
severity: 'low',
|
|
231
|
+
location: { file: 'multiple' },
|
|
232
|
+
description: 'Files written but never read',
|
|
233
|
+
evidence: writtenButNotRead.slice(0, 3),
|
|
234
|
+
root_cause: 'Orphaned output files',
|
|
235
|
+
impact: 'Wasted storage and potential confusion',
|
|
236
|
+
suggested_fix: 'Remove unused writes or add reads where needed'
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// 7. Calculate severity
|
|
241
|
+
const criticalCount = issues.filter(i => i.severity === 'critical').length;
|
|
242
|
+
const highCount = issues.filter(i => i.severity === 'high').length;
|
|
243
|
+
const severity = criticalCount > 0 ? 'critical' :
|
|
244
|
+
highCount > 1 ? 'high' :
|
|
245
|
+
highCount > 0 ? 'medium' :
|
|
246
|
+
issues.length > 0 ? 'low' : 'none';
|
|
247
|
+
|
|
248
|
+
// 8. Write diagnosis result
|
|
249
|
+
const diagnosisResult = {
|
|
250
|
+
status: 'completed',
|
|
251
|
+
issues_found: issues.length,
|
|
252
|
+
severity: severity,
|
|
253
|
+
execution_time_ms: Date.now() - startTime,
|
|
254
|
+
details: {
|
|
255
|
+
patterns_checked: [
|
|
256
|
+
'scattered_state',
|
|
257
|
+
'inconsistent_naming',
|
|
258
|
+
'missing_validation',
|
|
259
|
+
'read_write_alignment'
|
|
260
|
+
],
|
|
261
|
+
patterns_matched: evidence.map(e => e.pattern),
|
|
262
|
+
evidence: evidence,
|
|
263
|
+
data_flow_map: {
|
|
264
|
+
write_locations: writeLocations.length,
|
|
265
|
+
read_locations: readLocations.length,
|
|
266
|
+
unique_state_files: uniqueStateFiles.length
|
|
267
|
+
},
|
|
268
|
+
recommendations: [
|
|
269
|
+
uniqueStateFiles.length > 2 ? 'Implement centralized state manager' : null,
|
|
270
|
+
issues.some(i => i.description.includes('naming'))
|
|
271
|
+
? 'Create normalization layer for field names' : null,
|
|
272
|
+
issues.some(i => i.description.includes('validation'))
|
|
273
|
+
? 'Add Zod or JSON Schema validation' : null
|
|
274
|
+
].filter(Boolean)
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
Write(`${workDir}/diagnosis/dataflow-diagnosis.json`,
|
|
279
|
+
JSON.stringify(diagnosisResult, null, 2));
|
|
280
|
+
|
|
281
|
+
return {
|
|
282
|
+
stateUpdates: {
|
|
283
|
+
'diagnosis.dataflow': diagnosisResult,
|
|
284
|
+
issues: [...state.issues, ...issues]
|
|
285
|
+
},
|
|
286
|
+
outputFiles: [`${workDir}/diagnosis/dataflow-diagnosis.json`],
|
|
287
|
+
summary: `Data flow diagnosis: ${issues.length} issues found (severity: ${severity})`
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## State Updates
|
|
293
|
+
|
|
294
|
+
```javascript
|
|
295
|
+
return {
|
|
296
|
+
stateUpdates: {
|
|
297
|
+
'diagnosis.dataflow': {
|
|
298
|
+
status: 'completed',
|
|
299
|
+
issues_found: <count>,
|
|
300
|
+
severity: '<critical|high|medium|low|none>',
|
|
301
|
+
// ... full diagnosis result
|
|
302
|
+
},
|
|
303
|
+
issues: [...existingIssues, ...newIssues]
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## Error Handling
|
|
309
|
+
|
|
310
|
+
| Error Type | Recovery |
|
|
311
|
+
|------------|----------|
|
|
312
|
+
| Glob pattern error | Use fallback patterns |
|
|
313
|
+
| File read error | Skip and continue |
|
|
314
|
+
|
|
315
|
+
## Next Actions
|
|
316
|
+
|
|
317
|
+
- Success: action-diagnose-agent (or next in focus_areas)
|
|
318
|
+
- Skipped: If 'dataflow' not in focus_areas
|