@ghackk/multi-claude 1.0.9 → 1.0.12

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/claude-menu.ps1 CHANGED
@@ -582,7 +582,10 @@ function Build-ExportToken($name) {
582
582
  }
583
583
 
584
584
  Copy-Item $selected.FullName "$tempDir\launcher.bat"
585
- $name | Out-File "$tempDir\profile-name.txt" -Encoding UTF8 -NoNewline
585
+ # Also create Unix launcher for cross-platform compatibility
586
+ $shContent = "#!/bin/bash`nexport CLAUDE_CONFIG_DIR=`"`$HOME/.$name`"`nclaude `"`$@`""
587
+ [System.IO.File]::WriteAllText("$tempDir\launcher.sh", $shContent, (New-Object System.Text.UTF8Encoding $false))
588
+ [System.IO.File]::WriteAllText("$tempDir\profile-name.txt", $name, (New-Object System.Text.UTF8Encoding $false))
586
589
 
587
590
  $zipPath = "$env:TEMP\claude-export-$name.zip"
588
591
  if (Test-Path $zipPath) { Remove-Item $zipPath -Force }
@@ -661,7 +664,11 @@ function Apply-ImportToken($token) {
661
664
  Remove-Item $zipPath -Force
662
665
  return $false
663
666
  }
664
- $name = (Get-Content $nameFile -Raw).Trim()
667
+ $nameRaw = [System.IO.File]::ReadAllBytes($nameFile)
668
+ if ($nameRaw.Length -ge 3 -and $nameRaw[0] -eq 0xEF -and $nameRaw[1] -eq 0xBB -and $nameRaw[2] -eq 0xBF) {
669
+ $nameRaw = $nameRaw[3..($nameRaw.Length-1)]
670
+ }
671
+ $name = [System.Text.Encoding]::UTF8.GetString($nameRaw).Trim()
665
672
 
666
673
  Write-Host ""
667
674
  Write-Host " Detected profile: $name" -ForegroundColor Cyan
