diff --git a/src/features/team-mode/team-layout-tmux/layout.test.ts b/src/features/team-mode/team-layout-tmux/layout.test.ts index 33dccaeb2..a561771b6 100644 --- a/src/features/team-mode/team-layout-tmux/layout.test.ts +++ b/src/features/team-mode/team-layout-tmux/layout.test.ts @@ -197,6 +197,21 @@ describe("team-layout-tmux", () => { expect(titleSetters).toContain("m2") }) + test("#given caller inside tmux #when createTeamLayout runs #then it restores keyboard focus and avoids border status mutation", async () => { + // given + const { createTeamLayout } = await loadLayoutModule() + const members = [{ name: "m1", sessionId: "s-m1", worktreePath: "/tmp/m1" }] + + // when + await createTeamLayout("run-options", members, tmuxMgr as never) + + // then + const commands = getCommands() + const focusRestores = commands.filter((args) => args[0] === "select-pane" && args[1] === "-t" && args[2] === "%42") + expect(focusRestores.length).toBe(1) + expect(commands.some((args) => args[0] === "set-option" && args.includes("pane-border-status"))).toBe(false) + }) + test("#given ownedSession=false, focusWindowId=@10, gridWindowId=@11 #when removeTeamLayout runs #then tmux kill-window is called twice with -t @10 and -t @11 and kill-session is NEVER called", async () => { // given const { removeTeamLayout } = await loadLayoutModule() diff --git a/src/features/team-mode/team-layout-tmux/layout.ts b/src/features/team-mode/team-layout-tmux/layout.ts index 2b76b06e3..d43941cbd 100644 --- a/src/features/team-mode/team-layout-tmux/layout.ts +++ b/src/features/team-mode/team-layout-tmux/layout.ts @@ -38,12 +38,13 @@ const PANE_SHELL_INIT_DELAY_MS = 200 let paneCreationLock: Promise = Promise.resolve() -function acquirePaneCreationLock(): Promise<() => void> { +async function acquirePaneCreationLock(): Promise<() => void> { let release: () => void const newLock = new Promise((resolve) => { release = resolve }) const previousLock = paneCreationLock paneCreationLock = newLock - return previousLock.then(() => release!) + await previousLock + return release! } async function resolveCurrentWindowTarget(tmuxPath: string, leaderPaneId: string): Promise { @@ -105,6 +106,7 @@ async function createTeammatePaneInCurrentWindow( const paneId = splitResult.output.trim() await runTmuxCommand(tmuxPath, ["select-pane", "-t", paneId, "-T", member.name]) + await runTmuxCommand(tmuxPath, ["select-pane", "-t", leaderPaneId]) await runTmuxCommand(tmuxPath, ["set-option", "-p", "-t", paneId, "pane-border-style", "fg=cyan"]) await runTmuxCommand(tmuxPath, ["set-option", "-p", "-t", paneId, "pane-active-border-style", "fg=cyan"]) await runTmuxCommand(tmuxPath, ["set-option", "-p", "-t", paneId, "pane-border-format", "#[fg=cyan,bold] #{pane_title} #[default]"]) @@ -159,8 +161,6 @@ export async function createTeamLayout(teamRunId: string, members: Array = {} for (const member of members) {