@dst-justin/relay 2.1.1 → 2.1.3

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 (3) hide show
  1. package/README.md +25 -0
  2. package/package.json +1 -1
  3. package/relay +88 -36
package/README.md CHANGED
@@ -218,3 +218,28 @@ Sessions live in `~/.claude/projects/` and are shared across all accounts — af
218
218
  | `relay.ps1` | Full PowerShell implementation |
219
219
  | `relay.cmd` | Thin CMD wrapper — delegates to `relay.ps1` |
220
220
 
221
+
222
+ ---
223
+
224
+ ## Changelog
225
+
226
+ ### v2.1.1 — 2026-06-24
227
+ - Display current version and latest version at the end of `list`, `status`, `relay` (menu), `sessions`, and `help` commands
228
+ - Background version check (24h cache) — non-blocking, never slows down output
229
+ - `relay update` now detects original install method: uses `npm install -g` for npm installs, `git pull` for git clones, and direct GitHub download for bare script copies
230
+ - `npm install -g` post-install script automatically patches `~/.bashrc`, `~/.zshrc`, `~/.profile`, and fish `config.fish` if the npm bin dir is missing from PATH
231
+
232
+ ### v2.1.3 — 2026-06-24
233
+ - `relay autoswitch` with no subcommand: auto-routes to config wizard (first time) or status panel (already configured)
234
+ - Autoswitch status and log panels now show version info and update notice at the bottom
235
+ - Status panel shows available commands inline
236
+
237
+ ### v2.1.2 — 2026-06-24
238
+ - Improve autoswitch config wizard: 3-step flow with numbered account list, space-separated number input for order, visual chain preview (`work → personal → (cycle)`), and summary after save
239
+ - `relay update` now writes the live-fetched version to cache immediately, so display commands reflect the latest version without waiting 24h
240
+
241
+ ### v2.1.0 — 2026-06-24
242
+ - Upgraded GitHub Actions workflow to `actions/checkout@v6` and `actions/setup-node@v6` (Node 24 runtime, removes Node 20 deprecation warning)
243
+
244
+ ### v2.0.2 — 2026-06-23
245
+ - Skip `npm install` during `relay update` when already on the latest version or when version check fails
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dst-justin/relay",
3
- "version": "2.1.1",
3
+ "version": "2.1.3",
4
4
  "description": "Multi-account switcher for Claude Code — instant credential swap across macOS, Linux, and Windows",
