fix: annotate-last resolves wrong session after cd#366
Merged
backnotprop merged 2 commits intobacknotprop:mainfrom Mar 22, 2026
Merged
fix: annotate-last resolves wrong session after cd#366backnotprop merged 2 commits intobacknotprop:mainfrom
backnotprop merged 2 commits intobacknotprop:mainfrom
Conversation
When the user cd's during a Claude Code session, /plannotator-last picks up a stale session log from a different project directory because findSessionLogsForCwd() uses the current shell CWD, not the session's original project directory. Add three-tier session resolution: 1. PPID metadata (~/.claude/sessions/<ppid>.json) for deterministic O(1) lookup 2. CWD slug match (existing behavior, unchanged) 3. Ancestor directory walk as fallback Also: getLastRenderedMessage() now catches read errors instead of throwing, and extracted tryLogCandidates() to deduplicate the candidate iteration loop.
Owner
|
nice work |
Owner
|
making one adjustment for windows |
resolveSessionLogByPpid() was constructing the log path directly, bypassing the case-insensitive directory scan that findSessionLogsForCwd() already provides for Windows. Reuse that function instead. For provenance purposes, this commit was AI assisted.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
/plannotator-lastannotates the wrong message when the usercd's during a Claude Code session. No error, no warning — just the wrong content in the annotation UI.What happens
findSessionLogsForCwd()builds a project slug fromprocess.cwd(). Claude Code's session log lives under the slug for the original session directory, not the current shell CWD./Users/me→ log stored at~/.claude/projects/-Users-me/<id>.jsonlcd ~/projects/my-app/plannotator-lastuses CWD → looks in~/.claude/projects/-Users-me-projects-my-app/The user has no way to tell something went wrong until they read the text and realize it's not what they expected. By then they may have already written annotations against the wrong content.
Who this affects
Anyone who
cd's during a session. That's a common workflow —cdinto a repo, run commands, then annotate the assistant's response.This is a Claude Code-only bug. Codex uses
CODEX_THREAD_ID, OpenCode and Pi use their SDK APIs — none of them resolve sessions via CWD. The fix is scoped to the Claude Codeelsebranch; no other harness is touched.Fix
Three-tier session resolution (most precise first):
1. PPID session metadata (new, primary path)
Claude Code writes
~/.claude/sessions/<pid>.json:{"pid": 17326, "sessionId": "112c3961-...", "cwd": "/Users/me", "startedAt": ...}When
/plannotator-lastruns, its parent process is the Claude Code instance.process.ppid→ read the metadata → get the exact session ID and original CWD → open the exact JSONL. O(1), no scanning, no mtime heuristics.2. CWD slug match (existing behavior, unchanged)
Works when the shell CWD hasn't diverged from the session's project directory.
3. Ancestor walk (new fallback)
Walk up the directory tree trying parent slugs. Handles the case where PPID metadata is unavailable and the user
cd'd deeper into a subdirectory.Other changes
getLastRenderedMessage()now catches read errors instead of throwing on missing/corrupt files, so the fallback cascade doesn't crash mid-resolution.tryLogCandidates()to deduplicate the candidate iteration loop (was copy-pasted between CWD and ancestor fallbacks).Test plan
bun test apps/hook/server/)findSessionLogsByAncestorWalk(root returns empty, walks up to parent, skips exact CWD)CODEX_THREAD_ID, OpenCode and Pi use their SDK APIs — none of them resolve sessions via CWD. The fix is scoped to the Claude Codeelsebranch; no other harness is touched.