From 1e3e07737032a8f5f38dd8c0f2474fa612f9fd34 Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Wed, 22 Apr 2026 15:13:09 +0530 Subject: [PATCH] fix(gateway): preserve cli session binding metadata --- src/gateway/server-methods/agent.ts | 1 + ...erver.agent.gateway-server-agent-b.test.ts | 58 +++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/src/gateway/server-methods/agent.ts b/src/gateway/server-methods/agent.ts index e6b114794b9..a8dad53a799 100644 --- a/src/gateway/server-methods/agent.ts +++ b/src/gateway/server-methods/agent.ts @@ -688,6 +688,7 @@ export const agentHandlers: GatewayRequestHandlers = { groupChannel: resolvedGroupChannel ?? entry?.groupChannel, space: resolvedGroupSpace ?? entry?.space, cliSessionIds: entry?.cliSessionIds, + cliSessionBindings: entry?.cliSessionBindings, claudeCliSessionId: entry?.claudeCliSessionId, }; sessionEntry = mergeSessionEntry(entry, nextEntryPatch); diff --git a/src/gateway/server.agent.gateway-server-agent-b.test.ts b/src/gateway/server.agent.gateway-server-agent-b.test.ts index 67293eb25d1..a417793b5ac 100644 --- a/src/gateway/server.agent.gateway-server-agent-b.test.ts +++ b/src/gateway/server.agent.gateway-server-agent-b.test.ts @@ -223,6 +223,64 @@ describe("gateway server agent", () => { }); }); + test("agent preserves CLI session binding metadata when refreshing session state", async () => { + await useTempSessionStorePath(); + await writeSessionStore({ + entries: { + main: { + sessionId: "sess-cli", + updatedAt: Date.now(), + modelProvider: "claude-cli", + model: "claude-opus-4-6", + cliSessionIds: { + "claude-cli": "cli-session-123", + }, + cliSessionBindings: { + "claude-cli": { + sessionId: "cli-session-123", + authProfileId: "anthropic:work", + mcpConfigHash: "mcp-config-hash", + mcpResumeHash: "mcp-resume-hash", + }, + }, + claudeCliSessionId: "cli-session-123", + }, + }, + }); + + const res = await rpcReq(ws, "agent", { + message: "hi", + sessionKey: "main", + idempotencyKey: "idem-agent-cli-binding", + }); + expect(res.ok).toBe(true); + + const sessionStorePath = testState.sessionStorePath; + if (!sessionStorePath) { + throw new Error("expected session store path"); + } + const stored = JSON.parse(await fs.readFile(sessionStorePath, "utf-8")) as Record< + string, + { + cliSessionBindings?: Record; + cliSessionIds?: Record; + claudeCliSessionId?: string; + } + >; + expect(stored["agent:main:main"]?.cliSessionBindings).toEqual({ + "claude-cli": { + sessionId: "cli-session-123", + authProfileId: "anthropic:work", + mcpConfigHash: "mcp-config-hash", + mcpResumeHash: "mcp-resume-hash", + }, + }); + expect(stored["agent:main:main"]?.cliSessionIds).toEqual({ + "claude-cli": "cli-session-123", + }); + expect(stored["agent:main:main"]?.claudeCliSessionId).toBe("cli-session-123"); + }); + test("agent accepts built-in channel alias (imsg)", async () => { const registry = createRegistry([ {