Skip to content

fix(hooks): keep the ponytail level per Claude Code session - #1366

Open
buildwithme wants to merge 1 commit into
DietrichGebert:mainfrom
buildwithme:fix/session-level
Open

buildwithme wants to merge 1 commit into
DietrichGebert:mainfrom
buildwithme:fix/session-level

Conversation

@buildwithme

Copy link
Copy Markdown

Problem

With the default level off, every new Claude Code session deletes the per-project flag and the shared .ponytail-active flag (clearMode() from ponytail-activate.js). A session that is still on then reads off:

  • the band shows off, because it reads only the shared flag,
  • compaction re-activates as off (readMode() || 'off'), so the ruleset is gone for the rest of the session,
  • its subagents get no rules.

Resume also resets the level to the default (#1318). In the Claude Code desktop app this happens all the time: every new session in any repo, and every app restart that resumes a session.

Change

Claude Code passes CLAUDE_CODE_SESSION_ID to every hook, like CLAUDE_PROJECT_DIR. When it is set:

  • setMode also writes ponytail-modes/session-<id>, and readMode reads that file first.
  • clearMode records off in the session file instead of deleting it, so a session never falls back to a flag another session wrote.
  • Resume keeps the session's own level. A session with no record yet starts at the default, as before.
  • The band reads the session file first and the shared flag second.
  • Session files untouched for 30 days are pruned at a fresh start.

Hosts without that env var (Codex, Copilot, Qoder, Cursor and the rest) take the same path as today. The per-project and shared flags are still written, so the statusline works as before.

About #992

#992 was closed because keying by session "would touch every hook on every host". This change touches one runtime file, the SessionStart hook and the band, and only on Claude Code. The band is what makes the bug visible now: it shows one level per session, and it flips to off whenever another session starts.

Not in this PR

Tests

  • npm test: 173 of 174 pass. The one failure is csv: correct pandas one-liner passes; pandas is not installed on this machine.
  • claude plugin test .: 33 of 33 band tests pass, with one new case: the band shows its own session level, not the flag another session left behind.
  • node scripts/check-rule-copies.js and node scripts/check-versions.js pass.
  • New hook test: two sessions in one repo with default off. Session A switches to full. Session B starts, switches and stops. A stays full through compact, resume and subagent start; B stays off on resume.
  • Also checked with real headless Claude Code sessions on 5.3.2 with the same patch: other sessions started, switched and stopped in the same folder, then 3 turns and /compact. The level stayed full.

Refs #1162 (band and compaction part; the statusline part stays), #1318 (level part).
Related: #1175, #1321, #1174.

The live level was kept per project plus one shared flag. A new session that
starts at an "off" default deleted both, so a session that was still on lost
its level: the band showed off, compaction re-activated as off, and subagents
got no rules. Resume also reset the level to the default.

Claude Code passes CLAUDE_CODE_SESSION_ID to every hook, so the hooks now also
write ponytail-modes/session-<id>, and readMode reads it first. Off is recorded
as "off" instead of deleting the file, so a session never falls back to a flag
another session wrote. Resume keeps the session's own level; a session with no
record yet starts at the default. The band reads the session file first and the
shared flag as a fallback. Session files untouched for 30 days are pruned at a
fresh start.

Hosts without the env var keep the per-project and shared flags as before. The
statusline still reads the shared flag.

Refs DietrichGebert#1162, DietrichGebert#1318
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