Launch/Relaunch: stop opening duplicate terminals, stop the no-workspace relaunch loop, show the panel from the Tools menu - #26
Open
DaveTseng2019 wants to merge 5 commits into
Conversation
Repeated clicks on "Launch Claude Code" each spawned a brand-new terminal/CLI process with no check for an already-connected session. Guard LaunchClaudeAsync behind server.HasConnections; the "hooks & tools didn't load" banner's Relaunch button gets its own RelaunchAction that bypasses the guard, since that flow deliberately re-pins a misconfigured (but already connected) session. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The "hooks & tools didn't load" banner's Relaunch button promises to "pin the right folder," but if VS has no folder/workspace open there is no folder to pin - every relaunch just spawned another equally unpinned terminal that hit the same warning, inviting an endless click-relaunch-fail loop (reported after live testing). Refuse and tell the user to open a folder first instead of piling up dead terminals. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
External console is a standalone window the user explicitly asks for each time, and upstream allows unlimited concurrent external consoles - only the docked Launch button should refuse to pile up redundant terminals.
Tools -> "Launch Claude Code" is the only entry point a first-run user finds, and it started a session without ever surfacing the panel - so the toggles (auto-accept, debugger drive, screen capture), the attach tray and the usage stats stayed invisible until the user happened to find Tools -> "Claude Code Panel" as well. One click now does both. ShowPanel is factored out of OnShowPanel so both commands share it, and it runs AFTER the fire-and-forget launch: a panel that fails to open must not take the launch down with it. The panel's own Launch button doesn't route through here, so it can't re-show itself. Verified on the Exp hive: Tools -> Launch Claude Code opens the panel. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR tightens the Visual Studio extension’s launch/relaunch UX for the claude CLI by preventing accidental duplicate launches, avoiding a relaunch loop when no workspace is open, and ensuring the Claude panel is surfaced when launching from the Tools menu.
Changes:
- Add a dedicated
RelaunchActionpath to bypass the “already connected” guard for the “hooks & tools didn’t load” warning flow. - Add launch guards and a no-workspace relaunch refusal to prevent redundant terminals and an endless relaunch loop.
- Factor panel showing into a helper so Tools > Launch Claude Code also opens the panel.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/ClaudeCodeVS/Ui/ClaudeToolWindowControl.cs | Updates the warning banner button to invoke the new relaunch action. |
| src/ClaudeCodeVS/Ui/BridgeStatus.cs | Adds RelaunchAction to distinguish “re-pin” relaunch from normal launch/external launch. |
| src/ClaudeCodeVS/ClaudeCodeVsPackage.cs | Ensures Tools > Launch Claude Code also shows the panel via a shared ShowPanel() helper. |
| src/ClaudeCodeVS/BridgeHost.cs | Implements the connection guard exceptions (external + relaunch) and blocks relaunch when no workspace is open. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
580
to
582
| /// Prefers VS's native docked Terminal; <paramref name="forceExternal"/> skips it for users who want | ||
| /// a standalone console window (which, unlike the docked tab, survives closing VS). | ||
| /// </summary> |
Comment on lines
+591
to
+600
| // Guards the plain (docked) Launch button against piling up redundant terminals on repeat clicks | ||
| // while a session is already connected. External console is exempt - it's a standalone window the | ||
| // user explicitly asked for each time, and upstream allows unlimited concurrent external consoles. | ||
| // The "hooks & tools didn't load" banner's Relaunch button passes forceRelaunch=true to bypass this | ||
| // too - that flow is a deliberate re-pin of a *misconfigured* connected session, not an accidental duplicate. | ||
| if (!forceExternal && !forceRelaunch && _server?.HasConnections == true) | ||
| { | ||
| Log.Warn("Launch Claude Code: already connected - not opening another terminal."); | ||
| return; | ||
| } |
HasConnections only flips once the CLI's IDE WebSocket lands, so repeat clicks during the launch-to-handshake window still piled up terminals. Added a 10s launch cooldown on the same guarded path (sized to VsTerminalLauncher's stall timeout); External console and the banner's Relaunch stay exempt, as before. Also documented forceRelaunch in the XML doc. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Author
|
Thanks — both addressed in eecf0fa.
Verified in the Experimental hive: two Launch invocations 1.5s apart now produce exactly one |
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.
Re-submission of the launch-path fixes from the now-closed #24, split out so each PR is one reviewable topic. All four were found while using the extension.
The bugs
1. Duplicate terminals (
fix: guard Launch Claude Code against duplicate terminals)The panel's "Launch Claude Code" button never checked whether a session was already connected, so every press opened another terminal and another
claudeprocess.LaunchClaudeAsyncnow no-ops (with one log line) when_server.HasConnections.The warning card's "Relaunch Claude Code" button means something different - "this connection is pinned to the wrong folder, give me a correct one" - so it needs to bypass that guard. It gets its own
BridgeStatus.RelaunchActionwithforceRelaunch: true.2. Endless relaunch loop when no folder is open (
fix: don't relaunch into an endless loop when no workspace is open)The same warning card promises the relaunch "pins the right folder", but with no folder/workspace open in VS there is no right folder to pin. Each relaunch opened another terminal that tripped the same warning, so the user kept clicking.
LaunchClaudeAsyncnow refuses whenforceRelaunchis set andGetWorkspaceRootAsync()comes back empty, and says to open a folder first.3. External console blocked by the connected-guard (
fix: don't block External console when a session is already connected)Fallout from fix 1: "External console" deliberately launches a separate, VS-surviving window, so the already-connected guard must not apply to it.
4. Tools menu now shows the panel too (
feat: show the panel when launching from the Tools menu)Tools > "Launch Claude Code" is the only entry point a first-run user finds, and it started a session without ever surfacing the panel - so the safety toggles, the attach tray and the usage stats stayed invisible unless the user also found Tools > "Claude Code Panel".
ShowPanel()is factored out so both commands share it, and it runs after the fire-and-forget launch so a panel that fails to open cannot take the launch down with it.Verification
Done in the Experimental hive: pressing Launch twice opens one terminal (activity log shows "already connected - not opening another terminal"); relaunching with no workspace open no longer spawns processes; Tools > Launch Claude Code opens the panel. Release build clean.
🤖 Generated with Claude Code