10 Commits

Author SHA1 Message Date
trifatale
511c486a5e fix: add macOS DNS redirect preload for MITM
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-18 13:22:59 -09:00
trifatale
7982aebcd7 fix: improve macOS LS path detection
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-18 13:22:50 -09:00
Nikketryhard
e1ea22c7f0 feat: add discussion link about open source status to README 2026-02-18 14:45:41 -06:00
Nikketryhard
45b5cc15e0 refactor: remove automatic service/task installation from Linux, macOS, and Windows setup scripts. 2026-02-18 13:54:43 -06:00
Nikketryhard
9f36cc81d7 feat: Add GitHub issue templates for bug reports and feature requests. 2026-02-18 13:53:32 -06:00
Louie
6fd7cf6618 fix: add Antigravity prereq check to all setup scripts (#7)
All three setup scripts (Linux, macOS, Windows) now verify that the
Antigravity app is installed and the LS binary exists before proceeding.
Fails early with a clear error message and suggestions instead of a
cryptic runtime crash.

Closes #5
2026-02-18 13:17:31 -06:00
Louie
4966d8f648 Merge pull request #6 from Kazuki-0147/fix/headless-timeout
fix: avoid HTTPS_PROXY conflict with DNS redirect in headless mode
2026-02-18 13:08:43 -06:00
Kazuki-0147
60d7cd677e fix: avoid HTTPS_PROXY when DNS redirect is active in headless mode
When LD_PRELOAD DNS redirect is active, setting HTTPS_PROXY causes Go's
net/http to send HTTP CONNECT requests through the MITM proxy. However,
the MITM proxy expects direct TLS connections for SNI-based interception,
not CONNECT tunneling. This mismatch causes all non-gRPC calls (OAuth
token refresh, fetchUserInfo, etc.) to fail with EOF/timeout errors.

Changes:
- Only set HTTPS_PROXY/HTTP_PROXY as fallback when DNS redirect SO is
  not available
- Add GODEBUG=netdns=cgo to force Go's cgo (libc) DNS resolver, since
  the pure-Go resolver bypasses LD_PRELOAD getaddrinfo() hooks entirely

Fixes #4
2026-02-18 19:00:53 +00:00
Nikketryhard
03f44bc126 docs: document additional LS services, memory system, cascade configurations, supercomplete features, and browser automation policies. 2026-02-18 12:59:48 -06:00
Nikketryhard
29bebd79ea docs: add OS compatibility note to early stage warning 2026-02-18 04:16:02 -06:00
10 changed files with 860 additions and 133 deletions

102
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@@ -0,0 +1,102 @@
name: Bug Report
description: Something isn't working right
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for reporting! Please fill out the info below so we can debug faster.
- type: input
id: os
attributes:
label: Operating System
description: e.g. Ubuntu 24.04, macOS 15.2, Windows 11
placeholder: Ubuntu 24.04
validations:
required: true
- type: dropdown
id: mode
attributes:
label: Running Mode
description: How are you running ZeroGravity?
options:
- Headless (default, --headless)
- Classic (--classic, attached to running Antigravity)
- No MITM (--no-mitm)
validations:
required: true
- type: input
id: version
attributes:
label: ZeroGravity Version / Commit
description: "Output of `git rev-parse --short HEAD` or the version you downloaded"
placeholder: 4966d8f
validations:
required: true
- type: input
id: model
attributes:
label: Model Used
description: Which model were you using when the issue occurred?
placeholder: gemini-3-flash
- type: textarea
id: description
attributes:
label: What happened?
description: Describe the issue clearly. What did you expect vs what actually happened?
validations:
required: true
- type: textarea
id: logs
attributes:
label: Logs
description: |
Paste relevant log output. You can get logs with:
- `zg logs-all` (full logs)
- `journalctl --user -u zerogravity --no-pager -n 200` (systemd)
- Or check `~/.config/zerogravity/` for log files
render: text
- type: textarea
id: trace
attributes:
label: Call Trace
description: |
If available, paste the trace summary for the failing request.
Traces are saved to `~/.config/zerogravity/traces/YYYY-MM-DD/`.
You can get the latest one with:
```
TRACE_DIR=~/.config/zerogravity/traces/$(date +%Y-%m-%d)
cat "$TRACE_DIR/$(ls -t "$TRACE_DIR" | head -1)/summary.md"
```
render: markdown
- type: textarea
id: health
attributes:
label: Health Check Output
description: |
Paste the output of:
```
curl -s http://localhost:8741/health | jq .
zg status
```
render: json
- type: textarea
id: repro
attributes:
label: Steps to Reproduce
description: How can we reproduce this? Include the curl command or client config if applicable.
- type: textarea
id: extra
attributes:
label: Additional Context
description: Anything else — screenshots, network setup (VPN/proxy), Antigravity version, etc.

View File

@@ -0,0 +1,23 @@
name: Feature Request
description: Suggest an idea or improvement
labels: ["enhancement"]
body:
- type: textarea
id: description
attributes:
label: What do you want?
description: Describe the feature or improvement you'd like to see.
validations:
required: true
- type: textarea
id: usecase
attributes:
label: Use Case
description: Why do you need this? What problem does it solve?
- type: textarea
id: alternatives
attributes:
label: Alternatives Considered
description: Any workarounds or alternative approaches you've tried?

View File

@@ -20,8 +20,12 @@
> **Early stage.** Ran this on OpenCode with an Ultra account for 3 days straight, stress testing the whole time. No issues so far. For comparison, a Pro account got banned after about 3 hours using CLIProxyAPI / Antigravity Manager. Not using a firewall since I'm living overseas, so your situation may vary if google detects any suspicious activity. PS: The tool call part is still unstable and may hang sometimes. > **Early stage.** Ran this on OpenCode with an Ultra account for 3 days straight, stress testing the whole time. No issues so far. For comparison, a Pro account got banned after about 3 hours using CLIProxyAPI / Antigravity Manager. Not using a firewall since I'm living overseas, so your situation may vary if google detects any suspicious activity. PS: The tool call part is still unstable and may hang sometimes.
> >
> This software is developed on Linux. I aim to support every OS as best as possible, so if there is any issue please open an issue and I will be happy to assist.
>
> Star the repo so more people can find it while it still works. Issues and PRs are welcome. > Star the repo so more people can find it while it still works. Issues and PRs are welcome.
> **Should this stay open source?** [I need your help. Read the discussion and share your thoughts.](https://github.com/NikkeTryHard/zerogravity/discussions/10)
--- ---
## Skip Reading This — It's the Age of AI ## Skip Reading This — It's the Age of AI

View File

@@ -505,6 +505,76 @@ Team/organization management. Handles licensing, seats, credits.
- `UpdateCascadeWebSearchEnabled` — toggle web search - `UpdateCascadeWebSearchEnabled` — toggle web search
- `SetUserApiProviderKey` — BYOK key management - `SetUserApiProviderKey` — BYOK key management
### AnalyticsService (7+ methods)
Separate analytics service for recording telemetry and training data.
```
BatchRecordCompletions
BatchRecordPrompts
RecordCommandUsage
RecordCompletions
RecordContextToPrompt
RecordCortexTrajectory
RecordCortexTrajectoryStep
```
**Notable:** Distinct from `ApiServerService.Record*` — likely a dedicated analytics pipeline.
### UserAnalyticsService (5+ methods)
Per-user analytics dashboard service.
```
Analytics
CascadeAnalytics
GetAnalytics
GetPreferredTimeZone
UserPageAnalytics
```
### KnowledgeBaseService (17+ methods)
Enterprise knowledge base with multi-source ingestion. Uses OpenSearch backend.
```
AddGithubUsers
AddUsers
CancelKnowledgeBaseJobs
ConnectKnowledgeBaseAccount
DeleteKnowledgeBaseConnection
ForwardSlackPayload
GetConnectorInternalConfig
GetKnowledgeBaseConnectorState
GetKnowledgeBaseItemsFromScopeItems
GetKnowledgeBaseJobStates
GetKnowledgeBaseScopeItems
GetKnowledgeBaseWebhookUrl
IngestGithubData
IngestGoogleDriveData
IngestJiraData
IngestJiraPayload
IngestSlackData
IngestSlackPayload
KnowledgeBaseSearch
UpdateConnectorConfig
```
**Key insight:** Supports ingesting from **GitHub**, **Google Drive**, **Jira**, and **Slack** — full enterprise knowledge integration.
### CodeIndexService (4+ methods)
Code search and indexing. Uses OpenSearch for hybrid vector+keyword search.
```
GraphSearch
HybridSearch
OpenSearchAddRepository
OpenSearchGetIndex
```
**Notable:** `GraphSearch` suggests code graph traversal, `HybridSearch` combines vector embeddings with keyword matching.
### ModelManagementService (8 methods) ### ModelManagementService (8 methods)
Self-hosted model management for hybrid deployments. Self-hosted model management for hybrid deployments.
@@ -935,6 +1005,539 @@ https://iamcredentials.googleapis.com/v1/ ← Service account impersonation
--- ---
## Memory & Brain System
The LS has a sophisticated memory system that persists across conversations.
### Memory Sources
```
MEMORY_SOURCE_UNSPECIFIED
MEMORY_SOURCE_USER — manually created by user
MEMORY_SOURCE_CASCADE — extracted from cascade conversations
MEMORY_SOURCE_AUTO_CASCADE — automatically generated from cascades
```
### Memory Triggers
```
MEMORY_TRIGGER_UNSPECIFIED
MEMORY_TRIGGER_ALWAYS_ON — always active
MEMORY_TRIGGER_GLOB — glob pattern match on file paths
MEMORY_TRIGGER_MANUAL — only when explicitly invoked
MEMORY_TRIGGER_MODEL_DECISION — model decides when to use
```
### Memory Actions
```
MEMORY_ACTION_TYPE_UNSPECIFIED
MEMORY_ACTION_TYPE_CREATE
MEMORY_ACTION_TYPE_UPDATE
MEMORY_ACTION_TYPE_DELETE
```
### Brain Entry Types
```
BRAIN_ENTRY_TYPE_UNSPECIFIED
BRAIN_ENTRY_TYPE_PLAN — implementation plans
BRAIN_ENTRY_TYPE_TASK — task checklists
```
### Brain Update Triggers
```
BRAIN_UPDATE_TRIGGER_UNSPECIFIED
BRAIN_UPDATE_TRIGGER_USER_REQUESTED — user explicitly asks
BRAIN_UPDATE_TRIGGER_USER_NEW_INFO — user provides new info
BRAIN_UPDATE_TRIGGER_RESEARCH_NEW_INFO — research discovers new info
BRAIN_UPDATE_TRIGGER_SYSTEM_FORCED — system-initiated update
```
### Brain Filter Strategies
```
BRAIN_FILTER_STRATEGY_UNSPECIFIED
BRAIN_FILTER_STRATEGY_NO_MEMORIES — exclude all memories
BRAIN_FILTER_STRATEGY_NO_SYSTEM_INJECTED_STEPS — exclude system steps
```
---
## Expanded Cascade Configuration Keys
Full list of all cascade config keys extracted from binary (60+ keys):
### Core Behavior
```
CASCADE_ENFORCE_QUOTA — quota enforcement toggle
CASCADE_BASE_MODEL_ID — default model selection
CASCADE_DEFAULT_MODEL_OVERRIDE — model override
CASCADE_GLOBAL_CONFIG_OVERRIDE — global cascade config
CASCADE_MEMORY_CONFIG_OVERRIDE — memory subsystem config
CASCADE_PLAN_BASED_CONFIG_OVERRIDE — planner config
CASCADE_FREE_CONFIG_OVERRIDE — free-tier config
```
### Tool Access
```
CASCADE_ENABLE_MCP_TOOLS — MCP tool use
CASCADE_ANTIGRAVITY_BROWSER_TOOLS_ENABLED
CASCADE_ENABLE_PROXY_WEB_SERVER — proxy web server
CASCADE_ENABLE_IDE_TERMINAL_EXECUTION
CASCADE_VIEW_FILE_TOOL_CONFIG_OVERRIDE
CASCADE_USE_REPLACE_CONTENT_EDIT_TOOL
```
### Web Search
```
CASCADE_WEB_SEARCH_TOOL_ENABLED
CASCADE_WEB_SEARCH_TOOL_DISABLED
CASCADE_WEB_SEARCH_TOOL_UNSPECIFIED
CASCADE_WEB_APP_DEPLOYMENTS_ENABLED
```
### Extension Code Execution
```
CASCADE_RUN_EXTENSION_CODE_ENABLED
CASCADE_RUN_EXTENSION_CODE_DISABLED
CASCADE_RUN_EXTENSION_CODE_ONLY
CASCADE_RUN_EXTENSION_CODE_AUTO_RUN_ENABLED
CASCADE_RUN_EXTENSION_CODE_AUTO_RUN_MODEL_DECIDES
CASCADE_RUN_EXTENSION_CODE_AUTO_RUN_UNSPECIFIED
```
### Command Auto-Execution Policy
```
CASCADE_COMMANDS_AUTO_EXECUTION_UNSPECIFIED
CASCADE_COMMANDS_AUTO_EXECUTION_OFF — always ask
CASCADE_COMMANDS_AUTO_EXECUTION_AUTO — auto-run safe commands
CASCADE_COMMANDS_AUTO_EXECUTION_EAGER — auto-run most commands
```
### Memory & Learning
```
CASCADE_ENABLE_AUTOMATED_MEMORIES — auto-generate memories
CASCADE_USER_MEMORIES_IN_SYS_PROMPT
CASCADE_ENABLE_CUSTOM_RECIPES
CASCADE_BACKGROUND_RESEARCH_CONFIG_OVERRIDE
CASCADE_USE_EXPERIMENT_CHECKPOINTER
CASCADE_USE_SUBAGENT_CHECKPOINTER
```
### Autocomplete & Input
```
CASCADE_INPUT_AUTOCOMPLETE_ENABLED
CASCADE_INPUT_AUTOCOMPLETE_DISABLED
CASCADE_INPUT_AUTOCOMPLETE_UNSPECIFIED
CASCADE_RECIPES_AT_MENTION_VISIBILITY
```
### Run Status
```
CASCADE_RUN_STATUS_UNSPECIFIED
CASCADE_RUN_STATUS_IDLE
CASCADE_RUN_STATUS_BUSY
CASCADE_RUN_STATUS_RUNNING
CASCADE_RUN_STATUS_CANCELING
```
### Edit Importance (for code diffs)
```
CASCADE_EDIT_IMPORTANCE_UNSPECIFIED
CASCADE_EDIT_IMPORTANCE_LOW
CASCADE_EDIT_IMPORTANCE_MEDIUM
CASCADE_EDIT_IMPORTANCE_HIGH
```
### Seat Types
```
CASCADE_SEAT_TYPE_UNSPECIFIED
CASCADE_SEAT_TYPE_ENTRY — entry tier
CASCADE_SEAT_TYPE_STANDARD — standard tier
```
---
## Supercomplete (Tab Completion) System
The "Supercomplete" system powers multi-line tab completions, distinct from basic autocomplete.
### Trigger Conditions
```
SUPERCOMPLETE_TRIGGER_CONDITION_UNSPECIFIED
SUPERCOMPLETE_TRIGGER_CONDITION_TYPING
SUPERCOMPLETE_TRIGGER_CONDITION_AUTOCOMPLETE_ACCEPT
SUPERCOMPLETE_TRIGGER_CONDITION_AUTOCOMPLETE_PREDICTIVE
SUPERCOMPLETE_TRIGGER_CONDITION_SUPERCOMPLETE_ACCEPT
SUPERCOMPLETE_TRIGGER_CONDITION_SUPERCOMPLETE_PREDICTIVE
SUPERCOMPLETE_TRIGGER_CONDITION_TAB_JUMP_ACCEPT
SUPERCOMPLETE_TRIGGER_CONDITION_TAB_JUMP_EDIT
SUPERCOMPLETE_TRIGGER_CONDITION_TAB_JUMP_PREDICTIVE
SUPERCOMPLETE_TRIGGER_CONDITION_CURSOR_LINE_NAVIGATION
SUPERCOMPLETE_TRIGGER_CONDITION_FORCED
```
### Filters
```
SUPERCOMPLETE_FILTER_PREFIX_MATCH
SUPERCOMPLETE_FILTER_SUFFIX_MATCH
SUPERCOMPLETE_FILTER_INSERTION_CAP
SUPERCOMPLETE_FILTER_DELETION_CAP
SUPERCOMPLETE_FILTER_NO_OP
SUPERCOMPLETE_FILTER_REVERT
SUPERCOMPLETE_FILTER_PREVIOUSLY_SHOWN
SUPERCOMPLETE_FILTER_WHITESPACE_ONLY
SUPERCOMPLETE_FILTER_SCORE_THRESHOLD
```
### Config Keys
```
SUPERCOMPLETE_TEMPERATURE
SUPERCOMPLETE_MODEL_CONFIG
SUPERCOMPLETE_LINE_RADIUS
SUPERCOMPLETE_MIN_SCORE
SUPERCOMPLETE_MAX_INSERTIONS
SUPERCOMPLETE_MAX_DELETIONS
SUPERCOMPLETE_MAX_TRAJECTORY_STEPS
SUPERCOMPLETE_MAX_TRAJECTORY_STEP_SIZE
SUPERCOMPLETE_MAX_CONCURRENT_REQUESTS
SUPERCOMPLETE_FAST_DEBOUNCE
SUPERCOMPLETE_REGULAR_DEBOUNCE
SUPERCOMPLETE_RECENT_STEPS_DURATION
SUPERCOMPLETE_USE_CODE_DIAGNOSTICS
SUPERCOMPLETE_CODE_DIAGNOSTICS_TOP_K
SUPERCOMPLETE_DIAGNOSTIC_SEVERITY_THRESHOLD
SUPERCOMPLETE_DISABLE_TYPING_CACHE
SUPERCOMPLETE_DONT_FILTER_MID_STREAMED
SUPERCOMPLETE_ALWAYS_USE_CACHE_ON_EQUAL_STATE
SUPERCOMPLETE_CACHE_ON_PARENT_ID_KILL_SWITCH
SUPERCOMPLETE_ON_ACCEPT_ONLY
SUPERCOMPLETE_PRUNE_RESPONSE
SUPERCOMPLETE_PRUNE_MAX_INSERT_DELETE_LINE_DELTA
SUPERCOMPLETE_INLINE_PURE_DELETE
SUPERCOMPLETE_INLINE_RICH_GHOST_TEXT_INSERTIONS
SUPERCOMPLETE_USE_CURRENT_LINE
SUPERCOMPLETE_NO_ACTIVE_NODE
```
### Tab Jump (Cursor Navigation)
```
TAB_JUMP_ENABLED
TAB_JUMP_LINE_RADIUS
TAB_JUMP_CUMULATIVE_PROMPT_CONFIG
TAB_JUMP_FILTER_IN_SELECTION
TAB_JUMP_FILTER_INSERTION_CAP
TAB_JUMP_FILTER_DELETION_CAP
TAB_JUMP_FILTER_SCORE_THRESHOLD
TAB_JUMP_FILTER_WHITESPACE_ONLY
TAB_JUMP_FILTER_NO_OP
TAB_JUMP_FILTER_REVERT
TAB_JUMP_STOP_TOKEN_MIDSTREAM
TAB_JUMP_ON_ACCEPT_ONLY
TAB_JUMP_PRUNE_RESPONSE
TAB_JUMP_PRUNE_MAX_INSERT_DELETE_LINE_DELTA
TAB_JUMP_MIN_FILTER_RADIUS
```
---
## Browser Automation Policies
### JS Execution Policy (user can control)
```
BROWSER_JS_EXECUTION_POLICY_UNSPECIFIED
BROWSER_JS_EXECUTION_POLICY_ALWAYS_ASK
BROWSER_JS_EXECUTION_POLICY_MODEL_DECIDES
BROWSER_JS_EXECUTION_POLICY_TURBO — never ask
BROWSER_JS_EXECUTION_POLICY_DISABLED
```
### JS Auto-Run Policy (cascade-level)
```
BROWSER_JS_AUTO_RUN_POLICY_UNSPECIFIED
BROWSER_JS_AUTO_RUN_POLICY_ENABLED
BROWSER_JS_AUTO_RUN_POLICY_DISABLED
BROWSER_JS_AUTO_RUN_POLICY_MODEL_DECIDES
```
### Browser Subagent Mode
```
BROWSER_SUBAGENT_MODE_UNSPECIFIED
BROWSER_SUBAGENT_MODE_MAIN_AGENT_ONLY
BROWSER_SUBAGENT_MODE_SUBAGENT_ONLY
BROWSER_SUBAGENT_MODE_SUBAGENT_PRIMARILY
BROWSER_SUBAGENT_MODE_BOTH_AGENTS
```
### Tool Set Mode (input/output level)
```
BROWSER_TOOL_SET_MODE_UNSPECIFIED
BROWSER_TOOL_SET_MODE_ALL_TOOLS
BROWSER_TOOL_SET_MODE_PIXEL_ONLY
BROWSER_TOOL_SET_MODE_ALL_INPUT_PIXEL_OUTPUT
```
### Ephemeral Options (what gets captured)
```
BROWSER_EPHEMERAL_OPTION_UNSPECIFIED
BROWSER_EPHEMERAL_OPTION_DOM
BROWSER_EPHEMERAL_OPTION_SCREENSHOT
```
### Action Waiting Reasons
```
BROWSER_ACTION_WAITING_REASON_UNSPECIFIED
BROWSER_ACTION_WAITING_REASON_PAGE_ACCESS
BROWSER_ACTION_WAITING_REASON_ACTION_PERMISSION
BROWSER_ACTION_WAITING_REASON_PAGE_ACCESS_AND_ACTION_PERMISSION
```
### Installation Status
```
BROWSER_INSTALLATION_STATUS_UNSPECIFIED
BROWSER_INSTALLATION_STATUS_NOT_INSTALLED
BROWSER_INSTALLATION_STATUS_IN_PROGRESS
BROWSER_INSTALLATION_STATUS_COMPLETE
BROWSER_INSTALLATION_STATUS_ERROR
```
---
## Sandbox System (macOS Seatbelt)
The LS includes a `sandbox-wrapper.sh` that sandboxes command execution on macOS using Apple's Seatbelt framework.
### Key Behaviors
- **File writes**: Denied by default, allowed only to workspace dir and `/tmp`
- **Network**: Denied unless `--allow-network` flag is passed
- **Gitignore**: Reads `.gitignore` and `.agyignore` to deny access to ignored files
- **Process isolation**: Uses `sandbox-exec` with a generated Seatbelt profile
- **Violation detection**: Detects "Operation not permitted" errors and suggests disabling sandbox
### `.agyignore` File
Custom ignore file (like `.gitignore`) specifically for the sandbox. Patterns in `.agyignore` deny both read and write access within the sandbox.
---
## Trainer / RLHF Infrastructure
The binary contains extensive proto definitions for model training, suggesting the LS participates in or configures training runs.
### Proto Package: `exa.trainer_pb`
**Training Objectives:**
```
DPOConfig — Direct Preference Optimization
KTOConfig — Kahneman-Tversky Optimization
OnPolicyGRPOConfig — Group Relative Policy Optimization
KnowledgeDistillationConfig
PreferenceLoss — preference-based loss functions
```
**Model Architecture:**
```
BaseModelConfig
EncoderDecoderModelConfig
MixtureOfExpertsConfig — MoE architecture
MultiLatentAttentionConfig — MLA (DeepSeek-style?)
MultiTokenPredictionConfig
CrossAttentionConfig
SlidingWindowAttentionConfig
```
**Quantization:**
```
QuantizationConfig
QuantizationMethod
QuantizationPrecision
QuantizationPolicy / PolicySet
LinearQuantization
LayerNormQuantization
```
**Training Infrastructure:**
```
OptimizerType / OptimizerExpAvgDtype
CheckpointBackend (TORCH_DCP, ZARR)
ParallelismConfig / LayerParallelismConfig
RoPEEmbeddingConfig (Llama, DeepseekV scaling)
SGLangInferenceProviderConfig
MockedInferenceProviderConfig
```
**Experiment Management:**
```
ExperimentProject / ExperimentMetadata
SweepAxis / SweepItem
ScheduledModel / SchedulingGroupConfig
DeviceWorkerRoutingInfo
DraftTargetModelPair — speculative decoding?
```
### Key Proto Packages
```
exa.cortex_pb — agent/cascade core
exa.chat_pb — chat message/conversation protos
exa.trainer_pb — training/RLHF
exa.analytics_pb — telemetry
exa.api_server_pb — cloud API server
exa.seat_management_pb — user/team management
exa.user_analytics_pb — user analytics
exa.opensearch_clients_pb — knowledge base / code index
exa.language_server_pb — LS service
exa.extension_server_pb — extension server
exa.model_management_pb — model management
```
---
## MCP Integration Constants
```
MCP_SERVER_STATUS_UNSPECIFIED
MCP_SERVER_STATUS_PENDING
MCP_SERVER_STATUS_READY
MCP_SERVER_STATUS_ERROR
MCP_ADD_SERVER
MCP_SAVE_CONFIG
MCP_EXPAND_TOOLS
MCP_TOOL
MCP_RESOURCE
```
---
## Cortex Step Statuses
```
CORTEX_STEP_STATUS_UNSPECIFIED
CORTEX_STEP_STATUS_PENDING
CORTEX_STEP_STATUS_QUEUED
CORTEX_STEP_STATUS_GENERATING
CORTEX_STEP_STATUS_RUNNING
CORTEX_STEP_STATUS_WAITING
CORTEX_STEP_STATUS_DONE
CORTEX_STEP_STATUS_ERROR
CORTEX_STEP_STATUS_CANCELED
CORTEX_STEP_STATUS_CLEARED
CORTEX_STEP_STATUS_HALTED
CORTEX_STEP_STATUS_INTERRUPTED
CORTEX_STEP_STATUS_INVALID
```
### Step Sources
```
CORTEX_STEP_SOURCE_UNSPECIFIED
CORTEX_STEP_SOURCE_MODEL — generated by LLM
CORTEX_STEP_SOURCE_SYSTEM — system-generated
CORTEX_STEP_SOURCE_SYSTEM_SDK — SDK-generated
CORTEX_STEP_SOURCE_USER_EXPLICIT — user-initiated
CORTEX_STEP_SOURCE_USER_IMPLICIT — implied by user action
```
### Step Credit Reasons
```
CORTEX_STEP_CREDIT_REASON_UNSPECIFIED
CORTEX_STEP_CREDIT_REASON_LINT_FIXING_DISCOUNT — lint fixes are discounted
```
### Manager Feedback Status
```
CORTEX_STEP_MANAGER_FEEDBACK_STATUS_UNSPECIFIED
CORTEX_STEP_MANAGER_FEEDBACK_STATUS_APPROVED
CORTEX_STEP_MANAGER_FEEDBACK_STATUS_DENIED
CORTEX_STEP_MANAGER_FEEDBACK_STATUS_ERROR
```
### Error Categories
```
CORTEX_ERROR_CATEGORY_UNSPECIFIED
CORTEX_ERROR_CATEGORY_OVERALL
CORTEX_ERROR_CATEGORY_ACTION_PREPARE
CORTEX_ERROR_CATEGORY_ACTION_APPLY
```
### Compile Tools (Lint Integration)
```
CORTEX_STEP_COMPILE_TOOL_UNSPECIFIED
CORTEX_STEP_COMPILE_TOOL_PYLINT
```
---
## Onboarding Flow
```
ONBOARDING_PROGRESS_UNKNOWN
ONBOARDING_PROGRESS_NONE
ONBOARDING_PROGRESS_ELIGIBLE
ONBOARDING_PROGRESS_ONBOARDED
ONBOARDING_ACTION_TYPE_UNSPECIFIED
ONBOARDING_ACTION_TYPE_CHAT
ONBOARDING_ACTION_TYPE_AUTOCOMPLETE
ONBOARDING_ACTION_TYPE_COMMAND
ONBOARDING_PAGE_TYPE_UNSPECIFIED
ONBOARDING_PAGE_TYPE_HOTKEY
ONBOARDING_PAGE_TYPE_LENS
ONBOARDING_PAGE_TYPE_SEARCH
```
**Onboarding pages discovered:**
```
ONBOARDING_LANDING_PAGE_OPENED
ONBOARDING_AUTH_PAGE_OPENED
ONBOARDING_AUTH_MANUAL_PAGE_OPENED
ONBOARDING_CHOOSE_THEME_PAGE_OPENED
ONBOARDING_KEYBINDINGS_PAGE_OPENED
ONBOARDING_AGENT_CONFIG_PAGE_OPENED
ONBOARDING_IMPORT_PAGE_OPENED
ONBOARDING_MIGRATION_SCOPE_PAGE_OPENED
ONBOARDING_SETUP_PAGE_OPENED
ONBOARDING_TERMS_OF_USE_PAGE_OPENED
ONBOARDING_USAGE_MODE_PAGE_OPENED
```
---
## Protobuf Enum Numbers (from extension.js) ## Protobuf Enum Numbers (from extension.js)
Extracted from the compiled protobuf enum definitions in `extension.js`. Extracted from the compiled protobuf enum definitions in `extension.js`.

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# ZeroGravity — Linux setup # ZeroGravity — Linux setup
# Creates the zerogravity-ls system user for UID-scoped iptables isolation, # Checks prerequisites, creates the zerogravity-ls system user for
# installs the systemd user service, and builds the dns_redirect.so preload lib. # UID-scoped iptables isolation, and builds the release binary.
set -euo pipefail set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
@@ -18,7 +18,26 @@ if [ ${#MISSING[@]} -gt 0 ]; then
exit 1 exit 1
fi fi
# ── 1. System user for UID isolation ── # ── 1. Prerequisite check: Antigravity must be installed ──
LS_BINARY="${ZEROGRAVITY_LS_PATH:-/usr/share/antigravity/resources/app/extensions/antigravity/bin/language_server_linux_x64}"
echo "→ Checking for Antigravity installation…"
if [ ! -f "$LS_BINARY" ]; then
echo ""
echo "✗ Antigravity is not installed (or the LS binary is missing)."
echo " ZeroGravity requires a working Antigravity installation."
echo " The Language Server binary is bundled with the Antigravity app"
echo " and cannot be downloaded separately."
echo ""
echo " Expected path:"
echo " $LS_BINARY"
echo ""
echo " Install Antigravity first, then re-run this script."
echo " Alternatively, set ZEROGRAVITY_LS_PATH to a custom LS binary location."
exit 1
fi
echo " Found: $LS_BINARY"
# ── 2. System user for UID isolation ──
echo "→ Creating zerogravity-ls system user…" echo "→ Creating zerogravity-ls system user…"
if id -u zerogravity-ls &>/dev/null; then if id -u zerogravity-ls &>/dev/null; then
echo " Already exists." echo " Already exists."
@@ -27,7 +46,7 @@ else
echo " Created." echo " Created."
fi fi
# ── 2. Sudoers rule (run commands as zerogravity-ls without password) ── # ── 3. Sudoers rule (run commands as zerogravity-ls without password) ──
SUDOERS="/etc/sudoers.d/zerogravity" SUDOERS="/etc/sudoers.d/zerogravity"
echo "→ Installing sudoers rule…" echo "→ Installing sudoers rule…"
if [ -f "$SUDOERS" ]; then if [ -f "$SUDOERS" ]; then
@@ -38,41 +57,15 @@ else
echo " Installed: $SUDOERS" echo " Installed: $SUDOERS"
fi fi
# ── 3. Data directory permissions ── # ── 4. Data directory permissions ──
echo "→ Setting up /tmp/zerogravity-standalone…" echo "→ Setting up /tmp/zerogravity-standalone…"
sudo mkdir -p /tmp/zerogravity-standalone sudo mkdir -p /tmp/zerogravity-standalone
sudo chmod 1777 /tmp/zerogravity-standalone sudo chmod 1777 /tmp/zerogravity-standalone
# ── 4. Config directory ── # ── 5. Config directory ──
echo "→ Setting up ~/.config/zerogravity…" echo "→ Setting up ~/.config/zerogravity…"
mkdir -p "$HOME/.config/zerogravity" mkdir -p "$HOME/.config/zerogravity"
# ── 5. Systemd user service ──
echo "→ Installing systemd user service…"
UNIT_DIR="$HOME/.config/systemd/user"
mkdir -p "$UNIT_DIR"
cat > "$UNIT_DIR/zerogravity.service" << EOF
[Unit]
Description=ZeroGravity Proxy
After=network.target
[Service]
Type=simple
ExecStart=$PROJECT_DIR/target/release/zerogravity
WorkingDirectory=$PROJECT_DIR
Environment=RUST_LOG=info
Restart=on-failure
RestartSec=3
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=default.target
EOF
systemctl --user daemon-reload
echo " Installed: $UNIT_DIR/zerogravity.service"
echo " Enable with: systemctl --user enable zerogravity"
# ── 6. Build ── # ── 6. Build ──
echo "→ Building release binary…" echo "→ Building release binary…"
cd "$PROJECT_DIR" cd "$PROJECT_DIR"

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# ZeroGravity — macOS setup # ZeroGravity — macOS setup
# Installs a launchd plist for automatic startup and sets up config directories. # Checks prerequisites, sets up config directories, and builds the release binary.
# No UID isolation on macOS — runs in headless/HTTPS_PROXY mode only. # No UID isolation on macOS — runs in headless/HTTPS_PROXY mode only.
set -euo pipefail set -euo pipefail
@@ -16,50 +16,37 @@ mkdir -p "$CONFIG_DIR"
echo "→ Setting up /tmp/zerogravity-standalone…" echo "→ Setting up /tmp/zerogravity-standalone…"
mkdir -p /tmp/zerogravity-standalone mkdir -p /tmp/zerogravity-standalone
# ── 3. Launchd plist ── # ── 3. Prerequisite check: Antigravity must be installed ──
echo "→ Installing launchd plist…" LS_BINARY="${ZEROGRAVITY_LS_PATH:-}"
PLIST_DIR="$HOME/Library/LaunchAgents" if [ -z "$LS_BINARY" ]; then
PLIST="$PLIST_DIR/com.zerogravity.proxy.plist" # Check both /Applications and ~/Applications
mkdir -p "$PLIST_DIR" for base in "/Applications/Antigravity.app" "$HOME/Applications/Antigravity.app"; do
cat > "$PLIST" << EOF candidate="$base/Contents/Resources/app/extensions/antigravity/bin/language_server_darwin_arm64"
<?xml version="1.0" encoding="UTF-8"?> if [ -f "$candidate" ]; then
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> LS_BINARY="$candidate"
<plist version="1.0"> break
<dict> fi
<key>Label</key> done
<string>com.zerogravity.proxy</string> fi
<key>ProgramArguments</key> echo "→ Checking for Antigravity installation…"
<array> if [ -z "$LS_BINARY" ] || [ ! -f "$LS_BINARY" ]; then
<string>$PROJECT_DIR/target/release/zerogravity</string> echo ""
</array> echo "✗ Antigravity is not installed (or the LS binary is missing)."
<key>WorkingDirectory</key> echo " ZeroGravity requires a working Antigravity installation."
<string>$PROJECT_DIR</string> echo " The Language Server binary is bundled with the Antigravity app"
<key>EnvironmentVariables</key> echo " and cannot be downloaded separately."
<dict> echo ""
<key>RUST_LOG</key> echo " Expected in: /Applications/Antigravity.app or ~/Applications/Antigravity.app"
<string>info</string> echo ""
</dict> echo " Install Antigravity first, then re-run this script."
<key>KeepAlive</key> echo " Alternatively, set ZEROGRAVITY_LS_PATH to a custom LS binary location."
<dict> exit 1
<key>SuccessfulExit</key> fi
<false/> echo " Found: $LS_BINARY"
</dict>
<key>StandardOutPath</key>
<string>$HOME/Library/Logs/zerogravity.log</string>
<key>StandardErrorPath</key>
<string>$HOME/Library/Logs/zerogravity.log</string>
</dict>
</plist>
EOF
echo " Installed: $PLIST"
echo " Start with: launchctl load $PLIST"
echo " Stop with: launchctl unload $PLIST"
# ── 4. Build ── # ── 4. Build ──
echo "→ Building release binary…" echo "→ Building release binary…"
cd "$PROJECT_DIR" cd "$PROJECT_DIR"
cargo build --release 2>&1 | tail -1 cargo build --release 2>&1 | tail -1
echo "" echo ""
echo "✓ Setup complete." echo "✓ Setup complete. Start with: zg start"
echo " Start with: launchctl load $PLIST"
echo " Or manually: zg start"

View File

@@ -1,6 +1,5 @@
# ZeroGravity — Windows setup # ZeroGravity — Windows setup
# Creates config directories, builds the release binary, and optionally # Creates config directories, checks prerequisites, and builds the release binary.
# installs as a scheduled task for automatic startup.
# Run as: powershell -ExecutionPolicy Bypass -File scripts\setup-windows.ps1 # Run as: powershell -ExecutionPolicy Bypass -File scripts\setup-windows.ps1
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
@@ -19,7 +18,26 @@ $DataDir = Join-Path $env:TEMP "zerogravity-standalone"
New-Item -ItemType Directory -Force -Path $DataDir | Out-Null New-Item -ItemType Directory -Force -Path $DataDir | Out-Null
Write-Host " $DataDir" Write-Host " $DataDir"
# ── 3. Build ── # ── 3. Prerequisite check: Antigravity must be installed ──
Write-Host "→ Checking for Antigravity installation…"
$LsBinary = Join-Path $env:LOCALAPPDATA "Programs\Antigravity\resources\app\extensions\antigravity\bin\language_server_windows_x64.exe"
if (-not (Test-Path $LsBinary)) {
Write-Host ""
Write-Host "✗ Antigravity is not installed (or the LS binary is missing)." -ForegroundColor Red
Write-Host " ZeroGravity requires a working Antigravity installation."
Write-Host " The Language Server binary is bundled with the Antigravity app"
Write-Host " and cannot be downloaded separately."
Write-Host ""
Write-Host " Expected path:"
Write-Host " $LsBinary"
Write-Host ""
Write-Host " Install Antigravity first, then re-run this script."
Write-Host " Alternatively, set ZEROGRAVITY_LS_PATH to a custom LS binary location."
exit 1
}
Write-Host " Found: $LsBinary"
# ── 4. Build ──
Write-Host "→ Building release binary…" Write-Host "→ Building release binary…"
Push-Location $ProjectDir Push-Location $ProjectDir
cargo build --release cargo build --release
@@ -32,37 +50,6 @@ if (-not (Test-Path $Binary)) {
} }
Write-Host " Built: $Binary" Write-Host " Built: $Binary"
# ── 4. Scheduled task (optional) ──
$TaskName = "ZeroGravity Proxy"
$Existing = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
if ($Existing) {
Write-Host "→ Scheduled task '$TaskName' already exists. Updating…"
Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false
}
Write-Host "→ Creating scheduled task '$TaskName'…"
$Action = New-ScheduledTaskAction `
-Execute $Binary `
-WorkingDirectory $ProjectDir
$Trigger = New-ScheduledTaskTrigger -AtLogOn
$Settings = New-ScheduledTaskSettingsSet `
-AllowStartIfOnBatteries `
-DontStopIfGoingOnBatteries `
-RestartCount 3 `
-RestartInterval (New-TimeSpan -Minutes 1)
Register-ScheduledTask `
-TaskName $TaskName `
-Action $Action `
-Trigger $Trigger `
-Settings $Settings `
-Description "ZeroGravity OpenAI-compatible proxy" | Out-Null
Write-Host " Installed as logon task."
Write-Host "" Write-Host ""
Write-Host "✓ Setup complete." Write-Host "✓ Setup complete."
Write-Host " Start now: schtasks /run /tn '$TaskName'" Write-Host " Start: .\target\release\zerogravity.exe"
Write-Host " Stop: schtasks /end /tn '$TaskName'"
Write-Host " Or manually: .\target\release\zerogravity.exe"

View File

@@ -58,7 +58,11 @@ impl Platform {
let ca_cert_path = env_or("SSL_CERT_FILE", default_ca_cert_path); let ca_cert_path = env_or("SSL_CERT_FILE", default_ca_cert_path);
let ls_user = env_or("ZEROGRAVITY_LS_USER", || "zerogravity-ls".into()); let ls_user = env_or("ZEROGRAVITY_LS_USER", || "zerogravity-ls".into());
let state_db_path = env_or("ZEROGRAVITY_STATE_DB", || default_state_db_path(&home)); let state_db_path = env_or("ZEROGRAVITY_STATE_DB", || default_state_db_path(&home));
let dns_redirect_so_path = format!("{}/dns-redirect.so", &data_dir); let dns_redirect_so_path = if cfg!(target_os = "macos") {
format!("{}/dns-redirect.dylib", &data_dir)
} else {
format!("{}/dns-redirect.so", &data_dir)
};
let config_dir = PathBuf::from(&config_dir); let config_dir = PathBuf::from(&config_dir);
let token_path = config_dir.join("token"); let token_path = config_dir.join("token");
@@ -104,18 +108,19 @@ fn default_ls_binary_path() -> String {
fn default_ls_binary_path() -> String { fn default_ls_binary_path() -> String {
let home = home_dir(); let home = home_dir();
// Check both /Applications and ~/Applications // Check both /Applications and ~/Applications
let candidates = ["language_server_macos_arm", "language_server_darwin_arm64"];
for base in &[ for base in &[
"/Applications/Antigravity.app", "/Applications/Antigravity.app",
&format!("{home}/Applications/Antigravity.app"), &format!("{home}/Applications/Antigravity.app"),
] { ] {
let path = format!( for name in candidates {
"{base}/Contents/Resources/app/extensions/antigravity/bin/language_server_darwin_arm64" let path = format!("{base}/Contents/Resources/app/extensions/antigravity/bin/{name}");
);
if std::path::Path::new(&path).exists() { if std::path::Path::new(&path).exists() {
return path; return path;
} }
} }
"/Applications/Antigravity.app/Contents/Resources/app/extensions/antigravity/bin/language_server_darwin_arm64".into() }
"/Applications/Antigravity.app/Contents/Resources/app/extensions/antigravity/bin/language_server_macos_arm".into()
} }
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
@@ -295,9 +300,9 @@ pub fn supports_uid_isolation() -> bool {
} }
} }
/// Returns true if LD_PRELOAD DNS redirect is supported (Linux only). /// Returns true if DNS redirect preload is supported (Linux/macOS).
pub fn supports_ld_preload() -> bool { pub fn supports_ld_preload() -> bool {
cfg!(target_os = "linux") cfg!(any(target_os = "linux", target_os = "macos"))
} }
#[cfg(test)] #[cfg(test)]

View File

@@ -65,12 +65,12 @@ pub fn discover_main_ls_config() -> Result<MainLSConfig, String> {
discovery::discover_main_ls_config() discovery::discover_main_ls_config()
} }
/// Build the dns_redirect.so preload library if it doesn't already exist. /// Build the dns_redirect preload library if it doesn't already exist.
/// ///
/// Linux only — hooks `getaddrinfo()` via LD_PRELOAD to redirect Google API /// Linux/macOS — hooks `getaddrinfo()` via LD_PRELOAD/DYLD_INSERT_LIBRARIES
/// domain lookups to 127.0.0.1. /// to redirect Google API domain lookups to 127.0.0.1.
/// ///
/// Returns the path to the .so on success, None on failure. /// Returns the path to the shared library on success, None on failure.
fn build_dns_redirect_so() -> Option<String> { fn build_dns_redirect_so() -> Option<String> {
if !platform::supports_ld_preload() { if !platform::supports_ld_preload() {
return None; return None;
@@ -91,10 +91,15 @@ fn build_dns_redirect_so() -> Option<String> {
return None; return None;
} }
// Compile: gcc -shared -fPIC -o dns_redirect.so dns_redirect.c -ldl let output = if cfg!(target_os = "macos") {
let output = Command::new("gcc") Command::new("cc")
.args(["-dynamiclib", "-o", so_path.as_str(), &c_path])
.output()
} else {
Command::new("gcc")
.args(["-shared", "-fPIC", "-o", so_path.as_str(), &c_path, "-ldl"]) .args(["-shared", "-fPIC", "-o", so_path.as_str(), &c_path, "-ldl"])
.output(); .output()
};
match output { match output {
Ok(out) if out.status.success() => { Ok(out) if out.status.success() => {

View File

@@ -275,22 +275,40 @@ impl StandaloneLS {
// With iptables, all outbound traffic is transparently redirected at the // With iptables, all outbound traffic is transparently redirected at the
// kernel level — setting HTTPS_PROXY on top causes double-proxying. // kernel level — setting HTTPS_PROXY on top causes double-proxying.
if headless || !platform::supports_uid_isolation() { if headless || !platform::supports_uid_isolation() {
// proxy_addr already includes the scheme (e.g. "http://127.0.0.1:8742")
env_vars.push(("HTTPS_PROXY".into(), mitm.proxy_addr.clone()));
env_vars.push(("HTTP_PROXY".into(), mitm.proxy_addr.clone()));
// LD_PRELOAD DNS redirect: hooks getaddrinfo() so Google API domains // LD_PRELOAD DNS redirect: hooks getaddrinfo() so Google API domains
// resolve to 127.0.0.1. Combined with the port-modified endpoint URL, // resolve to 127.0.0.1. Combined with the port-modified endpoint URL,
// this makes the LS connect to our MITM proxy for ALL API calls — // this makes the LS connect to our MITM proxy for ALL API calls —
// even the CodeAssistClient which has Proxy:nil hardcoded. // even the CodeAssistClient which has Proxy:nil hardcoded.
let so_path = build_dns_redirect_so(); let so_path = build_dns_redirect_so();
if let Some(so) = so_path { if let Some(ref so) = so_path {
info!(path = %so, "Enabling LD_PRELOAD DNS redirect for headless MITM"); info!(path = %so, "Enabling DNS redirect preload for headless MITM");
env_vars.push(("LD_PRELOAD".into(), so)); #[cfg(target_os = "macos")]
{
env_vars.push(("DYLD_INSERT_LIBRARIES".into(), so.clone()));
env_vars.push(("DYLD_FORCE_FLAT_NAMESPACE".into(), "1".into()));
}
#[cfg(not(target_os = "macos"))]
{
env_vars.push(("LD_PRELOAD".into(), so.clone()));
}
env_vars.push(( env_vars.push((
"DNS_REDIRECT_LOG".into(), "DNS_REDIRECT_LOG".into(),
format!("{data_dir}/dns-redirect.log"), format!("{data_dir}/dns-redirect.log"),
)); ));
// Force Go binaries to use cgo (libc) DNS resolver instead of
// the pure-Go resolver. Without this, getaddrinfo hooks are
// bypassed because Go resolves DNS internally.
env_vars.push(("GODEBUG".into(), "netdns=cgo".into()));
}
// Only set HTTPS_PROXY as fallback when DNS redirect is NOT available.
// When DNS redirect IS active, HTTPS_PROXY is redundant and harmful:
// Go's net/http sends HTTP CONNECT through the proxy, but the MITM
// proxy expects direct TLS connections (SNI-based interception).
// This causes OAuth token refresh and other non-gRPC calls to fail.
if so_path.is_none() {
env_vars.push(("HTTPS_PROXY".into(), mitm.proxy_addr.clone()));
env_vars.push(("HTTP_PROXY".into(), mitm.proxy_addr.clone()));
} }
} }
} }