diff --git a/server/codex-app-server.js b/server/codex-app-server.js index ca0ba0f..d1fdfb4 100644 --- a/server/codex-app-server.js +++ b/server/codex-app-server.js @@ -386,7 +386,8 @@ function isArchivedOrDeletedDesktopThread(thread = null) { if (!thread || typeof thread !== 'object') { return true; } - const status = String(thread.status || '').toLowerCase(); + const statusValue = typeof thread.status === 'string' ? thread.status : thread.status?.type; + const status = String(statusValue || '').toLowerCase(); const archivedAt = String(thread.archivedAt || thread.deletedAt || thread.archived_at || thread.deleted_at || '').trim(); const deletedFlag = Boolean(thread.deleted) || Boolean(thread.isDeleted) || status === 'deleted' || status === 'archived'; const archivedFlag = Boolean(thread.archived) || Boolean(thread.isArchived) || status === 'archived'; diff --git a/server/codex-app-server.test.mjs b/server/codex-app-server.test.mjs index 30e684e..86a3a97 100644 --- a/server/codex-app-server.test.mjs +++ b/server/codex-app-server.test.mjs @@ -27,6 +27,8 @@ test('filterDesktopThreadsForArchiveMode keeps archived threads only for archive { id: 'open-1', status: 'completed' }, { id: 'archived-1', status: 'archived' }, { id: 'archived-2', archived: true }, + { id: 'archived-3', status: { type: 'archived' } }, + { id: 'deleted-1', status: { type: 'deleted' } }, { status: 'archived' } ]; @@ -34,7 +36,9 @@ test('filterDesktopThreadsForArchiveMode keeps archived threads only for archive assert.deepEqual(filterDesktopThreadsForArchiveMode(threads, { archived: true }).map((thread) => thread.id), [ 'open-1', 'archived-1', - 'archived-2' + 'archived-2', + 'archived-3', + 'deleted-1' ]); }); diff --git a/server/codex-data.js b/server/codex-data.js index 0a2dfbe..dd6d72d 100644 --- a/server/codex-data.js +++ b/server/codex-data.js @@ -58,7 +58,7 @@ export { messagesFromDesktopThread } from './desktop-thread-projector.js'; export { normalizeComparablePath } from './session-index-builder.js'; const INCLUDE_MISSING_SUBAGENT_THREADS = process.env.CODEXMOBILE_INCLUDE_MISSING_SUBAGENT_THREADS === '1'; -const USE_APP_SERVER_THREAD_LIST = /^(1|true|yes|on)$/i.test(String(process.env.CODEXMOBILE_USE_APP_SERVER_THREAD_LIST || '').trim()); +const USE_LOCAL_THREAD_SCAN = /^(1|true|yes|on)$/i.test(String(process.env.CODEXMOBILE_USE_LOCAL_THREAD_SCAN || '').trim()); const execFileAsync = promisify(execFile); const LOCAL_THREAD_SCAN_LIMIT = 1000; const LOCAL_THREAD_HEAD_BYTES = 512 * 1024; @@ -458,7 +458,7 @@ async function listLocalDesktopThreadsFromJsonl({ limit = LOCAL_THREAD_SCAN_LIMI } async function listDesktopThreadsForCache() { - if (!USE_APP_SERVER_THREAD_LIST) { + if (USE_LOCAL_THREAD_SCAN) { return listLocalDesktopThreadsFromJsonl({ limit: LOCAL_THREAD_SCAN_LIMIT }); } const remote = listDesktopThreads({ limit: 1000 }) diff --git a/server/session-index-builder.js b/server/session-index-builder.js index 02bf641..0a802c8 100644 --- a/server/session-index-builder.js +++ b/server/session-index-builder.js @@ -120,7 +120,8 @@ function isArchivedOrDeletedDesktopThread(thread = null) { if (!thread || typeof thread !== 'object') { return true; } - const status = String(thread.status || '').toLowerCase(); + const statusValue = typeof thread.status === 'string' ? thread.status : thread.status?.type; + const status = String(statusValue || '').toLowerCase(); const archivedAt = String(thread.archivedAt || thread.deletedAt || thread.archiveAt || thread.archived_at || thread.deleted_at || '').trim(); const deletedAt = String(thread.deletedAt || thread.deleted_at || '').trim(); const flaggedDeleted = Boolean(thread.deleted) || Boolean(thread.isDeleted) || status === 'deleted' || status === 'archived'; diff --git a/server/session-index-builder.test.mjs b/server/session-index-builder.test.mjs index f2b4d19..f24bfef 100644 --- a/server/session-index-builder.test.mjs +++ b/server/session-index-builder.test.mjs @@ -135,6 +135,14 @@ test('session index builder preserves project ordering, projectless sessions, hi status: 'archived', updatedAt: 1_800_000_040, source: 'vscode' + }, + { + id: 'archived-object-status', + cwd: projectB, + name: 'archived object status', + status: { type: 'archived' }, + updatedAt: 1_800_000_041, + source: 'vscode' } ], spawnEdges: [ @@ -168,6 +176,7 @@ test('session index builder preserves project ordering, projectless sessions, hi assert.equal(index.projectById.get(projectAId).sessionCount, 3); assert.equal(index.sessionById.has('hidden-1'), false); assert.equal(index.sessionById.has('archived-1'), false); + assert.equal(index.sessionById.has('archived-object-status'), false); const parent = index.sessionById.get('parent-1'); assert.equal(parent.title, '手机标题');