<p align="center">
  <img src="https://img.shields.io/badge/rust-1.75+-555?style=flat-square&logo=rust&logoColor=white" alt="Rust" />
  <img src="https://img.shields.io/badge/platform-linux%20%7C%20macos%20%7C%20windows-555?style=flat-square" alt="Platform" />
  <img src="https://img.shields.io/badge/license-MIT-333?style=flat-square" alt="License" />
  <img src="https://img.shields.io/badge/API-OpenAI%20%7C%20Gemini-666?style=flat-square" alt="API" />
  <img src="https://img.shields.io/badge/TLS-BoringSSL-444?style=flat-square" alt="TLS" />
  <img src="https://img.shields.io/badge/proxy-MITM-555?style=flat-square" alt="MITM" />
  <img src="https://img.shields.io/badge/stealth-JA3%2FJA4-333?style=flat-square" alt="Stealth" />
</p>

<h1 align="center">ZeroGravity</h1>

<p align="center">
  <img src="assets/logo.png" alt="ZeroGravity" width="200" />
</p>

<p align="center">
  OpenAI-compatible proxy that intercepts and relays requests to Google's Antigravity language server, impersonating the real Electron webview.
</p>

---

```mermaid
%%{init: {'theme': 'dark', 'themeVariables': {'primaryColor': '#2a2a2a', 'primaryTextColor': '#d0d0d0', 'primaryBorderColor': '#888', 'lineColor': '#888', 'secondaryColor': '#333', 'tertiaryColor': '#3a3a3a', 'edgeLabelBackground': '#2a2a2a', 'nodeTextColor': '#d0d0d0'}}}%%
graph LR
    Client["Client"] -->|"OpenAI / Gemini API"| Proxy["Proxy :8741"]
    Proxy -->|"gRPC (dummy prompt)"| LS["Standalone LS"]
    LS -->|"HTTPS :443"| MITM["MITM :8742"]
    MITM -->|"Modified request<br/>(real prompt + tools)"| Google["Google API"]
    Google -->|"SSE response"| MITM
    MITM -->|"Usage, errors,<br/>function calls"| Proxy
    LS -.->|"iptables redirect<br/>(UID-scoped)"| MITM

    style Proxy fill:#4a4a4a,color:#e0e0e0,stroke:#888
    style MITM fill:#3a3a3a,color:#e0e0e0,stroke:#888
    style LS fill:#505050,color:#e0e0e0,stroke:#888
    style Google fill:#444,color:#e0e0e0,stroke:#888
```

## Models

| Name                | Label                      | Notes               |
| ------------------- | -------------------------- | ------------------- |
| `opus-4.6`          | Claude Opus 4.6 (Thinking) | Default model       |
| `opus-4.5`          | Claude Opus 4.5 (Thinking) | —                   |
| `gemini-3-pro`      | Gemini 3 Pro (High)        | Default Pro tier    |
| `gemini-3-pro-high` | Gemini 3 Pro (High)        | Alias               |
| `gemini-3-pro-low`  | Gemini 3 Pro (Low)         | —                   |
| `gemini-3-flash`    | Gemini 3 Flash             | Recommended for dev |

## Quick Start

```bash
# Headless mode (no running Antigravity app needed)
RUST_LOG=info ./target/release/zerogravity --headless

# Or use the daemon manager
zg start
```

## Setup

### Linux

```bash
# Prerequisites: Rust toolchain, iptables
./scripts/setup-linux.sh
```

Creates a `zerogravity-ls` system user for UID-scoped iptables isolation, installs a systemd user service, and builds the release binary.

```bash
# Start the service
systemctl --user enable --now zerogravity

# Or use the daemon manager
zg start
```

### macOS

```bash
# Prerequisites: Rust toolchain
./scripts/setup-macos.sh
```

Installs a launchd plist for automatic startup. No UID isolation — runs in headless/HTTPS_PROXY mode only.

```bash
# Start the service
launchctl load ~/Library/LaunchAgents/com.zerogravity.proxy.plist

# Or use the daemon manager
zg start
```

### Windows

```powershell
# Prerequisites: Rust toolchain
# Run as Administrator
powershell -ExecutionPolicy Bypass -File scripts\setup-windows.ps1
```

Creates config directories, builds the release binary, and installs a scheduled task for automatic startup at logon.

```powershell
# Start now
schtasks /run /tn "ZeroGravity Proxy"

# Or manually
.\target\release\zerogravity.exe
```

## Endpoints

| Method     | Path                              | Description                           |
| ---------- | --------------------------------- | ------------------------------------- |
| `POST`     | `/v1/responses`                   | Responses API (sync + streaming)      |
| `POST`     | `/v1/chat/completions`            | Chat Completions API (OpenAI compat)  |
| `POST`     | `/v1beta/models/{model}:{action}` | Official Gemini v1beta routes         |
| `GET/POST` | `/v1/search`                      | Web Search via Google grounding (WIP) |
| `GET`      | `/v1/models`                      | List available models                 |
| `GET`      | `/v1/sessions`                    | List active sessions                  |
| `DELETE`   | `/v1/sessions/{id}`               | Delete a session                      |
| `POST`     | `/v1/token`                       | Set OAuth token at runtime            |
| `GET`      | `/v1/usage`                       | MITM-intercepted token usage          |
| `GET`      | `/v1/quota`                       | LS quota and rate limits              |
| `GET`      | `/health`                         | Health check                          |

## Authentication

The proxy needs an OAuth 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"}'`

<details>
<summary>How to get the token</summary>

1. Open Antigravity
2. Go to **Help** > **Toggle Developer Tools**
3. Send any prompt
4. In the **Network** tab, find a request to `generativelanguage.googleapis.com`
5. Copy the `Authorization: Bearer ya29.xxx...` header value

</details>

## `zg` Commands

| Command         | Description                    |
| --------------- | ------------------------------ |
| `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

| Doc                                                               | Contents                                                             |
| ----------------------------------------------------------------- | -------------------------------------------------------------------- |
| [architecture.md](docs/architecture.md)                           | System overview, module map, request lifecycle (mermaid)             |
| [mitm.md](docs/mitm.md)                                           | MITM proxy internals, event flow, request modification               |
| [traces.md](docs/traces.md)                                       | Per-call debug trace system                                          |
| [extension-server-analysis.md](docs/extension-server-analysis.md) | Extension server protocol reverse engineering                        |
| [ls-binary-analysis.md](docs/ls-binary-analysis.md)               | LS binary reverse engineering — model catalog, gRPC services, protos |

## License

[MIT](LICENSE)