5
5
  "bin": {
6
6
  "relay": "./relay.js"
package/relay CHANGED
@@ -908,47 +908,74 @@ cmd_autoswitch_config() {
908
908
  exit 1
909
909
  fi
910
910
 
911
+ # ── Step 1: switch order ───────────────────────────────────────
911
912
  echo ""
912
- printf " Accounts found: ${CY}%s${R}\n\n" "$(IFS=', '; echo "${accounts[*]}")"
913
-
914
- printf " ${B}Switch order${R} (comma-separated, only listed accounts join autoswitch):\n"
913
+ printf " ${B}Step 1 / 3 — Switch order${R}\n"
914
+ printf " ${D}When an account hits its threshold, relay switches to the next one in order.${R}\n\n"
915
+ local i=1
916
+ for acct in "${accounts[@]}"; do
917
+ printf " ${D}%d${R} %s\n" "${i}" "${acct}"
918
+ i=$((i+1))
919
+ done
920
+ echo ""
921
+ printf " ${D}Type numbers in the order you want (e.g. ${CY}2 1${D} or just Enter to keep the order above):${R}\n"
915
922
  printf " > "; read -r order_input
916
- local order_str; order_str=$(echo "${order_input}" | "${PY}" -c "
917
- import sys,re
918
- raw=sys.stdin.read().strip()
919
- names=[x.strip() for x in raw.split(',') if x.strip()]
920
- print(','.join(names))")
921
923
 
924
+ # resolve numbers (space or comma) to names; empty = default order
925
+ local order_str; order_str=$(echo "${order_input}" | "${PY}" - "${accounts[@]}" <<'PYEOF'
926
+ import sys, re
927
+ raw = sys.stdin.read().strip()
928
+ accts = sys.argv[1:]
929
+ if not raw:
930
+ print(','.join(accts))
931
+ else:
932
+ tokens = re.split(r'[\s,]+', raw)
933
+ result = []
934
+ for t in tokens:
935
+ t = t.strip()
936
+ if t.isdigit():
937
+ idx = int(t) - 1
938
+ if 0 <= idx < len(accts): result.append(accts[idx])
939
+ elif t:
940
+ result.append(t)
941
+ print(','.join(result))
942
+ PYEOF
943
+ )
944
+ # show resolved order as a visual chain
945
+ local chain; chain=$(echo "${order_str}" | "${PY}" -c "
946
+ import sys; names=sys.stdin.read().strip().split(',')
947
+ print(' → '.join(names) + ' → (cycle)')")
948
+ printf " ${D}Order: ${CY}%s${R}\n" "${chain}"
949
+
950
+ # ── Step 2: thresholds ────────────────────────────────────────
922
951
  echo ""
923
- printf " ${B}Thresholds${R} (press enter to skip account it won't join autoswitch):\n"
952
+ printf " ${B}Step 2 / 3Thresholds${R}\n"
953
+ printf " ${D}Autoswitch triggers when an account's 5-hr usage exceeds this %%.${R}\n"
954
+ printf " ${D}Enter a number (e.g. 70), or press Enter for default 80%%.${R}\n\n"
955
+
924
956
  local thresholds_json="{"
925
957
  local order_json="["
926
- local first_order=1
927
- local first_thresh=1
958
+ local first=1
928
959
  IFS=',' read -ra order_arr <<< "${order_str}"
929
960
  for acct in "${order_arr[@]}"; do
930
- printf " %s threshold %% [default 80]: " "${acct}"
961
+ printf " ${CY}%s${R} threshold [80%%]: " "${acct}"
931
962
  read -r val
932
- if [[ -z "${val}" ]]; then
933
- continue
934
- fi
935
- [[ ${first_order} -eq 0 ]] && order_json+=","
963
+ [[ -z "${val}" ]] && val="80"
964
+ [[ ${first} -eq 0 ]] && { order_json+=","; thresholds_json+=","; }
936
965
  order_json+="\"${acct}\""
937
- first_order=0
938
- [[ ${first_thresh} -eq 0 ]] && thresholds_json+=","
939
966
  thresholds_json+="\"${acct}\":${val}"
940
- first_thresh=0
967
+ first=0
941
968
  done
942
969
  order_json+="]"
943
970
  thresholds_json+="}"
944
971
 
972
+ # ── Step 3: poll interval ─────────────────────────────────────
945
973
  echo ""
946
- printf " ${B}Poll interval${R} — low usage (minutes) [default 10]: "
947
- read -r low_min; low_min="${low_min:-10}"
948
- printf " ${B}Poll interval${R} high usage (minutes) [default 2]: "
949
- read -r high_min; high_min="${high_min:-2}"
950
- printf " ${B}High usage starts at${R} %% [default 50]: "
951
- read -r high_thr; high_thr="${high_thr:-50}"
974
+ printf " ${B}Step 3 / 3 — Check interval${R}\n"
975
+ printf " ${D}How often the daemon checks usage. Switches to faster polling near the threshold.${R}\n\n"
976
+ printf " Normal check every N minutes [10]: "; read -r low_min; low_min="${low_min:-10}"
977
+ printf " Fast check every N minutes [2]: "; read -r high_min; high_min="${high_min:-2}"
978
+ printf " Switch to fast polling at [50%%]: "; read -r high_thr; high_thr="${high_thr:-50}"
952
979
 
953
980
  local cfg_file="${RELAY_DIR}/autoswitch.json"
954
981
  printf '{"order":%s,"thresholds":%s,"poll":{"low_minutes":%s,"high_minutes":%s,"high_threshold":%s}}' \
@@ -957,7 +984,20 @@ print(','.join(names))")
957
984
  > "${cfg_file}"
958
985
 
959
986
  echo ""
960
- ok "Saved to ${cfg_file}"
987
+ ok "Config saved to ${cfg_file}"
988
+ echo ""
989
+ "${PY}" - "${cfg_file}" <<'PYEOF'
990
+ import json, sys
991
+ cfg = json.load(open(sys.argv[1]))
992
+ R='\033[0m'; B='\033[1m'; D='\033[2m'; CY='\033[36m'
993
+ for i, name in enumerate(cfg['order'], 1):
994
+ thr = cfg['thresholds'].get(name, '?')
995
+ print(f' {D}{i}.{R} {name:<14} → switch at {CY}{thr}%{R}')
996
+ p = cfg['poll']
997
+ lo, hi, thr = p['low_minutes'], p['high_minutes'], p['high_threshold']
998
+ print(f'\n {D}polling: {lo}min normal / {hi}min fast (fast above {thr}%){R}')
999
+ PYEOF
1000
+ echo ""
961
1001
  log "Run ${CY}relay autoswitch start${R} to activate"
962
1002
  }
963
1003
 
@@ -1055,6 +1095,7 @@ cmd_autoswitch_stop() {
1055
1095
  }
1056
1096
 
1057
1097
  cmd_autoswitch_status() {
1098
+ _check_update_bg
1058
1099
  hdr "autoswitch — status"
1059
1100
 
1060
1101
  local pid; pid=$(cat "${RELAY_DIR}/autoswitch.lock" 2>/dev/null || echo "")
@@ -1067,6 +1108,7 @@ cmd_autoswitch_status() {
1067
1108
  local cfg="${RELAY_DIR}/autoswitch.json"
1068
1109
  if [[ ! -f "${cfg}" ]]; then
1069
1110
  warn "No config. Run: relay autoswitch config"
1111
+ _show_update_notice
1070
1112
  return 0
1071
1113
  fi
1072
1114
 
@@ -1134,12 +1176,18 @@ except: pass
1134
1176
  EOF
1135
1177
 
1136
1178
  echo ""
1137
- log "Run ${CY}relay autoswitch log${R} to see full history"
1179
+ printf " ${D}────────────────────────────────────────${R}\n"
1180
+ printf " %-34s %s\n" " ${CY}relay autoswitch start${R}" "start daemon"
1181
+ printf " %-34s %s\n" " ${CY}relay autoswitch stop${R}" "stop daemon"
1182
+ printf " %-34s %s\n" " ${CY}relay autoswitch config${R}" "edit settings"
1183
+ printf " %-34s %s\n" " ${CY}relay autoswitch log${R}" "switch history"
1184
+ _show_update_notice
1138
1185
  }
1139
1186
 
1140
1187
  cmd_autoswitch_log() {
1188
+ _check_update_bg
1141
1189
  local log_file="${RELAY_DIR}/autoswitch.log"
1142
- [[ -f "${log_file}" ]] || { warn "No log yet"; return 0; }
1190
+ [[ -f "${log_file}" ]] || { warn "No log yet"; _show_update_notice; return 0; }
1143
1191
 
1144
1192
  hdr "autoswitch — log (last 20 events)"
1145
1193
  "${PY}" - "${log_file}" <<'EOF'
@@ -1162,6 +1210,7 @@ for line in lines[-20:]:
1162
1210
  print(f' {D}{ts}{R} {D}daemon start{R}')
1163
1211
  except: pass
1164
1212
  EOF
1213
+ _show_update_notice
1165
1214
  }
1166
1215
 
1167
1216
  cmd_autoswitch() {
@@ -1173,13 +1222,11 @@ cmd_autoswitch() {
1173
1222
  status) cmd_autoswitch_status ;;
1174
1223
  log) cmd_autoswitch_log ;;
1175
1224
  *)
1176
- hdr "autoswitch"
1177
- printf " %-32s %s\n" " relay autoswitch config" "interactive setup wizard"
1178
- printf " %-32s %s\n" " relay autoswitch start" "install and start daemon"
1179
- printf " %-32s %s\n" " relay autoswitch stop" "stop and remove daemon"
1180
- printf " %-32s %s\n" " relay autoswitch status" "show daemon state + config"
1181
- printf " %-32s %s\n" " relay autoswitch log" "show recent switch history"
1182
- echo ""
1225
+ if [[ ! -f "${RELAY_DIR}/autoswitch.json" ]]; then
1226
+ cmd_autoswitch_config
1227
+ else
1228
+ cmd_autoswitch_status
1229
+ fi
1183
1230
  ;;
1184
1231
  esac
1185
1232
  }
@@ -1296,7 +1343,12 @@ PYEOF
1296
1343
  warn "Could not determine latest version — check your network"
1297
1344
  log "To update manually: ${CY}npm install -g @dst-justin/relay@latest${R}"
1298
1345
  return 1
1299
- elif [[ "${current}" == "${latest}" ]]; then
1346
+ fi
1347
+
1348
+ # Refresh cache with this live result so display commands reflect it immediately
1349
+ printf '%s:%s' "$(date +%s)" "${latest}" > "${UPDATE_CACHE}" 2>/dev/null || true
1350
+
1351
+ if [[ "${current}" == "${latest}" ]]; then
1300
1352
  ok "Already up to date (${current})"; return 0
1301
1353
  else
1302
1354
  log "Latest available: ${B}${latest}${R}"