From b95f26e91c00d47e28b81dae7da70ec043d8ce3e Mon Sep 17 00:00:00 2001 From: Martin Laporte Date: Thu, 1 Oct 2026 10:23:12 +0200 Subject: [PATCH 1/2] feat: open Ghostty worktree tabs split with Claude Code New Ghostty tabs for a worktree now open with two side-by-side panes. The left pane resumes the folder's last Claude Code session (falling back to a fresh one), and the right pane is a plain shell. Co-Authored-By: Claude Opus 5.5 --- .../treebeard/src/bun/services/launcher.ts | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/treebeard/src/bun/services/launcher.ts b/packages/treebeard/src/bun/services/launcher.ts index 2b27826..2243bc3 100644 --- a/packages/treebeard/src/bun/services/launcher.ts +++ b/packages/treebeard/src/bun/services/launcher.ts @@ -13,8 +13,15 @@ export async function launchIde(ideId: IdeId, worktreePath: string): Promise { // Use AppleScript to switch to an existing Ghostty tab for this worktree, - // or open a new tab in the correct directory if none exists. - // This ensures proper tab naming and tab management like the opencode launcher. + // or open a new tab in the correct directory, split into two side-by-side + // panes, if none exists. The left pane resumes Claude Code when installed. + const env = await getShellEnv() + const whichProc = Bun.spawn(['which', 'claude'], { stdout: 'pipe', stderr: 'ignore', env }) + const claudePath = (await new Response(whichProc.stdout).text()).trim() + // --continue fails when the folder has no prior session, so fall back to a fresh one + const claudeInput = claudePath + ? `\n set initial input of leftCfg to "${claudePath} --continue || ${claudePath}\\n"` + : '' const pathParts = worktreePath.split('/') const worktreeName = pathParts.pop() || '' const projectName = pathParts.pop() || '' @@ -33,8 +40,13 @@ tell application "Ghostty" end repeat set cfg to new surface configuration set initial working directory of cfg to targetPath - set newTab to new tab in targetWindow with configuration cfg - perform action "set_tab_title:${tabTitle}" on (focused terminal of newTab) + set leftCfg to new surface configuration + set initial working directory of leftCfg to targetPath${claudeInput} + set newTab to new tab in targetWindow with configuration leftCfg + set leftTerm to focused terminal of newTab + perform action "set_tab_title:${tabTitle}" on leftTerm + split leftTerm direction right with configuration cfg + focus leftTerm end tell ` Bun.spawn(['/usr/bin/osascript', '-e', script], { stdout: 'ignore', stderr: 'ignore' }) From cb1a4768e408897de86979288fa42f49a3364a95 Mon Sep 17 00:00:00 2001 From: Martin Laporte Date: Thu, 1 Oct 2026 10:26:17 +0200 Subject: [PATCH 2/2] Update lockfile --- bun.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bun.lock b/bun.lock index f63fc13..2837685 100644 --- a/bun.lock +++ b/bun.lock @@ -12,7 +12,7 @@ }, "packages/treebeard": { "name": "treebeard", - "version": "2.11.0", + "version": "2.17.1", "dependencies": { "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0",