Created
February 12, 2026 14:07
-
-
Save bkaney/4b9e7ef9816f168eac064512fa3e1f49 to your computer and use it in GitHub Desktop.
Helper script for consultants or anyone juggling multiple client projects who wants to launch VS Code with a client-specific profile—keeping settings, Copilot access, and AI subscriptions cleanly isolated.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| set -euo pipefail | |
| # code-client: launch VS Code with per-client user-data-dir based on | |
| # ~/projects/{client}/{project} hierarchy. | |
| PROJECTS_ROOT="${PROJECTS_ROOT:-$HOME/projects}" | |
| CODE_BIN="${CODE_BIN:-code}" | |
| usage() { | |
| cat <<'EOF' | |
| Usage: | |
| code-client [path] [--no-isolation] [--client NAME] [--project-root] | |
| Examples: | |
| cd ~/projects/acme/app1 && code-client | |
| code-client ~/projects/acme/app1 | |
| code-client --no-isolation . | |
| code-client --client acme ~/projects/acme/app2 | |
| Env: | |
| PROJECTS_ROOT defaults to ~/projects | |
| CODE_BIN defaults to "code" | |
| EOF | |
| } | |
| NO_ISOLATION=0 | |
| FORCE_CLIENT="" | |
| OPEN_PROJECT_ROOT=0 | |
| ARGS=() | |
| while [[ $# -gt 0 ]]; do | |
| case "$1" in | |
| -h|--help) usage; exit 0 ;; | |
| --no-isolation) NO_ISOLATION=1; shift ;; | |
| --client) FORCE_CLIENT="${2:-}"; shift 2 ;; | |
| --project-root) OPEN_PROJECT_ROOT=1; shift ;; | |
| --) shift; ARGS+=("$@"); break ;; | |
| *) ARGS+=("$1"); shift ;; | |
| esac | |
| done | |
| TARGET_PATH="${ARGS[0]:-.}" | |
| TARGET_PATH="$(cd "$TARGET_PATH" 2>/dev/null && pwd || true)" | |
| if [[ -z "$TARGET_PATH" ]]; then | |
| echo "Could not resolve path: ${ARGS[0]:-.}" >&2 | |
| exit 2 | |
| fi | |
| if [[ "$NO_ISOLATION" -eq 1 ]]; then | |
| exec "$CODE_BIN" "$TARGET_PATH" | |
| fi | |
| # Normalize root for matching | |
| PROJECTS_ROOT="$(cd "$PROJECTS_ROOT" && pwd)" | |
| # Determine client/project from path | |
| # Expected: $PROJECTS_ROOT/<client>/<project>/... | |
| rel="${TARGET_PATH#"$PROJECTS_ROOT"/}" | |
| client="" | |
| project="" | |
| if [[ "$TARGET_PATH" == "$PROJECTS_ROOT"* && "$rel" != "$TARGET_PATH" ]]; then | |
| client="$(cut -d'/' -f1 <<<"$rel")" | |
| project="$(cut -d'/' -f2 <<<"$rel")" | |
| fi | |
| if [[ -n "$FORCE_CLIENT" ]]; then | |
| client="$FORCE_CLIENT" | |
| # If forcing client, open whatever target path user gave (unless --project-root) | |
| fi | |
| # If we can't determine a client, just open normally. | |
| if [[ -z "$client" || "$client" == "." || "$client" == ".." ]]; then | |
| exec "$CODE_BIN" "$TARGET_PATH" | |
| fi | |
| CLIENT_DIR="$PROJECTS_ROOT/$client" | |
| USER_DATA_DIR="$CLIENT_DIR/.vscode-user-data" | |
| mkdir -p "$USER_DATA_DIR" | |
| OPEN_PATH="$TARGET_PATH" | |
| if [[ "$OPEN_PROJECT_ROOT" -eq 1 && -n "$project" && "$project" != "$client" ]]; then | |
| OPEN_PATH="$PROJECTS_ROOT/$client/$project" | |
| else | |
| # If inside a client tree and we detected a project, default to project root. | |
| if [[ -n "$project" && "$project" != "$client" ]]; then | |
| OPEN_PATH="$PROJECTS_ROOT/$client/$project" | |
| fi | |
| fi | |
| exec "$CODE_BIN" --user-data-dir="$USER_DATA_DIR" "$OPEN_PATH" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment