Skip to content

Instantly share code, notes, and snippets.

@lukehedger
Last active March 10, 2026 11:12
Show Gist options
  • Select an option

  • Save lukehedger/e90bd4b10d8b00c1054e1d7e43091270 to your computer and use it in GitHub Desktop.

Select an option

Save lukehedger/e90bd4b10d8b00c1054e1d7e43091270 to your computer and use it in GitHub Desktop.
using claude agent teams split pane mode with ghostty

Ghostty Split Pane Mode for Claude Code Agent Teams

Background

Claude Code agent teams support two display modes:

  • In-process: all teammates run inside the main terminal (default)
  • Split panes: each teammate gets its own pane — requires tmux or iTerm2

Ghostty has native split pane support but until 1.3 had no programmatic way to create them. With the 1.3 release, AppleScript is now supported, which should allow Ghostty to be used for split pane mode without tmux.

Ghostty AppleScript API (1.3+)

Full docs: https://ghostty.org/docs/features/applescript

Object Model

application -> windows -> tabs -> terminals
Object Key Properties Key Elements
application name, frontmost, front window, version windows, terminals
window id, name, selected tab tabs, terminals
tab id, name, index, selected, focused terminal terminals
terminal id, name, working directory None

Key Commands

Command Purpose
split term direction Split a terminal, returns the new terminal
input text "..." to term Send paste-style text to a terminal
send key "..." to term Send a key press
focus term Focus a terminal and bring window to front
new surface configuration Create reusable config (command, cwd, env vars)

Split directions: right, left, down, up.

Surface Configuration Fields

  • command — replaces the shell with the specified command
  • initial working directory
  • initial input
  • font size
  • environment variables — list of KEY=VALUE strings
  • wait after command

Example: Split and Run a Command

tell application "Ghostty"
    set currentTerm to focused terminal of selected tab of front window
    set cfg to new surface configuration
    set command of cfg to "claude"
    set newTerm to split currentTerm direction right with configuration cfg
end tell

Script

Saved at ~/.claude/scripts/ghostty-teammate-split.applescript.

Usage

# Verify Ghostty AppleScript is working
osascript ~/.claude/scripts/ghostty-teammate-split.applescript test

# Create a single split
osascript ~/.claude/scripts/ghostty-teammate-split.applescript split right
osascript ~/.claude/scripts/ghostty-teammate-split.applescript split down "echo hello"

# Create a team layout (lead + N teammates)
osascript ~/.claude/scripts/ghostty-teammate-split.applescript layout 3
osascript ~/.claude/scripts/ghostty-teammate-split.applescript layout 3 "claude"

Layouts

1 mate:   [lead] | [mate1]

2 mates:  [lead]  | [mate1]
          [mate2] |

3 mates:  [lead]  | [mate1]
          [mate3] | [mate2]

4 mates:  [lead]  | [mate1]
          [mate3] | [mate2]
                  | [mate4]

5+ mates: [lead]  | [mate1]
                  | [mate2]
                  | [mate3]
                  | ...

Source

#!/usr/bin/osascript
--
-- ghostty-teammate-split.applescript
-- Creates split panes in Ghostty for Claude Code agent teams.
--
-- Ghostty 1.3+ required (AppleScript support).
-- AppleScript API is a preview feature in 1.3 — expect breaking changes in 1.4.
--

on run argv
	if (count of argv) = 0 then
		return "Usage: osascript ghostty-teammate-split.applescript <test|split|layout> [args...]"
	end if

	set subcommand to item 1 of argv

	if subcommand is "test" then
		return doTest()
	else if subcommand is "split" then
		return doSplit(argv)
	else if subcommand is "layout" then
		return doLayout(argv)
	else
		return "Unknown subcommand: " & subcommand & ". Use test, split, or layout."
	end if
end run

-- Verify Ghostty AppleScript is working
on doTest()
	tell application "Ghostty"
		set ver to version
		set win to front window
		set mainTab to selected tab of win
		set term to focused terminal of mainTab
		set cwd to working directory of term

		return "Ghostty " & ver & " | window: " & (id of win) & " | terminal: " & (id of term) & " | cwd: " & cwd
	end tell
