Repository navigation
test(studio): keep the chat status pulses as status dots, not Skeletons - #2358
Merged
Merged
Conversation
#2337 reviewed every animate-pulse in delegation-card, fleet-status-chip and session-details-dialog. All three are status dots for running work, not loading placeholders, so none becomes a Skeleton. Pin that: each pulse shows only while running, stays aria-hidden with the state spoken as text, and is not the Skeleton primitive. Also pin the details view's real loading state, a spinner beside "Loading details…" in a status region. Refs #2337 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
kantord
approved these changes
Oct 15, 2026
kantord
left a comment
Member
There was a problem hiding this comment.
Thanks for this, recording why these three dots stay dots is useful, and the decision table is clear. Approving, with a few non-blocking nits:
- This is 188 lines of tests for no code change, so it is worth asking whether a code comment or the decision table alone would carry the decision more cheaply.
- Only the
[data-slot="skeleton"]absence check guards against a Skeleton swap. The.animate-pulsecount would still pass, since Skeleton also pulses, and therounded-fullandbg-brandchecks pin styling rather than the decision. - It covers 3 of the
animate-pulsesites, so other pulse sites remain unpinned.
Fully or partially written by an AI agent.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
#2337 asks for the Skeleton primitive (
components/ui/skeleton.tsx) whereveranimate-pulsemarks content that is still loading. This PR reviews the three call sites that no other open PR touches. None of them is a loading placeholder. Each is a status dot that pulses while something runs, so no code changes. The PR records that decision and adds tests that pin it, so a later sweep can't turn these dots into Skeletons by mistake.Part of #2337
Part of #2201
Part of #2210
Decisions
features/chat/delegation-card.tsx:54StateGlyph:size-2 animate-pulse rounded-full bg-brandfeatures/chat/fleet-status-chip.tsx:132size-1.5 animate-pulse rounded-full bg-brandin a chip segmentsegment.running).features/chat/session-details-dialog.tsx:43STATE_DOT.running:bg-brand animate-pulseEach dot is decorative (
aria-hidden). The state is spoken as text beside it ("Running", the segment'saria-label, or "running"), and the dot disappears once the work settles. The prototype (stack-08) shows the same pulsing dots on all three surfaces; see the Prototype column below.The details view's real loading state ("Loading details…") is a spinner (
Loader2 animate-spin) in arole="status"paragraph, not ananimate-pulseplaceholder, so #2337 doesn't cover it. It stays unchanged, and is pinned too.Later: these files from the issue are in open PRs. Each one gets its decision once that PR lands:
features/chat/chat-composer.tsxfeatures/chat/delegation-panel.tsxfeatures/chat/reasoning-disclosure.tsxfeatures/chat/tool-call-list.tsxWhat changed
features/chat/status-pulse.pinning.test.tsx(new, 4 tests), against the unchanged code:aria-hidden, and "Running" sits in the card's live region;data-running), and keeps its accessible name (Subagents · 1 running · 1 done) inside theAgents in this chatlist;runningonly;idle,completed,failed,awaitingandcancelleddon't pulse;role="status"with "Loading details…" and anaria-hiddenspinner; it has no pulse, no Skeleton, and no detail list.Every pulse check also asserts that the dot isn't the Skeleton primitive (
[data-slot="skeleton"]).No production file changes.
No regression
Mutation proof. I applied each mutation alone, reran the pin file, and reverted it. Each one fails exactly one test:
data-slot="skeleton")aria-hiddencompleteddot pulses tooanimate-pulseGates (through the shared lock):
task studio:check:knowledge.test.ts› "declares the transport errors…" (expected 15, got 16). It already fails onmain(4aa238f3c, the CI run for that commit) because feat(studio): show a skill's files on its page #2155 and fix(studio): declare 400 and 429 on the knowledge routes #2313 collided. fix(studio): declare 400 and 429 on the skill files route, and stop hard-coding the route count #2355 has since fixed it onmain, and the CI Studio job for this PR passes. This PR doesn't touchapps/server.task studio:browser: 132 passed, 38 skipped.Screenshots
Before is
origin/main(4aa238f3c), After is this branch (d49cc4714), and Prototype isstack-08. Every capture is pixel-identical to Before, and a second Before capture also matched (noise 0);pixel-report.txtin the asset folder has the counts. There are no red boxes, because nothing changed. Amber boxes mark the reviewed status dots instead. A separate capture pass hid only those dots and diffed the result to find them.After matches the prototype: the prototype shows the same pulsing brand dots for running delegations, the fleet chip, and the running session state. The other differences in the Prototype column are layout and copy (for example, "Running" capitalised in its details dialog). This PR doesn't cover them.
Running delegation and fleet chip, desktop, light. The boxes are the fleet chip's Parallel segment dot and the dots of the running parallel group and branches 2 and 3. Branches 2 and 3 merge into one box.
Session details for a running session, desktop, light. The box beside "running" is the state dot. The dimmed chat behind the dialog shows the same delegation dots.
Desktop dark and 390px, light and dark
Running delegation, desktop, dark:
Running delegation, 390px, light. The chat hides the fleet chip in a narrow header, so only the card dots are boxed:
Running delegation, 390px, dark:
Session details, desktop, dark:
Session details, 390px, light:
Session details, 390px, dark:
🤖 Generated with Claude Code