feat(antigravity): add Google Antigravity client with sync-first cache parser - #355
Conversation
|
@ddarkr is attempting to deploy a commit to the Inevitable Team on Vercel. A member of the Team first needs to authorize it. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2d7c24c61f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let response = rpc_request( | ||
| connection, | ||
| "GetAllCascadeTrajectories", | ||
| &serde_json::json!({}), | ||
| )?; |
There was a problem hiding this comment.
Continue syncing when one RPC connection fails
list_trajectory_summaries currently propagates any single rpc_request error with ?, so tokscale antigravity sync aborts even if other detected language-server connections are healthy. This is user-visible when one editor instance exits or transiently fails between heartbeat probing and trajectory listing: one bad process prevents exporting sessions from all remaining processes. Treat per-connection RPC failures as best-effort (skip/log) to keep sync resilient.
Useful? React with 👍 / 👎.
| .get("createdAt") | ||
| .or_else(|| usage.get("timestamp")) | ||
| .and_then(Value::as_str) | ||
| .and_then(|text| chrono::DateTime::parse_from_rfc3339(text).ok()) |
There was a problem hiding this comment.
Parse numeric retry timestamps before writing artifacts
Timestamp extraction for retry usage only accepts RFC3339 strings via as_str, so numeric createdAt/timestamp fields become null in emitted JSONL rows. The antigravity parser later drops usage rows with non-positive timestamps, which silently undercounts tokens/cost whenever the RPC payload uses epoch numbers instead of strings. Add numeric timestamp handling here before falling back to created_at.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 12d2b21b96
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let mut ports = parse_ports(&run_command( | ||
| "lsof", | ||
| &["-Pan", "-p", &pid_str, "-iTCP", "-sTCP:LISTEN"], | ||
| )?); |
There was a problem hiding this comment.
Handle missing lsof gracefully during sync
Connection discovery hard-fails when lsof is unavailable because find_listening_ports propagates run_command("lsof", ...) errors with ?. On systems where lsof is not installed (common in minimal Linux setups), tokscale antigravity status/sync will abort as soon as an Antigravity process candidate is found, so users cannot refresh cache data despite having a running editor. This should degrade to a warning and skip that process instead of failing the whole command.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 20a5ac4f82
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let artifact_path = cache_dir.join(relative_path); | ||
| if artifact_path.exists() { | ||
| fs::remove_file(&artifact_path)?; |
There was a problem hiding this comment.
Restrict artifact deletion to cache directory
delete_artifact_relative_path trusts artifact_path from the manifest and directly does cache_dir.join(relative_path) before remove_file. Because join accepts absolute paths and .. segments, a corrupted/edited manifest can cause sync cleanup to delete files outside ~/.config/tokscale/antigravity-cache (for example an absolute path or ../../...). This makes artifact cleanup unsafe against malformed local state and can lead to unintended data loss.
Useful? React with 👍 / 👎.
| let ports = find_listening_ports(candidate.pid)?; | ||
| for port in ports { |
There was a problem hiding this comment.
Probe declared RPC port when port scan returns nothing
Connection discovery only iterates ports returned by find_listening_ports, so candidates are dropped when lsof is unavailable/restricted or returns no rows. Fresh evidence in this commit: ProcessCandidate.declared_port is parsed from --extension_server_port but never used during probing, which means antigravity status/sync can still report zero connections even though the process advertises a usable RPC port.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1660f1be3f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| relative: ".config/tokscale/antigravity-cache/sessions", | ||
| pattern: "*.jsonl", | ||
| headless: false, | ||
| parse_local: false |
There was a problem hiding this comment.
Mark antigravity as parseable in local defaults
ClientId::Antigravity is registered with parse_local: false, but default local parse paths (e.g., parse_local_unified_messages and run_clients_command) build their source list from ClientId::iter().filter(|c| c.parse_local()). That means synced Antigravity cache files are omitted unless callers explicitly pass "antigravity", so default local workflows can silently miss this new client’s data. Make Antigravity parse-local (or explicitly include it in those defaults) so the new integration is visible without manual source overrides.
Useful? React with 👍 / 👎.
Limit stale artifact deletion to session jsonl files under the cache root and include Antigravity in default local parsing so synced sessions are visible without explicit source filters.
Adds Antigravity to ClientFilter (variant + as_filter_str/to_client_id/ from_client_id arms), the legacy hidden `--antigravity` flag in ClientFlags, the TUI client color palette (#6366F1), and the README `Possible values` list so the new client is reachable through every filter surface.
resolve_cache_relative_artifact_path now canonicalizes the resolved candidate when it exists and verifies the canonical path remains under the canonical sessions cache root, so a symlink planted inside the sessions directory cannot redirect deletes to arbitrary files outside the cache. Adds a regression test that creates a symlink pointing outside the cache and asserts the deletion is rejected.
135ac58 to
78706fe
Compare
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
junhoyeo
left a comment
There was a problem hiding this comment.
Thanks for the persistence on this, @ddarkr! The sync-first architecture is the right call — keeps tokscale-core RPC-free and parsable offline. Approving and squash merging with credit to @bruce-shi for the original RPC endpoint discovery in #345.
…nd client filter UX (#467) Pre-release correctness and security fixes across the four PRs landed this cycle (#464, #454, #359, #355). ## Antigravity Trust boundary around the local language-server RPC was too loose: - Bound RPC body sizes at 16 MiB (Content-Length, chunked, and read-to-end paths) - Verify process identity by checking the executable path (`lsof` on macOS, `/proc/<pid>/exe` on Linux); accept paths containing either `antigravity` or `language_server` since some Antigravity-flavored servers launch from generic `language_server` binaries with `--app_data_dir antigravity` - Probe candidate endpoints with a real RPC call and JSON-shape check (probe body capped at 4 KiB) instead of trusting any 200 response; consume HTTP headers before reading body so the cap applies to the JSON body alone - Lock concurrent syncs on a per-cache PID lock file with bounded retry (3 attempts) instead of unbounded recursion. Eviction is gated on PID liveness only — long-running syncs no longer get stomped on by age-based timeouts. - Enforce manifest version on load: future versions abort, older versions start fresh - Recover corrupted manifests by moving them aside as `manifest.json.corrupt-<ts>` instead of failing every subsequent sync ## Codebuff Parser correctness around silent data loss: - Accumulate run-state usage across the full reverse `messageHistory` walk instead of returning on the first signal-bearing entry. Previously a newest assistant entry carrying only a model id would short-circuit the walk and silently drop real token counts on earlier entries. - Include the source-array ordinal in the fallback dedup key so two id-less assistant messages with identical session/timestamp/model/tokens no longer collapse into a single record - Reject non-positive numeric timestamps in the shared `parse_timestamp_value`/`parse_timestamp_str` helpers so messages with `timestamp: 0` or negative epochs fall through to chat-id / file-mtime fallback chain ## TUI + parsing User-visible client-filter UX: - Move `SYNTHETIC_HOTKEY` from `'x'` to `'n'`. `'x'` collided with Mux's hotkey, and the dispatch order made the displayed `[x]` for Synthetic purely cosmetic - Enable `ignore_case` on `--client/-c` so `OPENCODE`, `Codebuff`, and `antigravity` all parse as the same canonical filter ## Test results - `cargo test -p tokscale-cli` — 415 unit + 83 integration, all pass - `cargo test -p tokscale-core` — 566 unit + 10 codebuff + 3 hermes, all pass - `cargo check --workspace` — clean Each fix has a regression test where applicable.
The Korean, Japanese, and Simplified Chinese READMEs were not updated when Codebuff (#454), Goose (#457), and Antigravity (#355) landed. The English README also picked up missing Goose and Antigravity entries during this sweep. Sync all four to the same client list, settings table, Windows locations, Data Sources sections, and `tokscale antigravity` command documentation.
Summary
tokscale antigravity status|sync|purge-cacheso Antigravity usage can be collected from the local language server while the editor is runningtokscale-corefocused on parsing local data instead of live RPC collectionTest proof
cargo test— passedcargo test -p tokscale-cli antigravity— passedcargo test -p tokscale-core antigravity— passedcargo run -p tokscale-cli -- antigravity status— verified sync-first UXcargo run -p tokscale-cli -- antigravity sync— verified cache sync flowcargo run -p tokscale-cli -- models --antigravity --json— verified parsed reporting pathSummary by cubic
Adds Antigravity support:
tokscale antigravitysyncs usage from the local language server into a cached JSONL store, andtokscale-coreparses it with canonical model aliases for accurate pricing. Runtokscale antigravity syncwhile the editor is open; synced usage appears in local reports by default (optional--client antigravityfilter; legacy--antigravity; TUI hotkeya).New Features
tokscale antigravitysubcommands:status,sync,purge-cache.~/.config/tokscale/antigravity-cache/sessions/*.jsonl; manifest preserves prior confirmed artifacts.antigravityclient (scans cached JSONL), parser, and pricing alias normalization for placeholders and “thinking” variants (e.g.,model_placeholder_m26→claude-opus-4-6,gemini-3-flash-c→gemini-3-flash-preview).--client antigravity(legacy--antigravity) and TUI entry (hotkeya).Bug Fixes
.jsonlpaths, canonicalize targets and reject symlink escapes, and remove stale legacy artifacts after sync.lsof, probe declared RPC ports when discovery returns nothing, and improvestatus/syncdiagnostics.Written for commit 78706fe. Summary will update on new commits.