fix: verify Cursor chat store before reopen (#1037)

* test: reproduce issue #841

* test: cover Cursor chat store discovery

* fix: verify Cursor chat store before resume (closes #841)

* test: preserve non-Cursor resume behavior

* test: cover conservative Cursor resume gating

* fix: gate Cursor reopen until store verification

* test: cover legacy Cursor drawer fallback

* fix: scan unique legacy Cursor store drawer

* test: preserve raw Cursor workspace path hashing

* fix: hash raw Cursor workspace path

* test: pin Cursor probe owner and machine

* fix: probe Cursor store on recorded owner

* test: normalize Cursor probe owner home

* fix: normalize Cursor probe owner home
This commit is contained in:
SSU-WEI HUANG
2026-07-16 12:34:41 +08:00
committed by GitHub
parent adb6f41858
commit 520c3f511a
27 changed files with 955 additions and 34 deletions
@@ -0,0 +1,58 @@
import { useQuery } from '@tanstack/react-query'
import type { ApiClient } from '@/api/client'
import type { CursorChatStoreStatus, Session, SessionSummary } from '@/types/api'
import { queryKeys } from '@/lib/query-keys'
type CursorChatStoreSession = Pick<Session | SessionSummary, 'id' | 'active' | 'metadata'>
export function useCursorChatStoreStatus(args: {
api: ApiClient | null
session: CursorChatStoreSession | null
enabled?: boolean
}): {
status: CursorChatStoreStatus | undefined
isApplicable: boolean
isLoading: boolean
error: string | null
} {
const { api, session } = args
const metadata = session?.metadata
const cursorSessionId = metadata && 'cursorSessionId' in metadata
? metadata.cursorSessionId
: metadata && 'agentSessionId' in metadata
? metadata.agentSessionId
: undefined
const shouldProbe = Boolean(
session
&& !session.active
&& metadata?.flavor === 'cursor'
&& cursorSessionId
&& metadata.path
)
const enabled = Boolean((args.enabled ?? true) && api && shouldProbe)
const sessionId = session?.id ?? 'unknown'
const query = useQuery({
queryKey: queryKeys.sessionCursorChatStore(sessionId),
queryFn: async () => {
if (!api || !session) {
throw new Error('Cursor session unavailable')
}
return await api.getCursorChatStoreStatus(session.id)
},
enabled,
staleTime: 5_000,
retry: false,
})
return {
status: query.data,
isApplicable: shouldProbe,
isLoading: query.isLoading,
error: query.error instanceof Error
? query.error.message
: query.error
? 'Failed to inspect Cursor chat store'
: null,
}
}