fix: add cmux __tmux-compat prefix to interactive_bash tool
Extract isCmuxCompatEnvironment to shared module and fix interactive_bash to resolve cmux executables with the __tmux-compat prefix, matching all other tmux command paths in the codebase.
This commit is contained in:
@@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Detect whether we are running inside cmux (cmux omo).
|
||||||
|
* When cmux-omo sets up the environment it injects a tmux shim and sets
|
||||||
|
* CMUX_SOCKET_PATH / TMUX. If detected, redirect tmux commands to
|
||||||
|
* `cmux __tmux-compat` so they become native cmux splits instead of
|
||||||
|
* failing because there is no real tmux server running.
|
||||||
|
*/
|
||||||
|
export function isCmuxCompatEnvironment(): boolean {
|
||||||
|
return Boolean(process.env.CMUX_SOCKET_PATH) ||
|
||||||
|
process.env.TMUX?.includes("cmuxterm") === true
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
export * from "./types"
|
export * from "./types"
|
||||||
export * from "./constants"
|
export * from "./constants"
|
||||||
|
export * from "./cmux-detect"
|
||||||
export * from "./runner"
|
export * from "./runner"
|
||||||
export * from "./tmux-utils"
|
export * from "./tmux-utils"
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { spawn } from "../bun-spawn-shim"
|
import { spawn } from "../bun-spawn-shim"
|
||||||
|
import { isCmuxCompatEnvironment } from "./cmux-detect"
|
||||||
|
|
||||||
type RunTmuxOptions = {
|
type RunTmuxOptions = {
|
||||||
retry?: number
|
retry?: number
|
||||||
@@ -29,18 +30,6 @@ function isTerminalTmuxError(stderr: string): boolean {
|
|||||||
return TERMINAL_TMUX_ERROR_PATTERN.test(stderr)
|
return TERMINAL_TMUX_ERROR_PATTERN.test(stderr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Detect whether we are running inside cmux (cmux omo).
|
|
||||||
* When cmux-omo sets up the environment it injects a tmux shim and sets
|
|
||||||
* CMUX_SOCKET_PATH / TMUX. If detected, redirect tmux commands to
|
|
||||||
* `cmux __tmux-compat` so they become native cmux splits instead of
|
|
||||||
* failing because there is no real tmux server running.
|
|
||||||
*/
|
|
||||||
function isCmuxCompatEnvironment(): boolean {
|
|
||||||
return Boolean(process.env.CMUX_SOCKET_PATH) ||
|
|
||||||
process.env.TMUX?.includes("cmuxterm") === true
|
|
||||||
}
|
|
||||||
|
|
||||||
function resolveTmuxExecutable(tmuxPath: string): string[] {
|
function resolveTmuxExecutable(tmuxPath: string): string[] {
|
||||||
if (!isCmuxCompatEnvironment()) {
|
if (!isCmuxCompatEnvironment()) {
|
||||||
return [tmuxPath]
|
return [tmuxPath]
|
||||||
|
|||||||
@@ -1,14 +1,10 @@
|
|||||||
import { spawn } from "../../shared/bun-spawn-shim"
|
import { spawn } from "../../shared/bun-spawn-shim"
|
||||||
|
import { isCmuxCompatEnvironment } from "../../shared/tmux/cmux-detect"
|
||||||
|
|
||||||
let tmuxPath: string | null = null
|
let tmuxPath: string | null = null
|
||||||
let initPromise: Promise<string | null> | null = null
|
let initPromise: Promise<string | null> | null = null
|
||||||
let tmuxPathEnvironmentKey: "cmux" | "tmux" | null = null
|
let tmuxPathEnvironmentKey: "cmux" | "tmux" | null = null
|
||||||
|
|
||||||
function isCmuxCompatEnvironment(): boolean {
|
|
||||||
return Boolean(process.env.CMUX_SOCKET_PATH) ||
|
|
||||||
process.env.TMUX?.includes("cmuxterm") === true
|
|
||||||
}
|
|
||||||
|
|
||||||
function getEnvironmentKey(): "cmux" | "tmux" {
|
function getEnvironmentKey(): "cmux" | "tmux" {
|
||||||
return isCmuxCompatEnvironment() ? "cmux" : "tmux"
|
return isCmuxCompatEnvironment() ? "cmux" : "tmux"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,19 @@
|
|||||||
import { tool, type ToolDefinition } from "@opencode-ai/plugin/tool"
|
import { tool, type ToolDefinition } from "@opencode-ai/plugin/tool"
|
||||||
import { spawnWithWindowsHide } from "../../shared/spawn-with-windows-hide"
|
import { spawnWithWindowsHide } from "../../shared/spawn-with-windows-hide"
|
||||||
|
import { isCmuxCompatEnvironment } from "../../shared/tmux/cmux-detect"
|
||||||
import { BLOCKED_TMUX_SUBCOMMANDS, DEFAULT_TIMEOUT_MS, INTERACTIVE_BASH_DESCRIPTION } from "./constants"
|
import { BLOCKED_TMUX_SUBCOMMANDS, DEFAULT_TIMEOUT_MS, INTERACTIVE_BASH_DESCRIPTION } from "./constants"
|
||||||
import { getCachedTmuxPath } from "./tmux-path-resolver"
|
import { getCachedTmuxPath } from "./tmux-path-resolver"
|
||||||
|
|
||||||
|
function resolveTmuxExecutable(tmuxPath: string): string[] {
|
||||||
|
if (!isCmuxCompatEnvironment()) {
|
||||||
|
return [tmuxPath]
|
||||||
|
}
|
||||||
|
|
||||||
|
const executableName = tmuxPath.split(/[\\/]/).pop()
|
||||||
|
const cmuxExecutable = executableName === "cmux" ? tmuxPath : "cmux"
|
||||||
|
return [cmuxExecutable, "__tmux-compat"]
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Quote-aware command tokenizer with escape handling
|
* Quote-aware command tokenizer with escape handling
|
||||||
* Handles single/double quotes and backslash escapes without external dependencies
|
* Handles single/double quotes and backslash escapes without external dependencies
|
||||||
@@ -90,7 +101,7 @@ tmux capture-pane -p -t ${sessionName} -S -1000
|
|||||||
The Bash tool can execute these commands directly. Do NOT retry with interactive_bash.`
|
The Bash tool can execute these commands directly. Do NOT retry with interactive_bash.`
|
||||||
}
|
}
|
||||||
|
|
||||||
const proc = spawnWithWindowsHide([tmuxPath, ...parts], {
|
const proc = spawnWithWindowsHide([...resolveTmuxExecutable(tmuxPath), ...parts], {
|
||||||
stdout: "pipe",
|
stdout: "pipe",
|
||||||
stderr: "pipe",
|
stderr: "pipe",
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user