Releases: g1mn/agyswap
Release list
v0.6.0: 429 Rate-Limit Guard & 2026 Stateless MCP
Changelog
All notable changes to agyswap are documented here.
Format: Keep a Changelog
[0.6.0] — 2026-09-04
Added
- 🛡️
agyswap guard: Continuous auto-rotation protector foragyCLI sessions. Proactively detects429 Too Many Requests,RESOURCE_EXHAUSTED, and quota errors in real-time, automatically rotates to the next healthy account, and resumes conversation seamlessly viaagy -c. - 🤖 2026 Stateless Model Context Protocol (MCP) Server (
agyswap mcp): Full support for the latest 2026 Stateless MCP specification. Offers 5 autonomous agent tools (list_accounts,get_quota,switch_account,rotate_token,compact_context) over standard stdio or lightweight zero-dependency HTTP (--http). - 🧠 Automatic Context Compaction Flag (
--ctx/-c): Runsagyswap ctx cleanbefore profile switches to synchronize 96.1% compressed AST repository maps and state snapshots into.agents/memory/. - ⌨️
agyswap prompt: Ultra-fast sub-millisecond status formatter for Starship, zshPROMPT, and tmux statusbars (--plain,--json). - 🎮 Docs & Playground Upgrades: Added Interactive Rate-Limit Guard Simulator and Stateless MCP Sandbox & Quick Config to
docs/index.html.
Fixed
- 🔴 Fixed
cmd_switchactive_slot persistence bug:config.json'sactive_slotandlast_used_atare now properly saved immediately after Keychain updates, fixing blind rotation,sync,health, andvizstale-slot cascading failures. - 🔴 Fixed CWE-214 secret exposure in
KeychainManager.set_payload(): Passwords are now passed via standard input (stdin pipe) instead of command arguments (-w raw_password), preventing local process sniffing viaps aux. - 🔴 Protected
.pypirccredentials: Added.pypircto.gitignoreto prevent accidental credential commits. - 🟡 Fixed SVG spec error in
docs/index.html: Removed invalidheight="auto"attribute. - 🟡 Added
cmd_viztemplate fallback: Auto-downloads the dashboard template from GitHub for Homebrew and curl users lacking localdocs/.
[0.5.0] — 2026-08-29
Added
agyswap alias: standalone alias management (agyswap alias,agyswap alias <slot> <name>,agyswap alias <slot> --unset)agyswap enable/agyswap disable: hold a slot out of blind rotation (agyswap switchwith no target) without removing its credentials; explicitagyswap switch <slot>still works on a disabled slotagyswap quota: per-account, per-model Gemini API quota tracking (--refresh,--json), TTL-cached (45s) and merge-safe — never clobbers other accounts' cached data on writeagyswap tui/agyswap watch: live, keyboard-driven terminal dashboard with real-time per-model quota bars (rich+textual)
Changed
- Data directory moved from
~/.agy-swap/to~/.agyswap/— automatically migrated in place on first run; the old path collided with an unrelated third-party tool of a similar name requires-pythonraised to>=3.9(matchesrich/textual's actual floor; CI already only tested 3.9+)richandtextualare now required dependencies (used only bytui/watch) —agyswapis no longer zero-dependency- Fixed a packaging bug where the wheel only ever included
agyswap.pyand silently droppedmodules/(meaningagyswap ctx ...was likely already broken forpip/pipxinstalls);[tool.hatch.build.targets.wheel]now explicitly includesmodules/**/*.pyandmodules/**/*.tcss - Fixed the same
modules/gap for Homebrew (Formula/agyswap.rbnow installsmodules/alongside the binary) and the curl installer (install.shnow fetchesmodules/from the repo tarball);agyswap.pynow resolves its own real install location (following symlinks) to findmodules/regardless of install method docs/index.html(GitHub Pages): updated for the above — new Command Reference cards foralias/enable/disable/quota/tui/watch, corrected "zero dependencies" claims, updated storage layout + a migration note,rich/textualinstall caveats on the Homebrew/curl tabs, 3 new FAQ entries, and fixed a pre-existing duplicate section-letter bug (two sections were both labeled "G")docs/index.html's Interactive Architecture Topology (section A): added a "Live TUI Dashboard" node and a new "Live TUI Dashboard Path" preset, added a 5th Engine Core bullet for the quota cache + TUI safety layer, and extended the Google endpoints node to show the quota API — verified visually in a real browser (no overlap/clipping, presets highlight correctly)assets/architecture.svg/docs/assets/architecture.svg(README's Architecture Overview image, two files kept byte-identical perRELEASING.md): same Live TUI Dashboard node + quota cache bullet + quota API line as above, fixed a stray~/.agy-swap/(legacy path) it still showed, fixed the "Zero Dependencies" footer, and fixed its header badge which was still stuck at "V0.1.0" despite the Engine Core box already saying v0.4.0 — verified visuallyassets/banner.svg/docs/assets/banner.svg: fixed the "DEPENDENCIES: 0 External Deps" feature pill to say "rich+textual (TUI)" — verified visually.logo.svg/logo-icon.svgchecked, no stale claims found
Fixed (cross-review pass)
migrate_legacy_data_dir():config.jsonnow moves last, not first — an interrupted migration (crash, disk full) used to permanently strandslots//backup/in the legacy directory since the "already migrated" guard only checked for the newconfig.jsonagyswap quota --json(with a target/slot given) no longer dumps every cached account — it's now scoped to the requested account(s), matching the human-readable outputmodules/quota.py'squota_cache.jsonread-modify-write is now protected by a file lock — concurrent writers (the TUI's background poller and a CLIagyswap quotacall) could previously clobber each other's just-written updates- A permanently-failing account (e.g. revoked token) is now retried at most once per TTL window instead of on every single call/poll tick
- A malformed/unexpected API response shape no longer crashes
agyswap quotaor the TUI's refresh worker with a raw traceback — it degrades to stale cached data like any other transient failure modules/tui/actions.py's mutation functions now wrap everyStorageManagercall and re-raise asActionError, so a corrupted-config or disk-full error can no longer escape past the TUI's error-handling layer and crash the whole dashboard- The TUI no longer runs blocking, lock-acquiring account mutations (disable/enable/remove) directly on the UI thread — they now run in a background worker like switch/add already did
- Switching accounts from the TUI now shows the same "token expiring soon" warning the CLI already shows
- Fixed a
_menu_stackleak in the TUI dashboard that made "Back" require an extra Escape press after every completed disable/enable/remove action - Fixed a race where a forced TUI refresh (after an account action) could run concurrently with an in-flight periodic refresh instead of replacing it
agyswap.py's bundled-package bootstrap now requires a marker file (modules/quota.py) instead of a bare directory check, so it can't be fooled into loading an unrelatedmodules/folderinstall.sh'smodules/fetch now stages the new copy before removing the old one, so a failed download can't leave an existing install with nomodules/at allagyswap renamenow rejects an empty alias (previously silently cleared it, inconsistent withagyswap alias's explicit--unset)StorageManager.load_config()'s corrupted-config recovery no longer callsprint()directly — it could garble the TUI's rendered screen since this runs on background worker threads too
[0.4.0] — 2026-08-28
Added
agyswap ctxsubsystem: AST-based Repo Map (ctx map), lightweight working-state snapshots (ctx state), and real-time compression benchmarking (ctx bench [--json|-md])agyswap ctx bench --golden: multi-language oracle regression suite (Python, TypeScript/TSX, Go, Rust, Java, C, C++, Shell) enforcing 100% symbol recall on every release- Java, C, C++, and header-file (
.h) support in the AST Repo Mapper (regex extractors with control-flow keyword guards) - Interactive Context Playground & ROI Calculator on the GitHub Pages docs, with a 9-language full-source-vs-repo-map split viewer
Fixed
ctx bench --jsonno longer leaks the full untrimmed repo map into its outputTokenBudgeter.trim_to_budgetno longer overshoots the requested token budget when appending its truncation banner- AST signature extraction now includes positional-only, keyword-only,
*args, and**kwargsparameters (previously silently dropped) - Decorator extraction is no longer limited to a hardcoded allowlist —
@x.setter,@app.route(...), and other real-world decorators are now preserved - Tuple-unpacking constant assignments (e.g.
A, B = 1, 2) are now extracted ctx bench --goldennow honors--dir/--budgetinstead of silently ignoring them.agents/memory/*files and directories are now created with secure permissions atomically, removing a brief world-readable TOCTOU window- Git status parsing now correctly handles quoted/spaced filenames and renames (
git status --porcelain -z) --budgetrejects zero/negative values with a clear usage error instead of silently producing broken output- Golden benchmark symbol-recall check no longer reports false positives when a symbol is renamed to something that merely starts with the old name
- ASCII benchmark report box borders now render aligned regardless of emoji width or digit count
[0.3.0] — 2026-08-23
Added
agyswap switch -r/--resume: Switch account + immediately resume last agy session (agy -c) with 100% conversation history preservedagyswap switch -n/--new: Switch account + launch a fresh agy session- `agyswap ...
v0.5.0
Added
agyswap alias: standalone alias management (agyswap alias,agyswap alias <slot> <name>,agyswap alias <slot> --unset)agyswap enable/agyswap disable: hold a slot out of blind rotation (agyswap switchwith no target) without removing its credentials; explicitagyswap switch <slot>still works on a disabled slotagyswap quota: per-account, per-model Gemini API quota tracking (--refresh,--json), TTL-cached (45s) and merge-safe — never clobbers other accounts' cached data on writeagyswap tui/agyswap watch: live, keyboard-driven terminal dashboard with real-time per-model quota bars (rich+textual)
Changed
- Data directory moved from
~/.agy-swap/to~/.agyswap/— automatically migrated in place on first run; the old path collided with an unrelated third-party tool of a similar name requires-pythonraised to>=3.9(matchesrich/textual's actual floor; CI already only tested 3.9+)richandtextualare now required dependencies (used only bytui/watch) —agyswapis no longer zero-dependency- Fixed a packaging bug where the wheel only ever included
agyswap.pyand silently droppedmodules/(meaningagyswap ctx ...was likely already broken forpip/pipxinstalls);[tool.hatch.build.targets.wheel]now explicitly includesmodules/**/*.pyandmodules/**/*.tcss - Fixed the same
modules/gap for Homebrew (Formula/agyswap.rbnow installsmodules/alongside the binary) and the curl installer (install.shnow fetchesmodules/from the repo tarball);agyswap.pynow resolves its own real install location (following symlinks) to findmodules/regardless of install method docs/index.html(GitHub Pages): updated for the above — new Command Reference cards foralias/enable/disable/quota/tui/watch, corrected "zero dependencies" claims, updated storage layout + a migration note,rich/textualinstall caveats on the Homebrew/curl tabs, 3 new FAQ entries, and fixed a pre-existing duplicate section-letter bug (two sections were both labeled "G")docs/index.html's Interactive Architecture Topology (section A): added a "Live TUI Dashboard" node and a new "Live TUI Dashboard Path" preset, added a 5th Engine Core bullet for the quota cache + TUI safety layer, and extended the Google endpoints node to show the quota API — verified visually in a real browser (no overlap/clipping, presets highlight correctly)assets/architecture.svg/docs/assets/architecture.svg(README's Architecture Overview image, two files kept byte-identical perRELEASING.md): same Live TUI Dashboard node + quota cache bullet + quota API line as above, fixed a stray~/.agy-swap/(legacy path) it still showed, fixed the "Zero Dependencies" footer, and fixed its header badge which was still stuck at "V0.1.0" despite the Engine Core box already saying v0.4.0 — verified visuallyassets/banner.svg/docs/assets/banner.svg: fixed the "DEPENDENCIES: 0 External Deps" feature pill to say "rich+textual (TUI)" — verified visually.logo.svg/logo-icon.svgchecked, no stale claims found
Fixed (cross-review pass)
migrate_legacy_data_dir():config.jsonnow moves last, not first — an interrupted migration (crash, disk full) used to permanently strandslots//backup/in the legacy directory since the "already migrated" guard only checked for the newconfig.jsonagyswap quota --json(with a target/slot given) no longer dumps every cached account — it's now scoped to the requested account(s), matching the human-readable outputmodules/quota.py'squota_cache.jsonread-modify-write is now protected by a file lock — concurrent writers (the TUI's background poller and a CLIagyswap quotacall) could previously clobber each other's just-written updates- A permanently-failing account (e.g. revoked token) is now retried at most once per TTL window instead of on every single call/poll tick
- A malformed/unexpected API response shape no longer crashes
agyswap quotaor the TUI's refresh worker with a raw traceback — it degrades to stale cached data like any other transient failure modules/tui/actions.py's mutation functions now wrap everyStorageManagercall and re-raise asActionError, so a corrupted-config or disk-full error can no longer escape past the TUI's error-handling layer and crash the whole dashboard- The TUI no longer runs blocking, lock-acquiring account mutations (disable/enable/remove) directly on the UI thread — they now run in a background worker like switch/add already did
- Switching accounts from the TUI now shows the same "token expiring soon" warning the CLI already shows
- Fixed a
_menu_stackleak in the TUI dashboard that made "Back" require an extra Escape press after every completed disable/enable/remove action - Fixed a race where a forced TUI refresh (after an account action) could run concurrently with an in-flight periodic refresh instead of replacing it
agyswap.py's bundled-package bootstrap now requires a marker file (modules/quota.py) instead of a bare directory check, so it can't be fooled into loading an unrelatedmodules/folderinstall.sh'smodules/fetch now stages the new copy before removing the old one, so a failed download can't leave an existing install with nomodules/at allagyswap renamenow rejects an empty alias (previously silently cleared it, inconsistent withagyswap alias's explicit--unset)StorageManager.load_config()'s corrupted-config recovery no longer callsprint()directly — it could garble the TUI's rendered screen since this runs on background worker threads too
v0.4.0
Added
agyswap ctxsubsystem: AST-based Repo Map (ctx map), lightweight working-state snapshots (ctx state), and real-time compression benchmarking (ctx bench [--json|-md])agyswap ctx bench --golden: multi-language oracle regression suite (Python, TypeScript/TSX, Go, Rust, Java, C, C++, Shell) enforcing 100% symbol recall on every release- Java, C, C++, and header-file (
.h) support in the AST Repo Mapper (regex extractors with control-flow keyword guards) - Interactive Context Playground & ROI Calculator on the GitHub Pages docs, with a 9-language full-source-vs-repo-map split viewer
Fixed
ctx bench --jsonno longer leaks the full untrimmed repo map into its outputTokenBudgeter.trim_to_budgetno longer overshoots the requested token budget when appending its truncation banner- AST signature extraction now includes positional-only, keyword-only,
*args, and**kwargsparameters (previously silently dropped) - Decorator extraction is no longer limited to a hardcoded allowlist —
@x.setter,@app.route(...), and other real-world decorators are now preserved - Tuple-unpacking constant assignments (e.g.
A, B = 1, 2) are now extracted ctx bench --goldennow honors--dir/--budgetinstead of silently ignoring them.agents/memory/*files and directories are now created with secure permissions atomically, removing a brief world-readable TOCTOU window- Git status parsing now correctly handles quoted/spaced filenames and renames (
git status --porcelain -z) --budgetrejects zero/negative values with a clear usage error instead of silently producing broken output- Golden benchmark symbol-recall check no longer reports false positives when a symbol is renamed to something that merely starts with the old name
- ASCII benchmark report box borders now render aligned regardless of emoji width or digit count
Full Changelog: https://github.com/g1mn/agyswap/blob/main/CHANGELOG.md#040--2026-08-28
v0.3.0 — Session Resume, Background Token Rotation & Zero Popups
What's New in v0.3.0
✨ One-Command Session Workflows
Switch accounts without losing context or re-running commands:
agyswap 2 -r # switch account + resume previous session (agy -c)
agyswap 2 -n # switch account + launch fresh agy session
agyswap 2 -r -y # switch + resume + auto-approve all tool permissions
agyswap 2 -n -y # switch + new session + auto-approve all tool permissionsThe -y / --dangerously-skip-permissions flag passes --dangerously-skip-permissions to agy, enabling fully automated workflows where agy auto-approves all tool permission requests.
🔄 Background Token Rotation (No Browser)
agyswap rotate --all # refresh all OAuth tokens silently (~1s, no browser)
agyswap rotate 2 # refresh specific slot🔐 Zero Keychain Popups
Keychain ACL is reset on every switch — macOS password/certificate popup dialogs are eliminated permanently.
🪟 Per-Session Account Isolation (vs cswap)
Unlike cswap for Claude (which switches all sessions immediately), agyswap leverages agy's stateful token model: existing sessions keep their own account, only new sessions inherit the switched profile. This enables running different accounts per terminal window simultaneously.
📖 Documentation
- Full README rewrite with
cswapvsagyswapcomparison table - New GitHub Pages sections: session isolation model, new command flags
CHANGELOG.mdadded with full v0.1.0–v0.3.0 historyRELEASING.mdadded: permanent release checklist ensuring all 9 files are updated every release
See CHANGELOG.md for full details.
v0.2.0: Background Token Rotation, Homebrew Tap, and Telegram Notifications
🚀 What's New in v0.2.0
- 🔄 Zero-Interaction Background Token Rotation: Seamlessly refreshes Google OAuth tokens in milliseconds without opening browser windows.
- ⚡ Batch Token Rotation (
agyswap rotate --all): One-line command to refresh and validate all registered account slots simultaneously. - 🍺 Homebrew Distribution: Full support for macOS package installation via official tap (
brew install g1mn/tap/agyswap) with automatic shell completions. - 🛡️ Privacy-Isolated Local Dashboards:
agyswap vizgenerates local-only~/.agy-swap/dashboard.html(Mode0600), keeping Git repositories 100% clean and credential-leak-proof. - 🎨 Official Visual Identity System: Embedded vector SVG brand mark, 1280x640 OpenGraph hero banner, and interactive architecture lifecycle map.
- 📱 Real-time Telegram Alerts: GitHub Actions integration for instant notifications on stars, forks, issues, PRs, comments, and weekly digests.
📦 Installation
# Homebrew (Recommended on macOS)
brew install g1mn/tap/agyswap
# One-Line Curl Installer
curl -fsSL https://raw.githubusercontent.com/g1mn/agyswap/main/install.sh | bashv0.1.0 - Initial Public Release 🚀
🔄 agyswap v0.1.0
A lightweight, zero-dependency developer utility to manage and switch between multiple Google Antigravity (agy) profiles on macOS Keychain.
✨ Key Highlights
- ⚡ Instant Switching: Swap active credentials in ~0.1s (
agyswap switch <slot|alias>). - 🔐 Native OS Security: Direct macOS
Security.frameworkC API binding (Mitigates CWE-214argvcredential exposure). - 🔒 Concurrency & Permissions: POSIX file locking (
fcntl.flock), owner-only permissions (0600/0700), umask-safe file handling. - 🚨 Token Protection: Proactive 30-minute expiry warnings and expired token guard.
- 🔍 Diagnostic Tools: Built-in
health,audit,whoami, androtatecommands. - 📦 Zero Dependencies: Pure Python 3 standard library implementation.
🚀 Installation
curl -fsSL https://raw.githubusercontent.com/g1mn/agyswap/main/install.sh | bash