claude-cac 1.4.3 → 1.4.4-beta.2
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/README.md +1 -0
- package/cac +35 -50
- package/package.json +1 -1
- package/scripts/postinstall.js +6 -0
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
[](https://www.npmjs.com/package/claude-cac)
|
|
16
16
|
[](https://github.com/nmhjklnm/cac)
|
|
17
17
|
[](https://cac.nextmind.space/docs)
|
|
18
|
+
[](https://t.me/claudecodecloak)
|
|
18
19
|
[](LICENSE)
|
|
19
20
|
[]()
|
|
20
21
|
|
package/cac
CHANGED
|
@@ -11,7 +11,7 @@ VERSIONS_DIR="$CAC_DIR/versions"
|
|
|
11
11
|
# ── utils: colors, read/write, UUID, proxy parsing ───────────────────────
|
|
12
12
|
|
|
13
13
|
# shellcheck disable=SC2034 # used in build-concatenated cac script
|
|
14
|
-
CAC_VERSION="1.4.
|
|
14
|
+
CAC_VERSION="1.4.4-beta.2"
|
|
15
15
|
|
|
16
16
|
_read() { [[ -f "$1" ]] && tr -d '[:space:]' < "$1" || echo "${2:-}"; }
|
|
17
17
|
_die() { printf '%b\n' "$(_red "error:") $*" >&2; exit 1; }
|
|
@@ -52,12 +52,12 @@ _gen_uuid() {
|
|
|
52
52
|
elif [[ -f /proc/sys/kernel/random/uuid ]]; then
|
|
53
53
|
cat /proc/sys/kernel/random/uuid
|
|
54
54
|
else
|
|
55
|
-
python3 -c "import uuid; print(uuid.uuid4())"
|
|
55
|
+
python3 -c "import uuid; print(uuid.uuid4())" || _die "python3 required for UUID generation (install python3 or uuidgen)"
|
|
56
56
|
fi
|
|
57
57
|
}
|
|
58
58
|
_new_uuid() { _gen_uuid | tr '[:lower:]' '[:upper:]'; }
|
|
59
59
|
_new_sid() { _gen_uuid | tr '[:upper:]' '[:lower:]'; }
|
|
60
|
-
_new_user_id() { python3 -c "import os; print(os.urandom(32).hex())"; }
|
|
60
|
+
_new_user_id() { python3 -c "import os; print(os.urandom(32).hex())" || _die "python3 required"; }
|
|
61
61
|
_new_machine_id() { _gen_uuid | tr -d '-' | tr '[:upper:]' '[:lower:]'; }
|
|
62
62
|
_new_hostname() { echo "host-$(_gen_uuid | cut -d- -f1 | tr '[:upper:]' '[:lower:]')"; }
|
|
63
63
|
_new_mac() { printf '02:%02x:%02x:%02x:%02x:%02x' $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)); }
|
|
@@ -921,9 +921,9 @@ _check_mtls() {
|
|
|
921
921
|
if openssl verify -CAfile "$ca_cert" "$client_cert" >/dev/null 2>&1; then
|
|
922
922
|
# check certificate expiry
|
|
923
923
|
local expiry
|
|
924
|
-
expiry=$(openssl x509 -in "$client_cert" -noout -enddate 2>/dev/null | cut -d= -f2)
|
|
924
|
+
expiry=$(openssl x509 -in "$client_cert" -noout -enddate 2>/dev/null | cut -d= -f2 || true)
|
|
925
925
|
local cn
|
|
926
|
-
cn=$(openssl x509 -in "$client_cert" -noout -subject 2>/dev/null | sed 's/.*CN *= *//')
|
|
926
|
+
cn=$(openssl x509 -in "$client_cert" -noout -subject 2>/dev/null | sed 's/.*CN *= *//' || true)
|
|
927
927
|
echo "$(_green "✓") mTLS certificate valid (CN=$cn, expires: $expiry)"
|
|
928
928
|
return 0
|
|
929
929
|
else
|
|
@@ -1280,21 +1280,38 @@ fi
|
|
|
1280
1280
|
[[ -x "$_real" ]] || { echo "[cac] error: claude not found, run 'cac claude install latest'" >&2; exit 1; }
|
|
1281
1281
|
|
|
1282
1282
|
# ── Relay local forwarding (always enabled when proxy is set) ──
|
|
1283
|
+
# Relay lifecycle: ENVIRONMENT-level, not session-level.
|
|
1284
|
+
# - Started on demand by the first session that needs it
|
|
1285
|
+
# - Persists across sessions (no cleanup on exit)
|
|
1286
|
+
# - Restarted if proxy changes (relay.proxy mismatch)
|
|
1287
|
+
# - Stopped by: cac env activate (switch), cac self delete, or machine reboot
|
|
1283
1288
|
_relay_active=false
|
|
1284
1289
|
if [[ -n "$PROXY" ]] && [[ -f "$CAC_DIR/relay.js" ]]; then
|
|
1285
1290
|
_relay_js="$CAC_DIR/relay.js"
|
|
1286
1291
|
_relay_pid_file="$CAC_DIR/relay.pid"
|
|
1287
1292
|
_relay_port_file="$CAC_DIR/relay.port"
|
|
1293
|
+
_relay_proxy_file="$CAC_DIR/relay.proxy"
|
|
1288
1294
|
|
|
1289
1295
|
# check if relay is already running
|
|
1290
1296
|
_relay_running=false
|
|
1291
1297
|
if [[ -f "$_relay_pid_file" ]]; then
|
|
1292
1298
|
_rpid=$(tr -d '[:space:]' < "$_relay_pid_file")
|
|
1293
|
-
kill -0 "$_rpid" 2>/dev/null && _relay_running=true
|
|
1299
|
+
[[ -n "$_rpid" ]] && kill -0 "$_rpid" 2>/dev/null && _relay_running=true
|
|
1300
|
+
fi
|
|
1301
|
+
|
|
1302
|
+
# kill stale relay if proxy changed (env switch without going through cac activate)
|
|
1303
|
+
# skip if relay.proxy absent (first run after upgrade — assume match)
|
|
1304
|
+
if [[ "$_relay_running" == "true" ]] && [[ -f "$_relay_proxy_file" ]]; then
|
|
1305
|
+
_old_proxy=$(tr -d '[:space:]' < "$_relay_proxy_file")
|
|
1306
|
+
if [[ "$_old_proxy" != "$PROXY" ]]; then
|
|
1307
|
+
kill "$_rpid" 2>/dev/null || true
|
|
1308
|
+
rm -f "$_relay_pid_file" "$_relay_port_file" "$_relay_proxy_file"
|
|
1309
|
+
_relay_running=false
|
|
1310
|
+
fi
|
|
1294
1311
|
fi
|
|
1295
1312
|
|
|
1296
1313
|
# start if not running
|
|
1297
|
-
if [[ "$_relay_running" != "true" ]]
|
|
1314
|
+
if [[ "$_relay_running" != "true" ]]; then
|
|
1298
1315
|
_rport=17890
|
|
1299
1316
|
while (echo >/dev/tcp/127.0.0.1/$_rport) 2>/dev/null; do
|
|
1300
1317
|
(( _rport++ ))
|
|
@@ -1306,6 +1323,7 @@ if [[ -n "$PROXY" ]] && [[ -f "$CAC_DIR/relay.js" ]]; then
|
|
|
1306
1323
|
(echo >/dev/tcp/127.0.0.1/$_rport) 2>/dev/null && break
|
|
1307
1324
|
sleep 0.1
|
|
1308
1325
|
done
|
|
1326
|
+
echo "$PROXY" > "$_relay_proxy_file"
|
|
1309
1327
|
echo "$_rport" > "$_relay_port_file"
|
|
1310
1328
|
fi
|
|
1311
1329
|
|
|
@@ -1319,40 +1337,6 @@ if [[ -n "$PROXY" ]] && [[ -f "$CAC_DIR/relay.js" ]]; then
|
|
|
1319
1337
|
fi
|
|
1320
1338
|
fi
|
|
1321
1339
|
|
|
1322
|
-
# cleanup function
|
|
1323
|
-
_cleanup_all() {
|
|
1324
|
-
# stop watchdog
|
|
1325
|
-
[[ -n "${_watchdog_pid:-}" ]] && kill "$_watchdog_pid" 2>/dev/null || true
|
|
1326
|
-
# cleanup relay
|
|
1327
|
-
if [[ "$_relay_active" == "true" ]] && [[ -f "$CAC_DIR/relay.pid" ]]; then
|
|
1328
|
-
local _p; _p=$(cat "$CAC_DIR/relay.pid" 2>/dev/null) || true
|
|
1329
|
-
[[ -n "$_p" ]] && kill "$_p" 2>/dev/null || true
|
|
1330
|
-
rm -f "$CAC_DIR/relay.pid" "$CAC_DIR/relay.port"
|
|
1331
|
-
fi
|
|
1332
|
-
}
|
|
1333
|
-
|
|
1334
|
-
trap _cleanup_all EXIT INT TERM
|
|
1335
|
-
|
|
1336
|
-
# ── Relay watchdog: auto-restart relay if it crashes ──
|
|
1337
|
-
if [[ "$_relay_active" == "true" ]]; then
|
|
1338
|
-
(while true; do
|
|
1339
|
-
sleep 10
|
|
1340
|
-
[[ -f "$_relay_pid_file" ]] || break # pid file gone = intentional shutdown
|
|
1341
|
-
_wpid=$(tr -d '[:space:]' < "$_relay_pid_file" 2>/dev/null) || break
|
|
1342
|
-
if ! kill -0 "$_wpid" 2>/dev/null; then
|
|
1343
|
-
echo "[cac] relay crashed, restarting..." >&2
|
|
1344
|
-
node "$_relay_js" "$_rport" "$PROXY" "$_relay_pid_file" </dev/null >>"$CAC_DIR/relay.log" 2>&1 &
|
|
1345
|
-
disown
|
|
1346
|
-
for _wi in {1..30}; do
|
|
1347
|
-
(echo >/dev/tcp/127.0.0.1/$_rport) 2>/dev/null && break
|
|
1348
|
-
sleep 0.1
|
|
1349
|
-
done
|
|
1350
|
-
fi
|
|
1351
|
-
done) &
|
|
1352
|
-
_watchdog_pid=$!
|
|
1353
|
-
disown
|
|
1354
|
-
fi
|
|
1355
|
-
|
|
1356
1340
|
# ── Concurrent session check ──
|
|
1357
1341
|
_max_sessions=10
|
|
1358
1342
|
[[ -f "$CAC_DIR/max_sessions" ]] && _ms=$(tr -d '[:space:]' < "$CAC_DIR/max_sessions") && [[ -n "$_ms" ]] && _max_sessions="$_ms"
|
|
@@ -1370,7 +1354,6 @@ set +e
|
|
|
1370
1354
|
"$_real" "$@"
|
|
1371
1355
|
_ec=$?
|
|
1372
1356
|
set -e
|
|
1373
|
-
_cleanup_all
|
|
1374
1357
|
exit "$_ec"
|
|
1375
1358
|
WRAPPER_EOF
|
|
1376
1359
|
local _tmp="$CAC_DIR/bin/claude.tmp"
|
|
@@ -1497,7 +1480,7 @@ _ensure_initialized() {
|
|
|
1497
1480
|
if [[ -n "$_cac_bin" ]] && [[ -L "$_cac_bin" ]]; then
|
|
1498
1481
|
local _link; _link="$(readlink "$_cac_bin")"
|
|
1499
1482
|
[[ "$_link" != /* ]] && _link="$(dirname "$_cac_bin")/$_link"
|
|
1500
|
-
_self_dir="$(cd "$(dirname "$_link")" && pwd)"
|
|
1483
|
+
_self_dir="$(cd "$(dirname "$_link")" 2>/dev/null && pwd)" || _self_dir=""
|
|
1501
1484
|
fi
|
|
1502
1485
|
# Fallback: directory of the running script
|
|
1503
1486
|
if [[ -z "$_self_dir" ]] || [[ ! -f "$_self_dir/relay.js" ]]; then
|
|
@@ -1594,7 +1577,7 @@ _env_cmd_create() {
|
|
|
1594
1577
|
if [[ ! "$proxy" =~ ^(http|https|socks5):// ]]; then
|
|
1595
1578
|
printf " $(_dim "Detecting proxy protocol ...") "
|
|
1596
1579
|
if proxy_url=$(_auto_detect_proxy "$proxy"); then
|
|
1597
|
-
echo "$(_cyan "$(echo "$proxy_url" | grep -oE '^[a-z]+')")"
|
|
1580
|
+
echo "$(_cyan "$(echo "$proxy_url" | grep -oE '^[a-z]+' || echo "http")")"
|
|
1598
1581
|
else
|
|
1599
1582
|
echo "$(_yellow "failed, defaulting to http")"
|
|
1600
1583
|
fi
|
|
@@ -1900,7 +1883,7 @@ _env_cmd_set() {
|
|
|
1900
1883
|
if [[ ! "$value" =~ ^(http|https|socks5):// ]]; then
|
|
1901
1884
|
printf " $(_dim "Detecting proxy protocol ...") "
|
|
1902
1885
|
if proxy_url=$(_auto_detect_proxy "$value"); then
|
|
1903
|
-
echo "$(_cyan "$(echo "$proxy_url" | grep -oE '^[a-z]+')")"
|
|
1886
|
+
echo "$(_cyan "$(echo "$proxy_url" | grep -oE '^[a-z]+' || echo "http")")"
|
|
1904
1887
|
else
|
|
1905
1888
|
echo "$(_yellow "failed, defaulting to http")"
|
|
1906
1889
|
fi
|
|
@@ -1997,6 +1980,7 @@ _relay_start() {
|
|
|
1997
1980
|
return 1
|
|
1998
1981
|
fi
|
|
1999
1982
|
|
|
1983
|
+
echo "$proxy" > "$CAC_DIR/relay.proxy"
|
|
2000
1984
|
echo "$port" > "$CAC_DIR/relay.port"
|
|
2001
1985
|
return 0
|
|
2002
1986
|
}
|
|
@@ -2006,7 +1990,7 @@ _relay_stop() {
|
|
|
2006
1990
|
if [[ -f "$pid_file" ]]; then
|
|
2007
1991
|
local pid; pid=$(tr -d '[:space:]' < "$pid_file")
|
|
2008
1992
|
if [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null; then
|
|
2009
|
-
kill "$pid" 2>/dev/null
|
|
1993
|
+
kill "$pid" 2>/dev/null || true
|
|
2010
1994
|
# wait for process exit
|
|
2011
1995
|
local _i
|
|
2012
1996
|
for _i in {1..20}; do
|
|
@@ -2016,7 +2000,7 @@ _relay_stop() {
|
|
|
2016
2000
|
fi
|
|
2017
2001
|
rm -f "$pid_file"
|
|
2018
2002
|
fi
|
|
2019
|
-
rm -f "$CAC_DIR/relay.port"
|
|
2003
|
+
rm -f "$CAC_DIR/relay.port" "$CAC_DIR/relay.proxy"
|
|
2020
2004
|
|
|
2021
2005
|
# cleanup route
|
|
2022
2006
|
_relay_remove_route 2>/dev/null || true
|
|
@@ -2305,7 +2289,7 @@ cmd_check() {
|
|
|
2305
2289
|
|
|
2306
2290
|
# ── concurrent sessions ──
|
|
2307
2291
|
local _claude_count
|
|
2308
|
-
_claude_count=$(pgrep -x "claude" 2>/dev/null | wc -l | tr -d '[:space:]')
|
|
2292
|
+
_claude_count=$(pgrep -x "claude" 2>/dev/null | wc -l | tr -d '[:space:]') || _claude_count=0
|
|
2309
2293
|
local _max_sessions; _max_sessions=$(_cac_setting max_sessions 10)
|
|
2310
2294
|
if [[ "$_claude_count" -gt "$_max_sessions" ]]; then
|
|
2311
2295
|
echo " $(_yellow "⚠") sessions $_claude_count running (threshold: $_max_sessions)"
|
|
@@ -2397,7 +2381,7 @@ cmd_check() {
|
|
|
2397
2381
|
|
|
2398
2382
|
# ── summary ──
|
|
2399
2383
|
echo
|
|
2400
|
-
if [[ ${#problems[@]} -eq 0 ]]; then
|
|
2384
|
+
if [[ ${#problems[@]:-0} -eq 0 ]]; then
|
|
2401
2385
|
echo " $(_green "✓") all good"
|
|
2402
2386
|
else
|
|
2403
2387
|
for p in "${problems[@]}"; do
|
|
@@ -2786,7 +2770,8 @@ _dk_detect_network() {
|
|
|
2786
2770
|
return 1
|
|
2787
2771
|
fi
|
|
2788
2772
|
|
|
2789
|
-
addr=$(ip -4 addr show "$iface" | awk '/inet /{print $2; exit}')
|
|
2773
|
+
addr=$(ip -4 addr show "$iface" 2>/dev/null | awk '/inet /{print $2; exit}') || addr=""
|
|
2774
|
+
[[ -z "$addr" ]] && { echo "error: cannot get address for $iface" >&2; return 1; }
|
|
2790
2775
|
ip="${addr%/*}"
|
|
2791
2776
|
prefix="${addr#*/}"
|
|
2792
2777
|
|
package/package.json
CHANGED
package/scripts/postinstall.js
CHANGED
|
@@ -42,6 +42,12 @@ if (home && fs.existsSync(wrapperPath)) {
|
|
|
42
42
|
if (patched.indexOf(buggyPgrep) !== -1 && patched.indexOf(fixedPgrep) === -1) {
|
|
43
43
|
patched = patched.replace(buggyPgrep, fixedPgrep);
|
|
44
44
|
}
|
|
45
|
+
// Fix: session exit killed the shared relay, breaking all other sessions.
|
|
46
|
+
// Remove the trap so _cleanup_all never fires on exit.
|
|
47
|
+
var buggyTrap = 'trap _cleanup_all EXIT INT TERM';
|
|
48
|
+
if (patched.indexOf(buggyTrap) !== -1) {
|
|
49
|
+
patched = patched.replace(buggyTrap, '');
|
|
50
|
+
}
|
|
45
51
|
if (patched !== wrapperContent) {
|
|
46
52
|
fs.writeFileSync(wrapperPath, patched);
|
|
47
53
|
}
|