mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
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:
@@ -159,6 +159,9 @@ export default {
|
||||
'session.action.export': 'Export conversation',
|
||||
'session.action.archive': 'Archive',
|
||||
'session.action.reopen': 'Reopen',
|
||||
'session.action.reopenCursorChecking': 'Checking whether Cursor chat data is still available on the recorded machine.',
|
||||
'session.action.reopenCursorMissing': 'Cursor chat data is no longer available on the recorded machine.',
|
||||
'session.action.reopenCursorCheckFailed': 'Could not verify Cursor chat data on the recorded machine.',
|
||||
'session.action.delete': 'Delete',
|
||||
'session.action.copy': 'Copy',
|
||||
|
||||
|
||||
@@ -159,6 +159,9 @@ export default {
|
||||
'session.action.export': '导出对话',
|
||||
'session.action.archive': '归档',
|
||||
'session.action.reopen': '重新打开',
|
||||
'session.action.reopenCursorChecking': '正在检查记录设备上的 Cursor 聊天数据是否仍然可用。',
|
||||
'session.action.reopenCursorMissing': '记录设备上的 Cursor 聊天数据已不可用。',
|
||||
'session.action.reopenCursorCheckFailed': '无法验证记录设备上的 Cursor 聊天数据。',
|
||||
'session.action.delete': '删除',
|
||||
'session.action.copy': '复制',
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ export const queryKeys = {
|
||||
slashCommands: (sessionId: string) => ['slash-commands', sessionId] as const,
|
||||
sessionCodexModels: (sessionId: string) => ['session-codex-models', sessionId] as const,
|
||||
sessionCursorModels: (sessionId: string) => ['session-cursor-models', sessionId] as const,
|
||||
sessionCursorChatStore: (sessionId: string) => ['session-cursor-chat-store', sessionId] as const,
|
||||
sessionPiModels: (sessionId: string) => ['session-pi-models', sessionId] as const,
|
||||
machineCursorModels: (machineId: string) => ['machine-cursor-models', machineId] as const,
|
||||
sessionOpencodeModels: (sessionId: string) => ['session-opencode-models', sessionId] as const,
|
||||
|
||||
@@ -64,7 +64,40 @@ describe('sessionResume', () => {
|
||||
flavor: 'cursor',
|
||||
cursorSessionId: 'cursor-thread-1',
|
||||
},
|
||||
}), 5)).toBe(true)
|
||||
}), 5, true)).toBe(true)
|
||||
})
|
||||
|
||||
it('conservatively rejects cursor resume until the chat store is verified', () => {
|
||||
expect(inactiveSessionCanResume(makeSession({
|
||||
metadata: {
|
||||
path: '/tmp/project',
|
||||
host: 'localhost',
|
||||
flavor: 'cursor',
|
||||
cursorSessionId: 'cursor-thread-1',
|
||||
},
|
||||
}), 5)).toBe(false)
|
||||
})
|
||||
|
||||
it('rejects cursor resume when the recorded chat store is missing on its machine', () => {
|
||||
expect(inactiveSessionCanResume(makeSession({
|
||||
metadata: {
|
||||
path: '/tmp/project',
|
||||
host: 'localhost',
|
||||
flavor: 'cursor',
|
||||
cursorSessionId: 'cursor-thread-1',
|
||||
},
|
||||
}), 5, false)).toBe(false)
|
||||
})
|
||||
|
||||
it('does not apply Cursor chat store status to other agent flavors', () => {
|
||||
expect(inactiveSessionCanResume(makeSession({
|
||||
metadata: {
|
||||
path: '/tmp/project',
|
||||
host: 'localhost',
|
||||
flavor: 'codex',
|
||||
codexSessionId: 'codex-thread-1',
|
||||
},
|
||||
}), 5, false)).toBe(true)
|
||||
})
|
||||
|
||||
it('resolveAgentSessionIdFromMetadata still returns cursorSessionId regardless of protocol', () => {
|
||||
|
||||
@@ -34,6 +34,7 @@ export function resolveAgentSessionIdFromMetadata(
|
||||
export function inactiveSessionCanResume(
|
||||
session: Session,
|
||||
userMessageCount: number,
|
||||
cursorChatOnDisk?: boolean,
|
||||
): boolean {
|
||||
if (session.active) {
|
||||
return true
|
||||
@@ -42,6 +43,10 @@ export function inactiveSessionCanResume(
|
||||
return false
|
||||
}
|
||||
if (resolveAgentSessionIdFromMetadata(session.metadata)) {
|
||||
const flavor = isKnownFlavor(session.metadata.flavor) ? session.metadata.flavor : 'claude'
|
||||
if (flavor === 'cursor') {
|
||||
return cursorChatOnDisk === true
|
||||
}
|
||||
return true
|
||||
}
|
||||
const flavor = isKnownFlavor(session.metadata.flavor) ? session.metadata.flavor : 'claude'
|
||||
|
||||
Reference in New Issue
Block a user