Skip to content

Latest commit

 

History

27 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

binwrap

A binary-agnostic CLI wrapper that intercepts custom flags and translates them into real arguments, env vars, or pre/post hooks before delegating to the target binary.

Point it at any CLI tool and extend it without touching the tool's own source: add flags it doesn't support, rename or drop arguments, switch accounts or config directories, inject environment variables, or run setup/teardown logic around every invocation.

How it works

binwrap <binary> [args...]

binwrap reads its first argument as the target binary, then processes remaining args. For any --flag or --flag=value it finds a matching $BINWRAP_HOME/<binary>/<flag>.sh handler, it sources it; otherwise the flag is forwarded unchanged. Handlers can also descend into subcommand-specific directories, inject env vars via WRAPPED_BIN_ENV, and hook into enter.sh/exit.sh for logic that should run around every invocation regardless of which flags were passed.

Note: single-dash flags (-f, -v, etc.) are not intercepted and always forwarded as-is.

Setup

  1. Clone this repo somewhere permanent:

    git clone <repo> ~/.local/share/binwrap
  2. Add aliases to your ~/.zshrc or ~/.bashrc:

    alias claude='~/.local/share/binwrap/binwrap claude'
  3. Install extensions:

    bash ~/.local/share/binwrap/install.sh
  4. Reload your shell: source ~/.zshrc

Configuration

Variable Default Purpose
BINWRAP_HOME ~/.config/binwrap Root for all installed handlers and data

Handlers are looked up at $BINWRAP_HOME/<binary>/<flag>.sh. Data files (e.g. mode prompts) live alongside handlers under $BINWRAP_HOME/<binary>/.

Shipped extensions (claude)

The extensions in this repo are all written against the claude CLI, since that's the tool the author uses day to day, but nothing in binwrap itself is Claude-specific. Anything below can be ported to another binary by writing a new handler script.

--account <name>

Sets CLAUDE_CONFIG_DIR to a per-account config directory, creating it from a template on first use. Useful for keeping separate logins/configs (work, personal, client) without switching env vars by hand.

claude --account work

An enter.sh hook applies $CLAUDE_ACCOUNT as the default account automatically when --account isn't passed explicitly.

--provider <name>

Sources $BINWRAP_HOME/claude/provider/<name>.sh, which sets environment variables to point the CLI at a different backend (e.g. OpenRouter instead of the Anthropic API).

claude --provider openrouter

--as <persona> <task>

Builds a system prompt from two arguments.

claude --as "a senior engineer" "review this code for security issues"
# → --append-system-prompt "You are a senior engineer. Your task: review this code for security issues"

--using <file1> [file2] ...

Reads one or more files and concatenates their content into a system prompt. Consumes arguments until the next --flag.

claude --using context.md notes.md --model sonnet

--mode <name>

Loads $BINWRAP_HOME/claude/mode/<name>.md as a system prompt.

claude --mode human-style

--human-style

Alias: loads $BINWRAP_HOME/claude/mode/human-style.md as a system prompt. No argument consumed. Nudges commit messages and PR text away from typical LLM writing tells (em-dashes, "Let me...", hedging, filler openers) toward a plain, direct voice.

claude --human-style

--strip-attribution

Alias: loads $BINWRAP_HOME/claude/mode/strip-attribution.md as a system prompt. No argument consumed. Tells the model not to add AI attribution (tool/model names, "Generated by", Co-Authored-By trailers) to git output.

claude --strip-attribution

This is a separate flag from --human-style on purpose: one is a writing-style preference, the other suppresses disclosure signals, and they shouldn't be bundled as one default. Check your repo's or org's policy on AI-assistance disclosure before using it. If you only want to drop the Co-Authored-By trailer, Claude Code has a native setting for that which is a better fit than this prompt.

Adding your own extensions

  1. Create $BINWRAP_HOME/<binary>/<flag>.sh
  2. Implement the handler contract:
    • BINWRAP_HOME and BINWRAP_BINARY are available from the dispatcher
    • Consume positional args by reading $1 and calling shift
    • On success: append translated args to WRAPPED_BIN_ARGS, env vars to WRAPPED_BIN_ENV
    • On failure: set WRAPPER_ERROR="<message>" and return
    • Never call exit directly from a handler
  3. Optionally add enter.sh / exit.sh in the same directory for logic that should run before or after every invocation of that binary, independent of which flags were passed.
  4. Add tests in tests/test_<flag>.sh

Handler patterns

No-arg (alias): don't shift, just append to WRAPPED_BIN_ARGS.

Single-arg: read $1, shift once.

Fixed N-arg: read and shift N times, checking each $1 is not a --flag.

Variadic: loop while $# -gt 0 && "$1" != --*, shifting each iteration.

Running tests

bash tests/run_tests.sh

Origin

This project started with a leak: when Anthropic accidentally published the Claude Code source, people found a system prompt used internally, gated to Anthropic's own employees, that instructed the assistant to write git output like a human developer with no traces of AI authorship. Generalizing that into a portable, tool-agnostic prompt is what got this repo going, and it's why the shipped extensions are Claude Code-themed.

That original prompt mixed two different things: writing style, and suppressing AI-attribution signals. It's been split into --human-style and --strip-attribution for that reason. Anthropic has since shipped its own, cleaner setting for the attribution part specifically, so that half of the original prompt is mostly obsolete now; it stays here as an option, not a recommendation.

binwrap itself grew past that single use case quickly. The dispatcher and handler mechanism are a generic way to bolt behavior onto any CLI without patching it, and most of what's shipped now (account switching, provider switching, env injection, hooks) has nothing to do with the original prompt.

About

CLI wrapper that lets you intercept and translate flags before they reach the target binary

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages