claude-glm-alt-installer 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/bin/ccx ADDED
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
+ ENV_FILE="$HOME/.claude-proxy/.env"
6
+ PORT="${CLAUDE_PROXY_PORT:-17870}"
7
+
8
+ # Check if --setup flag is provided
9
+ if [ "${1:-}" = "--setup" ]; then
10
+ echo "Setting up ~/.claude-proxy/.env..."
11
+ mkdir -p "$HOME/.claude-proxy"
12
+
13
+ if [ -f "$ENV_FILE" ]; then
14
+ echo "Existing .env found. Edit it manually at: $ENV_FILE"
15
+ exit 0
16
+ fi
17
+
18
+ cat > "$ENV_FILE" << 'EOF'
19
+ # Claude Proxy Configuration
20
+ # Edit this file to add your API keys
21
+
22
+ # OpenAI (optional)
23
+ OPENAI_API_KEY=
24
+ OPENAI_BASE_URL=https://api.openai.com/v1
25
+
26
+ # OpenRouter (optional)
27
+ OPENROUTER_API_KEY=
28
+ OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
29
+ OPENROUTER_REFERER=
30
+ OPENROUTER_TITLE=Claude Code via ccx
31
+
32
+ # Gemini (optional)
33
+ GEMINI_API_KEY=
34
+ GEMINI_BASE_URL=https://generativelanguage.googleapis.com/v1beta
35
+
36
+ # Z.AI GLM (optional - for glm: routing)
37
+ GLM_UPSTREAM_URL=https://api.z.ai/api/anthropic
38
+ ZAI_API_KEY=
39
+
40
+ # Anthropic (optional - for anthropic: routing)
41
+ ANTHROPIC_UPSTREAM_URL=https://api.anthropic.com
42
+ ANTHROPIC_API_KEY=
43
+ ANTHROPIC_VERSION=2023-06-01
44
+
45
+ # Proxy settings
46
+ CLAUDE_PROXY_PORT=17870
47
+ EOF
48
+
49
+ echo "āœ… Created $ENV_FILE"
50
+ echo ""
51
+ echo "Edit it to add your API keys, then run: ccx"
52
+ echo ""
53
+ echo "Example:"
54
+ echo " nano $ENV_FILE"
55
+ exit 0
56
+ fi
57
+
58
+ # Source the .env file if it exists
59
+ if [ -f "$ENV_FILE" ]; then
60
+ set -a
61
+ source "$ENV_FILE"
62
+ set +a
63
+ fi
64
+
65
+ export ANTHROPIC_BASE_URL="http://127.0.0.1:${PORT}"
66
+ export ANTHROPIC_AUTH_TOKEN="${ANTHROPIC_AUTH_TOKEN:-local-proxy-token}"
67
+
68
+ echo "[ccx] Starting Claude Code with multi-provider proxy..."
69
+ echo "[ccx] Proxy will listen on: ${ANTHROPIC_BASE_URL}"
70
+
71
+ # Start proxy in background
72
+ npx -y tsx "${ROOT_DIR}/adapters/anthropic-gateway.ts" > /tmp/claude-proxy.log 2>&1 &
73
+ PROXY_PID=$!
74
+
75
+ cleanup() {
76
+ echo ""
77
+ echo "[ccx] Shutting down proxy..."
78
+ kill ${PROXY_PID} 2>/dev/null || true
79
+ }
80
+ trap cleanup EXIT INT TERM
81
+
82
+ # Wait for proxy to be ready (health check)
83
+ echo "[ccx] Waiting for proxy to start..."
84
+ for i in {1..30}; do
85
+ if curl -sf "http://127.0.0.1:${PORT}/healthz" >/dev/null 2>&1; then
86
+ echo "[ccx] Proxy ready!"
87
+ break
88
+ fi
89
+ if [ $i -eq 30 ]; then
90
+ echo "āŒ Proxy failed to start. Check /tmp/claude-proxy.log"
91
+ cat /tmp/claude-proxy.log
92
+ exit 1
93
+ fi
94
+ sleep 0.5
95
+ done
96
+
97
+ echo ""
98
+ echo "šŸŽÆ Available model prefixes:"
99
+ echo " openai:<model> - OpenAI models (gpt-4o, gpt-4o-mini, etc.)"
100
+ echo " openrouter:<model> - OpenRouter models"
101
+ echo " gemini:<model> - Google Gemini models"
102
+ echo " glm:<model> - Z.AI GLM models (glm-4.7, glm-4.6, etc.)"
103
+ echo " anthropic:<model> - Anthropic Claude models"
104
+ echo ""
105
+ echo "šŸ’” Switch models in-session with: /model <prefix>:<model-name>"
106
+ echo ""
107
+
108
+ # Hand off to Claude Code
109
+ exec claude "$@"
package/bin/ccx.ps1 ADDED
@@ -0,0 +1,137 @@
1
+ param(
2
+ [switch]$Setup
3
+ )
4
+
5
+ $ErrorActionPreference = "Stop"
6
+
7
+ $ROOT_DIR = Split-Path -Parent (Split-Path -Parent $PSCommandPath)
8
+ $ENV_FILE = Join-Path $env:USERPROFILE ".claude-proxy\.env"
9
+ $PORT = if ($env:CLAUDE_PROXY_PORT) { $env:CLAUDE_PROXY_PORT } else { 17870 }
10
+
11
+ if ($Setup) {
12
+ Write-Host "Setting up ~/.claude-proxy/.env..."
13
+ $envDir = Join-Path $env:USERPROFILE ".claude-proxy"
14
+ if (-not (Test-Path $envDir)) {
15
+ New-Item -ItemType Directory -Path $envDir | Out-Null
16
+ }
17
+
18
+ if (Test-Path $ENV_FILE) {
19
+ Write-Host "Existing .env found. Edit it manually at: $ENV_FILE"
20
+ exit 0
21
+ }
22
+
23
+ @"
24
+ # Claude Proxy Configuration
25
+ # Edit this file to add your API keys
26
+
27
+ # OpenAI (optional)
28
+ OPENAI_API_KEY=
29
+ OPENAI_BASE_URL=https://api.openai.com/v1
30
+
31
+ # OpenRouter (optional)
32
+ OPENROUTER_API_KEY=
33
+ OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
34
+ OPENROUTER_REFERER=
35
+ OPENROUTER_TITLE=Claude Code via ccx
36
+
37
+ # Gemini (optional)
38
+ GEMINI_API_KEY=
39
+ GEMINI_BASE_URL=https://generativelanguage.googleapis.com/v1beta
40
+
41
+ # Z.AI GLM (optional)
42
+ GLM_UPSTREAM_URL=https://api.z.ai/api/anthropic
43
+ ZAI_API_KEY=
44
+
45
+ # Anthropic (optional)
46
+ ANTHROPIC_UPSTREAM_URL=https://api.anthropic.com
47
+ ANTHROPIC_API_KEY=
48
+ ANTHROPIC_VERSION=2023-06-01
49
+
50
+ # Proxy settings
51
+ CLAUDE_PROXY_PORT=17870
52
+ "@ | Out-File -FilePath $ENV_FILE -Encoding utf8
53
+
54
+ Write-Host "āœ… Created $ENV_FILE"
55
+ Write-Host ""
56
+ Write-Host "Edit it to add your API keys, then run: ccx"
57
+ Write-Host ""
58
+ Write-Host "Example:"
59
+ Write-Host " notepad $ENV_FILE"
60
+ exit 0
61
+ }
62
+
63
+ # Load .env file (simple parser for PowerShell)
64
+ if (Test-Path $ENV_FILE) {
65
+ Get-Content $ENV_FILE | ForEach-Object {
66
+ if ($_ -match '^\s*([^#][^=]+)=(.*)$') {
67
+ $name = $matches[1].Trim()
68
+ $value = $matches[2].Trim()
69
+ if ($value) {
70
+ [Environment]::SetEnvironmentVariable($name, $value, "Process")
71
+ }
72
+ }
73
+ }
74
+ }
75
+
76
+ $env:ANTHROPIC_BASE_URL = "http://127.0.0.1:$PORT"
77
+ if (-not $env:ANTHROPIC_AUTH_TOKEN) {
78
+ $env:ANTHROPIC_AUTH_TOKEN = "local-proxy-token"
79
+ }
80
+
81
+ Write-Host "[ccx] Starting Claude Code with multi-provider proxy..."
82
+ Write-Host "[ccx] Proxy will listen on: $($env:ANTHROPIC_BASE_URL)"
83
+
84
+ # Start proxy
85
+ $gatewayPath = Join-Path $ROOT_DIR "adapters\anthropic-gateway.ts"
86
+ $logPath = Join-Path $env:TEMP "claude-proxy.log"
87
+ $errorLogPath = Join-Path $env:TEMP "claude-proxy-error.log"
88
+
89
+ $proc = Start-Process "npx" -ArgumentList "-y","tsx",$gatewayPath -PassThru -WindowStyle Hidden -RedirectStandardOutput $logPath -RedirectStandardError $errorLogPath
90
+
91
+ # Wait for health check
92
+ Write-Host "[ccx] Waiting for proxy to start..."
93
+ $ready = $false
94
+ for ($i = 0; $i -lt 30; $i++) {
95
+ try {
96
+ $response = Invoke-WebRequest -Uri "http://127.0.0.1:$PORT/healthz" -UseBasicParsing -TimeoutSec 1 -ErrorAction Stop
97
+ if ($response.StatusCode -eq 200) {
98
+ Write-Host "[ccx] Proxy ready!"
99
+ $ready = $true
100
+ break
101
+ }
102
+ } catch {
103
+ Start-Sleep -Milliseconds 500
104
+ }
105
+ }
106
+
107
+ if (-not $ready) {
108
+ Write-Host "āŒ Proxy failed to start. Check logs:"
109
+ Write-Host " $logPath"
110
+ Write-Host " $errorLogPath"
111
+ if (Test-Path $errorLogPath) {
112
+ Get-Content $errorLogPath
113
+ }
114
+ if ($proc -and -not $proc.HasExited) { $proc.Kill() }
115
+ exit 1
116
+ }
117
+
118
+ Write-Host ""
119
+ Write-Host "šŸŽÆ Available model prefixes:"
120
+ Write-Host " openai:<model> - OpenAI models (gpt-4o, gpt-4o-mini, etc.)"
121
+ Write-Host " openrouter:<model> - OpenRouter models"
122
+ Write-Host " gemini:<model> - Google Gemini models"
123
+ Write-Host " glm:<model> - Z.AI GLM models (glm-4.7, glm-4.6, etc.)"
124
+ Write-Host " anthropic:<model> - Anthropic Claude models"
125
+ Write-Host ""
126
+ Write-Host "šŸ’” Switch models in-session with: /model <prefix>:<model-name>"
127
+ Write-Host ""
128
+
129
+ try {
130
+ & claude @args
131
+ } finally {
132
+ Write-Host ""
133
+ Write-Host "[ccx] Shutting down proxy..."
134
+ if ($proc -and -not $proc.HasExited) {
135
+ $proc.Kill()
136
+ }
137
+ }
package/bin/cli.js ADDED
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn } = require('child_process');
4
+ const path = require('path');
5
+ const os = require('os');
6
+ const fs = require('fs');
7
+
8
+ const platform = os.platform();
9
+ const rootDir = path.join(__dirname, '..');
10
+
11
+ console.log('šŸ”§ Claude-GLM Alt Installer (Community Fork)');
12
+ console.log('=============================================\n');
13
+ console.log(`Detected OS: ${platform}\n`);
14
+
15
+ function runInstaller() {
16
+ let command, args, scriptPath;
17
+
18
+ if (platform === 'win32') {
19
+ // Windows - run PowerShell installer
20
+ console.log('🪟 Running Windows PowerShell installer...\n');
21
+ scriptPath = path.join(rootDir, 'install.ps1');
22
+
23
+ if (!fs.existsSync(scriptPath)) {
24
+ console.error('āŒ Error: install.ps1 not found!');
25
+ process.exit(1);
26
+ }
27
+
28
+ command = 'powershell.exe';
29
+ args = [
30
+ '-NoProfile',
31
+ '-ExecutionPolicy', 'Bypass',
32
+ '-File', scriptPath
33
+ ];
34
+
35
+ } else if (platform === 'darwin' || platform === 'linux') {
36
+ // macOS or Linux - run bash installer
37
+ console.log(`🐧 Running Unix/Linux installer...\n`);
38
+ scriptPath = path.join(rootDir, 'install.sh');
39
+
40
+ if (!fs.existsSync(scriptPath)) {
41
+ console.error('āŒ Error: install.sh not found!');
42
+ process.exit(1);
43
+ }
44
+
45
+ command = 'bash';
46
+ args = [scriptPath];
47
+
48
+ } else {
49
+ console.error(`āŒ Unsupported platform: ${platform}`);
50
+ console.error('This installer supports Windows, macOS, and Linux.');
51
+ process.exit(1);
52
+ }
53
+
54
+ // Spawn the installer process
55
+ const installer = spawn(command, args, {
56
+ stdio: 'inherit',
57
+ cwd: rootDir
58
+ });
59
+
60
+ installer.on('error', (error) => {
61
+ console.error(`āŒ Failed to start installer: ${error.message}`);
62
+ process.exit(1);
63
+ });
64
+
65
+ installer.on('close', (code) => {
66
+ if (code !== 0) {
67
+ console.error(`\nāŒ Installer exited with code ${code}`);
68
+ process.exit(code);
69
+ }
70
+ console.log('\nāœ… Installation completed successfully!');
71
+ });
72
+ }
73
+
74
+ // Run the installer
75
+ runInstaller();
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Preinstall script to prevent incorrect installation method
5
+ * This package should ONLY be run with npx, not installed
6
+ */
7
+
8
+ // Check if being installed as a dependency vs run via npx
9
+ // When using npx, npm sets npm_execpath to npx or the install is in a temp directory
10
+ const isNpxInstall = process.env.npm_execpath && process.env.npm_execpath.includes('npx');
11
+ const isTempInstall = process.env.npm_config_cache && process.cwd().includes('_npx');
12
+
13
+ // Block ALL installation attempts (local and global)
14
+ if (!isNpxInstall && !isTempInstall) {
15
+ console.error('\nāŒ ERROR: Incorrect installation method!\n');
16
+ console.error('This package is meant to be run directly with npx only.\n');
17
+ console.error('āœ… Correct usage:');
18
+ console.error(' npx claude-glm-installer\n');
19
+ console.error('āŒ Do NOT install this package:');
20
+ console.error(' npm install claude-glm-installer');
21
+ console.error(' npm i claude-glm-installer');
22
+ console.error(' npm install -g claude-glm-installer\n');
23
+ console.error('Always use npx to run the latest version!\n');
24
+
25
+ process.exit(1);
26
+ }
27
+
28
+ // Allow installation to proceed only for npx
29
+ process.exit(0);