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 +28 -0
- package/CLAUDE.md +90 -0
- package/README.fr.md +6 -6
- package/README.md +6 -6
- package/eslint.config.js +20 -0
- package/index.js +50 -22
- package/package.json +11 -3
- package/src/detectors/claude-only.js +219 -0
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://
|
|
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://
|
|
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://
|
|
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://
|
|
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://
|
|
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 à `
|
|
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://
|
|
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://
|
|
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://
|
|
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://
|
|
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://
|
|
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 `
|
|
221
|
+
3. Check your network connection to `routerlab.ch`
|
|
222
222
|
|
|
223
223
|
---
|
|
224
224
|
|
package/eslint.config.js
ADDED
|
@@ -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
|
|
6
|
+
import updateNotifier from 'update-notifier';
|
|
7
7
|
import process from 'node:process';
|
|
8
8
|
import { createRequire } from 'node:module';
|
|
9
|
-
import
|
|
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.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
//
|
|
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
|
-
|
|
31
|
-
|
|
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
|
-
|
|
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
|
-
|
|
39
|
-
console.log(chalk.
|
|
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
|
|
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://
|
|
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://
|
|
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
|
|
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": "
|
|
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.
|
|
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
|
+
};
|