Skip to content

Add ghostty support to zen.#1

Merged
mgreau merged 1 commit intomgreau:mainfrom
afoucret:ghostty_support
Mar 4, 2026
Merged

Add ghostty support to zen.#1
mgreau merged 1 commit intomgreau:mainfrom
afoucret:ghostty_support

Conversation

@afoucret
Copy link
Copy Markdown
Contributor

Summary

  • Add Ghostty as an alternative terminal emulator alongside iTerm2
  • New terminal config option: iterm (default) or ghostty
  • Ghostty uses UI scripting for tab creation with fallback to new windows

Changes

  • New internal/terminal package with Terminal interface abstraction
  • New internal/ghostty package for Ghostty-specific implementation
  • Config validation for terminal type at load time
  • Renamed --no-iterm flag to --no-terminal
  • Fixed shell quoting for paths with spaces in both iTerm and Ghostty

Configuration

  terminal: ghostty  # or "iterm" (default)

Ghostty Requirements

  • Ghostty must be running before using zen commands
  • Requires Accessibility and Automation permissions
  • Falls back to new windows if tab creation fails

@mgreau mgreau self-requested a review February 21, 2026 19:46
@mgreau mgreau closed this Feb 21, 2026
@mgreau mgreau reopened this Feb 21, 2026
@mgreau
Copy link
Copy Markdown
Owner

mgreau commented Feb 21, 2026

Could you please rebase on main? I've just added a CI checks workflow and it needs to be on your branch to trigger.

mgreau

This comment was marked as duplicate.

mgreau

This comment was marked as duplicate.

mgreau

This comment was marked as duplicate.

Comment thread cmd/resume.go
cmd.Flags().IntVarP(&resumeSession, "session", "s", 0, "Resume Nth session instead of most recent (1-based)")
cmd.Flags().BoolVarP(&resumeList, "list", "l", false, "List available sessions without resuming")
cmd.Flags().BoolVar(&resumeNoITerm, "no-iterm", false, "Print the resume command instead of opening iTerm2")
cmd.Flags().BoolVar(&resumeNoITerm, "no-terminal", false, "Print the resume command instead of opening terminal")
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment on line 225 above this function still says --no-iterm:

// addResumeFlags adds the shared --session, --list, --no-iterm flags to a cobra command.

Should reference --no-terminal now that the flag has been renamed.

Comment thread internal/ghostty/tab.go
// Fallback to opening in new window if UI scripting fails
// This happens if Ghostty isn't open or accessibility permissions are missing
// Use Ghostty's -e flag to execute a shell command
fallbackCmd := exec.Command("open", "-na", "Ghostty", "--args", "-e", "/bin/bash", "-c", fullCmd)
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the UI scripting fails (line 38), the code silently falls back to opening a new window. The user gets no indication that tab creation didn't work. Consider logging a message to stderr (e.g., "Ghostty tab creation failed, falling back to new window") so users understand why they're getting windows instead of tabs.

Comment thread internal/ghostty/tab.go
func OpenTabWithClaude(workDir, initialPrompt, claudeBin string) error {
cmd := fmt.Sprintf("%s %q", claudeBin, initialPrompt)
return OpenTab(workDir, cmd)
} No newline at end of file
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing trailing newline at end of file.


func (t *GhosttyTerminal) OpenTabWithClaude(workDir, initialPrompt, claudeBin string) error {
return ghostty.OpenTabWithClaude(workDir, initialPrompt, claudeBin)
} No newline at end of file
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing trailing newline at end of file.

Comment thread cmd/resume.go
cmd.Flags().IntVarP(&resumeSession, "session", "s", 0, "Resume Nth session instead of most recent (1-based)")
cmd.Flags().BoolVarP(&resumeList, "list", "l", false, "List available sessions without resuming")
cmd.Flags().BoolVar(&resumeNoITerm, "no-iterm", false, "Print the resume command instead of opening iTerm2")
cmd.Flags().BoolVar(&resumeNoITerm, "no-terminal", false, "Print the resume command instead of opening terminal")
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The flag was renamed to --no-terminal, but the Go variable names still reference iTerm: resumeNoITerm (line 21), reviewNoITerm (cmd/review.go:50), workNewNoITerm (cmd/work.go:48). Consider renaming to resumeNoTerminal, reviewNoTerminal, workNewNoTerminal for consistency.

@mgreau mgreau merged commit cd8bc25 into mgreau:main Mar 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants