Custom wrapper for Claude Code CLI with identity management and 1Password secrets integration.
- Auto Remote Control: Every interactive session is automatically named and accessible from claude.ai/code and the Claude mobile app
- Git Identity Management: Separate git identity for Claude Code operations
- SSH Key Isolation: Dedicated SSH key for Claude git operations
- GitHub Token Management: Separate GitHub CLI token
- 1Password Integration: Secure secrets management with minimal TouchID prompts
- Multi-Level Secrets: Global, project, and local secrets support
- Debug Mode: Comprehensive logging for troubleshooting
- Graceful Degradation: Works with or without 1Password
- Modular Architecture: Clean separation of concerns for maintainability
-
Clone this repository:
git clone https://github.com/smartwatermelon/claude-wrapper.git ~/.claude-wrapper -
Symlink the wrapper to your local bin:
mkdir -p ~/.local/bin ln -sf ~/.claude-wrapper/bin/claude-wrapper ~/.local/bin/claude
-
Ensure
~/.local/binis in your PATH:echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc # or ~/.zshrc
-
Verify installation:
which claude # Should show ~/.local/bin/claude claude --version
The wrapper automatically sets up a dedicated git identity for Claude Code:
- Name:
Claude Code Bot - Email:
claude-code@smartwatermelon.github
Create a dedicated SSH key for Claude git operations:
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_claude_code -C "claude-code@smartwatermelon.github"
# Add to GitHub
cat ~/.ssh/id_ed25519_claude_code.pub
# Copy and add to https://github.com/settings/keysCreate a GitHub fine-grained PAT for Claude CLI operations:
# Create token at: https://github.com/settings/personal-access-tokens/new
# Required permissions: Contents (R/W), Pull requests (R/W), Actions (R)
# Save token (single account)
mkdir -p ~/.config/claude-code
echo "your_github_token_here" > ~/.config/claude-code/gh-token
chmod 600 ~/.config/claude-code/gh-tokenFine-grained PATs are scoped to a single owner (user or organization). To work with repos across multiple owners, create one token per owner:
# Personal repos (resource owner: your username)
echo "github_pat_personal..." > ~/.config/claude-code/gh-token.smartwatermelon
chmod 600 ~/.config/claude-code/gh-token.smartwatermelon
# Organization repos (resource owner: the org)
echo "github_pat_org..." > ~/.config/claude-code/gh-token.nightowlstudiollc
chmod 600 ~/.config/claude-code/gh-token.nightowlstudiollc
# Keep a default fallback (or copy one of the above)
cp ~/.config/claude-code/gh-token.smartwatermelon ~/.config/claude-code/gh-tokenThe wrapper detects the target repo owner from gh CLI arguments (e.g.,
--repo owner/repo, API paths like repos/owner/...) or the git remote of
the current directory, then loads the matching gh-token.<owner> file. If no
owner-specific file exists, it falls back to gh-token.
See SECRETS.md for comprehensive 1Password setup guide.
Quick setup:
# 1. Install 1Password CLI
brew install --cask 1password-cli
# 2. Enable app integration in 1Password settings
# 3. Create secrets file
mkdir -p ~/.config/claude-code
cat > ~/.config/claude-code/secrets.op <<EOF
ANTHROPIC_API_KEY=op://Personal/Claude-API/credential
GITHUB_TOKEN=op://Personal/GitHub/token
EOFUse claude command as normal:
# Normal usage — automatically starts a named remote session
claude
# With debug output
CLAUDE_DEBUG=true claude
# Pass arguments
claude -c "your command here"
claude --version
# Opt out of remote control for one session
CLAUDE_NO_REMOTE_CONTROL=true claude
# Already has --remote-control? Wrapper skips injection
claude --remote-control "Custom Name"The wrapper:
- Sets git identity
- Authenticates with 1Password (once per session)
- Loads secrets from multi-level files
- Injects
--remote-control <session-name>for interactive sessions - Passes through to real Claude CLI
Every interactive claude invocation automatically registers a remote session named after the current git repository (or directory when outside a git repo). This lets you pick up any session from claude.ai/code or the Claude mobile app.
~/Developer/my-app $ claude
# → equivalent to: claude --remote-control "my-app"
Session naming priority (per Claude docs):
- Name injected by the wrapper (repo or directory name)
/renameinside the session- Last meaningful message in conversation history
- Your first prompt
Opt-out options:
| Method | Scope |
|---|---|
CLAUDE_NO_REMOTE_CONTROL=true claude |
Single session |
export CLAUDE_NO_REMOTE_CONTROL=true |
Shell session |
/config → "Enable Remote Control for all sessions" → false |
Persisted in Claude config |
Remote control is skipped automatically for non-interactive invocations: --print/-p, --version, --help, subcommands (remote-control, mcp, etc.), and script automation (--no-session-persistence).
Requirements: Claude Code v2.1.51+, claude.ai authentication (not API key), Pro/Max/Team/Enterprise plan.
-
SECRETS.md: Comprehensive 1Password integration guide
- Setup and configuration
- Secret reference syntax
- Multi-level secrets
- Team workflows
- Troubleshooting
-
SECURITY.md: Security hardening documentation
- Permission validation
- Path security
- Binary validation
-
tests/README.md: Test suite documentation
- Running tests
- Manual testing scenarios
- Adding new tests
# Run all automated tests
./tests/test-wrapper.sh
./tests/test-remote-session.sh
# Run with verbose output
VERBOSE=true ./tests/test-wrapper.shclaude-wrapper/
├── bin/
│ └── claude-wrapper # Main entry point (orchestrates modules)
├── lib/
│ ├── logging.sh # Debug/error/warning logging
│ ├── permissions.sh # File permission validation
│ ├── path-security.sh # Path canonicalization and traversal protection
│ ├── git-identity.sh # Git author/committer identity
│ ├── github-token.sh # GitHub CLI token loading + multi-org routing setup
│ ├── gh-token-router.sh # Per-invocation token selection (sourced by gh wrapper)
│ ├── secrets-loader.sh # 1Password integration
│ ├── binary-discovery.sh # Claude binary search/validation
│ ├── pre-launch.sh # Project-specific pre-launch hooks
│ └── remote-session.sh # Automatic remote control session naming
├── docs/
│ ├── SECRETS.md # 1Password documentation
│ └── SECURITY.md # Security hardening documentation
├── tests/
│ ├── test-wrapper.sh # Test suite
│ ├── test-remote-session.sh # Remote session module tests
│ └── README.md # Test documentation
├── .claude/ # Project-specific Claude config
├── .gitignore
└── README.md # This file
This is security-critical infrastructure code. All changes require:
- ShellCheck compliance: Zero warnings or errors
- Test coverage: All new features must have tests
- Code review: AI-assisted review before commit
- Security review: Adversarial review for security changes
# Run ShellCheck on all modules
shellcheck bin/claude-wrapper lib/*.sh
# Run tests
./tests/test-wrapper.sh
# Run code review (requires Claude Code)
claude --agent code-reviewer bin/claude-wrapper lib/- Claude CLI process: Yes
- Git hooks: Yes (subprocesses inherit environment)
- Spawned agents: Yes (subprocesses inherit environment)
- Other terminal windows: No
- After Claude exits: No (environment cleared)
- 1Password vault: ✓ Encrypted, secure
- secrets.op files: ✓ Only references, not actual secrets
- Process environment: ✓ Temporary, cleared on exit
- Shell history: ✓ Not stored (not exported to shell)
- Never commit
.claude/secrets.local.op - Use separate vaults for different security levels
- Review secrets file permissions:
chmod 600 ~/.config/claude-code/secrets.op - Use service accounts for CI/CD
- Enable TouchID for 1Password app
# Verify Claude Code version (requires v2.1.51+)
claude --version
# Check you're using claude.ai auth (not API key)
# API keys do not support Remote Control
# Disable and re-enable for one session
CLAUDE_NO_REMOTE_CONTROL=true claude
# Debug injection
CLAUDE_DEBUG=true claude --version 2>&1 | grep -i remoteIf you're on a Team or Enterprise plan, an admin must enable the Remote Control toggle in Claude Code admin settings.
# Check symlink
ls -la ~/.local/bin/claude
# Verify PATH
echo $PATH | grep -o "\.local/bin"
# Recreate symlink
ln -sf ~/.claude-wrapper/bin/claude-wrapper ~/.local/bin/claude# Check git log shows bot identity
git log -1 --format='%an <%ae>'
# Should show: Claude Code Bot <claude-code@smartwatermelon.github>
# Debug wrapper
CLAUDE_DEBUG=true claude -c "git log -1"# Verify app integration
op account get
# Check 1Password app settings:
# - Settings → Security → Touch ID: ON
# - Settings → Developer → Integrate with CLI: ON# Enable debug mode
CLAUDE_DEBUG=true claude -c "printenv | grep API_KEY"
# Verify secret reference
op read "op://Personal/Claude-API/credential"
# Check secrets files exist
ls -la ~/.config/claude-code/secrets.opSee SECRETS.md for comprehensive troubleshooting.
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests:
./tests/test-wrapper.sh - Run ShellCheck:
shellcheck bin/claude-wrapper lib/*.sh - Submit a pull request
MIT License - see LICENSE file for details
- Claude Code - Official Claude Code CLI
- 1Password CLI - 1Password command-line tool
- GitHub CLI - GitHub command-line tool
- Auto Remote Control: Every interactive
claudeinvocation now automatically registers a named remote session- Session named after the git repository root (or current directory outside a repo)
- Skipped automatically for non-interactive uses (
--print,--version, subcommands,--no-session-persistence) - Opt-out via
CLAUDE_NO_REMOTE_CONTROL=true
- New module:
lib/remote-session.sh - New test suite:
tests/test-remote-session.sh(22 tests)
- Renamed from
claude-customtoclaude-wrapper - Modularized architecture: split into 8 focused modules in
lib/ - Each module is independently testable
- Improved test suite with TDD approach
- Full ShellCheck compliance across all modules
- Added 1Password secrets integration
- Multi-level secrets support (global, project, local)
- Enhanced error handling
- Debug mode
- Comprehensive test suite
- Full documentation
- Git identity management
- SSH key isolation
- GitHub token support
- Binary discovery logic