@cloudstreamsoftware/claude-tools 1.0.0 → 1.1.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 (189) 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/config/versions.json +63 -0
  17. package/dist/hooks/hooks.json +209 -0
  18. package/dist/index.js +47 -0
  19. package/dist/lib/asset-value.js +609 -0
  20. package/dist/lib/client-manager.js +300 -0
  21. package/dist/lib/command-matcher.js +242 -0
  22. package/dist/lib/cross-session-patterns.js +754 -0
  23. package/dist/lib/intent-classifier.js +1075 -0
  24. package/dist/lib/package-manager.js +374 -0
  25. package/dist/lib/recommendation-engine.js +597 -0
  26. package/dist/lib/session-memory.js +489 -0
  27. package/dist/lib/skill-effectiveness.js +486 -0
  28. package/dist/lib/skill-matcher.js +595 -0
  29. package/dist/lib/tutorial-metrics.js +242 -0
  30. package/dist/lib/tutorial-progress.js +209 -0
  31. package/dist/lib/tutorial-renderer.js +431 -0
  32. package/dist/lib/utils.js +380 -0
  33. package/dist/lib/verify-formatter.js +143 -0
  34. package/dist/lib/workflow-state.js +249 -0
  35. package/hooks/hooks.json +209 -0
  36. package/package.json +5 -1
  37. package/scripts/aggregate-sessions.js +290 -0
  38. package/scripts/branch-name-validator.js +291 -0
  39. package/scripts/build.js +101 -0
  40. package/scripts/commands/client-switch.js +231 -0
  41. package/scripts/deprecate-skill.js +610 -0
  42. package/scripts/diagnose.js +324 -0
  43. package/scripts/doc-freshness.js +168 -0
  44. package/scripts/generate-weekly-digest.js +393 -0
  45. package/scripts/health-check.js +270 -0
  46. package/scripts/hooks/credential-check.js +101 -0
  47. package/scripts/hooks/evaluate-session.js +81 -0
  48. package/scripts/hooks/pre-compact.js +66 -0
  49. package/scripts/hooks/prompt-analyzer.js +276 -0
  50. package/scripts/hooks/prompt-router.js +422 -0
  51. package/scripts/hooks/quality-gate-enforcer.js +371 -0
  52. package/scripts/hooks/session-end.js +156 -0
  53. package/scripts/hooks/session-start.js +195 -0
  54. package/scripts/hooks/skill-injector.js +333 -0
  55. package/scripts/hooks/suggest-compact.js +58 -0
  56. package/scripts/lib/asset-value.js +609 -0
  57. package/scripts/lib/client-manager.js +300 -0
  58. package/scripts/lib/command-matcher.js +242 -0
  59. package/scripts/lib/cross-session-patterns.js +754 -0
  60. package/scripts/lib/intent-classifier.js +1075 -0
  61. package/scripts/lib/package-manager.js +374 -0
  62. package/scripts/lib/recommendation-engine.js +597 -0
  63. package/scripts/lib/session-memory.js +489 -0
  64. package/scripts/lib/skill-effectiveness.js +486 -0
  65. package/scripts/lib/skill-matcher.js +595 -0
  66. package/scripts/lib/tutorial-metrics.js +242 -0
  67. package/scripts/lib/tutorial-progress.js +209 -0
  68. package/scripts/lib/tutorial-renderer.js +431 -0
  69. package/scripts/lib/utils.js +380 -0
  70. package/scripts/lib/verify-formatter.js +143 -0
  71. package/scripts/lib/workflow-state.js +249 -0
  72. package/scripts/onboard.js +363 -0
  73. package/scripts/quarterly-report.js +692 -0
  74. package/scripts/setup-package-manager.js +204 -0
  75. package/scripts/sync-upstream.js +391 -0
  76. package/scripts/test.js +108 -0
  77. package/scripts/tutorial-runner.js +351 -0
  78. package/scripts/validate-all.js +201 -0
  79. package/scripts/verifiers/agents.js +245 -0
  80. package/scripts/verifiers/config.js +186 -0
  81. package/scripts/verifiers/environment.js +123 -0
  82. package/scripts/verifiers/hooks.js +188 -0
  83. package/scripts/verifiers/index.js +38 -0
  84. package/scripts/verifiers/persistence.js +140 -0
  85. package/scripts/verifiers/plugin.js +215 -0
  86. package/scripts/verifiers/skills.js +209 -0
  87. package/scripts/verify-setup.js +164 -0
  88. package/skills/INDEX.md +157 -0
  89. package/skills/backend-patterns/SKILL.md +586 -0
  90. package/skills/backend-patterns/catalyst-patterns.md +128 -0
  91. package/skills/bigquery-patterns/SKILL.md +27 -0
  92. package/skills/bigquery-patterns/performance-optimization.md +518 -0
  93. package/skills/bigquery-patterns/query-patterns.md +372 -0
  94. package/skills/bigquery-patterns/schema-design.md +78 -0
  95. package/skills/cloudstream-project-template/SKILL.md +20 -0
  96. package/skills/cloudstream-project-template/structure.md +65 -0
  97. package/skills/coding-standards/SKILL.md +524 -0
  98. package/skills/coding-standards/deluge-standards.md +83 -0
  99. package/skills/compliance-patterns/SKILL.md +28 -0
  100. package/skills/compliance-patterns/hipaa/audit-requirements.md +251 -0
  101. package/skills/compliance-patterns/hipaa/baa-process.md +298 -0
  102. package/skills/compliance-patterns/hipaa/data-archival-strategy.md +387 -0
  103. package/skills/compliance-patterns/hipaa/phi-handling.md +52 -0
  104. package/skills/compliance-patterns/pci-dss/saq-a-requirements.md +307 -0
  105. package/skills/compliance-patterns/pci-dss/tokenization-patterns.md +382 -0
  106. package/skills/compliance-patterns/pci-dss/zoho-checkout-patterns.md +56 -0
  107. package/skills/compliance-patterns/soc2/access-controls.md +344 -0
  108. package/skills/compliance-patterns/soc2/audit-logging.md +458 -0
  109. package/skills/compliance-patterns/soc2/change-management.md +403 -0
  110. package/skills/compliance-patterns/soc2/deluge-execution-logging.md +407 -0
  111. package/skills/consultancy-workflows/SKILL.md +19 -0
  112. package/skills/consultancy-workflows/client-isolation.md +21 -0
  113. package/skills/consultancy-workflows/documentation-automation.md +454 -0
  114. package/skills/consultancy-workflows/handoff-procedures.md +257 -0
  115. package/skills/consultancy-workflows/knowledge-capture.md +513 -0
  116. package/skills/consultancy-workflows/time-tracking.md +26 -0
  117. package/skills/continuous-learning/SKILL.md +84 -0
  118. package/skills/continuous-learning/config.json +18 -0
  119. package/skills/continuous-learning/evaluate-session.sh +60 -0
  120. package/skills/continuous-learning-v2/SKILL.md +126 -0
  121. package/skills/continuous-learning-v2/config.json +61 -0
  122. package/skills/frontend-patterns/SKILL.md +635 -0
  123. package/skills/frontend-patterns/zoho-widget-patterns.md +103 -0
  124. package/skills/gcp-data-engineering/SKILL.md +36 -0
  125. package/skills/gcp-data-engineering/bigquery/performance-optimization.md +337 -0
  126. package/skills/gcp-data-engineering/dataflow/error-handling.md +496 -0
  127. package/skills/gcp-data-engineering/dataflow/pipeline-patterns.md +444 -0
  128. package/skills/gcp-data-engineering/dbt/model-organization.md +63 -0
  129. package/skills/gcp-data-engineering/dbt/testing-patterns.md +503 -0
  130. package/skills/gcp-data-engineering/medallion-architecture/bronze-layer.md +60 -0
  131. package/skills/gcp-data-engineering/medallion-architecture/gold-layer.md +311 -0
  132. package/skills/gcp-data-engineering/medallion-architecture/layer-transitions.md +517 -0
  133. package/skills/gcp-data-engineering/medallion-architecture/silver-layer.md +305 -0
  134. package/skills/gcp-data-engineering/zoho-to-gcp/data-extraction.md +543 -0
  135. package/skills/gcp-data-engineering/zoho-to-gcp/real-time-vs-batch.md +337 -0
  136. package/skills/security-review/SKILL.md +498 -0
  137. package/skills/security-review/compliance-checklist.md +53 -0
  138. package/skills/strategic-compact/SKILL.md +67 -0
  139. package/skills/tdd-workflow/SKILL.md +413 -0
  140. package/skills/tdd-workflow/zoho-testing.md +124 -0
  141. package/skills/tutorial/SKILL.md +249 -0
  142. package/skills/tutorial/docs/ACCESSIBILITY.md +169 -0
  143. package/skills/tutorial/lessons/00-philosophy-and-workflow.md +198 -0
  144. package/skills/tutorial/lessons/01-basics.md +81 -0
  145. package/skills/tutorial/lessons/02-training.md +86 -0
  146. package/skills/tutorial/lessons/03-commands.md +109 -0
  147. package/skills/tutorial/lessons/04-workflows.md +115 -0
  148. package/skills/tutorial/lessons/05-compliance.md +116 -0
  149. package/skills/tutorial/lessons/06-zoho.md +121 -0
  150. package/skills/tutorial/lessons/07-hooks-system.md +277 -0
  151. package/skills/tutorial/lessons/08-mcp-servers.md +316 -0
  152. package/skills/tutorial/lessons/09-client-management.md +215 -0
  153. package/skills/tutorial/lessons/10-testing-e2e.md +260 -0
  154. package/skills/tutorial/lessons/11-skills-deep-dive.md +272 -0
  155. package/skills/tutorial/lessons/12-rules-system.md +326 -0
  156. package/skills/tutorial/lessons/13-golden-standard-graduation.md +213 -0
  157. package/skills/tutorial/lessons/14-fork-setup-and-sync.md +312 -0
  158. package/skills/tutorial/lessons/15-living-examples-system.md +221 -0
  159. package/skills/tutorial/tracks/accelerated/README.md +134 -0
  160. package/skills/tutorial/tracks/accelerated/assessment/checkpoint-1.md +161 -0
  161. package/skills/tutorial/tracks/accelerated/assessment/checkpoint-2.md +175 -0
  162. package/skills/tutorial/tracks/accelerated/day-1-core-concepts.md +234 -0
  163. package/skills/tutorial/tracks/accelerated/day-2-essential-commands.md +270 -0
  164. package/skills/tutorial/tracks/accelerated/day-3-workflow-mastery.md +305 -0
  165. package/skills/tutorial/tracks/accelerated/day-4-compliance-zoho.md +304 -0
  166. package/skills/tutorial/tracks/accelerated/day-5-hooks-skills.md +344 -0
  167. package/skills/tutorial/tracks/accelerated/day-6-client-testing.md +386 -0
  168. package/skills/tutorial/tracks/accelerated/day-7-graduation.md +369 -0
  169. package/skills/zoho-patterns/CHANGELOG.md +108 -0
  170. package/skills/zoho-patterns/SKILL.md +446 -0
  171. package/skills/zoho-patterns/analytics/dashboard-patterns.md +352 -0
  172. package/skills/zoho-patterns/analytics/zoho-to-bigquery-pipeline.md +427 -0
  173. package/skills/zoho-patterns/catalyst/appsail-deployment.md +349 -0
  174. package/skills/zoho-patterns/catalyst/context-close-patterns.md +354 -0
  175. package/skills/zoho-patterns/catalyst/cron-batch-processing.md +374 -0
  176. package/skills/zoho-patterns/catalyst/function-patterns.md +439 -0
  177. package/skills/zoho-patterns/creator/form-design.md +304 -0
  178. package/skills/zoho-patterns/creator/publish-api-patterns.md +313 -0
  179. package/skills/zoho-patterns/creator/widget-integration.md +306 -0
  180. package/skills/zoho-patterns/creator/workflow-automation.md +253 -0
  181. package/skills/zoho-patterns/deluge/api-patterns.md +468 -0
  182. package/skills/zoho-patterns/deluge/batch-processing.md +403 -0
  183. package/skills/zoho-patterns/deluge/cross-app-integration.md +356 -0
  184. package/skills/zoho-patterns/deluge/error-handling.md +423 -0
  185. package/skills/zoho-patterns/deluge/syntax-reference.md +65 -0
  186. package/skills/zoho-patterns/integration/cors-proxy-architecture.md +426 -0
  187. package/skills/zoho-patterns/integration/crm-books-native-sync.md +277 -0
  188. package/skills/zoho-patterns/integration/oauth-token-management.md +461 -0
  189. package/skills/zoho-patterns/integration/zoho-flow-patterns.md +334 -0
