Skip to content

feat: show the working indicator in ChatPane (member DMs, split panes) - #7731

Merged
iamwhatever merged 1 commit into
mainfrom
feat/chatpane-ghost-loader
Sep 2, 2026
Merged

feat: show the working indicator in ChatPane (member DMs, split panes)#7731
iamwhatever merged 1 commit into
mainfrom
feat/chatpane-ghost-loader

Conversation

@CrysisDeu

@CrysisDeu CrysisDeu commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Problem / Motivation

A running turn inside a ChatPane host — a Crew Members DM thread, a split pane in the session grid — is invisible between tool steps. The pane renders streamed text and tool rows, but during the gaps (thinking, tool execution, post-tool pauses) nothing on screen moves: a hard-working member looks stalled, and users cannot tell "working" from "dead".

Why it matters

The Crew Members page is the accountability surface for autonomous member activity; "is it doing anything right now" is the page's core question. The full chat page already answers it with the ghost-pose loading carousel — panes answering it with silence is an inconsistency users notice immediately after meeting the animation on the main page.

What changed (motivation → approach → change)

Goal: the same working signal in panes as on the chat page — without inventing a second visual vocabulary.

Approach: reuse, don't rebuild. ChatFooter (the 4-slot ghost-pose carousel, theme-swappable via themeBranding loader/loaderIcons) is self-contained and driven entirely by props, so ChatPane can host it directly.

  • ChatPane.tsx: render ChatFooter inside the scroll container after the last message, fed from the pane's own per-slot stream state (selectSlotStreamState) — running shows the carousel, stopping/compacting show their existing states, active text streaming yields to the inline caret (ChatFooter's own algebra), idle renders nothing. Stop/regenerate chrome stays page-level.
  • No new state, no backend, no new i18n strings; theme loader overrides now apply in panes for free.
  • New isolated capture entry capture/chatpane-loader.html + capture/chatpane-loader.tsx (real ChatPane, warm-slot seeding through the same sseChatMessage/hydrateSlotMessages reducers the WS drives) and a state-asserted capture script scripts/capture-chatpane-loader.mjs.

Tests

