feat(tracking+gain): per-session token savings tracking#2537
Open
karl82 wants to merge 4 commits into
Open
Conversation
- Add current_session_id() helper reading CLAUDE_CODE_SESSION_ID env var - Migrate commands table: session_id TEXT DEFAULT '' + index - Add SessionStat struct for per-session aggregation - Add get_by_session(filter: Option<&str>) with LIKE prefix matching - 6 unit tests: grouping, empty-id exclusion, ordering, empty db, avg pct, prefix filter - Backward compatible: ALTER TABLE ignored on existing column, old rows get empty default
- rtk gain --session show all tracked sessions (most recent first) - rtk gain --session <id> filter by session ID prefix (e.g. '2a35ea7f') - show_session_view(): table with short ID, relative age, cmds, saved, avg% - Empty-state message for installs predating session tracking - Uses clap num_args=0..=1 + default_missing_value='' for optional arg
- LIKE → GLOB for session prefix filter (matches project_path convention) - COALESCE(SUM/AVG) guards against NULL on empty groups - LIMIT only applies to bare --session; prefix filter returns all matches - show_session_view: title shows prefix not first session ID - show_session_view: chars().take(8) instead of byte-index slice - --session <id>: show full rtk gain detail view scoped to that session (by-command table, efficiency meter, exec time) via get_summary_for_session()
… helpers Eliminates the duplicated table-rendering code between run() and show_session_detail() by factoring it into two shared private functions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.
What
Adds per-session token savings tracking to
rtk gain. Each Claude Code session gets its own row in the tracking database so you can see exactly how much each session saved.Changes
src/core/tracking.rssession_id TEXT DEFAULT ''column on thecommandstable (migration-safeALTER TABLE)session_idfor fast per-session queriesSessionStatstruct:session_id,last_seen,commands,saved_tokens,avg_savings_pctTracker::get_by_session(filter)— groups commands byCLAUDE_CODE_SESSION_ID, most recent first, empty IDs excludedTracker::get_summary_for_session(prefix)— fullGainSummaryscoped to one session (used for detail view)record()now capturesCLAUDE_CODE_SESSION_IDfrom env on every insertsrc/analytics/gain.rs--session [<SESSION_ID>]flag (short-S):--session→ table of all sessions (most recent 20), sorted newest first--session <prefix>→ detailed gain summary scoped to that session (same layout as globalrtk gain)print_summary_kpis()andprint_by_command_table()helpers (no behaviour change — reduces duplication between global and per-session views)src/main.rs--sessionflag on theGaincommandUsage
Notes
CLAUDE_CODE_SESSION_ID(recorded before this change, or commands run outside Claude Code) are silently excluded from session views — they still count in the globalrtk gainsummaryget_by_sessionuses GLOB not LIKE for prefix matching (consistent with existingproject_pathfilter — avoids_and%acting as wildcards)new_in_memory()(tests) uses the full schema directly🤖 Generated with Claude Code