All notable changes to claude-sentinel are documented here. Format follows Keep a Changelog.
- 1Password / Doppler secret integration —
auth/secrets.rs:SecretSourceenum supporting Keychain (default),op read "op://..."(1Password CLI),doppler secrets get KEY(Doppler CLI), and plain env var;ApiKeyEntry.sourcefield replaces hardcoded keychain path; backwards-compatible with existingapi_keys.toml;add_external_key()+describe_sources()helpers; 11 unit tests - Team profile sharing —
team_sync.rs:cst team init/push/pull/status; clones git remote into local cache;push()copies only safe files (profile.toml, settings overrides, MCP config, env.toml, auto-switch.toml) and commits;pull()fetches + resets; credentials and stats never synced; include/exclude_profiles filter; 6 unit tests .cstrcauto-detect —auto_detect.rs: walk directory tree for.cstrc(TOML), matchprofile/sessionfields;[[auto_detect]]entries withgit_remote_patternglobs for git-URL-based selection; glob normalises SSH/HTTPS URLs automatically; 13 unit tests- Live
history.jsonlparser —history_parser.rs: scan Claude Code's JSONL history forusageobjects, suminput_tokens/output_tokens/cache fields;estimated_cost_usd()helper; gracefully skips invalid lines; 10 unit tests - Round-robin config —
RoundRobinstruct inauto_switch/config.rs:[round_robin]TOML section withpool,rotate_after_tokens,enabled; daemon can distribute usage across a pool of profiles to maximise uptime
cst _auto-detect <dir> <current>— hidden command called by precmd hook; emits env exports when.cstrcrequests a different profile than currently activecst auto-detect-status [<dir>]— show what.cstrcwould activate in a directory without switchingcst remaininglive counts — now prefers livehistory.jsonltoken counts over cachedstats.json; shows(live)label when real data is available
_cst_check_switchprecmd hook now has a third step (after pending-switch and broadcast): checks.cstrcviacst _auto-detect $PWD $CST_CURRENT- Supports zsh, bash, fish
.github/workflows/release.yml— buildscstfor 5 targets (aarch64/x86_64 × macOS/Linux + Windows x86_64);.zipfor Windows,.tar.gzfor Unix; creates GitHub Release with checksums; extracts release notes fromCHANGELOG.md- Homebrew formula —
Formula/claude-sentinel.rb: selects binary by arch/OS, installs shell completions, caveats for first-run - Raycast script commands —
raycast/: switch-profile, show-status, show-remaining, list-profiles (bash scripts, compact/fullOutput modes) - 60 CLI integration tests —
crates/cst-cli/tests/cli_integration.rs; build-and-run thecstbinary against isolatedTempDirenvironments; covers smoke, profile CRUD, session CRUD, auto-detect, doctor, settings, team-sync git roundtrip, starship/tmux; passes on macOS and Linux; gated withCST_DATA_DIRenv-var isolation CST_DATA_DIRenv-var override —platform::data_dir()now checksCST_DATA_DIRfirst, redirecting the entire data layer for hermetic tests without touching~/.claude-sentinel/- Docker test environments —
docker/test/Dockerfile(Ubuntu 22.04) +Dockerfile.debian(Bookworm);scripts/test-docker.shrunner .github/workflows/integration.yml— new CI job: native matrix (Ubuntu, macOS, Windows) + Docker matrix (Ubuntu + Debian); triggers on push to main and PRs- 166 unit tests (up from 130) — deep test gap analysis and new test suites added
history_parsertests (8 new): truncated JSON lines, Windows CRLF endings, both-fields double-count documentation, zero-value fields, cost proportionality, null usage fields, missing file error pathauto_detecttests (11 new): malformed TOML returns None, only-auto-detect entries with no git match, glob edge cases (empty pattern, star-only, middle star, empty segment), normalise idempotency, HTTP/SSH-scheme URL normalisation, find_cstrc in current dirauth/secretstests (8 new): describe() security invariant (shows reference not secret), Doppler describe with no project/config, env var empty-value success, check_tool_available for non-CLI providers, serde tag field verification, Doppler roundtrip with all optionsteam_synctests (7 new): API key.encfile not copied,copy_profile_from_repoauth exclusion (defence against malicious repo), session stats.json excluded from sync, exclude-beats-include precedence, missing config file error, session sync file allowlist excludes history/stats, SYNC_FILES completeness and safety assertions
- Profile management — CRUD, clone, rename, import, templates (pro/max/api/bedrock/vertex)
- Session management — CRUD, tag, archive, symlink setup for shared global config
- Auth modules — OAuth symlink swap, API key pool (Keychain/AES-GCM), AWS Bedrock env injection, Google Vertex AI env injection
- 3-layer settings merge — global + profile + session overrides deep-merged on activate
- MCP overrides — per-profile add/disable of MCP servers vs global
~/.claude.json - env.toml overlay — per-session extra environment variables
- ProfileHooks — pre/post switch_in/out lifecycle hooks (non-fatal
sh -c) - SessionStats — token counts, cost estimates, rate-limit hit tracking
- Auto-switch daemon — tokio async file watcher, rate-limit pattern detection (10 patterns), fallback chain, quota reset scheduler, switch-back timer
- Switch log — append-only JSONL event log with reason, from/to, timestamp
- Broadcast switch — TTL-based broadcast file for signalling all open shells to switch profiles; per-shell
CST_BROADCAST_IDprevents duplicate application - Platform paths — cross-platform data/profile/session/claude-config dirs via
dirscrate
- Full command surface:
use,status,list,remaining,top,history,why,new,import,clone,rm,rename,login,add-key,session *,daemon *,auto-switch *,pause,run,sync,stats,doctor,validate,shell-init,starship,tmux,completions,templates,init cst switch-all <from> <to>— broadcast profile switch to all open shellscst session switch <session> --to <profile>— reassign a session to a different profilecst top— htop-style live dashboard (1s refresh): token usage table, quota timers, recent switch events, daemon status, braille spinnercst doctor— 5-group health check: Claude Code install, data dir, profiles/sessions symlinks, daemon PID health, shell rc integration; exits 1 on hard failurescst remaining— token usage for active session + profile totals + rate-limit countdown timers + cross-profile summary tablecst starship— Starship custom module output with quota warning;--configprints TOML snippetcst tmux— tmux status-right segment;--configprints config snippet- ratatui TUI — 4-tab interactive navigator (Profiles, Sessions, Auto-Switch, History); Enter activates via pending-switch;
rrefreshes
eval "$(cst shell-init)"— installscstshell function +_cst_check_switchprecmd hook- Precmd hook — checks both one-shot pending-switch (daemon-initiated) and broadcast-switch file
- Supports: zsh, bash, fish, PowerShell
CST_BROADCAST_IDper-shell env var prevents re-applying the same broadcast
- Tauri v2 app with system tray — left-click toggles window, right-click menu
- 4-tab window: Profiles, Sessions, Auto-Switch, Stats
- Neubrutalism design system — pure
#000/#fff, 2-4px solid borders, 4px offset shadows, zero border-radius, monospace throughout, ALL-CAPS labels - Zustand stores for profiles and daemon state
- Tauri commands wrap
cst-corefor all CRUD and daemon operations
- Cargo workspace:
cst-core,cst-cli,apps/desktop/src-tauri - GitHub Actions CI: test + clippy + release build matrix (ubuntu + macos, x86_64 + aarch64)
- devbox + direnv dev environment
- 87 unit tests
docs/ARCHITECTURE.md— crate structure, data flows, daemon design, TUI, Tauri appdocs/AUTH.md— all 4 auth typesdocs/AUTO-SWITCH.md— daemon config, rate-limit patterns, monitoring withcst topdocs/CONTRIBUTING.md— dev setup, TDD workflow, CI pipeline, commit conventionsdocs/DESIGN.md— complete neubrutalism design system specdocs/INSTALL.md— installation guidedocs/USAGE.md— full CLI reference with examples and ASCII layout diagrams
- Initial commit: Cargo workspace scaffold, directory structure, devbox/direnv config