Menu

#345 fix(etl): suppress VS Code frames when focused terminal is a coding agent

closed
nobody
None
2026-06-26
2026-06-26
Anonymous
No

Originally created by: adityaharishch

Summary

  • Adds is_coding_agent_terminal() to src/etl/session_builder.rs — detects when the focused VS Code terminal tab is running a coding agent (Claude Code, Codex, Cursor agent, Copilot CLI, Gemini, Aider, Amazon Q)
  • Adds a skip guard in src/etl/runner.rs so those frames are not converted into app_sessions rows — the coding-agent indexer already tracks these sessions, and double-capture was inflating "Code" focus time on the timeline
  • Updates dev-start.sh so cargo-watch also watches the local screenpipe-fork directory

Detection strategy

Pattern Example
Claude Code spinner (OSC title) Terminal - ⠂ agentic-worklog-pipeline
Version-number label (idle/startup) Terminal - 2.1.193, Terminal - 0.139.0
Process name contains-check Terminal - codex-aarch64-ap, Terminal - cursor-agent
Amazon Q exact-word Terminal - q (avoids qemu, queue-worker false positives)

Verified

capture_frames still receives all raw frames (written by the tray — unchanged). The filter only affects app_sessions. Confirmed no new spinner/version-label sessions are written to app_sessions with dev daemon running.

Test plan

  • [ ] cargo test passes (unit tests in session_builder.rs cover all 5 detection paths)
  • [ ] After merge: verify app_sessions no longer contains "Code" sessions with spinner window titles while Claude Code is running in an integrated terminal

Related

Tickets: #351

Discussion

  • Anonymous

    Anonymous - 2026-06-26

    Originally posted by: coderabbitai[bot]

    [!IMPORTANT]

    Review skipped

    Auto reviews are disabled on base/target branches other than the default branch.

    Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.


    ⚙️ Run configuration

    Configuration used: Organization UI

    Review profile: ASSERTIVE

    Plan: Pro Plus

    Run ID: 576be105-785b-401c-839e-81fae4b8e474

    You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

    Use the checkbox below for a quick retry:
    - [ ] 🔍 Trigger review

    ✨ Finishing Touches
    🧪 Generate unit tests (beta) - [ ] Create PR with unit tests - [ ] Commit unit tests in branch `fix/no-capture-coding-agent-terminals`

    Comment @coderabbitai help to get the list of available commands.

     
  • Anonymous

    Anonymous - 2026-06-26

    Originally posted by: adityaharishch

    Thanks for the thorough review. All findings addressed in commit a2c20411:

    🔴 [#1] (critical — spurious gap): Fixed — block_last_ts/block_last_frame_id now advance on every skipped coding-agent frame, mirroring the empty-app skip pattern. Integration test coding_agent_skip_does_not_produce_spurious_gap covers this: editor → 330 s of coding-agent frames → editor asserts 0 gap rows.

    🔴 [#2] (unanchored contains): Fixed — replaced .contains(name) with first_word.starts_with(name) anchored to the first space-delimited token. "decodex-runner" no longer matches "codex", "gitclaude" no longer matches "claude". Architecture-suffixed binaries (codex-aarch64-ap) still match via starts_with("codex").

    🔴 [#3] (is_version_label too broad): Fixed — removed is_version_label entirely. It suppressed any Terminal - N.N.N tab including Node REPL (20.11.0) and Python (3.11.5) sessions. The reviewer is right that the spinner check already covers the Claude Code active case, and Claude Code idle/startup is an acceptable miss.

    🟡 [#4] (browser_url shadows window_name): Fixed — the suppression check now always uses frame.window_name directly (raw_window) instead of the url_domain-resolved window.

    🟡 [#5] (em-dash separator): Fixed — is_coding_agent_terminal now tries both "Terminal - " (ASCII) and "Terminal — " (U+2014).

    🟡 [#7] (hardcoded personal path): Fixed — dev-start.sh now reads SCREENPIPE_FORK_PATH env var and omits the --watch flag when it's not set.

    🟡 [#8] (integration test): Added tests/etl_coding_agent_skip.rs with 3 tests: no spurious gap, editor frames not suppressed, coding-agent frames excluded from frame_count.

    🟢 [#9] (Vec allocation): Eliminated by removing is_version_label.

    🟢 [#10] (dead "q" in array): Removed — "q" is now only in the first_word == "q" exact-match path.


    🟡 [#6] (design — authoritative DB query): Not addressed in this PR. The reviewer's point is valid architecturally, but querying app_sessions WHERE task_method = 'coding_agent_live' wouldn't work at ETL time — the indexer seals rows up to 1 h after the session ends (idle-seal backstop), so in-progress coding-agent sessions have no DB row yet when the ETL runs. The heuristic approach is the only option that works in real-time. Happy to add a code comment explaining this constraint if useful.

     

    Related

    Tickets: #1
    Tickets: #10
    Tickets: #2
    Tickets: #3
    Tickets: #4
    Tickets: #5
    Tickets: #6
    Tickets: #7
    Tickets: #8
    Tickets: #9

  • Anonymous

    Anonymous - 2026-06-26

    Ticket changed by: adityaharishch

    • status: open --> closed
     

Log in to post a comment.