@@ -0,0 +1,324 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Diagnose Script for Everything Claude Code
5
+ * Deep diagnostics for troubleshooting issues
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ const { getClaudeDir, getSessionsDir, readFile, findFiles, log } = require('./lib/utils');
11
+
12
+ // Status indicators
13
+ const OK = '[OK]';
14
+ const WARN = '[WARN]';
15
+ const FAIL = '[FAIL]';
16
+
17
+ const recommendations = [];
18
+
19
+ function padRight(str, len) {
20
+ return str.padEnd(len);
21
+ }
22
+
23
+ function addRecommendation(text) {
24
+ recommendations.push(text);
25
+ }
26
+
27
+ // Configuration Checks
28
+ function checkJsonFile(name, filePath) {
29
+ if (!fs.existsSync(filePath)) {
30
+ return { status: WARN, message: 'Not found' };
31
+ }
32
+ try {
33
+ const content = readFile(filePath);
34
+ const parsed = JSON.parse(content);
35
+
36
+ // Additional validation based on file type
37
+ if (name === 'hooks.json' && parsed.hooks) {
38
+ return { status: OK, message: `Valid, ${parsed.hooks.length} hooks` };
39
+ }
40
+ if (name === 'settings.json' && parsed.mcpServers) {
41
+ const mcpCount = Object.keys(parsed.mcpServers).length;
42
+ return { status: OK, message: `Valid, ${mcpCount} MCPs` };
43
+ }
44
+
45
+ return { status: OK, message: 'Valid' };
46
+ } catch (err) {
47
+ addRecommendation(`Fix JSON syntax error in ${name}: ${err.message}`);
48
+ return { status: FAIL, message: `Invalid JSON: ${err.message.slice(0, 50)}` };
49
+ }
50
+ }
51
+
52
+ function checkConfigurations() {
53
+ log('Checking configurations...');
54
+
55
+ const hooksFile = path.join(process.cwd(), 'hooks', 'hooks.json');
56
+ const hooksResult = checkJsonFile('hooks.json', hooksFile);
57
+ log(` ${padRight('hooks.json:', 20)} ${hooksResult.status} ${hooksResult.message}`);
58
+
59
+ const settingsFile = path.join(getClaudeDir(), 'settings.json');
60
+ const settingsResult = checkJsonFile('settings.json', settingsFile);
61
+ log(` ${padRight('settings.json:', 20)} ${settingsResult.status} ${settingsResult.message}`);
62
+
63
+ const packageFile = path.join(process.cwd(), 'package.json');
64
+ const packageResult = checkJsonFile('package.json', packageFile);
65
+ log(` ${padRight('package.json:', 20)} ${packageResult.status} ${packageResult.message}`);
66
+
67
+ // Check if node_modules exists
68
+ const nodeModules = path.join(process.cwd(), 'node_modules');
69
+ if (!fs.existsSync(nodeModules)) {
70
+ log(` ${padRight('Dependencies:', 20)} ${FAIL} node_modules not found`);
71
+ addRecommendation('Run "npm install" to install dependencies');
72
+ } else {
73
+ log(` ${padRight('Dependencies:', 20)} ${OK} Installed`);
74
+ }
75
+
76
+ log('');
77
+ }
78
+
79
+ // Permission Checks
80
+ function checkPermission(name, dirPath) {
81
+ if (!fs.existsSync(dirPath)) {
82
+ return { status: WARN, message: 'Does not exist' };
83
+ }
84
+ try {
85
+ const testFile = path.join(dirPath, '.diagnose-test');
86
+ fs.writeFileSync(testFile, 'test');
87
+ fs.unlinkSync(testFile);
88
+ return { status: OK, message: 'Writable' };
89
+ } catch (err) {
90
+ addRecommendation(`Fix permissions on ${dirPath}: ${err.code}`);
91
+ return { status: FAIL, message: `Not writable: ${err.code}` };
92
+ }
93
+ }
94
+
95
+ function checkPermissions() {
96
+ log('Checking permissions...');
97
+
98
+ const claudeDir = getClaudeDir();
99
+ const claudeResult = checkPermission('~/.claude/', claudeDir);
100
+ log(` ${padRight('~/.claude/:', 20)} ${claudeResult.status} ${claudeResult.message}`);
101
+
102
+ const memoryDir = path.join(claudeDir, 'memory');
103
+ const memoryResult = checkPermission('~/.claude/memory/', memoryDir);
104
+ log(` ${padRight('~/.claude/memory/:', 20)} ${memoryResult.status} ${memoryResult.message}`);
105
+
106
+ const skillsDir = path.join(claudeDir, 'skills');
107
+ const skillsResult = checkPermission('~/.claude/skills/', skillsDir);
108
+ log(` ${padRight('~/.claude/skills/:', 20)} ${skillsResult.status} ${skillsResult.message}`);
109
+
110
+ log('');
111
+ }
112
+
113
+ // Recent Errors Check
114
+ function checkRecentErrors() {
115
+ log('Checking recent errors (last 24h)...');
116
+
117
+ const sessionsDir = getSessionsDir();
118
+ if (!fs.existsSync(sessionsDir)) {
119
+ log(` No sessions directory found`);
120
+ log('');
121
+ return;
122
+ }
123
+
124
+ const recentFiles = findFiles(sessionsDir, '*.jsonl', { maxAge: 1 });
125
+
126
+ if (recentFiles.length === 0) {
127
+ log(` No recent sessions found`);
128
+ log('');
129
+ return;
130
+ }
131
+
132
+ let errorCount = 0;
133
+ let timeoutCount = 0;
134
+ let jsonErrors = 0;
135
+ const errorPatterns = [];
136
+
137
+ for (const file of recentFiles.slice(0, 10)) {
138
+ // Check last 10 sessions
139
+ try {
140
+ const content = readFile(file.path);
141
+ const lines = content.split('\n').filter(Boolean);
142
+
143
+ for (const line of lines) {
144
+ try {
145
+ const entry = JSON.parse(line);
146
+ // Look for error patterns
147
+ if (entry.error || (entry.type && entry.type.includes('error'))) {
148
+ errorCount++;
149
+ if (entry.error && !errorPatterns.includes(entry.error.slice(0, 50))) {
150
+ errorPatterns.push(entry.error.slice(0, 50));
151
+ }
152
+ }
153
+ if (entry.timeout || (entry.message && entry.message.includes('timeout'))) {
154
+ timeoutCount++;
155
+ }
156
+ } catch {
157
+ jsonErrors++;
158
+ }
159
+ }
160
+ } catch {
161
+ // Skip unreadable files
162
+ }
163
+ }
164
+
165
+ if (errorCount === 0 && timeoutCount === 0 && jsonErrors === 0) {
166
+ log(` ${OK} No errors found in recent sessions`);
167
+ } else {
168
+ if (errorCount > 0) {
169
+ log(` ${WARN} ${errorCount} errors found`);
170
+ errorPatterns.slice(0, 3).forEach((pattern) => {
171
+ log(` - ${pattern}...`);
172
+ });
173
+ }
174
+ if (timeoutCount > 0) {
175
+ log(` ${WARN} ${timeoutCount} timeouts found`);
176
+ addRecommendation('Check hook timeout settings in hooks.json');
177
+ }
178
+ if (jsonErrors > 0) {
179
+ log(` ${WARN} ${jsonErrors} JSON parse errors in session files`);
180
+ addRecommendation('Some session files may be corrupted');
181
+ }
182
+ }
183
+
184
+ log('');
185
+ }
186
+
187
+ // MCP Connectivity Check
188
+ function checkMCPs() {
189
+ log('Checking MCPs...');
190
+
191
+ const settingsFile = path.join(getClaudeDir(), 'settings.json');
192
+ if (!fs.existsSync(settingsFile)) {
193
+ log(` ${WARN} No settings.json found - MCPs not configured`);
194
+ addRecommendation('Configure MCPs in ~/.claude/settings.json');
195
+ log('');
196
+ return;
197
+ }
198
+
199
+ try {
200
+ const content = readFile(settingsFile);
201
+ const settings = JSON.parse(content);
202
+
203
+ if (!settings.mcpServers || Object.keys(settings.mcpServers).length === 0) {
204
+ log(` ${WARN} No MCPs configured`);
205
+ addRecommendation('Add MCP servers to ~/.claude/settings.json');
206
+ log('');
207
+ return;
208
+ }
209
+
210
+ for (const [name, config] of Object.entries(settings.mcpServers)) {
211
+ // We can't actually test connectivity without running the MCP
212
+ // So we just verify the configuration looks valid
213
+ if (config.command || config.url) {
214
+ log(` ${padRight(name + ':', 20)} ${OK} Configured`);
215
+ } else {
216
+ log(` ${padRight(name + ':', 20)} ${WARN} Missing command or url`);
217
+ addRecommendation(`Check ${name} MCP configuration`);
218
+ }
219
+ }
220
+ } catch (err) {
221
+ log(` ${FAIL} Cannot parse settings.json: ${err.message}`);
222
+ addRecommendation('Fix JSON syntax in ~/.claude/settings.json');
223
+ }
224
+
225
+ log('');
226
+ }
227
+
228
+ // Common Misconfigurations
229
+ function checkCommonIssues() {
230
+ log('Checking common issues...');
231
+
232
+ // Check for .env file
233
+ const envFile = path.join(getClaudeDir(), '.env');
234
+ if (!fs.existsSync(envFile)) {
235
+ log(` ${WARN} No ~/.claude/.env file found`);
236
+ addRecommendation('Create ~/.claude/.env with required credentials');
237
+ } else {
238
+ log(` ${padRight('.env file:', 20)} ${OK} Found`);
239
+ }
240
+
241
+ // Check tutorial progress file
242
+ const milestonesFile = path.join(getClaudeDir(), 'onboarding', 'milestones.json');
243
+ if (fs.existsSync(milestonesFile)) {
244
+ try {
245
+ const content = readFile(milestonesFile);
246
+ const milestones = JSON.parse(content);
247
+ const completed = Object.values(milestones).filter((v) => v === true).length;
248
+ log(` ${padRight('Tutorial progress:', 20)} ${OK} ${completed} milestones completed`);
249
+ } catch {
250
+ log(` ${padRight('Tutorial progress:', 20)} ${WARN} Invalid milestones file`);
251
+ }
252
+ } else {
253
+ log(` ${padRight('Tutorial progress:', 20)} ${WARN} Not started`);
254
+ addRecommendation('Run /tutorial to start the tutorial');
255
+ }
256
+
257
+ // Check git status
258
+ try {
259
+ const { execSync } = require('child_process');
260
+ execSync('git rev-parse --git-dir', { stdio: 'pipe' });
261
+ const upstream = execSync('git remote -v', { encoding: 'utf8' });
262
+ if (upstream.includes('upstream')) {
263
+ log(` ${padRight('Git upstream:', 20)} ${OK} Configured`);
264
+ } else {
265
+ log(` ${padRight('Git upstream:', 20)} ${WARN} No upstream remote`);
266
+ addRecommendation('Add upstream remote: git remote add upstream [central-repo-url]');
267
+ }
268
+ } catch {
269
+ log(` ${padRight('Git repo:', 20)} ${WARN} Not a git repository`);
270
+ }
271
+
272
+ log('');
273
+ }
274
+
275
+ function printRecommendations() {
276
+ log('─'.repeat(50));
277
+ log('');
278
+
279
+ if (recommendations.length === 0) {
280
+ log('DIAGNOSIS: All checks passed');
281
+ log('');
282
+ log('No issues found. System appears healthy.');
283
+ } else {
284
+ log(`DIAGNOSIS: ${recommendations.length} issue(s) found`);
285
+ log('');
286
+ log('Recommendations:');
287
+ recommendations.forEach((rec, i) => {
288
+ log(` ${i + 1}. ${rec}`);
289
+ });
290
+ }
291
+
292
+ log('');
293
+ }
294
+
295
+ function runDiagnose(options = {}) {
296
+ const { config, permissions, errors, mcp } = options;
297
+ const runAll = !config && !permissions && !errors && !mcp;
298
+
299
+ log('');
300
+ log('Running diagnostics...');
301
+ log('');
302
+
303
+ if (runAll || config) checkConfigurations();
304
+ if (runAll || permissions) checkPermissions();
305
+ if (runAll || errors) checkRecentErrors();
306
+ if (runAll || mcp) checkMCPs();
307
+ if (runAll) checkCommonIssues();
308
+
309
+ printRecommendations();
310
+
311
+ // Exit with appropriate code for CI/CD
312
+ process.exit(recommendations.length > 0 ? 1 : 0);
313
+ }
314
+
315
+ // Parse arguments
316
+ const args = process.argv.slice(2);
317
+ const options = {
318
+ config: args.includes('--config'),
319
+ permissions: args.includes('--permissions'),
320
+ errors: args.includes('--errors'),
321
+ mcp: args.includes('--mcp'),
322
+ };
323
+
324
+ runDiagnose(options);
@@ -0,0 +1,168 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Documentation Freshness Checker
4
+ * Identifies stale documentation files that haven't been modified recently.
5
+ */
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+
9
+ const ROOT = path.join(__dirname, '..');
10
+
11
+ // Parse arguments
12
+ const args = process.argv.slice(2);
13
+ const failOnStale = args.find((a) => a.startsWith('--fail-on-stale='));
14
+ const staleThresholdDays = failOnStale ? parseInt(failOnStale.split('=')[1], 10) : 90;
15
+ const jsonOutput = args.includes('--json');
16
+ const verbose = args.includes('--verbose');
17
+
18
+ /**
19
+ * Get all markdown files recursively
20
+ */
21
+ function getMarkdownFiles(dir, files = []) {
22
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
23
+ for (const entry of entries) {
24
+ const fullPath = path.join(dir, entry.name);
25
+ if (entry.isDirectory()) {
26
+ // Skip node_modules, .git, archived
27
+ if (entry.name === 'node_modules' || entry.name === '.git' || entry.name === '_archived') {
28
+ continue;
29
+ }
30
+ getMarkdownFiles(fullPath, files);
31
+ } else if (entry.isFile() && entry.name.endsWith('.md')) {
32
+ files.push(fullPath);
33
+ }
34
+ }
35
+ return files;
36
+ }
37
+
38
+ /**
39
+ * Check for TODO/PLACEHOLDER markers
40
+ */
41
+ function hasPlaceholders(content) {
42
+ const markers = ['TODO:', 'PLACEHOLDER', 'FIXME:', 'TBD:', 'XXX:'];
43
+ return markers.some((m) => content.includes(m));
44
+ }
45
+
46
+ /**
47
+ * Get file modification date
48
+ */
49
+ function getModDate(file) {
50
+ const stats = fs.statSync(file);
51
+ return stats.mtime;
52
+ }
53
+
54
+ /**
55
+ * Calculate days since modification
56
+ */
57
+ function daysSince(date) {
58
+ const now = new Date();
59
+ const diff = now - date;
60
+ return Math.floor(diff / (1000 * 60 * 60 * 24));
61
+ }
62
+
63
+ // Get all markdown files
64
+ const markdownFiles = getMarkdownFiles(ROOT);
65
+ const now = new Date();
66
+
67
+ // Analyze each file
68
+ const results = {
69
+ total: markdownFiles.length,
70
+ stale: [],
71
+ hasPlaceholders: [],
72
+ recent: [],
73
+ byAge: {
74
+ last7Days: 0,
75
+ last30Days: 0,
76
+ last90Days: 0,
77
+ older: 0,
78
+ },
79
+ };
80
+
81
+ for (const file of markdownFiles) {
82
+ const relativePath = path.relative(ROOT, file);
83
+ const content = fs.readFileSync(file, 'utf8');
84
+ const modDate = getModDate(file);
85
+ const days = daysSince(modDate);
86
+
87
+ // Categorize by age
88
+ if (days <= 7) {
89
+ results.byAge.last7Days++;
90
+ results.recent.push({ file: relativePath, days });
91
+ } else if (days <= 30) {
92
+ results.byAge.last30Days++;
93
+ } else if (days <= 90) {
94
+ results.byAge.last90Days++;
95
+ } else {
96
+ results.byAge.older++;
97
+ results.stale.push({
98
+ file: relativePath,
99
+ days,
100
+ lastModified: modDate.toISOString().split('T')[0],
101
+ });
102
+ }
103
+
104
+ // Check for placeholders
105
+ if (hasPlaceholders(content)) {
106
+ results.hasPlaceholders.push({ file: relativePath });
107
+ }
108
+ }
109
+
110
+ // Sort stale by age (oldest first)
111
+ results.stale.sort((a, b) => b.days - a.days);
112
+
113
+ // Output results
114
+ if (jsonOutput) {
115
+ console.log(JSON.stringify(results, null, 2));
116
+ } else {
117
+ console.log('\n=== Documentation Freshness Report ===\n');
118
+ console.log(`Total files: ${results.total}`);
119
+ console.log(`\nAge Distribution:`);
120
+ console.log(` Last 7 days: ${results.byAge.last7Days}`);
121
+ console.log(` Last 30 days: ${results.byAge.last30Days}`);
122
+ console.log(` Last 90 days: ${results.byAge.last90Days}`);
123
+ console.log(` Older: ${results.byAge.older}`);
124
+
125
+ if (results.stale.length > 0) {
126
+ console.log(`\n\u26A0 Stale Files (>90 days):`);
127
+ const displayCount = verbose ? results.stale.length : Math.min(10, results.stale.length);
128
+ for (let i = 0; i < displayCount; i++) {
129
+ const { file, days, lastModified } = results.stale[i];
130
+ console.log(` - ${file} (${days} days old, last: ${lastModified})`);
131
+ }
132
+ if (!verbose && results.stale.length > 10) {
133
+ console.log(` ... and ${results.stale.length - 10} more (use --verbose to see all)`);
134
+ }
135
+ }
136
+
137
+ if (results.hasPlaceholders.length > 0) {
138
+ console.log(`\n\u26A0 Files with TODO/PLACEHOLDER markers:`);
139
+ for (const { file } of results.hasPlaceholders.slice(0, 10)) {
140
+ console.log(` - ${file}`);
141
+ }
142
+ if (results.hasPlaceholders.length > 10) {
143
+ console.log(` ... and ${results.hasPlaceholders.length - 10} more`);
144
+ }
145
+ }
146
+
147
+ if (results.recent.length > 0 && verbose) {
148
+ console.log(`\n\u2713 Recently Updated (last 7 days):`);
149
+ for (const { file, days } of results.recent.slice(0, 10)) {
150
+ console.log(` - ${file} (${days} days ago)`);
151
+ }
152
+ }
153
+
154
+ console.log('\n');
155
+ }
156
+
157
+ // Exit with error if --fail-on-stale is set and there are stale files
158
+ if (failOnStale && results.stale.length > 0) {
159
+ const criticalStale = results.stale.filter((f) => f.days > staleThresholdDays);
160
+ if (criticalStale.length > 0) {
161
+ console.error(
162
+ `\u2717 Found ${criticalStale.length} files older than ${staleThresholdDays} days`
163
+ );
164
+ process.exit(1);
165
+ }
166
+ }
167
+
168
+ process.exit(0);