claude-cac 1.4.0-beta.2 → 1.4.0-beta.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.
Files changed (2) hide show
  1. package/cac +37 -82
  2. 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.4.0-beta.2"
14
+ CAC_VERSION="1.4.0-beta.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; }
@@ -444,7 +444,7 @@ _write_blocked_hosts() {
444
444
  local hosts_file="$CAC_DIR/blocked_hosts"
445
445
  {
446
446
  echo "# cac — blocked telemetry domains"
447
- echo "# Generated by cac setup, used via HOSTALIASES"
447
+ echo "# Generated by cac, used via HOSTALIASES"
448
448
  for domain in "${TELEMETRY_DOMAINS[@]}"; do
449
449
  printf '%s\tlocalhost\n' "$domain"
450
450
  done
@@ -653,44 +653,27 @@ if (mtlsCert && mtlsKey) {
653
653
 
654
654
 
655
655
  // ─── 3. fetch telemetry interception patch ──────────────────────────────────
656
- // Node.js native fetch (undici) bypasses dns.lookup, circumventing DNS blocking
657
- // Strategy: prefer node-fetch (uses http/https modules -> dns.lookup)
658
- // otherwise wrap native fetch to block telemetry domains
656
+ // Wrap native fetch to block telemetry domains by URL check
657
+ // (do NOT replace with node-fetch its Response.body lacks ReadableStream.cancel(),
658
+ // which breaks Bun-based Claude Code streaming)
659
659
 
660
660
  (function patchFetch() {
661
- if (typeof globalThis === 'undefined') return;
661
+ if (typeof globalThis === 'undefined' || typeof globalThis.fetch !== 'function') return;
662
662
 
663
- // prefer node-fetch (based on http/https modules, naturally goes through dns.lookup interception chain)
664
- try {
665
- var nodeFetch = require('node-fetch');
666
- if (nodeFetch && typeof nodeFetch === 'function') {
667
- globalThis.fetch = nodeFetch;
668
- if (nodeFetch.Headers) globalThis.Headers = nodeFetch.Headers;
669
- if (nodeFetch.Request) globalThis.Request = nodeFetch.Request;
670
- if (nodeFetch.Response) globalThis.Response = nodeFetch.Response;
671
- return;
672
- }
673
- } catch(e) {
674
- // node-fetch not available
675
- }
663
+ var _origFetch = globalThis.fetch;
664
+ globalThis.fetch = function cacFetch(input, init) {
665
+ var hostname;
666
+ try {
667
+ var urlStr = typeof input === 'string' ? input :
668
+ (input && input.url) ? input.url : '';
669
+ if (urlStr) hostname = new URL(urlStr).hostname;
670
+ } catch(e) { /* ignore */ }
676
671
 
677
- // fallback: wrap native fetch to ensure telemetry domains are blocked
678
- if (typeof globalThis.fetch === 'function') {
679
- var _origFetch = globalThis.fetch;
680
- globalThis.fetch = function cacFetch(input, init) {
681
- var hostname;
682
- try {
683
- var urlStr = typeof input === 'string' ? input :
684
- (input && input.url) ? input.url : '';
685
- if (urlStr) hostname = new URL(urlStr).hostname;
686
- } catch(e) { /* ignore */ }
687
-
688
- if (hostname && isDomainBlocked(hostname)) {
689
- return Promise.reject(makeBlockedError(hostname, 'fetch'));
690
- }
691
- return _origFetch(input, init);
692
- };
693
- }
672
+ if (hostname && isDomainBlocked(hostname)) {
673
+ return Promise.reject(makeBlockedError(hostname, 'fetch'));
674
+ }
675
+ return _origFetch(input, init);
676
+ };
694
677
  })();
695
678
 
696
679
 
@@ -1062,11 +1045,14 @@ _write_env_settings() {
1062
1045
  SETTINGS_EOF
1063
1046
  }
1064
1047
 
1065
- # write CLAUDE.md to env .claude dir
1048
+ # write CAC Meta Prompt to env .claude/CLAUDE.md
1049
+ # Usage: _write_env_claude_md <config_dir> <env_name> [--append]
1066
1050
  _write_env_claude_md() {
1067
1051
  local config_dir="$1"
1068
1052
  local env_name="$2"
1069
- cat > "$config_dir/CLAUDE.md" << CLAUDEMD_EOF
1053
+ local _meta
1054
+ _meta=$(cat << CLAUDEMD_EOF
1055
+
1070
1056
  # cac managed environment
1071
1057
 
1072
1058
  This Claude Code instance is managed by **cac** (Claude Code Cloak).
@@ -1080,6 +1066,12 @@ Useful commands:
1080
1066
  - \`cac env check\` — verify current environment health
1081
1067
  - \`cac <name>\` — switch to another environment
1082
1068
  CLAUDEMD_EOF
1069
+ )
1070
+ if [[ "${3:-}" == "--append" ]]; then
1071
+ printf '\n%s\n' "$_meta" >> "$config_dir/CLAUDE.md"
1072
+ else
1073
+ printf '%s\n' "$_meta" > "$config_dir/CLAUDE.md"
1074
+ fi
1083
1075
  }
1084
1076
 
1085
1077
  _write_wrapper() {
@@ -1096,7 +1088,7 @@ ENVS_DIR="$CAC_DIR/envs"
1096
1088
  if [[ -f "$CAC_DIR/stopped" ]]; then
1097
1089
  _real=$(tr -d '[:space:]' < "$CAC_DIR/real_claude" 2>/dev/null || true)
1098
1090
  [[ -x "$_real" ]] && exec "$_real" "$@"
1099
- echo "[cac] error: real claude not found, run 'cac setup'" >&2; exit 1
1091
+ echo "[cac] error: real claude not found, reinstall with 'npm i -g claude-cac'" >&2; exit 1
1100
1092
  fi
1101
1093
 
1102
1094
  # read current environment
@@ -1285,7 +1277,7 @@ fi
1285
1277
  if [[ -z "$_real" ]] || [[ ! -x "$_real" ]]; then
1286
1278
  _real=$(tr -d '[:space:]' < "$CAC_DIR/real_claude")
1287
1279
  fi
1288
- [[ -x "$_real" ]] || { echo "[cac] error: claude not found, run 'cac setup'" >&2; exit 1; }
1280
+ [[ -x "$_real" ]] || { echo "[cac] error: claude not found, run 'cac claude install latest'" >&2; exit 1; }
1289
1281
 
1290
1282
  # ── Relay local forwarding (always enabled when proxy is set) ──
1291
1283
  _relay_active=false
@@ -1463,9 +1455,9 @@ IFCONFIG_EOF
1463
1455
  }
1464
1456
 
1465
1457
  # ━━━ cmd_setup.sh ━━━
1466
- # ── cmd: setup (auto-bootstrap, no manual step needed) ─────────
1458
+ # ── auto-bootstrap (silent, idempotent) ─────────────────────────
1467
1459
 
1468
- # Silent, idempotent initializationcalled automatically by any command
1460
+ # Called automatically by any command no manual setup needed
1469
1461
  _ensure_initialized() {
1470
1462
  mkdir -p "$CAC_DIR" "$ENVS_DIR" "$VERSIONS_DIR"
1471
1463
 
@@ -1535,44 +1527,6 @@ _ensure_initialized() {
1535
1527
  _generate_ca_cert 2>/dev/null || true
1536
1528
  }
1537
1529
 
1538
- # Explicit setup command — runs initialization with verbose output
1539
- cmd_setup() {
1540
- echo "$(_bold "cac setup")"
1541
- echo
1542
-
1543
- _ensure_initialized
1544
-
1545
- # Find or install Claude Code
1546
- local real_claude; real_claude=$(_read "$CAC_DIR/real_claude" "")
1547
- if [[ -z "$real_claude" ]] || [[ ! -x "$real_claude" ]]; then
1548
- echo " Claude Code not found"
1549
- printf " Install latest version? [Y/n] "
1550
- read -r _ans
1551
- if [[ "$_ans" != "n" && "$_ans" != "N" ]]; then
1552
- _claude_cmd_install latest
1553
- local latest_ver; latest_ver=$(_read "$VERSIONS_DIR/.latest" "")
1554
- if [[ -n "$latest_ver" ]]; then
1555
- real_claude="$VERSIONS_DIR/$latest_ver/claude"
1556
- echo "$real_claude" > "$CAC_DIR/real_claude"
1557
- fi
1558
- fi
1559
- fi
1560
-
1561
- if [[ -n "$real_claude" ]] && [[ -x "$real_claude" ]]; then
1562
- echo " Claude Code: $(_cyan "$real_claude")"
1563
- fi
1564
- echo " Wrapper: $(_cyan "$CAC_DIR/bin/claude")"
1565
- echo " Shims: $(_cyan "$CAC_DIR/shim-bin/")"
1566
- echo
1567
-
1568
- local rc_file; rc_file=$(_detect_rc_file)
1569
- if [[ -n "$rc_file" ]]; then
1570
- echo " Run to activate: $(_green "source $rc_file")"
1571
- fi
1572
- echo
1573
- echo " Create environment: $(_green "cac env create <name> [-p <proxy>]")"
1574
- }
1575
-
1576
1530
  # ━━━ cmd_env.sh ━━━
1577
1531
  # ── cmd: env (environment management, like "uv venv") ────────────
1578
1532
 
@@ -1714,6 +1668,7 @@ _env_cmd_create() {
1714
1668
  ln -sf "$src_claude_dir/CLAUDE.md" "$env_dir/.claude/CLAUDE.md"
1715
1669
  else
1716
1670
  cp "$src_claude_dir/CLAUDE.md" "$env_dir/.claude/CLAUDE.md"
1671
+ _write_env_claude_md "$env_dir/.claude" "$name" --append
1717
1672
  fi
1718
1673
  fi
1719
1674
  if [[ -f "$src_claude_dir/settings.json" ]]; then
@@ -1986,7 +1941,7 @@ _relay_start() {
1986
1941
  [[ -z "$proxy" ]] && return 1
1987
1942
 
1988
1943
  local relay_js="$CAC_DIR/relay.js"
1989
- [[ -f "$relay_js" ]] || { echo "error: relay.js not found, run 'cac setup'" >&2; return 1; }
1944
+ [[ -f "$relay_js" ]] || { echo "error: relay.js not found, reinstall with 'npm i -g claude-cac'" >&2; return 1; }
1990
1945
 
1991
1946
  # find available port (17890-17999)
1992
1947
  local port=17890
@@ -3330,7 +3285,7 @@ case "$1" in
3330
3285
  help|--help|-h) cmd_help ;;
3331
3286
  # ── deprecated (shims with warnings) ──
3332
3287
  add) echo "$(_yellow "warning:") 'cac add' → 'cac env create <name> -p <proxy>'" >&2; exit 1 ;;
3333
- setup) echo "$(_yellow "warning:") 'cac setup' is no longer needed — cac auto-initializes" >&2 ;;
3288
+ setup) echo "$(_yellow "removed:") 'cac setup' no longer exists — cac auto-initializes on first use" >&2 ;;
3334
3289
  check) echo "$(_yellow "warning:") 'cac check' → 'cac env check'" >&2; cmd_check ;;
3335
3290
  stop) echo "$(_yellow "warning:") 'cac stop' has been removed — switch with 'cac <name>'" >&2 ;;
3336
3291
  resume|-c) echo "$(_yellow "warning:") 'cac resume' removed — use 'cac env activate <name>'" >&2; exit 1 ;;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-cac",
3
- "version": "1.4.0-beta.2",
3
+ "version": "1.4.0-beta.4",
4
4
  "description": "Isolate, protect, and manage your Claude Code — versions, environments, identity, and proxy.",
5
5
  "bin": {
6
6
  "cac": "cac"