fix(wta): reconnect via master pipe after FRE login (first-tab session view empty)#186
Merged
Merged
Conversation
In helper mode (`--connect-master`) the initial
`run_acp_client_over_pipe` task fails immediately with
`Authentication required` when the user is in FRE (not yet logged
in). The post-login `LoginComplete` handler then fires
`try_start_acp`, but that path was hard-wired to spawn
`run_acp_client` (direct mode) — spawning its own copilot CLI
subprocess and bypassing wta-master entirely. The reconnected helper
never registers with master, so:
* every `intellterm.wta/...` ext-request fails with
`"Method not found": _intellterm.wta/sessions/list` (the ACP
SDK forwards unknown extensions to the agent with a leading
underscore, and the agent CLI doesn't know master-side
extensions);
* the alive-mirror never populates → the first tab's session view
stays blank for the life of the helper;
* `session_hook` publishes log `channel closed` (the rx was
consumed and dropped with the failed initial task).
Symptom from the field: after FRE, running `copilot` in tab 1's
shell pane produces a session that tab 1's session view never shows.
Tabs 2/3 (spawned post-login, never see `Authentication required`)
work fine and even see tab 1's session because their helpers reach
master via the standard pipe.
Fix:
* extend `DeferredAcpParams` with `master_pipe_name` and
`owner_tab_id`;
* add `App::set_master_pipe_acp_params`, called once at boot in
helper mode (main.rs) to pre-stash pipe-mode params on App;
* route `try_start_acp` through `run_acp_client_over_pipe` when
`master_pipe_name.is_some()`, rebuilding the `session_hook`
channel and re-binding `self.session_hook_tx` so hooks reach
master again;
* direct-mode FRE (no `--connect-master`) is unchanged — existing
`set_acp_params` and `LoginComplete` synthesis paths just
carry the two new fields as `None`.
Verified: `cargo build --target x86_64-pc-windows-msvc` clean,
`cargo test --bin wta` 698 passed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes a helper-mode (pipe-to-master) reconnection bug after FRE login where tab 1’s helper would fall back to direct-mode ACP, bypass wta-master, and therefore fail master-only intellterm.wta/... extension methods (leaving the session management view empty in the first tab).
Changes:
- Extend deferred ACP launch parameters to carry helper pipe-mode markers (
master_pipe_name,owner_tab_id) sotry_start_acpcan reconnect through wta-master after login. - Add a boot-time “pre-stash” in helper mode so post-FRE
LoginComplete -> try_start_acpusesrun_acp_client_over_pipeinstead ofrun_acp_client. - In
try_start_acp, add a pipe-mode reconnect branch that rebuilds thesession_hookchannel and spawns the pipe transport.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| tools/wta/src/main.rs | Pre-stashes helper pipe-mode ACP params so post-FRE reconnect uses the master pipe transport. |
| tools/wta/src/app.rs | Adds pipe-mode fields to deferred params and branches try_start_acp to reconnect via master pipe, rebuilding hook plumbing. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
…s PR Follows the existing convention in tools/wta/src/app.rs where every (tx, rx) pair from mpsc::unbounded_channel uses a short prefix + tx/rx name and is added to allow.txt (see ptx/prx, ntx/nrx, ltx/lrx, dtx/drx, rntx/rnrx, rtx/rrx, mrx). shtx/shrx = session_hook tx/rx, rebuilt in App::try_start_acp's pipe-mode reconnect branch. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
vanzue
approved these changes
Jun 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Symptom
After FRE, running
copilot(or any agent CLI) in tab 1's shell pane produces a session that tab 1's session view never shows, even though the underlying~/.copilot/session-state/<uuid>/dir exists and the hook fires correctly. Tabs 2/3 (opened after login) work fine and even see tab 1's session because their helpers reach master via the standard pipe. Repro from a user log (0.1.1522.0): *wta-main_helper-16548.log(tab 1's helper): * line 19:ERROR helper: run_acp_client_over_pipe failed error=... Authentication required* line 21:AgentError auth fallback: showing setup screen* line 23-29: user does FRE login,acp: try_start_acp triggered has_event_tx=true has_deferred=true* line 33 onward (every 5s, forever):WARN agents_view: sessions/list ext-request failed error=Error { code: -32601: Method not found, message: "\"Method not found\": _intellterm.wta/sessions/list", ... }— note the underscore prefix * line 43:WARN session_hook: failed to queue session_hook event for master error=channel closed*wta-main_master.log: helper 1 connects once at 06:46:44 then never again. The session for tab 1 (sid8514730f) only reaches master because tab 2's helper happens to forward the broadcast hook.Root cause
In helper mode (
--connect-master) the initialrun_acp_client_over_pipetask fails immediately withAuthentication requiredwhen the user is in FRE / not yet logged in. The post-loginLoginCompletehandler then firestry_start_acp, but that path was hard-wired to spawnrun_acp_client(direct mode) instead ofrun_acp_client_over_pipe. The reconnected helper: * spawns its own copilot CLI subprocess and bypasses wta-master entirely (never re-registers with master), * everyintellterm.wta/...ext-request fails withMethod not found— the ACP SDK forwards unknown extensions to the agent with a leading_, and the directly-spawned agent CLI doesn't know master-side extensions, * the alive-mirror never populates → the first tab's session view stays blank for the helper's lifetime, *session_hookpublishes logchannel closed(the rx was consumed and dropped with the failed initial task).Fix
Extend
DeferredAcpParamswithmaster_pipe_nameandowner_tab_id(None in direct mode). * NewApp::set_master_pipe_acp_params, called once at boot in helper mode frommain.rsto pre-stash pipe-mode params on App. *try_start_acpbranches onmaster_pipe_name.is_some(): * pipe-mode reconnect: rebuilds thesession_hookchannel, re-bindsself.session_hook_txso hooks reach master again, spawnsrun_acp_client_over_pipewith the original pipe / owner_tab. * direct-mode: unchanged. * Existingset_acp_paramsandLoginCompletedirect-mode synthesis paths just carry the two new fields asNone. Why pre-stash instead of recreating from scratch inLoginComplete: keeps the pipe-mode discovery in main.rs alongside the rest of the helper-mode wiring (single place that knows about--connect-master), andLoginComplete'sdeferred_acp.is_none()synthesis path stays purely about the legacy direct-mode FRE.Validation
Verified with a clean repro on
0.8.0.2:Logout helper (deletes the only "logged-in state" source — Windows Credential
Manager target
LegacyGeneric:target=copilot-cli/<host>:<user>— and~/.copilot/config.json):Repro / verify:
cmdkey /list | findstr copilotis empty.Log signature (single line, easy to grep for future regressions):
LoginComplete received: …wta-main_helper-23300.log)deferred_acp=false→ synthesizes direct-mode params →Spawning C:\…\copilot.exe… pid=Some(N)(own subprocess, bypasses master)wta-main_helper-26644.log)deferred_acp=true→try_start_acp: reconnecting via master pipe→run_acp_client_over_pipe→Session created (over pipe): <sid>→alive_mirror: alive session added by masterThe
deferred_acp=true|falseboolean on theLoginComplete receivedline is the canonical externally-visible signature of the pre-stash — any future regression of this code path will flip it back tofalse.cargo test --bin wta→ 698 passed locally onx86_64-pc-windows-msvc.Fixes #188.