From 0503c474a8a90c832ae67c7d003ffc11f7791193 Mon Sep 17 00:00:00 2001 From: bendtherules Date: Sat, 21 Mar 2026 17:42:38 +0530 Subject: [PATCH] fix: use sessionName instead of safeSessionName in tmux commands --- src/core/close.ts | 8 ++++---- tests/close.test.ts | 17 +++++++++++++++++ tests/open.test.ts | 25 +++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/core/close.ts b/src/core/close.ts index 1a41986..20fc663 100644 --- a/src/core/close.ts +++ b/src/core/close.ts @@ -54,14 +54,14 @@ export async function closeMultiModel(options: CloseSessionOptions): Promise { expect(executedCommands).toContain(`git branch -D opencode/${sanitized}/model`); }); + test("tmux commands use sessionName, not safeSessionName", async () => { + const unsanitized = "my session!"; + const sanitized = "my-session"; + mockCommandResponses[`tmux has-session -t ${unsanitized}`] = { ok: true, stdout: "", stderr: "" }; + mockCommandResponses[`tmux kill-session -t ${unsanitized}`] = { ok: true, stdout: "", stderr: "" }; + // No worktrees + mockCommandResponses["git worktree list --porcelain"] = { ok: true, stdout: "", stderr: "" }; + + const result = await closeMultiModel({ sessionName: unsanitized, cleanupWorktrees: false, force: false }); + expect(result.success).toBe(true); + // Verify tmux commands used unsanitized name + expect(executedCommands).toContain(`tmux has-session -t ${unsanitized}`); + expect(executedCommands).toContain(`tmux kill-session -t ${unsanitized}`); + // Ensure sanitized name not used in tmux commands + expect(executedCommands.some(c => c.includes(`-t ${sanitized}`))).toBe(false); + }); + test("skip archive tags when flag disabled", async () => { mockCommandResponses["tmux has-session -t test-session"] = { ok: false, stdout: "", stderr: "" }; const worktreePath = "/home/user/.local/share/opencode/multi-model/test-session/model"; diff --git a/tests/open.test.ts b/tests/open.test.ts index 5be14ef..0ea6559 100644 --- a/tests/open.test.ts +++ b/tests/open.test.ts @@ -232,6 +232,31 @@ describe("multi-model launch", () => { expect(executedCommands.some(c => c.startsWith("git worktree add -b opencode/test-session/gpt-5-2"))).toBe(true); }); + test("uses sessionName for tmux commands, not safeSessionName", async () => { + const unsanitized = "my awesome session!!"; + const sanitized = "my-awesome-session"; + mockCommandResponses[`tmux has-session -t ${unsanitized}`] = { ok: false, stdout: "", stderr: "" }; + mockCommandResponses[`git show-ref --verify --quiet refs/heads/opencode/${sanitized}/gpt-5-2`] = { ok: false, stdout: "", stderr: "" }; + mockCommandResponses[`git worktree add -b opencode/${sanitized}/gpt-5-2 /mock/home/.local/share/opencode/multi-model/${sanitized}/gpt-5-2`] = { ok: true, stdout: "", stderr: "" }; + mockCommandResponses[`tmux new-session -d -s ${unsanitized} -n gpt-5-2 -c /mock/home/.local/share/opencode/multi-model/${sanitized}/gpt-5-2`] = { ok: true, stdout: "", stderr: "" }; + mockCommandResponses[`tmux send-keys -t ${unsanitized}:gpt-5-2 opencode --model 'openai/gpt-5.2' C-m`] = { ok: true, stdout: "", stderr: "" }; + + const result = await openMultiModel({ + sessionName: unsanitized, + models: ["openai/gpt-5.2"], + }); + + expect(result.success).toBe(true); + // tmux commands should use unsanitized name + expect(executedCommands.some(c => c.startsWith(`tmux has-session -t ${unsanitized}`))).toBe(true); + expect(executedCommands.some(c => c.startsWith(`tmux new-session -d -s ${unsanitized}`))).toBe(true); + expect(executedCommands.some(c => c.startsWith(`tmux send-keys -t ${unsanitized}:`))).toBe(true); + // sanitized name should NOT appear in tmux commands + expect(executedCommands.some(c => c.includes(`-t ${sanitized}`))).toBe(false); + // git branches and paths should use sanitized name + expect(executedCommands.some(c => c.startsWith(`git worktree add -b opencode/${sanitized}/gpt-5-2`))).toBe(true); + }); + test("fails if tmux new-session fails for the first model and triggers undo", async () => { mockCommandResponses["tmux new-session -d -s test-session -n gpt-5-2 -c /mock/home/.local/share/opencode/multi-model/test-session/gpt-5-2"] = { ok: false, stdout: "", stderr: "tmux error" }; mockCommandResponses["git worktree remove -f /mock/home/.local/share/opencode/multi-model/test-session/gpt-5-2"] = { ok: true, stdout: "", stderr: "" };