Skip to content

Comments

fix: extract session summaries from Claude JSONL files#96

Open
AgentWrapper wants to merge 2 commits intomainfrom
feat/extract-session-summary-from-jsonl
Open

fix: extract session summaries from Claude JSONL files#96
AgentWrapper wants to merge 2 commits intomainfrom
feat/extract-session-summary-from-jsonl

Conversation

@AgentWrapper
Copy link
Collaborator

Summary

  • Fix toClaudeProjectPath() encoding bug — the function stripped the leading / before encoding, producing Users-equinox-... while Claude's actual project directories are -Users-equinox-.... This was the root cause of getSessionInfo() never finding JSONL files.
  • Add live agent info enrichment in session manager's enrichSessionWithRuntimeState() so the dashboard gets summaries, cost estimates, and agent session IDs on every refresh.
  • Add background summary persistence in lifecycle manager polling — writes summary to metadata files so they survive dashboard restarts.

Before/After

Before: Sessions without PRs show generic info:

💤 ao-37
spawning
terminal
detached

After: Sessions show actual agent summaries:

💤 Better Agent-to-Agent Communication Architecture
ao-37 • spawning • detached
terminal

Test plan

  • All existing tests updated and passing (85 agent-claude-code tests, 131 core tests)
  • pnpm build succeeds
  • Path encoding verified against actual ~/.claude/projects/ directories
  • Manual verification: start dashboard, confirm sessions display summaries

🤖 Generated with Claude Code

}
}
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Full JSONL file parsed twice per session per poll

Medium Severity

During each poll cycle, getSessionInfo() is called twice per active session — first in sessionManager.list() via enrichSessionWithRuntimeState(), then again in checkSession(). Since getSessionInfo() reads and parses entire JSONL conversation files (which grow with every message), this doubles the file I/O on every poll interval. The session object passed to checkSession already has agentInfo populated from enrichment, so the lifecycle manager could use session.agentInfo?.summary instead of re-invoking getSessionInfo().

Additional Locations (1)

Fix in Cursor Fix in Web

AgentWrapper and others added 2 commits February 20, 2026 19:33
Fix toClaudeProjectPath() encoding bug that prevented JSONL file discovery -
the function was stripping the leading / before encoding, producing
"Users-equinox-..." while Claude's actual directories are "-Users-equinox-...".

Add live agent info enrichment in session manager so the dashboard gets
summaries, cost estimates, and agent session IDs on every refresh.

Add background summary persistence in lifecycle manager polling so summaries
survive dashboard restarts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@AgentWrapper AgentWrapper force-pushed the feat/extract-session-summary-from-jsonl branch from e067b9a to a5655ae Compare February 20, 2026 14:07
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

const info = await agent.getSessionInfo(session);
if (info?.summary && info.summary !== session.metadata?.["summary"]) {
const sessionsDir = getSessionsDir(config.configPath, project.path);
updateMetadata(sessionsDir, session.id, { summary: info.summary });
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newlines in summary corrupt metadata file format

Medium Severity

The summary from getSessionInfo (sourced from JSONL files) can contain newline characters — either from Claude's auto-generated summaries or from multi-line user prompts used as fallback. Writing this unsanitized value via updateMetadata into the newline-delimited key=value metadata format corrupts the file. On the next read, the summary is silently truncated at the first newline, and any subsequent lines containing = overwrite other metadata keys like status or pr.

Fix in Cursor Fix in Web

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