777genius/claude-notifications-go

Ghostty exact-tab focus fails when Claude Code launched via 'claude -w' from parent dir

Open

#77 opened on Apr 19, 2026

View on GitHub
 (0 comments) (0 reactions) (0 assignees)Go (100 forks)auto 404
bughelp wanted

Repository metrics

Stars
 (759 stars)
PR merge metrics
 (PR metrics pending)

Description

Summary

focus-window for Ghostty matches the AppleScript-reported working directory of each tab against the notification's cwd. When Claude Code is launched with claude -w <worktree-name> from a parent dir, the shell's cwd never moves into the worktree, so Ghostty reports the parent dir and the candidate set built by ghosttyFocusCandidates (internal/notifier/ax_focus_darwin.go:425) never matches → falls back to AXDocument → window-level focus only (lands on a sibling tab in the same parent).

Repro

cd /repo
claude -w feat/foo                          # Claude internally uses /repo/.claude/worktrees/feat/foo
# Trigger any task_complete notification
# Click → Ghostty activates but stops at the wrong tab (a sibling tab whose Ghostty cwd happens to match /repo)

Evidence

  • Claude Code process cwd (correct): /repo/.claude/worktrees/feat/foo (verified via lsof -p <pid> -d cwd)
  • Ghostty AppleScript reports for that tab: /repo (parent), not the worktree
  • ghosttyFocusCandidates builds [worktree, symlink-resolved-worktree] — neither matches /repo
  • Falls through to focusGhosttyWindowByAXDocument → window-level focus only

Ghostty's AppleScript working directory reflects the most recent OSC 7 (shell cd), not the foreground process's cwd. claude -w doesn't move the parent shell's cwd into the worktree, so the discrepancy is permanent for that tab. Note that pre-cd-then-claude is not a workable workaround because -w is typically used to create the worktree on first run, when the worktree path does not yet exist.

Proposed Fixes (ranked)

1. Foreground-process cwd matching (correct, ~80 LOC + cgo) Query each Ghostty tab's foreground PID via AppleScript (tty of every terminallsof -t <tty>), then proc_pidinfo for cwd. Match the tab whose foreground process cwd equals the notification cwd. Disambiguates tabs that share a parent dir.

2. Parent-dir fallback (heuristic, ~30 LOC) Extend ghosttyFocusCandidates to walk up parent dirs (stop at git root or filesystem root). Accepts ambiguity when ≥2 tabs share a parent — first match wins.

Happy to send a PR for either, given guidance on which is acceptable.

Environment

  • Plugin v1.38.0
  • macOS 15.x, arm64
  • Ghostty (tip)
  • Claude Code with -w flag

Contributor guide