fix(tmux): pick per-instance ports and restore pane cleanup
This commit is contained in:
@@ -1,7 +1,9 @@
|
|||||||
function c --wraps=opencode --description 'opencode (auto-starts tmux for visual subagent panes)'
|
function c --wraps=opencode --description 'opencode (auto-starts tmux for visual subagent panes)'
|
||||||
|
set -l port (python -c 'import socket; s=socket.socket(); s.bind(("127.0.0.1", 0)); print(s.getsockname()[1]); s.close()')
|
||||||
|
|
||||||
if not set -q TMUX
|
if not set -q TMUX
|
||||||
tmux new-session opencode $argv
|
tmux new-session opencode --port $port $argv
|
||||||
else
|
else
|
||||||
opencode $argv
|
opencode --port $port $argv
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
function cc --wraps='opencode --continue' --description 'opencode --continue (auto-starts tmux for visual subagent panes)'
|
function cc --wraps='opencode --continue' --description 'opencode --continue (auto-starts tmux for visual subagent panes)'
|
||||||
|
set -l port (python -c 'import socket; s=socket.socket(); s.bind(("127.0.0.1", 0)); print(s.getsockname()[1]); s.close()')
|
||||||
|
|
||||||
if not set -q TMUX
|
if not set -q TMUX
|
||||||
tmux new-session opencode --continue $argv
|
tmux new-session opencode --port $port --continue $argv
|
||||||
else
|
else
|
||||||
opencode --continue $argv
|
opencode --port $port --continue $argv
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import type { Plugin } from "@opencode-ai/plugin"
|
import type { Plugin } from "@opencode-ai/plugin"
|
||||||
import { spawn } from "bun"
|
import { spawn } from "bun"
|
||||||
import { appendFileSync } from "fs"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tmux-panes plugin
|
* tmux-panes plugin
|
||||||
@@ -14,14 +13,8 @@ import { appendFileSync } from "fs"
|
|||||||
* - Panes close automatically when subagent sessions end
|
* - Panes close automatically when subagent sessions end
|
||||||
*
|
*
|
||||||
* Only activates when running inside a tmux session (TMUX env var is set).
|
* Only activates when running inside a tmux session (TMUX env var is set).
|
||||||
*
|
|
||||||
* Debug log: /tmp/opencode-tmux-debug.log
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const DEBUG_LOG = "/tmp/opencode-tmux-debug.log"
|
|
||||||
const log = (msg: string) =>
|
|
||||||
appendFileSync(DEBUG_LOG, `[${new Date().toISOString()}] ${msg}\n`)
|
|
||||||
|
|
||||||
const isInsideTmux = () => Boolean(process.env.TMUX)
|
const isInsideTmux = () => Boolean(process.env.TMUX)
|
||||||
const getCurrentPaneId = () => process.env.TMUX_PANE
|
const getCurrentPaneId = () => process.env.TMUX_PANE
|
||||||
|
|
||||||
@@ -31,7 +24,6 @@ const plugin: Plugin = async (ctx) => {
|
|||||||
const sessions = new Map<string, string>() // sessionId → tmux paneId
|
const sessions = new Map<string, string>() // sessionId → tmux paneId
|
||||||
const sourcePaneId = getCurrentPaneId()
|
const sourcePaneId = getCurrentPaneId()
|
||||||
const serverUrl = (ctx.serverUrl?.toString() ?? "").replace(/\/$/, "")
|
const serverUrl = (ctx.serverUrl?.toString() ?? "").replace(/\/$/, "")
|
||||||
log(`plugin init — serverUrl=${serverUrl} sourcePaneId=${sourcePaneId}`)
|
|
||||||
|
|
||||||
// Ordered list of pane IDs in the right column.
|
// Ordered list of pane IDs in the right column.
|
||||||
// Empty = no right column yet; length > 0 = right column exists.
|
// Empty = no right column yet; length > 0 = right column exists.
|
||||||
@@ -47,11 +39,7 @@ const plugin: Plugin = async (ctx) => {
|
|||||||
const sessionId: string = info.id
|
const sessionId: string = info.id
|
||||||
if (sessions.has(sessionId)) return
|
if (sessions.has(sessionId)) return
|
||||||
|
|
||||||
// Wrap the attach command: on failure, show the error and keep the
|
const cmd = `opencode attach ${serverUrl} --session ${sessionId}`
|
||||||
// pane open for 30 s so we can read it before it disappears.
|
|
||||||
const attachCmd = `opencode attach ${serverUrl} --session ${sessionId}`
|
|
||||||
const cmd = `bash -c '${attachCmd}; echo "--- exit: $? ---" >> ${DEBUG_LOG}; sleep 30'`
|
|
||||||
log(`spawning pane — cmd: ${attachCmd}`)
|
|
||||||
|
|
||||||
let args: string[]
|
let args: string[]
|
||||||
if (rightColumnPanes.length === 0) {
|
if (rightColumnPanes.length === 0) {
|
||||||
@@ -89,7 +77,6 @@ const plugin: Plugin = async (ctx) => {
|
|||||||
const proc = spawn(args, { stdout: "pipe", stderr: "pipe" })
|
const proc = spawn(args, { stdout: "pipe", stderr: "pipe" })
|
||||||
const paneId = (await new Response(proc.stdout).text()).trim()
|
const paneId = (await new Response(proc.stdout).text()).trim()
|
||||||
const exitCode = await proc.exited
|
const exitCode = await proc.exited
|
||||||
log(`split-window exit=${exitCode} paneId=${paneId}`)
|
|
||||||
if (exitCode === 0 && paneId) {
|
if (exitCode === 0 && paneId) {
|
||||||
sessions.set(sessionId, paneId)
|
sessions.set(sessionId, paneId)
|
||||||
rightColumnPanes.push(paneId)
|
rightColumnPanes.push(paneId)
|
||||||
|
|||||||
Reference in New Issue
Block a user