From 58e85960a103088cf9ff8bddb0c9a4c6b7efd7ad Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Sat, 4 Apr 2026 01:12:35 +0900 Subject: [PATCH] test(mcp): add regression coverage for transcript and disable overrides Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- .../claude-code-mcp-loader/loader.test.ts | 35 +++++++++ .../claude-code-hooks/transcript.test.ts | 78 +++++++++++++++++++ 2 files changed, 113 insertions(+) diff --git a/src/features/claude-code-mcp-loader/loader.test.ts b/src/features/claude-code-mcp-loader/loader.test.ts index 48ab1a288..4e7719cb6 100644 --- a/src/features/claude-code-mcp-loader/loader.test.ts +++ b/src/features/claude-code-mcp-loader/loader.test.ts @@ -138,6 +138,41 @@ describe("getSystemMcpServerNames", () => { } }) + it("removes a server name when a higher-precedence config disables it", async () => { + // given + writeFileSync(join(TEST_HOME, ".claude.json"), JSON.stringify({ + mcpServers: { + playwright: { + command: "npx", + args: ["@playwright/mcp@latest"], + }, + }, + })) + writeFileSync(join(TEST_DIR, ".mcp.json"), JSON.stringify({ + mcpServers: { + playwright: { + command: "npx", + args: ["@playwright/mcp@latest"], + disabled: true, + }, + }, + })) + + const originalCwd = process.cwd() + process.chdir(TEST_DIR) + + try { + // when + const { getSystemMcpServerNames } = await import("./loader") + const names = getSystemMcpServerNames() + + // then + expect(names.has("playwright")).toBe(false) + } finally { + process.chdir(originalCwd) + } + }) + it("merges server names from multiple .mcp.json files", async () => { // given mkdirSync(join(TEST_DIR, ".claude"), { recursive: true }) diff --git a/src/hooks/claude-code-hooks/transcript.test.ts b/src/hooks/claude-code-hooks/transcript.test.ts index a31aa3922..d7c4837f4 100644 --- a/src/hooks/claude-code-hooks/transcript.test.ts +++ b/src/hooks/claude-code-hooks/transcript.test.ts @@ -99,4 +99,82 @@ describe("transcript caching", () => { expect(client.session.messages).toHaveBeenCalledTimes(2) }) + + it("keeps intermediate tool calls across sequential transcript rebuilds", async () => { + // given + const client = createMockClient([]) + + // when + const firstPath = await buildTranscriptFromSession( + client, + "ses_sequential", + "/tmp", + "bash", + { command: "echo first" } + ) + const secondPath = await buildTranscriptFromSession( + client, + "ses_sequential", + "/tmp", + "read", + { filePath: "/tmp/second.txt" } + ) + const thirdPath = await buildTranscriptFromSession( + client, + "ses_sequential", + "/tmp", + "write", + { filePath: "/tmp/third.txt", content: "third" } + ) + + // then + expect(firstPath).not.toBeNull() + expect(secondPath).not.toBeNull() + expect(thirdPath).not.toBeNull() + + if (thirdPath) { + const content = readFileSync(thirdPath, "utf-8") + + expect(content).toContain("Bash") + expect(content).toContain("Read") + expect(content).toContain("Write") + } + + deleteTempTranscript(firstPath) + deleteTempTranscript(secondPath) + deleteTempTranscript(thirdPath) + }) + + it("cleans up previous temp transcript files when rebuilding cached transcripts", async () => { + // given + const client = createMockClient([]) + + // when + const firstPath = await buildTranscriptFromSession( + client, + "ses_cleanup", + "/tmp", + "bash", + { command: "echo first" } + ) + const secondPath = await buildTranscriptFromSession( + client, + "ses_cleanup", + "/tmp", + "read", + { filePath: "/tmp/second.txt" } + ) + + // then + expect(firstPath).not.toBeNull() + expect(secondPath).not.toBeNull() + + if (firstPath && secondPath) { + expect(existsSync(firstPath)).toBe(false) + expect(existsSync(secondPath)).toBe(true) + } + + deleteTempTranscript(firstPath) + deleteTempTranscript(secondPath) + }) })