/// import { beforeEach, describe, expect, it, mock } from "bun:test" import type { TmuxConfig } from "../../../config/schema" import type { TmuxCommandResult } from "../runner" const paneSpawnSpecifier = import.meta.resolve("./pane-spawn") const enabledTmuxConfig = { enabled: true, layout: "main-vertical", main_pane_size: 60, main_pane_min_width: 120, agent_pane_min_width: 40, isolation: "inline", } satisfies TmuxConfig const runTmuxCommandMock = mock(async (): Promise => ({ success: true, output: "%42", stdout: "%42", stderr: "", exitCode: 0, })) const isInsideTmuxMock = mock((): boolean => true) const isServerRunningMock = mock(async (): Promise => true) const getTmuxPathMock = mock(async (): Promise => "sh") const logMock = mock(() => undefined) function toStringArray(value: unknown): string[] { if (!Array.isArray(value)) { throw new Error("Expected array value") } const items: string[] = [] for (const item of value) { items.push(String(item)) } return items } function getRunTmuxCommandCall(index: number): [string, string[]] { const call = Reflect.get(runTmuxCommandMock.mock.calls, index) const command = Reflect.get(call, 0) const args = Reflect.get(call, 1) if (!Array.isArray(call) || typeof command !== "string" || !Array.isArray(args)) { throw new Error(`Expected tmux runner call at index ${index}`) } return [command, toStringArray(args)] } function getSplitWindowCommand(): string { const firstCall = getRunTmuxCommandCall(0) const splitCommand = firstCall[1][8] if (splitCommand === undefined) { throw new Error("Expected split-window command") } return splitCommand } function createDeps(): NonNullable[7]> { return { log: logMock, runTmuxCommand: runTmuxCommandMock, isInsideTmux: isInsideTmuxMock, isServerRunning: isServerRunningMock, getTmuxPath: getTmuxPathMock, } } async function loadSpawnTmuxPane(): Promise { const module = await import(`${paneSpawnSpecifier}?test=${crypto.randomUUID()}`) return module.spawnTmuxPane } describe("spawnTmuxPane runner integration", () => { beforeEach(() => { mock.restore() runTmuxCommandMock.mockClear() isInsideTmuxMock.mockClear() isServerRunningMock.mockClear() getTmuxPathMock.mockClear() logMock.mockClear() const tmuxCommandResults: TmuxCommandResult[] = [ { success: true, output: "%42", stdout: "%42", stderr: "", exitCode: 0 }, { success: true, output: "", stdout: "", stderr: "", exitCode: 0 }, ] runTmuxCommandMock.mockImplementation(async (): Promise => { const nextResult = tmuxCommandResults.shift() if (!nextResult) { throw new Error("No more tmux command results configured") } return nextResult }) isInsideTmuxMock.mockReturnValue(true) isServerRunningMock.mockResolvedValue(true) getTmuxPathMock.mockResolvedValue("sh") }) it("#given healthy tmux environment #when spawnTmuxPane called #then delegates split-window and select-pane to shared runner", async () => { // given const spawnTmuxPane = await loadSpawnTmuxPane() const directory = "/tmp/omo-project/(pane)" // when const result = await spawnTmuxPane("session-1", "worker", enabledTmuxConfig, "http://127.0.0.1:1234", directory, "%0", "-h", createDeps()) // then const firstCall = getRunTmuxCommandCall(0) const secondCall = getRunTmuxCommandCall(1) expect(result).toEqual({ success: true, paneId: "%42" }) expect(firstCall[1].slice(0, 8)).toEqual(["split-window", "-h", "-d", "-P", "-F", "#{pane_id}", "-t", "%0"]) expect(secondCall[1]).toEqual(["select-pane", "-t", "%42", "-T", "omo-subagent-worker"]) expect(getSplitWindowCommand()).toContain("Focus this pane to attach.") expect(getSplitWindowCommand()).toContain("tail -f /dev/null") expect(getSplitWindowCommand()).not.toContain("opencode attach") }) it("#given description with spaces #when spawnTmuxPane called #then includes it in the placeholder", async () => { // given const spawnTmuxPane = await loadSpawnTmuxPane() // when await spawnTmuxPane("session-1", "worker with spaces", enabledTmuxConfig, "http://127.0.0.1:1234", "/path with spaces/here", "%0", "-h", createDeps()) // then expect(getSplitWindowCommand()).toContain("OMO subagent pane ready: worker with spaces") }) it("#given empty directory #when spawnTmuxPane called #then keeps the placeholder detached from attach", async () => { // given const spawnTmuxPane = await loadSpawnTmuxPane() // when await spawnTmuxPane("session-1", "worker", enabledTmuxConfig, "http://127.0.0.1:1234", "", "%0", "-h", createDeps()) // then expect(getSplitWindowCommand()).not.toContain("--dir") }) it("#given description with shell metacharacters #when spawnTmuxPane called #then escapes the placeholder", async () => { // given const spawnTmuxPane = await loadSpawnTmuxPane() // when await spawnTmuxPane("session-1", 'worker "$(whoami)"', enabledTmuxConfig, "http://127.0.0.1:1234", "/path/with'quote", "%0", "-h", createDeps()) // then expect(getSplitWindowCommand()).toContain('\\"') expect(getSplitWindowCommand()).toContain("\\$") }) })