claude-cac 1.5.2 → 1.5.4
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/cac +56 -24
- package/package.json +1 -1
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.5.
|
|
14
|
+
CAC_VERSION="1.5.4"
|
|
15
15
|
|
|
16
16
|
_read() { [[ -f "$1" ]] && tr -d '[:space:]' < "$1" || echo "${2:-}"; }
|
|
17
17
|
_die() { printf '%b\n' "$(_red "error:") $*" >&2; exit 1; }
|
|
@@ -1044,6 +1044,9 @@ _write_env_settings() {
|
|
|
1044
1044
|
"statusLine": {
|
|
1045
1045
|
"type": "command",
|
|
1046
1046
|
"command": "bash $CLAUDE_CONFIG_DIR/statusline-command.sh"
|
|
1047
|
+
},
|
|
1048
|
+
"env": {
|
|
1049
|
+
"DISABLE_AUTOUPDATER": "1"
|
|
1047
1050
|
}
|
|
1048
1051
|
}
|
|
1049
1052
|
SETTINGS_EOF
|
|
@@ -1273,7 +1276,9 @@ if [[ -f "$_env_dir/persona" ]]; then
|
|
|
1273
1276
|
fi
|
|
1274
1277
|
|
|
1275
1278
|
# ── NS-level DNS interception ──
|
|
1276
|
-
|
|
1279
|
+
# Use -r (readable) not -f (exists) — root-owned files with mode 600 exist but
|
|
1280
|
+
# can't be read by normal user, causing bun/node to crash silently.
|
|
1281
|
+
if [[ -r "$CAC_DIR/cac-dns-guard.js" ]]; then
|
|
1277
1282
|
case "${NODE_OPTIONS:-}" in
|
|
1278
1283
|
*cac-dns-guard.js*) ;; # already injected, skip
|
|
1279
1284
|
*) export NODE_OPTIONS="${NODE_OPTIONS:-} --require $CAC_DIR/cac-dns-guard.js" ;;
|
|
@@ -1284,7 +1289,7 @@ if [[ -f "$CAC_DIR/cac-dns-guard.js" ]]; then
|
|
|
1284
1289
|
esac
|
|
1285
1290
|
fi
|
|
1286
1291
|
# fallback layer: HOSTALIASES (gethostbyname level)
|
|
1287
|
-
[[ -
|
|
1292
|
+
[[ -r "$CAC_DIR/blocked_hosts" ]] && export HOSTALIASES="$CAC_DIR/blocked_hosts"
|
|
1288
1293
|
|
|
1289
1294
|
# ── mTLS client certificate ──
|
|
1290
1295
|
if [[ -f "$_env_dir/client_cert.pem" ]] && [[ -f "$_env_dir/client_key.pem" ]]; then
|
|
@@ -1312,7 +1317,7 @@ fi
|
|
|
1312
1317
|
[[ -f "$_env_dir/machine_id" ]] && export CAC_MACHINE_ID=$(tr -d '[:space:]' < "$_env_dir/machine_id")
|
|
1313
1318
|
export CAC_USERNAME="user-$(echo "$_name" | cut -c1-8)"
|
|
1314
1319
|
export USER="$CAC_USERNAME" LOGNAME="$CAC_USERNAME"
|
|
1315
|
-
if [[ -
|
|
1320
|
+
if [[ -r "$CAC_DIR/fingerprint-hook.js" ]]; then
|
|
1316
1321
|
case "${NODE_OPTIONS:-}" in
|
|
1317
1322
|
*fingerprint-hook.js*) ;;
|
|
1318
1323
|
*) export NODE_OPTIONS="--require $CAC_DIR/fingerprint-hook.js ${NODE_OPTIONS:-}" ;;
|
|
@@ -1581,11 +1586,45 @@ _ensure_initialized() {
|
|
|
1581
1586
|
if [[ -z "$_self_dir" ]] || [[ ! -f "$_self_dir/relay.js" ]]; then
|
|
1582
1587
|
_self_dir="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)"
|
|
1583
1588
|
fi
|
|
1584
|
-
|
|
1585
|
-
|
|
1589
|
+
# Warn if running as root — files written here become root-owned and break
|
|
1590
|
+
# normal-user invocations (wrapper has set -e and will silently exit).
|
|
1591
|
+
if [[ $EUID -eq 0 ]]; then
|
|
1592
|
+
echo "[cac] warning: running as root may corrupt ~/.cac/ file ownership" >&2
|
|
1593
|
+
echo "[cac] hint: run as your normal user instead" >&2
|
|
1594
|
+
fi
|
|
1595
|
+
# rm -f first: user owns ~/.cac/ dir so can delete root-owned files even if can't overwrite them
|
|
1596
|
+
if [[ -f "$_self_dir/fingerprint-hook.js" ]]; then
|
|
1597
|
+
rm -f "$CAC_DIR/fingerprint-hook.js" 2>/dev/null || true
|
|
1598
|
+
cp "$_self_dir/fingerprint-hook.js" "$CAC_DIR/fingerprint-hook.js" 2>/dev/null || true
|
|
1599
|
+
fi
|
|
1600
|
+
if [[ -f "$_self_dir/relay.js" ]]; then
|
|
1601
|
+
rm -f "$CAC_DIR/relay.js" 2>/dev/null || true
|
|
1602
|
+
cp "$_self_dir/relay.js" "$CAC_DIR/relay.js" 2>/dev/null || true
|
|
1603
|
+
fi
|
|
1604
|
+
rm -f "$CAC_DIR/cac-dns-guard.js" 2>/dev/null || true
|
|
1586
1605
|
_write_dns_guard_js 2>/dev/null || true
|
|
1606
|
+
rm -f "$CAC_DIR/blocked_hosts" 2>/dev/null || true
|
|
1587
1607
|
_write_blocked_hosts 2>/dev/null || true
|
|
1588
1608
|
|
|
1609
|
+
# Patch all existing envs: ensure DISABLE_AUTOUPDATER=1 in settings.json
|
|
1610
|
+
local _sf
|
|
1611
|
+
for _sf in "$ENVS_DIR"/*/.claude/settings.json; do
|
|
1612
|
+
[[ -f "$_sf" ]] || continue
|
|
1613
|
+
grep -q '"DISABLE_AUTOUPDATER"' "$_sf" 2>/dev/null && continue
|
|
1614
|
+
python3 - "$_sf" << 'PYEOF' 2>/dev/null || true
|
|
1615
|
+
import json, sys
|
|
1616
|
+
path = sys.argv[1]
|
|
1617
|
+
with open(path) as f:
|
|
1618
|
+
d = json.load(f)
|
|
1619
|
+
if d.get('env', {}).get('DISABLE_AUTOUPDATER') == '1':
|
|
1620
|
+
sys.exit(0)
|
|
1621
|
+
d.setdefault('env', {})['DISABLE_AUTOUPDATER'] = '1'
|
|
1622
|
+
with open(path, 'w') as f:
|
|
1623
|
+
json.dump(d, f, indent=2)
|
|
1624
|
+
f.write('\n')
|
|
1625
|
+
PYEOF
|
|
1626
|
+
done
|
|
1627
|
+
|
|
1589
1628
|
# PATH (idempotent — always ensure it's in rc file)
|
|
1590
1629
|
local rc_file; rc_file=$(_detect_rc_file)
|
|
1591
1630
|
_write_path_to_rc "$rc_file" >/dev/null 2>&1 || true
|
|
@@ -1730,7 +1769,7 @@ _env_cmd_create() {
|
|
|
1730
1769
|
mkdir -p "$env_dir"
|
|
1731
1770
|
[[ -n "$proxy_url" ]] && echo "$proxy_url" > "$env_dir/proxy"
|
|
1732
1771
|
echo "$(_new_uuid)" > "$env_dir/uuid"
|
|
1733
|
-
|
|
1772
|
+
touch "$env_dir/user_id"
|
|
1734
1773
|
echo "$(_new_machine_id)" > "$env_dir/machine_id"
|
|
1735
1774
|
echo "$(_new_hostname)" > "$env_dir/hostname"
|
|
1736
1775
|
echo "$(_new_mac)" > "$env_dir/mac_address"
|
|
@@ -1823,7 +1862,6 @@ MERGE_EOF
|
|
|
1823
1862
|
if [[ -d "$env_dir/.claude" ]]; then
|
|
1824
1863
|
export CLAUDE_CONFIG_DIR="$env_dir/.claude"
|
|
1825
1864
|
fi
|
|
1826
|
-
_update_claude_json_user_id "$(_read "$env_dir/user_id")" 2>/dev/null || true
|
|
1827
1865
|
|
|
1828
1866
|
local elapsed; elapsed=$(_timer_elapsed)
|
|
1829
1867
|
echo
|
|
@@ -1919,7 +1957,6 @@ _env_cmd_activate() {
|
|
|
1919
1957
|
export CLAUDE_CONFIG_DIR="$ENVS_DIR/$name/.claude"
|
|
1920
1958
|
fi
|
|
1921
1959
|
|
|
1922
|
-
_update_claude_json_user_id "$(_read "$ENVS_DIR/$name/user_id")"
|
|
1923
1960
|
|
|
1924
1961
|
# Relay lifecycle
|
|
1925
1962
|
_relay_stop 2>/dev/null || true
|
|
@@ -2429,23 +2466,18 @@ cmd_check() {
|
|
|
2429
2466
|
else
|
|
2430
2467
|
_id_issues+=("repo hash not spoofed")
|
|
2431
2468
|
fi
|
|
2432
|
-
# user_id
|
|
2469
|
+
# user_id tracking: sync from .claude.json after login (real userID wins)
|
|
2433
2470
|
local _uid_ok=true
|
|
2434
|
-
local
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
_actual_uid=$(python3 -c "import json,sys; print(json.load(open(sys.argv[1])).get('userID',''))" "$_cj" 2>/dev/null || true)
|
|
2471
|
+
local _config_dir="${CLAUDE_CONFIG_DIR:-$ENVS_DIR/$current/.claude}"
|
|
2472
|
+
local _cj="$_config_dir/.claude.json"
|
|
2473
|
+
[[ -f "$_cj" ]] || _cj="$HOME/.claude.json"
|
|
2474
|
+
if [[ -f "$_cj" ]]; then
|
|
2475
|
+
local _actual_uid
|
|
2476
|
+
_actual_uid=$(python3 -c "import json,sys; print(json.load(open(sys.argv[1])).get('userID',''))" "$_cj" 2>/dev/null || true)
|
|
2477
|
+
if [[ -n "$_actual_uid" ]]; then
|
|
2442
2478
|
(( _id_total++ )) || true
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
_id_issues+=("user_id mismatch")
|
|
2446
|
-
else
|
|
2447
|
-
(( _id_ok++ )) || true
|
|
2448
|
-
fi
|
|
2479
|
+
echo "$_actual_uid" > "$env_dir/user_id" 2>/dev/null || true
|
|
2480
|
+
(( _id_ok++ )) || true
|
|
2449
2481
|
fi
|
|
2450
2482
|
fi
|
|
2451
2483
|
# billing header
|