diff --git a/src/features/hook-message-injector/injector.test.ts b/src/features/hook-message-injector/injector.test.ts index fffdf5a7..c66d18d9 100644 --- a/src/features/hook-message-injector/injector.test.ts +++ b/src/features/hook-message-injector/injector.test.ts @@ -4,6 +4,8 @@ import { findFirstMessageWithAgent, findNearestMessageWithFieldsFromSDK, findFirstMessageWithAgentFromSDK, + generateMessageId, + generatePartId, injectHookMessage, } from "./injector" import { isSqliteBackend, resetSqliteBackendCache } from "../../shared/opencode-storage-detection" @@ -192,6 +194,38 @@ describe("findFirstMessageWithAgentFromSDK", () => { }) }) +describe("generateMessageId", () => { + it("returns deterministic sequential IDs with fixed format", () => { + // given + const format = /^msg_\d{12}$/ + + // when + const firstId = generateMessageId() + const secondId = generateMessageId() + + // then + expect(firstId).toMatch(format) + expect(secondId).toMatch(format) + expect(Number(secondId.slice(4))).toBe(Number(firstId.slice(4)) + 1) + }) +}) + +describe("generatePartId", () => { + it("returns deterministic sequential IDs with fixed format", () => { + // given + const format = /^prt_\d{12}$/ + + // when + const firstId = generatePartId() + const secondId = generatePartId() + + // then + expect(firstId).toMatch(format) + expect(secondId).toMatch(format) + expect(Number(secondId.slice(4))).toBe(Number(firstId.slice(4)) + 1) + }) +}) + describe("injectHookMessage", () => { beforeEach(() => { vi.clearAllMocks() diff --git a/src/features/hook-message-injector/injector.ts b/src/features/hook-message-injector/injector.ts index 8f4e0d57..68520007 100644 --- a/src/features/hook-message-injector/injector.ts +++ b/src/features/hook-message-injector/injector.ts @@ -29,6 +29,9 @@ interface SDKMessage { } } +let messageCounter = 0 +let partCounter = 0 + function convertSDKMessageToStoredMessage(msg: SDKMessage): StoredMessage | null { const info = msg.info if (!info) return null @@ -204,16 +207,12 @@ export function findFirstMessageWithAgent(messageDir: string): string | null { return null } -function generateMessageId(): string { - const timestamp = Date.now().toString(16) - const random = Math.random().toString(36).substring(2, 14) - return `msg_${timestamp}${random}` +export function generateMessageId(): string { + return `msg_${String(++messageCounter).padStart(12, "0")}` } -function generatePartId(): string { - const timestamp = Date.now().toString(16) - const random = Math.random().toString(36).substring(2, 10) - return `prt_${timestamp}${random}` +export function generatePartId(): string { + return `prt_${String(++partCounter).padStart(12, "0")}` } function getOrCreateMessageDir(sessionID: string): string {