@paulduvall/claude-dev-toolkit 0.0.1-alpha.1

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.
@@ -0,0 +1,545 @@
1
+ /**
2
+ * 🟢 GREEN PHASE: REQ-023 Claude Code Compatibility
3
+ *
4
+ * Detects Claude Code installation status and provides compatibility guidance.
5
+ * Handles version validation and provides installation/upgrade instructions.
6
+ *
7
+ * Features:
8
+ * - Claude Code installation detection
9
+ * - Version compatibility validation
10
+ * - Platform-specific installation instructions
11
+ * - Configuration validation
12
+ * - Error handling integration
13
+ */
14
+
15
+ const { execSync } = require('child_process');
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+ const os = require('os');
19
+ const PlatformUtils = require('./platform-utils');
20
+ const ErrorFactory = require('./error-factory');
21
+ const ErrorRecoverySystem = require('./error-recovery-system');
22
+
23
+ class ClaudeCodeCompatibility {
24
+ constructor() {
25
+ this.platformUtils = new PlatformUtils();
26
+ this.errorFactory = new ErrorFactory();
27
+ this.errorRecovery = new ErrorRecoverySystem();
28
+ this.config = {
29
+ minimumVersion: '0.1.0',
30
+ recommendedVersion: '0.2.0',
31
+ downloadUrls: {
32
+ win32: 'https://claude.ai/download/windows',
33
+ darwin: 'https://claude.ai/download/mac',
34
+ linux: 'https://claude.ai/download/linux'
35
+ },
36
+ configPaths: {
37
+ win32: path.join(os.homedir(), 'AppData', 'Roaming', 'claude', 'settings.json'),
38
+ darwin: path.join(os.homedir(), '.config', 'claude', 'settings.json'),
39
+ linux: path.join(os.homedir(), '.config', 'claude', 'settings.json')
40
+ }
41
+ };
42
+ }
43
+
44
+ /**
45
+ * Check if Claude Code is installed
46
+ * @returns {Object} Installation status and details
47
+ */
48
+ checkClaudeCodeInstallation() {
49
+ try {
50
+ const versionOutput = execSync('claude --version', { encoding: 'utf8', timeout: 5000 });
51
+ const version = this._extractVersion(versionOutput);
52
+ const installPath = this._getClaudeCodePath();
53
+
54
+ return {
55
+ installed: true,
56
+ version: version,
57
+ path: installPath
58
+ };
59
+ } catch (error) {
60
+ return {
61
+ installed: false,
62
+ version: null,
63
+ path: null,
64
+ error: error.message
65
+ };
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Validate Claude Code version compatibility
71
+ * @param {string} currentVersion - Current installed version
72
+ * @param {string} minimumRequired - Minimum required version
73
+ * @returns {Object} Compatibility validation result
74
+ */
75
+ validateClaudeCodeVersion(currentVersion, minimumRequired = this.config.minimumVersion) {
76
+ const compatible = this._compareVersions(currentVersion, minimumRequired) >= 0;
77
+
78
+ return {
79
+ compatible: compatible,
80
+ currentVersion: currentVersion,
81
+ minimumRequired: minimumRequired,
82
+ recommendedVersion: this.config.recommendedVersion
83
+ };
84
+ }
85
+
86
+ /**
87
+ * Generate installation instructions for missing Claude Code
88
+ * @param {string} platform - Target platform
89
+ * @returns {Object} Installation instructions
90
+ */
91
+ generateInstallationInstructions(platform = process.platform) {
92
+ const instructions = {
93
+ platform: platform,
94
+ summary: `Install Claude Code for ${this.platformUtils.getPlatformName(platform)}`,
95
+ downloadUrl: this.config.downloadUrls[platform],
96
+ steps: [],
97
+ verificationSteps: []
98
+ };
99
+
100
+ switch (platform) {
101
+ case 'win32':
102
+ instructions.steps = [
103
+ '1. Download Claude Code from the official website',
104
+ '2. Run the installer as Administrator',
105
+ '3. Follow the installation wizard',
106
+ '4. Restart your command prompt or PowerShell'
107
+ ];
108
+ instructions.verificationSteps = [
109
+ 'Open Command Prompt or PowerShell',
110
+ 'Run: claude --version',
111
+ 'Verify version output is displayed'
112
+ ];
113
+ break;
114
+ case 'darwin':
115
+ instructions.steps = [
116
+ '1. Download Claude Code for Mac',
117
+ '2. Open the .dmg file',
118
+ '3. Drag Claude Code to Applications folder',
119
+ '4. Add to PATH: echo "export PATH=$PATH:/Applications/Claude.app/Contents/MacOS" >> ~/.zshrc'
120
+ ];
121
+ instructions.verificationSteps = [
122
+ 'Open Terminal',
123
+ 'Run: source ~/.zshrc',
124
+ 'Run: claude --version',
125
+ 'Verify installation is working'
126
+ ];
127
+ break;
128
+ case 'linux':
129
+ instructions.steps = [
130
+ '1. Download Claude Code for Linux',
131
+ '2. Extract the archive: tar -xzf claude-linux.tar.gz',
132
+ '3. Move to system directory: sudo mv claude /usr/local/bin/',
133
+ '4. Make executable: sudo chmod +x /usr/local/bin/claude'
134
+ ];
135
+ instructions.verificationSteps = [
136
+ 'Open terminal',
137
+ 'Run: which claude',
138
+ 'Run: claude --version',
139
+ 'Verify command is found and version displays'
140
+ ];
141
+ break;
142
+ }
143
+
144
+ return instructions;
145
+ }
146
+
147
+ /**
148
+ * Generate upgrade instructions for incompatible versions
149
+ * @param {string} currentVersion - Current version
150
+ * @param {string} minimumRequired - Minimum required version
151
+ * @param {string} platform - Target platform
152
+ * @returns {Object} Upgrade instructions
153
+ */
154
+ generateUpgradeInstructions(currentVersion, minimumRequired, platform = process.platform) {
155
+ return {
156
+ summary: `Upgrade Claude Code from ${currentVersion} to ${minimumRequired} or higher`,
157
+ currentVersion: currentVersion,
158
+ targetVersion: minimumRequired,
159
+ platform: platform,
160
+ backupRecommendation: 'Backup your current Claude Code settings before upgrading',
161
+ upgradeSteps: [
162
+ '1. Download the latest version from the official website',
163
+ '2. Close any running Claude Code instances',
164
+ '3. Run the new installer/upgrade package',
165
+ '4. Verify the upgrade was successful'
166
+ ],
167
+ verificationSteps: [
168
+ 'Run: claude --version',
169
+ `Verify version is ${minimumRequired} or higher`,
170
+ 'Test basic Claude Code functionality'
171
+ ]
172
+ };
173
+ }
174
+
175
+ /**
176
+ * Check Claude Code configuration
177
+ * @param {Object} mockConfig - Mock configuration for testing
178
+ * @returns {Object} Configuration validation result
179
+ */
180
+ checkClaudeCodeConfiguration(mockConfig = null) {
181
+ if (mockConfig) {
182
+ return {
183
+ valid: mockConfig.configExists,
184
+ issues: mockConfig.configExists ? [] : ['Configuration file not found'],
185
+ configPath: mockConfig.configPath,
186
+ recommendations: mockConfig.configExists ? [] : ['Run claude setup to create configuration']
187
+ };
188
+ }
189
+
190
+ const configPath = this.config.configPaths[process.platform];
191
+ const configExists = fs.existsSync(configPath);
192
+
193
+ const issues = [];
194
+ const recommendations = [];
195
+
196
+ if (!configExists) {
197
+ issues.push('Claude Code configuration file not found');
198
+ recommendations.push('Run "claude setup" to initialize configuration');
199
+ }
200
+
201
+ return {
202
+ valid: issues.length === 0,
203
+ issues: issues,
204
+ configPath: configPath,
205
+ recommendations: recommendations
206
+ };
207
+ }
208
+
209
+ /**
210
+ * Get resolution guidance for installation issues
211
+ * @param {string} issueType - Type of issue
212
+ * @returns {Object} Resolution guidance
213
+ */
214
+ getResolutionGuidance(issueType) {
215
+ const guidanceMap = {
216
+ 'not_installed': {
217
+ issue: 'not_installed',
218
+ description: 'Claude Code is not installed on this system',
219
+ priority: 'high',
220
+ solutions: [
221
+ 'Try: Download and install Claude Code from the official website',
222
+ 'Solution: Use your platform-specific package manager if available',
223
+ 'Step: Follow the installation instructions for your operating system'
224
+ ]
225
+ },
226
+ 'version_incompatible': {
227
+ issue: 'version_incompatible',
228
+ description: 'Installed Claude Code version is incompatible',
229
+ priority: 'high',
230
+ solutions: [
231
+ 'Try: Upgrade to the latest version of Claude Code',
232
+ 'Solution: Download and install the recommended version',
233
+ 'Step: Backup your settings before upgrading'
234
+ ]
235
+ },
236
+ 'path_not_found': {
237
+ issue: 'path_not_found',
238
+ description: 'Claude Code is installed but not in system PATH',
239
+ priority: 'medium',
240
+ solutions: [
241
+ 'Try: Add Claude Code installation directory to your PATH',
242
+ 'Solution: Restart your terminal or command prompt',
243
+ 'Step: Verify PATH configuration in your shell profile'
244
+ ]
245
+ },
246
+ 'permission_denied': {
247
+ issue: 'permission_denied',
248
+ description: 'Permission denied when accessing Claude Code',
249
+ priority: 'medium',
250
+ solutions: [
251
+ 'Try: Run as administrator or with sudo',
252
+ 'Solution: Check file permissions on Claude Code executable',
253
+ 'Step: Reinstall with proper permissions'
254
+ ]
255
+ },
256
+ 'corrupted_installation': {
257
+ issue: 'corrupted_installation',
258
+ description: 'Claude Code installation appears corrupted',
259
+ priority: 'high',
260
+ solutions: [
261
+ 'Try: Reinstall Claude Code completely',
262
+ 'Solution: Remove existing installation first',
263
+ 'Step: Clear any cached configuration files'
264
+ ]
265
+ }
266
+ };
267
+
268
+ return guidanceMap[issueType] || {
269
+ issue: issueType,
270
+ description: 'Unknown Claude Code compatibility issue',
271
+ priority: 'medium',
272
+ solutions: ['Try: Check Claude Code documentation for troubleshooting']
273
+ };
274
+ }
275
+
276
+ /**
277
+ * Check for multiple Claude Code installations
278
+ * @returns {Object} Multiple installation check result
279
+ */
280
+ checkMultipleInstallations() {
281
+ // Simplified implementation for GREEN phase
282
+ return {
283
+ multipleFound: false,
284
+ installations: [],
285
+ recommended: null
286
+ };
287
+ }
288
+
289
+ /**
290
+ * Resolve multiple installations
291
+ * @param {Array} installations - List of found installations
292
+ * @returns {Object} Resolution recommendation
293
+ */
294
+ resolveMultipleInstallations(installations) {
295
+ if (installations.length === 0) {
296
+ return {
297
+ recommended: null,
298
+ reasoning: 'No installations found',
299
+ cleanupSuggestions: []
300
+ };
301
+ }
302
+
303
+ // Find the highest version installation
304
+ let recommended = installations[0];
305
+ for (const installation of installations) {
306
+ if (this._compareVersions(installation.version, recommended.version) > 0) {
307
+ recommended = installation;
308
+ }
309
+ }
310
+
311
+ const others = installations.filter(inst => inst !== recommended);
312
+
313
+ return {
314
+ recommended: recommended,
315
+ reasoning: `Recommended version ${recommended.version} at ${recommended.path}`,
316
+ cleanupSuggestions: others.map(inst =>
317
+ `Remove installation at ${inst.path} (version ${inst.version})`
318
+ )
319
+ };
320
+ }
321
+
322
+ /**
323
+ * Validate Claude Code CLI access and permissions
324
+ * @returns {Object} Access validation result
325
+ */
326
+ validateClaudeCodeAccess() {
327
+ try {
328
+ execSync('claude --help', { encoding: 'utf8', timeout: 5000 });
329
+
330
+ return {
331
+ accessible: true,
332
+ executable: true,
333
+ permissions: 'valid',
334
+ pathIssues: false
335
+ };
336
+ } catch (error) {
337
+ const resolutionSteps = [
338
+ 'Check if Claude Code is installed',
339
+ 'Verify PATH environment variable includes Claude Code',
340
+ 'Check file permissions on Claude Code executable'
341
+ ];
342
+
343
+ return {
344
+ accessible: false,
345
+ executable: false,
346
+ permissions: 'invalid',
347
+ pathIssues: true,
348
+ resolutionSteps: resolutionSteps
349
+ };
350
+ }
351
+ }
352
+
353
+ /**
354
+ * Handle installation errors with Claude Code specific guidance
355
+ * @param {Error} error - Installation error
356
+ * @returns {Object} Error handling result
357
+ */
358
+ handleInstallationError(error) {
359
+ const enhancedError = this.errorFactory.wrapError(error, {
360
+ component: 'claude-code-compatibility',
361
+ operation: 'installation',
362
+ claudeCodeSpecific: true
363
+ });
364
+
365
+ return {
366
+ handled: true,
367
+ claudeCodeSpecific: true,
368
+ error: enhancedError,
369
+ guidance: {
370
+ summary: 'Claude Code installation error detected',
371
+ errorCode: enhancedError.code,
372
+ errorMessage: enhancedError.message,
373
+ claudeSpecific: 'This error is related to Claude Code CLI installation'
374
+ },
375
+ nextSteps: [
376
+ 'Verify Claude Code is properly installed',
377
+ 'Check system PATH configuration',
378
+ 'Review Claude Code installation instructions'
379
+ ]
380
+ };
381
+ }
382
+
383
+ /**
384
+ * Check system environment compatibility
385
+ * @returns {Object} Environment compatibility result
386
+ */
387
+ checkSystemEnvironment() {
388
+ const requirements = [
389
+ {
390
+ name: 'node',
391
+ version: '>=16.0.0',
392
+ satisfied: this._checkNodeVersion()
393
+ },
394
+ {
395
+ name: 'npm',
396
+ version: '>=7.0.0',
397
+ satisfied: this._checkNpmVersion()
398
+ }
399
+ ];
400
+
401
+ const issues = requirements.filter(req => !req.satisfied)
402
+ .map(req => `${req.name} requirement not met: needs ${req.version}`);
403
+
404
+ return {
405
+ compatible: issues.length === 0,
406
+ requirements: requirements,
407
+ issues: issues,
408
+ recommendations: issues.length > 0 ? [
409
+ 'Update Node.js to latest LTS version',
410
+ 'Update npm to latest version'
411
+ ] : []
412
+ };
413
+ }
414
+
415
+ /**
416
+ * Generate comprehensive compatibility report
417
+ * @returns {Object} Complete compatibility report
418
+ */
419
+ generateCompatibilityReport() {
420
+ const installation = this.checkClaudeCodeInstallation();
421
+ const configuration = this.checkClaudeCodeConfiguration();
422
+ const environment = this.checkSystemEnvironment();
423
+ const access = this.validateClaudeCodeAccess();
424
+
425
+ const allIssues = [
426
+ ...(installation.installed ? [] : ['Claude Code not installed']),
427
+ ...configuration.issues,
428
+ ...environment.issues,
429
+ ...(access.accessible ? [] : ['Claude Code not accessible'])
430
+ ];
431
+
432
+ const recommendations = [
433
+ ...configuration.recommendations,
434
+ ...environment.recommendations,
435
+ ...(access.resolutionSteps || [])
436
+ ];
437
+
438
+ const resolutionPlan = {
439
+ steps: allIssues.length > 0 ? [
440
+ 'Address installation issues first',
441
+ 'Configure system environment',
442
+ 'Verify Claude Code accessibility',
443
+ 'Test basic functionality'
444
+ ] : []
445
+ };
446
+
447
+ return {
448
+ timestamp: new Date().toISOString(),
449
+ installation: installation,
450
+ version: installation.installed ?
451
+ this.validateClaudeCodeVersion(installation.version) : {
452
+ compatible: false,
453
+ currentVersion: null,
454
+ minimumRequired: '0.1.0',
455
+ message: 'Claude Code not installed'
456
+ },
457
+ configuration: configuration,
458
+ environment: environment,
459
+ summary: {
460
+ compatible: allIssues.length === 0,
461
+ issues: allIssues,
462
+ recommendations: recommendations
463
+ },
464
+ resolutionPlan: resolutionPlan
465
+ };
466
+ }
467
+
468
+ /**
469
+ * Extract version from command output
470
+ * @param {string} output - Command output
471
+ * @returns {string} Extracted version
472
+ * @private
473
+ */
474
+ _extractVersion(output) {
475
+ const versionMatch = output.match(/(\d+\.\d+\.\d+)/);
476
+ return versionMatch ? versionMatch[1] : 'unknown';
477
+ }
478
+
479
+ /**
480
+ * Get Claude Code installation path
481
+ * @returns {string} Installation path
482
+ * @private
483
+ */
484
+ _getClaudeCodePath() {
485
+ try {
486
+ const command = this.platformUtils.resolveCommand('which', process.platform) + ' claude';
487
+ return execSync(command, { encoding: 'utf8', timeout: 3000 }).trim();
488
+ } catch (error) {
489
+ return 'unknown';
490
+ }
491
+ }
492
+
493
+ /**
494
+ * Compare version strings
495
+ * @param {string} version1 - First version
496
+ * @param {string} version2 - Second version
497
+ * @returns {number} Comparison result (-1, 0, 1)
498
+ * @private
499
+ */
500
+ _compareVersions(version1, version2) {
501
+ const v1Parts = version1.split('.').map(Number);
502
+ const v2Parts = version2.split('.').map(Number);
503
+
504
+ for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
505
+ const v1Part = v1Parts[i] || 0;
506
+ const v2Part = v2Parts[i] || 0;
507
+
508
+ if (v1Part > v2Part) return 1;
509
+ if (v1Part < v2Part) return -1;
510
+ }
511
+
512
+ return 0;
513
+ }
514
+
515
+
516
+ /**
517
+ * Check Node.js version requirement
518
+ * @returns {boolean} Whether Node.js version is satisfied
519
+ * @private
520
+ */
521
+ _checkNodeVersion() {
522
+ try {
523
+ const nodeVersion = process.version.substring(1); // Remove 'v' prefix
524
+ return this._compareVersions(nodeVersion, '16.0.0') >= 0;
525
+ } catch (error) {
526
+ return false;
527
+ }
528
+ }
529
+
530
+ /**
531
+ * Check npm version requirement
532
+ * @returns {boolean} Whether npm version is satisfied
533
+ * @private
534
+ */
535
+ _checkNpmVersion() {
536
+ try {
537
+ const npmVersion = execSync('npm --version', { encoding: 'utf8', timeout: 5000 }).trim();
538
+ return this._compareVersions(npmVersion, '7.0.0') >= 0;
539
+ } catch (error) {
540
+ return false;
541
+ }
542
+ }
543
+ }
544
+
545
+ module.exports = ClaudeCodeCompatibility;