ChatPane.workingLoader.test.tsx pins the wiring (ChatFooter's own suite covers its visibility algebra):

  • tool_running → footer + carousel render in the pane
  • idle → no footer at all
  • active text streaming (fresh tick) → footer absent, the inline caret owns the signal

Manual verification

working indicator in a member DM pane

recorded from b824395 · feat/chatpane-ghost-loader · vite dev serving branch source, isolated capture entry capture/chatpane-loader.html with route-stubbed /api fixtures, state asserted before every frame · no live gateway

Stills: 01-running-dark · 02-idle-dark · 03-running-light

Gates: tsc -b clean, eslint clean, full frontend suite 27431 passed, full 19-check i18n suite PASS.

no linked issue: gap identified during the Crew Members animation design review with the maintainer in-session; no tracking issue exists.

@CrysisDeu
CrysisDeu requested a review from a team September 1, 2026 21:29
@CrysisDeu
CrysisDeu requested a review from a team as a code owner September 1, 2026 21:29
@github-actions github-actions Bot added the readiness: checking Automated validation is still running label Sep 1, 2026
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

First Principles Review (Fable 5) — ✅ PASS

Premise-level review of b824395ae67744d08e0ac38266749e46a9f86d71 — why this exists and whether the shipped surface is the smallest honest version. Updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

All evidence is in. Both sibling transcript hosts carry their own signal (SideChat has three pulsing dots at SideChat.tsx:591-593; ChatEmbed keeps a header dot + "streaming" label), the capture apparatus follows a 372-script convention, and the ChatPane diff adds no new state or props — ChatFooter simply gains its second real consumer.

First-Principles-Verdict: PASS

Reuse at cause level: the pane hosts the page's existing ChatFooter unchanged, and every rider is the repo's established capture/test convention.

What this change ships

Intent: make a running turn visible inside ChatPane hosts (member DMs, split panes) between tool steps — an ADDITION.

  1. Panes show the ghost-pose working carousel while a turn runs — justified
  2. Panes show the existing stopping/compacting states — declared, inherent to the reused algebra
  3. Theme loader/loaderIcons overrides now apply in panes — declared, free via reuse
  4. Indicator also covers the pre-stream gap (paneSlot.running union) — declared in tests, same union the full page uses
  5. New capture entry + state-asserted capture script — declared, matches 157 capture-entry / 372 capture-script siblings
  6. Three stills + GIF committed under temp-screenshots/ — declared, matches the 569-file convention
  7. New wiring test file — declared

No duplication: grep <ChatFooter finds exactly two production consumers (ChatPage.tsx:7997, ChatPane.tsx:724) of one component; no props were added to it, and the pane's inputs (streamState, running, paneSlot) all pre-existed. Grep <ChatMessageList finds three production hosts: SideChat already has its own dot indicator, leaving only app-sdk/ChatEmbed.tsx:257 with header-chrome-only signaling — outside the declared job (an app-embed surface, not the Crew Members accountability page), so not a point patch. The "nothing on screen moves" framing slightly overstates the framed-pane case (the header dot at ChatPane.tsx:655 pulses), but the in-flow gap the feature fills is real and the frameless member-DM host shows no header at all.

[FIRST-PRINCIPLES-REVIEWED] b824395

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Design Review (Fable 5) — ✅ PASS

Design-level review of b824395ae67744d08e0ac38266749e46a9f86d71 — updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

Design-Verdict: PASS

Straight reuse of the page's existing loader through its prop seam, fed by the pane's own slot state — the right shape, minimal surface.

Suggestions

  • The footer-input derivation (lastRole / content-length-as-streamTick) is now duplicated verbatim between ChatPage.tsx:5826 and ChatPane.tsx:728-733; a shared selector/helper would keep the two hosts from drifting when the streaming-quiet heuristic next changes.

[DESIGN-REVIEWED] b824395

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

UX Review (Fable 5) — ✅ PASS

UX-level review of b824395ae67744d08e0ac38266749e46a9f86d71 — updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

The diff is a small parity change: ChatPane (member DMs, split panes) now renders the same ChatFooter working indicator the full chat page already uses, with per-slot stream state driving it. Screenshots confirm the carousel renders correctly in dark and light, a stop affordance (red square) is present in the composer while running, and the idle state shows no residue. No new user-facing strings; existing i18n'd states ("Stopping…", "Compacting…") are wired through. ChatMessageList adds no competing indicator, and the footer already suppresses itself while text actively streams, so there is no double-cursor risk. Placement matches the chat page (inside the scroller, after the last message).

UX-Verdict: PASS

Straight parity port of the existing working indicator to panes — same component, same placement, per-slot state wired correctly, both themes verified.

[UX-REVIEWED] b824395

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Opus 4.8 Review — ✅ no blocking findings

Reviewed b824395ae67744d08e0ac38266749e46a9f86d71 — this comment is updated in place on each push.

Review details

No findings.

[OPUS-REVIEWED] b824395

Verdict parsed from the review's SHA-scoped output markers for commit b824395ae67744d08e0ac38266749e46a9f86d71.

False positive or not applicable? A repository writer can comment:
/ai-review override fable b824395ae67744d08e0ac38266749e46a9f86d71: <one-sentence reason>

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

GPT 5.6 Review — ✅ no blocking findings

GPT 5.6 completed its review of b824395ae67744d08e0ac38266749e46a9f86d71 and found no blocking issues.

This comment is updated in place on each push.

Review details

No findings.
[GPT-REVIEWED] b824395

False positive or not applicable? A repository writer can comment:
/ai-review override gpt b824395ae67744d08e0ac38266749e46a9f86d71: <one-sentence reason>

@github-actions github-actions Bot added merge conflict Branch has merge conflicts with its base — author must resolve before merge readiness: action required A blocking check or review needs attention and removed readiness: checking Automated validation is still running labels Sep 1, 2026
@CrysisDeu
CrysisDeu force-pushed the feat/chatpane-ghost-loader branch from f15ebe3 to 5c463d8 Compare September 1, 2026 23:14
@github-actions github-actions Bot added readiness: checking Automated validation is still running readiness: action required A blocking check or review needs attention and removed merge conflict Branch has merge conflicts with its base — author must resolve before merge readiness: action required A blocking check or review needs attention readiness: checking Automated validation is still running labels Sep 1, 2026
A running turn in a ChatPane host — a Crew Members DM thread, a split
pane — was invisible between tool steps: the pane renders streamed text
and tool rows but nothing during the gaps, so a working member looked
stalled. The full chat page already solves this with ChatFooter's
ghost-pose carousel (theme-swappable via themeBranding loader /
loaderIcons).

Host that same footer in ChatPane, inside the scroll container after the
last message, driven by the pane's own per-slot stream state
(selectSlotStreamState): running shows the carousel, active text
streaming yields to the inline caret, idle renders nothing. No new
visual vocabulary, no new state, and themes' loader overrides apply in
panes for free.

Adds an isolated capture entry (capture/chatpane-loader.html) seeding
the warm-slot path through the same reducers the WS drives, plus a
state-asserted capture script and committed evidence.
@CrysisDeu
CrysisDeu force-pushed the feat/chatpane-ghost-loader branch from 5c463d8 to b824395 Compare September 2, 2026 00:12
@CrysisDeu

Copy link
Copy Markdown
Collaborator Author

Disposition — GPT advisory finding (ChatPane.tsx:725, head 5c463d8): FIXED in b824395. The pane's footer now unions the stream-state signal with the slots-broadcast one — running={running || !!paneSlot?.running}, stopping likewise — matching what the full page gets from startLocalTurn + syncSlotRunningFromServer: the indicator shows in the pre-first-frame window after a send (and for Slack/cron-initiated turns), and a server-reported stopping is not missed. Pinned by a new test case (server running=true, stream still idle → footer renders).

@github-actions github-actions Bot added readiness: checking Automated validation is still running readiness: passed Eligible automated validation passed for the current revision and removed readiness: action required A blocking check or review needs attention readiness: checking Automated validation is still running labels Sep 2, 2026
@iamwhatever
iamwhatever merged commit 31bcdd3 into main Sep 2, 2026
69 checks passed
@iamwhatever
iamwhatever deleted the feat/chatpane-ghost-loader branch September 2, 2026 01:16
@github-actions github-actions Bot removed the readiness: passed Eligible automated validation passed for the current revision label Sep 2, 2026
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.

3 participants