📡 Architecture Documentation

Antigravity Mobile
System Architecture

A Python-based remote monitoring and control system that lets you manage your AI coding assistant from your phone — monitor tasks, approve commands, switch models, and stream execution logs in real-time.

7
Python Modules
18
API Endpoints
2
WebSocket Channels
3
Communication Protocols

What is Antigravity Mobile?

A pip-installable CLI tool and FastAPI server that bridges the gap between a desktop AI coding agent (Antigravity IDE) and a mobile phone, enabling remote oversight and control.

📱
Mobile Dashboard
Glassmorphic dark-themed responsive UI with real-time system stats (CPU, RAM, Disk), agent console, and task management.
🔄
Bidirectional Control
Send prompts to the desktop agent from your phone. The agent streams its execution logs back in real-time via WebSocket.
Mobile Approvals
Approve or reject terminal commands requested by the desktop agent — directly from your phone, via a file-based handshake protocol.
🧠
Model Switcher
Hot-swap the active AI model (Gemini, Claude, GPT variants) in your Antigravity IDE by modifying the IDE settings file remotely.
Task Runner
Schedule, confirm, and monitor shell commands with thread-based subprocess execution, real-time log streaming, and cancellation support.
🔒
Security First
PIN authentication, token-based sessions with 24h TTL, rate-limited login (5 attempts / 15 min lockout), and path traversal protection.

System Architecture Diagram

The system follows a hub-and-spoke model with the FastAPI server at the center, mediating between the mobile client, the desktop AI agent, and the local filesystem.

🌐 External Access Layer
📱 Mobile Browser
index.html (glassmorphic SPA)
localtunnel / HTTPS
🌍 LocalTunnel Proxy
npx localtunnel --port 8000
HTTPWS REST + WebSocket
⚙️ Server Layer (FastAPI + Uvicorn)
🖥️ server.py
FastAPI App — 18 endpoints
FILE JSON files
PROC subprocess
HTTP polling
🔧 Internal Components
📄 File-Based IPC
remote_prompt.json, agent_status.json, etc.
🤖 Task Runner
task_runner.py — threaded subprocess mgr
👻 Agent Daemon
agent_daemon.py — long-poll listener
reads / writes workspace files
🧠 AI Agent Layer
🧠 Antigravity IDE Agent
Follows AGENTS.md rules + SKILL.md instructions
⚙️ IDE Settings
settings.json — model selection

Project Structure & Module Breakdown

Each module has a clear responsibility within the system. The package is pip-installable and exposes a single CLI entry point.

project structure
antigravity-mobile/
├── antigravity_remote/          # Main Python package
│   ├── __init__.py               # Package init, __version__ = "0.3.7"
│   ├── __main__.py               # python -m entry point → cli.main()
│   ├── cli.py                    # CLI: argparse, setup wizard, start, remote, daemon (799 lines)
│   ├── server.py                 # FastAPI app: REST API, WebSocket, auth, state (638 lines)
│   ├── agent_daemon.py           # Daemon: long-poll server for remote prompts (117 lines)
│   ├── agent_approve.py          # Approval helper: file-based + HTTP fallback (159 lines)
│   ├── task_runner.py            # Task lifecycle: schedule, run, cancel, log (212 lines)
│   └── templates/
│       └── index.html            # Mobile dashboard SPA (1397 lines, single-file)
├── .agents/
│   ├── AGENTS.md                 # Agent behavior rules for remote mode
│   └── skills/remote_control/
│       └── SKILL.md              # Step-by-step remote control loop skill
├── tests/
│   └── test_server.py            # pytest suite: auth, rate limits, traversal, lifecycle
├── pyproject.toml                # Build config, deps, CLI entry point
└── README.md                     # User-facing documentation
cli.py 799 lines
The main CLI module and entry point for the antigravity-mobile command. Built with Python's argparse, it provides 8 subcommands and a beautiful ASCII art welcome screen with ANSI coloring.
Key Functions
  • main() — argparse dispatcher, ANSI setup
  • cmd_setup() — 4-step setup wizard (PIN, agents, mode, PATH)
  • cmd_start() — regenerate PIN, kill port, launch uvicorn
  • cmd_run() — authenticate, schedule, confirm & stream a task
  • cmd_remote() — toggle remote_mode.json on/off
  • cmd_daemon() — start the agent_daemon listener
  • cmd_update()pip install --upgrade
  • cmd_uninstall() — cleanup files + guide pip uninstall
