fix(team-mode): resolve caller tmux window target
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -18,7 +18,7 @@ function shellSingleQuote(value: string): string {
|
|||||||
return `'${value.split("'").join(`'"'"'`)}'`
|
return `'${value.split("'").join(`'"'"'`)}'`
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createTmuxStub(options: { stdout: string; exitCode: number }): Promise<TmuxStub> {
|
async function createTmuxStub(options: { stdout: string; windowStdout?: string; exitCode: number }): Promise<TmuxStub> {
|
||||||
const directory = await mkdtemp(path.join(tmpdir(), "resolve-caller-tmux-session-"))
|
const directory = await mkdtemp(path.join(tmpdir(), "resolve-caller-tmux-session-"))
|
||||||
temporaryDirectories.push(directory)
|
temporaryDirectories.push(directory)
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ async function createTmuxStub(options: { stdout: string; exitCode: number }): Pr
|
|||||||
const script = [
|
const script = [
|
||||||
"#!/bin/sh",
|
"#!/bin/sh",
|
||||||
`printf '%s\\n' \"$@\" >> ${shellSingleQuote(logPath)}`,
|
`printf '%s\\n' \"$@\" >> ${shellSingleQuote(logPath)}`,
|
||||||
`printf '%s' ${shellSingleQuote(options.stdout)}`,
|
`case "$*" in *'#{session_name}:#{window_index}'*) printf '%s' ${shellSingleQuote(options.windowStdout ?? options.stdout)} ;; *) printf '%s' ${shellSingleQuote(options.stdout)} ;; esac`,
|
||||||
`exit ${options.exitCode}`,
|
`exit ${options.exitCode}`,
|
||||||
].join("\n")
|
].join("\n")
|
||||||
|
|
||||||
@@ -67,17 +67,20 @@ describe("resolveCallerTmuxSession", () => {
|
|||||||
expect(await readLogLines(stub.logPath)).toHaveLength(0)
|
expect(await readLogLines(stub.logPath)).toHaveLength(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("#given TMUX_PANE=%42 and display returns '$7' #when resolve runs #then returns { sessionId: '$7' }", async () => {
|
test("#given TMUX_PANE=%42 and display returns session and window #when resolve runs #then returns caller tmux target", async () => {
|
||||||
// given
|
// given
|
||||||
process.env.TMUX_PANE = "%42"
|
process.env.TMUX_PANE = "%42"
|
||||||
const stub = await createTmuxStub({ stdout: "$7", exitCode: 0 })
|
const stub = await createTmuxStub({ stdout: "$7", windowStdout: "test-session:0", exitCode: 0 })
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = await resolveCallerTmuxSession(stub.tmuxPath)
|
const result = await resolveCallerTmuxSession(stub.tmuxPath)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({ sessionId: "$7" })
|
expect(result).toEqual({ sessionId: "$7", paneId: "%42", windowTarget: "test-session:0" })
|
||||||
expect(await readLogLines(stub.logPath)).toEqual(["display", "-p", "-F", "#{session_id}", "-t", "%42"])
|
expect(await readLogLines(stub.logPath)).toEqual([
|
||||||
|
"display", "-p", "-F", "#{session_id}", "-t", "%42",
|
||||||
|
"display", "-p", "-F", "#{session_name}:#{window_index}", "-t", "%42",
|
||||||
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
test("#given TMUX_PANE=%42 and display returns 'garbage' #when resolve runs #then returns null", async () => {
|
test("#given TMUX_PANE=%42 and display returns 'garbage' #when resolve runs #then returns null", async () => {
|
||||||
|
|||||||
@@ -2,9 +2,12 @@ import { runTmuxCommand } from "../../../shared/tmux"
|
|||||||
|
|
||||||
type ResolvedCallerTmuxSession = {
|
type ResolvedCallerTmuxSession = {
|
||||||
sessionId: string
|
sessionId: string
|
||||||
|
paneId: string
|
||||||
|
windowTarget: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const TMUX_SESSION_ID_PATTERN = /^\$[0-9]+$/
|
const TMUX_SESSION_ID_PATTERN = /^\$[0-9]+$/
|
||||||
|
const TMUX_WINDOW_TARGET_PATTERN = /^[^:]+:[0-9]+$/
|
||||||
|
|
||||||
export async function resolveCallerTmuxSession(tmuxPath: string): Promise<ResolvedCallerTmuxSession | null> {
|
export async function resolveCallerTmuxSession(tmuxPath: string): Promise<ResolvedCallerTmuxSession | null> {
|
||||||
const callerPaneId = process.env.TMUX_PANE
|
const callerPaneId = process.env.TMUX_PANE
|
||||||
@@ -12,15 +15,25 @@ export async function resolveCallerTmuxSession(tmuxPath: string): Promise<Resolv
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await runTmuxCommand(tmuxPath, ["display", "-p", "-F", "#{session_id}", "-t", callerPaneId])
|
const sessionResult = await runTmuxCommand(tmuxPath, ["display", "-p", "-F", "#{session_id}", "-t", callerPaneId])
|
||||||
if (!result.success) {
|
if (!sessionResult.success) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const sessionId = result.output.trim()
|
const sessionId = sessionResult.output.trim()
|
||||||
if (!TMUX_SESSION_ID_PATTERN.test(sessionId)) {
|
if (!TMUX_SESSION_ID_PATTERN.test(sessionId)) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return { sessionId }
|
const windowResult = await runTmuxCommand(tmuxPath, ["display", "-p", "-F", "#{session_name}:#{window_index}", "-t", callerPaneId])
|
||||||
|
if (!windowResult.success) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const windowTarget = windowResult.output.trim()
|
||||||
|
if (!TMUX_WINDOW_TARGET_PATTERN.test(windowTarget)) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return { sessionId, paneId: callerPaneId, windowTarget }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user