claude-scionos 1.0.1 → 2.0.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/CHANGELOG.md CHANGED
@@ -5,6 +5,33 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.0.0] - 2025-12-12
9
+
10
+ ### ⚠️ BREAKING CHANGES
11
+ - Enhanced detection system replaces basic checks
12
+ - Improved error handling with detailed diagnostics
13
+ - Better cross-platform support and user guidance
14
+
15
+ ### Added
16
+ - **Advanced System Detection**: Comprehensive OS, shell, and environment detection
17
+ - **Enhanced Claude Code Detection**: Checks both directory and CLI availability with detailed status
18
+ - **Improved Git Bash Detection**: Better Windows support with automatic path discovery
19
+ - **Detailed Error Messages**: Actionable troubleshooting information for users
20
+ - **System Information Display**: Shows detected OS and shell during startup
21
+ - **Modular Architecture**: New `src/detectors/` directory for extensible detection logic
22
+
23
+ ### Improved
24
+ - **User Experience**: Much clearer feedback when something goes wrong
25
+ - **Cross-Platform Compatibility**: Better handling of Windows, macOS, and Linux
26
+ - **Installation Guidance**: OS-specific instructions when dependencies are missing
27
+ - **Code Organization**: Cleaner separation of concerns with dedicated detection modules
28
+
29
+ ### Technical Changes
30
+ - Replaced basic `which()` checks with comprehensive detection system
31
+ - Added support for detecting Claude Code configuration files
32
+ - Enhanced shell detection (PowerShell, CMD, bash, zsh, fish)
33
+ - Improved error recovery and user guidance
34
+
8
35
  ## [1.0.1] - 2025-11-29
9
36
 
10
37
  ### Added
@@ -41,5 +68,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
41
68
  - Automatic credential cleanup on exit
42
69
  - Environment variable isolation
43
70
 
71
+ [2.0.0]: https://github.com/ScioNos/claude-scionos/compare/v1.0.1...v2.0.0
44
72
  [1.0.1]: https://github.com/ScioNos/claude-scionos/compare/v1.0.0...v1.0.1
45
73
  [1.0.0]: https://github.com/ScioNos/claude-scionos/releases/tag/v1.0.0
package/CLAUDE.md ADDED
@@ -0,0 +1,90 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ claude-scionos is a lightweight Node.js CLI wrapper that provides ephemeral and secure execution of the official Claude Code CLI. It's designed for the SNIA environment and focuses on in-memory credential management with zero disk persistence.
8
+
9
+ ## Architecture
10
+
11
+ The project is a single-file Node.js application (`index.js`) that:
12
+
13
+ 1. **Validates prerequisites**: Checks if Claude Code CLI is installed and available in PATH
14
+ 2. **Windows-specific check**: Verifies Git Bash installation (required by Claude Code on Windows)
15
+ 3. **Secure token collection**: Uses `@inquirer/prompts` for masked password input
16
+ 4. **Environment isolation**: Creates isolated environment variables with:
17
+ - `ANTHROPIC_BASE_URL`: Set to `https://routerlab.ch` (hardcoded SNIA endpoint)
18
+ - `ANTHROPIC_AUTH_TOKEN`: User-provided token (memory only)
19
+ - `ANTHROPIC_API_KEY`: Explicitly set to empty string
20
+ 5. **Process spawning**: Launches Claude Code CLI with inherited stdio and custom environment
21
+
22
+ ## Key Dependencies
23
+
24
+ - `@inquirer/prompts`: For secure password input with masking
25
+ - `cross-spawn`: Platform-agnostic process spawning
26
+ - `chalk`: Terminal colors for user-friendly output
27
+ - `update-notifier`: Automatic npm update notifications
28
+ - `which`: Command availability checking
29
+
30
+ ## Development Commands
31
+
32
+ ```bash
33
+ # Run locally during development
34
+ node index.js
35
+
36
+ # Lint code
37
+ npm run lint
38
+
39
+ # Version bumping (automated commit messages)
40
+ npm run release:patch # Bump patch version
41
+ npm run release:minor # Bump minor version
42
+ npm run release:major # Bump major version
43
+
44
+ # Check for vulnerabilities
45
+ npm audit
46
+ ```
47
+
48
+ ## Testing
49
+
50
+ Currently no automated tests are configured. When implementing tests, focus on:
51
+ - Version flag handling (`--version`, `-v`)
52
+ - Claude Code CLI detection
53
+ - Windows Git Bash detection logic
54
+ - Token validation and environment setup
55
+
56
+ ## Release Process
57
+
58
+ 1. Update version in `package.json` if not using npm scripts
59
+ 2. Update `SESSION_SUMMARY.md` with changes
60
+ 3. Commit changes with descriptive message
61
+ 4. Publish to npm: `npm publish`
62
+ 5. Create GitHub release with changelog
63
+
64
+ ## Platform-Specific Behavior
65
+
66
+ ### Windows
67
+ - Requires Git Bash for Claude Code CLI to function
68
+ - Detects Git Bash in standard locations:
69
+ - `C:\Program Files\Git\bin\bash.exe` (64-bit)
70
+ - `C:\Program Files (x86)\Git\bin\bash.exe` (32-bit)
71
+ - Custom path via `CLAUDE_CODE_GIT_BASH_PATH` environment variable
72
+ - Provides clear error messages with installation guidance
73
+
74
+ ### Unix (macOS/Linux)
75
+ - No additional requirements beyond Claude Code CLI
76
+ - Standard Unix process spawning behavior
77
+
78
+ ## Important Constants
79
+
80
+ - `ANTHROPIC_BASE_URL`: `"https://routerlab.ch"` (SNIA-specific endpoint)
81
+ - Minimum Node.js version: 22
82
+ - Package entry point: `index.js` with shebang for direct execution
83
+
84
+ ## Code Style Notes
85
+
86
+ - ES6 modules throughout (`import`/`export`)
87
+ - Async/await pattern for asynchronous operations
88
+ - Colored terminal output using chalk
89
+ - Clear user error messages with actionable guidance
90
+ - Process exit codes: 0 (success), 1 (error)
package/README.fr.md CHANGED
@@ -60,7 +60,7 @@ Avant d'utiliser `claude-scionos`, assurez-vous d'avoir :
60
60
  npm install -g @anthropic-ai/claude-code
61
61
  ```
62
62
 
63
- - Un **ANTHROPIC_AUTH_TOKEN** valide depuis [https://hubs02225.snia.ch/console/token](https://hubs02225.snia.ch/console/token)
63
+ - Un **ANTHROPIC_AUTH_TOKEN** valide depuis [https://routerlab.ch/keys](https://routerlab.ch/keys)
64
64
 
65
65
  ---
66
66
 
@@ -113,7 +113,7 @@ npx claude-scionos
113
113
  $ npx claude-scionos
114
114
 
115
115
  Claude Code (via ScioNos)
116
- To retrieve your token, visit: https://hubs02225.snia.ch/console/token
116
+ To retrieve your token, visit: https://routerlab.ch/keys
117
117
  ? Please enter your ANTHROPIC_AUTH_TOKEN: ********
118
118
 
119
119
  # Claude Code démarre...
@@ -134,7 +134,7 @@ npx claude-scionos -v
134
134
  1. **Vérification** : Vérifie que la commande `claude` est disponible dans votre PATH
135
135
  2. **Saisie du jeton** : Demande de manière sécurisée votre jeton d'authentification (entrée masquée)
136
136
  3. **Configuration de l'environnement** : Crée des variables d'environnement isolées :
137
- - `ANTHROPIC_BASE_URL` → `https://hubs02225.snia.ch`
137
+ - `ANTHROPIC_BASE_URL` → `https://routerlab.ch`
138
138
  - `ANTHROPIC_AUTH_TOKEN` → Votre jeton (mémoire uniquement)
139
139
  4. **Exécution** : Lance le processus Claude Code avec l'environnement personnalisé
140
140
  5. **Nettoyage** : Détruit automatiquement les informations d'identification à la sortie
@@ -157,7 +157,7 @@ Bien que `claude-scionos` assure une sécurité maximale en conservant les jeton
157
157
  ✅ **Bonnes pratiques :**
158
158
 
159
159
  - Ne partagez jamais votre `ANTHROPIC_AUTH_TOKEN` avec d'autres personnes
