seminar-vibecoding/code-proxy.sh
2026-08-06 23:08:41 +03:00

106 lines
3.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# Launch VS Code with all traffic proxied through a local HTTP bridge that
# itself forwards to your SOCKS5h tunnel (ssh -D). The bridge is auto-started
# before Code launches and auto-stopped when Code exits -- but only if this
# script started it (a bridge you started yourself is left running).
#
# tools/code --> http://127.0.0.1:18080 --> http2socks.py --> socks5h://127.0.0.1:12026 --> ssh -D
#
# Using the HTTP bridge (instead of pointing Chromium straight at SOCKS5)
# means anything that only understands HTTP proxies -- extensions,
# language servers, terminals, tasks -- also goes through the tunnel via
# the HTTP_PROXY/HTTPS_PROXY/ALL_PROXY env vars below.
#
# Usage:
# ./code-proxy.sh # open current dir in a new window
# ./code-proxy.sh /path/to/proj # open a specific folder
# ./code-proxy.sh --reuse-window # extra `code` flags pass through
#
# Env overrides:
# CODE_PROXY_BIND bridge listen addr (default 127.0.0.1)
# CODE_PROXY_PORT bridge listen port (default 18080)
# KEEP_BRIDGE=1 don't auto-stop a bridge this script started
# UPSTREAM socks5h://host:port (default socks5h://127.0.0.1:12026)
set -uo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BRIDGE="$HERE/http2socks.sh"
PIDFILE="$HERE/.http2socks.pid"
BIND="${CODE_PROXY_BIND:-127.0.0.1}"
PORT="${CODE_PROXY_PORT:-18080}"
PROXY="http://${BIND}:${PORT}"
BYPASS="localhost;127.0.0.1;[::1]"
BYPASS_ENV="localhost,127.0.0.1,::1"
# --- bridge lifecycle -------------------------------------------------------
bridge_running() {
[[ -f "$PIDFILE" ]] && kill -0 "$(cat "$PIDFILE" 2>/dev/null)" 2>/dev/null
}
started_bridge=0
ensure_bridge() {
if bridge_running; then
echo "bridge: already running (pid $(cat "$PIDFILE")) on $PROXY"
return 0
fi
if [[ ! -x "$BRIDGE" ]]; then
echo "bridge: $BRIDGE missing or not executable" >&2
exit 1
fi
export BIND="$BIND" PORT="$PORT"
if ! "$BRIDGE" start; then
echo "bridge: failed to start" >&2
exit 1
fi
started_bridge=1
}
stop_bridge() {
if [[ ${KEEP_BRIDGE:-0} -eq 1 ]]; then
echo "bridge: KEEP_BRIDGE=1, leaving it running"
return 0
fi
if bridge_running; then
"$BRIDGE" stop
fi
}
cleanup() {
if [[ $started_bridge -eq 1 ]]; then
stop_bridge
fi
}
trap cleanup EXIT INT TERM
# --- launch code ------------------------------------------------------------
# If an existing `code` instance is running, VS Code reuses it and silently
# ignores the proxy flags (and our exported env vars don't reach the already
# running process). Warn so you don't get a false sense of being proxied.
if pgrep -f '/lib/vscode/code' >/dev/null 2>&1; then
echo "warning: a VS Code instance is already running." >&2
echo " Proxy flags are ignored by reused windows -- fully quit it" >&2
echo " first for real end-to-end proxying." >&2
fi
ensure_bridge
export HTTP_PROXY="$PROXY"
export HTTPS_PROXY="$PROXY"
export ALL_PROXY="$PROXY"
export NO_PROXY="$BYPASS_ENV"
echo "code-proxy: proxy=$PROXY -> socks5h://127.0.0.1:12026 (bridge auto-stops on exit)"
# Run code as a foreground child (NOT exec) so our EXIT trap can fire and
# stop the bridge once VS Code quits.
#code --proxy-server="$PROXY" --proxy-bypass-list="$BYPASS" "$@"
$@
code_rc=$?
exit "$code_rc"