Merge pull request #4066 from PeterPonyu/fix/2887-filter-terminal-probe-replies
fix(tmux-subagent): drain terminal probe replies during delegated pane startup (#2887)
This commit is contained in:
@@ -255,6 +255,30 @@ describe("team-layout-tmux", () => {
|
||||
expect(commands.some((args) => args[0] === "set-option")).toBe(false)
|
||||
})
|
||||
|
||||
test("#given delegated pane startup #when split-window is called #then -d flag is always present to prevent terminal probe replies leaking into caller pane (fix #2887)", async () => {
|
||||
// given
|
||||
const { createTeamLayout } = await loadLayoutModule()
|
||||
const members = [
|
||||
{ name: "m1", sessionId: "s-m1", worktreePath: "/tmp/m1" },
|
||||
{ name: "m2", sessionId: "s-m2", worktreePath: "/tmp/m2" },
|
||||
{ name: "m3", sessionId: "s-m3", worktreePath: "/tmp/m3" },
|
||||
]
|
||||
|
||||
// when
|
||||
await createTeamLayout("run-probe-drain", members, tmuxMgr as never)
|
||||
|
||||
// then: every split-window call must carry -d so focus never bounces to the
|
||||
// new pane; without -d, terminal capability probe replies (DA1/DA2, OSC color)
|
||||
// emitted during pane startup are misrouted to the caller pane's stdin and
|
||||
// appear as literal garbage text in the main OpenCode chat input.
|
||||
const commands = getCommands()
|
||||
const splitWindowCalls = commands.filter((args) => args[0] === "split-window")
|
||||
expect(splitWindowCalls.length).toBeGreaterThan(0)
|
||||
for (const splitArgs of splitWindowCalls) {
|
||||
expect(splitArgs).toContain("-d")
|
||||
}
|
||||
})
|
||||
|
||||
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()
|
||||
@@ -392,7 +416,7 @@ describe("team-layout-tmux", () => {
|
||||
const commands = getCommands()
|
||||
const splitCalls = commands.filter((args) => args[0] === "split-window")
|
||||
expect(splitCalls).toEqual([
|
||||
["split-window", "-t", process.env.TMUX_PANE ?? "", "-h", "-l", "70%", "-P", "-F", "#{pane_id}", "-c", "/tmp/m1"],
|
||||
["split-window", "-t", process.env.TMUX_PANE ?? "", "-h", "-d", "-l", "70%", "-P", "-F", "#{pane_id}", "-c", "/tmp/m1"],
|
||||
])
|
||||
expect(commands.filter((args) => args[0] === "new-window").length).toBe(0)
|
||||
})
|
||||
|
||||
@@ -61,7 +61,7 @@ function selectExistingTeammatePane(teammatePanes: Array<string>, callerPaneId:
|
||||
|
||||
function buildSplitArgs(callerPaneId: string, teammatePanes: Array<string>, member: TeamLayoutMember): Array<string> {
|
||||
if (teammatePanes.length === 0) {
|
||||
return ["split-window", "-t", callerPaneId, "-h", "-l", "70%", "-P", "-F", "#{pane_id}", "-c", getPaneWorkingDirectory(member)]
|
||||
return ["split-window", "-t", callerPaneId, "-h", "-d", "-l", "70%", "-P", "-F", "#{pane_id}", "-c", getPaneWorkingDirectory(member)]
|
||||
}
|
||||
|
||||
return [
|
||||
@@ -69,6 +69,7 @@ function buildSplitArgs(callerPaneId: string, teammatePanes: Array<string>, memb
|
||||
"-t",
|
||||
selectExistingTeammatePane(teammatePanes, callerPaneId),
|
||||
teammatePanes.length % 2 === 1 ? "-v" : "-h",
|
||||
"-d",
|
||||
"-P",
|
||||
"-F",
|
||||
"#{pane_id}",
|
||||
|
||||
Reference in New Issue
Block a user