160
- - Récupérez un nouveau jeton pour chaque session depuis [https://hubs02225.snia.ch/console/token](https://hubs02225.snia.ch/console/token)
160
+ - Récupérez un nouveau jeton pour chaque session depuis [https://routerlab.ch/keys](https://routerlab.ch/keys)
161
161
  - Évitez d'exécuter sur des systèmes partagés/non fiables
162
162
  - Utilisez pour le développement local ou des pipelines CI/CD sécurisés
163
163
 
@@ -216,9 +216,9 @@ claude --version
216
216
  **Problème :** Jeton invalide ou expiré.
217
217
 
218
218
  **Solution :**
219
- 1. Obtenez un nouveau jeton depuis [https://hubs02225.snia.ch/console/token](https://hubs02225.snia.ch/console/token)
219
+ 1. Obtenez un nouveau jeton depuis [https://routerlab.ch/keys](https://routerlab.ch/keys)
220
220
  2. Assurez-vous de copier le jeton complet (sans espaces supplémentaires)
221
- 3. Vérifiez votre connexion réseau à `hubs02225.snia.ch`
221
+ 3. Vérifiez votre connexion réseau à `routerlab.ch`
222
222
 
223
223
  ---
224
224
 
package/README.md CHANGED
@@ -60,7 +60,7 @@ Before using `claude-scionos`, ensure you have:
60
60
  npm install -g @anthropic-ai/claude-code
61
61
  ```
62
62
 
63
- - A valid **ANTHROPIC_AUTH_TOKEN** from [https://hubs02225.snia.ch/console/token](https://hubs02225.snia.ch/console/token)
63
+ - A valid **ANTHROPIC_AUTH_TOKEN** from [https://routerlab.ch/keys](https://routerlab.ch/keys)
64
64
 
65
65
  ---
66
66
 
@@ -113,7 +113,7 @@ npx claude-scionos
113
113
  $ npx claude-scionos
114
114
 
115
115
  Claude Code (via ScioNos)
116
- To retrieve your token, visit: https://hubs02225.snia.ch/console/token
116
+ To retrieve your token, visit: https://routerlab.ch/keys
117
117
  ? Please enter your ANTHROPIC_AUTH_TOKEN: ********
118
118
 
119
119
  # Claude Code starts...
@@ -134,7 +134,7 @@ npx claude-scionos -v
134
134
  1. **Verification**: Checks if `claude` command is available in your PATH
135
135
  2. **Token Input**: Securely prompts for your authentication token (masked input)
136
136
  3. **Environment Setup**: Creates isolated environment variables:
137
- - `ANTHROPIC_BASE_URL` → `https://hubs02225.snia.ch`
137
+ - `ANTHROPIC_BASE_URL` → `https://routerlab.ch`
138
138
  - `ANTHROPIC_AUTH_TOKEN` → Your token (memory only)
139
139
  4. **Execution**: Spawns Claude Code process with custom environment
140
140
  5. **Cleanup**: Automatically destroys credentials on exit
@@ -157,7 +157,7 @@ While `claude-scionos` ensures maximum security by keeping tokens in memory only
157
157
  ✅ **Best Practices:**
158
158
 
159
159
  - Never share your `ANTHROPIC_AUTH_TOKEN` with others
160
- - Retrieve a fresh token for each session from [https://hubs02225.snia.ch/console/token](https://hubs02225.snia.ch/console/token)
160
+ - Retrieve a fresh token for each session from [https://routerlab.ch/keys](https://routerlab.ch/keys)
161
161
  - Avoid running on shared/untrusted systems
162
162
  - Use for local development or secure CI/CD pipelines
163
163
 
@@ -216,9 +216,9 @@ claude --version
216
216
  **Problem:** Invalid or expired token.
217
217
 
218
218
  **Solution:**
219
- 1. Get a fresh token from [https://hubs02225.snia.ch/console/token](https://hubs02225.snia.ch/console/token)
219
+ 1. Get a fresh token from [https://routerlab.ch/keys](https://routerlab.ch/keys)
220
220
  2. Ensure you're copying the complete token (no extra spaces)
221
- 3. Check your network connection to `hubs02225.snia.ch`
221
+ 3. Check your network connection to `routerlab.ch`
222
222
 
223
223
  ---
224
224
 
@@ -0,0 +1,20 @@
1
+ import globals from 'globals';
2
+ import pluginJs from '@eslint/js';
3
+
4
+ export default [
5
+ {
6
+ languageOptions: {
7
+ globals: {
8
+ ...globals.node,
9
+ ...globals.builtin,
10
+ }
11
+ }
12
+ },
13
+ pluginJs.configs.recommended,
14
+ {
15
+ rules: {
16
+ 'no-console': 'off',
17
+ 'no-process-exit': 'off',
18
+ }
19
+ }
20
+ ];
package/index.js CHANGED
@@ -1,57 +1,84 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  import chalk from 'chalk';
4
4
  import { password } from '@inquirer/prompts';
5
5
  import spawn from 'cross-spawn';
6
- import which from 'which';
6
+ import updateNotifier from 'update-notifier';
7
7
  import process from 'node:process';
8
8
  import { createRequire } from 'node:module';
9
- import fs from 'node:fs';
9
+ import { isClaudeCodeInstalled, detectOS, checkGitBashOnWindows, getInstallationInstructions } from './src/detectors/claude-only.js';
10
10
 
11
11
  const require = createRequire(import.meta.url);
12
12
  const pkg = require('./package.json');
13
13
 
14
+ // Initialize update notifier
15
+ updateNotifier({ pkg }).notify();
16
+
14
17
  // 0. Handle --version / -v flag
15
18
  if (process.argv.includes('--version') || process.argv.includes('-v')) {
16
19
  console.log(pkg.version);
17
20
  process.exit(0);
18
21
  }
19
22
 
20
- // 1. Check if "claude" command is available
21
- try {
22
- await which('claude');
23
- } catch (error) {
24
- console.error(chalk.redBright("Error: 'claude' command not found. Please install Claude Code first: npm install -g @anthropic-ai/claude-code"));
23
+ // 1. Enhanced System Detection
24
+ console.log(chalk.cyan('🔍 Checking system configuration...'));
25
+
26
+ // Detect OS and environment
27
+ const osInfo = detectOS();
28
+ console.log(chalk.gray(`✓ OS: ${osInfo.type} (${osInfo.arch})`));
29
+ console.log(chalk.gray(`✓ Shell: ${osInfo.shell}`));
30
+
31
+ // Check Claude Code installation
32
+ const claudeStatus = isClaudeCodeInstalled();
33
+
34
+ if (!claudeStatus.installed) {
35
+ console.error(chalk.redBright('\n❌ Claude Code not found'));
36
+
37
+ // Show detailed detection info
38
+ console.log(chalk.yellow('\nDetection Details:'));
39
+ console.log(chalk.gray(claudeStatus.details));
40
+
41
+ // Show installation instructions
42
+ const instructions = getInstallationInstructions(osInfo, claudeStatus);
43
+ console.log(chalk.cyan(instructions));
44
+
25
45
  process.exit(1);
26
46
  }
27
47
 
28
- // 2. Check Git Bash on Windows
48
+ // Show Claude Code status
49
+ console.log(chalk.green('\n✓ Claude Code detected'));
50
+ console.log(chalk.gray(claudeStatus.details));
51
+
52
+ // 2. Check Git Bash on Windows (if needed)
29
53
  if (process.platform === 'win32') {
30
- const possiblePaths = [
31
- process.env.CLAUDE_CODE_GIT_BASH_PATH,
32
- 'C:\\Program Files\\Git\\bin\\bash.exe',
33
- 'C:\\Program Files (x86)\\Git\\bin\\bash.exe',
34
- ].filter(Boolean);
54
+ console.log(chalk.cyan('\n🔍 Checking Git Bash availability...'));
55
+ const gitBashStatus = checkGitBashOnWindows();
35
56
 
36
- const gitBashFound = possiblePaths.some(path => fs.existsSync(path));
57
+ if (!gitBashStatus.available) {
58
+ console.log(chalk.red('\n❌ Git Bash is required on Windows'));
59
+ console.log(chalk.gray(gitBashStatus.message));
37
60
 
38
- if (!gitBashFound) {
39
- console.log(chalk.red('\n Git Bash is required on Windows\n'));
40
- console.log(chalk.cyan('📥 Install Git for Windows:'));
61
+ // Show Git Bash installation instructions
62
+ console.log(chalk.cyan('\n📥 Install Git for Windows:'));
41
63
  console.log(chalk.white(' https://git-scm.com/downloads/win\n'));
42
64
  console.log(chalk.cyan('⚙️ Or set the path manually:'));
43
- console.log(chalk.white(' CLAUDE_CODE_GIT_BASH_PATH=C:\\Program Files\\Git\\bin\\bash.exe\n'));
65
+ console.log(chalk.white(' set CLAUDE_CODE_GIT_BASH_PATH=C:\\Program Files\\Git\\bin\\bash.exe'));
66
+ console.log(chalk.white(' (PowerShell: $env:CLAUDE_CODE_GIT_BASH_PATH="C:\\Program Files\\Git\\bin\\bash.exe")\n'));
44
67
  console.log(chalk.yellow('💡 After installation, restart your terminal and try again.\n'));
45
68
  process.exit(1);
69
+ } else {
70
+ console.log(chalk.green('✓ Git Bash available'));
71
+ console.log(chalk.gray(gitBashStatus.message));
46
72
  }
47
73
  }
48
74
 
49
75
  // 3. Intro
50
76
  console.clear();
51
77
  console.log(chalk.cyan.bold("Claude Code (via ScioNos)"));
78
+ console.log(chalk.gray(`Running on ${osInfo.type} with ${osInfo.shell}`));
52
79
 
53
80
  // 4. Token info
54
- console.log(chalk.blueBright("To retrieve your token, visit: https://hubs02225.snia.ch/console/token"));
81
+ console.log(chalk.blueBright("To retrieve your token, visit: https://routerlab.ch/keys"));
55
82
 
56
83
  // 5. Token input
57
84
  const token = await password({
@@ -68,13 +95,14 @@ const token = await password({
68
95
  // 6. Environment configuration
69
96
  const env = {
70
97
  ...process.env,
71
- ANTHROPIC_BASE_URL: "https://hubs02225.snia.ch",
98
+ ANTHROPIC_BASE_URL: "https://routerlab.ch",
72
99
  ANTHROPIC_AUTH_TOKEN: token,
73
100
  ANTHROPIC_API_KEY: "" // Force empty string
74
101
  };
75
102
 
76
103
  // 7. Launch Claude Code
77
- const child = spawn('claude', [], {
104
+ const args = process.argv.slice(2);
105
+ const child = spawn('claude', args, {
78
106
  stdio: 'inherit',
79
107
  env: env
80
108
  });
package/package.json CHANGED
@@ -1,13 +1,15 @@
1
1
  {
2
2
  "name": "claude-scionos",
3
- "version": "1.0.1",
3
+ "version": "2.0.0",
4
4
  "description": "Ephemeral and secure runner for Claude Code CLI in SNIA environment",
5
+ "type": "module",
5
6
  "main": "index.js",
6
7
  "bin": {
7
8
  "claude-scionos": "index.js"
8
9
  },
9
10
  "scripts": {
10
11
  "test": "echo \"Error: no test specified\" && exit 1",
12
+ "lint": "eslint .",
11
13
  "release:patch": "npm version patch -m \"Chore: Bump version to %s\"",
12
14
  "release:minor": "npm version minor -m \"Chore: Bump version to %s\"",
13
15
  "release:major": "npm version major -m \"Chore: Bump version to %s\""
@@ -33,9 +35,15 @@
33
35
  },
34
36
  "private": false,
35
37
  "dependencies": {
36
- "@inquirer/prompts": "^8.0.1",
38
+ "@inquirer/prompts": "^8.0.2",
37
39
  "chalk": "^5.6.2",
38
40
  "cross-spawn": "^7.0.6",
41
+ "update-notifier": "^7.3.1",
39
42
  "which": "^6.0.0"
43
+ },
44
+ "devDependencies": {
45
+ "@eslint/js": "^9.39.1",
46
+ "eslint": "^9.39.1",
47
+ "globals": "^16.5.0"
40
48
  }
41
- }
49
+ }
@@ -0,0 +1,219 @@
1
+ // Claude Code Detection Module for claude-scionos
2
+ import { execSync } from 'child_process';
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+ import os from 'os';
6
+
7
+ /**
8
+ * Detects if Claude Code is installed and returns detailed status
9
+ * @returns {{installed: boolean, path: string|null, configPath: string|null, cliAvailable: boolean, details: string}}
10
+ */
11
+ function isClaudeCodeInstalled() {
12
+ // Check for Claude Code directory in user home
13
+ const claudeDir = path.join(os.homedir(), '.claude');
14
+ const details = [];
15
+
16
+ if (fs.existsSync(claudeDir)) {
17
+ details.push(`✓ Found Claude directory: ${claudeDir}`);
18
+
19
+ // Check for settings.json to confirm it's actually Claude Code
20
+ const settingsPath = path.join(claudeDir, 'settings.json');
21
+ if (fs.existsSync(settingsPath)) {
22
+ details.push(`✓ Configuration file found: ${settingsPath}`);
23
+
24
+ // Try to read the config to see if it's configured
25
+ try {
26
+ const config = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
27
+ const hasBaseUrl = config.env?.ANTHROPIC_BASE_URL;
28
+ const hasApiKey = config.env?.ANTHROPIC_API_KEY;
29
+
30
+ if (hasBaseUrl && hasApiKey) {
31
+ details.push(`✓ Claude Code is configured with custom API`);
32
+ } else if (hasBaseUrl || hasApiKey) {
33
+ details.push(`⚠ Claude Code is partially configured`);
34
+ } else {
35
+ details.push(`ℹ Claude Code installed but not configured`);
36
+ }
37
+ } catch (error) {
38
+ details.push(`⚠ Could not read configuration file`);
39
+ }
40
+
41
+ return {
42
+ installed: true,
43
+ path: claudeDir,
44
+ configPath: settingsPath,
45
+ cliAvailable: false, // Will check next
46
+ details: details.join('\n ')
47
+ };
48
+ } else {
49
+ details.push(`⚠ Directory exists but no settings.json found`);
50
+ }
51
+ }
52
+
53
+ // Also check for the claude CLI command in PATH
54
+ try {
55
+ const command = process.platform === 'win32' ? 'where claude' : 'which claude';
56
+ const claudePath = execSync(command, { encoding: 'utf8' }).trim();
57
+
58
+ if (claudePath) {
59
+ details.push(`✓ Claude CLI found in PATH: ${claudePath}`);
60
+
61
+ // Try to get version to confirm it's working
62
+ try {
63
+ const version = execSync('claude --version', { encoding: 'utf8' }).trim();
64
+ details.push(`✓ Version: ${version}`);
65
+ } catch (error) {
66
+ details.push(`⚠ CLI found but version check failed`);
67
+ }
68
+
69
+ return {
70
+ installed: true,
71
+ path: claudeDir && fs.existsSync(claudeDir) ? claudeDir : null,
72
+ configPath: claudeDir && fs.existsSync(path.join(claudeDir, 'settings.json'))
73
+ ? path.join(claudeDir, 'settings.json')
74
+ : null,
75
+ cliAvailable: true,
76
+ cliPath: claudePath,
77
+ details: details.join('\n ')
78
+ };
79
+ }
80
+ } catch (error) {
81
+ details.push(`✗ Claude CLI not found in PATH`);
82
+ }
83
+
84
+ return {
85
+ installed: false,
86
+ path: null,
87
+ configPath: null,
88
+ cliAvailable: false,
89
+ details: details.join('\n ')
90
+ };
91
+ }
92
+
93
+ /**
94
+ * Detects operating system and shell information
95
+ * @returns {{platform: string, type: string, shell: string, arch: string}}
96
+ */
97
+ function detectOS() {
98
+ const platform = os.platform();
99
+ const arch = os.arch();
100
+ let type, shell;
101
+
102
+ switch (platform) {
103
+ case 'darwin':
104
+ type = 'macOS';
105
+ break;
106
+ case 'win32':
107
+ type = 'Windows';
108
+ break;
109
+ case 'linux':
110
+ type = 'Linux';
111
+ break;
112
+ default:
113
+ type = platform;
114
+ }
115
+
116
+ // Detect shell
117
+ if (process.platform === 'win32') {
118
+ if (process.env.PSModulePath) {
119
+ shell = 'PowerShell';
120
+ } else if (process.env.WINDIR) {
121
+ shell = 'Command Prompt (CMD)';
122
+ } else {
123
+ shell = 'Windows Shell';
124
+ }
125
+ } else {
126
+ const shellPath = process.env.SHELL || '';
127
+ if (shellPath.includes('zsh')) {
128
+ shell = 'Zsh';
129
+ } else if (shellPath.includes('bash')) {
130
+ shell = 'Bash';
131
+ } else if (shellPath.includes('fish')) {
132
+ shell = 'Fish';
133
+ } else if (shellPath) {
134
+ shell = shellPath.split('/').pop() || 'Unknown Unix Shell';
135
+ } else {
136
+ shell = 'Default Unix Shell';
137
+ }
138
+ }
139
+
140
+ return {
141
+ platform,
142
+ type,
143
+ shell,
144
+ arch
145
+ };
146
+ }
147
+
148
+ /**
149
+ * Checks Git Bash availability on Windows (required for Claude Code)
150
+ * @returns {{available: boolean, path: string|null, message: string}}
151
+ */
152
+ function checkGitBashOnWindows() {
153
+ if (process.platform !== 'win32') {
154
+ return { available: true, path: null, message: 'Not required on non-Windows systems' };
155
+ }
156
+
157
+ const possiblePaths = [
158
+ process.env.CLAUDE_CODE_GIT_BASH_PATH,
159
+ 'C:\\Program Files\\Git\\bin\\bash.exe',
160
+ 'C:\\Program Files (x86)\\Git\\bin\\bash.exe',
161
+ ].filter(Boolean);
162
+
163
+ for (const bashPath of possiblePaths) {
164
+ if (fs.existsSync(bashPath)) {
165
+ return {
166
+ available: true,
167
+ path: bashPath,
168
+ message: `Git Bash found at: ${bashPath}`
169
+ };
170
+ }
171
+ }
172
+
173
+ return {
174
+ available: false,
175
+ path: null,
176
+ message: 'Git Bash not found. Claude Code requires Git Bash on Windows.'
177
+ };
178
+ }
179
+
180
+ /**
181
+ * Provides installation instructions based on OS and current state
182
+ * @param {Object} osInfo - OS detection result
183
+ * @param {Object} claudeStatus - Claude Code detection result
184
+ * @returns {string} Installation instructions
185
+ */
186
+ function getInstallationInstructions(osInfo, claudeStatus) {
187
+ let instructions = [];
188
+
189
+ if (osInfo.type === 'Windows') {
190
+ instructions.push('\n📋 Installation Instructions for Windows:');
191
+ instructions.push('');
192
+ instructions.push('1. Install Git for Windows (includes Git Bash):');
193
+ instructions.push(' https://git-scm.com/downloads/win');
194
+ instructions.push('');
195
+ instructions.push('2. Install Claude Code CLI:');
196
+ instructions.push(' npm install -g @anthropic-ai/claude-code');
197
+ instructions.push('');
198
+ instructions.push('3. Restart your terminal and try again.');
199
+ instructions.push('');
200
+ instructions.push('💡 If Git Bash is installed but not detected:');
201
+ instructions.push(' set CLAUDE_CODE_GIT_BASH_PATH=C:\\Program Files\\Git\\bin\\bash.exe');
202
+ } else {
203
+ instructions.push('\n📋 Installation Instructions:');
204
+ instructions.push('');
205
+ instructions.push(`Install Claude Code CLI with npm:`);
206
+ instructions.push(' npm install -g @anthropic-ai/claude-code');
207
+ instructions.push('');
208
+ instructions.push('Then restart your terminal and try again.');
209
+ }
210
+
211
+ return instructions.join('\n');
212
+ }
213
+
214
+ export {
215
+ isClaudeCodeInstalled,
216
+ detectOS,
217
+ checkGitBashOnWindows,
218
+ getInstallationInstructions
219
+ };