fix(vibe): only override the vibe snapshot when teardown lost the live toolset

The persisted pre-vibe snapshot was applied on every reconciliation that
re-entered vibe mode, including cold resumes and switches in from a non-vibe
session. Those paths build their toolset from the current CLI flags and
settings, so replacing it with a historical snapshot silently drops tools the
session was started with: resuming a session that entered vibe under
--tools read with --tools read,bash restored only read on exit.

Gate the override on the one case the snapshot exists for: the vibe -> vibe
switch, where #clearTransientModeState kept the already-reduced live set.
This commit is contained in:
Josh Mini
2026-08-09 11:23:07 +08:00
parent 1e142aace9
commit bb5bfb2c04
2 changed files with 78 additions and 1 deletions
@@ -2513,6 +2513,14 @@ export class InteractiveMode implements InteractiveModeContext {
this.#vibeModeOwnerScope?.ownerId === targetVibeScope.ownerId &&
this.#vibeModeOwnerScope.parentSessionId === targetVibeScope.parentSessionId &&
this.#vibeModeOwnerScope.parentSessionFile === targetVibeScope.parentSessionFile;
// #clearTransientModeState below keeps the live active set instead of
// applying a snapshot, so for a vibe -> vibe switch the live toolset is
// already the reduced vibe set and cannot serve as the pre-vibe snapshot.
// That is the only case the persisted snapshot is for: a cold resume or a
// switch in from a non-vibe session built its toolset from the current CLI
// flags and settings, and that set — not a historical one — is what exiting
// vibe must restore.
const vibeToolsetLostToTeardown = this.vibeModeEnabled && !preserveVibe;
await this.#clearTransientModeState({ preserveVibe, vibeScopeAlreadySuspended });
await VibeSessionRegistry.global().rehydrate(vibeSession);
const goalEnabled = this.session.settings.get("goal.enabled");
@@ -2552,7 +2560,9 @@ export class InteractiveMode implements InteractiveModeContext {
if (!preserveVibe) {
await this.#enterVibeMode({
persistModeChange: false,
previousTools: readPersistedToolNames(sessionContext.modeData?.previousTools),
previousTools: vibeToolsetLostToTeardown
? readPersistedToolNames(sessionContext.modeData?.previousTools)
: undefined,
});
}
return;