Skip to content

(state): Drive the single spinner from the conversation head turn #625

Closed

Description

@devsuitup

Draft: D5.

Problem and evidence. Audit §2 R1/R9 describes a continuously spinning OSC title across eight completed head turns; this is audit-only runtime evidence. The mechanism remains: main.js:2507 directly sets _cliBusy from the title and :2536 also sets it from progress; main.js:1852 exposes the same flag to reconciliation (public/session-activity.js:206). public/session-state.js:4 puts busy above agentsBusy, reproduced by an executed combined-state render. transcript-turn.js:31 already recognizes closure with stop reason plus turn_duration and queue checks (:98), but an empty tail returns closed:false (:114), also reproduced. That false is not positive evidence of an open turn.

Expected behavior. Implement the maintainer's one-glyph contract. A live head with positive main-turn evidence displays an animated spinner/Working, including a silent synchronous tool call. A confirmed head at its prompt with known background work displays the same spinner family statically, with prompt/background wording. At the prompt without background work retain the waiting glyph. Attention retains priority in the one slot; liveness and archive semantics remain distinct. Background agents, shells, Monitor, or cron must not animate the head on their own. OSC spinner/progress and job working are coarse in-flight hints, not sufficient turn evidence; OSC idle remains a fast prompt hint reconciled against ordering and newer head evidence.

Use or extend the existing turn reader without weakening trigger/compaction guarantees. Distinguish open, closed, and unknown; filter task notifications, tool results, meta records, sidechains, and command-only output correctly. A new real prompt/assistant turn after a closure reopens it. For unavailable/malformed/truncated evidence, show the established neutral/unknown state rather than manufacturing Working or confirmed prompt status. Verified growth requests classification; it alone cannot prove which thread is in a turn. Remote data unavailable through the existing mirror remains a documented degraded case; no new SSH polling per row. Remove competing 3s/20s agent clocks from authoritative classification.

Acceptance criteria a reviewer can run. Add head-turn fixtures for open prompt → silent synchronous tool → valid closure with one background task → later genuine prompt. Assert animated → animated → static → animated, including a background shell/Monitor/cron with zero agents. Test empty/truncated tail, task notification at rest, queued/dequeued prompts, local commands, manual/automatic compaction, dead parent, stale OSC/progress, and attention during a turn. With #564, old member busy/new head at prompt stays static; reversing the head states animates. DOM/CSS tests assert one .session-icon, no second activity badge, no animation on static mode, and matching accessible text. Run node --test --test-concurrency=1 test/trigger-transcript-fallback.test.js test/session-state.test.js test/local-pty-adapter.test.js test/local-transcript-adapter.test.js test/remote-session-adapter.test.js test/dom-sidebar-icon-slot.test.js after adding focused cases.

Dependencies/order. Wave 3 after D4's background facts and D1. #564 head selection is required for merged rows; #616 owns scan placement. D6 owns title color and unseen state, D7 owns the number.

Out of scope. Replacing the terminal CLI spinner, a second glyph/badge, changing trigger authorization, merging Idle/Stale vocabulary, header/status-bar redesign, or calling every unclosed tail Working.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions