profilehop
v0.1.0
Published
Switch accounts across AI coding agents with isolated local profiles.
Maintainers
Readme
Profile Hop
Switch accounts across AI coding agents.
One lightweight command for named accounts, reauthentication, and local usage. Zero runtime dependencies. Credentials stay on your machine and login is handled by the installed agent.
Early release: all adapters have automated invocation tests; live authentication coverage varies. See release validation before relying on an adapter on a new platform.
profilehop add codex work
profilehop add codex personal
profilehop add claude work
profilehop use work
profilehop codex
profilehop claude
profilehop usageuse work selects your work account for every agent with that label. use codex personal changes only Codex. Launch a specific account with profilehop codex personal, or run profilehop for a numbered picker.
Install
Requires Node.js 22+ and the agents you want to use installed separately. This repository is the source distribution; an npm release has not yet been published.
git clone https://github.com/ChaseBurr/ProfileHop.git
cd ProfileHop
npm install --ignore-scripts
npm test
npm install -g . --ignore-scripts
profilehop helpTo try it without global installation, use node bin/profilehop.js help from this checkout. Both the npm package and terminal command are profilehop. After the first npm release, install it with npm install -g profilehop.
Upgrading from CLIhop
From your existing checkout, run npm install -g . --ignore-scripts to register the new profilehop command. Existing ~/.clihop profiles are reused in place, preserving credentials, profile paths, and locks. CLIHOP_HOME and CLIHOP_NO_UPDATE_CHECK=1 remain supported; prefer PROFILEHOP_HOME and PROFILEHOP_NO_UPDATE_CHECK for new setups. If both home variables are set, PROFILEHOP_HOME takes precedence. Update shell completions with profilehop completion bash|zsh|fish for your shell.
Updates and publishing
profilehop update --check # Check npm now without installing
profilehop update # Install the latest stable npm releaseProfile Hop checks its version cache on startup and contacts npm at most once per hour, with an 800 ms timeout. If a newer release exists, it prints a message to run profilehop update. Notices use stderr, keeping JSON stdout clean. Nothing is installed automatically. --local stays offline and only consults existing cache data. Set PROFILEHOP_NO_UPDATE_CHECK=1 to disable automatic checks and notices; CI disables them too.
The updater supports the active global npm installation, installs the exact new version with scripts disabled, and preserves account profiles. Updating a global link from npm install -g . replaces that link with the npm release while preserving the checkout. Other installation methods must use their original package manager. Updates become available when a new version is published to npm, not when a commit is pushed. See the publishing and update guide for your first release and subsequent versions.
Supported agents
| Agent | Command | Account mechanism | Usage reporting |
| ------------------ | --------------------- | --------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| Codex | profilehop codex | Separate profile, official login | usage codex fetches account token activity and current limits; --local reads session tokens |
| Claude Code | profilehop claude | Separate profile, official login | Local token records |
| Gemini CLI | profilehop gemini | Separate profile, interactive /auth | Local token records |
| OpenCode | profilehop opencode | Separate XDG directories, official login | usage delegates to opencode stats |
| Pi | profilehop pi | Separate profile, interactive /login | Local token records |
| Cline CLI | profilehop cline | Separate data directory, cline auth | Unavailable in this release |
| Goose | profilehop goose | Separate config/data/state, goose configure | Unavailable in this release |
| GitHub Copilot CLI | profilehop copilot | Explicit token environment reference | Unavailable; use native /usage |
| Cursor CLI | profilehop cursor | Explicit API-key environment reference | Unavailable; use provider dashboard |
| Aider | profilehop aider | Explicit API-key environment reference | Unavailable; see agent session output |
Adapter support is based on current primary documentation, with contract tests using fake agents. Real browser-login testing requires your accounts. See the research and compatibility notes for sources, platform limitations, and agents not yet enabled. “Across agents” does not mean every agent or authentication method is universally supported.
Account commands
profilehop add codex work # Register and open the agent's login
profilehop add gemini personal # Complete onboarding, then exit
profilehop add pi work # Enter /login, choose provider, then exit
profilehop add codex later --no-login # Register without starting an agent
profilehop reauth codex work # Retry the official login in the same profile
profilehop reauth gemini personal # Enter /auth inside Gemini
profilehop list # Active accounts have an asterisk
profilehop list --all # Include archived accounts
profilehop current # Current account for each agent
profilehop status codex work # Local selection metadata
profilehop status codex work --native # Run codex login status
profilehop status claude work --native # Run claude auth status
profilehop rename codex work business # Stable directory and Keychain identity
profilehop remove codex business # Archive; no credential/session deletion
profilehop restore codex business
profilehop path codex business # Print the profile directoryNames use lowercase letters, numbers, underscores, and hyphens; start with a letter. An account is identified by agent plus name. The first profile for an agent becomes its selection, even when login is deferred. Selection is not proof of authentication. Profile Hop records login attempts, not a claimed authenticated state; Gemini/Pi interactive exit codes do not prove login succeeded.
Run the selected agent with normal arguments after --:
profilehop run codex work -- exec "Review the current changes"
profilehop claude personal -- --resume
profilehop opencode work -- stats --days 7
profilehop goose work -- session --resumeSwitching affects future Profile Hop launches. Bare codex, claude, etc. still use their ordinary configurations. Profile Hop does not inject aliases into your shell or change a running session's identity. Account profiles intentionally have separate configurations, sessions, and plugins. Project and organization policies still apply.
Token and API-key accounts
Copilot uses COPILOT_GITHUB_TOKEN; Cursor uses CURSOR_API_KEY. Aider supports several provider keys. --env TARGET=SOURCE_VARIABLE maps an existing secret environment variable to the agent's expected variable. Only its name is stored, never its value. Use your existing secret manager to supply these variables; do not put actual keys in command arguments or commit them.
# First supply WORK_COPILOT_TOKEN through your secret manager/environment.
profilehop add copilot work --env COPILOT_GITHUB_TOKEN=WORK_COPILOT_TOKEN
profilehop copilot work
profilehop add cursor personal --env CURSOR_API_KEY=PERSONAL_CURSOR_KEY
profilehop add aider work --env ANTHROPIC_API_KEY=WORK_ANTHROPIC_KEY
# Replace the binding, or rotate the existing source variable in your secret manager.
profilehop reauth cursor personal --env CURSOR_API_KEY=NEW_CURSOR_KEYMissing variables fail before an agent is launched. reauth for these adapters checks the binding locally; it does not claim the remote key is valid. New --env arguments replace the account's full binding set. API-key billing follows the provider's API plan and is not necessarily covered by your subscription.
For Codex with an explicit OPENAI_API_KEY binding, add/reauth invokes the documented codex login --with-api-key and pipes the key through stdin. Codex stores it inside that profile. Run profilehop reauth codex <name> after rotating the source key to update Codex's saved login.
Native profile adapters also accept a restricted set of environment references. See src/agents.js for the allowlist. Known inherited provider credentials and endpoint overrides are removed from child environments to reduce accidental account mixups. Unreferenced cloud credentials and project-specific credential helpers are outside this account-isolation contract; inspect your agent configuration before using cloud federation or custom gateways.
Usage for all accounts
Human-readable usage is a terminal dashboard with account cards, colored usage bars, compact token counts, and reset countdowns in your local timezone. Native Codex results take precedence over empty local history. Colors indicate consumption: green below 70%, yellow from 70%, and red from 90%; percentages always remain visible. Narrow terminals wrap the cards. Redirected output and TERM=dumb use plain ASCII without ANSI colors; NO_COLOR disables colors. --json retains the machine-readable data format.
profilehop usage # Native checks for all managed accounts where supported
profilehop usage codex # Account lifetime tokens and current quota windows
profilehop usage codex --json # Structured local and account measurements
profilehop usage opencode work # Installed agent's native statistics
profilehop usage --local # Offline session records for all accounts
profilehop usage --local --json # Machine-readable offline counts and provenance
profilehop usage claude work --local --days 7Usage runs native checks by default for Codex and OpenCode. Other adapters use their supported local readers or report unavailable measurements. Use --local for an entirely offline check: it reads supported session records without running agents, contacting providers, or refreshing tokens. Local usage excludes other devices and sessions outside these profiles. Duplicated, forked, pruned, truncated, or changed log formats can make totals incomplete. Numbers are observations, not invoices.
Codex rate-limit windows, if present in its local logs, are labeled cached with observation and reset times. They become stale after five minutes or after a reset. A dash means no supported measurement was found, never “zero usage.” Signing in alone does not create local token records. Usage readers have file, byte, and depth limits and flag partial results. --days filters local token records; cached limits retain their own timestamp.
For Codex, the default check starts a private stdio app-server under the selected account lock and requests the documented account/rateLimits/read and account/usage/read methods. It reports remaining percentages, reset times, and lifetime token activity when available. It starts no conversation or model turn. Codex handles credentials and any token refresh; API-key accounts and older Codex versions may not support these measurements. With several Codex profiles, each is checked separately. Close an active Profile Hop session for that profile before requesting native diagnostics, or use --local to read its session records while it is running.
For OpenCode, the default check runs opencode stats. Native processes may initialize their profiles, load configuration, or contact providers. Codex native output supports --json; OpenCode's raw stats do not. Use --local --json for offline JSON across all adapters. --days requires --local. The former usage flag --native has been removed; status --native remains available. See usage formats and assumptions.
Diagnostics and recovery
profilehop doctor
profilehop doctor --json
profilehop unlock codex work
profilehop unlock --metadatadoctor inspects installation paths, private permissions, unsafe filesystem objects, configured environment references, and lock presence. It does not repair or log in. unlock refuses when the recorded wrapper or child process is alive. An interrupted launch with an unknown child PID requires manual process inspection. Do not unlock a profile whose descendants are still using it.
Only one Profile Hop process can use a profile at a time. Different profiles can run concurrently. Normal completion releases the lock; crashes retain it for review. Use Profile Hop to launch managed profiles consistently, since external processes do not participate in Profile Hop's locks.
Storage and security
New installations use ~/.profilehop. If ~/.clihop already exists, Profile Hop continues using it, even if both directories exist. No profiles are moved or merged. PROFILEHOP_HOME (or the legacy CLIHOP_HOME) may point to a dedicated absolute directory whose parent already exists. Existing unrelated directories, your home directory, filesystem roots, and your current working directory are rejected. Runtime state does not belong in this source repository.
~/.profilehop/
state.json # Labels, selections, variable names; no key values
locks/ # Wrapper and child PIDs
profiles/<uuid>/ # Agent-owned credentials, configuration and historyNew directories use 0700 and metadata uses 0600 on POSIX, with an inherited 077 umask. Windows relies on your user-profile ACLs; Profile Hop does not set or audit ACLs. The wrapper uses argument arrays with shell: false, atomic metadata replacement, validated paths, bounded reads, and recoverable archiving. No runtime dependencies, telemetry, install-time hooks, automatic installation, credential exports, process-wide logout, or automatic process killing for account switching. Startup version checks fetch public npm metadata only; profilehop update explicitly downloads and installs a release.
Profile Hop is not an operating-system sandbox. An agent you launch can still read files or execute tools according to its own permissions. Profile Hop never adds approval-bypass flags; it explicitly disables Cline auto-approval and uses Goose's approval mode. It cannot protect against a malicious installed binary, same-user malware, or every upstream bug. Review SECURITY.md for the threat model and the checks performed.
Shell completion
profilehop completion bash, profilehop completion zsh, and profilehop completion fish print static completions for commands and agent names. Save the output into your shell's completion directory. Profile Hop never edits your shell startup files. Account-name completion is not included yet.
Development
npm ci --ignore-scripts
npm run check
npm run verify:package
npm audit --omit=dev
npm run verify:local # Optional: installed agents, help onlyTests use temporary directories and mock executables. They do not touch your real accounts or make paid model calls. Package verification creates a tarball, checks its file allowlist, installs it offline in a temporary directory with scripts disabled, and exercises the packaged commands. The CI matrix is configured for Node 22 and 24 on Linux, macOS, and Windows. Browser OAuth requires a separate manual compatibility pass before release. Contributions adding agents need official configuration/authentication sources, isolation tests, explicit usage capabilities, and a documented fallback when isolation cannot be verified.
MIT license. Independent project; not affiliated with the supported agent vendors.
