From 744dee70e99cdaf2d91e73f60cc205b633e07832 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Tue, 17 Feb 2026 14:08:28 +0900 Subject: [PATCH] refactor: remove 3 orphaned files and unused import from tmux-subagent --- src/features/tmux-subagent/manager-cleanup.ts | 43 ----- .../tmux-subagent/pane-split-availability.ts | 9 +- src/features/tmux-subagent/session-cleaner.ts | 80 -------- src/features/tmux-subagent/session-spawner.ts | 177 ------------------ 4 files changed, 4 insertions(+), 305 deletions(-) delete mode 100644 src/features/tmux-subagent/manager-cleanup.ts delete mode 100644 src/features/tmux-subagent/session-cleaner.ts delete mode 100644 src/features/tmux-subagent/session-spawner.ts diff --git a/src/features/tmux-subagent/manager-cleanup.ts b/src/features/tmux-subagent/manager-cleanup.ts deleted file mode 100644 index 47ca4836b..000000000 --- a/src/features/tmux-subagent/manager-cleanup.ts +++ /dev/null @@ -1,43 +0,0 @@ -import type { TmuxConfig } from "../../config/schema" -import type { TrackedSession } from "./types" -import { log } from "../../shared" -import { queryWindowState } from "./pane-state-querier" -import { executeAction } from "./action-executor" -import { TmuxPollingManager } from "./polling-manager" - -export class ManagerCleanup { - constructor( - private sessions: Map, - private sourcePaneId: string | undefined, - private pollingManager: TmuxPollingManager, - private tmuxConfig: TmuxConfig, - private serverUrl: string - ) {} - - async cleanup(): Promise { - this.pollingManager.stopPolling() - - if (this.sessions.size > 0) { - log("[tmux-session-manager] closing all panes", { count: this.sessions.size }) - const state = this.sourcePaneId ? await queryWindowState(this.sourcePaneId) : null - - if (state) { - const closePromises = Array.from(this.sessions.values()).map((s) => - executeAction( - { type: "close", paneId: s.paneId, sessionId: s.sessionId }, - { config: this.tmuxConfig, serverUrl: this.serverUrl, windowState: state } - ).catch((err) => - log("[tmux-session-manager] cleanup error for pane", { - paneId: s.paneId, - error: String(err), - }), - ), - ) - await Promise.all(closePromises) - } - this.sessions.clear() - } - - log("[tmux-session-manager] cleanup complete") - } -} diff --git a/src/features/tmux-subagent/pane-split-availability.ts b/src/features/tmux-subagent/pane-split-availability.ts index a37a83f1c..572cf606d 100644 --- a/src/features/tmux-subagent/pane-split-availability.ts +++ b/src/features/tmux-subagent/pane-split-availability.ts @@ -1,11 +1,10 @@ import { MIN_PANE_WIDTH } from "./types" import type { SplitDirection, TmuxPaneInfo } from "./types" import { - DIVIDER_SIZE, - MAX_COLS, - MAX_ROWS, - MIN_SPLIT_HEIGHT, - MIN_SPLIT_WIDTH, + DIVIDER_SIZE, + MAX_COLS, + MAX_ROWS, + MIN_SPLIT_HEIGHT, } from "./tmux-grid-constants" function minSplitWidthFor(minPaneWidth: number): number { diff --git a/src/features/tmux-subagent/session-cleaner.ts b/src/features/tmux-subagent/session-cleaner.ts deleted file mode 100644 index d087433b3..000000000 --- a/src/features/tmux-subagent/session-cleaner.ts +++ /dev/null @@ -1,80 +0,0 @@ -import type { TmuxConfig } from "../../config/schema" -import type { TrackedSession } from "./types" -import type { SessionMapping } from "./decision-engine" -import { log } from "../../shared" -import { queryWindowState } from "./pane-state-querier" -import { decideCloseAction } from "./decision-engine" -import { executeAction } from "./action-executor" -import { TmuxPollingManager } from "./polling-manager" - -export interface TmuxUtilDeps { - isInsideTmux: () => boolean - getCurrentPaneId: () => string | undefined -} - -export class SessionCleaner { - constructor( - private tmuxConfig: TmuxConfig, - private deps: TmuxUtilDeps, - private sessions: Map, - private sourcePaneId: string | undefined, - private getSessionMappings: () => SessionMapping[], - private pollingManager: TmuxPollingManager, - private serverUrl: string - ) {} - - private isEnabled(): boolean { - return this.tmuxConfig.enabled && this.deps.isInsideTmux() - } - - async onSessionDeleted(event: { sessionID: string }): Promise { - if (!this.isEnabled()) return - if (!this.sourcePaneId) return - - const tracked = this.sessions.get(event.sessionID) - if (!tracked) return - - log("[tmux-session-manager] onSessionDeleted", { sessionId: event.sessionID }) - - const state = await queryWindowState(this.sourcePaneId) - if (!state) { - this.sessions.delete(event.sessionID) - return - } - - const closeAction = decideCloseAction(state, event.sessionID, this.getSessionMappings()) - if (closeAction) { - await executeAction(closeAction, { config: this.tmuxConfig, serverUrl: this.serverUrl, windowState: state }) - } - - this.sessions.delete(event.sessionID) - - if (this.sessions.size === 0) { - this.pollingManager.stopPolling() - } - } - - async closeSessionById(sessionId: string): Promise { - const tracked = this.sessions.get(sessionId) - if (!tracked) return - - log("[tmux-session-manager] closing session pane", { - sessionId, - paneId: tracked.paneId, - }) - - const state = this.sourcePaneId ? await queryWindowState(this.sourcePaneId) : null - if (state) { - await executeAction( - { type: "close", paneId: tracked.paneId, sessionId }, - { config: this.tmuxConfig, serverUrl: this.serverUrl, windowState: state } - ) - } - - this.sessions.delete(sessionId) - - if (this.sessions.size === 0) { - this.pollingManager.stopPolling() - } - } -} diff --git a/src/features/tmux-subagent/session-spawner.ts b/src/features/tmux-subagent/session-spawner.ts deleted file mode 100644 index 4c43b653e..000000000 --- a/src/features/tmux-subagent/session-spawner.ts +++ /dev/null @@ -1,177 +0,0 @@ -import type { TmuxConfig } from "../../config/schema" -import type { TrackedSession, CapacityConfig } from "./types" -import { log } from "../../shared" -import { queryWindowState } from "./pane-state-querier" -import { decideSpawnActions, type SessionMapping } from "./decision-engine" -import { executeActions } from "./action-executor" -import { TmuxPollingManager } from "./polling-manager" - -interface SessionCreatedEvent { - type: string - properties?: { info?: { id?: string; parentID?: string; title?: string } } -} - -export interface TmuxUtilDeps { - isInsideTmux: () => boolean - getCurrentPaneId: () => string | undefined -} - -export class SessionSpawner { - constructor( - private tmuxConfig: TmuxConfig, - private deps: TmuxUtilDeps, - private sessions: Map, - private pendingSessions: Set, - private sourcePaneId: string | undefined, - private getCapacityConfig: () => CapacityConfig, - private getSessionMappings: () => SessionMapping[], - private waitForSessionReady: (sessionId: string) => Promise, - private pollingManager: TmuxPollingManager, - private serverUrl: string - ) {} - - private isEnabled(): boolean { - return this.tmuxConfig.enabled && this.deps.isInsideTmux() - } - - async onSessionCreated(event: SessionCreatedEvent): Promise { - const enabled = this.isEnabled() - log("[tmux-session-manager] onSessionCreated called", { - enabled, - tmuxConfigEnabled: this.tmuxConfig.enabled, - isInsideTmux: this.deps.isInsideTmux(), - eventType: event.type, - infoId: event.properties?.info?.id, - infoParentID: event.properties?.info?.parentID, - }) - - if (!enabled) return - if (event.type !== "session.created") return - - const info = event.properties?.info - if (!info?.id || !info?.parentID) return - - const sessionId = info.id - const title = info.title ?? "Subagent" - - if (this.sessions.has(sessionId) || this.pendingSessions.has(sessionId)) { - log("[tmux-session-manager] session already tracked or pending", { sessionId }) - return - } - - if (!this.sourcePaneId) { - log("[tmux-session-manager] no source pane id") - return - } - - this.pendingSessions.add(sessionId) - - try { - const state = await queryWindowState(this.sourcePaneId) - if (!state) { - log("[tmux-session-manager] failed to query window state") - return - } - - log("[tmux-session-manager] window state queried", { - windowWidth: state.windowWidth, - mainPane: state.mainPane?.paneId, - agentPaneCount: state.agentPanes.length, - agentPanes: state.agentPanes.map((p) => p.paneId), - }) - - const decision = decideSpawnActions( - state, - sessionId, - title, - this.getCapacityConfig(), - this.getSessionMappings() - ) - - log("[tmux-session-manager] spawn decision", { - canSpawn: decision.canSpawn, - reason: decision.reason, - actionCount: decision.actions.length, - actions: decision.actions.map((a) => { - if (a.type === "close") return { type: "close", paneId: a.paneId } - if (a.type === "replace") return { type: "replace", paneId: a.paneId, newSessionId: a.newSessionId } - return { type: "spawn", sessionId: a.sessionId } - }), - }) - - if (!decision.canSpawn) { - log("[tmux-session-manager] cannot spawn", { reason: decision.reason }) - return - } - - const result = await executeActions( - decision.actions, - { config: this.tmuxConfig, serverUrl: this.serverUrl, windowState: state } - ) - - for (const { action, result: actionResult } of result.results) { - if (action.type === "close" && actionResult.success) { - this.sessions.delete(action.sessionId) - log("[tmux-session-manager] removed closed session from cache", { - sessionId: action.sessionId, - }) - } - if (action.type === "replace" && actionResult.success) { - this.sessions.delete(action.oldSessionId) - log("[tmux-session-manager] removed replaced session from cache", { - oldSessionId: action.oldSessionId, - newSessionId: action.newSessionId, - }) - } - } - - if (result.success && result.spawnedPaneId) { - const sessionReady = await this.waitForSessionReady(sessionId) - - if (!sessionReady) { - log("[tmux-session-manager] session not ready after timeout, closing spawned pane", { - sessionId, - paneId: result.spawnedPaneId, - }) - - await executeActions( - [{ type: "close", paneId: result.spawnedPaneId, sessionId }], - { - config: this.tmuxConfig, - serverUrl: this.serverUrl, - windowState: state, - }, - ) - - return - } - - const now = Date.now() - this.sessions.set(sessionId, { - sessionId, - paneId: result.spawnedPaneId, - description: title, - createdAt: new Date(now), - lastSeenAt: new Date(now), - }) - log("[tmux-session-manager] pane spawned and tracked", { - sessionId, - paneId: result.spawnedPaneId, - sessionReady, - }) - this.pollingManager.startPolling() - } else { - log("[tmux-session-manager] spawn failed", { - success: result.success, - results: result.results.map((r) => ({ - type: r.action.type, - success: r.result.success, - error: r.result.error, - })), - }) - } - } finally { - this.pendingSessions.delete(sessionId) - } - } -}