agyswap • Architecture & Lifecycle Map

agyswap — Antigravity CLI Account Switcher

Per-session account isolation · Zero-interaction token rotation · One-command session resume. Powered by native macOS Keychain, with a live TUI dashboard and Gemini quota tracking on top.

⚡ Switching Speed
~0.1s
Instant profile & session swap
🛡️ 429 Auto-Guard
Zero Downtime
Auto-rotates & resumes on quota limits
🧠 Context Savings
96.1% Saved
AST skeletons (~1.9k / 50k tokens)
🤖 Agent Protocol
Stateless MCP
2026 spec · stdio + zero-dep HTTP

A · Interactive Architecture Topology Full System

Click presets on the left or nodes below to inspect components across CLI runtime, macOS Keychain, and Google OAuth endpoints.

💻 Developer / Shell $ agyswap 2 $ agyswap switch work $ agyswap health $ agyswap audit zsh · bash · fish 🖥️ Live TUI Dashboard $ agyswap tui $ agyswap watch 3s poll · rich+textual own safety layer (actions.py) 🔄 agyswap Engine Core (v0.6.1) ⚡ Native C API Binding SecKeychain APIs (0% argv leak) 🔒 StorageManager & File Lock fcntl.flock + Mode 0600 / 0700 🚨 Expired Token Guard & Health 30-min soon warning + --force 🌐 Google UserInfo & JWT Claims Offline parsing + Bearer API 📊 Quota Cache & TUI Safety Layer modules/quota.py + actions.py Pure Python 3 · rich+textual for tui/watch only 🔐 macOS Keychain service: gemini / acct: antigravity go-keyring-base64:<JSON> 🤖 Google Antigravity (agy) Gemini / Code Execution Agent ~/.gemini/antigravity-cli/ 📁 Local Slot Store (0600) ~/.agyswap/slots/slot-*.json config.json + rolling backups .agyswap.lock (fcntl barrier) 🌐 Google OAuth & Quota oauth2/v3/userinfo & token cloudcode-pa.googleapis.com (quota)

B · Account Slot Inventory 3 Profiles Loaded

Interactive preview of registered profile slots. Run agyswap viz --open locally on macOS to view your real accounts.

Slot Account / Alias Status Token Expiry Auth Method

C · Profile Switching Sequence ~0.1s Fast Path

Detailed execution flow triggered during an account switch operation.

1

Concurrency Lock & Target Resolution

Acquires fcntl.flock on .agyswap.lock and resolves target slot by number, email, or alias.

2

Expired Token Guard

Compares token.expiry with system UTC clock. If expired without --force, switch is safely blocked with a renewal guide.

3

Native C API Keychain Injection

Directly modifies macOS Keychain using SecKeychainItemModifyAttributesAndData via ctypes without touching process argv.

4

Atomic Config Update & Session Notice

Atomically saves config.json and scans for running agy processes via lsof to emit session restart guidance.

# Example 1: Quick Switch $ agyswap switch work ✓ Switched Antigravity profile to #2 (work@company.com). ⚠️ Detected 1 running agy session: • PID 45920 ~/projects/agyswap (1 session) Start a new terminal session to apply the profile. # Example 2: Expired Token Guard in Action $ agyswap switch 3 ✗ Slot #3 (dev@project.org) token has expired (expired 2h ago). Try refreshing: agyswap rotate 3 Force switch: agyswap switch 3 --force

D · Command Reference

agyswap [list|ls]
Displays account slots with tree-style token validity view, active session indicators, and sync timestamps.
agyswap <slot> [-r|-n] [-y]
Quick-switch profile. -r: resume last session (agy -c). -n: launch fresh session. -y: pass --dangerously-skip-permissions to agy for fully automated no-prompt workflows.
agyswap add [alias]
Registers currently active agy login session as a managed slot with Google profile metadata.
agyswap health [--json]
Overview dashboard of token expiry status across all registered profiles with warning flags.
agyswap audit
Audits and auto-corrects filesystem permissions (0700/0600) and verifies Keychain integrity.
agyswap rotate [--all | slot]
Background OAuth token refresh. --all rotates every slot simultaneously — no browser interaction required.
agyswap export [file]
Exports slot metadata to JSON format for migration (sensitive live tokens excluded for security).
agyswap import <file>
Imports slot metadata from JSON with automatic slot conflict resolution.
agyswap ctx [bench|map|state|clean]
AST Codebase Mapping & Token Optimizer. bench [--golden] [--json|-md]: measure compression, or run the 10-language oracle regression. map/state: compact context snapshots. clean: sync both before /clear.
agyswap alias [slot] [name] [--unset]
Standalone alias management — list every aliased slot, set a new alias, or clear one. Same rename engine as agyswap rename, exposed as its own command.
agyswap enable|disable <slot>
Holds a slot out of blind rotation (agyswap switch with no target) without deleting its credentials. Explicit agyswap switch <slot> still works on a disabled slot.
agyswap quota [slot] [--refresh] [--json]
Per-account, per-model Gemini API quota — remaining %, reset time. TTL-cached (45s) and merge-safe; --refresh bypasses the cache.
agyswap tui / agyswap watch
Live, keyboard-driven terminal dashboard with real-time per-model quota bars (rich + textual). watch jumps straight into the live-monitor view.
agyswap guard [slot] [-r] [-y] [--ctx]
🛡️ Rate-Limit Continuous Protector. Automatically detects 429 quota exhaustion in real-time, rotates credentials in ~0.1s, and resumes conversation context seamlessly via agy -c without human intervention.
agyswap mcp [--http] [--port 8765]
🤖 2026 Stateless Model Context Protocol (MCP) Server. Enables Antigravity, Cursor, and Claude Code to autonomously query Gemini quotas and rotate credentials via stdio or lightweight HTTP.
agyswap prompt [--plain] [--json]
⚡ Sub-millisecond status string for Starship, zsh PROMPT, and tmux (e.g. [agy:work 85%]). Zero network lag.
agyswap completion <shell>
Generates shell auto-completion scripts for zsh, bash, and fish with dynamic slot completion.

E · Intelligent Context Optimization & Token Benchmarks

Reduces agentic token consumption by 94.2% using pure AST skeletons and lightweight state snapshots. Zero external dependencies.

┌─────────────────────────────────────────────────────────────┐ │ 📊 agyswap Context Compression Benchmark │ ├─────────────────────────────────────────────────────────────┤ │ Indexed Files : 20 │ │ Raw Codebase Lines : 3,101 lines (123,082 chars) │ │ Raw Token Footprint: ~34,189 tokens │ ├─────────────────────────────────────────────────────────────┤ │ Repo-Map Lines : 135 lines │ │ Repo-Map Tokens : ~1,995 / 2,000 tokens │ │ Saved Tokens / Run : ~32,194 tokens │ ├─────────────────────────────────────────────────────────────┤ │ Compression Rate : [██████████████████░░] 94.2% │ └─────────────────────────────────────────────────────────────┘
Workflow Phase Naive Full-File Read agyswap ctx (AST Map + Firewall) Net Efficiency
Codebase Discovery Full source read (~34.2k tokens) REPO_MAP.md (~2.0k tokens) 🔥 94.2% Saved
Session Reset Recovery Re-read raw files (~34.2k tokens) STATE.md (< 300 tokens) ⚡ 99.6% Saved
10 Agent Sessions ~342,000 tokens ($1.03+) ~20,000 tokens ($0.06) 17x Cost / Rate-limit Savings

🏆 Golden Quality Benchmark — Multi-Language Oracle Regression

A fixed fixture set (tests/fixtures/golden_repo/) with a known symbol checklist — every release must extract 100% of them, catching silent AST/regex regressions across languages before they ship.

┌─────────────────────────────────────────────────────────────┐ │ 🏆 agyswap Golden Quality & Context Benchmark Monitor │ ├─────────────────────────────────────────────────────────────┤ │ Standard Fixtures : 11 files (323 lines) │ │ Raw Code Footprint : ~2,136 tokens │ │ Repo-Map Size : ~704 tokens │ ├─────────────────────────────────────────────────────────────┤ │ Token Compression : 67.0% 🟢 │ │ Symbol Recall : 100.0% (36/36 symbols) 🟢 │ │ Information Density: 51.1 symbols / 1k Tokens 🟢 │ │ AST Parsing Latency: 1.90 ms ⚡ │ └─────────────────────────────────────────────────────────────┘

Coverage: Python TypeScript TSX Go Rust Java C C++ Shell — native ast parsing for Python, hardened regex extractors (with control-flow keyword guards) for the rest.

F · 🎮 Interactive Context Playground & ROI Calculator

Simulate token savings on your own project scale and compare full source code with AST-extracted Repo Maps in real time.

🎛️ Real-Time Token Savings & Cost Calculator

Project Codebase Lines: 10,000 lines
Monthly AI Agent Sessions: 50 sessions
Token Compression Rate
98.3%
~1,950 vs ~115,000 tokens
Monthly Saved Tokens
5.65M
Tokens preserved per month
Context Lifespan
59x Longer
Before context bloat/rate-limit

🔍 Full Source Code vs. AST Repo-Map (Golden Fixtures)

📄 Raw Full Code (50 lines) ~550 Tokens

          
🗺️ AST Extracted Skeleton (7 lines) ~75 Tokens (86% Saved)

          

G · 🛡️ Interactive Rate-Limit Guard Simulator

Live Auto-Recovery Demo

Experience how agyswap guard catches 429 quota exhaustion in real-time, rotates credentials in ~0.1s, and resumes coding without human intervention.

ACTIVE: Slot #1 (personal@gmail.com)
▶ Launching agy session [Slot #1 · personal@gmail.com]...
────────────────────────────────────────────────────────────
[agy] Ready. Paired programming session active. Listening for instructions...

H · 🤖 2026 Stateless MCP Sandbox & Quick Config

Zero-Dependency JSON-RPC

Enables AI agents to query their own quotas and rotate profiles autonomously via standard MCP over stdio or lightweight HTTP.

{ "mcpServers": { "agyswap": { "command": "agyswap", "args": ["mcp"] } } }
{ "mcpServers": { "agyswap": { "command": "agyswap", "args": ["mcp"] } } }
{ "mcpServers": { "agyswap": { "command": "agyswap", "args": ["mcp"] } } }
MCP Tool Name Input Schema Autonomous Agent Action
agyswap_list_accounts {} Queries all slots, active state, aliases, and token health info.
agyswap_get_quota { target?, refresh? } Inspects real-time remaining % and reset times for Gemini models.
agyswap_switch_account { target?, force?, compact_context? } Rotates active Keychain credential & compacts AST context automatically.
agyswap_rotate_token { target?, all? } Refreshes OAuth credentials in background without browser interaction.
agyswap_compact_context { budget?, goal? } Generates 96% compressed REPO_MAP.md and STATE.md into .agents/memory/.
🧪 Test Stateless MCP Requests (1-Shot JSON-RPC)
{
  "jsonrpc": "2.0",
  "result": {
    "protocolVersion": "2026-07-28",
    "capabilities": { "stateless": true }
  }
}

I · Security Architecture & Threat Model

Security Layer Implementation Mechanism Threat Mitigated
Keychain Binding macOS Security.framework Native C API via ctypes Process argument sniffing (ps aux / CWE-214)
Storage Isolation Files 0600, Dirs 0700 (opener=secure_opener) Cross-user access & Umask race conditions
Concurrency Lock fcntl.flock on .agyswap.lock (config/slots) and a dedicated lock for quota_cache.json Lost updates during concurrent terminal runs, incl. the TUI's background poller racing a CLI call
Template Escaping safe_json_for_script Unicode character sanitization Stored XSS inside HTML <script> blocks

J · POSIX Storage Layout

~/.agyswap/ # Mode 0700 (Owner rwx only) ├── config.json # Mode 0600 (active_slot, accounts metadata) ├── .agyswap.lock # Mode 0600 (flock concurrency barrier) ├── quota_cache.json # Mode 0600 (TTL-cached Gemini quota, merge-safe) ├── dashboard.html # Mode 0600 (generated by 'agyswap viz') ├── slots/ # Mode 0700 (Isolated slot directory) │ ├── slot-1.json # Mode 0600 (OAuth token credentials) │ └── slot-2.json # Mode 0600 └── backup/ # Mode 0700 (Directory) └── config-YYYYMMDD-HHMMSS.json # Mode 0600 (Rolling automated backups)

Migrating from an older install? Data used to live at ~/.agy-swap/ (hyphenated — it collided with an unrelated third-party tool of a similar name). agyswap moves just its own files here automatically the first time you run any command after upgrading.

K · Installation & Shell Completion

# Install via Homebrew Tap (Shell completions automatically configured): brew install g1mn/tap/agyswap # 'agyswap tui'/'watch' need rich+textual, which Homebrew doesn't vendor: pip3 install --user rich textual
# Install via official installer script (fetches modules/ automatically): curl -fsSL https://raw.githubusercontent.com/g1mn/agyswap/main/install.sh | bash # 'agyswap tui'/'watch' need rich+textual: pip3 install --user rich textual
# Install from cloned repository via pip/pipx (pulls in rich+textual automatically): git clone https://github.com/g1mn/agyswap.git cd agyswap pip install .
# Add to ~/.zshrc: echo 'eval "$(agyswap completion zsh)"' >> ~/.zshrc && source ~/.zshrc
# Add to ~/.bashrc: echo 'eval "$(agyswap completion bash)"' >> ~/.bashrc && source ~/.bashrc
# Install to fish completions directory: agyswap completion fish > ~/.config/fish/completions/agyswap.fish

L · Troubleshooting FAQ

Do running agy CLI sessions switch immediately? +
macOS caches Keychain reads in memory for short durations. While the Keychain is updated instantly in ~0.1s, starting a new terminal prompt or restarting existing agy sessions guarantees active credential activation.
How do I safely migrate to a new Mac? +
Run agyswap export backup.json on your old Mac. On your new Mac, run agyswap import backup.json. Live tokens are excluded from export for security; simply log into each profile once via agy and run agyswap sync.
What should I do if a token expires? +
Run agyswap rotate <slot> to initiate a token refresh, or log into the expired account using agy and run agyswap sync.
My data used to live at ~/.agy-swap — where did it go? +
Moved automatically to ~/.agyswap/ (no hyphen) the first time you ran any command after upgrading — the old hyphenated path collided with an unrelated third-party tool of a similar name. Only agyswap's own files (config, slots, backups) were moved; nothing else in the old directory was touched.
Why does `agyswap tui` say it can't load the TUI module? +
tui/watch need the rich and textual packages. Pip/pipx installs get them automatically; Homebrew and the curl installer don't vendor them, so run pip3 install --user rich textual once. Every other command works without them.
What's the difference between `disable` and `remove`? +
agyswap disable <slot> just holds an account out of blind rotation (agyswap switch with no target skips it) — its credentials stay intact and agyswap switch <slot> still switches to it explicitly. agyswap remove <slot> deletes the slot's stored token entirely.