@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,692 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Quarterly Report Generator
|
|
4
|
+
*
|
|
5
|
+
* Generates comprehensive quarterly review report analyzing skill effectiveness,
|
|
6
|
+
* identifying deprecation/promotion candidates, and tracking knowledge asset value.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* npm run quarterly:report # Generate current quarter report
|
|
10
|
+
* npm run quarterly:report --json # Output as JSON
|
|
11
|
+
* npm run quarterly:report --verbose # Include per-skill details
|
|
12
|
+
* npm run quarterly:report --status # Show current quarter status only
|
|
13
|
+
*
|
|
14
|
+
* Output: ~/.claude/knowledge/reports/quarterly-Q[X]-[YEAR].md
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const fs = require('fs');
|
|
18
|
+
const path = require('path');
|
|
19
|
+
const os = require('os');
|
|
20
|
+
|
|
21
|
+
// Paths
|
|
22
|
+
const CLAUDE_DIR = path.join(os.homedir(), '.claude');
|
|
23
|
+
const KNOWLEDGE_DIR = path.join(CLAUDE_DIR, 'knowledge');
|
|
24
|
+
const REPORTS_DIR = path.join(KNOWLEDGE_DIR, 'reports');
|
|
25
|
+
const PLUGIN_ROOT = process.env.CLAUDE_PLUGIN_ROOT || path.join(__dirname, '..');
|
|
26
|
+
const VERSIONS_FILE = path.join(PLUGIN_ROOT, 'config', 'versions.json');
|
|
27
|
+
|
|
28
|
+
// Try to load optional dependencies
|
|
29
|
+
let skillEffectiveness, assetValue, crossSessionPatterns;
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
skillEffectiveness = require('./lib/skill-effectiveness');
|
|
33
|
+
} catch (e) {
|
|
34
|
+
skillEffectiveness = null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
assetValue = require('./lib/asset-value');
|
|
39
|
+
} catch (e) {
|
|
40
|
+
assetValue = null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
crossSessionPatterns = require('./lib/cross-session-patterns');
|
|
45
|
+
} catch (e) {
|
|
46
|
+
crossSessionPatterns = null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Ensure directories exist.
|
|
51
|
+
*/
|
|
52
|
+
function ensureDirectories() {
|
|
53
|
+
if (!fs.existsSync(CLAUDE_DIR)) {
|
|
54
|
+
fs.mkdirSync(CLAUDE_DIR, { recursive: true });
|
|
55
|
+
}
|
|
56
|
+
if (!fs.existsSync(KNOWLEDGE_DIR)) {
|
|
57
|
+
fs.mkdirSync(KNOWLEDGE_DIR, { recursive: true });
|
|
58
|
+
}
|
|
59
|
+
if (!fs.existsSync(REPORTS_DIR)) {
|
|
60
|
+
fs.mkdirSync(REPORTS_DIR, { recursive: true });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Parse command line arguments.
|
|
66
|
+
*/
|
|
67
|
+
function parseArgs() {
|
|
68
|
+
const args = process.argv.slice(2);
|
|
69
|
+
return {
|
|
70
|
+
json: args.includes('--json'),
|
|
71
|
+
verbose: args.includes('--verbose') || args.includes('-v'),
|
|
72
|
+
status: args.includes('--status'),
|
|
73
|
+
help: args.includes('--help') || args.includes('-h'),
|
|
74
|
+
quarter: args.find((a) => a.startsWith('--quarter='))?.split('=')[1],
|
|
75
|
+
year: args.find((a) => a.startsWith('--year='))?.split('=')[1],
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Get current quarter info.
|
|
81
|
+
*/
|
|
82
|
+
function getCurrentQuarter() {
|
|
83
|
+
const now = new Date();
|
|
84
|
+
const quarter = Math.ceil((now.getMonth() + 1) / 3);
|
|
85
|
+
const year = now.getFullYear();
|
|
86
|
+
return { quarter, year };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Get quarter date range.
|
|
91
|
+
*/
|
|
92
|
+
function getQuarterDateRange(quarter, year) {
|
|
93
|
+
const startMonth = (quarter - 1) * 3;
|
|
94
|
+
const start = new Date(year, startMonth, 1);
|
|
95
|
+
const end = new Date(year, startMonth + 3, 0);
|
|
96
|
+
return { start, end };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Load version registry.
|
|
101
|
+
*/
|
|
102
|
+
function loadVersionRegistry() {
|
|
103
|
+
try {
|
|
104
|
+
if (fs.existsSync(VERSIONS_FILE)) {
|
|
105
|
+
return JSON.parse(fs.readFileSync(VERSIONS_FILE, 'utf8'));
|
|
106
|
+
}
|
|
107
|
+
} catch (err) {
|
|
108
|
+
console.error(`[Quarterly] Warning: Could not load versions.json: ${err.message}`);
|
|
109
|
+
}
|
|
110
|
+
return { skills: {}, agents: {} };
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Load skill effectiveness data.
|
|
115
|
+
*/
|
|
116
|
+
function loadEffectivenessData() {
|
|
117
|
+
const effectivenessFile = path.join(KNOWLEDGE_DIR, 'skill-effectiveness.json');
|
|
118
|
+
try {
|
|
119
|
+
if (fs.existsSync(effectivenessFile)) {
|
|
120
|
+
return JSON.parse(fs.readFileSync(effectivenessFile, 'utf8'));
|
|
121
|
+
}
|
|
122
|
+
} catch (err) {
|
|
123
|
+
console.error(`[Quarterly] Warning: Could not load effectiveness data: ${err.message}`);
|
|
124
|
+
}
|
|
125
|
+
return { skills: {}, summary: {} };
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Analyze skill trends.
|
|
130
|
+
*/
|
|
131
|
+
function analyzeSkillTrends(effectivenessData, versions) {
|
|
132
|
+
const trends = {
|
|
133
|
+
improving: [],
|
|
134
|
+
declining: [],
|
|
135
|
+
stable: [],
|
|
136
|
+
new: [],
|
|
137
|
+
inactive: [],
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const allSkills = { ...versions.skills };
|
|
141
|
+
|
|
142
|
+
for (const [skillName, skillInfo] of Object.entries(allSkills)) {
|
|
143
|
+
const effectiveness = effectivenessData.skills?.[skillName];
|
|
144
|
+
|
|
145
|
+
if (!effectiveness || effectiveness.applicationCount === 0) {
|
|
146
|
+
// Check if truly new or just unused
|
|
147
|
+
if (skillInfo.introduced === versions.version) {
|
|
148
|
+
trends.new.push({ name: skillName, ...skillInfo });
|
|
149
|
+
} else {
|
|
150
|
+
trends.inactive.push({ name: skillName, ...skillInfo, daysSinceLastUse: 90 });
|
|
151
|
+
}
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const rate = effectiveness.effectivenessRate || 0;
|
|
156
|
+
const prevRate = effectiveness.previousQuarterRate || rate;
|
|
157
|
+
const change = rate - prevRate;
|
|
158
|
+
|
|
159
|
+
const skillData = {
|
|
160
|
+
name: skillName,
|
|
161
|
+
effectiveness: rate,
|
|
162
|
+
previousEffectiveness: prevRate,
|
|
163
|
+
change,
|
|
164
|
+
usageCount: effectiveness.applicationCount || 0,
|
|
165
|
+
...skillInfo,
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
if (change > 0.1) {
|
|
169
|
+
trends.improving.push(skillData);
|
|
170
|
+
} else if (change < -0.1) {
|
|
171
|
+
trends.declining.push(skillData);
|
|
172
|
+
} else {
|
|
173
|
+
trends.stable.push(skillData);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Sort by effectiveness
|
|
178
|
+
trends.improving.sort((a, b) => b.change - a.change);
|
|
179
|
+
trends.declining.sort((a, b) => a.change - b.change);
|
|
180
|
+
trends.stable.sort((a, b) => b.effectiveness - a.effectiveness);
|
|
181
|
+
|
|
182
|
+
return trends;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Identify deprecation candidates.
|
|
187
|
+
*/
|
|
188
|
+
function identifyDeprecationCandidates(effectivenessData, versions) {
|
|
189
|
+
const candidates = [];
|
|
190
|
+
const EFFECTIVENESS_THRESHOLD = 0.4;
|
|
191
|
+
const MIN_USES = 10;
|
|
192
|
+
const INACTIVE_DAYS = 90;
|
|
193
|
+
|
|
194
|
+
for (const [skillName, skillInfo] of Object.entries(versions.skills)) {
|
|
195
|
+
if (skillInfo.status === 'deprecated') continue;
|
|
196
|
+
|
|
197
|
+
const effectiveness = effectivenessData.skills?.[skillName];
|
|
198
|
+
|
|
199
|
+
// Check low effectiveness
|
|
200
|
+
if (effectiveness && effectiveness.applicationCount >= MIN_USES) {
|
|
201
|
+
const rate = effectiveness.effectivenessRate || 0;
|
|
202
|
+
if (rate < EFFECTIVENESS_THRESHOLD) {
|
|
203
|
+
candidates.push({
|
|
204
|
+
name: skillName,
|
|
205
|
+
reason: 'low_effectiveness',
|
|
206
|
+
effectiveness: rate,
|
|
207
|
+
usageCount: effectiveness.applicationCount,
|
|
208
|
+
justification: `Effectiveness ${(rate * 100).toFixed(0)}% after ${effectiveness.applicationCount} uses`,
|
|
209
|
+
severity: rate < 0.2 ? 'high' : 'medium',
|
|
210
|
+
});
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Check inactivity
|
|
216
|
+
if (!effectiveness || effectiveness.applicationCount === 0) {
|
|
217
|
+
const lastUsed = effectiveness?.lastUsed;
|
|
218
|
+
if (lastUsed) {
|
|
219
|
+
const daysSince = Math.floor(
|
|
220
|
+
(Date.now() - new Date(lastUsed).getTime()) / (1000 * 60 * 60 * 24)
|
|
221
|
+
);
|
|
222
|
+
if (daysSince > INACTIVE_DAYS) {
|
|
223
|
+
candidates.push({
|
|
224
|
+
name: skillName,
|
|
225
|
+
reason: 'inactive',
|
|
226
|
+
daysSinceLastUse: daysSince,
|
|
227
|
+
justification: `Not used in ${daysSince} days`,
|
|
228
|
+
severity: 'low',
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Sort by severity
|
|
236
|
+
const severityOrder = { high: 0, medium: 1, low: 2 };
|
|
237
|
+
candidates.sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]);
|
|
238
|
+
|
|
239
|
+
return candidates;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Identify promotion candidates.
|
|
244
|
+
*/
|
|
245
|
+
function identifyPromotionCandidates(effectivenessData) {
|
|
246
|
+
const candidates = [];
|
|
247
|
+
const EFFECTIVENESS_THRESHOLD = 0.9;
|
|
248
|
+
const MIN_USES = 20;
|
|
249
|
+
|
|
250
|
+
// Check learned skills
|
|
251
|
+
const learnedSkillsDir = path.join(CLAUDE_DIR, 'skills', 'learned');
|
|
252
|
+
if (fs.existsSync(learnedSkillsDir)) {
|
|
253
|
+
try {
|
|
254
|
+
const learnedSkills = fs.readdirSync(learnedSkillsDir).filter((f) => f.endsWith('.md'));
|
|
255
|
+
|
|
256
|
+
for (const skillFile of learnedSkills) {
|
|
257
|
+
const skillName = path.basename(skillFile, '.md');
|
|
258
|
+
const effectiveness = effectivenessData.skills?.[skillName];
|
|
259
|
+
|
|
260
|
+
if (effectiveness && effectiveness.applicationCount >= MIN_USES) {
|
|
261
|
+
const rate = effectiveness.effectivenessRate || 0;
|
|
262
|
+
if (rate >= EFFECTIVENESS_THRESHOLD) {
|
|
263
|
+
candidates.push({
|
|
264
|
+
name: skillName,
|
|
265
|
+
type: 'learned',
|
|
266
|
+
effectiveness: rate,
|
|
267
|
+
usageCount: effectiveness.applicationCount,
|
|
268
|
+
justification: `${(rate * 100).toFixed(0)}% effectiveness over ${effectiveness.applicationCount} uses`,
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
} catch (err) {
|
|
274
|
+
// Learned skills directory doesn't exist or is empty
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
candidates.sort((a, b) => b.effectiveness - a.effectiveness);
|
|
279
|
+
return candidates;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Get asset value summary.
|
|
284
|
+
*/
|
|
285
|
+
function getAssetValueSummary() {
|
|
286
|
+
if (assetValue && typeof assetValue.getAllAssetValues === 'function') {
|
|
287
|
+
try {
|
|
288
|
+
return assetValue.getAllAssetValues();
|
|
289
|
+
} catch (err) {
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Generate executive summary.
|
|
298
|
+
*/
|
|
299
|
+
function generateExecutiveSummary(data) {
|
|
300
|
+
const { trends, deprecationCandidates, promotionCandidates, assetSummary } = data;
|
|
301
|
+
|
|
302
|
+
const totalSkills =
|
|
303
|
+
trends.improving.length +
|
|
304
|
+
trends.declining.length +
|
|
305
|
+
trends.stable.length +
|
|
306
|
+
trends.new.length +
|
|
307
|
+
trends.inactive.length;
|
|
308
|
+
|
|
309
|
+
const avgEffectiveness =
|
|
310
|
+
[...trends.improving, ...trends.declining, ...trends.stable]
|
|
311
|
+
.filter((s) => s.effectiveness)
|
|
312
|
+
.reduce((sum, s) => sum + s.effectiveness, 0) /
|
|
313
|
+
Math.max([...trends.improving, ...trends.declining, ...trends.stable].length, 1) || 0;
|
|
314
|
+
|
|
315
|
+
return {
|
|
316
|
+
totalSkills,
|
|
317
|
+
avgEffectiveness,
|
|
318
|
+
improving: trends.improving.length,
|
|
319
|
+
declining: trends.declining.length,
|
|
320
|
+
stable: trends.stable.length,
|
|
321
|
+
inactive: trends.inactive.length,
|
|
322
|
+
deprecationCandidates: deprecationCandidates.length,
|
|
323
|
+
promotionCandidates: promotionCandidates.length,
|
|
324
|
+
totalAssetValue: assetSummary?.summary?.totalEstimatedValue || 0,
|
|
325
|
+
criticalActions: deprecationCandidates.filter((c) => c.severity === 'high').length,
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Generate markdown report.
|
|
331
|
+
*/
|
|
332
|
+
function generateMarkdownReport(data, options) {
|
|
333
|
+
const {
|
|
334
|
+
quarter,
|
|
335
|
+
year,
|
|
336
|
+
summary,
|
|
337
|
+
trends,
|
|
338
|
+
deprecationCandidates,
|
|
339
|
+
promotionCandidates,
|
|
340
|
+
assetSummary,
|
|
341
|
+
} = data;
|
|
342
|
+
|
|
343
|
+
const lines = [];
|
|
344
|
+
|
|
345
|
+
// Header
|
|
346
|
+
lines.push(`# Quarterly Review Report: Q${quarter} ${year}`);
|
|
347
|
+
lines.push('');
|
|
348
|
+
lines.push(`Generated: ${new Date().toISOString()}`);
|
|
349
|
+
lines.push('');
|
|
350
|
+
|
|
351
|
+
// Executive Summary
|
|
352
|
+
lines.push('## Executive Summary');
|
|
353
|
+
lines.push('');
|
|
354
|
+
lines.push('| Metric | Value |');
|
|
355
|
+
lines.push('|--------|-------|');
|
|
356
|
+
lines.push(`| Total Skills/Agents | ${summary.totalSkills} |`);
|
|
357
|
+
lines.push(`| Average Effectiveness | ${(summary.avgEffectiveness * 100).toFixed(0)}% |`);
|
|
358
|
+
lines.push(`| Improving | ${summary.improving} |`);
|
|
359
|
+
lines.push(`| Declining | ${summary.declining} |`);
|
|
360
|
+
lines.push(`| Stable | ${summary.stable} |`);
|
|
361
|
+
lines.push(`| Inactive (90+ days) | ${summary.inactive} |`);
|
|
362
|
+
lines.push(`| Deprecation Candidates | ${summary.deprecationCandidates} |`);
|
|
363
|
+
lines.push(`| Promotion Candidates | ${summary.promotionCandidates} |`);
|
|
364
|
+
if (summary.totalAssetValue > 0) {
|
|
365
|
+
lines.push(`| Total Asset Value | $${summary.totalAssetValue.toLocaleString()} |`);
|
|
366
|
+
}
|
|
367
|
+
lines.push('');
|
|
368
|
+
|
|
369
|
+
if (summary.criticalActions > 0) {
|
|
370
|
+
lines.push(
|
|
371
|
+
`> **Action Required:** ${summary.criticalActions} skill(s) require immediate attention.`
|
|
372
|
+
);
|
|
373
|
+
lines.push('');
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Skill Effectiveness Analysis
|
|
377
|
+
lines.push('## Skill Effectiveness Analysis');
|
|
378
|
+
lines.push('');
|
|
379
|
+
|
|
380
|
+
if (trends.improving.length > 0) {
|
|
381
|
+
lines.push('### Improving Skills');
|
|
382
|
+
lines.push('');
|
|
383
|
+
lines.push('| Skill | Effectiveness | Change | Uses |');
|
|
384
|
+
lines.push('|-------|--------------|--------|------|');
|
|
385
|
+
for (const skill of trends.improving.slice(0, 10)) {
|
|
386
|
+
const change =
|
|
387
|
+
skill.change > 0
|
|
388
|
+
? `+${(skill.change * 100).toFixed(0)}%`
|
|
389
|
+
: `${(skill.change * 100).toFixed(0)}%`;
|
|
390
|
+
lines.push(
|
|
391
|
+
`| ${skill.name} | ${(skill.effectiveness * 100).toFixed(0)}% | ${change} | ${skill.usageCount} |`
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
lines.push('');
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
if (trends.declining.length > 0) {
|
|
398
|
+
lines.push('### Declining Skills');
|
|
399
|
+
lines.push('');
|
|
400
|
+
lines.push('| Skill | Effectiveness | Change | Uses |');
|
|
401
|
+
lines.push('|-------|--------------|--------|------|');
|
|
402
|
+
for (const skill of trends.declining.slice(0, 10)) {
|
|
403
|
+
const change = `${(skill.change * 100).toFixed(0)}%`;
|
|
404
|
+
lines.push(
|
|
405
|
+
`| ${skill.name} | ${(skill.effectiveness * 100).toFixed(0)}% | ${change} | ${skill.usageCount} |`
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
lines.push('');
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
if (options.verbose && trends.stable.length > 0) {
|
|
412
|
+
lines.push('### Stable Skills');
|
|
413
|
+
lines.push('');
|
|
414
|
+
lines.push('| Skill | Effectiveness | Uses |');
|
|
415
|
+
lines.push('|-------|--------------|------|');
|
|
416
|
+
for (const skill of trends.stable) {
|
|
417
|
+
lines.push(
|
|
418
|
+
`| ${skill.name} | ${(skill.effectiveness * 100).toFixed(0)}% | ${skill.usageCount} |`
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
lines.push('');
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// Deprecation Recommendations
|
|
425
|
+
lines.push('## Deprecation Recommendations');
|
|
426
|
+
lines.push('');
|
|
427
|
+
|
|
428
|
+
if (deprecationCandidates.length === 0) {
|
|
429
|
+
lines.push('No deprecation candidates identified this quarter.');
|
|
430
|
+
lines.push('');
|
|
431
|
+
} else {
|
|
432
|
+
lines.push('| Skill | Reason | Severity | Justification |');
|
|
433
|
+
lines.push('|-------|--------|----------|---------------|');
|
|
434
|
+
for (const candidate of deprecationCandidates) {
|
|
435
|
+
const severityEmoji =
|
|
436
|
+
candidate.severity === 'high' ? '🔴' : candidate.severity === 'medium' ? '🟠' : '🟡';
|
|
437
|
+
lines.push(
|
|
438
|
+
`| ${candidate.name} | ${candidate.reason} | ${severityEmoji} ${candidate.severity} | ${candidate.justification} |`
|
|
439
|
+
);
|
|
440
|
+
}
|
|
441
|
+
lines.push('');
|
|
442
|
+
|
|
443
|
+
lines.push('### Deprecation Commands');
|
|
444
|
+
lines.push('');
|
|
445
|
+
lines.push('```bash');
|
|
446
|
+
for (const candidate of deprecationCandidates.filter((c) => c.severity === 'high')) {
|
|
447
|
+
lines.push(`npm run skill:deprecate ${candidate.name} --removal-target 2.0.0`);
|
|
448
|
+
}
|
|
449
|
+
lines.push('```');
|
|
450
|
+
lines.push('');
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// Promotion Recommendations
|
|
454
|
+
lines.push('## Promotion Recommendations');
|
|
455
|
+
lines.push('');
|
|
456
|
+
|
|
457
|
+
if (promotionCandidates.length === 0) {
|
|
458
|
+
lines.push('No promotion candidates identified this quarter.');
|
|
459
|
+
lines.push('');
|
|
460
|
+
} else {
|
|
461
|
+
lines.push('| Skill | Type | Effectiveness | Uses |');
|
|
462
|
+
lines.push('|-------|------|--------------|------|');
|
|
463
|
+
for (const candidate of promotionCandidates) {
|
|
464
|
+
lines.push(
|
|
465
|
+
`| ${candidate.name} | ${candidate.type} | ${(candidate.effectiveness * 100).toFixed(0)}% | ${candidate.usageCount} |`
|
|
466
|
+
);
|
|
467
|
+
}
|
|
468
|
+
lines.push('');
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// Asset Value Report
|
|
472
|
+
if (assetSummary && assetSummary.summary) {
|
|
473
|
+
lines.push('## Knowledge Asset Value');
|
|
474
|
+
lines.push('');
|
|
475
|
+
lines.push('| Category | Count | Value |');
|
|
476
|
+
lines.push('|----------|-------|-------|');
|
|
477
|
+
if (assetSummary.summary.byCategory) {
|
|
478
|
+
for (const [category, stats] of Object.entries(assetSummary.summary.byCategory)) {
|
|
479
|
+
if (stats.count > 0) {
|
|
480
|
+
lines.push(`| ${category} | ${stats.count} | $${stats.totalValue.toLocaleString()} |`);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
lines.push(
|
|
485
|
+
`| **Total** | **${assetSummary.summary.totalAssets}** | **$${assetSummary.summary.totalEstimatedValue.toLocaleString()}** |`
|
|
486
|
+
);
|
|
487
|
+
lines.push('');
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// Next Steps
|
|
491
|
+
lines.push('## Next Steps');
|
|
492
|
+
lines.push('');
|
|
493
|
+
lines.push('1. Review deprecation candidates in team meeting');
|
|
494
|
+
lines.push('2. Create migration guides for approved deprecations');
|
|
495
|
+
lines.push('3. Execute deprecations using `npm run skill:deprecate`');
|
|
496
|
+
lines.push('4. Update CHANGELOG.md with changes');
|
|
497
|
+
lines.push('5. Notify team of upcoming deprecations');
|
|
498
|
+
lines.push('');
|
|
499
|
+
|
|
500
|
+
// Footer
|
|
501
|
+
lines.push('---');
|
|
502
|
+
lines.push('');
|
|
503
|
+
lines.push('*Generated by CloudStream Claude Code Quarterly Report*');
|
|
504
|
+
lines.push('');
|
|
505
|
+
lines.push('See `docs/quarterly-review-process.md` for full review process documentation.');
|
|
506
|
+
|
|
507
|
+
return lines.join('\n');
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Output terminal report.
|
|
512
|
+
*/
|
|
513
|
+
function outputTerminal(data) {
|
|
514
|
+
const { quarter, year, summary, trends, deprecationCandidates, promotionCandidates } = data;
|
|
515
|
+
|
|
516
|
+
console.log('');
|
|
517
|
+
console.log('='.repeat(60));
|
|
518
|
+
console.log(` QUARTERLY REVIEW REPORT: Q${quarter} ${year}`);
|
|
519
|
+
console.log('='.repeat(60));
|
|
520
|
+
console.log('');
|
|
521
|
+
|
|
522
|
+
// Summary
|
|
523
|
+
console.log('EXECUTIVE SUMMARY');
|
|
524
|
+
console.log('-'.repeat(40));
|
|
525
|
+
console.log(` Total Skills/Agents: ${summary.totalSkills}`);
|
|
526
|
+
console.log(` Average Effectiveness: ${(summary.avgEffectiveness * 100).toFixed(0)}%`);
|
|
527
|
+
console.log(` Improving: ${summary.improving}`);
|
|
528
|
+
console.log(` Declining: ${summary.declining}`);
|
|
529
|
+
console.log(` Stable: ${summary.stable}`);
|
|
530
|
+
console.log(` Inactive (90+ days): ${summary.inactive}`);
|
|
531
|
+
console.log('');
|
|
532
|
+
|
|
533
|
+
// Deprecation candidates
|
|
534
|
+
if (deprecationCandidates.length > 0) {
|
|
535
|
+
console.log('DEPRECATION CANDIDATES');
|
|
536
|
+
console.log('-'.repeat(40));
|
|
537
|
+
for (const candidate of deprecationCandidates) {
|
|
538
|
+
const emoji =
|
|
539
|
+
candidate.severity === 'high' ? '[!]' : candidate.severity === 'medium' ? '[*]' : '[-]';
|
|
540
|
+
console.log(` ${emoji} ${candidate.name}`);
|
|
541
|
+
console.log(` ${candidate.justification}`);
|
|
542
|
+
}
|
|
543
|
+
console.log('');
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// Promotion candidates
|
|
547
|
+
if (promotionCandidates.length > 0) {
|
|
548
|
+
console.log('PROMOTION CANDIDATES');
|
|
549
|
+
console.log('-'.repeat(40));
|
|
550
|
+
for (const candidate of promotionCandidates) {
|
|
551
|
+
console.log(` [+] ${candidate.name}`);
|
|
552
|
+
console.log(` ${candidate.justification}`);
|
|
553
|
+
}
|
|
554
|
+
console.log('');
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
// Asset value
|
|
558
|
+
if (summary.totalAssetValue > 0) {
|
|
559
|
+
console.log('KNOWLEDGE ASSET VALUE');
|
|
560
|
+
console.log('-'.repeat(40));
|
|
561
|
+
console.log(` Total Value: $${summary.totalAssetValue.toLocaleString()}`);
|
|
562
|
+
console.log('');
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// Actions
|
|
566
|
+
if (summary.criticalActions > 0) {
|
|
567
|
+
console.log('ACTION REQUIRED');
|
|
568
|
+
console.log('-'.repeat(40));
|
|
569
|
+
console.log(` ${summary.criticalActions} skill(s) need immediate attention.`);
|
|
570
|
+
console.log(' Run with --verbose for details.');
|
|
571
|
+
console.log('');
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
console.log('Report saved to: ~/.claude/knowledge/reports/');
|
|
575
|
+
console.log('');
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Show status only.
|
|
580
|
+
*/
|
|
581
|
+
function showStatus(data) {
|
|
582
|
+
const { quarter, year, summary } = data;
|
|
583
|
+
|
|
584
|
+
console.log('');
|
|
585
|
+
console.log(`Quarterly Review Status: Q${quarter} ${year}`);
|
|
586
|
+
console.log('-'.repeat(40));
|
|
587
|
+
console.log(` Skills Analyzed: ${summary.totalSkills}`);
|
|
588
|
+
console.log(` Avg Effectiveness: ${(summary.avgEffectiveness * 100).toFixed(0)}%`);
|
|
589
|
+
console.log(` Deprecation Candidates: ${summary.deprecationCandidates}`);
|
|
590
|
+
console.log(` Promotion Candidates: ${summary.promotionCandidates}`);
|
|
591
|
+
console.log(` Critical Actions: ${summary.criticalActions}`);
|
|
592
|
+
console.log('');
|
|
593
|
+
console.log('Run `npm run quarterly:report` for full report.');
|
|
594
|
+
console.log('');
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Show help.
|
|
599
|
+
*/
|
|
600
|
+
function showHelp() {
|
|
601
|
+
console.log(`
|
|
602
|
+
Quarterly Report Generator
|
|
603
|
+
|
|
604
|
+
Usage:
|
|
605
|
+
npm run quarterly:report Generate current quarter report
|
|
606
|
+
npm run quarterly:report --json Output as JSON
|
|
607
|
+
npm run quarterly:report --verbose Include per-skill details
|
|
608
|
+
npm run quarterly:report --status Show current quarter status only
|
|
609
|
+
npm run quarterly:report --quarter=N Specify quarter (1-4)
|
|
610
|
+
npm run quarterly:report --year=YYYY Specify year
|
|
611
|
+
|
|
612
|
+
Output:
|
|
613
|
+
Report saved to: ~/.claude/knowledge/reports/quarterly-Q[X]-[YEAR].md
|
|
614
|
+
`);
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
/**
|
|
618
|
+
* Main entry point.
|
|
619
|
+
*/
|
|
620
|
+
async function main() {
|
|
621
|
+
const args = parseArgs();
|
|
622
|
+
|
|
623
|
+
if (args.help) {
|
|
624
|
+
showHelp();
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
ensureDirectories();
|
|
629
|
+
|
|
630
|
+
// Determine quarter
|
|
631
|
+
const current = getCurrentQuarter();
|
|
632
|
+
const quarter = args.quarter ? parseInt(args.quarter, 10) : current.quarter;
|
|
633
|
+
const year = args.year ? parseInt(args.year, 10) : current.year;
|
|
634
|
+
|
|
635
|
+
console.log(`[Quarterly] Generating report for Q${quarter} ${year}...`);
|
|
636
|
+
|
|
637
|
+
// Load data
|
|
638
|
+
const versions = loadVersionRegistry();
|
|
639
|
+
const effectivenessData = loadEffectivenessData();
|
|
640
|
+
|
|
641
|
+
// Analyze
|
|
642
|
+
const trends = analyzeSkillTrends(effectivenessData, versions);
|
|
643
|
+
const deprecationCandidates = identifyDeprecationCandidates(effectivenessData, versions);
|
|
644
|
+
const promotionCandidates = identifyPromotionCandidates(effectivenessData);
|
|
645
|
+
const assetSummary = getAssetValueSummary();
|
|
646
|
+
|
|
647
|
+
// Generate summary
|
|
648
|
+
const summary = generateExecutiveSummary({
|
|
649
|
+
trends,
|
|
650
|
+
deprecationCandidates,
|
|
651
|
+
promotionCandidates,
|
|
652
|
+
assetSummary,
|
|
653
|
+
});
|
|
654
|
+
|
|
655
|
+
const data = {
|
|
656
|
+
quarter,
|
|
657
|
+
year,
|
|
658
|
+
generatedAt: new Date().toISOString(),
|
|
659
|
+
summary,
|
|
660
|
+
trends,
|
|
661
|
+
deprecationCandidates,
|
|
662
|
+
promotionCandidates,
|
|
663
|
+
assetSummary,
|
|
664
|
+
};
|
|
665
|
+
|
|
666
|
+
// Output
|
|
667
|
+
if (args.status) {
|
|
668
|
+
showStatus(data);
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
if (args.json) {
|
|
673
|
+
console.log(JSON.stringify(data, null, 2));
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
// Generate and save markdown report
|
|
678
|
+
const markdown = generateMarkdownReport(data, args);
|
|
679
|
+
const reportFile = path.join(REPORTS_DIR, `quarterly-Q${quarter}-${year}.md`);
|
|
680
|
+
fs.writeFileSync(reportFile, markdown);
|
|
681
|
+
|
|
682
|
+
console.log(`[Quarterly] Report saved: ${reportFile}`);
|
|
683
|
+
|
|
684
|
+
// Also output to terminal
|
|
685
|
+
outputTerminal(data);
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// Run
|
|
689
|
+
main().catch((err) => {
|
|
690
|
+
console.error('[Quarterly] Error:', err.message);
|
|
691
|
+
process.exit(1);
|
|
692
|
+
});
|