Skip to content

fix: chain the statusline badge instead of taking the whole slot - #910

Open
xanderscannell wants to merge 1 commit into
DietrichGebert:mainfrom
xanderscannell:fix/statusline-compose
Open

xanderscannell wants to merge 1 commit into
DietrichGebert:mainfrom
xanderscannell:fix/statusline-compose

Conversation

@xanderscannell

Copy link
Copy Markdown

Problem

Claude Code has a single statusLine slot, and the setup nudge in ponytail-activate.js treats it as all-or-nothing:

  • A statusLine is already configuredhasStatusline = true and ponytail stays silent forever. Anyone running a custom status line, or another plugin's, never gets the badge at all and is never told why.
  • No statusLine → the nudge claims the slot outright. That's fine while ponytail is active, but the script exits silently when the mode flag is absent, so turning ponytail off leaves an empty row rather than the line you had.

The repo already assumes chained status lines exist — scripts/uninstall.js splits on &&/; and preserves non-ponytail segments (#374) — but nothing on the install path ever produces one.

Fix

Chain into the slot instead of taking it. The badge already prints without a trailing newline, so running it ahead of the existing command renders both on one row, and an inactive ponytail exits 0 with no output, leaving the rest of the line untouched.

; rather than && as the separator: Claude Code runs the status line through Git Bash when Git Bash is installed and PowerShell when it isn't, and Windows PowerShell 5.1 cannot parse && (verified on 5.1.26100). ; parses in Git Bash, PowerShell 5.1 and PowerShell 7.

The snippet is rebuilt from the existing statusLine block, so sibling keys such as padding and refreshInterval survive rather than being dropped when the suggested JSON is pasted in.

Ponytail stays quiet when it is already in the chain, or when statusLine.command is not a string (nothing safe to chain onto).

scripts/uninstall.js needs no change: splitting ponytail ; base leaves a single remaining segment, which rejoins with no separator, so unchaining round-trips to the original command exactly. Verified below.

Result

ponytail full:   [PONYTAIL] Opus 5 | ~/proj | main | Ctx:42%
ponytail ultra:  [PONYTAIL:ULTRA] Opus 5 | ~/proj | main | Ctx:42%
ponytail off:    Opus 5 | ~/proj | main | Ctx:42%

One row in every case. The third line is the behaviour this fixes — today that row is blank.

Verification

  • node scripts/check-rule-copies.js and node scripts/check-versions.js pass. npm test passes 94/95; the one failure, csv: correct pandas one-liner passes, fails identically on unmodified main in my environment and is untouched by this change.
  • New assertions in tests/hooks.test.js fail against the current ponytail-activate.js and pass with the change.
  • Tested live on Windows 11 with Git Bash, against a real user statusLine: the nudge fired, Claude applied the chained command, the badge rendered inline on one row, and toggling ponytail off left the status line intact.
  • Round-tripped a ;-chained command through node scripts/uninstall.js and confirmed statusLine.command came back byte-for-byte as the original.

Notes

  • No version bump; check-versions.js pins 8 files and releases look like separate chore: release commits.
  • Separate from this change, getHideStatus() is honoured by pi-extension/index.js but not by the Claude Code statusline scripts, so PONYTAIL_HIDE_STATUS silently does nothing there. Happy to open an issue if that's worth fixing.

Claude Code has one statusLine slot, and the setup nudge treated it as
all-or-nothing. With a statusLine already configured, activate.js set
hasStatusline and stayed silent for good, so anyone running a custom
status line (or another plugin's) never got the badge at all. With none,
the nudge claimed the slot outright, which leaves a blank row whenever
ponytail goes quiet.

Chain into it instead. The badge already prints without a trailing
newline, so running it ahead of the existing command renders both on one
row, and an inactive ponytail exits 0 with no output, leaving that
command's line untouched. Separator is ';' rather than '&&': Claude Code
runs the status line through Git Bash when installed and PowerShell when
not, and Windows PowerShell 5.1 cannot parse '&&'.

- hooks/ponytail-activate.js: read the command already in the slot and
  chain it after ours; stay quiet when ponytail is already in the chain,
  or when the statusLine is not a string command. The snippet is rebuilt
  from the existing block, so sibling keys (padding, refreshInterval)
  survive instead of being dropped by the paste
- hooks/ponytail-statusline.{sh,ps1}: trailing space after the color
  reset, so the badge does not butt against the next command's output
- tests/hooks.test.js: an existing status line gets the nudge and comes
  back out of the snippet intact; ponytail already in the chain is not
  offered again

scripts/uninstall.js needs no change: it already splits on ';' and keeps
non-ponytail segments (DietrichGebert#374), and a single remaining segment rejoins
without a separator, so unchaining round-trips exactly.
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.

1 participant