From 870babd252d4e0b919b79d658a18627b5c85bd45 Mon Sep 17 00:00:00 2001 From: Eva Date: Fri, 1 May 2026 23:08:31 +0700 Subject: [PATCH] fix: tighten session entry slot cleanup checks --- .../session-entry-projection.contract.test.ts | 14 ++++++++++---- src/plugins/host-hook-cleanup.ts | 6 +++++- src/plugins/session-entry-slot-keys.ts | 8 ++++++++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/plugins/contracts/session-entry-projection.contract.test.ts b/src/plugins/contracts/session-entry-projection.contract.test.ts index 551b1b57bf2..e0895fef400 100644 --- a/src/plugins/contracts/session-entry-projection.contract.test.ts +++ b/src/plugins/contracts/session-entry-projection.contract.test.ts @@ -162,8 +162,11 @@ describe("plugin session extension SessionEntry projection", () => { }), ).resolves.toMatchObject({ ok: true }); expect( - (loadSessionStore(storePath, { skipCache: true })["agent:main:main"] as never) - .approvalSnapshot, + ( + loadSessionStore(storePath, { skipCache: true })[ + "agent:main:main" + ] as unknown as Record + ).approvalSnapshot, ).toEqual({ state: "ready" }); await expect( @@ -195,8 +198,11 @@ describe("plugin session extension SessionEntry projection", () => { }), ).resolves.toMatchObject({ ok: true }); expect( - (loadSessionStore(storePath, { skipCache: true })["agent:main:main"] as never) - .approvalSnapshot, + ( + loadSessionStore(storePath, { skipCache: true })[ + "agent:main:main" + ] as unknown as Record + ).approvalSnapshot, ).toEqual({ state: "ready-again" }); await expect( diff --git a/src/plugins/host-hook-cleanup.ts b/src/plugins/host-hook-cleanup.ts index 294e3063da8..3fa2613a214 100644 --- a/src/plugins/host-hook-cleanup.ts +++ b/src/plugins/host-hook-cleanup.ts @@ -159,7 +159,11 @@ function collectSessionEntrySlotKeys( if (!shouldCleanPlugin(registration.pluginId, pluginId)) { continue; } - const normalized = normalizeSessionEntrySlotKey(registration.extension.sessionEntrySlotKey); + const slotKey = registration.extension.sessionEntrySlotKey; + if (slotKey === undefined) { + continue; + } + const normalized = normalizeSessionEntrySlotKey(slotKey); if (normalized.ok) { slotKeys.add(normalized.key); } diff --git a/src/plugins/session-entry-slot-keys.ts b/src/plugins/session-entry-slot-keys.ts index 5bdc06123a1..53b69187593 100644 --- a/src/plugins/session-entry-slot-keys.ts +++ b/src/plugins/session-entry-slot-keys.ts @@ -103,6 +103,14 @@ const SESSION_ENTRY_RESERVED_SLOT_KEY_LIST = [ "acp", ] as const satisfies ReadonlyArray; +type ReservedSessionEntrySlotKey = Extract< + (typeof SESSION_ENTRY_RESERVED_SLOT_KEY_LIST)[number], + keyof SessionEntry +>; +type MissingSessionEntryReservedSlotKeys = Exclude; +type AssertNever = T; +type _AssertAllSessionEntryKeysAreReserved = AssertNever; + const SESSION_ENTRY_RESERVED_SLOT_KEYS = new Set(SESSION_ENTRY_RESERVED_SLOT_KEY_LIST); const SESSION_ENTRY_SLOT_KEY_RE = /^[A-Za-z][A-Za-z0-9_]*$/u;