Repository navigation
Conversation
…ation id On Windows, agy started in a WSL pane writes its transcript under the guest home, but the id-based lookup only searched the Windows home. When the hook-reported path is absent, Chat now tries the host brain first and then each running distro's home, reusing the Codex WSL fallback shape. Attested distros, guest hook paths and stalled-distro refusals keep their existing exact-path rules.
Status rows delivered through the WSL hook relay carry a `wsl:<distro>` connection id, so the screen-approval publisher and ingest treated them as direct-SSH mirrors and never raised the Allow/Deny card. WSL relay ids are now accepted, while the runtime only binds such a row to a WSL pty of the same distro. Direct SSH stays excluded.
8ad9505 to
e0a3931
Compare
|
| } | ||
| // Why: enumerating WSL homes spawns wsl.exe, so only pay it after the host misses. | ||
| let unavailable: WslTranscriptFsError | undefined | ||
| for (const candidate of await wslAntigravityTranscriptPaths(conversationId)) { |
There was a problem hiding this comment.
Failed discovery looks like absence If the first running-distro probe fails and there is no cached result, WSL discovery returns no homes. This loop then returns
null, treating the Antigravity transcript as missing even though it was never checked. A WSL conversation can appear absent during a discovery outage instead of being reported as temporarily unavailable.
Knowledge Base Used:
There was a problem hiding this comment.
Agreed that a failed running-distro probe looks like "no homes". This comes from the shared probe: resolveRunningWslDistros swallows the failure and returns the last known list, or [], and the existing Codex WSL fallback inherits the same behaviour. For Chat this means a pending transcript rather than a terminal "missing": transcript-watch keeps re-resolving every 0.5–5 s and binds once the probe recovers. Reporting it as unavailable would mean changing that shared probe for every WSL reader, so I'd prefer to handle it as a separate change. I'm happy to add it here if maintainers want it in this PR.
There was a problem hiding this comment.
That’s a fair clarification. Given resolveRunningWslDistros deliberately converts discovery failures into the cached list (or []), this resolver cannot distinguish “no running WSL homes” from “discovery failed” without changing the shared probe contract. Here, null means the transcript remains unresolved: transcript-watch keeps retrying and can bind once discovery recovers, rather than surfacing a terminal missing state.
I’ll withdraw this finding; preserving unavailable-vs-missing semantics across all WSL readers is better handled as a separate change.
Tip: You can customize Greptile's behavior for this repo with .greptile/rules.md and .greptile/config.json.
| const homeDirs = deps.wslSnapshot | ||
| ? await snapshotHomeDirs(deps.wslSnapshot) | ||
| : await resolveWslHomeDirs(deps.listWslHomeDirs) |
There was a problem hiding this comment.
Repeated WSL home probes When an id-only Antigravity transcript has not been written yet, Chat retries the lookup. This default home loader bypasses the existing home-directory cache, so each host miss can repeat running-distro and home probes, adding avoidable
wsl.exe work while Chat waits.
Knowledge Base Used: Limit WSL session scans to running distros
There was a problem hiding this comment.
Fixed in 1c94a41. Home dirs were already cached by getWslHomeAsync, but the running-distro list was being fetched for home discovery and again for every candidate path. The fallback now builds one createWslTranscriptResolutionSnapshot per attempt and passes it to both, which is how the Codex path works. A new test asserts one running-distro probe per attempt.
Chat re-resolves an unwritten transcript every few seconds, and the WSL fallback listed running distros once for home discovery and again for every candidate path. One resolution snapshot now serves the whole attempt, as the Codex path does, and a cancelled lookup no longer starts WSL discovery.
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
Two WSL-only follow-ups on the Antigravity Chat stack. I read the full diff, traced the affected call paths, and reran the focused and neighboring suites (all green).
- Id-based transcript lookup falls back to WSL guests —
resolveAntigravitySessionFilenow tries the host brain first, then each running distro's guest brain via the newwslAntigravityTranscriptPaths, mirroring the Codex fallback. Host hits and explicitantigravityBrainDiroverrides still short-circuit, and an attested distro or guest hook path still never falls back to an id match (the outer gates inresolveSessionFilePathare intact). - Stalled-distro handling — the WSL loop defers a stalled distro as
unavailablewithout hiding a later distro's hit, and throwsWslTranscriptFsErrorwhen no hit was found but a distro never answered, so a stall reads as "unavailable", not "missing". Non-refusal errors are rethrown rather than swallowed. - WSL command approvals — the screen ingest and publisher now accept
wsl:relay connection ids while still rejecting SSH mirrors, and the runtime binds a row to a pty only throughantigravityHookRowMatchesPty(same distro, WSL pty). I verified theisWsl === trueguard holds in production: the renderer spawn path and controller inventory both setisWsl: truefor WSL panes, so it will not false-negative normal WSL use.
The new tests are behavioral, not tautological — the resolver, ingest, and publisher cases each fail on the parent commit as the author states. oxlint is clean over the changed files.
DeepSeek Flash (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
Delta since the prior pullfrog review (e0a3931): one commit, 1c94a41 ("share one WSL snapshot per transcript lookup"), plus its test updates. All other files are unchanged.
- One WSL snapshot per attempt —
resolveAntigravitySessionFilenow builds a singlecreateWslTranscriptResolutionSnapshot()after the host miss and threads it through bothwslAntigravityTranscriptPathsand eachtoHostReadableTranscriptPathprobe, solistRunningWslDistrosAsync/getWslHomeAsyncrun once per resolve instead of once per candidate. - Explicit Windows gate and abort checks — an early
process.platform !== 'win32'return now precedes the snapshot, andsignal?.throwIfAborted()brackets it so a cancelled Chat lookup never starts WSL discovery. - Tests — the resolver suite is now 11 cases: the existing host/override/attested-path cases assert against
listRunningWslDistrosAsync(the probe the snapshot now uses), and two new cases pin "probes distros once per attempt" and "does not start WSL discovery for a cancelled lookup". I reran it: 11 pass.
The single-snapshot change is a correctness-neutral performance fix; the wslSnapshot is only used to short-circuit the running-distro filter, and the existence probe still runs per candidate, so the stalled-distro semantics from the prior review are unchanged.
DeepSeek Flash (free via Pullfrog for OSS) | 𝕏
|
This run hit its time limit while still working, so it stopped before finishing. Give runs longer with
|
Recover scoped transcript, terminal approvals, and WSL support on current main. Keep hook-server authority, captured-grid rules, quiescence, and current journals. Negotiate Antigravity reads and subscriptions on desktop, web, and mobile. Credits #15773, #21660, #21776, and #24141. Co-authored-by: haoliangli <haoliangli@users.noreply.github.com> Co-authored-by: sojiro-o <53679703+sojiro-o@users.noreply.github.com>
Preserves accepted Antigravity Chat source from @haoliangli (#15773) and @sojiro-o (#24141). Carries runtime-owned Chat association and authoritative ruled-screen publication onto fixed main 752871b.
Antigravity records first turns at whole seconds, leaving a millisecond composer echo visible below later turns. Publish optional source precision and use it when matching local sends and seeded launch prompts; retain strict transcript boundaries and exact matching when precision is absent. Credits @sojiro-o/#25117 for the first-send diagnosis and proposed regression. Retains the Antigravity Chat contributions from @haoliangli/#15773 and @sojiro-o/#24141 without changing accepted readiness or capture assets. Co-authored-by: sojiro-o <53679703+sojiro-o@users.noreply.github.com>
Compose main 2b3b692 with the complete Chat feature and ed05 source-clock repair. Preserve provider step order and incoming split-reasoning order; remove a duplicated import introduced by the automatic merge and test the combined ordering contract. Retains credits for @sojiro-o/#25117 and #24141 and @haoliangli/#15773; original author objects and measured coauthor trailers remain unchanged.
|
Closing. This PR was stacked on #24627, which has been idle since October 4. Meanwhile, Antigravity Chat landed on |

ELI5
When Antigravity (agy) runs inside WSL on Windows, the Chat view could lose track of the conversation file, and it never showed the Allow/Deny card when agy asked to run a command — the chat just looked busy while the terminal waited. Both now work for WSL panes.
What Changed
Two small WSL-only fixes on top of the Antigravity Chat stack (#21660, #21776):
C:\Users\…\.gemini\antigravity-cli\brain), so a WSL session was never found. After: it tries the Windows brain first, then each running distro's home (\\wsl.localhost\<distro>\home\…\.gemini\…), mirroring the existing Codex WSL fallback (wslCodexSessionsDirs). Existing exact-path rules are unchanged: an attested distro or a guest hook path never falls back to an id match elsewhere, and a stalled distro still reports "unavailable", not "missing".wsl:<distro>connection id, and the screen-approval publisher/ingest rejected any connection id as a direct-SSH mirror, so the card was never raised. After:wsl:ids are accepted (the pty is on this host), direct SSH stays excluded, and the runtime binds awsl:row only to a WSL pty of the same distro (antigravityHookRowMatchesPty). No screen-matching rule changed — the captured approval screen on WSL agy 1.2.14 matches the existing rule line for line.Why
isWslHookRelayConnectionId(e.g.runtime-worktree-pty-agent-sources.ts); the approval path was the one place that did not.wsl.exe) behind a host miss and inherits the existing stalled-distro gate, instead of adding a new scan.Linked Issue
Refs #20157 (WSL item). Follow-up to #21660 and #21776.
Visual Proof
Before: agy asks


Run this command?in the terminal while Chat shows only the pendingrun_command.After: the same request raises the Allow/Deny card in Chat; Allow runs it and Deny stops it.

Testing
Platform: Windows 11 (build 26200) + WSL2 Ubuntu 26.04, agy 1.2.14.
null. After:\\wsl.localhost\Ubuntu-26.04\home\…\transcript.jsonlin ~300 ms. Guest-hook-path, missing-id and wrong-distro cases were unchanged.sleep 8 && echo okand the reply rendered, and Deny stopped a second request. Chat rendering and Japanese/multi-line input also worked.session-file-resolver-antigravity-wsl.test.ts(9 cases); 3 fail on the parent commit.server-ingest-antigravity-screen.test.tsandantigravity-screen-permission-publisher.test.ts, plus a pty-matching table; 2 fail on the parent commit.oxlint/oxfmtpass. Changed-code quality has 0 new findings. A typecheck scoped to the changed files is clean; fullpnpm tcis left to CI (the local machine has 8 GB of RAM).Not verified: WSL paired/mobile runtime, and a hook-less Orca restart restoring a WSL Antigravity tab (the id-only path is covered by the live resolver run above, not through the UI).
Note for testers: Orca launches agy with
--dangerously-skip-permissionsby default (DEFAULT_TUI_AGENT_ARGS), so switch Antigravity to Manual to see approvals. On a Windows dev checkout, runpnpm run build:relaybeforepnpm dev; otherwise WSL panes get no hook relay and Chat never binds to the transcript.AI Disclosure
Claude Opus 5.5 (Claude Code) investigated, implemented and ran the verification with me; I reviewed the changes and did the manual UI testing.
Review
Direct SSH behaviour is unchanged and still covered by the existing tests. No wire, opcode or status-store shape changes.
Agent skill upstream boundary
Notes
Security: no new paths are opened beyond
\\wsl.localhosthomes of running distros, and conversation ids are still restricted to one path segment. Cross-platform: the fallback runs only onwin32. SSH: unchanged. Mobile: no change. Performance: the WSL enumeration runs only after a Windows-home miss.Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred) — focused checks local, full suite via CI