Summary
xcode_tools_bridge_disconnect is documented as the tool that disconnects the Xcode IDE bridge and unregisters proxied xcode_tools_* tools.
On the current latest release (v2.3.2, released 2026-03-31), the manual disconnect path still triggers the bridge invalidation callback, which schedules syncTools({ reason: "listChanged" }) again.
That means the disconnect flow can immediately fall back into the same auto-resync path that is supposed to be used for remote tool catalog changes, not for an explicit manual disconnect.
Why this looks like a bug
This seems to violate the current contract of the xcode-ide bridge tools:
xcode_tools_bridge_disconnect is described as: Disconnect bridge and unregister proxied xcode_tools_* tools.
xcode_tools_bridge_sync is described as the explicit manual retry path: One-shot connect + tools/list sync (manual retry; avoids background prompt spam).
If disconnect still allows the listChanged invalidation path to schedule a resync, those two tools no longer have clearly separated semantics.
It also appears to conflict with the repo's broader lifecycle direction in recent fixes (#273 / #274): bounded and deterministic bridge/server behavior, rather than surprising reconnects during teardown or manual disconnect flows.
Actual behavior
During local verification in my fork, I patched a minimal repro around XcodeToolsBridgeManager.disconnectTool() and observed this call order:
registry.clear
service.disconnect
syncTools({ reason: "listChanged" })
I also added a temporary regression test asserting that a manual disconnect should not call syncTools({ reason: "listChanged" }), and the test failed because the sync path was invoked once.
Expected behavior
After xcode_tools_bridge_disconnect:
- the bridge should remain disconnected
- proxied
xcode_tools_* tools should stay unregistered
- no automatic
listChanged resync should run as part of that manual disconnect path
- the next re-sync should happen only through an explicit/manual bridge action such as
xcode_tools_bridge_sync
Relevant code path
src/integrations/xcode-tools-bridge/client.ts
src/integrations/xcode-tools-bridge/tool-service.ts
src/integrations/xcode-tools-bridge/manager.ts
The critical flow appears to be:
disconnect() calls service.disconnect()
- bridge close triggers
onBridgeClosed
onBridgeClosed forwards to onToolCatalogInvalidated
manager handles that with void this.syncTools({ reason: "listChanged" })
Version checked
- latest release:
v2.3.2
- also reproduced locally against current
upstream/main checked out in my fork/worktree before preparing a fix
Note
I have a narrow fix plus regression test ready and can open a PR that suppresses listChanged-driven resync while a manual bridge disconnect is in progress.
Summary
xcode_tools_bridge_disconnectis documented as the tool that disconnects the Xcode IDE bridge and unregisters proxiedxcode_tools_*tools.On the current latest release (
v2.3.2, released 2026-03-31), the manual disconnect path still triggers the bridge invalidation callback, which schedulessyncTools({ reason: "listChanged" })again.That means the disconnect flow can immediately fall back into the same auto-resync path that is supposed to be used for remote tool catalog changes, not for an explicit manual disconnect.
Why this looks like a bug
This seems to violate the current contract of the xcode-ide bridge tools:
xcode_tools_bridge_disconnectis described as:Disconnect bridge and unregister proxied xcode_tools_* tools.xcode_tools_bridge_syncis described as the explicit manual retry path:One-shot connect + tools/list sync (manual retry; avoids background prompt spam).If
disconnectstill allows thelistChangedinvalidation path to schedule a resync, those two tools no longer have clearly separated semantics.It also appears to conflict with the repo's broader lifecycle direction in recent fixes (
#273/#274): bounded and deterministic bridge/server behavior, rather than surprising reconnects during teardown or manual disconnect flows.Actual behavior
During local verification in my fork, I patched a minimal repro around
XcodeToolsBridgeManager.disconnectTool()and observed this call order:registry.clearservice.disconnectsyncTools({ reason: "listChanged" })I also added a temporary regression test asserting that a manual disconnect should not call
syncTools({ reason: "listChanged" }), and the test failed because the sync path was invoked once.Expected behavior
After
xcode_tools_bridge_disconnect:xcode_tools_*tools should stay unregisteredlistChangedresync should run as part of that manual disconnect pathxcode_tools_bridge_syncRelevant code path
src/integrations/xcode-tools-bridge/client.tssrc/integrations/xcode-tools-bridge/tool-service.tssrc/integrations/xcode-tools-bridge/manager.tsThe critical flow appears to be:
disconnect()callsservice.disconnect()onBridgeClosedonBridgeClosedforwards toonToolCatalogInvalidatedmanagerhandles that withvoid this.syncTools({ reason: "listChanged" })Version checked
v2.3.2upstream/mainchecked out in my fork/worktree before preparing a fixNote
I have a narrow fix plus regression test ready and can open a PR that suppresses
listChanged-driven resync while a manual bridge disconnect is in progress.