diff --git a/src/features/tmux-subagent/session-created-handler.test.ts b/src/features/tmux-subagent/session-created-handler.test.ts
index 8b0fdd4aa..77b8c2782 100644
--- a/src/features/tmux-subagent/session-created-handler.test.ts
+++ b/src/features/tmux-subagent/session-created-handler.test.ts
@@ -1,11 +1,6 @@
-import { describe, test, expect, mock, afterEach } from "bun:test"
+///
-// ---------------------------------------------------------------------------
-// Module-level mocks — must be registered BEFORE importing the handler so the
-// handler picks up the mocked exports instead of the real implementations.
-// queryWindowState and executeActions hit real tmux/spawn subprocesses; we
-// replace them with spies so the spawn path can actually be exercised in tests.
-// ---------------------------------------------------------------------------
+import { describe, test, expect, mock, afterEach } from "bun:test"
const mockQueryWindowState = mock(async (_paneId: string) => ({
windowWidth: 244,
@@ -20,9 +15,6 @@ const mockExecuteActions = mock(async (_actions: unknown[], _ctx: unknown) => ({
results: [],
}))
-mock.module("./pane-state-querier", () => ({ queryWindowState: mockQueryWindowState }))
-mock.module("./action-executor", () => ({ executeActions: mockExecuteActions }))
-
import type { SessionCreatedHandlerDeps } from "./session-created-handler"
import { handleSessionCreated } from "./session-created-handler"
import type { SessionCreatedEvent } from "./session-created-event"
@@ -50,12 +42,6 @@ function makeDeps(overrides: Partial = {}): {
mockExecuteActions: ReturnType
mockWaitForSessionReady: ReturnType
} {
- const mockExecuteActions = mock(async () => ({
- success: true,
- spawnedPaneId: "%99",
- results: [],
- }))
-
const mockWaitForSessionReady = mock(async (_sessionId: string) => true)
const deps: SessionCreatedHandlerDeps = {
@@ -72,6 +58,8 @@ function makeDeps(overrides: Partial = {}): {
getSessionMappings: () => [],
waitForSessionReady: mockWaitForSessionReady,
startPolling: mock(() => {}),
+ queryWindowState: mockQueryWindowState,
+ executeActions: mockExecuteActions,
...overrides,
}
@@ -132,7 +120,7 @@ describe("handleSessionCreated – #3505 session readiness race", () => {
callLog.push("waitForSessionReady:end")
return ready
})
- mockExecuteActions.mockImplementation(async (_actions, _ctx) => {
+ mockExecuteActions.mockImplementation(async (_actions: unknown[], _ctx: unknown) => {
callLog.push("executeActions")
return { success: true, spawnedPaneId: "%99", results: [] }
})
@@ -195,6 +183,7 @@ describe("handleSessionCreated – #3505 session readiness race", () => {
sessionId: "ses_existing",
paneId: "%5",
description: "TestAgent",
+ attachActivated: false,
createdAt: new Date(),
lastSeenAt: new Date(),
closePending: false,
diff --git a/src/features/tmux-subagent/session-created-handler.ts b/src/features/tmux-subagent/session-created-handler.ts
index 1d806ecc7..a4a08639d 100644
--- a/src/features/tmux-subagent/session-created-handler.ts
+++ b/src/features/tmux-subagent/session-created-handler.ts
@@ -25,6 +25,8 @@ export interface SessionCreatedHandlerDeps {
getSessionMappings: () => SessionMapping[]
waitForSessionReady: (sessionId: string) => Promise
startPolling: () => void
+ queryWindowState?: typeof queryWindowState
+ executeActions?: typeof executeActions
}
export async function handleSessionCreated(
@@ -63,7 +65,10 @@ export async function handleSessionCreated(
deps.pendingSessions.add(sessionId)
try {
- const state = await queryWindowState(deps.sourcePaneId)
+ const queryWindowStateImpl = deps.queryWindowState ?? queryWindowState
+ const executeActionsImpl = deps.executeActions ?? executeActions
+
+ const state = await queryWindowStateImpl(deps.sourcePaneId)
if (!state) {
log("[tmux-session-manager] failed to query window state")
return
@@ -115,7 +120,7 @@ export async function handleSessionCreated(
return
}
- const result = await executeActions(decision.actions, {
+ const result = await executeActionsImpl(decision.actions, {
config: deps.tmuxConfig,
directory: deps.directory,
serverUrl: deps.serverUrl,