@@ -694,12 +701,16 @@ function Apply-ImportToken($token) {
694
701
  Write-Host " Profile restored (credentials, settings, session)" -ForegroundColor Green
695
702
 
696
703
  $launcherSrc = "$extractDir\launcher.bat"
697
- $launcherDest = "$ACCOUNTS_DIR\$name.bat"
698
- if (Test-Path $launcherSrc) {
699
- if (!(Test-Path $ACCOUNTS_DIR)) { New-Item -ItemType Directory -Path $ACCOUNTS_DIR | Out-Null }
700
- Copy-Item $launcherSrc $launcherDest -Force
701
- Write-Host " Launcher created" -ForegroundColor Green
704
+ if (!(Test-Path $launcherSrc)) {
705
+ # Cross-platform: generate .bat from profile name if only .sh exists
706
+ $batContent = "@echo off`r`nset CLAUDE_CONFIG_DIR=%USERPROFILE%\.$name`r`nclaude %*"
707
+ $launcherSrc = "$extractDir\launcher.bat"
708
+ [System.IO.File]::WriteAllText($launcherSrc, $batContent)
702
709
  }
710
+ $launcherDest = "$ACCOUNTS_DIR\$name.bat"
711
+ if (!(Test-Path $ACCOUNTS_DIR)) { New-Item -ItemType Directory -Path $ACCOUNTS_DIR | Out-Null }
712
+ Copy-Item $launcherSrc $launcherDest -Force
713
+ Write-Host " Launcher created" -ForegroundColor Green
703
714
 
704
715
  Write-Host ""
705
716
  Write-Host " Profile '$name' imported successfully!" -ForegroundColor Green
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ghackk/multi-claude",
3
- "version": "1.0.9",
3
+ "version": "1.0.12",
4
4
  "description": "Run multiple Claude CLI accounts with shared settings, plugins, marketplace sync, and backup/restore",
5
5
  "bin": {
6
6
  "multi-claude": "bin/claude-multi.js"
@@ -576,6 +576,8 @@ build_export_token() {
576
576
  fi
577
577
 
578
578
  [ -f "$ACCOUNTS_DIR/$name.sh" ] && cp "$ACCOUNTS_DIR/$name.sh" "$tempDir/launcher.sh"
579
+ # Also create Windows launcher for cross-platform compatibility
580
+ printf "@echo off\r\nset CLAUDE_CONFIG_DIR=%%USERPROFILE%%\\.%s\r\nclaude %%*\r\n" "$name" > "$tempDir/launcher.bat"
579
581
  echo -n "$name" > "$tempDir/profile-name.txt"
580
582
 
581
583
  local zipPath=$(mktemp)
@@ -659,7 +661,12 @@ apply_import_token() {
659
661
  rm -rf "$tempDir"
660
662
  return 1
661
663
  fi
662
- local name=$(cat "$nameFile" | tr -d '\r\n')
664
+ local name=$(python3 -c "
665
+ import sys
666
+ data = open('$nameFile', 'rb').read()
667
+ if data[:3] == b'\xef\xbb\xbf': data = data[3:]
668
+ sys.stdout.write(data.decode('utf-8').strip())
669
+ " 2>/dev/null || cat "$nameFile" | tr -d '\r\n')
663
670
 
664
671
  if ! echo "$name" | grep -qE '^[a-zA-Z0-9_-]+$'; then
665
672
  echo -e " \033[31mInvalid profile name in token.\033[0m"
@@ -692,11 +699,16 @@ apply_import_token() {
692
699
  cp -r "$importConfig"/. "$configDir/"
693
700
  echo -e " \033[32mProfile restored (credentials, settings, session)\033[0m"
694
701
 
702
+ mkdir -p "$ACCOUNTS_DIR"
695
703
  if [ -f "$tempDir/launcher.sh" ]; then
696
704
  cp "$tempDir/launcher.sh" "$ACCOUNTS_DIR/$name.sh"
697
705
  chmod +x "$ACCOUNTS_DIR/$name.sh"
698
- echo -e " \033[32mLauncher created\033[0m"
706
+ else
707
+ # Cross-platform: generate .sh from profile name if only .bat exists
708
+ printf '#!/bin/bash\nexport CLAUDE_CONFIG_DIR="$HOME/.%s"\nclaude "$@"\n' "$name" > "$ACCOUNTS_DIR/$name.sh"
709
+ chmod +x "$ACCOUNTS_DIR/$name.sh"
699
710
  fi
711
+ echo -e " \033[32mLauncher created\033[0m"
700
712
 
701
713
  echo ""
702
714
  echo -e " \033[32mProfile '$name' imported successfully!\033[0m"
@@ -1255,13 +1267,14 @@ show_menu() {
1255
1267
  echo " 3. Launch Account"
1256
1268
  echo " 4. Rename Account"
1257
1269
  echo -e " \033[31m5. Delete Account\033[0m"
1258
- echo " 6. Backup Sessions"
1259
- echo " 7. Restore Sessions"
1260
- echo -e " \033[33m8. Shared Settings (MCP/Skills)\033[0m"
1261
- echo -e " \033[35m9. Plugins & Marketplace\033[0m"
1262
- echo -e " \033[32mE. Export Profile (Pair Code)\033[0m"
1263
- echo -e " \033[32mI. Import Profile (Pair Code)\033[0m"
1264
- echo " 0. Exit"
1270
+ echo -e " \033[33m6. Shared Settings (MCP/Skills)\033[0m"
1271
+ echo -e " \033[35m7. Shared Plugins & Marketplace\033[0m"
1272
+ echo -e " \033[32m8. Remote Session Backup\033[0m"
1273
+ echo -e " \033[32m9. Remote Session Restore\033[0m"
1274
+ echo -e " \033[32mE. Send Account (Pair Code)\033[0m"
1275
+ echo -e " \033[32mI. Receive Account (Pair Code)\033[0m"
1276
+ echo -e " \033[90mH. Help\033[0m"
1277
+ echo -e " \033[31m0. Exit\033[0m"
1265
1278
  echo -e "\033[36m======================================\033[0m"
1266
1279
  echo ""
1267
1280
  }
@@ -1274,23 +1287,23 @@ show_help() {
1274
1287
  echo -e " \033[90m Create, launch, rename, and delete Claude CLI accounts.\033[0m"
1275
1288
  echo -e " \033[90m Each account gets its own isolated config directory.\033[0m"
1276
1289
  echo ""
1277
- echo -e " \033[37m6-7. Backup & Restore\033[0m"
1278
- echo -e " \033[90m Create timestamped local backups of all accounts and settings.\033[0m"
1279
- echo ""
1280
- echo -e " \033[37m8. Shared Settings\033[0m"
1290
+ echo -e " \033[37m6. Shared Settings (MCP/Skills)\033[0m"
1281
1291
  echo -e " \033[90m Define MCP servers, env vars, and CLAUDE.md instructions\033[0m"
1282
1292
  echo -e " \033[90m that automatically apply to ALL accounts on launch.\033[0m"
1283
1293
  echo ""
1284
- echo -e " \033[37m9. Plugins & Marketplace\033[0m"
1294
+ echo -e " \033[37m7. Shared Plugins & Marketplace\033[0m"
1285
1295
  echo -e " \033[90m Enable/disable plugins globally or per-account.\033[0m"
1286
1296
  echo -e " \033[90m Browse and manage marketplace indexes.\033[0m"
1287
1297
  echo ""
1288
- echo -e " \033[37mE. Export Profile (Pair Code)\033[0m"
1298
+ echo -e " \033[37m8-9. Remote Backup & Restore\033[0m"
1299
+ echo -e " \033[90m Cloud backup/restore of all accounts and settings.\033[0m"
1300
+ echo ""
1301
+ echo -e " \033[37mE. Send Account (Pair Code)\033[0m"
1289
1302
  echo -e " \033[90m Send a single account to another machine. You get a short code\033[0m"
1290
1303
  echo -e " \033[90m like A7X4B-K9M4PX — the other person enters it using 'I'.\033[0m"
1291
1304
  echo -e " \033[90m The code expires in 10 minutes and works only once.\033[0m"
1292
1305
  echo ""
1293
- echo -e " \033[37mI. Import Profile (Pair Code)\033[0m"
1306
+ echo -e " \033[37mI. Receive Account (Pair Code)\033[0m"
1294
1307
  echo -e " \033[90m Receive an account from someone else. Enter the pairing code\033[0m"
1295
1308
  echo -e " \033[90m they gave you and the account appears on your machine.\033[0m"
1296
1309
  echo ""
@@ -1306,10 +1319,10 @@ while true; do
1306
1319
  3) launch_account ;;
1307
1320
  4) rename_account ;;
1308
1321
  5) delete_account ;;
1309
- 6) backup_sessions ;;
1310
- 7) restore_sessions ;;
1311
- 8) manage_shared_settings ;;
1312
- 9) manage_plugins ;;
1322
+ 6) manage_shared_settings ;;
1323
+ 7) manage_plugins ;;
1324
+ 8) cloud_backup ;;
1325
+ 9) cloud_restore ;;
1313
1326
  [eE]) pair_export ;;
