Skip to content

Commit 983569f

Browse files
authored
fix: use recency heuristic for pending tool_use and show "Now" for active sessions (#16)
When a tool_use has no matching tool_result, use a 2-minute recency threshold to distinguish between tools currently executing (Working) and tools genuinely waiting for user approval (Needs Input). Also display "Now" instead of elapsed time for Working sessions in both the terminal UI and web dashboard. Fixes #14
1 parent 2ffe05a commit 983569f

File tree

3 files changed

+13
-4
lines changed

3 files changed

+13
-4
lines changed

internal/session/session.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -741,8 +741,14 @@ func determineStatus(entries []LogEntry, isRunning bool) (Status, string, bool)
741741
}
742742
}
743743

744-
// If there's a pending tool_use, session is waiting for input (not ghost/idle)
744+
// If there's a pending tool_use, check recency to decide status.
745+
// Many tools (Task, Read, Grep, Write, Edit, etc.) are auto-approved and
746+
// execute without user interaction. A recent pending tool_use likely means
747+
// the tool is currently executing, not waiting for approval.
745748
if hasPendingToolUse {
749+
if lastAssistant != nil && time.Since(lastAssistant.Timestamp) < 2*time.Minute {
750+
return StatusWorking, "Using: " + pendingToolName, false
751+
}
746752
return StatusNeedsInput, "Using: " + pendingToolName, false
747753
}
748754

internal/ui/ui.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,13 +314,16 @@ func formatContext(s session.Session, width int) string {
314314
// The main row shows status, project, context, and activity.
315315
// A second indented line shows the last message using the full width.
316316
func renderSessionRow(s session.Session, l sessionLayout, nl string) {
317-
elapsed := formatElapsed(time.Since(s.LastActivity))
317+
activity := formatElapsed(time.Since(s.LastActivity))
318+
if s.Status == session.StatusWorking {
319+
activity = "Now"
320+
}
318321

319322
row := fmt.Sprintf("%s %s %s %-*s",
320323
formatStatus(s.Status, l.status),
321324
formatProject(s, l.project),
322325
formatContext(s, l.context),
323-
l.activity, elapsed)
326+
l.activity, activity)
324327
fmt.Print(row + nl)
325328

326329
// Second line: last message aligned with status text (after "● ")

internal/web/static/app.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@
9090
sessionsList.innerHTML = currentSessions.map(s => {
9191
const cls = statusClass(s.status);
9292
const symbol = statusSymbol(s.status);
93-
const age = formatAge(s.last_activity);
93+
const age = s.status === 'Working' ? 'Now' : formatAge(s.last_activity);
9494
const pct = s.context_percent || 0;
9595
const ctxCls = pct > 90 ? 'high' : pct > 75 ? 'medium' : 'low';
9696

0 commit comments

Comments
 (0)