diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-07-18 23:46:34 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-07-18 23:56:20 +0300 |
| commit | a51a15914a5b29155022a1fd589d2bcc6409cadf (patch) | |
| tree | 8602b6d94c811666d49e4c2aa7636bb6a9b0e8a3 /src/integration/assets/herdr-agent-state.test.ts | |
| parent | 60c040057e3949ae93ee88d495df09b4b848d22d (diff) | |
fix: support javascript integrations on windows
refs #1531
Diffstat (limited to 'src/integration/assets/herdr-agent-state.test.ts')
| -rw-r--r-- | src/integration/assets/herdr-agent-state.test.ts | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/src/integration/assets/herdr-agent-state.test.ts b/src/integration/assets/herdr-agent-state.test.ts index c662e132..50f1fc52 100644 --- a/src/integration/assets/herdr-agent-state.test.ts +++ b/src/integration/assets/herdr-agent-state.test.ts @@ -1,9 +1,11 @@ import { afterEach, expect, test } from "bun:test"; import { rm } from "node:fs/promises"; -import { createServer, type Server } from "node:net"; +import net, { createServer, type Server } from "node:net"; import { tmpdir } from "node:os"; import { join } from "node:path"; +const originalPlatform = process.platform; +const originalCreateConnection = net.createConnection; const originalEnvironment = { HERDR_ENV: process.env.HERDR_ENV, HERDR_OMP_IDLE_DEBOUNCE_MS: process.env.HERDR_OMP_IDLE_DEBOUNCE_MS, @@ -30,6 +32,8 @@ afterEach(async () => { socketPath = undefined; } + Object.defineProperty(process, "platform", { value: originalPlatform }); + net.createConnection = originalCreateConnection; for (const [name, value] of Object.entries(originalEnvironment)) { if (value === undefined) { delete process.env[name]; @@ -44,6 +48,15 @@ const integrations = [ { name: "Oh My Pi", modulePath: "./omp/herdr-agent-state.ts" }, ] as const; +const socketPlugins = [ + { + name: "OpenCode", + modulePath: "./opencode/herdr-agent-state.js", + sessionID: "opencode-session", + }, + { name: "Kilo", modulePath: "./kilo/herdr-agent-state.js", sessionID: "kilo-session" }, +] as const; + function importFresh(modulePath: string) { importCounter += 1; return import(`${modulePath}?test=${importCounter}`); @@ -74,6 +87,15 @@ function configureIntegrationEnvironment(recordingSocketPath: string) { process.env.HERDR_PANE_ID = "test:p1"; } +function captureConnectionEndpoint() { + let connectedEndpoint: unknown; + net.createConnection = ((...args: unknown[]) => { + connectedEndpoint = args[0]; + return Reflect.apply(originalCreateConnection, net, args); + }) as typeof net.createConnection; + return () => connectedEndpoint; +} + async function startRecordingServer(name: string): Promise<unknown[]> { const recordingSocketPath = join(tmpdir(), `herdr-${name}-${process.pid}.sock`); socketPath = recordingSocketPath; @@ -102,7 +124,61 @@ async function startRecordingServer(name: string): Promise<unknown[]> { return requests; } +for (const socketPlugin of socketPlugins) { + test(`${socketPlugin.name} maps the Windows socket marker path to a named pipe endpoint`, async () => { + const markerPath = `herdr-${socketPlugin.name.toLowerCase()}-${process.pid}.sock`; + configureIntegrationEnvironment(markerPath); + Object.defineProperty(process, "platform", { value: "win32" }); + const connectedEndpoint = captureConnectionEndpoint(); + + const { HerdrAgentStatePlugin } = await importFresh(socketPlugin.modulePath); + const plugin = await HerdrAgentStatePlugin(); + await plugin.event({ + event: { + type: "session.updated", + properties: { sessionID: socketPlugin.sessionID }, + }, + }); + + expect(connectedEndpoint()).toBe(`\\\\.\\pipe\\${markerPath}`); + }); +} + +test("OpenCode stays disabled without the Herdr socket environment", async () => { + process.env.HERDR_ENV = "1"; + process.env.HERDR_PANE_ID = "test:p1"; + delete process.env.HERDR_SOCKET_PATH; + + const { HerdrAgentStatePlugin } = await importFresh("./opencode/herdr-agent-state.js"); + + expect(await HerdrAgentStatePlugin()).toEqual({}); +}); + for (const integration of integrations) { + test(`${integration.name} maps the Windows socket marker path to a named pipe endpoint`, async () => { + const markerPath = `herdr-${integration.name.toLowerCase().replaceAll(" ", "-")}-${process.pid}.sock`; + configureIntegrationEnvironment(markerPath); + Object.defineProperty(process, "platform", { value: "win32" }); + const connectedEndpoint = captureConnectionEndpoint(); + const { handlers, pi } = createExtensionHarness(); + + const { default: install } = await importFresh(integration.modulePath); + install(pi); + await handlers.get("session_start")?.( + { reason: "startup" }, + { + hasUI: true, + isIdle: () => true, + sessionManager: { + getSessionFile: () => undefined, + getSessionId: () => "test-session", + }, + }, + ); + + expect(connectedEndpoint()).toBe(`\\\\.\\pipe\\${markerPath}`); + }); + test(`${integration.name} reload preserves working state when the agent is active`, async () => { const requests = await startRecordingServer( integration.name.toLowerCase().replaceAll(" ", "-"), |
