Skip to content

Add Codex Desktop app monitoring support#116

Open
crosswyb wants to merge 2 commits into
graykode:mainfrom
crosswyb:feature/codex-desktop-monitoring
Open

Add Codex Desktop app monitoring support#116
crosswyb wants to merge 2 commits into
graykode:mainfrom
crosswyb:feature/codex-desktop-monitoring

Conversation

@crosswyb
Copy link
Copy Markdown

Summary

Adds a new CodexDesktopCollector that monitors Codex Desktop app sessions by reading token usage data from ~/.codex/logs_2.sqlite. This is complementary to the existing CodexCollector which only covers Codex CLI.

How it works

  • Detects the Codex Desktop process (Codex.app/Contents/MacOS/Codex) via ps
  • Reads ~/.codex/logs_2.sqlite using the sqlite3 CLI (no new Rust dependencies)
  • Parses structured log entries containing input_token_count, output_token_count, cached_token_count per conversation
  • Groups by conversation.id to form per-session views
  • Registered as "codex-desktop" agent in MultiCollector, respects hidden_agents config
  • Sessions auto-mark as Done when the desktop app process exits

Design decisions

  • No new dependencies — uses std::process::Command to call sqlite3 CLI with -json output, consistent with existing patterns (lsof, ps, git)
  • Separate collector — not merged into existing CodexCollector because the data source (SQLite vs JSONL) and discovery strategy (process name vs codex binary) are fundamentally different
  • High-water mark — tracks last_ts to only re-read new log entries each tick

Limitations

  • No cwd/project_name/chat_messages/tool_calls (SQLite logs don't expose these at the same granularity as JSONL)
  • Context window percentage is estimated (no per-turn breakdown in aggregated SQLite data)
  • Requires sqlite3 CLI to be installed (pre-installed on macOS, available everywhere)

Testing

  • 3 new unit tests for field extraction logic
  • All 139 existing tests pass (updated with_hidden test assertions for the new 4th collector)

Closes: N/A — feature request from user who needed desktop app monitoring alongside CLI support

crosswyb added 2 commits May 10, 2026 21:28
Add a new collector (codex_desktop.rs) that monitors Codex Desktop app
sessions by reading token usage data from ~/.codex/logs_2.sqlite, in
addition to the existing Codex CLI JSONL-based collector.

- Reads per-conversation input/output/cached token counts from SQLite
- Detects Codex Desktop process via ps (Codex.app)
- Registers as 'codex-desktop' agent in MultiCollector
- Supports hide/show via hidden_agents config
- All 139 existing tests pass

Constraint: sqlite3 CLI must be available at runtime
Scope-risk: narrow - new file, no changes to existing collectors
- Now tracks event lifecycle (response.created → response.in_progress
  → response.completed) to show Thinking/Executing/Waiting status
- Replaced historical-only SQLite polling with recent-events query
- Shows placeholder session when desktop app is running but idle
- 141 tests pass (was 139, added 2 new event kind tests)
@graykode
Copy link
Copy Markdown
Owner

Thanks for adding Codex Desktop support. The feature direction makes sense for abtop, but I don't think this implementation is safe to merge yet.

Main blockers:

  • src/collector/codex_desktop.rs:97 treats logs.ts as milliseconds, but the Codex Desktop DB stores epoch seconds plus ts_nanos. With real DB rows this can make sessions fail the active-window check, and the same unit mismatch affects started_at values later in the file.
  • src/collector/codex_desktop.rs:265-345 rereads the latest 500 rows on every collect pass and adds token counts again each time. last_ts is updated but not used as a cursor. This will inflate token totals on every refresh. Rows are also processed newest-to-oldest, so an older event can overwrite last_event_kind after a newer event.
  • src/collector/codex_desktop.rs:310-318 skips tool-related events before they can drive SessionStatus::Executing, because conversation.id is only extracted for completed/failed/created/in_progress events.
  • src/collector/codex_desktop.rs:140-149 calculates context_percent by subtracting other conversations' total input from the current conversation. A conversation's context should not depend on unrelated sessions; this should use the latest per-conversation context/input value instead.

Verification:

  • cargo test passes locally: 141 tests.
  • cargo clippy -- -D warnings fails on this branch with derivable_impls, unnecessary_cast, and useless_format in src/collector/codex_desktop.rs.

Suggested direction: use a stable processed-row cursor such as (ts, ts_nanos, id), process rows in ascending order, avoid re-adding already-processed token events, and store latest per-conversation context/input separately from lifetime token totals.

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.

2 participants