fix(sessions): filter sidechain (sub-agent) JSONL files from sidebar#726
fix(sessions): filter sidechain (sub-agent) JSONL files from sidebar#726ofligit wants to merge 1 commit intositeboon:mainfrom
Conversation
📝 WalkthroughWalkthroughThe pull request modifies Changes
Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
server/projects.js (1)
2030-2031: Consider:searchConversationsmay surface sidechain entries.The
searchConversationsfunction uses the sameagent-*filename filter but doesn't applyisInteractiveClaudeSessionFileor skip entries withisSidechain === true. This means search results could include matches from sidechain content.This may be acceptable since:
- Search is for content discovery, not session resumption
- Adding file-level checks would increase latency for search
If sidechain content is appearing in search results and causing noise, consider adding the
isSidechainentry-level skip to the search loop.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@server/projects.js` around lines 2030 - 2031, searchConversations currently filters JSONL files by filename (excluding agent-*) but does not check per-entry flags, so sidechain entries can surface; update the search loop inside searchConversations to skip any conversation entry where entry.isSidechain === true (and optionally reuse the existing isInteractiveClaudeSessionFile check) so sidechain content is excluded from search results while keeping the filename-level filter (refer to the searchConversations function and the isInteractiveClaudeSessionFile / isSidechain entry properties to locate the change).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@server/projects.js`:
- Around line 2030-2031: searchConversations currently filters JSONL files by
filename (excluding agent-*) but does not check per-entry flags, so sidechain
entries can surface; update the search loop inside searchConversations to skip
any conversation entry where entry.isSidechain === true (and optionally reuse
the existing isInteractiveClaudeSessionFile check) so sidechain content is
excluded from search results while keeping the filename-level filter (refer to
the searchConversations function and the isInteractiveClaudeSessionFile /
isSidechain entry properties to locate the change).
fix(sessions): filter sidechain (sub-agent) JSONL files from sidebar
Summary
The session sidebar surfaces every
*.jsonlfile in~/.claude/projects/<project-dir>/as a resumable session. That includesMCP-spawned sub-agent transcripts which the Agent SDK writes with normal UUID filenames —
indistinguishable from real sessions by name. Each one becomes a phantom
"tab" in the sidebar and resuming it does nothing useful, since each is a
finished non-interactive sub-conversation.
The existing
agent-*.jsonlfilename filter only catches Task-tooltranscripts; it doesn't catch MCP sub-agents.
Fix
Adds a content-based predicate
isInteractiveClaudeSessionFile()next tothe existing filename filter in
server/projects.js. It streams eachcandidate file, finds the first
user/assistantentry, and returnsentry.isSidechain !== true. Files with no user/assistant entry (e.g.files that contain only
file-history-snapshotrecords) are treated asnon-interactive.
Why
isSidechainand not a heuristic:sub-conversation".
through the same SDK code that sets it, so the predicate is forward-
compatible.
The filename
agent-*filter is kept as a cheap fast-path so we don'thave to open those files at all.
A small defensive change in
parseJsonlSessions()also skips individualentries with
isSidechain === true. The file-level filter is the primarygate; this prevents a stray sidechain entry inside a mixed-content file
from materialising a phantom session.
Files changed
server/projects.jsisInteractiveClaudeSessionFile(filePath)getSessions(): applies the predicate after theagent-*filenamefilter, before iterating into
parseJsonlSessions()parseJsonlSessions(): per-entry defensive skip whenentry.isSidechain === trueVerification
node --check server/projects.jspasses.session is preserved; sidechain UUID files (when present) are dropped;
file-history-snapshot-only stub files (nosessionId, didn't renderbefore either) are also dropped — no behavioural change for those, just
cleaner up-front filtering.
Taskmaster-heavy projects no longer show competing-tab phantoms.
Out of scope (follow-up)
isSidechainis Claude-specific. Other providers will hit the same UXbug class as they grow MCP-style sub-agents. The architectural home for
that is a per-provider
provider.isInteractiveSession(records)predicatedispatched by a shared sidebar filter, which fits naturally into the
DB-driven session refactor in #715. Not changing the provider adapter
shape here to keep this fix small and back-portable.
Summary by CodeRabbit
Release Notes