@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,204 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Package Manager Setup Script
4
+ *
5
+ * Interactive script to configure preferred package manager.
6
+ * Can be run directly or via the /setup-pm command.
7
+ *
8
+ * Usage:
9
+ * node scripts/setup-package-manager.js [pm-name]
10
+ * node scripts/setup-package-manager.js --detect
11
+ * node scripts/setup-package-manager.js --global pnpm
12
+ * node scripts/setup-package-manager.js --project bun
13
+ */
14
+
15
+ const {
16
+ PACKAGE_MANAGERS,
17
+ getPackageManager,
18
+ setPreferredPackageManager,
19
+ setProjectPackageManager,
20
+ getAvailablePackageManagers,
21
+ detectFromLockFile,
22
+ detectFromPackageJson,
23
+ } = require('./lib/package-manager');
24
+
25
+ function showHelp() {
26
+ console.log(`
27
+ Package Manager Setup for Claude Code
28
+
29
+ Usage:
30
+ node scripts/setup-package-manager.js [options] [package-manager]
31
+
32
+ Options:
33
+ --detect Detect and show current package manager
34
+ --global <pm> Set global preference (saves to ~/.claude/package-manager.json)
35
+ --project <pm> Set project preference (saves to .claude/package-manager.json)
36
+ --list List available package managers
37
+ --help Show this help message
38
+
39
+ Package Managers:
40
+ npm Node Package Manager (default with Node.js)
41
+ pnpm Fast, disk space efficient package manager
42
+ yarn Classic Yarn package manager
43
+ bun All-in-one JavaScript runtime & toolkit
44
+
45
+ Examples:
46
+ # Detect current package manager
47
+ node scripts/setup-package-manager.js --detect
48
+
49
+ # Set pnpm as global preference
50
+ node scripts/setup-package-manager.js --global pnpm
51
+
52
+ # Set bun for current project
53
+ node scripts/setup-package-manager.js --project bun
54
+
55
+ # List available package managers
56
+ node scripts/setup-package-manager.js --list
57
+ `);
58
+ }
59
+
60
+ function detectAndShow() {
61
+ const pm = getPackageManager();
62
+ const available = getAvailablePackageManagers();
63
+ const fromLock = detectFromLockFile();
64
+ const fromPkg = detectFromPackageJson();
65
+
66
+ console.log('\n=== Package Manager Detection ===\n');
67
+
68
+ console.log('Current selection:');
69
+ console.log(` Package Manager: ${pm.name}`);
70
+ console.log(` Source: ${pm.source}`);
71
+ console.log('');
72
+
73
+ console.log('Detection results:');
74
+ console.log(` From package.json: ${fromPkg || 'not specified'}`);
75
+ console.log(` From lock file: ${fromLock || 'not found'}`);
76
+ console.log(` Environment var: ${process.env.CLAUDE_PACKAGE_MANAGER || 'not set'}`);
77
+ console.log('');
78
+
79
+ console.log('Available package managers:');
80
+ for (const pmName of Object.keys(PACKAGE_MANAGERS)) {
81
+ const installed = available.includes(pmName);
82
+ const indicator = installed ? '✓' : '✗';
83
+ const current = pmName === pm.name ? ' (current)' : '';
84
+ console.log(` ${indicator} ${pmName}${current}`);
85
+ }
86
+
87
+ console.log('');
88
+ console.log('Commands:');
89
+ console.log(` Install: ${pm.config.installCmd}`);
90
+ console.log(` Run script: ${pm.config.runCmd} [script-name]`);
91
+ console.log(` Execute binary: ${pm.config.execCmd} [binary-name]`);
92
+ console.log('');
93
+ }
94
+
95
+ function listAvailable() {
96
+ const available = getAvailablePackageManagers();
97
+ const pm = getPackageManager();
98
+
99
+ console.log('\nAvailable Package Managers:\n');
100
+
101
+ for (const pmName of Object.keys(PACKAGE_MANAGERS)) {
102
+ const config = PACKAGE_MANAGERS[pmName];
103
+ const installed = available.includes(pmName);
104
+ const current = pmName === pm.name ? ' (current)' : '';
105
+
106
+ console.log(`${pmName}${current}`);
107
+ console.log(` Installed: ${installed ? 'Yes' : 'No'}`);
108
+ console.log(` Lock file: ${config.lockFile}`);
109
+ console.log(` Install: ${config.installCmd}`);
110
+ console.log(` Run: ${config.runCmd}`);
111
+ console.log('');
112
+ }
113
+ }
114
+
115
+ function setGlobal(pmName) {
116
+ if (!PACKAGE_MANAGERS[pmName]) {
117
+ console.error(`Error: Unknown package manager "${pmName}"`);
118
+ console.error(`Available: ${Object.keys(PACKAGE_MANAGERS).join(', ')}`);
119
+ process.exit(1);
120
+ }
121
+
122
+ const available = getAvailablePackageManagers();
123
+ if (!available.includes(pmName)) {
124
+ console.warn(`Warning: ${pmName} is not installed on your system`);
125
+ }
126
+
127
+ try {
128
+ setPreferredPackageManager(pmName);
129
+ console.log(`\n✓ Global preference set to: ${pmName}`);
130
+ console.log(' Saved to: ~/.claude/package-manager.json');
131
+ console.log('');
132
+ } catch (err) {
133
+ console.error(`Error: ${err.message}`);
134
+ process.exit(1);
135
+ }
136
+ }
137
+
138
+ function setProject(pmName) {
139
+ if (!PACKAGE_MANAGERS[pmName]) {
140
+ console.error(`Error: Unknown package manager "${pmName}"`);
141
+ console.error(`Available: ${Object.keys(PACKAGE_MANAGERS).join(', ')}`);
142
+ process.exit(1);
143
+ }
144
+
145
+ try {
146
+ setProjectPackageManager(pmName);
147
+ console.log(`\n✓ Project preference set to: ${pmName}`);
148
+ console.log(' Saved to: .claude/package-manager.json');
149
+ console.log('');
150
+ } catch (err) {
151
+ console.error(`Error: ${err.message}`);
152
+ process.exit(1);
153
+ }
154
+ }
155
+
156
+ // Main
157
+ const args = process.argv.slice(2);
158
+
159
+ if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
160
+ showHelp();
161
+ process.exit(0);
162
+ }
163
+
164
+ if (args.includes('--detect')) {
165
+ detectAndShow();
166
+ process.exit(0);
167
+ }
168
+
169
+ if (args.includes('--list')) {
170
+ listAvailable();
171
+ process.exit(0);
172
+ }
173
+
174
+ const globalIdx = args.indexOf('--global');
175
+ if (globalIdx !== -1) {
176
+ const pmName = args[globalIdx + 1];
177
+ if (!pmName) {
178
+ console.error('Error: --global requires a package manager name');
179
+ process.exit(1);
180
+ }
181
+ setGlobal(pmName);
182
+ process.exit(0);
183
+ }
184
+
185
+ const projectIdx = args.indexOf('--project');
186
+ if (projectIdx !== -1) {
187
+ const pmName = args[projectIdx + 1];
188
+ if (!pmName) {
189
+ console.error('Error: --project requires a package manager name');
190
+ process.exit(1);
191
+ }
192
+ setProject(pmName);
193
+ process.exit(0);
194
+ }
195
+
196
+ // If just a package manager name is provided, set it globally
197
+ const pmName = args[0];
198
+ if (PACKAGE_MANAGERS[pmName]) {
199
+ setGlobal(pmName);
200
+ } else {
201
+ console.error(`Error: Unknown option or package manager "${pmName}"`);
202
+ showHelp();
203
+ process.exit(1);
204
+ }
@@ -0,0 +1,391 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Upstream Sync Tool
4
+ *
5
+ * Syncs fork with upstream repository while preserving customizations.
6
+ *
7
+ * Usage:
8
+ * node scripts/sync-upstream.js check # Preview what would sync
9
+ * node scripts/sync-upstream.js dry-run # Test merge without committing
10
+ * node scripts/sync-upstream.js auto # Full sync + tests + commit
11
+ * node scripts/sync-upstream.js abort # Cancel in-progress merge
12
+ */
13
+
14
+ const { execSync, spawnSync } = require('child_process');
15
+ const path = require('path');
16
+ const fs = require('fs');
17
+
18
+ // Directories to sync from upstream
19
+ const SYNC_DIRS = ['agents/', 'commands/', 'skills/', 'rules/', 'mcp-configs/'];
20
+
21
+ // Directories that are never synced (user customizations)
22
+ const PROTECTED_DIRS = ['.env', 'personal/', 'private/'];
23
+
24
+ // ANSI color codes
25
+ const colors = {
26
+ reset: '\x1b[0m',
27
+ bold: '\x1b[1m',
28
+ red: '\x1b[31m',
29
+ green: '\x1b[32m',
30
+ yellow: '\x1b[33m',
31
+ blue: '\x1b[34m',
32
+ cyan: '\x1b[36m',
33
+ };
34
+
35
+ // Disable colors if NO_COLOR is set
36
+ const noColor = process.env.NO_COLOR || process.argv.includes('--no-color');
37
+
38
+ function c(color, text) {
39
+ if (noColor) return text;
40
+ return `${colors[color]}${text}${colors.reset}`;
41
+ }
42
+
43
+ function log(message) {
44
+ console.log(message);
45
+ }
46
+
47
+ function error(message) {
48
+ console.error(c('red', `Error: ${message}`));
49
+ }
50
+
51
+ function success(message) {
52
+ console.log(c('green', `✓ ${message}`));
53
+ }
54
+
55
+ function warn(message) {
56
+ console.log(c('yellow', `⚠ ${message}`));
57
+ }
58
+
59
+ function info(message) {
60
+ console.log(c('cyan', `ℹ ${message}`));
61
+ }
62
+
63
+ /**
64
+ * Execute a git command and return output.
65
+ */
66
+ function git(args, options = {}) {
67
+ try {
68
+ const result = execSync(`git ${args}`, {
69
+ encoding: 'utf8',
70
+ stdio: options.silent ? ['pipe', 'pipe', 'pipe'] : undefined,
71
+ ...options,
72
+ });
73
+ return { success: true, output: result.trim() };
74
+ } catch (err) {
75
+ return {
76
+ success: false,
77
+ output: err.stdout?.trim() || '',
78
+ error: err.stderr?.trim() || err.message,
79
+ };
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Check if upstream remote is configured.
85
+ */
86
+ function hasUpstream() {
87
+ const result = git('remote -v', { silent: true });
88
+ return result.success && result.output.includes('upstream');
89
+ }
90
+
91
+ /**
92
+ * Get current version from package.json.
93
+ */
94
+ function getCurrentVersion() {
95
+ try {
96
+ const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
97
+ return pkg.version || '0.0.0';
98
+ } catch {
99
+ return '0.0.0';
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Get upstream version (latest tag or package.json).
105
+ */
106
+ function getUpstreamVersion() {
107
+ const result = git('show upstream/main:package.json', { silent: true });
108
+ if (result.success) {
109
+ try {
110
+ const pkg = JSON.parse(result.output);
111
+ return pkg.version || '0.0.0';
112
+ } catch {
113
+ return '0.0.0';
114
+ }
115
+ }
116
+ return '0.0.0';
117
+ }
118
+
119
+ /**
120
+ * Check for breaking version change.
121
+ */
122
+ function isBreakingChange(current, upstream) {
123
+ const currentMajor = parseInt(current.split('.')[0], 10);
124
+ const upstreamMajor = parseInt(upstream.split('.')[0], 10);
125
+ return upstreamMajor > currentMajor;
126
+ }
127
+
128
+ /**
129
+ * Check command: Preview what would sync.
130
+ */
131
+ function cmdCheck() {
132
+ log(c('bold', '\n=== Upstream Sync Check ===\n'));
133
+
134
+ // Verify upstream remote
135
+ if (!hasUpstream()) {
136
+ error('Upstream remote not configured.');
137
+ info('Run: git remote add upstream https://github.com/affaan-m/everything-claude-code.git');
138
+ process.exit(1);
139
+ }
140
+ success('Upstream remote configured');
141
+
142
+ // Fetch upstream
143
+ info('Fetching upstream...');
144
+ const fetchResult = git('fetch upstream');
145
+ if (!fetchResult.success) {
146
+ error(`Failed to fetch upstream: ${fetchResult.error}`);
147
+ process.exit(1);
148
+ }
149
+ success('Fetched upstream');
150
+
151
+ // Check version
152
+ const current = getCurrentVersion();
153
+ const upstream = getUpstreamVersion();
154
+ log(`\n${c('bold', 'Versions:')}`);
155
+ log(` Current: ${current}`);
156
+ log(` Upstream: ${upstream}`);
157
+
158
+ if (isBreakingChange(current, upstream)) {
159
+ warn(`Breaking change detected (${current} → ${upstream}). Manual review required.`);
160
+ }
161
+
162
+ // Show commits behind
163
+ const behindResult = git('rev-list --count HEAD..upstream/main', { silent: true });
164
+ const commitsBehind = parseInt(behindResult.output, 10) || 0;
165
+
166
+ log(`\n${c('bold', 'Status:')}`);
167
+ if (commitsBehind === 0) {
168
+ success('Already up to date with upstream');
169
+ return;
170
+ }
171
+ log(` ${commitsBehind} commit(s) behind upstream`);
172
+
173
+ // Show what would change
174
+ log(`\n${c('bold', 'Changed files in upstream:')}`);
175
+ const diffResult = git('diff --name-only HEAD..upstream/main', { silent: true });
176
+ if (diffResult.success && diffResult.output) {
177
+ const files = diffResult.output.split('\n');
178
+ const syncFiles = files.filter((f) => SYNC_DIRS.some((d) => f.startsWith(d)));
179
+ const protectedFiles = files.filter(
180
+ (f) => PROTECTED_DIRS.some((d) => f.startsWith(d)) || f === 'CLAUDE.md'
181
+ );
182
+ const otherFiles = files.filter((f) => !syncFiles.includes(f) && !protectedFiles.includes(f));
183
+
184
+ if (syncFiles.length > 0) {
185
+ log(`\n ${c('green', 'Will sync')} (${syncFiles.length} files):`);
186
+ syncFiles.slice(0, 10).forEach((f) => log(` ${f}`));
187
+ if (syncFiles.length > 10) log(` ... and ${syncFiles.length - 10} more`);
188
+ }
189
+
190
+ if (protectedFiles.length > 0) {
191
+ log(`\n ${c('yellow', 'Protected')} (${protectedFiles.length} files):`);
192
+ protectedFiles.forEach((f) => log(` ${f}`));
193
+ }
194
+
195
+ if (otherFiles.length > 0) {
196
+ log(`\n ${c('blue', 'Other changes')} (${otherFiles.length} files):`);
197
+ otherFiles.slice(0, 5).forEach((f) => log(` ${f}`));
198
+ if (otherFiles.length > 5) log(` ... and ${otherFiles.length - 5} more`);
199
+ }
200
+ }
201
+
202
+ log(`\n${c('bold', 'Next steps:')}`);
203
+ log(' npm run sync-dry-run # Test the merge');
204
+ log(' npm run sync-auto # Apply the sync');
205
+ }
206
+
207
+ /**
208
+ * Dry-run command: Test merge without committing.
209
+ */
210
+ function cmdDryRun() {
211
+ log(c('bold', '\n=== Upstream Sync Dry Run ===\n'));
212
+
213
+ if (!hasUpstream()) {
214
+ error('Upstream remote not configured.');
215
+ process.exit(1);
216
+ }
217
+
218
+ // Fetch upstream
219
+ info('Fetching upstream...');
220
+ git('fetch upstream');
221
+
222
+ // Check for uncommitted changes
223
+ const statusResult = git('status --porcelain', { silent: true });
224
+ if (statusResult.output) {
225
+ warn('You have uncommitted changes. Commit or stash them first.');
226
+ log(statusResult.output);
227
+ process.exit(1);
228
+ }
229
+
230
+ // Try merge with --no-commit
231
+ info('Testing merge (no commit)...');
232
+ const mergeArgs = SYNC_DIRS.join(' ');
233
+ const mergeResult = git(`merge --no-commit --no-ff -X ours upstream/main -- ${mergeArgs}`, {
234
+ silent: true,
235
+ });
236
+
237
+ if (!mergeResult.success) {
238
+ if (mergeResult.error.includes('conflict')) {
239
+ warn('Merge would have conflicts:');
240
+ const conflictResult = git('diff --name-only --diff-filter=U', { silent: true });
241
+ if (conflictResult.output) {
242
+ conflictResult.output.split('\n').forEach((f) => log(` ${f}`));
243
+ }
244
+ } else {
245
+ error(`Merge test failed: ${mergeResult.error}`);
246
+ }
247
+ } else {
248
+ success('Merge would succeed without conflicts');
249
+ }
250
+
251
+ // Abort the test merge
252
+ git('merge --abort', { silent: true });
253
+ success('Test merge aborted (no changes made)');
254
+
255
+ log(`\n${c('bold', 'Next steps:')}`);
256
+ log(' npm run sync-auto # Apply the sync for real');
257
+ }
258
+
259
+ /**
260
+ * Auto command: Full sync with tests.
261
+ */
262
+ function cmdAuto() {
263
+ log(c('bold', '\n=== Upstream Sync Auto ===\n'));
264
+
265
+ if (!hasUpstream()) {
266
+ error('Upstream remote not configured.');
267
+ process.exit(1);
268
+ }
269
+
270
+ // Check for uncommitted changes
271
+ const statusResult = git('status --porcelain', { silent: true });
272
+ if (statusResult.output) {
273
+ error('You have uncommitted changes. Commit or stash them first.');
274
+ log(statusResult.output);
275
+ process.exit(1);
276
+ }
277
+
278
+ // Check version for breaking changes
279
+ git('fetch upstream');
280
+ const current = getCurrentVersion();
281
+ const upstream = getUpstreamVersion();
282
+
283
+ if (isBreakingChange(current, upstream)) {
284
+ error(`Breaking change detected (${current} → ${upstream}).`);
285
+ info('Major version changes require manual review.');
286
+ info('Review CHANGELOG.md on upstream, then merge manually.');
287
+ process.exit(1);
288
+ }
289
+
290
+ // Perform merge
291
+ info('Merging upstream changes...');
292
+ const mergeArgs = SYNC_DIRS.join(' ');
293
+ const mergeResult = git(`merge -X ours upstream/main -- ${mergeArgs}`);
294
+
295
+ if (!mergeResult.success) {
296
+ error('Merge failed. Resolve conflicts manually or run: npm run sync-abort');
297
+ process.exit(1);
298
+ }
299
+ success('Merge completed');
300
+
301
+ // Run tests
302
+ info('Running tests to validate...');
303
+ try {
304
+ execSync('npm test', { stdio: 'inherit' });
305
+ success('All tests passed');
306
+ } catch {
307
+ error('Tests failed after merge!');
308
+ warn('You may need to fix issues or run: npm run sync-abort');
309
+ process.exit(1);
310
+ }
311
+
312
+ // Show summary
313
+ log(`\n${c('bold', 'Sync completed successfully!')}`);
314
+ log(` Version: ${current} → ${upstream}`);
315
+ log(' Run: git push origin main # to deploy');
316
+ }
317
+
318
+ /**
319
+ * Abort command: Cancel in-progress merge.
320
+ */
321
+ function cmdAbort() {
322
+ log(c('bold', '\n=== Abort Sync ===\n'));
323
+
324
+ const result = git('merge --abort');
325
+ if (result.success) {
326
+ success('Merge aborted successfully');
327
+ } else if (result.error.includes('no merge')) {
328
+ info('No merge in progress');
329
+ } else {
330
+ error(`Failed to abort: ${result.error}`);
331
+ process.exit(1);
332
+ }
333
+ }
334
+
335
+ /**
336
+ * Show help.
337
+ */
338
+ function showHelp() {
339
+ log(`
340
+ ${c('bold', 'Upstream Sync Tool')}
341
+
342
+ Syncs fork with upstream repository while preserving customizations.
343
+
344
+ ${c('bold', 'Commands:')}
345
+ check Preview what would sync
346
+ dry-run Test merge without committing
347
+ auto Full sync + tests + commit
348
+ abort Cancel in-progress merge
349
+
350
+ ${c('bold', 'Usage:')}
351
+ npm run sync-check
352
+ npm run sync-dry-run
353
+ npm run sync-auto
354
+ npm run sync-abort
355
+
356
+ ${c('bold', 'Synced directories:')}
357
+ ${SYNC_DIRS.join(', ')}
358
+
359
+ ${c('bold', 'Protected (never synced):')}
360
+ ${PROTECTED_DIRS.join(', ')}, CLAUDE.md
361
+ `);
362
+ }
363
+
364
+ // Main
365
+ const command = process.argv[2];
366
+
367
+ switch (command) {
368
+ case 'check':
369
+ cmdCheck();
370
+ break;
371
+ case 'dry-run':
372
+ cmdDryRun();
373
+ break;
374
+ case 'auto':
375
+ cmdAuto();
376
+ break;
377
+ case 'abort':
378
+ cmdAbort();
379
+ break;
380
+ case 'help':
381
+ case '--help':
382
+ case '-h':
383
+ showHelp();
384
+ break;
385
+ default:
386
+ if (command) {
387
+ error(`Unknown command: ${command}`);
388
+ }
389
+ showHelp();
390
+ process.exit(command ? 1 : 0);
391
+ }
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Test script for @cloudstreamsoftware/claude-tools
4
+ * Validates package structure and basic functionality
5
+ */
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+
10
+ const ROOT = path.resolve(__dirname, '..');
11
+ let passed = 0;
12
+ let failed = 0;
13
+
14
+ function test(name, fn) {
15
+ try {
16
+ fn();
17
+ console.log(`✓ ${name}`);
18
+ passed++;
19
+ } catch (e) {
20
+ console.log(`✗ ${name}`);
21
+ console.log(` Error: ${e.message}`);
22
+ failed++;
23
+ }
24
+ }
25
+
26
+ function assert(condition, message) {
27
+ if (!condition) throw new Error(message || 'Assertion failed');
28
+ }
29
+
30
+ console.log('Running @cloudstreamsoftware/claude-tools tests...\n');
31
+
32
+ // Package structure tests
33
+ test('package.json exists', () => {
34
+ assert(fs.existsSync(path.join(ROOT, 'package.json')));
35
+ });
36
+
37
+ test('package.json is valid JSON', () => {
38
+ const pkg = require(path.join(ROOT, 'package.json'));
39
+ assert(pkg.name === '@cloudstreamsoftware/claude-tools');
40
+ });
41
+
42
+ test('bin/cloudstream-setup.js exists', () => {
43
+ assert(fs.existsSync(path.join(ROOT, 'bin', 'cloudstream-setup.js')));
44
+ });
45
+
46
+ test('bin/postinstall.js exists', () => {
47
+ assert(fs.existsSync(path.join(ROOT, 'bin', 'postinstall.js')));
48
+ });
49
+
50
+ test('hooks/hooks.json exists', () => {
51
+ assert(fs.existsSync(path.join(ROOT, 'hooks', 'hooks.json')));
52
+ });
53
+
54
+ test('hooks/hooks.json is valid JSON', () => {
55
+ const hooks = require(path.join(ROOT, 'hooks', 'hooks.json'));
56
+ assert(hooks.hooks, 'hooks.json should have a "hooks" property');
57
+ });
58
+
59
+ // Script tests
60
+ test('scripts/hooks/ directory exists', () => {
61
+ assert(fs.existsSync(path.join(ROOT, 'scripts', 'hooks')));
62
+ });
63
+
64
+ test('scripts/lib/ directory exists', () => {
65
+ assert(fs.existsSync(path.join(ROOT, 'scripts', 'lib')));
66
+ });
67
+
68
+ const requiredHookScripts = [
69
+ 'prompt-router.js',
70
+ 'prompt-analyzer.js',
71
+ 'credential-check.js',
72
+ 'session-start.js',
73
+ 'session-end.js',
74
+ 'quality-gate-enforcer.js',
75
+ 'skill-injector.js',
76
+ ];
77
+
78
+ requiredHookScripts.forEach(script => {
79
+ test(`scripts/hooks/${script} exists`, () => {
80
+ assert(fs.existsSync(path.join(ROOT, 'scripts', 'hooks', script)));
81
+ });
82
+ });
83
+
84
+ // Build output tests (if dist exists)
85
+ if (fs.existsSync(path.join(ROOT, 'dist'))) {
86
+ test('dist/index.js exists', () => {
87
+ assert(fs.existsSync(path.join(ROOT, 'dist', 'index.js')));
88
+ });
89
+
90
+ test('dist/index.js exports expected interface', () => {
91
+ const pkg = require(path.join(ROOT, 'dist', 'index.js'));
92
+ assert(pkg.root, 'Should export root path');
93
+ assert(pkg.paths, 'Should export paths object');
94
+ assert(typeof pkg.getHooksConfig === 'function', 'Should export getHooksConfig');
95
+ assert(typeof pkg.getSkills === 'function', 'Should export getSkills');
96
+ assert(typeof pkg.getAgents === 'function', 'Should export getAgents');
97
+ });
98
+ }
99
+
100
+ // Summary
101
+ console.log(`\n${'='.repeat(40)}`);
102
+ console.log(`Tests: ${passed + failed} total, ${passed} passed, ${failed} failed`);
103
+
104
+ if (failed > 0) {
105
+ process.exit(1);
106
+ } else {
107
+ console.log('\n✅ All tests passed!');
108
+ }