@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.
- package/README.md +152 -37
- package/agents/INDEX.md +183 -0
- package/agents/architect.md +247 -0
- package/agents/build-error-resolver.md +555 -0
- package/agents/catalyst-deployer.md +132 -0
- package/agents/code-reviewer.md +121 -0
- package/agents/compliance-auditor.md +148 -0
- package/agents/creator-architect.md +395 -0
- package/agents/deluge-reviewer.md +98 -0
- package/agents/doc-updater.md +471 -0
- package/agents/e2e-runner.md +711 -0
- package/agents/planner.md +122 -0
- package/agents/refactor-cleaner.md +309 -0
- package/agents/security-reviewer.md +582 -0
- package/agents/tdd-guide.md +302 -0
- package/config/versions.json +63 -0
- package/dist/hooks/hooks.json +209 -0
- package/dist/index.js +47 -0
- package/dist/lib/asset-value.js +609 -0
- package/dist/lib/client-manager.js +300 -0
- package/dist/lib/command-matcher.js +242 -0
- package/dist/lib/cross-session-patterns.js +754 -0
- package/dist/lib/intent-classifier.js +1075 -0
- package/dist/lib/package-manager.js +374 -0
- package/dist/lib/recommendation-engine.js +597 -0
- package/dist/lib/session-memory.js +489 -0
- package/dist/lib/skill-effectiveness.js +486 -0
- package/dist/lib/skill-matcher.js +595 -0
- package/dist/lib/tutorial-metrics.js +242 -0
- package/dist/lib/tutorial-progress.js +209 -0
- package/dist/lib/tutorial-renderer.js +431 -0
- package/dist/lib/utils.js +380 -0
- package/dist/lib/verify-formatter.js +143 -0
- package/dist/lib/workflow-state.js +249 -0
- package/hooks/hooks.json +209 -0
- package/package.json +5 -1
- package/scripts/aggregate-sessions.js +290 -0
- package/scripts/branch-name-validator.js +291 -0
- package/scripts/build.js +101 -0
- package/scripts/commands/client-switch.js +231 -0
- package/scripts/deprecate-skill.js +610 -0
- package/scripts/diagnose.js +324 -0
- package/scripts/doc-freshness.js +168 -0
- package/scripts/generate-weekly-digest.js +393 -0
- package/scripts/health-check.js +270 -0
- package/scripts/hooks/credential-check.js +101 -0
- package/scripts/hooks/evaluate-session.js +81 -0
- package/scripts/hooks/pre-compact.js +66 -0
- package/scripts/hooks/prompt-analyzer.js +276 -0
- package/scripts/hooks/prompt-router.js +422 -0
- package/scripts/hooks/quality-gate-enforcer.js +371 -0
- package/scripts/hooks/session-end.js +156 -0
- package/scripts/hooks/session-start.js +195 -0
- package/scripts/hooks/skill-injector.js +333 -0
- package/scripts/hooks/suggest-compact.js +58 -0
- package/scripts/lib/asset-value.js +609 -0
- package/scripts/lib/client-manager.js +300 -0
- package/scripts/lib/command-matcher.js +242 -0
- package/scripts/lib/cross-session-patterns.js +754 -0
- package/scripts/lib/intent-classifier.js +1075 -0
- package/scripts/lib/package-manager.js +374 -0
- package/scripts/lib/recommendation-engine.js +597 -0
- package/scripts/lib/session-memory.js +489 -0
- package/scripts/lib/skill-effectiveness.js +486 -0
- package/scripts/lib/skill-matcher.js +595 -0
- package/scripts/lib/tutorial-metrics.js +242 -0
- package/scripts/lib/tutorial-progress.js +209 -0
- package/scripts/lib/tutorial-renderer.js +431 -0
- package/scripts/lib/utils.js +380 -0
- package/scripts/lib/verify-formatter.js +143 -0
- package/scripts/lib/workflow-state.js +249 -0
- package/scripts/onboard.js +363 -0
- package/scripts/quarterly-report.js +692 -0
- package/scripts/setup-package-manager.js +204 -0
- package/scripts/sync-upstream.js +391 -0
- package/scripts/test.js +108 -0
- package/scripts/tutorial-runner.js +351 -0
- package/scripts/validate-all.js +201 -0
- package/scripts/verifiers/agents.js +245 -0
- package/scripts/verifiers/config.js +186 -0
- package/scripts/verifiers/environment.js +123 -0
- package/scripts/verifiers/hooks.js +188 -0
- package/scripts/verifiers/index.js +38 -0
- package/scripts/verifiers/persistence.js +140 -0
- package/scripts/verifiers/plugin.js +215 -0
- package/scripts/verifiers/skills.js +209 -0
- package/scripts/verify-setup.js +164 -0
- package/skills/INDEX.md +157 -0
- package/skills/backend-patterns/SKILL.md +586 -0
- package/skills/backend-patterns/catalyst-patterns.md +128 -0
- package/skills/bigquery-patterns/SKILL.md +27 -0
- package/skills/bigquery-patterns/performance-optimization.md +518 -0
- package/skills/bigquery-patterns/query-patterns.md +372 -0
- package/skills/bigquery-patterns/schema-design.md +78 -0
- package/skills/cloudstream-project-template/SKILL.md +20 -0
- package/skills/cloudstream-project-template/structure.md +65 -0
- package/skills/coding-standards/SKILL.md +524 -0
- package/skills/coding-standards/deluge-standards.md +83 -0
- package/skills/compliance-patterns/SKILL.md +28 -0
- package/skills/compliance-patterns/hipaa/audit-requirements.md +251 -0
- package/skills/compliance-patterns/hipaa/baa-process.md +298 -0
- package/skills/compliance-patterns/hipaa/data-archival-strategy.md +387 -0
- package/skills/compliance-patterns/hipaa/phi-handling.md +52 -0
- package/skills/compliance-patterns/pci-dss/saq-a-requirements.md +307 -0
- package/skills/compliance-patterns/pci-dss/tokenization-patterns.md +382 -0
- package/skills/compliance-patterns/pci-dss/zoho-checkout-patterns.md +56 -0
- package/skills/compliance-patterns/soc2/access-controls.md +344 -0
- package/skills/compliance-patterns/soc2/audit-logging.md +458 -0
- package/skills/compliance-patterns/soc2/change-management.md +403 -0
- package/skills/compliance-patterns/soc2/deluge-execution-logging.md +407 -0
- package/skills/consultancy-workflows/SKILL.md +19 -0
- package/skills/consultancy-workflows/client-isolation.md +21 -0
- package/skills/consultancy-workflows/documentation-automation.md +454 -0
- package/skills/consultancy-workflows/handoff-procedures.md +257 -0
- package/skills/consultancy-workflows/knowledge-capture.md +513 -0
- package/skills/consultancy-workflows/time-tracking.md +26 -0
- package/skills/continuous-learning/SKILL.md +84 -0
- package/skills/continuous-learning/config.json +18 -0
- package/skills/continuous-learning/evaluate-session.sh +60 -0
- package/skills/continuous-learning-v2/SKILL.md +126 -0
- package/skills/continuous-learning-v2/config.json +61 -0
- package/skills/frontend-patterns/SKILL.md +635 -0
- package/skills/frontend-patterns/zoho-widget-patterns.md +103 -0
- package/skills/gcp-data-engineering/SKILL.md +36 -0
- package/skills/gcp-data-engineering/bigquery/performance-optimization.md +337 -0
- package/skills/gcp-data-engineering/dataflow/error-handling.md +496 -0
- package/skills/gcp-data-engineering/dataflow/pipeline-patterns.md +444 -0
- package/skills/gcp-data-engineering/dbt/model-organization.md +63 -0
- package/skills/gcp-data-engineering/dbt/testing-patterns.md +503 -0
- package/skills/gcp-data-engineering/medallion-architecture/bronze-layer.md +60 -0
- package/skills/gcp-data-engineering/medallion-architecture/gold-layer.md +311 -0
- package/skills/gcp-data-engineering/medallion-architecture/layer-transitions.md +517 -0
- package/skills/gcp-data-engineering/medallion-architecture/silver-layer.md +305 -0
- package/skills/gcp-data-engineering/zoho-to-gcp/data-extraction.md +543 -0
- package/skills/gcp-data-engineering/zoho-to-gcp/real-time-vs-batch.md +337 -0
- package/skills/security-review/SKILL.md +498 -0
- package/skills/security-review/compliance-checklist.md +53 -0
- package/skills/strategic-compact/SKILL.md +67 -0
- package/skills/tdd-workflow/SKILL.md +413 -0
- package/skills/tdd-workflow/zoho-testing.md +124 -0
- package/skills/tutorial/SKILL.md +249 -0
- package/skills/tutorial/docs/ACCESSIBILITY.md +169 -0
- package/skills/tutorial/lessons/00-philosophy-and-workflow.md +198 -0
- package/skills/tutorial/lessons/01-basics.md +81 -0
- package/skills/tutorial/lessons/02-training.md +86 -0
- package/skills/tutorial/lessons/03-commands.md +109 -0
- package/skills/tutorial/lessons/04-workflows.md +115 -0
- package/skills/tutorial/lessons/05-compliance.md +116 -0
- package/skills/tutorial/lessons/06-zoho.md +121 -0
- package/skills/tutorial/lessons/07-hooks-system.md +277 -0
- package/skills/tutorial/lessons/08-mcp-servers.md +316 -0
- package/skills/tutorial/lessons/09-client-management.md +215 -0
- package/skills/tutorial/lessons/10-testing-e2e.md +260 -0
- package/skills/tutorial/lessons/11-skills-deep-dive.md +272 -0
- package/skills/tutorial/lessons/12-rules-system.md +326 -0
- package/skills/tutorial/lessons/13-golden-standard-graduation.md +213 -0
- package/skills/tutorial/lessons/14-fork-setup-and-sync.md +312 -0
- package/skills/tutorial/lessons/15-living-examples-system.md +221 -0
- package/skills/tutorial/tracks/accelerated/README.md +134 -0
- package/skills/tutorial/tracks/accelerated/assessment/checkpoint-1.md +161 -0
- package/skills/tutorial/tracks/accelerated/assessment/checkpoint-2.md +175 -0
- package/skills/tutorial/tracks/accelerated/day-1-core-concepts.md +234 -0
- package/skills/tutorial/tracks/accelerated/day-2-essential-commands.md +270 -0
- package/skills/tutorial/tracks/accelerated/day-3-workflow-mastery.md +305 -0
- package/skills/tutorial/tracks/accelerated/day-4-compliance-zoho.md +304 -0
- package/skills/tutorial/tracks/accelerated/day-5-hooks-skills.md +344 -0
- package/skills/tutorial/tracks/accelerated/day-6-client-testing.md +386 -0
- package/skills/tutorial/tracks/accelerated/day-7-graduation.md +369 -0
- package/skills/zoho-patterns/CHANGELOG.md +108 -0
- package/skills/zoho-patterns/SKILL.md +446 -0
- package/skills/zoho-patterns/analytics/dashboard-patterns.md +352 -0
- package/skills/zoho-patterns/analytics/zoho-to-bigquery-pipeline.md +427 -0
- package/skills/zoho-patterns/catalyst/appsail-deployment.md +349 -0
- package/skills/zoho-patterns/catalyst/context-close-patterns.md +354 -0
- package/skills/zoho-patterns/catalyst/cron-batch-processing.md +374 -0
- package/skills/zoho-patterns/catalyst/function-patterns.md +439 -0
- package/skills/zoho-patterns/creator/form-design.md +304 -0
- package/skills/zoho-patterns/creator/publish-api-patterns.md +313 -0
- package/skills/zoho-patterns/creator/widget-integration.md +306 -0
- package/skills/zoho-patterns/creator/workflow-automation.md +253 -0
- package/skills/zoho-patterns/deluge/api-patterns.md +468 -0
- package/skills/zoho-patterns/deluge/batch-processing.md +403 -0
- package/skills/zoho-patterns/deluge/cross-app-integration.md +356 -0
- package/skills/zoho-patterns/deluge/error-handling.md +423 -0
- package/skills/zoho-patterns/deluge/syntax-reference.md +65 -0
- package/skills/zoho-patterns/integration/cors-proxy-architecture.md +426 -0
- package/skills/zoho-patterns/integration/crm-books-native-sync.md +277 -0
- package/skills/zoho-patterns/integration/oauth-token-management.md +461 -0
- package/skills/zoho-patterns/integration/zoho-flow-patterns.md +334 -0
|
@@ -0,0 +1,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
|
+
}
|
package/scripts/test.js
ADDED
|
@@ -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
|
+
}
|