@ghackk/multi-claude 1.0.19 → 1.0.21

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,40 @@
1
+ #!/usr/bin/env node
2
+ const { execSync } = require('child_process');
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const os = require('os');
6
+
7
+ if (os.platform() === 'win32') process.exit(0); // Windows npm bin is typically on PATH already
8
+
9
+ try {
10
+ const npmBin = execSync('npm bin -g', { encoding: 'utf-8' }).trim();
11
+ if (!npmBin) process.exit(0);
12
+
13
+ // Check if already on PATH
14
+ const pathDirs = (process.env.PATH || '').split(':');
15
+ if (pathDirs.includes(npmBin)) process.exit(0);
16
+
17
+ const home = os.homedir();
18
+ const rcFiles = ['.bashrc', '.zshrc', '.profile'].map(f => path.join(home, f));
19
+ const exportLine = `export PATH="${npmBin}:$PATH"`;
20
+
21
+ let added = false;
22
+ for (const rc of rcFiles) {
23
+ if (!fs.existsSync(rc)) continue;
24
+ const content = fs.readFileSync(rc, 'utf-8');
25
+ if (content.includes(npmBin)) { added = true; break; }
26
+ }
27
+
28
+ if (!added) {
29
+ // Find first existing rc file to append to
30
+ for (const rc of rcFiles) {
31
+ if (!fs.existsSync(rc)) continue;
32
+ fs.appendFileSync(rc, `\n# npm global bin\n${exportLine}\n`);
33
+ console.log(` Added ${npmBin} to PATH in ${path.basename(rc)}`);
34
+ console.log(' Restart your terminal or run: source ~/' + path.basename(rc));
35
+ break;
36
+ }
37
+ }
38
+ } catch (_) {
39
+ // Silent fail — non-critical
40
+ }
package/claude-menu.ps1 CHANGED
@@ -90,6 +90,73 @@ function Ensure-ClaudeInstalled {
90
90
 
91
91
  Ensure-ClaudeInstalled
92
92
 
93
+ # ─── DEPENDENCY CHECK ──────────────────────────────────────────────────────
94
+
95
+ function Ensure-Dependencies {
96
+ $missing = @()
97
+ $optional = @()
98
+
99
+ # Required
100
+ if (!(Get-Command git -ErrorAction SilentlyContinue)) { $missing += "git" }
101
+
102
+ # Optional but recommended
103
+ if (!(Get-Command python3 -ErrorAction SilentlyContinue) -and !(Get-Command python -ErrorAction SilentlyContinue)) { $optional += "python" }
104
+ if (!(Get-Command npm -ErrorAction SilentlyContinue)) { $optional += "npm (Node.js)" }
105
+
106
+ if ($missing.Count -eq 0 -and $optional.Count -eq 0) { return }
107
+
108
+ Write-Host ""
109
+ if ($missing.Count -gt 0) {
110
+ Write-Host " Missing required dependencies:" -ForegroundColor Red
111
+ foreach ($dep in $missing) { Write-Host " x $dep" -ForegroundColor Red }
112
+ }
113
+ if ($optional.Count -gt 0) {
114
+ Write-Host " Missing optional dependencies:" -ForegroundColor Yellow
115
+ foreach ($dep in $optional) { Write-Host " ~ $dep" -ForegroundColor Yellow }
116
+ }
117
+
118
+ Write-Host ""
119
+ $hasPkg = $false
120
+ if (Get-Command winget -ErrorAction SilentlyContinue) { $hasPkg = $true }
121
+ if (Get-Command scoop -ErrorAction SilentlyContinue) { $hasPkg = $true }
122
+
123
+ if ($hasPkg) {
124
+ $choice = Read-Host " Install missing dependencies now? (y/n)"
125
+ if ($choice -ieq "y" -or $choice -ieq "yes") {
126
+ $allDeps = $missing + $optional
127
+ foreach ($dep in $allDeps) {
128
+ $pkgName = $dep -replace " \(.*\)", ""
129
+ Write-Host " Installing $dep..." -ForegroundColor Gray
130
+ $installed = $false
131
+ if (Get-Command winget -ErrorAction SilentlyContinue) {
132
+ try {
133
+ if ($pkgName -eq "python") { winget install Python.Python.3 --accept-source-agreements --accept-package-agreements 2>$null }
134
+ elseif ($pkgName -eq "git") { winget install Git.Git --accept-source-agreements --accept-package-agreements 2>$null }
135
+ elseif ($pkgName -eq "npm") { winget install OpenJS.NodeJS --accept-source-agreements --accept-package-agreements 2>$null }
136
+ $installed = $true
137
+ } catch {}
138
+ }
139
+ if (!$installed -and (Get-Command scoop -ErrorAction SilentlyContinue)) {
140
+ try {
141
+ scoop install $pkgName 2>$null
142
+ $installed = $true
143
+ } catch {}
144
+ }
145
+ if ($installed) { Write-Host " Done" -ForegroundColor Green }
146
+ else { Write-Host " Failed — install manually" -ForegroundColor Red }
147
+ }
148
+ # Refresh PATH
149
+ $env:PATH = [System.Environment]::GetEnvironmentVariable("PATH", "User") + ";" + [System.Environment]::GetEnvironmentVariable("PATH", "Machine")
150
+ }
151
+ } else {
152
+ Write-Host " Please install missing dependencies manually." -ForegroundColor Yellow
153
+ }
154
+ Write-Host ""
155
+ pause
156
+ }
157
+
158
+ Ensure-Dependencies
159
+
93
160
  # ─── ENSURE DIRECTORIES EXIST ───────────────────────────────────────────────
94
161
 
95
162
  if (!(Test-Path $ACCOUNTS_DIR)) { New-Item -ItemType Directory -Path $ACCOUNTS_DIR | Out-Null }
package/package.json CHANGED
@@ -1,7 +1,10 @@
1
1
  {
2
2
  "name": "@ghackk/multi-claude",
3
- "version": "1.0.19",
3
+ "version": "1.0.21",
4
4
  "description": "Run multiple Claude CLI accounts with shared settings, plugins, marketplace sync, and backup/restore",
5
+ "scripts": {
6
+ "postinstall": "node bin/postinstall.js"
7
+ },
5
8
  "bin": {
6
9
  "multi-claude": "bin/claude-multi.js"
7
10
  },
@@ -119,6 +119,110 @@ ensure_claude_installed() {
119
119
 
120
120
  ensure_claude_installed
121
121
 
122
+ # ─── DEPENDENCY CHECK ─────────────────────────────────────────────────────
123
+
124
+ detect_pkg_manager() {
125
+ if command -v pkg &>/dev/null && [ -d "/data/data/com.termux" ]; then
126
+ echo "termux"
127
+ elif command -v brew &>/dev/null; then
128
+ echo "brew"
129
+ elif command -v apt &>/dev/null; then
130
+ echo "apt"
131
+ elif command -v dnf &>/dev/null; then
132
+ echo "dnf"
133
+ elif command -v yum &>/dev/null; then
134
+ echo "yum"
135
+ elif command -v pacman &>/dev/null; then
136
+ echo "pacman"
137
+ elif command -v apk &>/dev/null; then
138
+ echo "apk"
139
+ else
140
+ echo ""
141
+ fi
142
+ }
143
+
144
+ install_pkg() {
145
+ local pkg="$1"
146
+ local mgr="$2"
147
+ case "$mgr" in
148
+ termux) pkg install -y "$pkg" 2>/dev/null ;;
149
+ brew) brew install "$pkg" 2>/dev/null ;;
150
+ apt) sudo apt install -y "$pkg" 2>/dev/null ;;
151
+ dnf) sudo dnf install -y "$pkg" 2>/dev/null ;;
152
+ yum) sudo yum install -y "$pkg" 2>/dev/null ;;
153
+ pacman) sudo pacman -S --noconfirm "$pkg" 2>/dev/null ;;
154
+ apk) sudo apk add "$pkg" 2>/dev/null ;;
155
+ *) return 1 ;;
156
+ esac
157
+ }
158
+
159
+ ensure_dependencies() {
160
+ local missing=()
161
+ local optional_missing=()
162
+
163
+ # Required dependencies
164
+ for cmd in curl jq tar gzip; do
165
+ command -v "$cmd" &>/dev/null || missing+=("$cmd")
166
+ done
167
+
168
+ # Optional but recommended
169
+ for cmd in python3 zip unzip base64; do
170
+ command -v "$cmd" &>/dev/null || optional_missing+=("$cmd")
171
+ done
172
+
173
+ [ ${#missing[@]} -eq 0 ] && [ ${#optional_missing[@]} -eq 0 ] && return 0
174
+
175
+ echo ""
176
+ local mgr=$(detect_pkg_manager)
177
+
178
+ if [ ${#missing[@]} -gt 0 ]; then
179
+ echo -e " \033[31mMissing required dependencies:\033[0m"
180
+ for cmd in "${missing[@]}"; do
181
+ echo -e " \033[31m✗\033[0m $cmd"
182
+ done
183
+ fi
184
+
185
+ if [ ${#optional_missing[@]} -gt 0 ]; then
186
+ echo -e " \033[33mMissing optional dependencies:\033[0m"
187
+ for cmd in "${optional_missing[@]}"; do
188
+ echo -e " \033[33m~\033[0m $cmd"
189
+ done
190
+ fi
191
+
192
+ echo ""
193
+ if [ -n "$mgr" ]; then
194
+ echo -e " \033[36mDetected package manager: $mgr\033[0m"
195
+ echo -e " \033[37mInstall missing dependencies now? (y/n)\033[0m"
196
+ read -p " > " dep_choice
197
+ if [[ "${dep_choice,,}" == "y" || "${dep_choice,,}" == "yes" ]]; then
198
+ local all_deps=("${missing[@]}" "${optional_missing[@]}")
199
+ for cmd in "${all_deps[@]}"; do
200
+ echo -e " \033[90mInstalling $cmd...\033[0m"
201
+ if install_pkg "$cmd" "$mgr"; then
202
+ echo -e " \033[32m✓ $cmd installed\033[0m"
203
+ else
204
+ echo -e " \033[31m✗ Failed to install $cmd\033[0m"
205
+ fi
206
+ done
207
+ fi
208
+ else
209
+ echo -e " \033[33mCould not detect package manager.\033[0m"
210
+ echo -e " \033[37mPlease install manually: ${missing[*]} ${optional_missing[*]}\033[0m"
211
+ fi
212
+
213
+ # Re-check required deps
214
+ for cmd in curl jq tar gzip; do
215
+ if ! command -v "$cmd" &>/dev/null; then
216
+ echo ""
217
+ echo -e " \033[31m$cmd is still missing. Some features may not work.\033[0m"
218
+ fi
219
+ done
220
+ echo ""
221
+ read -p " Press Enter to continue..." _
222
+ }
223
+
224
+ ensure_dependencies
225
+
122
226
  # ─── ENSURE DIRECTORIES EXIST ────────────────────────────────────────────
123
227
 
124
228
  mkdir -p "$ACCOUNTS_DIR" "$BACKUP_DIR"