@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.
Files changed (190) hide show
  1. package/README.md +152 -37
  2. package/agents/INDEX.md +183 -0
  3. package/agents/architect.md +247 -0
  4. package/agents/build-error-resolver.md +555 -0
  5. package/agents/catalyst-deployer.md +132 -0
  6. package/agents/code-reviewer.md +121 -0
  7. package/agents/compliance-auditor.md +148 -0
  8. package/agents/creator-architect.md +395 -0
  9. package/agents/deluge-reviewer.md +98 -0
  10. package/agents/doc-updater.md +471 -0
  11. package/agents/e2e-runner.md +711 -0
  12. package/agents/planner.md +122 -0
  13. package/agents/refactor-cleaner.md +309 -0
  14. package/agents/security-reviewer.md +582 -0
  15. package/agents/tdd-guide.md +302 -0
  16. package/bin/cloudstream-setup.js +16 -6
  17. package/config/versions.json +63 -0
  18. package/dist/hooks/hooks.json +209 -0
  19. package/dist/index.js +47 -0
  20. package/dist/lib/asset-value.js +609 -0
  21. package/dist/lib/client-manager.js +300 -0
  22. package/dist/lib/command-matcher.js +242 -0
  23. package/dist/lib/cross-session-patterns.js +754 -0
  24. package/dist/lib/intent-classifier.js +1075 -0
  25. package/dist/lib/package-manager.js +374 -0
  26. package/dist/lib/recommendation-engine.js +597 -0
  27. package/dist/lib/session-memory.js +489 -0
  28. package/dist/lib/skill-effectiveness.js +486 -0
  29. package/dist/lib/skill-matcher.js +595 -0
  30. package/dist/lib/tutorial-metrics.js +242 -0
  31. package/dist/lib/tutorial-progress.js +209 -0
  32. package/dist/lib/tutorial-renderer.js +431 -0
  33. package/dist/lib/utils.js +380 -0
  34. package/dist/lib/verify-formatter.js +143 -0
  35. package/dist/lib/workflow-state.js +249 -0
  36. package/hooks/hooks.json +209 -0
  37. package/package.json +5 -1
  38. package/scripts/aggregate-sessions.js +290 -0
  39. package/scripts/branch-name-validator.js +291 -0
  40. package/scripts/build.js +101 -0
  41. package/scripts/commands/client-switch.js +231 -0
  42. package/scripts/deprecate-skill.js +610 -0
  43. package/scripts/diagnose.js +324 -0
  44. package/scripts/doc-freshness.js +168 -0
  45. package/scripts/generate-weekly-digest.js +393 -0
  46. package/scripts/health-check.js +270 -0
  47. package/scripts/hooks/credential-check.js +101 -0
  48. package/scripts/hooks/evaluate-session.js +81 -0
  49. package/scripts/hooks/pre-compact.js +66 -0
  50. package/scripts/hooks/prompt-analyzer.js +276 -0
  51. package/scripts/hooks/prompt-router.js +422 -0
  52. package/scripts/hooks/quality-gate-enforcer.js +371 -0
  53. package/scripts/hooks/session-end.js +156 -0
  54. package/scripts/hooks/session-start.js +195 -0
  55. package/scripts/hooks/skill-injector.js +333 -0
  56. package/scripts/hooks/suggest-compact.js +58 -0
  57. package/scripts/lib/asset-value.js +609 -0
  58. package/scripts/lib/client-manager.js +300 -0
  59. package/scripts/lib/command-matcher.js +242 -0
  60. package/scripts/lib/cross-session-patterns.js +754 -0
  61. package/scripts/lib/intent-classifier.js +1075 -0
  62. package/scripts/lib/package-manager.js +374 -0
  63. package/scripts/lib/recommendation-engine.js +597 -0
  64. package/scripts/lib/session-memory.js +489 -0
  65. package/scripts/lib/skill-effectiveness.js +486 -0
  66. package/scripts/lib/skill-matcher.js +595 -0
  67. package/scripts/lib/tutorial-metrics.js +242 -0
  68. package/scripts/lib/tutorial-progress.js +209 -0
  69. package/scripts/lib/tutorial-renderer.js +431 -0
  70. package/scripts/lib/utils.js +380 -0
  71. package/scripts/lib/verify-formatter.js +143 -0
  72. package/scripts/lib/workflow-state.js +249 -0
  73. package/scripts/onboard.js +363 -0
  74. package/scripts/quarterly-report.js +692 -0
  75. package/scripts/setup-package-manager.js +204 -0
  76. package/scripts/sync-upstream.js +391 -0
  77. package/scripts/test.js +108 -0
  78. package/scripts/tutorial-runner.js +351 -0
  79. package/scripts/validate-all.js +201 -0
  80. package/scripts/verifiers/agents.js +245 -0
  81. package/scripts/verifiers/config.js +186 -0
  82. package/scripts/verifiers/environment.js +123 -0
  83. package/scripts/verifiers/hooks.js +188 -0
  84. package/scripts/verifiers/index.js +38 -0
  85. package/scripts/verifiers/persistence.js +140 -0
  86. package/scripts/verifiers/plugin.js +215 -0
  87. package/scripts/verifiers/skills.js +209 -0
  88. package/scripts/verify-setup.js +164 -0
  89. package/skills/INDEX.md +157 -0
  90. package/skills/backend-patterns/SKILL.md +586 -0
  91. package/skills/backend-patterns/catalyst-patterns.md +128 -0
  92. package/skills/bigquery-patterns/SKILL.md +27 -0
  93. package/skills/bigquery-patterns/performance-optimization.md +518 -0
  94. package/skills/bigquery-patterns/query-patterns.md +372 -0
  95. package/skills/bigquery-patterns/schema-design.md +78 -0
  96. package/skills/cloudstream-project-template/SKILL.md +20 -0
  97. package/skills/cloudstream-project-template/structure.md +65 -0
  98. package/skills/coding-standards/SKILL.md +524 -0
  99. package/skills/coding-standards/deluge-standards.md +83 -0
  100. package/skills/compliance-patterns/SKILL.md +28 -0
  101. package/skills/compliance-patterns/hipaa/audit-requirements.md +251 -0
  102. package/skills/compliance-patterns/hipaa/baa-process.md +298 -0
  103. package/skills/compliance-patterns/hipaa/data-archival-strategy.md +387 -0
  104. package/skills/compliance-patterns/hipaa/phi-handling.md +52 -0
  105. package/skills/compliance-patterns/pci-dss/saq-a-requirements.md +307 -0
  106. package/skills/compliance-patterns/pci-dss/tokenization-patterns.md +382 -0
  107. package/skills/compliance-patterns/pci-dss/zoho-checkout-patterns.md +56 -0
  108. package/skills/compliance-patterns/soc2/access-controls.md +344 -0
  109. package/skills/compliance-patterns/soc2/audit-logging.md +458 -0
  110. package/skills/compliance-patterns/soc2/change-management.md +403 -0
  111. package/skills/compliance-patterns/soc2/deluge-execution-logging.md +407 -0
  112. package/skills/consultancy-workflows/SKILL.md +19 -0
  113. package/skills/consultancy-workflows/client-isolation.md +21 -0
  114. package/skills/consultancy-workflows/documentation-automation.md +454 -0
  115. package/skills/consultancy-workflows/handoff-procedures.md +257 -0
  116. package/skills/consultancy-workflows/knowledge-capture.md +513 -0
  117. package/skills/consultancy-workflows/time-tracking.md +26 -0
  118. package/skills/continuous-learning/SKILL.md +84 -0
  119. package/skills/continuous-learning/config.json +18 -0
  120. package/skills/continuous-learning/evaluate-session.sh +60 -0
  121. package/skills/continuous-learning-v2/SKILL.md +126 -0
  122. package/skills/continuous-learning-v2/config.json +61 -0
  123. package/skills/frontend-patterns/SKILL.md +635 -0
  124. package/skills/frontend-patterns/zoho-widget-patterns.md +103 -0
  125. package/skills/gcp-data-engineering/SKILL.md +36 -0
  126. package/skills/gcp-data-engineering/bigquery/performance-optimization.md +337 -0
  127. package/skills/gcp-data-engineering/dataflow/error-handling.md +496 -0
  128. package/skills/gcp-data-engineering/dataflow/pipeline-patterns.md +444 -0
  129. package/skills/gcp-data-engineering/dbt/model-organization.md +63 -0
  130. package/skills/gcp-data-engineering/dbt/testing-patterns.md +503 -0
  131. package/skills/gcp-data-engineering/medallion-architecture/bronze-layer.md +60 -0
  132. package/skills/gcp-data-engineering/medallion-architecture/gold-layer.md +311 -0
  133. package/skills/gcp-data-engineering/medallion-architecture/layer-transitions.md +517 -0
  134. package/skills/gcp-data-engineering/medallion-architecture/silver-layer.md +305 -0
  135. package/skills/gcp-data-engineering/zoho-to-gcp/data-extraction.md +543 -0
  136. package/skills/gcp-data-engineering/zoho-to-gcp/real-time-vs-batch.md +337 -0
  137. package/skills/security-review/SKILL.md +498 -0
  138. package/skills/security-review/compliance-checklist.md +53 -0
  139. package/skills/strategic-compact/SKILL.md +67 -0
  140. package/skills/tdd-workflow/SKILL.md +413 -0
  141. package/skills/tdd-workflow/zoho-testing.md +124 -0
  142. package/skills/tutorial/SKILL.md +249 -0
  143. package/skills/tutorial/docs/ACCESSIBILITY.md +169 -0
  144. package/skills/tutorial/lessons/00-philosophy-and-workflow.md +198 -0
  145. package/skills/tutorial/lessons/01-basics.md +81 -0
  146. package/skills/tutorial/lessons/02-training.md +86 -0
  147. package/skills/tutorial/lessons/03-commands.md +109 -0
  148. package/skills/tutorial/lessons/04-workflows.md +115 -0
  149. package/skills/tutorial/lessons/05-compliance.md +116 -0
  150. package/skills/tutorial/lessons/06-zoho.md +121 -0
  151. package/skills/tutorial/lessons/07-hooks-system.md +277 -0
  152. package/skills/tutorial/lessons/08-mcp-servers.md +316 -0
  153. package/skills/tutorial/lessons/09-client-management.md +215 -0
  154. package/skills/tutorial/lessons/10-testing-e2e.md +260 -0
  155. package/skills/tutorial/lessons/11-skills-deep-dive.md +272 -0
  156. package/skills/tutorial/lessons/12-rules-system.md +326 -0
  157. package/skills/tutorial/lessons/13-golden-standard-graduation.md +213 -0
  158. package/skills/tutorial/lessons/14-fork-setup-and-sync.md +312 -0
  159. package/skills/tutorial/lessons/15-living-examples-system.md +221 -0
  160. package/skills/tutorial/tracks/accelerated/README.md +134 -0
  161. package/skills/tutorial/tracks/accelerated/assessment/checkpoint-1.md +161 -0
  162. package/skills/tutorial/tracks/accelerated/assessment/checkpoint-2.md +175 -0
  163. package/skills/tutorial/tracks/accelerated/day-1-core-concepts.md +234 -0
  164. package/skills/tutorial/tracks/accelerated/day-2-essential-commands.md +270 -0
  165. package/skills/tutorial/tracks/accelerated/day-3-workflow-mastery.md +305 -0
  166. package/skills/tutorial/tracks/accelerated/day-4-compliance-zoho.md +304 -0
  167. package/skills/tutorial/tracks/accelerated/day-5-hooks-skills.md +344 -0
  168. package/skills/tutorial/tracks/accelerated/day-6-client-testing.md +386 -0
  169. package/skills/tutorial/tracks/accelerated/day-7-graduation.md +369 -0
  170. package/skills/zoho-patterns/CHANGELOG.md +108 -0
  171. package/skills/zoho-patterns/SKILL.md +446 -0
  172. package/skills/zoho-patterns/analytics/dashboard-patterns.md +352 -0
  173. package/skills/zoho-patterns/analytics/zoho-to-bigquery-pipeline.md +427 -0
  174. package/skills/zoho-patterns/catalyst/appsail-deployment.md +349 -0
  175. package/skills/zoho-patterns/catalyst/context-close-patterns.md +354 -0
  176. package/skills/zoho-patterns/catalyst/cron-batch-processing.md +374 -0
  177. package/skills/zoho-patterns/catalyst/function-patterns.md +439 -0
  178. package/skills/zoho-patterns/creator/form-design.md +304 -0
  179. package/skills/zoho-patterns/creator/publish-api-patterns.md +313 -0
  180. package/skills/zoho-patterns/creator/widget-integration.md +306 -0
  181. package/skills/zoho-patterns/creator/workflow-automation.md +253 -0
  182. package/skills/zoho-patterns/deluge/api-patterns.md +468 -0
  183. package/skills/zoho-patterns/deluge/batch-processing.md +403 -0
  184. package/skills/zoho-patterns/deluge/cross-app-integration.md +356 -0
  185. package/skills/zoho-patterns/deluge/error-handling.md +423 -0
  186. package/skills/zoho-patterns/deluge/syntax-reference.md +65 -0
  187. package/skills/zoho-patterns/integration/cors-proxy-architecture.md +426 -0
  188. package/skills/zoho-patterns/integration/crm-books-native-sync.md +277 -0
  189. package/skills/zoho-patterns/integration/oauth-token-management.md +461 -0
  190. 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
+ });