feat: improve thinking detection and add usage overlay - #3
Conversation
Greptile SummaryEnhanced thinking state detection with new patterns ( Key Changes:
Issues Found:
Confidence Score: 3/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant User
participant TUI as TUI Model
participant Monitor
participant Store as SQLite Store
participant Detector
participant Usage as Usage Parser
participant FS as File System
Note over User,FS: App Initialization
User->>TUI: Start ccmanager
TUI->>Monitor: NewMonitor(pollInterval, store)
Monitor->>Detector: NewDetector()
Monitor->>Store: Reference stored
Note over Monitor,FS: Session Discovery & Persistence
Monitor->>Monitor: poll()
Monitor->>Detector: DetectState(content)
Detector-->>Monitor: StateThinking/StateIdle/StateUrgent
Monitor->>Store: GetClaudeSessionID(tmuxSession)
Store-->>Monitor: claudeSessionID (from DB)
alt No persisted session ID
Monitor->>Usage: FindActiveSessionID(workingDir)
Usage->>FS: Read .claude/projects/*/session_*.jsonl
FS-->>Usage: Active session ID
Usage-->>Monitor: claudeSessionID
Monitor->>Store: CreateSession(tmuxSession)
Monitor->>Store: SetClaudeSessionID(tmuxSession, claudeSessionID)
end
Monitor->>Usage: GetSessionByID(workingDir, claudeSessionID)
Usage->>FS: Parse session JSONL file
FS-->>Usage: Session data
Usage-->>Monitor: SessionUsage with tokens & cost
Note over User,FS: Usage Overlay Feature (Press 'u')
User->>TUI: Press 'u' key
TUI->>TUI: showUsage = true
TUI->>TUI: Launch goroutine
TUI->>Usage: GetGlobalUsage()
Usage->>FS: ReadDir(.claude/projects)
Usage->>FS: FindSessionFiles for each project
Usage->>FS: ParseSessionFile for each session
FS-->>Usage: Token data from all sessions
Usage-->>TUI: GlobalUsage (aggregated)
TUI->>TUI: Set m.globalUsage (race condition)
TUI->>User: Display usage overlay
Note over TUI,Store: Enhanced Thinking Detection
Monitor->>Detector: DetectState(terminal content)
Detector->>Detector: Match thinking patterns
Note over Detector: New patterns: thinking..., thinking…,<br/>reasoning, (esc to cancel),<br/>(ctrl+c to interrupt), thought for Xs
Detector-->>Monitor: StateThinking
Monitor-->>TUI: Session state update
|
| case "u": | ||
| m.showUsage = true | ||
| go func() { | ||
| global, _ := usage.GetGlobalUsage() | ||
| m.globalUsage = global | ||
| }() |
There was a problem hiding this comment.
logic: Race condition: the goroutine updates m.globalUsage without synchronization while the UI reads it in viewUsageOverlay() on line 736-741 of view.go. This can cause data races.
| case "u": | |
| m.showUsage = true | |
| go func() { | |
| global, _ := usage.GetGlobalUsage() | |
| m.globalUsage = global | |
| }() | |
| case "u": | |
| m.showUsage = true | |
| return tea.Cmd(func() tea.Msg { | |
| global, _ := usage.GetGlobalUsage() | |
| return messages.UsageLoaded{Usage: global} | |
| }) |
Prompt To Fix With AI
This is a comment left during a code review.
Path: internal/tui/model.go
Line: 572:577
Comment:
**logic:** Race condition: the goroutine updates `m.globalUsage` without synchronization while the UI reads it in `viewUsageOverlay()` on line 736-741 of view.go. This can cause data races.
```suggestion
case "u":
m.showUsage = true
return tea.Cmd(func() tea.Msg {
global, _ := usage.GetGlobalUsage()
return messages.UsageLoaded{Usage: global}
})
```
How can I resolve this? If you propose a fix, please make it concise.| regexp.MustCompile(`(?i)thinking\.{3}`), | ||
| regexp.MustCompile(`(?i)thinking…`), | ||
| regexp.MustCompile(`(?i)reasoning`), | ||
| regexp.MustCompile(`⠋|⠙|⠹|⠸|⠼|⠴|⠦|⠧|⠇|⠏`), | ||
| regexp.MustCompile(`Working\.\.\.`), | ||
| regexp.MustCompile(`Processing\.\.\.`), | ||
| regexp.MustCompile(`\(esc to cancel\)`), | ||
| regexp.MustCompile(`\(ctrl.* to interrupt\)`), | ||
| regexp.MustCompile(`thought for \d+`), | ||
| regexp.MustCompile(`thinking`), |
There was a problem hiding this comment.
logic: Overly broad pattern: the regexp.MustCompile(\thinking`)` pattern on line 83 will match any text containing "thinking" (e.g., "I'm thinking about the problem" in user input). This is too broad and will cause false positives. The case-insensitive patterns on lines 74-76 already cover thinking states properly.
| regexp.MustCompile(`(?i)thinking\.{3}`), | |
| regexp.MustCompile(`(?i)thinking…`), | |
| regexp.MustCompile(`(?i)reasoning`), | |
| regexp.MustCompile(`⠋|⠙|⠹|⠸|⠼|⠴|⠦|⠧|⠇|⠏`), | |
| regexp.MustCompile(`Working\.\.\.`), | |
| regexp.MustCompile(`Processing\.\.\.`), | |
| regexp.MustCompile(`\(esc to cancel\)`), | |
| regexp.MustCompile(`\(ctrl.* to interrupt\)`), | |
| regexp.MustCompile(`thought for \d+`), | |
| regexp.MustCompile(`thinking`), | |
| thinkingPatterns: []*regexp.Regexp{ | |
| regexp.MustCompile(`(?i)thinking\.{3}`), | |
| regexp.MustCompile(`(?i)thinking…`), | |
| regexp.MustCompile(`(?i)reasoning`), | |
| regexp.MustCompile(`⠋|⠙|⠹|⠸|⠼|⠴|⠦|⠧|⠇|⠏`), | |
| regexp.MustCompile(`Working\.\.\.`), | |
| regexp.MustCompile(`Processing\.\.\.`), | |
| regexp.MustCompile(`\(esc to cancel\)`), | |
| regexp.MustCompile(`\(ctrl.* to interrupt\)`), | |
| regexp.MustCompile(`thought for \d+`), | |
| }, |
Was the standalone "thinking" pattern intentional for matching lowercase thinking states without punctuation?
Prompt To Fix With AI
This is a comment left during a code review.
Path: internal/claude/detector.go
Line: 74:83
Comment:
**logic:** Overly broad pattern: the `regexp.MustCompile(\`thinking\`)` pattern on line 83 will match any text containing "thinking" (e.g., "I'm thinking about the problem" in user input). This is too broad and will cause false positives. The case-insensitive patterns on lines 74-76 already cover thinking states properly.
```suggestion
thinkingPatterns: []*regexp.Regexp{
regexp.MustCompile(`(?i)thinking\.{3}`),
regexp.MustCompile(`(?i)thinking…`),
regexp.MustCompile(`(?i)reasoning`),
regexp.MustCompile(`⠋|⠙|⠹|⠸|⠼|⠴|⠦|⠧|⠇|⠏`),
regexp.MustCompile(`Working\.\.\.`),
regexp.MustCompile(`Processing\.\.\.`),
regexp.MustCompile(`\(esc to cancel\)`),
regexp.MustCompile(`\(ctrl.* to interrupt\)`),
regexp.MustCompile(`thought for \d+`),
},
```
Was the standalone "thinking" pattern intentional for matching lowercase thinking states without punctuation?
How can I resolve this? If you propose a fix, please make it concise.- Send double Enter only for multi-line content (3+ lines) to signal paste completion - Fix mainHeight calculation to prevent UI extending beyond screen - Improve thinking state detection patterns - Add global usage overlay (press 'u') - Persist Claude session ID for usage tracking across restarts
72e445b to
d637996
Compare
Summary
thought for Xs,(esc to cancel),(ctrl+c to interrupt), unicode ellipsis, and lowercase variantsu) showing active sessions and all-time usage across projectsTest plan
make test)make lint)make build)