Skip to content

fix(remote): give immediate feedback on Stop and prevent stuck thinki…

MacroscopeApp / Macroscope - UI Consistency failed Aug 29, 2026 in 3m 17s

UI Consistency: 1 issue found

apps/web/src/components/ChatView.tsx — the new isStoppingTurn optimistic state is set (onInterrupt, line 5502) and cleared (effects at lines 2348–2356) but never read by any component. No control renders a stopping affordance, so the Stop button and the timeline working row look unchanged during the relay round trip and the PR's stated feedback fix is not user-visible. Compare isStoppingBackgroundWork, which is rendered as disabled + "Stopping..." on its Button.

Suggested fix: thread the flag to the consuming surface (ComposerPrimaryActions' renderStopGenerationButton, and/or MessagesTimeline's working row label), preserving the existing stop control's hit target, aria-label, focus-visible ring and pointer cursor while adding disabled/aria-busy. A focused test on the new prop's disabled/label transition is warranted because this changes state-dependent behavior.

Details

Note

Your check run agent prompt is: .macroscope/check-run-agents/ui-consistency.md
More information about how Check Run Agents work can be found in our Help Center.

Scope: only apps/web/src/**/*.{ts,tsx,css} files were targeted. The single in-scope changed file is apps/web/src/components/ChatView.tsx; the server/shared terminal-escape changes were read as context only.

Verification performed:

  • git grep isStoppingTurn at the PR head: matches occur solely inside ChatView.tsx (declaration, two reset effects, one setter in onInterrupt); no JSX or prop reads the value.
  • Reviewed ComposerPrimaryActions.tsx (stop control, lines 88–107) and MessagesTimeline.tsx (working row / workingStepLabel, lines 1302–1315): neither receives a stopping prop.
  • Confirmed the analogous, correctly rendered pattern at ChatView.tsx lines 4498–4568.
  • Checked lint/typecheck configuration: no noUnusedLocals and no error-level unused-variable rule, so the dead state will not be caught by CI gates.

No other in-scope findings: no new raw controls recreating ui primitives, no Tailwind/global CSS ownership changes, no theme/variant changes, no scroll or virtualization changes, and no environment-routing changes in the diff.


🔍 Agent activity — 11 tool calls

💭 Looking at ChatView.tsx, I notice the diff adds an isStoppingTurn state along with setIsStoppingTurn calls, but I don't see it actually being used to render anything like a "Stopping..." indicator in the UI. I should check the file to confirm whether that state is wired up anywhere.

1. git_tools — isStoppingTurn

2. git_tools — isStoppingBackgroundWork

💭 I notice isStoppingTurn is set but never read or rendered anywhere in the UI, meaning the PR's claimed fix for the stuck-thinking feedback issue doesn't actually surface anything to the user — it's dead state, and possibly an unused-variable lint issue too. I want to check the stop handler around line 5500 and see where the Stop button actually lives.

3. browse_code — apps/web/src/components/ChatView.tsx

4. git_tools — isWorking(=|}|,)

💭 I realize isStoppingTurn never actually reaches the UI, so I should trace where isWorking gets passed to the composer component to see how the stop button state is wired up.

5. browse_code — apps/web/src/components/ChatView.tsx

💭 I'm looking for where the stop button is rendered in the composer, so I'll search for "onInterrupt" in the codebase.

6. git_tools — onInterrupt

7. git_tools — workingStepLabel

💭 I want to check ComposerPrimaryActions to see if the stop button actually reads isStoppingTurn for its state. It looks like isStoppingTurn is never actually read anywhere, meaning the PR's claimed fix of giving immediate feedback on Stop doesn't produce any visible change, and this unused variable could also trip up lint or typecheck if noUnusedLocals is enabled—worth checking tsconfig. I should also look at workingStepLabel near line 2312, since that might be where "Stopping…" was intended to display.

8. browse_code — apps/web/src/components/chat/ComposerPrimaryActions.tsx

9. browse_code — apps/web/src/components/ChatView.tsx

💭 I've confirmed that isStoppingTurn is dead state — the stop button never shows a disabled or stopping visual, and the "Thinking..." timeline row is unaffected, so the PR's stated purpose of adding user feedback isn't actually implemented, plus there's a risk of unused-variable lint warnings. Now I want to check whether the lint config actually flags unused variables.

10. browse_code — Does the repo's TypeScript config enable noUnusedLocals, and does the ESLint config error on unused variables (e.g. @typescript-eslint/no-unused-vars) for apps/web? Quote the relevant config lines.

💭 No lint failure occurs, but the finding still holds: the stopping state has no visible UI effect, so the fix doesn't actually deliver feedback to the user. That's a real behavior gap in ChatView.tsx — the smallest correct fix would thread the stopping state through to the composer's stop button and working-row label, but since that touches ComposerPrimaryActions across files, an inline diff isn't practical here. I also note there's no timeout if the remote session never resolves the stop, so "Stopping..." could persist indefinitely — similar to the existing isStoppingBackgroundWork pattern, so not a new issue. The MessagesTimeline row that shows "Thinking..." could ideally reflect isStoppingTurn too, but that's a secondary concern next to the main dead-state finding. I'll post an inline comment on the useState declaration block and treat this as a failing finding since the feedback claim isn't actually satisfied.

11. modify_pr — One finding: the new optimistic stopping state in ChatView.tsx is never rendered, so the Stop button still gives no feedback on remote.


Agent Credits: 89 credits

Token usage: 32 uncached input · 332,577 cache-read input · 68,115 cache-write input · 9,991 output
Agent Credits may also include non-token charges from external tools such as web research.