From 00587fcce82c5e9ba011ba0981eeb2bc40153e8a Mon Sep 17 00:00:00 2001 From: Nikketryhard Date: Wed, 18 Feb 2026 01:54:54 -0600 Subject: [PATCH] feat: rebrand to ZeroGravity, replace proxyctl with zg Rust binary Phase 1 - Rename: - Crate: antigravity-proxy -> zerogravity - Env: ANTIGRAVITY_OAUTH_TOKEN -> ZEROGRAVITY_TOKEN - Paths: ~/.config/antigravity-proxy -> ~/.config/zerogravity - Paths: /tmp/antigravity-* -> /tmp/zerogravity-* - User: antigravity-ls -> zerogravity-ls - Service: antigravity-proxy -> zerogravity Phase 2 - zg daemon manager: - New Rust binary src/bin/zg.rs replaces scripts/proxyctl bash - Commands: start, stop, restart, rebuild, status, logs, test, health - Auto-resolves project dir from binary location - All commands exit immediately (safe for agent fast-bash) --- Cargo.lock | 74 +++++------ Cargo.toml | 10 +- GEMINI.md | 38 +++--- README.md | 26 ++-- docs/mitm.md | 6 +- docs/traces.md | 8 +- scripts/mitm-redirect.sh | 10 +- src/api/completions.rs | 2 +- src/api/gemini.rs | 2 +- src/api/responses.rs | 2 +- src/backend.rs | 6 +- src/bin/snapshot.rs | 2 +- src/bin/zg.rs | 273 +++++++++++++++++++++++++++++++++++++++ src/constants.rs | 2 +- src/main.rs | 22 ++-- src/standalone/mod.rs | 6 +- src/standalone/spawn.rs | 32 ++--- src/trace.rs | 4 +- 18 files changed, 403 insertions(+), 122 deletions(-) create mode 100644 src/bin/zg.rs diff --git a/Cargo.lock b/Cargo.lock index 06d34bc..fff3344 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -103,43 +103,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "antigravity-proxy" -version = "3.0.0" -dependencies = [ - "async-stream", - "axum", - "base64", - "brotli 7.0.0", - "bytes", - "chrono", - "clap", - "flate2", - "http", - "http-body-util", - "httparse", - "hyper", - "hyper-util", - "rand", - "rcgen", - "regex", - "rustls", - "rustls-native-certs", - "rustls-pemfile", - "serde", - "serde_json", - "time", - "tokio", - "tokio-rustls", - "tokio-stream", - "tower-http", - "tracing", - "tracing-subscriber", - "uuid", - "wreq", - "wreq-util", -] - [[package]] name = "async-stream" version = "0.3.6" @@ -2396,6 +2359,43 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zerogravity" +version = "3.0.0" +dependencies = [ + "async-stream", + "axum", + "base64", + "brotli 7.0.0", + "bytes", + "chrono", + "clap", + "flate2", + "http", + "http-body-util", + "httparse", + "hyper", + "hyper-util", + "rand", + "rcgen", + "regex", + "rustls", + "rustls-native-certs", + "rustls-pemfile", + "serde", + "serde_json", + "time", + "tokio", + "tokio-rustls", + "tokio-stream", + "tower-http", + "tracing", + "tracing-subscriber", + "uuid", + "wreq", + "wreq-util", +] + [[package]] name = "zeroize" version = "1.8.2" diff --git a/Cargo.toml b/Cargo.toml index 1305e3f..2313be7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,16 @@ [package] -name = "antigravity-proxy" +name = "zerogravity" version = "3.0.0" edition = "2021" +[[bin]] +name = "zerogravity" +path = "src/main.rs" + +[[bin]] +name = "zg" +path = "src/bin/zg.rs" + [dependencies] axum = { version = "0.8", features = ["json"] } tokio = { version = "1", features = ["full"] } diff --git a/GEMINI.md b/GEMINI.md index 84e7dd5..83a98f1 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -27,41 +27,41 @@ This "LS as dumb relay" pattern keeps the LS interactions minimal and predictabl ## Agent Quick Reference -### `proxyctl` — Daemon Manager +### `zg` — Daemon Manager -`proxyctl` commands exit immediately (not foreground) — safe for agent use via fast-bash MCP. +`zg` commands exit immediately (not foreground) — safe for agent use via fast-bash MCP. ```bash # Rebuild and restart after code changes -proxyctl restart +zg restart # Quick test -proxyctl test "say hi in 3 words" +zg test "say hi in 3 words" # Check status -proxyctl status +zg status # Check health -proxyctl health +zg health ``` | Command | Description | | --------------------- | ----------------------------------- | -| `proxyctl start` | Start the proxy daemon | -| `proxyctl stop` | Stop the proxy daemon | -| `proxyctl restart` | Rebuild + restart | -| `proxyctl rebuild` | Build release binary only | -| `proxyctl status` | Service status + quota + usage | -| `proxyctl logs [N]` | Tail last N lines + follow | -| `proxyctl logs-all` | Full log dump (no follow) | -| `proxyctl test [msg]` | Quick test request (gemini-3-flash) | -| `proxyctl health` | Health check | +| `zg start` | Start the proxy daemon | +| `zg stop` | Stop the proxy daemon | +| `zg restart` | Rebuild + restart | +| `zg rebuild` | Build release binary only | +| `zg status` | Service status + quota + usage | +| `zg logs [N]` | Tail last N lines + follow | +| `zg logs-all` | Full log dump (no follow) | +| `zg test [msg]` | Quick test request (gemini-3-flash) | +| `zg health` | Health check | ### Testing After Changes ```bash # 1. Rebuild + restart -proxyctl restart +zg restart # 2. Test an endpoint curl -s http://localhost:8741/v1/chat/completions \ @@ -69,7 +69,7 @@ curl -s http://localhost:8741/v1/chat/completions \ -d '{"model": "gemini-3-flash", "messages": [{"role": "user", "content": "Say hi"}]}' | jq . # 3. Inspect latest trace -TRACE_DIR=~/.config/antigravity-proxy/traces/$(date +%Y-%m-%d) +TRACE_DIR=~/.config/zerogravity/traces/$(date +%Y-%m-%d) cat "$TRACE_DIR/$(ls -t "$TRACE_DIR" | head -1)/summary.md" ``` @@ -99,8 +99,8 @@ cat "$TRACE_DIR/$(ls -t "$TRACE_DIR" | head -1)/summary.md" The proxy needs an OAuth token: -1. **Env var**: `ANTIGRAVITY_OAUTH_TOKEN=ya29.xxx` -2. **Token file**: `~/.config/antigravity-proxy-token` +1. **Env var**: `ZEROGRAVITY_TOKEN=ya29.xxx` +2. **Token file**: `~/.config/zerogravity-token` 3. **Runtime**: `curl -X POST http://localhost:8741/v1/token -d '{"token":"ya29.xxx"}'` ## CLI Flags diff --git a/README.md b/README.md index 3a4a411..a9825ff 100644 --- a/README.md +++ b/README.md @@ -23,10 +23,10 @@ graph LR ```bash # Headless mode (no running Antigravity app needed) -RUST_LOG=info ./target/release/antigravity-proxy --headless +RUST_LOG=info ./target/release/zerogravity --headless # Or use the daemon manager -proxyctl start +zg start ``` ## Endpoints @@ -50,22 +50,22 @@ proxyctl start The proxy needs an OAuth token: -1. **Env var**: `ANTIGRAVITY_OAUTH_TOKEN=ya29.xxx` -2. **Token file**: `~/.config/antigravity-proxy-token` +1. **Env var**: `ZEROGRAVITY_TOKEN=ya29.xxx` +2. **Token file**: `~/.config/zerogravity-token` 3. **Runtime**: `curl -X POST http://localhost:8741/v1/token -d '{"token":"ya29.xxx"}'` -## `proxyctl` Commands +## `zg` Commands | Command | Description | | --------------------- | ------------------------------ | -| `proxyctl start` | Start the proxy daemon | -| `proxyctl stop` | Stop the proxy daemon | -| `proxyctl restart` | Rebuild + restart | -| `proxyctl rebuild` | Build release binary only | -| `proxyctl status` | Service status + quota + usage | -| `proxyctl logs [N]` | Tail last N lines + follow | -| `proxyctl test [msg]` | Quick test request | -| `proxyctl health` | Health check | +| `zg start` | Start the proxy daemon | +| `zg stop` | Stop the proxy daemon | +| `zg restart` | Rebuild + restart | +| `zg rebuild` | Build release binary only | +| `zg status` | Service status + quota + usage | +| `zg logs [N]` | Tail last N lines + follow | +| `zg test [msg]` | Quick test request | +| `zg health` | Health check | ## Documentation diff --git a/docs/mitm.md b/docs/mitm.md index 3135fd1..53834af 100644 --- a/docs/mitm.md +++ b/docs/mitm.md @@ -132,11 +132,11 @@ Events dispatched through `tokio::sync::mpsc` channels from MITM → API handler ### UID-Scoped iptables (Classic Mode) ```bash -# One-time setup — creates antigravity-ls user + iptables rule +# One-time setup — creates zerogravity-ls user + iptables rule sudo ./scripts/mitm-redirect.sh install # Run proxy (standalone LS + MITM both enabled by default) -RUST_LOG=info ./target/release/antigravity-proxy +RUST_LOG=info ./target/release/zerogravity # Check intercepted usage curl -s http://localhost:8741/v1/usage | jq . @@ -150,7 +150,7 @@ sudo ./scripts/mitm-redirect.sh uninstall No iptables or sudo needed. The LS connects through `HTTPS_PROXY` instead: ```bash -RUST_LOG=info ./target/release/antigravity-proxy --headless +RUST_LOG=info ./target/release/zerogravity --headless ``` --- diff --git a/docs/traces.md b/docs/traces.md index b475835..00566d1 100644 --- a/docs/traces.md +++ b/docs/traces.md @@ -5,7 +5,7 @@ Per-call debug traces for inspecting request/response flow. Every API call write ## Location ``` -~/.config/antigravity-proxy/traces/{YYYY-MM-DD}/{HH-MM-SS.sss}_{cascade_short}/ +~/.config/zerogravity/traces/{YYYY-MM-DD}/{HH-MM-SS.sss}_{cascade_short}/ ``` Disable with `--no-trace`. @@ -108,11 +108,11 @@ Traces are designed for LLM consumption. To inspect the last trace: ```bash # Find latest trace -ls -t ~/.config/antigravity-proxy/traces/$(date +%Y-%m-%d)/ | head -1 +ls -t ~/.config/zerogravity/traces/$(date +%Y-%m-%d)/ | head -1 # Read the summary -cat ~/.config/antigravity-proxy/traces/$(date +%Y-%m-%d)/$(ls -t ~/.config/antigravity-proxy/traces/$(date +%Y-%m-%d)/ | head -1)/summary.md +cat ~/.config/zerogravity/traces/$(date +%Y-%m-%d)/$(ls -t ~/.config/zerogravity/traces/$(date +%Y-%m-%d)/ | head -1)/summary.md # Grep for failures -grep 'outcome=.*error\|outcome=.*timeout' ~/.config/antigravity-proxy/traces/$(date +%Y-%m-%d)/*/meta.txt +grep 'outcome=.*error\|outcome=.*timeout' ~/.config/zerogravity/traces/$(date +%Y-%m-%d)/*/meta.txt ``` diff --git a/scripts/mitm-redirect.sh b/scripts/mitm-redirect.sh index 2ed877c..10f4f02 100755 --- a/scripts/mitm-redirect.sh +++ b/scripts/mitm-redirect.sh @@ -6,7 +6,7 @@ # modification, no system-wide changes. # # Flow: -# 1. Standalone LS runs as 'antigravity-ls' user (via sudo -u) +# 1. Standalone LS runs as 'zerogravity-ls' user (via sudo -u) # 2. iptables catches :443 traffic from that UID only → REDIRECT to MITM port # 3. MITM terminates TLS (Go client trusts our CA via SSL_CERT_FILE) # 4. MITM forwards upstream, captures usage @@ -24,10 +24,10 @@ set -euo pipefail MITM_PORT="${2:-8742}" -LS_USER="antigravity-ls" +LS_USER="zerogravity-ls" DATA_DIR="/tmp/antigravity-standalone" LS_BINARY="/usr/share/antigravity/resources/app/extensions/antigravity/bin/language_server_linux_x64" -SUDOERS_FILE="/etc/sudoers.d/antigravity-ls" +SUDOERS_FILE="/etc/sudoers.d/zerogravity-ls" install() { if [[ $EUID -ne 0 ]]; then @@ -54,7 +54,7 @@ install() { echo " + data dir: $DATA_DIR (mode 1777, writable by all)" # ── 3. Sudoers entry ──────────────────────────────────────────────── - # Allow the invoking user (SUDO_USER) to run ANY command as antigravity-ls. + # Allow the invoking user (SUDO_USER) to run ANY command as zerogravity-ls. # This is needed for the proxy to spawn the LS binary. local REAL_USER="${SUDO_USER:-$(logname 2>/dev/null || whoami)}" cat > "$SUDOERS_FILE" < Result { https_port = "3100".to_string(); } - let oauth_token = std::env::var("ANTIGRAVITY_OAUTH_TOKEN") + let oauth_token = std::env::var("ZEROGRAVITY_TOKEN") .ok() .filter(|s| !s.is_empty()) .or_else(|| { let home = std::env::var("HOME").unwrap_or_default(); - let path = format!("{home}/.config/antigravity-proxy-token"); + let path = format!("{home}/.config/zerogravity/token"); fs::read_to_string(&path) .ok() .map(|s| s.trim().to_string()) diff --git a/src/bin/snapshot.rs b/src/bin/snapshot.rs index 242c440..baf436b 100644 --- a/src/bin/snapshot.rs +++ b/src/bin/snapshot.rs @@ -1,3 +1,3 @@ fn main() { - antigravity_proxy::snapshot::run_cli(); + zerogravity::snapshot::run_cli(); } diff --git a/src/bin/zg.rs b/src/bin/zg.rs new file mode 100644 index 0000000..d2abac2 --- /dev/null +++ b/src/bin/zg.rs @@ -0,0 +1,273 @@ +//! `zg` — ZeroGravity daemon manager. +//! +//! All commands exit immediately (safe for agent use via fast-bash MCP). + +use std::process::{Command, Stdio}; + +const SERVICE: &str = "zerogravity"; +const PORT: u16 = 8741; + +// ANSI colors +const RED: &str = "\x1b[0;31m"; +const GREEN: &str = "\x1b[0;32m"; +const YELLOW: &str = "\x1b[1;33m"; +const CYAN: &str = "\x1b[0;36m"; +const BOLD: &str = "\x1b[1m"; +const DIM: &str = "\x1b[2m"; +const NC: &str = "\x1b[0m"; + +fn main() { + let args: Vec = std::env::args().collect(); + let cmd = args.get(1).map(|s| s.as_str()).unwrap_or(""); + let arg = args.get(2).map(|s| s.as_str()); + + match cmd { + "start" => do_start(), + "stop" => do_stop(), + "restart" => do_restart(), + "rebuild" => do_build(), + "status" => do_status(), + "logs" => do_logs(arg.unwrap_or("30"), false), + "logs-follow" => do_logs(arg.unwrap_or("30"), true), + "logs-all" => do_logs_all(), + "test" => do_test(arg.unwrap_or("Say hello in exactly 3 words")), + "health" => do_health(), + _ => usage(), + } +} + +fn usage() { + println!("{BOLD}zg{NC} — ZeroGravity daemon manager\n"); + println!(" {CYAN}start{NC} Start the proxy daemon"); + println!(" {CYAN}stop{NC} Stop the proxy daemon"); + println!(" {CYAN}restart{NC} Rebuild + restart"); + println!(" {CYAN}rebuild{NC} Build release binary only"); + println!(" {CYAN}status{NC} Service status + quota + usage"); + println!(" {CYAN}logs{NC} [N] Show last N lines (default 30)"); + println!(" {CYAN}logs-follow{NC} [N] Tail last N lines + follow"); + println!(" {CYAN}logs-all{NC} Full log dump"); + println!(" {CYAN}test{NC} [msg] Quick test request (gemini-3-flash)"); + println!(" {CYAN}health{NC} Health check"); +} + +fn project_dir() -> String { + // Resolve project dir from binary location: + // binary is at /target/release/zg or /target/debug/zg + let exe = std::env::current_exe().expect("cannot resolve exe path"); + let exe_dir = exe.parent().expect("no parent dir"); + + // Walk up from target/release/ or target/debug/ + if let Some(target_dir) = exe_dir.parent() { + if let Some(project) = target_dir.parent() { + return project.to_string_lossy().to_string(); + } + } + + // Fallback: use current dir + std::env::current_dir() + .expect("no cwd") + .to_string_lossy() + .to_string() +} + +fn base_url() -> String { + let port = std::env::var("PROXY_PORT") + .ok() + .and_then(|p| p.parse::().ok()) + .unwrap_or(PORT); + format!("http://localhost:{port}") +} + +fn systemctl(args: &[&str]) -> bool { + Command::new("systemctl") + .arg("--user") + .args(args) + .status() + .map(|s| s.success()) + .unwrap_or(false) +} + +fn curl_get(path: &str) -> Option { + let url = format!("{}{}", base_url(), path); + Command::new("curl") + .args(["-sf", &url]) + .output() + .ok() + .filter(|o| o.status.success()) + .map(|o| String::from_utf8_lossy(&o.stdout).to_string()) +} + +fn curl_post(path: &str, body: &str) -> Option { + let url = format!("{}{}", base_url(), path); + Command::new("curl") + .args(["-sf", &url, "-H", "Content-Type: application/json", "-d", body]) + .output() + .ok() + .filter(|o| o.status.success()) + .map(|o| String::from_utf8_lossy(&o.stdout).to_string()) +} + +fn health_ok() -> bool { + curl_get("/health").is_some() +} + +fn jq_print(json: &str) { + let mut child = Command::new("jq") + .arg(".") + .stdin(Stdio::piped()) + .spawn() + .expect("jq not found"); + if let Some(stdin) = child.stdin.as_mut() { + use std::io::Write; + let _ = stdin.write_all(json.as_bytes()); + } + let _ = child.wait(); +} + +// ── Commands ── + +fn do_build() { + let dir = project_dir(); + println!("{YELLOW}Building release binary...{NC}"); + let status = Command::new("cargo") + .args(["build", "--release"]) + .current_dir(&dir) + .stdin(Stdio::inherit()) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .status() + .expect("failed to run cargo"); + + if status.success() { + println!("{GREEN}Build complete.{NC}"); + } else { + eprintln!("{RED}Build failed.{NC}"); + std::process::exit(1); + } +} + +fn do_start() { + systemctl(&["daemon-reload"]); + systemctl(&["start", SERVICE]); + println!("{GREEN}Started.{NC} Waiting for ready..."); + + for _ in 0..20 { + if health_ok() { + println!("{GREEN}ZeroGravity is up on port {PORT}.{NC}"); + return; + } + std::thread::sleep(std::time::Duration::from_millis(500)); + } + + eprintln!("{RED}Proxy didn't become healthy in 10s. Check logs:{NC}"); + let _ = Command::new("journalctl") + .args(["--user", "-u", SERVICE, "--no-pager", "-n", "20"]) + .status(); + std::process::exit(1); +} + +fn do_stop() { + let _ = systemctl(&["stop", SERVICE]); + println!("{YELLOW}Stopped.{NC}"); +} + +fn do_restart() { + println!("{YELLOW}Stopping...{NC}"); + do_stop(); + do_build(); + do_start(); +} + +fn do_status() { + println!("{BOLD}── Service ──{NC}"); + let output = Command::new("systemctl") + .args(["--user", "status", SERVICE, "--no-pager"]) + .output(); + match output { + Ok(o) => { + let text = String::from_utf8_lossy(&o.stdout); + // Print first 6 lines + for (i, line) in text.lines().enumerate() { + if i >= 6 { break; } + println!("{line}"); + } + } + Err(_) => println!("{RED}Not running{NC}"), + } + println!(); + + if !health_ok() { + println!("{RED}Proxy is not responding on port {PORT}.{NC}"); + std::process::exit(1); + } + + println!("{BOLD}── Quota ──{NC}"); + match curl_get("/v1/quota") { + Some(json) => jq_print(&json), + None => println!("{DIM}(no quota data){NC}"), + } + println!(); + + println!("{BOLD}── Usage ──{NC}"); + match curl_get("/v1/usage") { + Some(json) => jq_print(&json), + None => println!("{DIM}(no usage data){NC}"), + } + println!(); + + println!("{BOLD}── Sessions ──{NC}"); + match curl_get("/v1/sessions") { + Some(json) => jq_print(&json), + None => println!("{DIM}(no sessions){NC}"), + } +} + +fn do_logs(n: &str, follow: bool) { + let mut args = vec!["--user", "-u", SERVICE, "--no-pager", "-n", n]; + if follow { + args.push("-f"); + } + let _ = Command::new("journalctl") + .args(&args) + .stdin(Stdio::inherit()) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .status(); +} + +fn do_logs_all() { + let _ = Command::new("journalctl") + .args(["--user", "-u", SERVICE, "--no-pager"]) + .stdin(Stdio::inherit()) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .status(); +} + +fn do_test(msg: &str) { + println!("{CYAN}Testing:{NC} {msg}"); + let body = format!( + r#"{{"model":"gemini-3-flash","input":"{}","stream":false,"timeout":30}}"#, + msg.replace('"', r#"\""#) + ); + match curl_post("/v1/responses", &body) { + Some(json) => jq_print(&json), + None => { + eprintln!("{RED}Request failed. Is the proxy running?{NC}"); + std::process::exit(1); + } + } +} + +fn do_health() { + match curl_get("/health") { + Some(json) => { + jq_print(&json); + println!("{GREEN}Healthy{NC}"); + } + None => { + println!("{RED}Not responding{NC}"); + std::process::exit(1); + } + } +} diff --git a/src/constants.rs b/src/constants.rs index 4f55673..372d05a 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -185,7 +185,7 @@ pub fn log_base() -> String { /// Token file path. pub fn token_file_path() -> String { let home = std::env::var("HOME").unwrap_or_else(|_| "/root".to_string()); - format!("{home}/.config/antigravity-proxy-token") + format!("{home}/.config/zerogravity/token") } /// User-Agent string matching the Electron webview — computed once. diff --git a/src/main.rs b/src/main.rs index b6371e1..ab38620 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -//! Antigravity OpenAI Proxy — Rust edition v3 (stealth hardened). +//! ZeroGravity — Rust edition v3 (stealth hardened). //! //! Single-binary replacement for server.py. BoringSSL TLS impersonation, //! byte-exact protobuf encoding, Chrome header fingerprinting, cascade @@ -26,8 +26,8 @@ use mitm::store::MitmStore; #[derive(Parser)] #[command( - name = "antigravity-proxy", - about = "Antigravity OpenAI Proxy (stealth)" + name = "zerogravity", + about = "ZeroGravity — stealth LLM proxy" )] struct Cli { /// Port to listen on @@ -64,7 +64,7 @@ struct Cli { #[arg(long, conflicts_with = "headless")] classic: bool, - /// Disable per-call debug traces (on by default, writes JSON to ~/.config/antigravity-proxy/traces/) + /// Disable per-call debug traces (on by default, writes JSON to ~/.config/zerogravity/traces/) #[arg(long)] no_trace: bool, } @@ -236,12 +236,12 @@ async fn main() { let backend = Arc::new(if let Some((_, port, ref csrf)) = standalone_ls { // Build backend pointing at standalone LS - let oauth = std::env::var("ANTIGRAVITY_OAUTH_TOKEN") + let oauth = std::env::var("ZEROGRAVITY_TOKEN") .ok() .filter(|s| !s.is_empty()) .or_else(|| { let home = std::env::var("HOME").unwrap_or_default(); - let path = format!("{home}/.config/antigravity-proxy-token"); + let path = format!("{home}/.config/zerogravity/token"); std::fs::read_to_string(&path) .ok() .map(|s| s.trim().to_string()) @@ -282,7 +282,7 @@ async fn main() { let trace_collector = trace::TraceCollector::new(trace_enabled); if trace_enabled { trace_collector.cleanup_old_traces(7); - info!("Debug tracing enabled → ~/.config/antigravity-proxy/traces/"); + info!("Debug tracing enabled → ~/.config/zerogravity/traces/"); } let state = Arc::new(AppState { @@ -391,7 +391,7 @@ fn print_banner( let ver = crate::constants::antigravity_version(); println!(); - println!(" \x1b[1;35m>> antigravity-proxy\x1b[0m \x1b[2mv{ver}\x1b[0m"); + println!(" \x1b[1;35m>> zerogravity\x1b[0m \x1b[2mv{ver}\x1b[0m"); println!(" \x1b[2m────────────────────────────────────────────────\x1b[0m"); println!(); println!(" \x1b[1mcore\x1b[0m"); @@ -462,11 +462,11 @@ fn print_banner( if token == "NOT SET" { println!(" \x1b[1;33m[!]\x1b[0m no oauth token"); - println!(" export ANTIGRAVITY_OAUTH_TOKEN=ya29.xxx"); + println!(" export ZEROGRAVITY_TOKEN=ya29.xxx"); println!( " curl -X POST http://127.0.0.1:{port}/v1/token -d '{{\"token\":\"ya29.xxx\"}}'" ); - println!(" echo 'ya29.xxx' > ~/.config/antigravity-proxy-token"); + println!(" echo 'ya29.xxx' > ~/.config/zerogravity/token"); println!(); } } @@ -522,5 +522,5 @@ fn dirs_data_dir() -> std::path::PathBuf { let home = std::env::var("HOME").unwrap_or_else(|_| "/tmp".to_string()); std::path::PathBuf::from(home) .join(".config") - .join("antigravity-proxy") + .join("zerogravity") } diff --git a/src/standalone/mod.rs b/src/standalone/mod.rs index fe71562..bd2a8fd 100644 --- a/src/standalone/mod.rs +++ b/src/standalone/mod.rs @@ -24,13 +24,13 @@ const LS_BINARY_PATH: &str = const APP_ROOT: &str = "/usr/share/antigravity/resources/app"; /// Data directory for the standalone LS. -const DATA_DIR: &str = "/tmp/antigravity-standalone"; +const DATA_DIR: &str = "/tmp/zerogravity-standalone"; /// System user for UID-scoped iptables isolation. -const LS_USER: &str = "antigravity-ls"; +const LS_USER: &str = "zerogravity-ls"; /// Path for the compiled dns_redirect.so preload library. -const DNS_REDIRECT_SO_PATH: &str = "/tmp/antigravity-dns-redirect.so"; +const DNS_REDIRECT_SO_PATH: &str = "/tmp/zerogravity-dns-redirect.so"; /// Source file for the DNS redirect preload library (relative to binary). const DNS_REDIRECT_C_SOURCE: &str = include_str!("../mitm/dns_redirect.c"); diff --git a/src/standalone/spawn.rs b/src/standalone/spawn.rs index 8c537dd..49b9e23 100644 --- a/src/standalone/spawn.rs +++ b/src/standalone/spawn.rs @@ -57,9 +57,9 @@ impl StandaloneLS { 1, // DETECT_AND_USE_PROXY_ENABLED ); - // Setup data dir (mode 1777 so both current user and antigravity-ls can write) + // Setup data dir (mode 1777 so both current user and zerogravity-ls can write) let gemini_dir = format!("{DATA_DIR}/.gemini"); - let app_data_dir = format!("{DATA_DIR}/.gemini/antigravity-standalone"); + let app_data_dir = format!("{DATA_DIR}/.gemini/zerogravity-standalone"); let annotations_dir = format!("{app_data_dir}/annotations"); let brain_dir = format!("{app_data_dir}/brain"); for dir in [ @@ -77,7 +77,7 @@ impl StandaloneLS { } } // Check if data dir is writable by writing a test file. - // Old runs as `antigravity-ls` user leave dirs owned by that user. + // Old runs as `zerogravity-ls` user leave dirs owned by that user. let test_path = format!("{app_data_dir}/.write_test"); if std::fs::write(&test_path, b"ok").is_err() { eprintln!( @@ -138,12 +138,12 @@ impl StandaloneLS { }) .unwrap_or_else(|| { // Fall back to env var / token file - let token = std::env::var("ANTIGRAVITY_OAUTH_TOKEN") + let token = std::env::var("ZEROGRAVITY_TOKEN") .ok() .filter(|s| !s.is_empty()) .or_else(|| { let home = std::env::var("HOME").unwrap_or_default(); - let path = format!("{home}/.config/antigravity-proxy-token"); + let path = format!("{home}/.config/zerogravity/token"); std::fs::read_to_string(&path) .ok() .map(|s| s.trim().to_string()) @@ -153,7 +153,7 @@ impl StandaloneLS { if !token.is_empty() { info!("Loaded OAuth token from env/file (no refresh token — manual refresh needed)"); } else { - eprintln!("[headless] ⚠ No OAuth token found. Login to Antigravity first, or set ANTIGRAVITY_OAUTH_TOKEN"); + eprintln!("[headless] ⚠ No OAuth token found. Login to Antigravity first, or set ZEROGRAVITY_TOKEN"); } (token, None) }); @@ -224,7 +224,7 @@ impl StandaloneLS { "https://daily-cloudcode-pa.googleapis.com".to_string() }, "-app_data_dir".to_string(), - "antigravity-standalone".to_string(), + "zerogravity-standalone".to_string(), "-gemini_dir".to_string(), gemini_dir, ]; @@ -240,16 +240,16 @@ impl StandaloneLS { if let Some(mitm) = mitm_config { // Go's SSL_CERT_FILE replaces the entire system cert pool, so we // need a combined bundle: system CAs + our MITM CA - // Write to /tmp — accessible by antigravity-ls user + // Write to /tmp — accessible by zerogravity-ls user // (user's ~/.config/ is not traversable by other UIDs) - let combined_ca_path = "/tmp/antigravity-mitm-combined-ca.pem".to_string(); + let combined_ca_path = "/tmp/zerogravity-mitm-ca.pem".to_string(); let system_ca = std::fs::read_to_string("/etc/ssl/certs/ca-certificates.crt").unwrap_or_default(); let mitm_ca = std::fs::read_to_string(&mitm.ca_cert_path) .map_err(|e| format!("Failed to read MITM CA cert: {e}"))?; std::fs::write(&combined_ca_path, format!("{system_ca}\n{mitm_ca}")) .map_err(|e| format!("Failed to write combined CA bundle: {e}"))?; - // Make readable by antigravity-ls user + // Make readable by zerogravity-ls user #[cfg(unix)] { use std::os::unix::fs::PermissionsExt; @@ -286,18 +286,18 @@ impl StandaloneLS { env_vars.push(("LD_PRELOAD".into(), so)); env_vars.push(( "DNS_REDIRECT_LOG".into(), - "/tmp/antigravity-dns-redirect.log".into(), + "/tmp/zerogravity-dns-redirect.log".into(), )); } } } // In headless mode, never use sudo — run as current user - // In normal mode, use sudo if 'antigravity-ls' user exists + // In normal mode, use sudo if 'zerogravity-ls' user exists let use_sudo = !headless && has_ls_user(); let mut cmd = if use_sudo { - info!("Using UID isolation: spawning LS as 'antigravity-ls' user"); + info!("Using UID isolation: spawning LS as 'zerogravity-ls' user"); let mut c = Command::new("sudo"); c.args(["-n", "-u", LS_USER, "--", "/usr/bin/env"]); for (k, v) in &env_vars { @@ -317,7 +317,7 @@ impl StandaloneLS { }; // Capture stderr for debugging — logs to /tmp so we can diagnose LS failures - let stderr_file = std::fs::File::create("/tmp/antigravity-ls-debug.log") + let stderr_file = std::fs::File::create("/tmp/zerogravity-ls-debug.log") .map_err(|e| format!("Failed to create LS debug log: {e}"))?; cmd.stdin(Stdio::piped()) .stdout(Stdio::null()) @@ -342,7 +342,7 @@ impl StandaloneLS { let ls_pid = if use_sudo { // Give sudo a moment to spawn the real process std::thread::sleep(std::time::Duration::from_millis(500)); - // Find the LS process owned by antigravity-ls user + // Find the LS process owned by zerogravity-ls user find_ls_pid_for_user(LS_USER).ok() } else { Some(child.id()) @@ -424,7 +424,7 @@ impl StandaloneLS { // The child is sudo which already exited. Kill the actual LS. if let Some(pid) = self.ls_pid { info!(pid, "Killing LS process via sudo -u {}", LS_USER); - // Run kill AS the antigravity-ls user (same UID can signal) + // Run kill AS the zerogravity-ls user (same UID can signal) let ok = std::process::Command::new("sudo") .args(["-n", "-u", LS_USER, "kill", "-TERM", &pid.to_string()]) .stdout(Stdio::null()) diff --git a/src/trace.rs b/src/trace.rs index 6ca6625..1da4330 100644 --- a/src/trace.rs +++ b/src/trace.rs @@ -1,7 +1,7 @@ //! Per-call debug trace system. //! //! Every API call gets a structured JSON trace file written to -//! `~/.config/antigravity-proxy/traces/{YYYY-MM-DD}/{HH-MM-SS}_{cascade_short}.json`. +//! `~/.config/zerogravity/traces/{YYYY-MM-DD}/{HH-MM-SS}_{cascade_short}.json`. //! //! Designed for LLM consumption: compact, structured, no raw bodies. @@ -23,7 +23,7 @@ impl TraceCollector { let home = std::env::var("HOME").unwrap_or_else(|_| "/tmp".to_string()); let traces_dir = PathBuf::from(home) .join(".config") - .join("antigravity-proxy") + .join("zerogravity") .join("traces"); Self { enabled,