feat: improve horizontal overflow cues and off-screen task attention#52
feat: improve horizontal overflow cues and off-screen task attention#52ASRagab wants to merge 7 commits intojohannesjo:mainfrom
Conversation
|
Hey hey! Thank you very much! I'm on a short break since we just got a baby, but I'll review this ASAP once I'm back |
There was a problem hiding this comment.
Pull request overview
This PR improves usability when many task slices are open side-by-side by adding horizontal overflow cues, tracking runtime-only per-task viewport visibility, and introducing a richer “attention” model (active/needs input/error/ready) that can surface in the sidebar, edge cues, and desktop notifications.
Changes:
- Added left/right overflow affordances to the tiling strip and runtime-only per-task viewport visibility tracking.
- Introduced additive task “attention” state derived from agent output/question detection, and surfaced it in the sidebar/status dot + desktop notifications.
- Increased xterm scrollback (centralized constant) for better agent review/debugging.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/styles.css | Adds styling for sidebar offscreen attention badges and tiling overflow/attention edge cues. |
| src/store/ui.ts | Adds getters/setters for runtime-only task viewport visibility state in the store. |
| src/store/types.ts | Introduces TaskViewportVisibility type and stores it in AppStore. |
| src/store/taskStatus.ts | Adds TaskAttentionState, background-output analysis scheduling, and derived attention helpers. |
| src/store/taskStatus.test.ts | Adds coverage for new attention state behavior and background prompt edge cases. |
| src/store/store.ts | Re-exports attention and viewport visibility APIs/types from the store barrel. |
| src/store/desktopNotifications.ts | Switches desktop notifications to attention-based transitions (ready/needs_input/error). |
| src/store/core.ts | Initializes taskViewportVisibility and narrows cleanupPanelEntries input type. |
| src/remote/AgentDetail.tsx | Uses centralized scrollback constant for remote agent terminal. |
| src/lib/terminalConstants.ts | Adds shared TERMINAL_SCROLLBACK_LINES = 10_000 constant. |
| src/components/TilingLayout.tsx | Implements overflow cues, viewport visibility publishing, and offscreen attention direction detection. |
| src/components/TerminalView.tsx | Uses centralized scrollback constant for main terminal. |
| src/components/StatusDot.tsx | Extends dot rendering to reflect attention state (color + optional glow/pulse). |
| src/components/Sidebar.tsx | Surfaces offscreen attention (badge + row emphasis) and passes attention into StatusDot. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Coalesce scroll handler with requestAnimationFrame to avoid synchronous layout reads (getBoundingClientRect) on every scroll event - Drop subtree:true from MutationObserver so internal panel renders don't trigger expensive disconnect/reconnect cycles (panel add/remove is already covered by the taskOrder createEffect + ResizeObserver) - Compute getTaskAttentionState once in getOffscreenAttentionInfo instead of calling both taskNeedsAttention and getTaskAttentionState (taskNeedsAttention internally calls getTaskAttentionState, so the attention state was derived twice per invocation)
|
Addressed the 3 review comments from Copilot in 1. MutationObserver 2. Scroll handler rAF coalescing ( 3. Deduplicate attention state computation ( All changes verified: |
|
Thank you very much! <3 |
|
Good work overall — the three Copilot comments (MutationObserver subtree, scroll rAF coalescing, attention deduplication) were addressed cleanly. One new issue I noticed: Desktop notification re-firing when state persists ( The } else if (current === 'needs_input') {
scheduleBatch('needs_input', taskId);
} else if (current === 'error') {
scheduleBatch('error', taskId);
}The original Suggested fix — mirror the } else if (current === 'needs_input' && prev !== 'needs_input') {
scheduleBatch('needs_input', taskId);
} else if (current === 'error' && prev !== 'error') {
scheduleBatch('error', taskId);
}Everything else looks solid: the rAF guard on scroll is correctly implemented and cleaned up (removeEventListener prevents new events; the existing |
johannesjo
left a comment
There was a problem hiding this comment.
The three original Copilot review comments were all correctly addressed. One remaining issue before merge:
Notification spam — the createEffect in desktopNotifications.ts that fires needs_input/error notifications is missing a transition guard. It fires on every reactive re-run while a task is in that state, not just on state entry. With multiple tasks open, any unrelated attention-state change can trigger duplicate notifications. Fix: track previous state per task and only notify on prev !== currentState transitions.
Otherwise this PR is solid. Details in the review comment.
Mirror the ready-branch transition guard so needs_input/error only fire on state entry, not on every reactive re-run while the task stays in that state. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
# Conflicts: # src/components/StatusDot.tsx # src/store/taskStatus.ts
|
@johannesjo last comment addressed |
Summary
This PR improves the usability of Parallel Code when many task slices are open side-by-side.
The key change in framing was that horizontal scrolling already existed; the real product gaps were:
This PR addresses those gaps and also increases terminal scrollback for agent review/debugging.
What changed
1) Horizontal overflow affordance
src/components/TilingLayout.tsxsrc/styles.cssto use a narrow accent/caret-led cue rather than a heavy overlay2) Runtime-only viewport visibility for task slices
visibleoffscreen-leftoffscreen-rightTilingLayout3) Additive task attention model
src/store/taskStatus.tswithout replacing the existing dot status model:idleactiveneeds_inputerrorreadygetTaskDotStatus()intact for backward compatibility4) Better off-screen/background attention detection
[Y/n]prompts could otherwise loseneeds_inputstate5) UI surfacing for off-screen attention
SidebarandStatusDotso off-screen tasks can surface stronger attention cues6) Attention-aware desktop notifications
readyneeds_inputerror7) Longer terminal scrollback
10_000lines in both:src/components/TerminalView.tsxsrc/remote/AgentDetail.tsxsrc/lib/terminalConstants.tsWhy this approach
Notes on implementation details
Validation
npm run typechecknpm run lintnpx vitest run src/store/taskStatus.test.tsAll passed locally.
Files changed
src/components/Sidebar.tsxsrc/components/StatusDot.tsxsrc/components/TerminalView.tsxsrc/components/TilingLayout.tsxsrc/lib/terminalConstants.tssrc/remote/AgentDetail.tsxsrc/store/core.tssrc/store/desktopNotifications.tssrc/store/store.tssrc/store/taskStatus.test.tssrc/store/taskStatus.tssrc/store/types.tssrc/store/ui.tssrc/styles.cssCommit structure
feat: add horizontal overflow affordance cuesfeat: surface off-screen task attentionfeat: increase terminal scrollbackchore: simplify sidebar attention cleanup