Skip to content

fix: lock session usage tracking to specific Claude session ID - #2

Merged
MartianGreed merged 2 commits into
mainfrom
push-xuzwywomvokm
Jan 21, 2026
Merged

MartianGreed merged 2 commits into
mainfrom
push-xuzwywomvokm

Conversation

@MartianGreed

Copy link
Copy Markdown
Owner

No description provided.

@greptile-apps

greptile-apps Bot commented Jan 20, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes usage tracking by locking each tmux session to a specific Claude session ID at discovery time, preventing incorrect usage attribution when multiple sessions exist in the same working directory.

Key Changes:

  • Added ClaudeSessionID field to SessionState that locks to the most recent Claude session at discovery time
  • Added FindActiveSessionID() and GetSessionByID() functions to look up and retrieve specific session usage
  • Updated updateUsage() in monitor to use locked session ID instead of finding most recent
  • Modified WatchSession() to accept optional session ID parameter for targeted file watching
  • Added Claude Code logo pattern detection for better idle state recognition
  • Enhanced TUI with usage display in header and improved notification overlay

Issues Found:

  • Removed TrimPrefix on line 165 of internal/usage/parser.go breaks path encoding for root-level directories, causing directory lookup failures

Confidence Score: 3/5

  • This PR has a critical path encoding bug that will break directory lookups
  • The session locking logic is well-implemented and solves the usage tracking problem effectively. However, removing the TrimPrefix call in FindProjectDir() introduces a critical bug where paths starting with / (all absolute paths) will be encoded with a leading dash, preventing the code from finding Claude's project directories. This will cause usage tracking to fail entirely for root-level paths.
  • Pay close attention to internal/usage/parser.go line 165 - the path encoding change will break directory lookups

Important Files Changed

Filename Overview
internal/usage/parser.go Added session ID lookup functions and removed path prefix trimming which may break directory lookups for root paths
internal/daemon/monitor.go Added ClaudeSessionID field to lock usage tracking to specific session, preventing session switching issues
internal/usage/watcher.go Updated WatchSession to accept sessionID parameter for locked session tracking

Sequence Diagram

sequenceDiagram
    participant Monitor as Monitor (daemon)
    participant Tmux as Tmux Client
    participant Usage as Usage Parser
    participant Watcher as Usage Watcher
    participant FS as File System

    Note over Monitor: Session Discovery
    Monitor->>Tmux: ListSessions()
    Tmux-->>Monitor: tmux sessions
    Monitor->>Tmux: GetSessionPath(session)
    Tmux-->>Monitor: workingDir
    
    Note over Monitor,Usage: Lock Session ID (NEW)
    Monitor->>Usage: FindActiveSessionID(workingDir)
    Usage->>FS: FindProjectDir & list *.jsonl files
    FS-->>Usage: session files
    Usage->>FS: Stat files for most recent
    Usage-->>Monitor: claudeSessionID
    
    Monitor->>Usage: GetSessionByID(workingDir, claudeSessionID)
    Usage->>FS: Read specific session JSONL file
    FS-->>Usage: session data
    Usage-->>Monitor: SessionUsage
    
    Note over Monitor: Store locked session ID
    Monitor->>Monitor: Store ClaudeSessionID in SessionState
    Monitor->>Watcher: WatchSession(name, workingDir, claudeSessionID)
    
    Note over Watcher: Continuous Monitoring
    loop Every pollInterval
        Watcher->>FS: Stat(sessionFile)
        FS-->>Watcher: file info
        alt File changed
            Watcher->>Usage: ParseSessionFile(sessionFile)
            Usage->>FS: Read JSONL lines
            FS-->>Usage: token usage data
            Usage-->>Watcher: Updated SessionUsage
            Watcher->>Monitor: Notify update
        end
    end
    
    Note over Monitor: Usage Updates (NEW)
    loop Every 5 poll cycles
        Monitor->>Usage: GetSessionByID(workingDir, claudeSessionID)
        Usage-->>Monitor: SessionUsage for locked session
        Monitor->>Monitor: Update SessionState.Usage
    end
Loading

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

9 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment thread internal/usage/parser.go
Comment on lines 164 to 165
// Claude Code uses path encoding: /Users/foo/bar -> -Users-foo-bar
encodedPath := strings.ReplaceAll(workingDir, "/", "-")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

logic: Removing TrimPrefix breaks path encoding for root-level directories. For example, /Users/foo/bar now encodes to -Users-foo-bar instead of Users-foo-bar, which won't match Claude's actual directory structure.

Suggested change
// Claude Code uses path encoding: /Users/foo/bar -> -Users-foo-bar
encodedPath := strings.ReplaceAll(workingDir, "/", "-")
// Claude Code uses path encoding: /Users/foo/bar -> -Users-foo-bar
encodedPath := strings.ReplaceAll(workingDir, "/", "-")
encodedPath = strings.TrimPrefix(encodedPath, "-")
Prompt To Fix With AI
This is a comment left during a code review.
Path: internal/usage/parser.go
Line: 164:165

Comment:
**logic:** Removing `TrimPrefix` breaks path encoding for root-level directories. For example, `/Users/foo/bar` now encodes to `-Users-foo-bar` instead of `Users-foo-bar`, which won't match Claude's actual directory structure.

```suggestion
	// Claude Code uses path encoding: /Users/foo/bar -> -Users-foo-bar
	encodedPath := strings.ReplaceAll(workingDir, "/", "-")
	encodedPath = strings.TrimPrefix(encodedPath, "-")
```

How can I resolve this? If you propose a fix, please make it concise.

@MartianGreed
MartianGreed merged commit b94da6d into main Jan 21, 2026
4 checks passed
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