@cloudstreamsoftware/claude-tools 1.0.0 → 1.2.0
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/README.md +152 -37
- package/agents/INDEX.md +183 -0
- package/agents/architect.md +247 -0
- package/agents/build-error-resolver.md +555 -0
- package/agents/catalyst-deployer.md +132 -0
- package/agents/code-reviewer.md +121 -0
- package/agents/compliance-auditor.md +148 -0
- package/agents/creator-architect.md +395 -0
- package/agents/deluge-reviewer.md +98 -0
- package/agents/doc-updater.md +471 -0
- package/agents/e2e-runner.md +711 -0
- package/agents/planner.md +122 -0
- package/agents/refactor-cleaner.md +309 -0
- package/agents/security-reviewer.md +582 -0
- package/agents/tdd-guide.md +302 -0
- package/bin/cloudstream-setup.js +16 -6
- package/config/versions.json +63 -0
- package/dist/hooks/hooks.json +209 -0
- package/dist/index.js +47 -0
- package/dist/lib/asset-value.js +609 -0
- package/dist/lib/client-manager.js +300 -0
- package/dist/lib/command-matcher.js +242 -0
- package/dist/lib/cross-session-patterns.js +754 -0
- package/dist/lib/intent-classifier.js +1075 -0
- package/dist/lib/package-manager.js +374 -0
- package/dist/lib/recommendation-engine.js +597 -0
- package/dist/lib/session-memory.js +489 -0
- package/dist/lib/skill-effectiveness.js +486 -0
- package/dist/lib/skill-matcher.js +595 -0
- package/dist/lib/tutorial-metrics.js +242 -0
- package/dist/lib/tutorial-progress.js +209 -0
- package/dist/lib/tutorial-renderer.js +431 -0
- package/dist/lib/utils.js +380 -0
- package/dist/lib/verify-formatter.js +143 -0
- package/dist/lib/workflow-state.js +249 -0
- package/hooks/hooks.json +209 -0
- package/package.json +5 -1
- package/scripts/aggregate-sessions.js +290 -0
- package/scripts/branch-name-validator.js +291 -0
- package/scripts/build.js +101 -0
- package/scripts/commands/client-switch.js +231 -0
- package/scripts/deprecate-skill.js +610 -0
- package/scripts/diagnose.js +324 -0
- package/scripts/doc-freshness.js +168 -0
- package/scripts/generate-weekly-digest.js +393 -0
- package/scripts/health-check.js +270 -0
- package/scripts/hooks/credential-check.js +101 -0
- package/scripts/hooks/evaluate-session.js +81 -0
- package/scripts/hooks/pre-compact.js +66 -0
- package/scripts/hooks/prompt-analyzer.js +276 -0
- package/scripts/hooks/prompt-router.js +422 -0
- package/scripts/hooks/quality-gate-enforcer.js +371 -0
- package/scripts/hooks/session-end.js +156 -0
- package/scripts/hooks/session-start.js +195 -0
- package/scripts/hooks/skill-injector.js +333 -0
- package/scripts/hooks/suggest-compact.js +58 -0
- package/scripts/lib/asset-value.js +609 -0
- package/scripts/lib/client-manager.js +300 -0
- package/scripts/lib/command-matcher.js +242 -0
- package/scripts/lib/cross-session-patterns.js +754 -0
- package/scripts/lib/intent-classifier.js +1075 -0
- package/scripts/lib/package-manager.js +374 -0
- package/scripts/lib/recommendation-engine.js +597 -0
- package/scripts/lib/session-memory.js +489 -0
- package/scripts/lib/skill-effectiveness.js +486 -0
- package/scripts/lib/skill-matcher.js +595 -0
- package/scripts/lib/tutorial-metrics.js +242 -0
- package/scripts/lib/tutorial-progress.js +209 -0
- package/scripts/lib/tutorial-renderer.js +431 -0
- package/scripts/lib/utils.js +380 -0
- package/scripts/lib/verify-formatter.js +143 -0
- package/scripts/lib/workflow-state.js +249 -0
- package/scripts/onboard.js +363 -0
- package/scripts/quarterly-report.js +692 -0
- package/scripts/setup-package-manager.js +204 -0
- package/scripts/sync-upstream.js +391 -0
- package/scripts/test.js +108 -0
- package/scripts/tutorial-runner.js +351 -0
- package/scripts/validate-all.js +201 -0
- package/scripts/verifiers/agents.js +245 -0
- package/scripts/verifiers/config.js +186 -0
- package/scripts/verifiers/environment.js +123 -0
- package/scripts/verifiers/hooks.js +188 -0
- package/scripts/verifiers/index.js +38 -0
- package/scripts/verifiers/persistence.js +140 -0
- package/scripts/verifiers/plugin.js +215 -0
- package/scripts/verifiers/skills.js +209 -0
- package/scripts/verify-setup.js +164 -0
- package/skills/INDEX.md +157 -0
- package/skills/backend-patterns/SKILL.md +586 -0
- package/skills/backend-patterns/catalyst-patterns.md +128 -0
- package/skills/bigquery-patterns/SKILL.md +27 -0
- package/skills/bigquery-patterns/performance-optimization.md +518 -0
- package/skills/bigquery-patterns/query-patterns.md +372 -0
- package/skills/bigquery-patterns/schema-design.md +78 -0
- package/skills/cloudstream-project-template/SKILL.md +20 -0
- package/skills/cloudstream-project-template/structure.md +65 -0
- package/skills/coding-standards/SKILL.md +524 -0
- package/skills/coding-standards/deluge-standards.md +83 -0
- package/skills/compliance-patterns/SKILL.md +28 -0
- package/skills/compliance-patterns/hipaa/audit-requirements.md +251 -0
- package/skills/compliance-patterns/hipaa/baa-process.md +298 -0
- package/skills/compliance-patterns/hipaa/data-archival-strategy.md +387 -0
- package/skills/compliance-patterns/hipaa/phi-handling.md +52 -0
- package/skills/compliance-patterns/pci-dss/saq-a-requirements.md +307 -0
- package/skills/compliance-patterns/pci-dss/tokenization-patterns.md +382 -0
- package/skills/compliance-patterns/pci-dss/zoho-checkout-patterns.md +56 -0
- package/skills/compliance-patterns/soc2/access-controls.md +344 -0
- package/skills/compliance-patterns/soc2/audit-logging.md +458 -0
- package/skills/compliance-patterns/soc2/change-management.md +403 -0
- package/skills/compliance-patterns/soc2/deluge-execution-logging.md +407 -0
- package/skills/consultancy-workflows/SKILL.md +19 -0
- package/skills/consultancy-workflows/client-isolation.md +21 -0
- package/skills/consultancy-workflows/documentation-automation.md +454 -0
- package/skills/consultancy-workflows/handoff-procedures.md +257 -0
- package/skills/consultancy-workflows/knowledge-capture.md +513 -0
- package/skills/consultancy-workflows/time-tracking.md +26 -0
- package/skills/continuous-learning/SKILL.md +84 -0
- package/skills/continuous-learning/config.json +18 -0
- package/skills/continuous-learning/evaluate-session.sh +60 -0
- package/skills/continuous-learning-v2/SKILL.md +126 -0
- package/skills/continuous-learning-v2/config.json +61 -0
- package/skills/frontend-patterns/SKILL.md +635 -0
- package/skills/frontend-patterns/zoho-widget-patterns.md +103 -0
- package/skills/gcp-data-engineering/SKILL.md +36 -0
- package/skills/gcp-data-engineering/bigquery/performance-optimization.md +337 -0
- package/skills/gcp-data-engineering/dataflow/error-handling.md +496 -0
- package/skills/gcp-data-engineering/dataflow/pipeline-patterns.md +444 -0
- package/skills/gcp-data-engineering/dbt/model-organization.md +63 -0
- package/skills/gcp-data-engineering/dbt/testing-patterns.md +503 -0
- package/skills/gcp-data-engineering/medallion-architecture/bronze-layer.md +60 -0
- package/skills/gcp-data-engineering/medallion-architecture/gold-layer.md +311 -0
- package/skills/gcp-data-engineering/medallion-architecture/layer-transitions.md +517 -0
- package/skills/gcp-data-engineering/medallion-architecture/silver-layer.md +305 -0
- package/skills/gcp-data-engineering/zoho-to-gcp/data-extraction.md +543 -0
- package/skills/gcp-data-engineering/zoho-to-gcp/real-time-vs-batch.md +337 -0
- package/skills/security-review/SKILL.md +498 -0
- package/skills/security-review/compliance-checklist.md +53 -0
- package/skills/strategic-compact/SKILL.md +67 -0
- package/skills/tdd-workflow/SKILL.md +413 -0
- package/skills/tdd-workflow/zoho-testing.md +124 -0
- package/skills/tutorial/SKILL.md +249 -0
- package/skills/tutorial/docs/ACCESSIBILITY.md +169 -0
- package/skills/tutorial/lessons/00-philosophy-and-workflow.md +198 -0
- package/skills/tutorial/lessons/01-basics.md +81 -0
- package/skills/tutorial/lessons/02-training.md +86 -0
- package/skills/tutorial/lessons/03-commands.md +109 -0
- package/skills/tutorial/lessons/04-workflows.md +115 -0
- package/skills/tutorial/lessons/05-compliance.md +116 -0
- package/skills/tutorial/lessons/06-zoho.md +121 -0
- package/skills/tutorial/lessons/07-hooks-system.md +277 -0
- package/skills/tutorial/lessons/08-mcp-servers.md +316 -0
- package/skills/tutorial/lessons/09-client-management.md +215 -0
- package/skills/tutorial/lessons/10-testing-e2e.md +260 -0
- package/skills/tutorial/lessons/11-skills-deep-dive.md +272 -0
- package/skills/tutorial/lessons/12-rules-system.md +326 -0
- package/skills/tutorial/lessons/13-golden-standard-graduation.md +213 -0
- package/skills/tutorial/lessons/14-fork-setup-and-sync.md +312 -0
- package/skills/tutorial/lessons/15-living-examples-system.md +221 -0
- package/skills/tutorial/tracks/accelerated/README.md +134 -0
- package/skills/tutorial/tracks/accelerated/assessment/checkpoint-1.md +161 -0
- package/skills/tutorial/tracks/accelerated/assessment/checkpoint-2.md +175 -0
- package/skills/tutorial/tracks/accelerated/day-1-core-concepts.md +234 -0
- package/skills/tutorial/tracks/accelerated/day-2-essential-commands.md +270 -0
- package/skills/tutorial/tracks/accelerated/day-3-workflow-mastery.md +305 -0
- package/skills/tutorial/tracks/accelerated/day-4-compliance-zoho.md +304 -0
- package/skills/tutorial/tracks/accelerated/day-5-hooks-skills.md +344 -0
- package/skills/tutorial/tracks/accelerated/day-6-client-testing.md +386 -0
- package/skills/tutorial/tracks/accelerated/day-7-graduation.md +369 -0
- package/skills/zoho-patterns/CHANGELOG.md +108 -0
- package/skills/zoho-patterns/SKILL.md +446 -0
- package/skills/zoho-patterns/analytics/dashboard-patterns.md +352 -0
- package/skills/zoho-patterns/analytics/zoho-to-bigquery-pipeline.md +427 -0
- package/skills/zoho-patterns/catalyst/appsail-deployment.md +349 -0
- package/skills/zoho-patterns/catalyst/context-close-patterns.md +354 -0
- package/skills/zoho-patterns/catalyst/cron-batch-processing.md +374 -0
- package/skills/zoho-patterns/catalyst/function-patterns.md +439 -0
- package/skills/zoho-patterns/creator/form-design.md +304 -0
- package/skills/zoho-patterns/creator/publish-api-patterns.md +313 -0
- package/skills/zoho-patterns/creator/widget-integration.md +306 -0
- package/skills/zoho-patterns/creator/workflow-automation.md +253 -0
- package/skills/zoho-patterns/deluge/api-patterns.md +468 -0
- package/skills/zoho-patterns/deluge/batch-processing.md +403 -0
- package/skills/zoho-patterns/deluge/cross-app-integration.md +356 -0
- package/skills/zoho-patterns/deluge/error-handling.md +423 -0
- package/skills/zoho-patterns/deluge/syntax-reference.md +65 -0
- package/skills/zoho-patterns/integration/cors-proxy-architecture.md +426 -0
- package/skills/zoho-patterns/integration/crm-books-native-sync.md +277 -0
- package/skills/zoho-patterns/integration/oauth-token-management.md +461 -0
- package/skills/zoho-patterns/integration/zoho-flow-patterns.md +334 -0
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Weekly Digest Generator
|
|
4
|
+
*
|
|
5
|
+
* Generates human-readable weekly summary of patterns, trends, and recommendations.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* node scripts/generate-weekly-digest.js [--days=7] [--email]
|
|
9
|
+
*
|
|
10
|
+
* Options:
|
|
11
|
+
* --days Analysis window in days (default: 7)
|
|
12
|
+
* --email Send digest via email (if configured)
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const fs = require('fs');
|
|
17
|
+
const {
|
|
18
|
+
getClaudeDir,
|
|
19
|
+
ensureDir,
|
|
20
|
+
writeFile,
|
|
21
|
+
getDateString,
|
|
22
|
+
getDateTimeString,
|
|
23
|
+
log,
|
|
24
|
+
} = require('./lib/utils');
|
|
25
|
+
|
|
26
|
+
const {
|
|
27
|
+
analyzeAllSessions,
|
|
28
|
+
detectCrossSessionPatterns,
|
|
29
|
+
analyzeByTechnology,
|
|
30
|
+
analyzeTrends,
|
|
31
|
+
buildSkillCorrectionMatrix,
|
|
32
|
+
getAggregatedData,
|
|
33
|
+
} = require('./lib/cross-session-patterns');
|
|
34
|
+
|
|
35
|
+
const { getSessionStartRecommendations } = require('./lib/recommendation-engine');
|
|
36
|
+
|
|
37
|
+
// Parse command line arguments
|
|
38
|
+
function parseArgs() {
|
|
39
|
+
const args = process.argv.slice(2);
|
|
40
|
+
const options = {
|
|
41
|
+
days: 7,
|
|
42
|
+
email: false,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
for (const arg of args) {
|
|
46
|
+
if (arg.startsWith('--days=')) {
|
|
47
|
+
options.days = parseInt(arg.split('=')[1], 10) || 7;
|
|
48
|
+
} else if (arg === '--email') {
|
|
49
|
+
options.email = true;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return options;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Calculate week range string
|
|
58
|
+
*/
|
|
59
|
+
function getWeekRange(days) {
|
|
60
|
+
const end = new Date();
|
|
61
|
+
const start = new Date(end.getTime() - days * 24 * 60 * 60 * 1000);
|
|
62
|
+
|
|
63
|
+
const formatDate = (d) => {
|
|
64
|
+
const months = [
|
|
65
|
+
'Jan',
|
|
66
|
+
'Feb',
|
|
67
|
+
'Mar',
|
|
68
|
+
'Apr',
|
|
69
|
+
'May',
|
|
70
|
+
'Jun',
|
|
71
|
+
'Jul',
|
|
72
|
+
'Aug',
|
|
73
|
+
'Sep',
|
|
74
|
+
'Oct',
|
|
75
|
+
'Nov',
|
|
76
|
+
'Dec',
|
|
77
|
+
];
|
|
78
|
+
return `${months[d.getMonth()]} ${d.getDate()}`;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
return `${formatDate(start)} - ${formatDate(end)}, ${end.getFullYear()}`;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Truncate string for display
|
|
86
|
+
*/
|
|
87
|
+
function truncate(str, length) {
|
|
88
|
+
if (!str) return '';
|
|
89
|
+
if (str.length <= length) return str;
|
|
90
|
+
return str.substring(0, length - 3) + '...';
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Get trend emoji
|
|
95
|
+
*/
|
|
96
|
+
function getTrendEmoji(percentChange) {
|
|
97
|
+
if (percentChange <= -25) return '\u2B07\uFE0F'; // Down arrow
|
|
98
|
+
if (percentChange >= 25) return '\u2B06\uFE0F'; // Up arrow
|
|
99
|
+
return '\u27A1\uFE0F'; // Right arrow (stable)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Generate the weekly digest markdown
|
|
104
|
+
*/
|
|
105
|
+
function generateDigest(data, options) {
|
|
106
|
+
const weekRange = getWeekRange(options.days);
|
|
107
|
+
|
|
108
|
+
let md = `# Weekly Knowledge Digest: ${weekRange}\n\n`;
|
|
109
|
+
md += `*Generated: ${getDateTimeString()}*\n\n`;
|
|
110
|
+
md += `---\n\n`;
|
|
111
|
+
|
|
112
|
+
// Summary Section
|
|
113
|
+
md += `## Summary\n\n`;
|
|
114
|
+
md += `| Metric | Value |\n`;
|
|
115
|
+
md += `|--------|-------|\n`;
|
|
116
|
+
md += `| Sessions analyzed | ${data.summary.sessionCount} |\n`;
|
|
117
|
+
md += `| Corrections recorded | ${data.summary.correctionCount} |\n`;
|
|
118
|
+
md += `| Patterns detected | ${data.patterns.highConfidence.length + data.patterns.emerging.length} |\n`;
|
|
119
|
+
md += `| Skills applied | ${data.skillApplications || 'N/A'} |\n\n`;
|
|
120
|
+
|
|
121
|
+
// Top Patterns This Week
|
|
122
|
+
if (data.patterns.highConfidence.length > 0 || data.patterns.emerging.length > 0) {
|
|
123
|
+
md += `## Top Patterns This Week\n\n`;
|
|
124
|
+
md += `| Pattern | Category | Occurrences | Trend |\n`;
|
|
125
|
+
md += `|---------|----------|-------------|-------|\n`;
|
|
126
|
+
|
|
127
|
+
const allPatterns = [...data.patterns.highConfidence, ...data.patterns.emerging]
|
|
128
|
+
.sort((a, b) => b.totalOccurrences - a.totalOccurrences)
|
|
129
|
+
.slice(0, 10);
|
|
130
|
+
|
|
131
|
+
for (const p of allPatterns) {
|
|
132
|
+
const trend = data.trends.improving.find((t) => t.original === p.original)
|
|
133
|
+
? '\u2193 improving'
|
|
134
|
+
: data.trends.worsening.find((t) => t.original === p.original)
|
|
135
|
+
? '\u2191 worsening'
|
|
136
|
+
: '\u2192 stable';
|
|
137
|
+
|
|
138
|
+
md += `| ${truncate(p.original, 40)} | ${p.category} | ${p.totalOccurrences} | ${trend} |\n`;
|
|
139
|
+
}
|
|
140
|
+
md += '\n';
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Improvements Section
|
|
144
|
+
if (data.trends.improving.length > 0) {
|
|
145
|
+
md += `## Improvements \u{1F389}\n\n`;
|
|
146
|
+
md += `Great progress on these patterns:\n\n`;
|
|
147
|
+
|
|
148
|
+
for (const t of data.trends.improving.slice(0, 5)) {
|
|
149
|
+
md += `- **${truncate(t.original, 50)}** down ${Math.abs(t.percentChange)}%`;
|
|
150
|
+
if (t.linkedSkill) {
|
|
151
|
+
md += ` (${t.linkedSkill} helping)`;
|
|
152
|
+
}
|
|
153
|
+
md += '\n';
|
|
154
|
+
}
|
|
155
|
+
md += '\n';
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Concerns Section
|
|
159
|
+
if (data.trends.worsening.length > 0) {
|
|
160
|
+
md += `## Concerns \u26A0\uFE0F\n\n`;
|
|
161
|
+
md += `These patterns need attention:\n\n`;
|
|
162
|
+
|
|
163
|
+
for (const t of data.trends.worsening.slice(0, 5)) {
|
|
164
|
+
md += `- **${truncate(t.original, 50)}** up ${t.percentChange}%`;
|
|
165
|
+
|
|
166
|
+
// Suggest action
|
|
167
|
+
if (t.percentChange > 50) {
|
|
168
|
+
md += ` - consider adding to quality gates`;
|
|
169
|
+
}
|
|
170
|
+
md += '\n';
|
|
171
|
+
}
|
|
172
|
+
md += '\n';
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// New Patterns Section
|
|
176
|
+
if (data.trends.new && data.trends.new.length > 0) {
|
|
177
|
+
md += `## New Patterns\n\n`;
|
|
178
|
+
md += `First observed this week:\n\n`;
|
|
179
|
+
|
|
180
|
+
for (const t of data.trends.new.slice(0, 5)) {
|
|
181
|
+
md += `- ${truncate(t.original, 50)} (${t.occurrences} occurrences)\n`;
|
|
182
|
+
}
|
|
183
|
+
md += '\n';
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Skill Insights Section
|
|
187
|
+
if (Object.keys(data.skillMatrix).length > 0) {
|
|
188
|
+
md += `## Skill Insights\n\n`;
|
|
189
|
+
|
|
190
|
+
// Find most effective skill
|
|
191
|
+
let mostEffective = null;
|
|
192
|
+
let highestEffectiveness = 0;
|
|
193
|
+
|
|
194
|
+
// Find most used skill
|
|
195
|
+
let mostUsed = null;
|
|
196
|
+
let highestUsage = 0;
|
|
197
|
+
|
|
198
|
+
// Find skill needing improvement
|
|
199
|
+
let needsImprovement = null;
|
|
200
|
+
let lowestEffectiveness = 1;
|
|
201
|
+
|
|
202
|
+
for (const [skill, metrics] of Object.entries(data.skillMatrix)) {
|
|
203
|
+
if (metrics.effectiveness > highestEffectiveness) {
|
|
204
|
+
highestEffectiveness = metrics.effectiveness;
|
|
205
|
+
mostEffective = { name: skill, ...metrics };
|
|
206
|
+
}
|
|
207
|
+
if (metrics.applications > highestUsage) {
|
|
208
|
+
highestUsage = metrics.applications;
|
|
209
|
+
mostUsed = { name: skill, ...metrics };
|
|
210
|
+
}
|
|
211
|
+
if (metrics.effectiveness < lowestEffectiveness && metrics.applications > 2) {
|
|
212
|
+
lowestEffectiveness = metrics.effectiveness;
|
|
213
|
+
needsImprovement = { name: skill, ...metrics };
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (mostEffective) {
|
|
218
|
+
md += `- **Most Effective:** ${mostEffective.name} (${Math.round(mostEffective.effectiveness * 100)}%)\n`;
|
|
219
|
+
}
|
|
220
|
+
if (mostUsed) {
|
|
221
|
+
md += `- **Most Used:** ${mostUsed.name} (${mostUsed.applications} applications)\n`;
|
|
222
|
+
}
|
|
223
|
+
if (needsImprovement) {
|
|
224
|
+
md += `- **Needs Improvement:** ${needsImprovement.name} (${Math.round(needsImprovement.effectiveness * 100)}%)\n`;
|
|
225
|
+
}
|
|
226
|
+
md += '\n';
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Technology Breakdown
|
|
230
|
+
if (Object.keys(data.techPatterns).length > 0) {
|
|
231
|
+
md += `## Technology Breakdown\n\n`;
|
|
232
|
+
md += `| Technology | Sessions | Correction Rate | Top Issue |\n`;
|
|
233
|
+
md += `|------------|----------|-----------------|----------|\n`;
|
|
234
|
+
|
|
235
|
+
for (const [tech, techData] of Object.entries(data.techPatterns)) {
|
|
236
|
+
const topIssue = techData.topIssues[0]
|
|
237
|
+
? truncate(techData.topIssues[0].original, 30)
|
|
238
|
+
: 'None';
|
|
239
|
+
|
|
240
|
+
md += `| ${tech} | ${techData.sessionCount} | ${techData.correctionRate.toFixed(1)}/session | ${topIssue} |\n`;
|
|
241
|
+
}
|
|
242
|
+
md += '\n';
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Recommendations Section
|
|
246
|
+
if (data.recommendations.length > 0) {
|
|
247
|
+
md += `## Recommendations\n\n`;
|
|
248
|
+
|
|
249
|
+
for (let i = 0; i < Math.min(5, data.recommendations.length); i++) {
|
|
250
|
+
const rec = data.recommendations[i];
|
|
251
|
+
const emoji =
|
|
252
|
+
rec.priority === 'high'
|
|
253
|
+
? '\u{1F534}'
|
|
254
|
+
: rec.priority === 'medium'
|
|
255
|
+
? '\u{1F7E0}'
|
|
256
|
+
: '\u{1F7E1}';
|
|
257
|
+
|
|
258
|
+
md += `${i + 1}. ${emoji} **${rec.title}**\n`;
|
|
259
|
+
md += ` ${rec.message}\n`;
|
|
260
|
+
if (rec.action) {
|
|
261
|
+
md += ` *Action: \`${rec.action}\`*\n`;
|
|
262
|
+
}
|
|
263
|
+
md += '\n';
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Quick Stats
|
|
268
|
+
md += `## Quick Stats\n\n`;
|
|
269
|
+
md += `\`\`\`\n`;
|
|
270
|
+
md += `High-confidence patterns: ${data.patterns.highConfidence.length}\n`;
|
|
271
|
+
md += `Emerging patterns: ${data.patterns.emerging.length}\n`;
|
|
272
|
+
md += `Trends improving: ${data.trends.improving.length}\n`;
|
|
273
|
+
md += `Trends worsening: ${data.trends.worsening.length}\n`;
|
|
274
|
+
md += `Active recommendations: ${data.recommendations.length}\n`;
|
|
275
|
+
md += `\`\`\`\n\n`;
|
|
276
|
+
|
|
277
|
+
// Footer
|
|
278
|
+
md += `---\n\n`;
|
|
279
|
+
md += `*This digest was automatically generated by the CloudStream knowledge aggregation system.*\n`;
|
|
280
|
+
md += `*Run \`/aggregate\` to refresh data or \`/recommendations\` for full list.*\n`;
|
|
281
|
+
|
|
282
|
+
return md;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Save digest to file
|
|
287
|
+
*/
|
|
288
|
+
function saveDigest(content, options) {
|
|
289
|
+
const reportsDir = path.join(getClaudeDir(), 'knowledge', 'reports');
|
|
290
|
+
ensureDir(reportsDir);
|
|
291
|
+
|
|
292
|
+
const date = getDateString();
|
|
293
|
+
const filename = `weekly-digest-${date}.md`;
|
|
294
|
+
const filepath = path.join(reportsDir, filename);
|
|
295
|
+
|
|
296
|
+
writeFile(filepath, content);
|
|
297
|
+
|
|
298
|
+
return filepath;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Load aggregated data or run fresh analysis
|
|
303
|
+
*/
|
|
304
|
+
function loadOrAnalyze(options) {
|
|
305
|
+
// Try to load existing aggregated data
|
|
306
|
+
const existing = getAggregatedData();
|
|
307
|
+
|
|
308
|
+
if (existing && existing.patternLibrary) {
|
|
309
|
+
log('[Digest] Using existing aggregated data');
|
|
310
|
+
|
|
311
|
+
return {
|
|
312
|
+
summary: existing.summary || { sessionCount: 0, correctionCount: 0 },
|
|
313
|
+
patterns: existing.patternLibrary || { highConfidence: [], emerging: [] },
|
|
314
|
+
trends: existing.trendAnalysis || { improving: [], worsening: [], new: [] },
|
|
315
|
+
skillMatrix: existing.skillCorrectionMatrix || {},
|
|
316
|
+
techPatterns: existing.contextPatterns?.techPatterns || {},
|
|
317
|
+
recommendations: existing.recommendations || [],
|
|
318
|
+
skillApplications: 'N/A',
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Run fresh analysis
|
|
323
|
+
log('[Digest] Running fresh analysis...');
|
|
324
|
+
|
|
325
|
+
const { sessions, corrections, summary } = analyzeAllSessions();
|
|
326
|
+
|
|
327
|
+
if (summary.insufficient) {
|
|
328
|
+
return null;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const patterns = detectCrossSessionPatterns(3);
|
|
332
|
+
const trends = analyzeTrends(options.days);
|
|
333
|
+
const skillMatrix = buildSkillCorrectionMatrix();
|
|
334
|
+
const techPatterns = analyzeByTechnology();
|
|
335
|
+
const recommendations = getSessionStartRecommendations(10);
|
|
336
|
+
|
|
337
|
+
return {
|
|
338
|
+
summary,
|
|
339
|
+
patterns,
|
|
340
|
+
trends,
|
|
341
|
+
skillMatrix,
|
|
342
|
+
techPatterns,
|
|
343
|
+
recommendations,
|
|
344
|
+
skillApplications: 'N/A',
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Main function
|
|
350
|
+
*/
|
|
351
|
+
async function main() {
|
|
352
|
+
const options = parseArgs();
|
|
353
|
+
|
|
354
|
+
log(`[Digest] Generating weekly digest (${options.days} day window)...`);
|
|
355
|
+
|
|
356
|
+
// Load or analyze data
|
|
357
|
+
const data = loadOrAnalyze(options);
|
|
358
|
+
|
|
359
|
+
if (!data) {
|
|
360
|
+
log('[Digest] Insufficient data for digest. Need at least 5 sessions.');
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Generate digest content
|
|
365
|
+
const content = generateDigest(data, options);
|
|
366
|
+
|
|
367
|
+
// Save to file
|
|
368
|
+
const filepath = saveDigest(content, options);
|
|
369
|
+
log(`[Digest] Saved to: ${filepath}`);
|
|
370
|
+
|
|
371
|
+
// Output to console as well
|
|
372
|
+
console.log('\n' + '='.repeat(60));
|
|
373
|
+
console.log(content);
|
|
374
|
+
console.log('='.repeat(60) + '\n');
|
|
375
|
+
|
|
376
|
+
// Email notification (if configured and requested)
|
|
377
|
+
if (options.email) {
|
|
378
|
+
log('[Digest] Email notification not yet implemented');
|
|
379
|
+
// Future: integrate with notification system
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
log('[Digest] Done');
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// Run if called directly
|
|
386
|
+
if (require.main === module) {
|
|
387
|
+
main().catch((err) => {
|
|
388
|
+
log(`[Digest] Error: ${err.message}`);
|
|
389
|
+
process.exit(1);
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
module.exports = { generateDigest, saveDigest, loadOrAnalyze };
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Health Check Script for Everything Claude Code
|
|
5
|
+
* Verifies system configuration and reports status
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const {
|
|
11
|
+
getClaudeDir,
|
|
12
|
+
getHomeDir,
|
|
13
|
+
commandExists,
|
|
14
|
+
runCommand,
|
|
15
|
+
readFile,
|
|
16
|
+
log,
|
|
17
|
+
isWindows,
|
|
18
|
+
} = require('./lib/utils');
|
|
19
|
+
|
|
20
|
+
// Status indicators
|
|
21
|
+
const OK = '[OK]';
|
|
22
|
+
const WARN = '[WARN]';
|
|
23
|
+
const FAIL = '[FAIL]';
|
|
24
|
+
const SKIP = '[SKIP]';
|
|
25
|
+
|
|
26
|
+
// Track overall status
|
|
27
|
+
let overallStatus = 'PASS';
|
|
28
|
+
const issues = [];
|
|
29
|
+
|
|
30
|
+
function setStatus(status) {
|
|
31
|
+
if (status === 'FAIL') overallStatus = 'FAIL';
|
|
32
|
+
else if (status === 'WARN' && overallStatus !== 'FAIL') overallStatus = 'WARN';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function check(name, condition, warnOnly = false) {
|
|
36
|
+
if (condition.success) {
|
|
37
|
+
return { status: OK, message: condition.message || 'OK' };
|
|
38
|
+
} else {
|
|
39
|
+
const status = warnOnly ? WARN : FAIL;
|
|
40
|
+
setStatus(warnOnly ? 'WARN' : 'FAIL');
|
|
41
|
+
issues.push(`${name}: ${condition.message}`);
|
|
42
|
+
return { status, message: condition.message };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function padRight(str, len) {
|
|
47
|
+
return str.padEnd(len);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Environment Checks
|
|
51
|
+
function checkNodeVersion() {
|
|
52
|
+
const version = process.version;
|
|
53
|
+
const major = parseInt(version.slice(1).split('.')[0], 10);
|
|
54
|
+
return {
|
|
55
|
+
success: major >= 18,
|
|
56
|
+
message: major >= 18 ? version : `${version} (requires 18+)`,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function checkPackageManager() {
|
|
61
|
+
if (commandExists('npm')) {
|
|
62
|
+
return { success: true, message: 'npm' };
|
|
63
|
+
} else if (commandExists('yarn')) {
|
|
64
|
+
return { success: true, message: 'yarn' };
|
|
65
|
+
} else if (commandExists('pnpm')) {
|
|
66
|
+
return { success: true, message: 'pnpm' };
|
|
67
|
+
}
|
|
68
|
+
return { success: false, message: 'No package manager found' };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function checkGitRepo() {
|
|
72
|
+
const result = runCommand('git rev-parse --git-dir');
|
|
73
|
+
if (!result.success) {
|
|
74
|
+
return { success: true, message: 'Not a git repo (OK)' };
|
|
75
|
+
}
|
|
76
|
+
const statusResult = runCommand('git status --porcelain');
|
|
77
|
+
if (statusResult.success) {
|
|
78
|
+
const changes = statusResult.output.trim();
|
|
79
|
+
if (changes === '') {
|
|
80
|
+
return { success: true, message: 'Clean' };
|
|
81
|
+
}
|
|
82
|
+
const lines = changes.split('\n').filter(Boolean);
|
|
83
|
+
return { success: true, message: `${lines.length} uncommitted changes` };
|
|
84
|
+
}
|
|
85
|
+
return { success: true, message: 'OK' };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Claude State Checks
|
|
89
|
+
function checkClaudeDir() {
|
|
90
|
+
const claudeDir = getClaudeDir();
|
|
91
|
+
if (!fs.existsSync(claudeDir)) {
|
|
92
|
+
return { success: false, message: 'Directory not found' };
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
const testFile = path.join(claudeDir, '.health-check-test');
|
|
96
|
+
fs.writeFileSync(testFile, 'test');
|
|
97
|
+
fs.unlinkSync(testFile);
|
|
98
|
+
return { success: true, message: 'Writable' };
|
|
99
|
+
} catch {
|
|
100
|
+
return { success: false, message: 'Not writable' };
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function checkSessionMemory() {
|
|
105
|
+
const memoryFile = path.join(getClaudeDir(), 'memory', 'session-memory.json');
|
|
106
|
+
if (!fs.existsSync(memoryFile)) {
|
|
107
|
+
return { success: true, message: 'Not created yet (OK)' };
|
|
108
|
+
}
|
|
109
|
+
try {
|
|
110
|
+
const content = readFile(memoryFile);
|
|
111
|
+
JSON.parse(content);
|
|
112
|
+
return { success: true, message: 'Valid' };
|
|
113
|
+
} catch {
|
|
114
|
+
return { success: false, message: 'Invalid JSON' };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function checkHooks() {
|
|
119
|
+
const hooksFile = path.join(process.cwd(), 'hooks', 'hooks.json');
|
|
120
|
+
if (!fs.existsSync(hooksFile)) {
|
|
121
|
+
return { success: false, message: 'hooks.json not found' };
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
const content = readFile(hooksFile);
|
|
125
|
+
const hooks = JSON.parse(content);
|
|
126
|
+
const count = hooks.hooks ? hooks.hooks.length : 0;
|
|
127
|
+
return { success: true, message: `${count} configured` };
|
|
128
|
+
} catch {
|
|
129
|
+
return { success: false, message: 'Invalid JSON' };
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Plugin State Checks
|
|
134
|
+
function checkDirectory(name, dirPath) {
|
|
135
|
+
if (!fs.existsSync(dirPath)) {
|
|
136
|
+
return { success: false, message: 'Not found' };
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
const files = fs.readdirSync(dirPath).filter((f) => f.endsWith('.md'));
|
|
140
|
+
return { success: true, message: `${files.length} found` };
|
|
141
|
+
} catch {
|
|
142
|
+
return { success: false, message: 'Cannot read' };
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// MCP Checks (optional)
|
|
147
|
+
function checkMCPConfig(mcpName) {
|
|
148
|
+
const claudeDir = getClaudeDir();
|
|
149
|
+
const settingsFiles = [
|
|
150
|
+
path.join(claudeDir, 'settings.json'),
|
|
151
|
+
path.join(claudeDir, 'claude_desktop_config.json'),
|
|
152
|
+
];
|
|
153
|
+
|
|
154
|
+
for (const settingsFile of settingsFiles) {
|
|
155
|
+
if (fs.existsSync(settingsFile)) {
|
|
156
|
+
try {
|
|
157
|
+
const content = readFile(settingsFile);
|
|
158
|
+
const settings = JSON.parse(content);
|
|
159
|
+
if (settings.mcpServers && settings.mcpServers[mcpName]) {
|
|
160
|
+
return { success: true, message: 'Configured' };
|
|
161
|
+
}
|
|
162
|
+
} catch {
|
|
163
|
+
// Continue checking other files
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return { success: false, message: 'Not configured' };
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function runHealthCheck(options = {}) {
|
|
171
|
+
const { quick = false, verbose = false } = options;
|
|
172
|
+
|
|
173
|
+
log('');
|
|
174
|
+
log('Running health check...');
|
|
175
|
+
log('');
|
|
176
|
+
|
|
177
|
+
// Environment
|
|
178
|
+
log('Environment:');
|
|
179
|
+
const nodeResult = check('Node.js', checkNodeVersion());
|
|
180
|
+
log(` ${padRight('Node.js:', 16)} ${nodeResult.status} ${nodeResult.message}`);
|
|
181
|
+
|
|
182
|
+
const pkgResult = check('Package Manager', checkPackageManager());
|
|
183
|
+
log(` ${padRight('Package Mgr:', 16)} ${pkgResult.status} ${pkgResult.message}`);
|
|
184
|
+
|
|
185
|
+
if (!quick) {
|
|
186
|
+
const gitResult = check('Git Repo', checkGitRepo(), true);
|
|
187
|
+
log(` ${padRight('Git Repo:', 16)} ${gitResult.status} ${gitResult.message}`);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
log('');
|
|
191
|
+
|
|
192
|
+
// Claude State
|
|
193
|
+
log('Claude State:');
|
|
194
|
+
const claudeDirResult = check('~/.claude/', checkClaudeDir());
|
|
195
|
+
log(` ${padRight('~/.claude/:', 16)} ${claudeDirResult.status} ${claudeDirResult.message}`);
|
|
196
|
+
|
|
197
|
+
const memoryResult = check('Session Memory', checkSessionMemory(), true);
|
|
198
|
+
log(` ${padRight('Session Memory:', 16)} ${memoryResult.status} ${memoryResult.message}`);
|
|
199
|
+
|
|
200
|
+
const hooksResult = check('Hooks', checkHooks());
|
|
201
|
+
log(` ${padRight('Hooks:', 16)} ${hooksResult.status} ${hooksResult.message}`);
|
|
202
|
+
|
|
203
|
+
log('');
|
|
204
|
+
|
|
205
|
+
// Plugin State
|
|
206
|
+
if (!quick) {
|
|
207
|
+
log('Plugin:');
|
|
208
|
+
const commandsDir = path.join(process.cwd(), 'commands');
|
|
209
|
+
const commandsResult = check('Commands', checkDirectory('Commands', commandsDir));
|
|
210
|
+
log(` ${padRight('Commands:', 16)} ${commandsResult.status} ${commandsResult.message}`);
|
|
211
|
+
|
|
212
|
+
const skillsDir = path.join(process.cwd(), 'skills');
|
|
213
|
+
const skillsResult = check('Skills', checkDirectory('Skills', skillsDir));
|
|
214
|
+
log(` ${padRight('Skills:', 16)} ${skillsResult.status} ${skillsResult.message}`);
|
|
215
|
+
|
|
216
|
+
const agentsDir = path.join(process.cwd(), 'agents');
|
|
217
|
+
const agentsResult = check('Agents', checkDirectory('Agents', agentsDir));
|
|
218
|
+
log(` ${padRight('Agents:', 16)} ${agentsResult.status} ${agentsResult.message}`);
|
|
219
|
+
|
|
220
|
+
log('');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// MCPs (optional - warnings only)
|
|
224
|
+
if (!quick) {
|
|
225
|
+
log('MCPs (optional):');
|
|
226
|
+
const memoryMCP = check('memory MCP', checkMCPConfig('memory'), true);
|
|
227
|
+
log(` ${padRight('memory:', 16)} ${memoryMCP.status} ${memoryMCP.message}`);
|
|
228
|
+
|
|
229
|
+
const context7MCP = check('context7 MCP', checkMCPConfig('context7'), true);
|
|
230
|
+
log(` ${padRight('context7:', 16)} ${context7MCP.status} ${context7MCP.message}`);
|
|
231
|
+
|
|
232
|
+
log('');
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Summary
|
|
236
|
+
log('─'.repeat(50));
|
|
237
|
+
log('');
|
|
238
|
+
|
|
239
|
+
if (overallStatus === 'PASS') {
|
|
240
|
+
log('HEALTH CHECK: PASS');
|
|
241
|
+
log('');
|
|
242
|
+
log('All systems operational. Ready to use Everything Claude Code.');
|
|
243
|
+
} else if (overallStatus === 'WARN') {
|
|
244
|
+
log('HEALTH CHECK: WARN');
|
|
245
|
+
log('');
|
|
246
|
+
log('System is functional but has warnings:');
|
|
247
|
+
issues.forEach((issue) => log(` - ${issue}`));
|
|
248
|
+
} else {
|
|
249
|
+
log('HEALTH CHECK: FAIL');
|
|
250
|
+
log('');
|
|
251
|
+
log('Critical issues found:');
|
|
252
|
+
issues.forEach((issue) => log(` - ${issue}`));
|
|
253
|
+
log('');
|
|
254
|
+
log('Run /diagnose for detailed troubleshooting.');
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
log('');
|
|
258
|
+
|
|
259
|
+
// Exit with appropriate code for CI/CD
|
|
260
|
+
process.exit(overallStatus === 'FAIL' ? 1 : 0);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Parse arguments
|
|
264
|
+
const args = process.argv.slice(2);
|
|
265
|
+
const options = {
|
|
266
|
+
quick: args.includes('--quick'),
|
|
267
|
+
verbose: args.includes('--verbose'),
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
runHealthCheck(options);
|