{"id":49293493,"url":"https://github.com/diranged/claude-profile","last_synced_at":"2026-04-26T02:02:38.598Z","repository":{"id":349074936,"uuid":"1200796167","full_name":"diranged/claude-profile","owner":"diranged","description":"Run Claude Code ... But with Profiles!","archived":false,"fork":false,"pushed_at":"2026-04-13T09:33:21.000Z","size":2214,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-13T11:28:42.224Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/diranged.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"docs/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-03T20:50:58.000Z","updated_at":"2026-04-13T09:33:25.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/diranged/claude-profile","commit_stats":null,"previous_names":["diranged/claude-profile"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/diranged/claude-profile","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diranged%2Fclaude-profile","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diranged%2Fclaude-profile/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diranged%2Fclaude-profile/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diranged%2Fclaude-profile/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/diranged","download_url":"https://codeload.github.com/diranged/claude-profile/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diranged%2Fclaude-profile/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32283294,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-25T18:29:39.964Z","status":"online","status_checked_at":"2026-04-26T02:00:05.962Z","response_time":129,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-26T02:02:38.061Z","updated_at":"2026-04-26T02:02:38.592Z","avatar_url":"https://github.com/diranged.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Claude Profile\n\n**Claude Code... but with Profiles.**\n\nA transparent wrapper around [Claude Code](https://docs.anthropic.com/en/docs/claude-code) that enables multiple subscription profiles. Each profile gets its own isolated config directory and macOS keychain entry, allowing concurrent sessions across different Claude subscriptions (e.g., work and personal).\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/demo.gif\" alt=\"Claude Profile Demo\" width=\"800\"\u003e\n\u003c/p\u003e\n\n## How It Works\n\nClaude Profile leverages Claude Code's built-in `CLAUDE_CONFIG_DIR` environment variable. When set, Claude Code automatically hashes the directory path (SHA-256) into its macOS keychain service name, producing a unique credential store per profile. No patching or hacking required -- it uses official, documented behavior.\n\n```\nDefault keychain entry:       \"Claude Code-credentials\"\nProfile keychain entry:       \"Claude Code-credentials-\u003csha256[:8]\u003e\"\n```\n\nEach profile is a directory under `~/.claude-profiles/\u003cname\u003e/` containing:\n- `config/` -- used as `CLAUDE_CONFIG_DIR` (Claude's settings, credentials, sessions)\n- `claude-profile.yaml` -- profile-specific metadata (color code)\n\n## Installation\n\n### Quick Install (Recommended)\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/diranged/claude-profile/main/install.sh | sh\n```\n\nThis detects your OS and architecture, downloads the latest release, verifies the SHA-256 checksum, and installs to `/usr/local/bin`.\n\nTo install a specific version or to a custom directory:\n\n```bash\n# Pin a version\ncurl -fsSL https://raw.githubusercontent.com/diranged/claude-profile/main/install.sh | VERSION=v0.1.0 sh\n\n# Custom install directory\ncurl -fsSL https://raw.githubusercontent.com/diranged/claude-profile/main/install.sh | INSTALL_DIR=~/.local/bin sh\n```\n\n### From GitHub Releases\n\nDownload a prebuilt binary from the [Releases](https://github.com/diranged/claude-profile/releases) page. Binaries are available for Linux, macOS, and Windows on both amd64 and arm64.\n\n### From Source\n\nRequires Go 1.25+:\n\n```bash\ngit clone https://github.com/diranged/claude-profile.git\ncd claude-profile\nmake install    # Builds and copies to $GOPATH/bin\n```\n\n### From Go\n\n```bash\ngo install github.com/diranged/claude-profile-go/cmd/main.go@latest\n```\n\n## Quick Start\n\n1. **Create a profile:**\n\n   ```bash\n   claude-profile create work\n   ```\n\n   The interactive wizard will:\n   - Create the isolated config directory\n   - Offer to copy your existing `~/.claude` config files (CLAUDE.md, settings.json)\n   - Let you pick a banner/statusline color\n   - Configure the Claude Code statusline automatically\n\n2. **Authenticate:**\n\n   ```bash\n   # OAuth (interactive)\n   claude-profile -P work auth login\n\n   # SSO\n   claude-profile -P work auth login --sso\n\n   # Or launch Claude and use /login inside the REPL\n   claude-profile -P work\n   ```\n\n3. **Use it as a drop-in replacement for `claude`:**\n\n   ```bash\n   claude-profile -P work\n   claude-profile -P work \"explain this code\"\n   claude-profile -P personal --model opus\n   ```\n\n4. **Use an environment variable instead of `-p`:**\n\n   ```bash\n   export CLAUDE_PROFILE=work\n   claude-profile \"explain this code\"\n   ```\n\n## Shell Aliases\n\nOnce your profiles are set up, shell aliases make switching effortless. Add these to your `~/.zshrc` or `~/.bashrc`:\n\n```bash\n# Personal Claude — just type \"myclaude\"\nalias myclaude='claude-profile -P personal'\n\n# Work Claude with a shared project config directory\nalias workclaude='claude-profile -P work --add-dir ~/git/work/common-claude'\n\n# Quick one-shot questions against different profiles\nalias askwork='claude-profile -P work -p'\nalias askpersonal='claude-profile -P personal -p'\n```\n\nYou can pass any Claude flags through — the alias is just a shortcut for the profile selection:\n\n```bash\nmyclaude                                 # Interactive REPL\nmyclaude \"explain this function\"         # One-shot question\nworkclaude --model opus -c \"run tests\"   # Specific model + command\nworkclaude auth login --sso              # Re-authenticate\n```\n\nThis pairs well with `CLAUDE_PROFILE` for scripts:\n\n```bash\n# In a work-specific script or .envrc:\nexport CLAUDE_PROFILE=work\nclaude-profile \"summarize the recent changes\"\n```\n\n## Command Reference\n\n### `claude-profile create \u003cprofile\u003e`\n\nInteractive wizard that creates a new profile. Steps through config bootstrapping, color selection, and statusline setup.\n\n```bash\nclaude-profile create work\nclaude-profile create personal\n```\n\n### `claude-profile list`\n\nLists all profiles with their authentication status.\n\n```bash\n$ claude-profile list\n  work                 (keychain)\n  personal             (file)\n  experiment           (none)\n```\n\nAuth status is one of:\n- **keychain** -- OAuth credentials stored in macOS Keychain\n- **file** -- credentials stored in `.credentials.json` (plaintext fallback)\n- **none** -- no credentials found\n\n### `claude-profile show \u003cprofile\u003e`\n\nDisplays detailed information about a profile.\n\n```bash\n$ claude-profile show work\nProfile:          work\nConfig dir:       /Users/you/.claude-profiles/work/config\nKeychain service: Claude Code-credentials-6061db4b\nAuth:             keychain\nSubscription:     pro\nRate limit tier:  t3\nExpires:          2025-01-15T12:00:00Z\nScopes:           user:inference, user:read\n```\n\n### `claude-profile delete \u003cprofile\u003e`\n\nRemoves a profile's directory and its macOS keychain entry. Prompts for confirmation by default.\n\n```bash\nclaude-profile delete old-profile\nclaude-profile delete old-profile --force   # Skip confirmation\n```\n\n### `claude-profile sessions`\n\nLists all Claude Code sessions across every repository, grouped by directory. This solves a common pain point: when you work across many repos and create sessions frequently, it's hard to remember which repo a particular session lives in.\n\n```bash\n# List sessions from the last 7 days (default)\n$ claude-profile -P me sessions\n\n SESSIONS (21 sessions across 8 repos)\n\n=== /Users/you/git/myorg/api-service ===\n  abc12345  2026-04-15 14:30  [main]          fix the flaky integration test in auth middleware\n  def67890  2026-04-14 09:15  [feature/oauth] add OAuth2 PKCE flow to the login endpoint\n\n=== /Users/you/git/myorg/frontend ===\n  11122233  2026-04-15 11:00  [main]          why is the bundle size 2MB larger after the last merge?\n\n=== /Users/you/git/personal/blog ===\n  44455566  2026-04-13 20:45  [main]          write a post about Claude Code profiles\n```\n\n**Flags:**\n\n| Flag | Default | Description |\n|---|---|---|\n| `--since` | `7d` | Time window — supports `Nd` (days), `Nh` (hours), `Nm` (minutes) |\n| `--repo` | | Case-insensitive substring filter on the repo path |\n\n```bash\n# Last 30 days\nclaude-profile -P me sessions --since 30d\n\n# Only sessions in repos matching \"sproutbook\"\nclaude-profile -P me sessions --repo sproutbook\n\n# Combine filters\nclaude-profile -P me sessions --since 14d --repo api\n```\n\nEach line shows:\n- **Session ID** (first 8 characters) — use this with `--resume`\n- **Last modified timestamp**\n- **Git branch** at the time the session was created\n- **First prompt** — truncated to help you identify the session's purpose\n\n### `--resume` Directory Safety Check\n\nWhen you resume a session with `claude-profile -P \u003cprofile\u003e --resume \u003cid\u003e`, claude-profile verifies that your current working directory matches where the session was originally started. This prevents the common mistake of resuming a session from the wrong repo, which leads to Claude operating on the wrong codebase with stale context.\n\n**Wrong directory — you get a helpful error:**\n\n```\n$ pwd\n/Users/you/git/myorg/frontend\n$ claude-profile -P me --resume abc12345\n\n✗ Session abc12345 was started in a different directory.\n\n  Session cwd:  /Users/you/git/myorg/api-service\n  Current cwd:  /Users/you/git/myorg/frontend\n  Branch:       main\n  First prompt: fix the flaky integration test in auth middleware\n\n  To resume, cd to the correct directory:\n    cd /Users/you/git/myorg/api-service \u0026\u0026 claude-profile -P me --resume abc12345\n```\n\n**Right directory — passes through to Claude normally:**\n\n```\n$ cd /Users/you/git/myorg/api-service\n$ claude-profile -P me --resume abc12345\n╭── Claude Profile v0.2.0 ──────────────────╮\n│ Profile:      me                          │\n│ ...                                       │\n╰───────────────────────────────────────────╯\n```\n\n**Ambiguous session ID prefix:**\n\n```\n$ claude-profile -P me --resume abc\n✗ Session prefix \"abc\" matches multiple sessions:\n  abc12345  /Users/you/git/myorg/api-service   main  2026-04-15 14:30\n  abc99999  /Users/you/git/personal/blog       main  2026-04-13 20:45\n```\n\n**Bare `--resume` (no ID):**\n\nWhen you pass `--resume` without a session ID, Claude Code shows its built-in session picker for the current directory. This passes through untouched.\n\n#### Typical Workflow\n\n1. **Find your session** — you remember working on something but not which repo:\n   ```bash\n   claude-profile -P me sessions --repo api\n   ```\n\n2. **Spot the session** — `abc12345` with prompt \"fix the flaky integration test\"\n\n3. **Resume it** — claude-profile tells you if you need to `cd` first:\n   ```bash\n   claude-profile -P me --resume abc12345\n   ```\n\n### Passthrough Mode (Default)\n\nWhen no subcommand matches, all arguments are forwarded to the real `claude` binary. This is the primary usage mode -- claude-profile acts as a transparent wrapper.\n\n```bash\n# These all pass through to claude:\nclaude-profile -P work\nclaude-profile -P work \"explain this function\"\nclaude-profile -P work --model opus -c \"run tests\"\nclaude-profile -P work auth login\nclaude-profile -P work auth login --sso\n```\n\nThe `-p`/`--profile` flag (and `--profile=value` / `-pvalue` forms) is stripped before forwarding. All other flags and arguments pass through untouched. Claude Profile acts as a transparent wrapper.\n\n### `claude-profile statusline [-- command args...]`\n\nActs as a Claude Code statusline provider. Prints a colored line showing the active profile name, auth method, and subscription type. Optionally chains to another statusline command.\n\n```bash\n# Standalone\nclaude-profile statusline\n\n# Chaining with another statusline tool\nclaude-profile statusline -- bunx -y ccstatusline@latest\n```\n\nThis is configured automatically by the `create` wizard in the profile's `settings.json`:\n\n```json\n{\n  \"statusLine\": {\n    \"type\": \"command\",\n    \"command\": \"/path/to/claude-profile statusline\",\n    \"padding\": 0\n  }\n}\n```\n\nIf an existing statusline command is detected during creation, it is preserved by chaining:\n\n```json\n{\n  \"statusLine\": {\n    \"type\": \"command\",\n    \"command\": \"/path/to/claude-profile statusline -- bunx -y ccstatusline@latest\",\n    \"padding\": 0\n  }\n}\n```\n\n## Credential Isolation\n\nProfile isolation relies on Claude Code's own keychain hashing behavior:\n\n1. claude-profile sets `CLAUDE_CONFIG_DIR` to `~/.claude-profiles/\u003cname\u003e/config`\n2. Claude Code computes `SHA-256(CLAUDE_CONFIG_DIR)` and takes the first 8 hex characters\n3. The keychain service name becomes `Claude Code-credentials-\u003chash\u003e`\n4. Each profile gets a completely independent credential store\n\nThis matches Claude Code's internal `V51()` function. The hash is deterministic -- the same config directory always produces the same keychain entry.\n\n**Example:**\n\n```\nConfig dir:  /Users/you/.claude-profiles/work/config\nSHA-256:     6061db4b...\nKeychain:    Claude Code-credentials-6061db4b\n```\n\n## Statusline Integration\n\nThe statusline command reads profile info from environment variables set at launch time:\n\n| Variable | Description |\n|---|---|\n| `CLAUDE_PROFILE_NAME` | Active profile name |\n| `CLAUDE_PROFILE_AUTH` | Auth status (keychain/file/none) |\n| `CLAUDE_PROFILE_SUB` | Subscription type (pro/max/free/unknown) |\n| `CLAUDE_PROFILE_COLOR` | ANSI 256-color code for the profile |\n\nThese are injected into the Claude process environment by the passthrough handler, making them available to the statusline command when Claude Code invokes it.\n\n## Color Customization\n\nEach profile has an ANSI 256-color code used for the launch banner and statusline text. The `create` wizard offers these presets:\n\n| Color | Name | Code |\n|---|---|---|\n| ![#87af87](https://img.shields.io/badge/●-87af87?style=flat-square\u0026labelColor=87af87\u0026color=87af87) | Green (default) | 108 |\n| ![#0066ff](https://img.shields.io/badge/●-0066ff?style=flat-square\u0026labelColor=0066ff\u0026color=0066ff) | Blue | 33 |\n| ![#ff8700](https://img.shields.io/badge/●-ff8700?style=flat-square\u0026labelColor=ff8700\u0026color=ff8700) | Orange | 208 |\n| ![#ff5f87](https://img.shields.io/badge/●-ff5f87?style=flat-square\u0026labelColor=ff5f87\u0026color=ff5f87) | Pink | 204 |\n| ![#00ffff](https://img.shields.io/badge/●-00ffff?style=flat-square\u0026labelColor=00ffff\u0026color=00ffff) | Cyan | 51 |\n| ![#ff0000](https://img.shields.io/badge/●-ff0000?style=flat-square\u0026labelColor=ff0000\u0026color=ff0000) | Red | 196 |\n| ![#af87ff](https://img.shields.io/badge/●-af87ff?style=flat-square\u0026labelColor=af87ff\u0026color=af87ff) | Purple | 141 |\n| ![#ffff00](https://img.shields.io/badge/●-ffff00?style=flat-square\u0026labelColor=ffff00\u0026color=ffff00) | Yellow | 226 |\n| | Custom | 0-255 |\n\nThe color is stored in `claude-profile.yaml` inside the profile directory and can be edited directly:\n\n```yaml\ncolor: 204\n```\n\n## Authentication Methods\n\nClaude Profile does not handle authentication itself. It sets up the isolated environment and then delegates to Claude Code's built-in auth mechanisms.\n\n### OAuth (Claude Subscription)\n\n```bash\nclaude-profile -P work auth login\n# Or inside Claude's REPL: /login\n```\n\nCredentials are stored in the macOS Keychain under a profile-specific service name.\n\n### SSO (Enterprise)\n\n```bash\nclaude-profile -P work auth login --sso\n```\n\n### API Key\n\n```bash\nANTHROPIC_API_KEY=sk-ant-... claude-profile -P work\n```\n\nNo keychain entry is created. The API key is passed through the environment.\n\n### AWS Bedrock\n\n```bash\nCLAUDE_CODE_USE_BEDROCK=1 claude-profile -P work\n```\n\nCredentials come from AWS environment variables or IAM roles. Claude Profile detects this and skips the keychain credential check.\n\n### Google Vertex AI\n\n```bash\nCLAUDE_CODE_USE_VERTEX=1 claude-profile -P work\n```\n\nCredentials come from GCP environment. Claude Profile detects this and skips the keychain credential check.\n\n## Environment Variables Reference\n\n| Variable | Description |\n|---|---|\n| `CLAUDE_PROFILE` | Default profile name (alternative to `-p` flag) |\n| `CLAUDE_PROFILES_DIR` | Override profiles base directory (default: `~/.claude-profiles`) |\n| `CLAUDE_PROFILE_DEBUG` | Enable debug logging (set to any non-empty value) |\n| `CLAUDE_CONFIG_DIR` | Set automatically by claude-profile per-profile |\n| `CLAUDE_CODE_USE_BEDROCK` | Signals Bedrock auth; skips keychain check |\n| `CLAUDE_CODE_USE_VERTEX` | Signals Vertex auth; skips keychain check |\n| `ANTHROPIC_API_KEY` | Direct API key auth; skips keychain check |\n| `CLAUDE_PROFILE_NAME` | Set in Claude's env for statusline use |\n| `CLAUDE_PROFILE_AUTH` | Set in Claude's env for statusline use |\n| `CLAUDE_PROFILE_SUB` | Set in Claude's env for statusline use |\n| `CLAUDE_PROFILE_COLOR` | Set in Claude's env for statusline use |\n\n## License\n\nSee [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdiranged%2Fclaude-profile","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdiranged%2Fclaude-profile","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdiranged%2Fclaude-profile/lists"}