1314
1327
  [iI]) pair_import ;;
1315
1328
  [hH]) show_help ;;
@@ -582,7 +582,10 @@ function Build-ExportToken($name) {
582
582
  }
583
583
 
584
584
  Copy-Item $selected.FullName "$tempDir\launcher.bat"
585
- $name | Out-File "$tempDir\profile-name.txt" -Encoding UTF8 -NoNewline
585
+ # Also create Unix launcher for cross-platform compatibility
586
+ $shContent = "#!/bin/bash`nexport CLAUDE_CONFIG_DIR=`"`$HOME/.$name`"`nclaude `"`$@`""
587
+ [System.IO.File]::WriteAllText("$tempDir\launcher.sh", $shContent, (New-Object System.Text.UTF8Encoding $false))
588
+ [System.IO.File]::WriteAllText("$tempDir\profile-name.txt", $name, (New-Object System.Text.UTF8Encoding $false))
586
589
 
587
590
  $zipPath = "$env:TEMP\claude-export-$name.zip"
588
591
  if (Test-Path $zipPath) { Remove-Item $zipPath -Force }
@@ -661,7 +664,11 @@ function Apply-ImportToken($token) {
661
664
  Remove-Item $zipPath -Force
662
665
  return $false
663
666
  }
664
- $name = (Get-Content $nameFile -Raw).Trim()
667
+ $nameRaw = [System.IO.File]::ReadAllBytes($nameFile)
668
+ if ($nameRaw.Length -ge 3 -and $nameRaw[0] -eq 0xEF -and $nameRaw[1] -eq 0xBB -and $nameRaw[2] -eq 0xBF) {
669
+ $nameRaw = $nameRaw[3..($nameRaw.Length-1)]
670
+ }
671
+ $name = [System.Text.Encoding]::UTF8.GetString($nameRaw).Trim()
665
672
 
666
673
  Write-Host ""
667
674
  Write-Host " Detected profile: $name" -ForegroundColor Cyan
@@ -694,12 +701,16 @@ function Apply-ImportToken($token) {
694
701
  Write-Host " Profile restored (credentials, settings, session)" -ForegroundColor Green
695
702
 
696
703
  $launcherSrc = "$extractDir\launcher.bat"
697
- $launcherDest = "$ACCOUNTS_DIR\$name.bat"
698
- if (Test-Path $launcherSrc) {
699
- if (!(Test-Path $ACCOUNTS_DIR)) { New-Item -ItemType Directory -Path $ACCOUNTS_DIR | Out-Null }
700
- Copy-Item $launcherSrc $launcherDest -Force
701
- Write-Host " Launcher created" -ForegroundColor Green
704
+ if (!(Test-Path $launcherSrc)) {
705
+ # Cross-platform: generate .bat from profile name if only .sh exists
706
+ $batContent = "@echo off`r`nset CLAUDE_CONFIG_DIR=%USERPROFILE%\.$name`r`nclaude %*"
707
+ $launcherSrc = "$extractDir\launcher.bat"
708
+ [System.IO.File]::WriteAllText($launcherSrc, $batContent)
702
709
  }
710
+ $launcherDest = "$ACCOUNTS_DIR\$name.bat"
711
+ if (!(Test-Path $ACCOUNTS_DIR)) { New-Item -ItemType Directory -Path $ACCOUNTS_DIR | Out-Null }
712
+ Copy-Item $launcherSrc $launcherDest -Force
713
+ Write-Host " Launcher created" -ForegroundColor Green
703
714
 
704
715
  Write-Host ""
705
716
  Write-Host " Profile '$name' imported successfully!" -ForegroundColor Green