fix(team-mode): preserve tmux focus during layout

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
YeonGyu-Kim
2026-05-01 18:49:22 +09:00
parent b99325f206
commit e6cd50cc15
2 changed files with 19 additions and 4 deletions
@@ -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()
@@ -38,12 +38,13 @@ const PANE_SHELL_INIT_DELAY_MS = 200
let paneCreationLock: Promise<void> = Promise.resolve()
function acquirePaneCreationLock(): Promise<() => void> {
async function acquirePaneCreationLock(): Promise<() => void> {
let release: () => void
const newLock = new Promise<void>((resolve) => { release = resolve })
const previousLock = paneCreationLock
paneCreationLock = newLock
return previousLock.then(() => release!)
await previousLock
return release!
}
async function resolveCurrentWindowTarget(tmuxPath: string, leaderPaneId: string): Promise<string | null> {
@@ -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<TeamLay
const windowId = await resolveCurrentWindowId(tmuxPath, leaderPaneId)
if (!windowTarget || !windowId) return null
await runTmuxCommand(tmuxPath, ["set-option", "-w", "-t", windowTarget, "pane-border-status", "top"])
const panesByMember: Record<string, string> = {}
for (const member of members) {