@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,195 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * SessionStart Hook - Load previous context on new session
4
+ *
5
+ * Cross-platform (Windows, macOS, Linux)
6
+ *
7
+ * Runs when a new Claude session starts. Checks for recent session
8
+ * files and notifies Claude of available context to load.
9
+ */
10
+
11
+ const path = require('path');
12
+ const fs = require('fs');
13
+ const {
14
+ getSessionsDir,
15
+ getLearnedSkillsDir,
16
+ getClaudeDir,
17
+ findFiles,
18
+ ensureDir,
19
+ log,
20
+ } = require('../lib/utils');
21
+ const { getPackageManager, getSelectionPrompt } = require('../lib/package-manager');
22
+
23
+ // Try to load recommendation engine
24
+ let getSessionStartRecommendations = null;
25
+ try {
26
+ const recEngine = require('../lib/recommendation-engine');
27
+ getSessionStartRecommendations = recEngine.getSessionStartRecommendations;
28
+ } catch {
29
+ // Recommendation engine not available
30
+ }
31
+
32
+ async function main() {
33
+ const sessionsDir = getSessionsDir();
34
+ const learnedDir = getLearnedSkillsDir();
35
+
36
+ // Ensure directories exist
37
+ ensureDir(sessionsDir);
38
+ ensureDir(learnedDir);
39
+
40
+ // Check for recent session files (last 7 days)
41
+ const recentSessions = findFiles(sessionsDir, '*.tmp', { maxAge: 7 });
42
+
43
+ if (recentSessions.length > 0) {
44
+ const latest = recentSessions[0];
45
+ log(`[SessionStart] Found ${recentSessions.length} recent session(s)`);
46
+ log(`[SessionStart] Latest: ${latest.path}`);
47
+ }
48
+
49
+ // Check for learned skills
50
+ const learnedSkills = findFiles(learnedDir, '*.md');
51
+
52
+ if (learnedSkills.length > 0) {
53
+ log(`[SessionStart] ${learnedSkills.length} learned skill(s) available in ${learnedDir}`);
54
+ }
55
+
56
+ // Detect and report package manager
57
+ const pm = getPackageManager();
58
+ log(`[SessionStart] Package manager: ${pm.name} (${pm.source})`);
59
+
60
+ // If package manager was detected via fallback, show selection prompt
61
+ if (pm.source === 'fallback' || pm.source === 'default') {
62
+ log('[SessionStart] No package manager preference found.');
63
+ log(getSelectionPrompt());
64
+ }
65
+
66
+ // Load client context if available
67
+ const clientId = process.env.CLOUDSTREAM_CLIENT_ID;
68
+ const complianceMode = process.env.CLOUDSTREAM_COMPLIANCE_MODE || 'standard';
69
+
70
+ if (clientId) {
71
+ log(`[SessionStart] Client: ${clientId} | Compliance: ${complianceMode}`);
72
+ }
73
+
74
+ // Check for pre-compact context restoration
75
+ const contextFile = path.join(sessionsDir, 'pre-compact-context.json');
76
+ if (fs.existsSync(contextFile)) {
77
+ try {
78
+ const savedContext = JSON.parse(fs.readFileSync(contextFile, 'utf8'));
79
+ log(
80
+ `[SessionStart] Restored context: Client=${savedContext.activeClient}, Compliance=${savedContext.complianceMode}`
81
+ );
82
+ } catch (e) {
83
+ // Ignore parse errors
84
+ }
85
+ }
86
+
87
+ // Check if this is a first-time user (no sessions and no tutorial progress)
88
+ const milestonesFile = path.join(getClaudeDir(), 'onboarding', 'milestones.json');
89
+ const isFirstTime = recentSessions.length === 0 && !fs.existsSync(milestonesFile);
90
+
91
+ if (isFirstTime) {
92
+ log('');
93
+ log('Welcome to CloudStream Claude Code!');
94
+ log('');
95
+ log('Get started:');
96
+ log(' /onboard - Interactive setup wizard (recommended)');
97
+ log(' /health-check - Verify your environment is configured correctly');
98
+ log(' /tutorial - Interactive 15-lesson tutorial');
99
+ log(' /plan - Plan a feature before coding');
100
+ log('');
101
+ log('Need help? Run /diagnose for troubleshooting');
102
+ log('Documentation: README.md, GETTING-STARTED.md');
103
+ log('');
104
+ }
105
+
106
+ // Check for tutorial progress
107
+ try {
108
+ const tutorialProgress = require('../lib/tutorial-progress');
109
+ if (tutorialProgress.hasProgress()) {
110
+ const progress = tutorialProgress.loadProgress();
111
+ if (!tutorialProgress.isComplete(progress)) {
112
+ const percent = tutorialProgress.getCompletionPercent(progress);
113
+ log(
114
+ `[SessionStart] Tutorial in progress: ${percent}% complete (${progress.completedLessons.length}/9 lessons)`
115
+ );
116
+ log(`[SessionStart] Resume with: /tutorial ${progress.currentLesson}`);
117
+ }
118
+ }
119
+ } catch {
120
+ // Tutorial module not available, skip
121
+ }
122
+
123
+ // Surface recommendations from cross-session analysis
124
+ await surfaceRecommendations();
125
+
126
+ process.exit(0);
127
+ }
128
+
129
+ /**
130
+ * Load aggregation config
131
+ */
132
+ function loadAggregationConfig() {
133
+ const configPath = path.join(__dirname, '..', '..', 'config', 'aggregation.json');
134
+ try {
135
+ if (fs.existsSync(configPath)) {
136
+ return JSON.parse(fs.readFileSync(configPath, 'utf8'));
137
+ }
138
+ } catch {
139
+ // Config not available
140
+ }
141
+ return { recommendations: { enabled: false } };
142
+ }
143
+
144
+ /**
145
+ * Surface recommendations at session start
146
+ */
147
+ async function surfaceRecommendations() {
148
+ const config = loadAggregationConfig();
149
+
150
+ // Check if recommendations are enabled
151
+ if (!config.recommendations?.enabled || !config.recommendations?.showAtSessionStart) {
152
+ return;
153
+ }
154
+
155
+ // Check if recommendation engine is available
156
+ if (!getSessionStartRecommendations) {
157
+ return;
158
+ }
159
+
160
+ try {
161
+ const maxRecs = config.recommendations.maxAtSessionStart || 3;
162
+ const recommendations = getSessionStartRecommendations(maxRecs);
163
+
164
+ if (recommendations.length === 0) {
165
+ return;
166
+ }
167
+
168
+ log('');
169
+ log('[SessionStart] Insights from your recent sessions:');
170
+ log('');
171
+
172
+ for (const rec of recommendations) {
173
+ const emoji = rec.priority === 'high' ? '[!]' : rec.priority === 'medium' ? '[*]' : '[-]';
174
+
175
+ log(` ${emoji} ${rec.title}`);
176
+ log(` ${rec.message}`);
177
+
178
+ if (rec.action) {
179
+ log(` Action: ${rec.action}`);
180
+ }
181
+ log('');
182
+ }
183
+
184
+ log(' Run /recommendations for full list');
185
+ log('');
186
+ } catch (err) {
187
+ // Don't block session start on recommendation errors
188
+ log(`[SessionStart] Could not load recommendations: ${err.message}`);
189
+ }
190
+ }
191
+
192
+ main().catch((err) => {
193
+ console.error('[SessionStart] Error:', err.message);
194
+ process.exit(0); // Don't block on errors
195
+ });
@@ -0,0 +1,333 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Skill Injector Hook - Auto-Apply Relevant Skills
5
+ *
6
+ * This hook runs on PreToolUse (Edit, Write, Read) to detect relevant
7
+ * skills based on file context and inject them as guidance.
8
+ *
9
+ * Performance: Lightweight matching, only reads skill content for high-confidence matches.
10
+ *
11
+ * Hook Type: PreToolUse
12
+ */
13
+
14
+ const fs = require('fs');
15
+ const path = require('path');
16
+ const { readStdinJson, log, output, readFile, getClaudeDir } = require('../lib/utils');
17
+ const {
18
+ buildContext,
19
+ matchSkills,
20
+ formatMatchedSkills,
21
+ getSkillContent,
22
+ loadLearnedSkills,
23
+ } = require('../lib/skill-matcher');
24
+ const { loadSessionMemory, updateContext } = require('../lib/session-memory');
25
+
26
+ // Cache to avoid re-matching for same file in same session
27
+ const matchCache = new Map();
28
+ const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
29
+
30
+ /**
31
+ * Get cached match or compute new one
32
+ */
33
+ function getCachedOrMatch(filePath, content) {
34
+ const cacheKey = `${filePath}:${content?.length || 0}`;
35
+
36
+ const cached = matchCache.get(cacheKey);
37
+ if (cached && Date.now() - cached.timestamp < CACHE_TTL_MS) {
38
+ return cached.matches;
39
+ }
40
+
41
+ // Build context and match
42
+ const sessionMemory = loadSessionMemory();
43
+ const context = buildContext(filePath, content, {
44
+ complianceMode: sessionMemory.context?.complianceMode || null,
45
+ technologies: sessionMemory.context?.technologies || [],
46
+ });
47
+
48
+ const matches = matchSkills(context);
49
+
50
+ // Cache result
51
+ matchCache.set(cacheKey, {
52
+ matches,
53
+ timestamp: Date.now(),
54
+ });
55
+
56
+ // Update session context with detected technologies
57
+ if (context.technologies.size > 0) {
58
+ updateContext({
59
+ files: [filePath],
60
+ technologies: Array.from(context.technologies),
61
+ });
62
+ }
63
+
64
+ return matches;
65
+ }
66
+
67
+ /**
68
+ * Get the most important skill guidance to show
69
+ */
70
+ function getKeyGuidance(match) {
71
+ const content = getSkillContent(match);
72
+ if (!content) return null;
73
+
74
+ // Extract key sections based on skill type
75
+ const lines = content.split('\n');
76
+ const keyLines = [];
77
+
78
+ let inKeySection = false;
79
+ const keySectionHeaders = [
80
+ /^#+\s*(critical|important|must|always|never|constraints?|limits?|warnings?)/i,
81
+ /^#+\s*(quick reference|key points|summary)/i,
82
+ ];
83
+
84
+ for (let i = 0; i < lines.length && keyLines.length < 10; i++) {
85
+ const line = lines[i];
86
+
87
+ // Check if entering a key section
88
+ if (keySectionHeaders.some((pattern) => pattern.test(line))) {
89
+ inKeySection = true;
90
+ keyLines.push(line);
91
+ continue;
92
+ }
93
+
94
+ // Check if leaving section (next header)
95
+ if (inKeySection && /^#+\s/.test(line) && !keySectionHeaders.some((p) => p.test(line))) {
96
+ inKeySection = false;
97
+ continue;
98
+ }
99
+
100
+ // Collect content from key sections
101
+ if (inKeySection && line.trim()) {
102
+ keyLines.push(line);
103
+ }
104
+
105
+ // Also collect bullet points that look important
106
+ if (/^[-*]\s*(CRITICAL|IMPORTANT|MUST|ALWAYS|NEVER|WARNING|CAUTION):/i.test(line)) {
107
+ keyLines.push(line);
108
+ }
109
+ }
110
+
111
+ if (keyLines.length === 0) {
112
+ // Fallback: first 5 non-empty lines after first header
113
+ let foundHeader = false;
114
+ for (const line of lines) {
115
+ if (/^#/.test(line)) {
116
+ foundHeader = true;
117
+ continue;
118
+ }
119
+ if (foundHeader && line.trim() && keyLines.length < 5) {
120
+ keyLines.push(line);
121
+ }
122
+ }
123
+ }
124
+
125
+ return keyLines.join('\n');
126
+ }
127
+
128
+ /**
129
+ * Format deprecation warning for a match
130
+ */
131
+ function formatDeprecationWarning(match) {
132
+ if (!match.deprecation) return null;
133
+
134
+ let warning = ` [DEPRECATED] This skill is deprecated`;
135
+
136
+ if (match.deprecation.supersededBy) {
137
+ warning += ` - use "${match.deprecation.supersededBy}" instead`;
138
+ }
139
+
140
+ if (match.deprecation.reason) {
141
+ warning += `\n Reason: ${match.deprecation.reason}`;
142
+ }
143
+
144
+ if (match.deprecation.migrationGuide) {
145
+ warning += `\n Migration guide: ${match.deprecation.migrationGuide}`;
146
+ }
147
+
148
+ if (match.deprecation.removalTarget) {
149
+ warning += `\n Removal target: ${match.deprecation.removalTarget}`;
150
+ }
151
+
152
+ return warning + '\n';
153
+ }
154
+
155
+ /**
156
+ * Format skill guidance for stderr output
157
+ */
158
+ function formatSkillGuidance(matches) {
159
+ if (matches.length === 0) return null;
160
+
161
+ let output = '';
162
+
163
+ // Show matched skills summary
164
+ output += '[Skill] Relevant patterns detected:\n';
165
+
166
+ for (const match of matches) {
167
+ const confidence = Math.round(match.score * 100);
168
+ const typeLabel = match.type === 'learned' ? '(learned)' : '';
169
+ const versionLabel = match.version ? ` v${match.version}` : '';
170
+
171
+ output += `\n[Skill] ${match.skill}${versionLabel} ${typeLabel} - ${confidence}% match\n`;
172
+
173
+ // Show deprecation warning if deprecated
174
+ if (match.deprecation) {
175
+ const deprecationWarning = formatDeprecationWarning(match);
176
+ if (deprecationWarning) {
177
+ output += deprecationWarning;
178
+ }
179
+ }
180
+
181
+ // Get key guidance for high-confidence matches
182
+ if (match.score >= 0.6) {
183
+ const guidance = getKeyGuidance(match);
184
+ if (guidance) {
185
+ // Indent guidance
186
+ const indentedGuidance = guidance
187
+ .split('\n')
188
+ .map((line) => ` ${line}`)
189
+ .join('\n');
190
+ output += indentedGuidance + '\n';
191
+ }
192
+ }
193
+ }
194
+
195
+ return output;
196
+ }
197
+
198
+ /**
199
+ * Check for anti-patterns from session memory
200
+ */
201
+ function checkAntiPatterns(content) {
202
+ const sessionMemory = loadSessionMemory();
203
+ const warnings = [];
204
+
205
+ // Check against session anti-patterns
206
+ if (sessionMemory.antiPatterns) {
207
+ for (const antiPattern of sessionMemory.antiPatterns) {
208
+ if (antiPattern.name && content.includes(antiPattern.name)) {
209
+ warnings.push({
210
+ type: 'anti-pattern',
211
+ name: antiPattern.name,
212
+ avoidance: antiPattern.avoidance,
213
+ });
214
+ }
215
+ }
216
+ }
217
+
218
+ // Check against corrections (things we've been told not to do)
219
+ if (sessionMemory.corrections) {
220
+ for (const correction of sessionMemory.corrections) {
221
+ if (correction.original && correction.count >= 2) {
222
+ // Only warn for repeated corrections
223
+ if (content.toLowerCase().includes(correction.original.toLowerCase())) {
224
+ warnings.push({
225
+ type: 'previous-correction',
226
+ original: correction.original,
227
+ corrected: correction.corrected,
228
+ count: correction.count,
229
+ });
230
+ }
231
+ }
232
+ }
233
+ }
234
+
235
+ return warnings;
236
+ }
237
+
238
+ /**
239
+ * Format anti-pattern warnings
240
+ */
241
+ function formatAntiPatternWarnings(warnings) {
242
+ if (warnings.length === 0) return null;
243
+
244
+ let output = '\n[Learning] Potential issues detected based on session history:\n';
245
+
246
+ for (const warning of warnings) {
247
+ if (warning.type === 'anti-pattern') {
248
+ output += ` - Anti-pattern: "${warning.name}"\n`;
249
+ if (warning.avoidance) {
250
+ output += ` Instead: ${warning.avoidance}\n`;
251
+ }
252
+ } else if (warning.type === 'previous-correction') {
253
+ output += ` - Previously corrected (${warning.count}x): "${warning.original}"\n`;
254
+ if (warning.corrected) {
255
+ output += ` Preferred: ${warning.corrected}\n`;
256
+ }
257
+ }
258
+ }
259
+
260
+ return output;
261
+ }
262
+
263
+ /**
264
+ * Main hook execution
265
+ */
266
+ async function main() {
267
+ try {
268
+ const input = await readStdinJson();
269
+ const tool = input.tool;
270
+ const toolInput = input.tool_input || {};
271
+
272
+ // Get file path based on tool
273
+ let filePath = null;
274
+ let content = null;
275
+
276
+ if (tool === 'Edit') {
277
+ filePath = toolInput.file_path;
278
+ content = toolInput.new_string || '';
279
+ } else if (tool === 'Write') {
280
+ filePath = toolInput.file_path;
281
+ content = toolInput.content || '';
282
+ } else if (tool === 'Read') {
283
+ filePath = toolInput.file_path;
284
+ // For Read, we don't have content yet, but can still match on file path
285
+ content = '';
286
+ }
287
+
288
+ if (!filePath) {
289
+ output(JSON.stringify(input));
290
+ return;
291
+ }
292
+
293
+ // Skip for non-code files
294
+ const codeExtensions = ['.ts', '.tsx', '.js', '.jsx', '.ds', '.sql', '.py', '.md'];
295
+ const ext = path.extname(filePath);
296
+ if (!codeExtensions.includes(ext)) {
297
+ output(JSON.stringify(input));
298
+ return;
299
+ }
300
+
301
+ // Get matched skills
302
+ const matches = getCachedOrMatch(filePath, content);
303
+
304
+ // Format and output skill guidance
305
+ if (matches.length > 0) {
306
+ const guidance = formatSkillGuidance(matches);
307
+ if (guidance) {
308
+ log(guidance);
309
+ }
310
+ }
311
+
312
+ // Check for anti-patterns in content being written
313
+ if (content && (tool === 'Edit' || tool === 'Write')) {
314
+ const warnings = checkAntiPatterns(content);
315
+ if (warnings.length > 0) {
316
+ const warningOutput = formatAntiPatternWarnings(warnings);
317
+ if (warningOutput) {
318
+ log(warningOutput);
319
+ }
320
+ }
321
+ }
322
+
323
+ // Pass through input unchanged
324
+ output(JSON.stringify(input));
325
+ } catch (err) {
326
+ // On error, log but don't block
327
+ log(`[SkillInjector] Error: ${err.message}`);
328
+ output('{}');
329
+ }
330
+ }
331
+
332
+ // Run
333
+ main();
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Strategic Compact Suggester
4
+ *
5
+ * Cross-platform (Windows, macOS, Linux)
6
+ *
7
+ * Runs on PreToolUse or periodically to suggest manual compaction at logical intervals
8
+ *
9
+ * Why manual over auto-compact:
10
+ * - Auto-compact happens at arbitrary points, often mid-task
11
+ * - Strategic compacting preserves context through logical phases
12
+ * - Compact after exploration, before execution
13
+ * - Compact after completing a milestone, before starting next
14
+ */
15
+
16
+ const path = require('path');
17
+ const { getTempDir, readFile, writeFile, log } = require('../lib/utils');
18
+
19
+ async function main() {
20
+ // Track tool call count (increment in a temp file)
21
+ // Use a session-specific counter file based on PID from parent process
22
+ // or session ID from environment
23
+ const sessionId = process.env.CLAUDE_SESSION_ID || process.ppid || 'default';
24
+ const counterFile = path.join(getTempDir(), `claude-tool-count-${sessionId}`);
25
+ const threshold = parseInt(process.env.COMPACT_THRESHOLD || '50', 10);
26
+
27
+ let count = 1;
28
+
29
+ // Read existing count or start at 1
30
+ const existing = readFile(counterFile);
31
+ if (existing) {
32
+ count = parseInt(existing.trim(), 10) + 1;
33
+ }
34
+
35
+ // Save updated count
36
+ writeFile(counterFile, String(count));
37
+
38
+ // Suggest compact after threshold tool calls
39
+ if (count === threshold) {
40
+ log(
41
+ `[StrategicCompact] ${threshold} tool calls reached - consider /compact if transitioning phases`
42
+ );
43
+ }
44
+
45
+ // Suggest at regular intervals after threshold
46
+ if (count > threshold && count % 25 === 0) {
47
+ log(
48
+ `[StrategicCompact] ${count} tool calls - good checkpoint for /compact if context is stale`
49
+ );
50
+ }
51
+
52
+ process.exit(0);
53
+ }
54
+
55
+ main().catch((err) => {
56
+ console.error('[StrategicCompact] Error:', err.message);
57
+ process.exit(0);
58
+ });