Commit Graph

126 Commits

Author SHA1 Message Date
Louie
7455f76351 feat: match Go TLS fingerprint for MITM upstream (#11)
* feat: match Go TLS fingerprint for MITM upstream connections

Replace rustls with boring2 (BoringSSL) for all MITM→Google upstream
connections, configured with Go crypto/tls exact defaults:

- Cipher suites: TLS_AES_128_GCM_SHA256 + 14 others in Go order
- Curves: X25519, P-256, P-384
- Signature algorithms: ECDSA+SHA256, RSA-PSS+SHA256, etc.
- HTTP/2 SETTINGS: 4MB stream window, 1GB connection window, 10MB
  header list, no adaptive windowing

Local TLS (LS→MITM) still uses rustls for CA cert presentation.
boring2/tokio-boring2 were already compiled as transitive deps from
wreq — no new build time added.

* chore: fmt + update README TLS description
2026-02-18 16:15:08 -06: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
Nikketryhard
94162fda61 chore: remove legacy proxyctl and mitm-redirect.sh scripts
Both are superseded by the zg binary and setup-linux.sh.
Updated docs/mitm.md to reflect current setup flow.
v1.0.1
2026-02-18 04:13:53 -06:00
Nikketryhard
30c5550ea8 docs: simplify setup sections in README 2026-02-18 04:11:16 -06:00
Nikketryhard
134126358f fix: cross-platform support + auto token from state.vscdb
- User-Agent now matches actual OS (macOS/Windows/Linux)
- grep -oP replaced with grep -oE for macOS BSD compat
- Port-killer gated with cfg(unix)/cfg(windows)
- zg binary: macOS uses launchctl, Windows uses schtasks
- Data dir mismatch fixed in mitm-redirect.sh
- Windows setup-windows.ps1 ProjectDir fixed
- README: token path, prerequisites updated
- setup-linux.sh: pre-flight dependency checks
- OAuth token auto-read from Antigravity state.vscdb
- Version bump to 1.0.1
2026-02-18 04:09:41 -06:00
Nikketryhard
efdb98e6f0 docs: Relocate the authentication section and refine token acquisition instructions in the README. 2026-02-18 03:50:29 -06:00
Nikketryhard
132f8fb3e6 docs: add "How It Works" section and update early stage warning with tool call stability note 2026-02-18 03:48:09 -06:00
Nikketryhard
ea12127acb chore: remove outdated planning documents and the known issues file.chore: remove outdated planning documents and the known issues file. 2026-02-18 03:33:47 -06:00
Nikketryhard
7577e28229 docs: add project status update and correct GitHub username in README. 2026-02-18 03:31:11 -06:00
Louie
f05f2057ff Update README to reflect AI terminology 2026-02-18 03:25:29 -06:00
Nikketryhard
633813eea0 docs: Add agent-focused setup instructions and project explanation to the README. 2026-02-18 03:02:00 -06:00
Nikketryhard
29bcee350c docs: Improve token retrieval instructions and add details about OAuth token expiration and refresh. 2026-02-18 02:55:29 -06:00
Nikketryhard
22177a28a1 chore: fix all clippy warnings and add Cargo.toml metadata 2026-02-18 02:50:47 -06:00
Nikketryhard
ad0aa1556c feat: Add LICENSE file and refactor MITM response handling and tracing. 2026-02-18 02:43:05 -06:00
Nikketryhard
c0c12de83c feat: Add gemini-3-pro-low model, refine Gemini model aliases, and include a token acquisition guide in the README. 2026-02-18 02:40:27 -06:00
Nikketryhard
38f797c0f2 docs: reorder introductory text, update Rust badge style, and clarify WIP status in README. 2026-02-18 02:35:48 -06:00
Nikketryhard
918d8f73f2 chore: bump version to v1.0.0 and update README with shields, models, and setup guides v1.0.0 2026-02-18 02:32:56 -06:00
Nikketryhard
9ae6fa6eaf docs: improve README presentation by centering text and updating mermaid diagram colors. 2026-02-18 02:29:46 -06:00
Nikketryhard
f9fa9c6f22 docs: add project logo to README and adjust table formatting. 2026-02-18 02:28:04 -06:00
Nikketryhard
c7231e5590 feat: add Windows setup script (scheduled task) 2026-02-18 02:14:33 -06:00
Nikketryhard
8a9662edea feat: add cross-platform support via platform detection module
Introduces src/platform.rs with OS detection and env var overrides.
All hardcoded Linux paths replaced with Platform::detect() across
8 source files. Key changes:

- New Platform struct with 11 fields (all overridable via env vars)
- /proc/ access gated to Linux (#[cfg(target_os = "linux")])
- pgrep/pkill patterns broadened for cross-platform LS discovery
- sec-ch-ua-platform header now dynamic per OS
- Token, traces, config, CA cert paths use platform module
- LD_PRELOAD DNS redirect gated to Linux only
- Setup scripts for Linux (systemd) and macOS (launchd)
- find_ls_binary_path has cross-platform stubs

All 46 tests pass, cargo check clean.
2026-02-18 02:13:23 -06:00
Nikketryhard
7136c0e53c docs: mark /v1/search as WIP in endpoint tables 2026-02-18 02:00:57 -06:00
Nikketryhard
1a5075dd20 refactor: remove /v1/gemini endpoint, replaced by /v1beta routes
- Delete handle_gemini handler (identical to handle_gemini_v1beta)
- Remove /v1/gemini route from router
- Update root handler service name to zerogravity
- Clean all doc references
2026-02-18 01:59:22 -06:00
Nikketryhard
59ed872ed3 chore: fix remaining Antigravity Proxy refs, add systemd unit
- Rename CA org to ZeroGravity
- Fix lib.rs docstring
- Fix mitm-redirect.sh comment
- Fix README title
2026-02-18 01:56:43 -06:00
Nikketryhard
00587fcce8 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)
2026-02-18 01:54:54 -06:00
Nikketryhard
409ee97405 fix: replace \\n with <br/> in mermaid node labels 2026-02-18 01:35:12 -06:00
Nikketryhard
3d87c04d20 docs: overhaul docs, add architecture and traces, update README/GEMINI
- Add docs/architecture.md with 4 mermaid diagrams
- Add docs/mitm.md with 3 mermaid diagrams (replaces mitm-interception-status)
- Add docs/traces.md documenting per-call trace system
- Rewrite README.md to be concise with mermaid and doc refs
- Rewrite GEMINI.md for core philosophy and agent usage
- Clean extension-server-analysis.md (remove stale debug sections)
- Delete temp docs: standalone-ls-todo, panel-stream-investigation,
  endpoint-gap-analysis, request-comparison
2026-02-18 01:31:18 -06:00
Nikketryhard
28d3296c87 fix: gemini route, usage capture, search timeout, and trace finalization
- Add missing /v1/gemini POST route and handler
- Capture MitmEvent::Usage in gemini sync/streaming handlers
- Add retry counter (max 3) to search handler to prevent hang
- Add trace finalization at all gemini_sync channel exit points
- Fix UpstreamError trace outcome label
- Add timeout trace with error recording
- Dispatch Usage before ResponseComplete in SSE flush
2026-02-18 01:31:18 -06:00
Nikketryhard
48674f65da refactor: decompose large functions and remove dead code
- Decompose modify_request() into 7 single-responsibility helpers
- Decompose handle_http_over_tls(): extract read_full_request, dispatch_stream_events
- Promote connect_upstream/resolve_upstream to module-level functions
- Split standalone.rs (1238 lines) into 4 submodules:
  standalone/mod.rs, spawn.rs, discovery.rs, stub.rs
- Extract proto wire primitives into proto/wire.rs
- Remove 6 dead MitmStore methods
- Remove dead SessionResult, DEFAULT_SESSION, get_or_create
- Remove dead decode_varint_at, extract_conversation_id
- Clean all unused imports across 10 files
- Suppress structural dead_code warnings on deserialization fields

Warnings: 20 -> 0. All 43 tests pass.
2026-02-17 22:27:26 -06:00
Nikketryhard
637fbc0e54 refactor: endpoint parity and proxy improvements
Mixed changes from recent sessions: endpoint feature parity
improvements, proxy bug fixes, and store cleanup.
2026-02-16 21:47:00 -06:00
Nikketryhard
86675fd960 docs: add real request comparison (proxy vs CLIProxyAPI)
Captured actual MITM headers and body from a live request.
CLIProxyAPI side reconstructed from source code.
2026-02-16 21:46:52 -06:00
Nikketryhard
34799fa2a9 feat: add official Gemini v1beta API routes
Replace /v1/gemini with proper Gemini API paths:
- POST /v1beta/models/{model}:generateContent (sync)
- POST /v1beta/models/{model}:streamGenerateContent (streaming)

Model is extracted from URL path. Uses axum wildcard
catch-all since colons in path segments are not supported.
2026-02-16 21:46:52 -06:00
Nikketryhard
eb4c846b24 feat: match CLIProxyAPI system instruction pattern
Replace custom IGNORE/no-tools messages with CLIProxyAPI-style
multi-part system instruction: part[0] = identity text,
part[1] = Please ignore following [ignore]...[/ignore].
2026-02-16 21:46:52 -06:00
Nikketryhard
cac30067ef feat: add structured output to Gemini endpoint
Gemini endpoint now accepts responseMimeType and responseSchema
fields, injected into Google's generationConfig via MITM. Supports
both snake_case and camelCase aliases.
2026-02-16 19:57:18 -06:00
Nikketryhard
135cd47f8f fix: proxyctl logs no longer hangs
logs command was using journalctl -f (follow) which blocks forever.
Split into three commands:
- logs [N]: show last N lines and exit (default 30)
- logs-follow [N]: tail + follow (old behavior)
- logs-all: full dump
2026-02-16 19:44:23 -06:00
Nikketryhard
a47c572e48 fix: forward Google's exact error messages to client
Root cause: errors from Google were being swallowed, replaced with
placeholders like 'Google API returned HTTP 400' or '[Timeout waiting
for response]', or silently converted to fake 'incomplete' responses.

Changes across all endpoints (/v1/chat/completions, /v1/responses,
/v1/gemini, /v1/search):

Error message fidelity:
- UpstreamError message now includes Google's status prefix: [STATUS] msg
- Falls back to raw body if JSON parsing fails (protobuf, HTML, etc.)
- ErrorDetail gains optional code and param fields

Timeout handling:
- poll_for_response returns UpstreamError(504, DEADLINE_EXCEEDED) on timeout
  instead of '[Timeout waiting for AI response]' placeholder text
- Streaming timeouts emit proper error events, not fake content
- Sync bypass timeouts return 504 Gateway Timeout, not 200 incomplete

Missing error checks added:
- responses.rs sync bypass: added upstream_error check in polling loop
- gemini.rs sync bypass: added upstream_error check in polling loop
- gemini.rs streaming: added upstream_error check in polling loop
  (was completely missing — errors only handled in sync path)

DRY helpers:
- upstream_error_message(): shared exact message extraction
- upstream_error_type(): shared Google→OpenAI error type mapping
- All streaming handlers use these instead of inline formatting
2026-02-16 19:30:32 -06:00
Nikketryhard
931e1cc5a1 chore: remove unused push_tool_round_calls and attach_tool_round_results 2026-02-16 19:22:09 -06:00
Nikketryhard
ba96534ead fix: prevent tool_rounds cross-cascade contamination causing hangs
Root cause: proxy.rs eagerly pushed tool rounds via push_tool_round_calls
when intercepting Google's functionCall response. These stale rounds leaked
into LS follow-up requests, producing malformed history that Google timed
out on (60s 'no upstream response').

