Skip to content

Comments

fix: return ActivityDetection from getActivityState to fix stale lastActivityAt#112

Open
AgentWrapper wants to merge 7 commits intomainfrom
session/ao-53
Open

fix: return ActivityDetection from getActivityState to fix stale lastActivityAt#112
AgentWrapper wants to merge 7 commits intomainfrom
session/ao-53

Conversation

@AgentWrapper
Copy link
Collaborator

@AgentWrapper AgentWrapper commented Feb 18, 2026

Summary

  • Dashboard showed "Active 2h ago" even when agents were active minutes ago because lastActivityAt was sourced from the metadata file's mtime (only updates on PR creation, status changes), not during agent work
  • getActivityState() now returns ActivityDetection { state, timestamp? } instead of a bare ActivityState string — the timestamp comes from data the plugin already had (JSONL file mtime), requiring zero additional I/O
  • enrichSessionWithRuntimeState() uses detected.timestamp to update lastActivityAt, eliminating the separate getSessionInfo() call that was previously added for this purpose

Changes

  • packages/core/src/types.ts — new ActivityDetection interface, updated Agent.getActivityState return type
  • packages/core/src/session-manager.ts — use detected.state + detected.timestamp from activity detection
  • 4 agent plugins (claude-code, aider, codex, opencode) — return { state, timestamp } objects
  • Tests — all activity-detection, session-manager, lifecycle-manager, status, and integration tests updated

Test plan

  • New test: updates lastActivityAt from ActivityDetection timestamp — verifies JSONL mtime overwrites stale metadata mtime
  • New test: keeps metadata lastActivityAt when ActivityDetection has no timestamp — verifies we never regress
  • All 54 session-manager tests pass
  • All 42 activity-detection tests pass (updated assertions for ActivityDetection shape)
  • Full test suite passes (all 21 packages)
  • Typecheck and lint clean

🤖 Generated with Claude Code

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.

@AgentWrapper AgentWrapper changed the title fix: update lastActivityAt from agent JSONL instead of stale metadata mtime fix: return ActivityDetection from getActivityState to fix stale lastActivityAt Feb 18, 2026
AgentWrapper and others added 7 commits February 19, 2026 07:27
…adata mtime

The dashboard showed "Active 2h ago" even when agents were active minutes ago
because lastActivityAt was sourced from the metadata file's mtime, which only
changes on metadata writes (PR creation, status updates), not during agent work.

Now enrichSessionWithRuntimeState() calls getSessionInfo() to read the agent's
JSONL session file mtime, updating lastActivityAt with the actual last activity
timestamp. Also enriches agentInfo with live summary/cost/sessionId data.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use 2099-01-01 instead of a near-future date so the test doesn't break
when wall-clock time passes the hardcoded date.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…are string

getActivityState() now returns { state, timestamp } instead of a bare
ActivityState string. The timestamp comes from data the plugin already
had (JSONL file mtime), eliminating the separate getSessionInfo() call
that was used solely to update lastActivityAt.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove AgentSessionInfo.lastLogModified and lastMessageType fields
  (timestamp now comes from ActivityDetection, these were dead weight
  adding a wasted stat() call per session per poll cycle)
- Add missing unit test: older ActivityDetection timestamp should not
  regress lastActivityAt
- Add timestamp assertions to integration tests (claude-code, aider)
  to verify real implementations provide timestamps that feed
  lastActivityAt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…egration tests

Move ~200 lines of duplicated tmux TTY + PID process detection logic
from 4 agent plugins into a single isAgentProcessRunning() utility in
ao-core. Integration tests now fail explicitly when polling doesn't
capture observations instead of silently passing via if-guards.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
16 tests covering the tmux TTY + ps parsing path (match on TTY, no match,
empty TTY, bare command, path prefix, substring rejection, regex escaping,
multiple panes, tmux failure) and PID-based fallback (alive, dead, zero,
negative, NaN, string coercion) plus edge cases (no id, no pid, empty
tmux id).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Mocks process.kill to verify the EPERM branch (process exists but
no permission to signal → returns true) and ESRCH branch (no such
process → returns false). These were the last untested branches in
isAgentProcessRunning.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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