feat: MITM interception for standalone LS with UID isolation

- Spawn standalone LS as dedicated 'antigravity-ls' user via sudo
- UID-scoped iptables redirect (port 443 → MITM proxy) via mitm-redirect.sh
- Combined CA bundle (system CAs + MITM CA) for Go TLS trust
- Transparent TLS interception with chunked response detection
- Google SSE parser for streamGenerateContent usage extraction
- Timeouts on all MITM operations (TLS handshake, upstream, idle)
- Forward response data immediately (no buffering)
- Per-model token usage capture (input, output, thinking)
- Update docs and known issues to reflect resolved TLS blocker
This commit is contained in:
Nikketryhard
2026-02-14 17:50:12 -06:00
parent 6842bfeaa5
commit d4de436856
10 changed files with 1156 additions and 478 deletions

View File

@@ -62,6 +62,51 @@ pub fn varint_field(field: u32, val: u64) -> Vec<u8> {
out
}
// ─── Init metadata builder (for standalone LS stdin) ─────────────────────────
/// Build the init metadata protobuf that the LS expects on stdin at startup.
///
/// This replaces the Python snippet in `standalone-ls.sh` with proper Rust encoding.
/// Fields match what the real Antigravity extension sends to the LS.
///
/// Field layout (from binary analysis):
/// 1: api_key (string) — unique session key
/// 3: ide_name (string) — "antigravity"
/// 4: antigravity_version (string) — e.g. "1.107.0"
/// 5: ide_version (string) — e.g. "1.16.5"
/// 6: locale (string) — "en_US"
/// 10: session_id (string) — unique session identifier
/// 11: editor_name (string) — "antigravity"
/// 34: detect_and_use_proxy (varint enum) — 1 = ENABLED
pub fn build_init_metadata(
api_key: &str,
antigravity_version: &str,
ide_version: &str,
session_id: &str,
detect_and_use_proxy: u64,
) -> Vec<u8> {
let mut buf = Vec::with_capacity(128);
// Field 1: api_key
buf.extend(proto_string(1, api_key.as_bytes()));
// Field 3: ide_name
buf.extend(proto_string(3, CLIENT_NAME.as_bytes()));
// Field 4: antigravity version
buf.extend(proto_string(4, antigravity_version.as_bytes()));
// Field 5: IDE/client version
buf.extend(proto_string(5, ide_version.as_bytes()));
// Field 6: locale
buf.extend(proto_string(6, b"en_US"));
// Field 10: session_id
buf.extend(proto_string(10, session_id.as_bytes()));
// Field 11: editor_name
buf.extend(proto_string(11, CLIENT_NAME.as_bytes()));
// Field 34: detect_and_use_proxy enum (1 = ENABLED)
buf.extend(varint_field(34, detect_and_use_proxy));
buf
}
// ─── SendUserCascadeMessageRequest builder ───────────────────────────────────
/// Build the `SendUserCascadeMessageRequest` protobuf binary.