Changes:
- Remove push_tool_round_calls from proxy.rs response interception
- proxy.rs: use get_tool_rounds (non-destructive) instead of take_tool_rounds
  so accumulated rounds persist across multiple LS requests per cascade
- responses.rs/gemini.rs: build rounds via take+push+set pattern — each
  handler accumulates its own rounds from get_last_function_calls + results
- completions.rs: unchanged (set_tool_rounds replaces from messages)
- clear_tools: also clears tool_rounds to prevent stale data between sessions
- store.rs: add get_tool_rounds (non-destructive clone) method
2026-02-16 19:21:03 -06:00
Nikketryhard
32f02d6456 fix: extend multi-round tool history to responses and gemini endpoints
- proxy.rs: push_tool_round_calls alongside set_last_function_calls
  when Google responds with functionCall — accumulates rounds
- responses.rs: attach_tool_round_results to pair tool results with
  the correct round instead of flat add_tool_result
- gemini.rs: same attach_tool_round_results integration
- store.rs: add push_tool_round_calls and attach_tool_round_results
  methods for cross-request round accumulation
- Legacy add_tool_result kept for backward compat alongside new path
2026-02-16 19:11:38 -06:00
Nikketryhard
39381a4dfe fix: multi-round tool history rewrite and finishReason handling
- Add ToolRound struct to pair function calls with results per-round
- Replace single-match history rewrite (broke after first round) with
  multi-round loop that rewrites ALL placeholder model turns
- Fix tool result name fallback: use positional index instead of always
  picking the first call
- Set is_complete for any finishReason (FUNCTION_CALL, MAX_TOKENS, etc.)
  not just STOP — prevents response_complete flag from never being set
- Legacy fallback: responses.rs path (single-round via last_calls +
  pending_results) still works when tool_rounds is empty
- Add tests: multi-round rewrite, single-round legacy, no-op, and
  FUNCTION_CALL/MAX_TOKENS finishReason handling
2026-02-16 19:05:37 -06:00
Nikketryhard
6bda2ecafa fix: tool call race conditions and missing completions tool result extraction
- store.rs: record_function_call now falls back to active_cascade_id
  (matching record_usage behavior) instead of blind _latest fallback
- store.rs: add cascade-aware take_function_calls(cascade_id) method
  with priority: exact match → active cascade → _latest → any key
- completions.rs: extract tool_calls from assistant messages and tool
  results from tool messages, storing them for MITM injection. This was
  the ROOT CAUSE — the completions handler stored tool definitions but
  never extracted tool results, so modify_request couldn't rewrite the
  LS conversation history with proper functionCall/functionResponse
- responses.rs: use cascade-aware take_function_calls for consistency
2026-02-16 18:43:16 -06:00
Nikketryhard
38b4130c55 feat: Implement request generation counter and state management to prevent stale data and unblock Language Server for follow-up requests. 2026-02-16 16:21:52 -06:00
Nikketryhard
e6a339d92e fix: clear request_in_flight when stream ends
Without this, request_in_flight stayed true after tool call streaming,
blocking all subsequent turns until the next completions handler
happened to clear it first.
2026-02-16 01:02:09 -06:00