fix(sync): reflect share status from global store after cancel (#1709)

* fix(sync): reflect share status from global store after cancel

Fix #1551: unshareSession() called updateLiveSession() which silently
fails when the child store doesn't exist. The sidebar rendered from the
child store first, showing stale share data. Now overlays the global
session's share field at merge points.

* fix(sync): extract shared mergeLiveSessionWithGlobalSession helper

Extracted the share-field overlay into a single shared helper in
useGlobalSessionsStore.ts. All 3 merge sites now use the helper
instead of duplicating the overlay logic.

* test(sync): add unit tests for mergeLiveSessionWithGlobalSession helper

---------

Co-authored-by: Leonid Skorobogatyy <bash@opencode.itc.local>
This commit is contained in:
bashrusakh
2026-06-23 22:18:44 +03:00
committed by GitHub
co-authored by Leonid Skorobogatyy
parent 5f3ef320d2
commit a25fc4c25a
5 changed files with 45 additions and 7 deletions
@@ -1,7 +1,7 @@
import React from 'react';
import { useSessionUIStore } from '@/sync/session-ui-store';
import { useAllSessionStatuses, useAllLiveSessions } from '@/sync/sync-context';
import { mergeSessionDirectoryMetadata, useGlobalSessionsStore, ensureGlobalSessionsLoaded, refreshGlobalSessions } from '@/stores/useGlobalSessionsStore';
import { mergeLiveSessionWithGlobalSession, useGlobalSessionsStore, ensureGlobalSessionsLoaded, refreshGlobalSessions } from '@/stores/useGlobalSessionsStore';
import { useUIStore } from '@/stores/useUIStore';
import { useProjectsStore } from '@/stores/useProjectsStore';
import type { Session } from '@opencode-ai/sdk/v2';
@@ -37,7 +37,7 @@ function useAllProjectSessions(): Session[] {
const liveById = new Map(liveSessions.map((session) => [session.id, session]));
const merged = globalActiveSessions.map((session) => {
const liveSession = liveById.get(session.id);
return liveSession ? mergeSessionDirectoryMetadata(liveSession, session) : session;
return liveSession ? mergeLiveSessionWithGlobalSession(liveSession, session) : session;
});
const seen = new Set(merged.map((session) => session.id));
for (const session of liveSessions) {
@@ -70,7 +70,7 @@ import {
normalizePath,
} from './sidebar/utils';
import {
mergeSessionDirectoryMetadata,
mergeLiveSessionWithGlobalSession,
refreshGlobalSessions,
refreshGlobalSessionsForDirectories,
resolveGlobalSessionDirectory,
@@ -361,7 +361,7 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
const liveById = new Map(liveSessions.map((session) => [session.id, session]));
const merged = globalActiveSessions.map((session) => {
const liveSession = liveById.get(session.id);
return liveSession ? mergeSessionDirectoryMetadata(liveSession, session) : session;
return liveSession ? mergeLiveSessionWithGlobalSession(liveSession, session) : session;
});
const seenIds = new Set(merged.map((session) => session.id));