Platform Helpers
  • generate_config() — 6-digit PIN + 256-bit secret key
  • kill_port_process() — psutil + taskkill fallback
  • configure_windows_path() — winreg PATH modification
  • remove_windows_path() — clean PATH on uninstall
  • print_banner() — ASCII art with ANSI color codes
  • print_quickstart() — formatted quick-start guide
server.py 638 lines
The core FastAPI application that serves as the central hub. It manages authentication, system monitoring, task orchestration, model switching, remote prompts, and approval workflows — with both REST and WebSocket interfaces.
Core Responsibilities
  • PIN authentication → token-based sessions
  • Rate limiting (5 attempts / 15 min lockout)
  • Real-time system stats via psutil
  • Task scheduling, confirmation, cancellation
  • Remote prompt lifecycle management
  • File-based approval request/response
  • Model switching via IDE settings.json
  • WebSocket broadcast (status every 2s)
State Management
  • ACTIVE_SESSIONS — dict[token → timestamp], 24h TTL
  • LOGIN_ATTEMPTS — dict[IP → (count, time)]
  • REMOTE_PROMPT — in-memory prompt state machine
  • REMOTE_APPROVAL — in-memory approval state machine
  • TaskRunner — thread-safe task lifecycle manager
  • File polling: agent_status.json, agent_response.json, agent_approval_request.json
agent_daemon.py 117 lines
A lightweight long-polling daemon that bridges the server and the IDE agent. It runs as a background process, continuously checking for new remote prompts via the server API, and writes them to a local file when detected.
Execution Flow
  1. Check remote_mode.json — if disabled, sleep 5s and retry
  2. Read config.json for the access PIN
  3. Authenticate with the FastAPI server to get a session token
  4. Enter long-poll loop: GET /api/agent/prompt/check every 2s
  5. When a prompt is detected (status=pending), write it to remote_prompt.json
  6. Exit with code 0 — this triggers the IDE to wake the agent
agent_approve.py 159 lines
The command approval helper that implements a dual-channel confirmation protocol. It supports both file-based IPC (for silent operation) and HTTP API (for server-connected operation), with graceful offline fallback.
Exit Codes Protocol
0 APPROVED — proceed with command 1 REJECTED — skip the action 2 TIMEOUT — no response within timeout 3 OFFLINE — server unreachable, bypass to desktop
task_runner.py 212 lines
Thread-safe task lifecycle manager. Handles command scheduling, subprocess execution, real-time log streaming, cancellation, and persistent state via a JSON database.
Task Class
  • id — 8-char UUID prefix
  • command — shell command string
  • status — pending | running | completed | failed | cancelled
  • exit_code — subprocess return code
  • created_by — "remote" origin tag
Security Validations
  • Rejects empty commands
  • Max 2000 character limit
  • Null byte (\x00) detection
  • Control character filtering
  • Thread-safe locking on all state mutations
templates/index.html 1397 lines
A self-contained single-page application (SPA) served as the mobile dashboard. It uses vanilla HTML/CSS/JS with no framework dependencies — the entire UI, styling, and logic lives in one file.
UI Features
  • PIN authentication screen
  • Real-time system metrics (CPU/RAM/Disk gauges)
  • Agent status & execution log viewer
  • Task scheduler with confirm/cancel
  • Model switcher with limit indicators
  • Mobile approval dialog
  • Workspace file browser
