From 07ccbd20479dcabff04f019a25591e4a7a1a1c1f Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Sun, 5 Apr 2026 13:27:50 +0900 Subject: [PATCH] fix(event): respect tmux integration disabled state in event forwarding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with assistance of [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode) --- src/plugin/event.test.ts | 116 ++++++++++++++++++++++++++++++++++++++- src/plugin/event.ts | 32 ++++++----- 2 files changed, 133 insertions(+), 15 deletions(-) diff --git a/src/plugin/event.test.ts b/src/plugin/event.test.ts index 81addf3bc..28e2d7fb2 100644 --- a/src/plugin/event.test.ts +++ b/src/plugin/event.test.ts @@ -452,7 +452,16 @@ describe("createEventHandler - event forwarding", () => { const forwardedEvents: EventInput[] = [] const eventHandler = createEventHandler({ ctx: asEventHandlerContext({}), - pluginConfig: asPluginConfig({}), + pluginConfig: asPluginConfig({ + tmux: { + enabled: true, + layout: "main-vertical", + main_pane_size: 60, + main_pane_min_width: 120, + agent_pane_min_width: 40, + isolation: "inline", + }, + }), firstMessageVariantGate: { markSessionCreated: () => {}, clear: () => {}, @@ -485,6 +494,100 @@ describe("createEventHandler - event forwarding", () => { expect(forwardedEvents[0]?.event.type).toBe("message.part.delta") }) + it("does not forward tmux activity events when tmux integration is disabled", async () => { + //#given + const forwardedEvents: EventInput[] = [] + const eventHandler = createEventHandler({ + ctx: asEventHandlerContext({}), + pluginConfig: asPluginConfig({ + tmux: { + enabled: false, + layout: "main-vertical", + main_pane_size: 60, + main_pane_min_width: 120, + agent_pane_min_width: 40, + isolation: "inline", + }, + }), + firstMessageVariantGate: { + markSessionCreated: () => {}, + clear: () => {}, + }, + managers: createEventHandlerManagers({ + skillMcpManager: { + disconnectSession: async () => {}, + }, + tmuxSessionManager: { + onEvent: (event: EventInput["event"]) => { + forwardedEvents.push({ event }) + }, + onSessionCreated: async () => {}, + onSessionDeleted: async () => {}, + }, + }), + hooks: createEventHandlerHooks({}), + }) + + //#when + await eventHandler(asEventHandlerInput({ + event: { + type: "message.part.delta", + properties: { sessionID: "ses_tmux_disabled", field: "text", delta: "x" }, + }, + })) + + //#then + expect(forwardedEvents).toHaveLength(0) + }) + + it("does not forward session.created to tmux session manager when tmux integration is disabled", async () => { + //#given + const createdSessions: string[] = [] + const eventHandler = createEventHandler({ + ctx: asEventHandlerContext({}), + pluginConfig: asPluginConfig({ + tmux: { + enabled: false, + layout: "main-vertical", + main_pane_size: 60, + main_pane_min_width: 120, + agent_pane_min_width: 40, + isolation: "inline", + }, + }), + firstMessageVariantGate: { + markSessionCreated: () => {}, + clear: () => {}, + }, + managers: createEventHandlerManagers({ + skillMcpManager: { + disconnectSession: async () => {}, + }, + tmuxSessionManager: { + onSessionCreated: async (event: { properties?: { info?: { id?: string } } }) => { + const sessionId = event.properties?.info?.id + if (sessionId) { + createdSessions.push(sessionId) + } + }, + onSessionDeleted: async () => {}, + }, + }), + hooks: createEventHandlerHooks({}), + }) + + //#when + await eventHandler(asEventHandlerInput({ + event: { + type: "session.created", + properties: { info: { id: "ses_tmux_disabled", parentID: "ses_parent" } }, + }, + })) + + //#then + expect(createdSessions).toHaveLength(0) + }) + it("forwards session.deleted to write-existing-file-guard hook", async () => { //#given const forwardedEvents: EventInput[] = [] @@ -492,7 +595,16 @@ describe("createEventHandler - event forwarding", () => { const deletedSessions: string[] = [] const eventHandler = createEventHandler({ ctx: {} as never, - pluginConfig: {} as never, + pluginConfig: asPluginConfig({ + tmux: { + enabled: true, + layout: "main-vertical", + main_pane_size: 60, + main_pane_min_width: 120, + agent_pane_min_width: 40, + isolation: "inline", + }, + }), firstMessageVariantGate: { markSessionCreated: () => {}, clear: () => {}, diff --git a/src/plugin/event.ts b/src/plugin/event.ts index f57947931..0124fb8ad 100644 --- a/src/plugin/event.ts +++ b/src/plugin/event.ts @@ -36,6 +36,7 @@ import { lspManager } from "../tools"; import type { CreatedHooks } from "../create-hooks"; import type { Managers } from "../create-managers"; +import { isTmuxIntegrationEnabled } from "../create-runtime-tmux-config"; import { pruneRecentSyntheticIdles } from "./recent-synthetic-idles"; import { normalizeSessionStatusToIdle } from "./session-status-normalizer"; @@ -138,7 +139,8 @@ export function createEventHandler(args: { managers: Managers; hooks: CreatedHooks; }): (input: EventInput) => Promise { - const { ctx, firstMessageVariantGate, managers, hooks } = args; + const { ctx, pluginConfig, firstMessageVariantGate, managers, hooks } = args; + const tmuxIntegrationEnabled = isTmuxIntegrationEnabled(pluginConfig) const pluginContext = ctx as { directory: string; client: { @@ -344,7 +346,7 @@ export function createEventHandler(args: { const { event } = input; const props = event.properties as Record | undefined; - if (TMUX_ACTIVITY_EVENT_TYPES.has(event.type)) { + if (tmuxIntegrationEnabled && TMUX_ACTIVITY_EVENT_TYPES.has(event.type)) { managers.tmuxSessionManager.onEvent?.(event as { type: string; properties?: Record }); } @@ -357,14 +359,16 @@ export function createEventHandler(args: { firstMessageVariantGate.markSessionCreated(sessionInfo); - await managers.tmuxSessionManager.onSessionCreated( - event as { - type: string; - properties?: { - info?: { id?: string; parentID?: string; title?: string }; - }; - }, - ); + if (tmuxIntegrationEnabled) { + await managers.tmuxSessionManager.onSessionCreated( + event as { + type: string; + properties?: { + info?: { id?: string; parentID?: string; title?: string }; + }; + }, + ); + } } if (event.type === "session.deleted") { @@ -394,9 +398,11 @@ export function createEventHandler(args: { deleteSessionTools(sessionInfo.id); await managers.skillMcpManager.disconnectSession(sessionInfo.id); await lspManager.cleanupTempDirectoryClients(); - await managers.tmuxSessionManager.onSessionDeleted({ - sessionID: sessionInfo.id, - }); + if (tmuxIntegrationEnabled) { + await managers.tmuxSessionManager.onSessionDeleted({ + sessionID: sessionInfo.id, + }); + } } }