Add shim command for transparent claude→proxy routing#10
Open
teocns wants to merge 1 commit into
Open
Conversation
Drops a tiny bash wrapper at $XDG_DATA_HOME/teamclaude-shim/claude and prepends that directory to the user's shell PATH. Plain `claude` invocations then probe the proxy port; if it's up, the shim applies `teamclaude env` and execs the real claude, otherwise it execs the real claude directly. The shim lives in its own directory, separate from where Claude Code's auto-updater rewrites its binary, so it survives self-updates indefinitely (same trick rbenv/asdf/mise use). Surface: teamclaude shim install [--no-rc] [--shim-dir PATH] teamclaude shim uninstall teamclaude shim status Zero new dependencies. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a
teamclaude shimsubcommand that drops a tiny bash wrapper at$XDG_DATA_HOME/teamclaude-shim/claudeand wires it onto every shell'sPATHvia the rustup-style env-file pattern. Plainclaudeinvocations then probe the proxy port locally — applyingteamclaude envand exec'ing the realclaudeif the proxy is up, or exec'ing the realclaudedirectly if it isn't.The shim lives in its own directory, separate from where Claude Code's auto-updater rewrites its binary, so it survives
claudeself-updates indefinitely (same trickrbenv,asdf, andmiseuse to survive language-version updates).Why
teamclaude runcovers ad-hoc invocations, but anyone who typesclaudedirectly — from a shell, an editor, a script, a hotkey — bypasses the proxy. A naive shadow-symlink in the same dir asclaudeworks for a day, then gets clobbered the next time Claude Code self-updates. The PATH-prepended shim dir avoids that collision class entirely.Surface
Shell coverage
Modeled on
~/.cargo/env(the rustup install pattern). Three files written under the shim dir:claude— the wrapper (executable)env— POSIX sh loader, idempotent at source-time viacase ":${PATH}:" in *:"...":*) ;;env.fish— fish loader usingfish_add_path-style logicThen a single
. "<shim-dir>/env"line is appended to each rc:~/.bashrcAND~/.bash_profile(covers macOS Terminal's login-shell precedence)~/.zshrc~/.profile~/.config/fish/conf.d/teamclaude-shim.fish(auto-loaded; no rc edit)The loaders are idempotent at source time (PATH dedup via case statement /
not contains) so re-sourcing is safe across shell reloads. Uninstall surgically strips the comment + source line from each rc and removes all written files.Implementation notes
src/shim.jsuses onlynode:fs,node:path,node:os. The bash wrapper and shell loaders are embedded as template literals and written at install time — no shell scripts in the repo, consistent with the existing pure-Node layout.case 'shim'to the switch insrc/index.js. NewshimCommand()parsesinstall/uninstall/statusand forwards flags. Help text and README updated to match existing CLI vocabulary.$SHELL(avoids creating.bashrcon a zsh-only machine).$HOMEportability. When the shim dir lives under$HOME, env files reference it as$HOME/...(rustup convention) for portability across machines on shared/network homes.PATH, skipping any entry whose realpath matches itself — works regardless of where Claude Code installs (npm, homebrew, native installer).Tested
node --checkon both modified files; existingeslintclean (no new warnings).$HOMEpopulated with pre-existing rc content — original content preserved verbatim, no duplicate source lines on re-install, full cleanup on uninstall.envfrom bash exportsPATHcorrectly; sourcing it twice does not duplicate the entry (case-statement idempotence works).:3456, eval'steamclaude env, exec's realclaude --versionsuccessfully through the proxy.claude --versiondirectly with a clean env.