end doTest

-- Create a single split pane and optionally run a command
-- Usage: split <direction> [command]
-- Direction: right, left, down, up
on doSplit(argv)
	set splitDir to "right"
	set cmd to ""

	if (count of argv)  2 then set splitDir to item 2 of argv
	if (count of argv)  3 then set cmd to item 3 of argv

	tell application "Ghostty"
		set mainTab to selected tab of front window
		set currentTerm to focused terminal of mainTab

		if cmd is not "" then
			set cfg to new surface configuration
			set command of cfg to cmd
			set newTerm to split currentTerm direction splitDir with configuration cfg
		else
			set newTerm to split currentTerm direction splitDir
		end if

		return id of newTerm
	end tell
end doSplit

-- Create a multi-pane team layout
-- Usage: layout <num_teammates> [command]
on doLayout(argv)
	set numTeammates to 3
	set cmd to ""

	if (count of argv)  2 then set numTeammates to (item 2 of argv) as integer
	if (count of argv)  3 then set cmd to item 3 of argv

	tell application "Ghostty"
		activate

		set mainTab to selected tab of front window
		set leadTerm to focused terminal of mainTab
		set paneIds to {id of leadTerm}

		if numTeammates = 1 then
			set mate1 to mySplit(leadTerm, "right", cmd)
			set end of paneIds to id of mate1

		else if numTeammates = 2 then
			set mate1 to mySplit(leadTerm, "right", cmd)
			set mate2 to mySplit(leadTerm, "down", cmd)
			set end of paneIds to id of mate1
			set end of paneIds to id of mate2

		else if numTeammates = 3 then
			set mate1 to mySplit(leadTerm, "right", cmd)
			set mate2 to mySplit(mate1, "down", cmd)
			set mate3 to mySplit(leadTerm, "down", cmd)
			set end of paneIds to id of mate1
			set end of paneIds to id of mate2
			set end of paneIds to id of mate3

		else if numTeammates = 4 then
			set mate1 to mySplit(leadTerm, "right", cmd)
			set mate2 to mySplit(mate1, "down", cmd)
			set mate3 to mySplit(leadTerm, "down", cmd)
			set mate4 to mySplit(mate2, "down", cmd)
			set end of paneIds to id of mate1
			set end of paneIds to id of mate2
			set end of paneIds to id of mate3
			set end of paneIds to id of mate4

		else
			-- 5+ teammates: lead gets left column, teammates stacked on right
			set rightTerm to mySplit(leadTerm, "right", cmd)
			set end of paneIds to id of rightTerm

			set prevTerm to rightTerm
			repeat with i from 2 to numTeammates
				set newTerm to mySplit(prevTerm, "down", cmd)
				set end of paneIds to id of newTerm
				set prevTerm to newTerm
			end repeat
		end if

		focus leadTerm

		set idStr to ""
		repeat with i from 1 to count of paneIds
			if i > 1 then set idStr to idStr & ","
			set idStr to idStr & (item i of paneIds)
		end repeat
		return idStr
	end tell
end doLayout

-- Helper: split a terminal with optional command
on mySplit(targetTerm, splitDir, cmd)
	tell application "Ghostty"
		if cmd is not "" then
			set cfg to new surface configuration
			set command of cfg to cmd
			return split targetTerm direction splitDir with configuration cfg
		else
			return split targetTerm direction splitDir
		end if
	end tell
end mySplit

Caveats

  • Ghostty AppleScript is a preview feature in 1.3 — the API may have breaking changes in 1.4
  • The command surface config field replaces the shell entirely with that command (when the command exits, the pane closes). Use initial input instead if you want a shell that runs a command
  • This does not integrate with Claude Code's teammateMode yet — Claude Code would need to add Ghostty as a supported terminal alongside tmux/iTerm2. The teammateMode setting only accepts "auto", "in-process", or "tmux"

Next Steps

  • Test the script with Ghostty 1.3
  • If it works, consider opening a feature request on claude-code to add Ghostty as a supported split pane terminal
  • The Ghostty API returns terminal IDs, supports working directory queries, and has environment variables on surface configs — all the building blocks Claude Code would need
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment