claude-smart 0.2.5

Cross-platform Claude Code smart session manager
claude-smart-0.2.5 is not a library.

claude-smart (csm)

Cross-platform smart session manager for Claude Code.

csm is a single binary that wraps the claude CLI with:

  • smart session selection — resume the right session, or start fresh, per directory;
  • profile management — multiple isolated Claude Code config homes (CLAUDE_CONFIG_DIR) with a one-command switcher;
  • account scoring + auto-switch — pick the least-saturated account to launch under, and relaunch on a rate-limit hit;
  • usage metering — a multi-profile usage table (opt-in; see Hub);
  • a limit-detection hook and a relaunch/handoff loop.

It runs on macOS, Linux/WSL, and Windows-native with a single binary — no shell implementation to keep in sync.

Install

# from crates.io
cargo install claude-smart

# or build from source
git clone https://github.com/DaveDev42/claude-smart
cd claude-smart && cargo install --path .

The binary is named csm. An optional shell function lets cas switch the active profile in your current shell (a child process cannot mutate its parent's environment, so this part is a tiny shim — see Profiles below).

Usage

csm [claude-args...]                 bare = smart launch (implicit `csm run`)
csm run [csm-flags] [-- claude...]   smart launcher (session + account + relaunch)

csm profiles [list]                  list configured profiles
csm profiles add  <name> [<dir>]     register (dir defaults to ~/.claude.<name>)
csm profiles set  <name> <dir>       register/overwrite a profile dir
csm profiles rm   <name>             unregister (refused if it is the default)
csm profiles use  <name>             set the machine default profile
csm profiles edit                    interactive editor (TTY)
csm profiles dir  [<name>]           print a profile's config dir

csm usage [--json] [--no-fetch]      multi-profile usage table (opt-in; see Hub)

csm pick-account [<cur>] [--include-current]
csm scan [<cwd>]                     session listing (TSV)
csm statusline                       `<profile>@<host>` for the shell prompt
csm completions {zsh|bash|pwsh}      shell completions

No collision with claude

csm only treats a known word as its own subcommand. Any word it doesn't recognize is forwarded verbatim to claude — so csm mcp, csm doctor, csm update, csm /login, etc. all reach the real claude untouched. The reserved word set is deliberately disjoint from claude's subcommands. To pass a flag that csm would otherwise interpret (-c, -r, -n, --model, …), put it after --: csm run -- -c.

Profiles

A profile is a named Claude Code config home (CLAUDE_CONFIG_DIR). The registry is a flat JSON map at ~/.config/claude-as/profiles.json:

{
  "personal": "/home/you/.claude.personal",
  "work":     "/home/you/.claude.work"
}

The machine default profile NAME lives in ~/.config/claude-as/default. Manage the registry with csm profiles … (or the interactive csm profiles edit). No account names are compiled into the binary — everything comes from your registry.

Switching the active profile in your shell

Add a tiny function so cas <name> switches CLAUDE_CONFIG_DIR in the current shell (the binary prints an export line; the shell evals it):

# ~/.zshrc
cas() { eval "$(command csm cas --eval --shell zsh -- "$@")"; }
# $PROFILE
function cas { Invoke-Expression ((Get-Command csm -CommandType Application).Source + " cas --eval --shell pwsh -- " + ($args -join ' ')) }

cas <name> switches this shell; cas -g <name> / csm profiles use <name> sets the machine-wide default; cas status shows the current/default/available profiles.

Without a registry (degraded mode)

The registry is optional. With no ~/.config/claude-as/profiles.json (a fresh machine, or a "toss" box you never set up), csm runs in a degraded mode: the plain smart launcher still works, and the registry-dependent commands fail safe rather than erroring out —

Command Without a registry
csm run (and bare csm) works — launches claude under the current CLAUDE_CONFIG_DIR
csm scan, statusline, newuuid, completions, sidecar work — they don't need the registry
csm profiles list prints (profiles.json absent — CAS/pick features disabled)
csm usage prints usage metering disabled … + (no profiles configured — csm profiles add )
csm pick-account no-op (empty stdout), prints the csm profiles add <name> hint, exits 0

So account scoring / auto-switch / pick-account simply don't engage until you csm profiles add at least one profile — nothing crashes.

Hub (usage metering — opt-in)

csm usage and account scoring read usage data from a hub — a machine you designate that periodically scrapes Claude Code usage limits and serves them. This is entirely opt-in via two environment variables; with neither set, the hub features are simply disabled and csm works as a plain smart launcher:

Variable Meaning
CLAUDE_USAGE_URL HTTP endpoint that returns the usage JSON blob. Empty/unset = HTTP disabled.
CLAUDE_HUB_HOSTNAME Short hostname of the hub. When it matches the local host, csm reads the hub's cache directly (no network).

When unset, csm usage prints a "metering disabled" line and still shows your registry. When the hub is unreachable, csm usage serves the last-known cache with a staleness header (⚠ hub data is 7m old …); --no-fetch reads only the cache. No hub identifiers are baked into the binary — it ships clean for anyone to use.

Hub-down account selection. When account auto-selection needs fresh usage but the hub can't be reached, csm does not silently keep the current account. In an interactive terminal it opens an fzf account picker showing the last-known (stale) usage so you can choose deliberately; in a non-interactive context (the Stop hook, scripts) it fails safe to the current profile instead of blocking on a picker. The picker is ordered by recommendation, not alphabetically: rows are ranked exactly as the live scorer (pick_best) would choose — viable accounts first (highest week_all.pct, soonest-reset tie-break), saturated / session-limited / errored / no-data rows below — so the account auto-pick would have selected leads the list. Because fzf's cursor starts on the first row, pressing Enter takes the recommendation; you only need to move when you want a different one. Pressing Escape / Ctrl-C in any picker cancels the launch entirely (csm exits without starting claude) — it does not silently fall through to a default.

Custom usage command (CSM_USAGE_CMD)

You don't have to run a hub. Set CSM_USAGE_CMD to any command that prints a usage JSON blob (the same shape the hub serves) on stdout, and csm will use it as a usage source. It runs ahead of the hub HTTP/SSH transports — the explicit "check via my own script" path — and its result is cached like a hub fetch, so a slow command is not re-run within the cache TTL.

Variable Meaning
CSM_USAGE_CMD Shell command whose stdout is a usage JSON blob. Empty/unset = disabled. Runs via sh -c (POSIX) / cmd /C (Windows) — so on Windows the value must be cmd.exe-safe (single-quote quoting and Unix pipelines won't work; wrap complex logic in a .cmd/.ps1 script and point at that).
CSM_USAGE_CMD_TIMEOUT Hard deadline in seconds for that command (default 10). On timeout csm falls through to the hub.
CLAUDE_USAGE_TTL / CSM_USAGE_TTL_SECS Positive-cache lifetime in seconds (default 60). The legacy name wins if both are set.

csm does the scoring and the account choice itself — the command only reports the facts (each profile's usage); you do not pick a profile in it.

The command is not compiled in — the extraction mechanism is yours to own, because a robust one is environment-specific. (Note: at the time of writing, the claude CLI has no usage subcommand, and its /usage slash command does not reliably emit the session/week percent gauges in non-interactive mode — so a plain claude -p-based recipe is not recommended as a usage source. If you script one, validate that your command actually yields the gauges before relying on it for account scoring.)

See examples/usage-collector.sh for a reference CSM_USAGE_CMD: it shows the three practical strategies — proxy an existing hub endpoint (one curl), re-emit a cache file, or synthesize the JSON from per-profile facts. (The full usage JSON shape and a reference hub deployment are documented in the design notes under docs/.)

License

BSD 3-Clause License. See LICENSE.