diff --git a/src/features/tmux-subagent/manager.ts b/src/features/tmux-subagent/manager.ts index 3f9ca54e7..be6f5d808 100644 --- a/src/features/tmux-subagent/manager.ts +++ b/src/features/tmux-subagent/manager.ts @@ -77,6 +77,13 @@ const FAILED_READINESS_SWEEP_INTERVAL_MS = 60 * 1000 const MAX_DEFERRED_QUEUE_SIZE = 20 const MAX_CLOSE_RETRY_COUNT = 3 const MAX_ISOLATED_CONTAINER_NULL_STATE_COUNT = 2 +let nextIsolatedSessionManagerId = 1 + +function createIsolatedSessionManagerId(): string { + const managerId = String(nextIsolatedSessionManagerId) + nextIsolatedSessionManagerId += 1 + return managerId +} export class TmuxSessionManager { private client: OpencodeClient @@ -102,6 +109,7 @@ export class TmuxSessionManager { private isolatedContainerNullStateCount = 0 private staleSweepCompleted = false private staleSweepInProgress = false + private isolatedSessionManagerId = createIsolatedSessionManagerId() constructor(ctx: PluginInput, tmuxConfig: TmuxConfig, deps: Partial = {}) { this.client = ctx.client this.tmuxConfig = tmuxConfig @@ -197,7 +205,16 @@ export class TmuxSessionManager { this.deps.log("[tmux-session-manager] creating isolated tmux container", { isolation, sessionId, title }) const result = isolation === "session" - ? await spawnTmuxSession(sessionId, title, this.tmuxConfig, this.serverUrl, this.projectDirectory, this.sourcePaneId) + ? await spawnTmuxSession( + sessionId, + title, + this.tmuxConfig, + this.serverUrl, + this.projectDirectory, + this.sourcePaneId, + undefined, + this.isolatedSessionManagerId, + ) : await spawnTmuxWindow(sessionId, title, this.tmuxConfig, this.serverUrl, this.projectDirectory) if (result.success && result.paneId) { @@ -1322,7 +1339,7 @@ export class TmuxSessionManager { this.isolatedWindowPaneId = undefined if (this.tmuxConfig.isolation === "session") { - const isolatedSessionName = getIsolatedSessionName() + const isolatedSessionName = getIsolatedSessionName(process.pid, this.isolatedSessionManagerId) try { const killed = await killTmuxSessionIfExists(isolatedSessionName) this.deps.log("[tmux-session-manager] isolated session teardown", { diff --git a/src/shared/tmux/tmux-utils/session-spawn.ts b/src/shared/tmux/tmux-utils/session-spawn.ts index 27f68cc07..11ca8e07a 100644 --- a/src/shared/tmux/tmux-utils/session-spawn.ts +++ b/src/shared/tmux/tmux-utils/session-spawn.ts @@ -32,8 +32,10 @@ async function resolveSpawnTmuxSessionDeps(deps?: Partial) } } -export function getIsolatedSessionName(pid: number = process.pid): string { - return `${ISOLATED_SESSION_NAME_PREFIX}-${pid}` +export function getIsolatedSessionName(pid: number = process.pid, managerId?: string): string { + return managerId + ? `${ISOLATED_SESSION_NAME_PREFIX}-${pid}-${managerId}` + : `${ISOLATED_SESSION_NAME_PREFIX}-${pid}` } async function getWindowDimensions( @@ -64,6 +66,7 @@ export async function spawnTmuxSession( _directory: string, sourcePaneId?: string, depsInput?: Partial, + managerId?: string, ): Promise { const deps = await resolveSpawnTmuxSessionDeps(depsInput) const { log, runTmuxCommand } = deps @@ -108,7 +111,7 @@ export async function spawnTmuxSession( } } - const isolatedSessionName = getIsolatedSessionName() + const isolatedSessionName = getIsolatedSessionName(process.pid, managerId) const sessionAlreadyExists = await sessionExists(tmux, isolatedSessionName, runTmuxCommand) const args = sessionAlreadyExists