Design System
  • Inter + JetBrains Mono fonts
  • Lucide icon library
  • Dark theme (#09090b base)
  • Glassmorphic card panels
  • WebSocket auto-reconnect
  • Mobile-first responsive (max 600px)

How It All Works Together

Three key workflows define the system's behavior: remote prompt execution, command approval, and real-time monitoring.

🚀 Flow 1: Remote Prompt Execution
1
User Sends Prompt from Phone
Mobile dashboard sends POST /api/agent/prompt with the task prompt. Server sets REMOTE_PROMPT status to "pending" and writes remote_prompt.json to disk.
2
Daemon Detects the Prompt
The agent_daemon.py process is long-polling GET /api/agent/prompt/check every 2 seconds. When it detects a pending prompt, it writes remote_prompt.json locally and exits with code 0.
3
IDE Agent Wakes Up
The daemon exit triggers the IDE to wake the AI agent. The agent reads remote_prompt.json, clears it, and begins executing the task following SKILL.md instructions.
4
Agent Streams Progress
During execution, the agent continuously updates agent_status.json and appends to agent_execution.log. The server reads these on each /api/status call or WebSocket tick.
5
Task Complete → Response
Agent writes agent_response.json with status + output. The server picks it up during the next status poll, updates REMOTE_PROMPT, and deletes the file. The mobile dashboard shows the response.
✅ Flow 2: Command Approval Protocol
1
Agent Needs Permission
Before executing a state-modifying command, the agent writes agent_approval_request.json with {"type": "command", "target": "..."}.
2
Server Detects Request
During the next get_system_status() call (triggered by WebSocket or REST), the server reads the approval request file, sets REMOTE_APPROVAL to "pending", and deletes the file from disk.
3
Mobile User Sees Approval Dialog
The WebSocket pushes the approval state to the phone. The dashboard renders an Approve/Reject dialog with the command details.
4
Decision Written to File
When the user taps Approve or Reject, POST /api/agent/approve/response is called. The server writes agent_approval_response.json with the decision.
5
Agent Reads Decision
The agent polls for agent_approval_response.json every 1.5 seconds. When found, it reads the status, deletes the file, and proceeds or aborts accordingly.
📡 Communication Protocols
HTTP REST API
Mobile → Server communication. 18 endpoints for auth, tasks, prompts, approvals, model switching. Bearer token auth on all protected routes.
WS WebSocket
Real-time push from Server → Mobile. Two channels: /ws/status (2s interval system broadcast) and /ws/logs/{id} (live task log streaming).
FILE File IPC
Server ↔ Agent communication via JSON files in the workspace. 6 signal files: remote_prompt, agent_status, agent_execution.log, agent_approval_request/response, agent_response.

REST & WebSocket Endpoints

Complete list of all 18 REST endpoints and 2 WebSocket channels exposed by the FastAPI server.

Method Endpoint Auth Description
POST /api/login Authenticate with PIN → receive session token. Rate limited: 5 attempts / 15 min.
GET /api/status Bearer System stats (CPU, RAM, Disk), agent status, last 20 log lines.
GET /api/workspace Bearer Directory tree of the workspace (3 levels deep, hidden files excluded).
GET /api/file?path= Bearer Read file contents. Protected against path traversal via os.path.realpath() containment check.
GET /api/tasks Bearer List all scheduled/running/completed tasks.
POST /api/schedule Bearer Schedule a new command task (status: pending). Input validated for null bytes, control chars, length.
POST /api/tasks/{id}/confirm Bearer Confirm and start executing a pending task in a background thread.
POST /api/tasks/{id}/cancel Bearer Cancel a pending or kill a running task (process tree termination).
GET /api/tasks/{id}/logs Bearer Get task log content, status, and exit code.
POST /api/tasks/summary Bearer Generate markdown summary of all tasks → writes summary.md.
GET /api/agent/status Bearer Current model, all available models, IDE limits, prompt & approval state.
POST /api/agent/model Bearer Switch active AI model in Antigravity IDE settings.
POST /api/agent/prompt Bearer Send a remote prompt to the desktop agent. Writes remote_prompt.json.
GET /api/agent/prompt/check Bearer Check/consume pending prompt (transitions status: pending → executing).
POST /api/agent/response Bearer Post agent's task response (status + output).
POST /api/agent/approve/request Bearer Post a new approval request (command/edit/create/delete).
GET /api/agent/approve/check Bearer Check current approval decision status.
POST /api/agent/approve/response Bearer Submit approval decision (approved/rejected). Writes agent_approval_response.json.
POST /api/shutdown Bearer Kill localtunnel proxy processes.
WS /ws/status?token= Query Real-time system status broadcast every 2 seconds. Includes tasks, agent info, model, limits.
WS /ws/logs/{id}?token= Query Live log streaming for a specific task. Tails the log file and streams new lines.

Security Model

Multi-layered security approach covering authentication, authorization, input validation, and path traversal protection.

🔒 Secure Authentication
  • 6-digit PIN generated via secrets.choice()
  • 256-bit hex secret key via secrets.token_hex(32)
  • PIN regenerated on every server start
  • Session token via secrets.token_hex(16)
  • 24-hour session TTL with automatic expiry
🛡️ Secure Rate Limiting
  • Max 5 failed login attempts per IP
  • 15-minute lockout after exceeding limit
  • Tracks via LOGIN_ATTEMPTS dict keyed by client IP
  • Auto-resets after lockout window expires
  • Successful login clears the counter
🗂️ Secure Path Traversal Protection
  • /api/file resolves paths with os.path.realpath()
  • Verifies resolved path starts with workspace base + os.sep
  • Prevents symlink escape attacks
  • Returns 403 for out-of-boundary access
⚠️ Caution Input Validation
  • Commands validated for null bytes (\x00)
  • ASCII control characters rejected (except \t, \n, \r)
  • 2000 character maximum command length
  • Empty command rejection
  • Note: Commands run with shell=True — relies on PIN auth as primary gate

Inter-Process Communication Files

The agent and server communicate through workspace JSON files. This is the "silent" protocol that avoids triggering desktop popups.

File Writer Reader Purpose
remote_prompt.json Server + Daemon Agent Carries the user's remote prompt from phone to agent. Cleared after read.
agent_status.json Agent Server Agent's current state: {"status": "working"|"idle", "task": "..."}
agent_execution.log Agent Server Append-only log of step-by-step agent execution thoughts (last 20 lines served).
agent_approval_request.json Agent Server Command approval request: {"type": "command", "target": "..."}. Deleted after server reads it.
agent_approval_response.json Server Agent Approval decision: {"status": "approved"|"rejected"}. Deleted after agent reads it.
agent_response.json Agent Server Final task response: {"status": "completed", "output": "..."}. Deleted after server reads it.
remote_mode.json CLI Agent + Daemon Feature toggle: {"enabled": true|false}. Controls whether remote features are active.
config.json CLI Server + Daemon + Approve Access credentials: {"pin": "...", "secret_key": "..."}. Regenerated on every server start.

Dependencies & Technology

FastAPI
Web Framework
Uvicorn
ASGI Server
psutil
System Monitor
Jinja2
Templates
pyproject.toml — dependencies
# Runtime dependencies
fastapi>=0.100.0      # Async web framework with auto OpenAPI docs
uvicorn>=0.22.0       # Lightning-fast ASGI server
jinja2>=3.1.0         # Template engine (available but templates are inline)
websockets>=11.0      # WebSocket protocol support
psutil>=5.9.0         # Cross-platform system monitoring

# Dev dependencies
pytest>=7.0.0         # Test framework
httpx>=0.24.0         # Async HTTP client for testing

# stdlib (no install needed)
argparse              # CLI argument parsing
secrets               # Cryptographic random generation
threading             # Thread-based task execution
subprocess            # Shell command execution
urllib.request        # Daemon/approve HTTP calls (no requests dep)

Test Coverage

The test suite uses pytest with FastAPI's TestClient to validate authentication, authorization, security, and task lifecycle.

Test Cases (7 tests)
  • test_login_invalid_pin — 401 on wrong PIN
  • test_login_success — valid token returned
  • test_unauthorized_endpoints — 401/403 without auth
  • test_authorized_status — system stats returned
  • test_login_rate_limiting — 429 after 5 failures
  • test_session_expiry — 401 on expired token
  • test_path_traversal_protection — 403 on ../
Additional Validations
  • test_command_validation — null bytes, control chars, length
  • test_task_lifecycle — schedule → confirm → run → logs
  • Cleanup fixture with autouse=True
  • Session and rate limit state reset between tests
  • Test config with known PIN 999999