fix(ui): restore default launcher dock - #10800
Conversation
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Reviewed the launcher layout, curation, surface wiring, focused tests, and attached #9144 evidence. I do not see a code blocker in the default Chat/Settings dock behavior: the seeded dock is capped, docked apps are removed from the grouped pages, and an explicitly cleared stored dock remains respected. I cannot merge this as-is because GitHub reports the PR as |
706d745 to
c5e3452
Compare
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
|
Rebased #10800 onto current Pushed head: Validation run locally in
GitHub now reports the PR as |
c5e3452 to
4ae6376
Compare
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
…inter paging control at any width Two adversarially-confirmed QA findings (one root cause): - The home↔launcher rail and the launcher grid pager both attach pointer handlers on the same bubble path: one horizontal drag was tracked — and painted — by BOTH pagers (touch: ~1.35x finger motion, background gap at the screen edge, spring-back jerk on release), and for mouse/pen the outer handler's later setPointerCapture stole the pointer mid-drag, freezing the inner pager (dragRef never saw pointerup, ResizeObserver resync skipped) — mouse drag-paging on launcher page 0 could never reach the Developer page. Violated the shell-surface store invariant that a swipe claimed by two machines must be structurally impossible. useHorizontalPager now runs a shared pointer-claim registry: trackers register in bubble order (innermost first); the first pager that commits a horizontal axis AND canMove in the drag direction claims the pointer exclusively and synchronously EVICTS the rest (push, not poll — losers may never see another event once the winner holds capture). Eviction abandons the drag immediately and settles to the resting page. An unowned dead-end drag rubber-bands on the innermost pager only. finish() claims before advancing so two pagers can never both commit one pointerup. Also fixes a latent scheduleOffset bug where a synchronous rAF left the frame permanently pending, swallowing later drag paints. - PagerEdgeButtons dropped its min-width:1024px gate (hover+fine-pointer kept): with page dots off in production, a fine-pointer window under 1024px had NO control that reached launcher page 2. Also updates the springboard-migration component tests to the #10800-QA dock re-seed semantics (dock-less migrated layouts dock chat+settings; manual page order still preserved for non-dock ids) — the old expectation was invalidated by the launcher-layout upgrade-path fix in this PR. Tests: 4 new nested-harness arbitration tests + 3 composed tests on the real bubbling path (tile-origin drags) + real-browser regression in run-home-screen-e2e (mouse drags page the inner grid both directions; the rail never hijacks) — HOME-SCREEN and LAUNCHER e2e PASSED; focused suites 88/88; packages/ui typecheck clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ity, dock upgrade trap, chat-first sidebar, credential-preserving saves (#10994) * fix(ui): deep-QA batch — transcript data loss, notification reachability, dock upgrade trap, chat-first sidebar, credential-preserving saves Confirmed by an adversarially-verified QA sweep of the chat/launcher/home surfaces on develop (20 confirmed findings; this lands the highest-value, lowest-risk nine): - shell-state: keep attachment-only and secret-request-only turns in the transcript window — an image-only send (or a generated-image reply) used to silently vanish when the turn settled (CRITICAL: perceived data loss). New unit tests cover both roles, every phase, and the empty-array case. - HomeScreen pull-zone: stop double-counting safe-area-top (the strip deadened ~70px of home content on notched iPhones — taps dead, scroll refused); the strip now spans only the residual tucked band + 30px. It is also a real button now: click/tap and Enter/Space open the notification center, so desktop fine-pointer and keyboard/AT users have a path to notifications (was pointer-drag-only, home-only). - launcher-layout: re-seed the default dock for pre-#10800 payloads (favorites [] without intent marker) — those users were locked out of the dock forever with no in-product recovery. An explicitly committed empty dock now stamps dockCleared and stays respected. Corrupt payloads fall back to the seeded default. Migration + marker regression tests added. - ConversationsSidebar: 'New chat' clears the active terminal session (the fresh conversation was created but never shown); the collapsed-rail '+' is now chat-first (it always spawned a TERMINAL via an unreachable-branch bug; New terminal stays in the expanded terminal section). - conversation guards: stamp scope 'general' at creation and reject reserved legacy page-chat titles on rename — renaming a chat to 'wallet'/'settings'/… made it vanish from every list with no recovery. - plugin/connector config saves: handlePluginConfigSave now reports success; ConnectorsSection + PluginsView keep the user's typed draft when a save fails (pasted tokens/keys were silently wiped on network errors). - e2e harness de-flake (verified root causes, not product bugs): chat-sheet keyboard block uses structural flicks instead of a knife's-edge velocity race; launcher fixture overflows the seeded dock (27 specs) with a loud bundle-time guard, restoring the Page-2/page-swipe assertions. Focused suites green: shell-state (13), launcher-layout (35 incl. property), HomeScreen (7), conversations (21), settings+plugins state (202); run-launcher-e2e 15/15; run-chat-sheet-e2e PASSED (51 screenshots). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(evidence): post-fix captures for the deep UI/UX QA sweep (#10722) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(ui): notification dismiss visibility, safe deep-link on home tile, reachable background redo Three more adversarially-confirmed QA findings: - NotificationCenter row dismiss (X) was opacity-0 with only a hover reveal — invisible on touch (the pull-down sheet is the primary mobile surface) yet still hit-testable, so near-edge taps silently deleted notifications; keyboard focus landed on an invisible button. Now dimmed visible at rest, full opacity on hover and focus-visible. - The home Notifications tile fed producer/LLM-influenceable deepLink strings straight into the navigate:view rail, bypassing the scheme-checked navigateDeepLink single source of truth: https deep links were dead taps (cross-origin pushState throw swallowed), unvetted schemes were forwarded, and the tile never marked the notification read (surfaces diverged). Now mirrors NotificationRow.handleOpen exactly. - Background redo (#10771) was unreachable by any user path: the UI channel handles op 'redo' but the BACKGROUND action's op union/resolver/schema had no redo and no UI control existed. Added the redo op end-to-end (regex intent, explicit op, handler broadcast, similes/examples/schema) and a Redo2 button next to Undo gated on canRedoBackground. 4 new tests; plugin suite 21/21, UI suites 15/15. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(ui): overlays stacked above the chat win taps and Escape; palette opens visible Two adversarially-confirmed z-order findings: - The chat's document-level outside-tap swallower ate the FIRST tap on any surface painted above the chat glass (notification pull-down sheet at z-9501, tutorial card at Z_TUTORIAL, any Radix dialog) and collapsed the chat under it. The swallower now cedes taps whose target sits inside [data-above-shell-overlay] or [role=dialog]; the notification sheet, its backdrop, and the tutorial spotlight are tagged. - /commands opened the CommandPalette dialog (Z_DIALOG=170) BEHIND the open chat sheet (Z_SHELL_OVERLAY=9000) — an invisible focus-trapped dialog; Escape then closed the palette AND collapsed the chat at once. The composer's palette route now collapses the sheet first so the palette opens visible over the pill (raising all dialogs above the shell overlay was rejected: tooltips at Z_TOOLTIP=300 inside dialogs would stack under them), and the chat's Escape handler defers to an open dialog (scoped to [data-state=open] dialogs + the notification sheet — broad role=dialog would match always-mounted shell surfaces and permanently disable Escape-collapse). Regression tests: taps inside a role=dialog layer no longer collapse the sheet; Escape with an open dialog leaves the chat open and collapses it once the dialog is gone. 4/4 targeted + existing collapse tests green; run-chatux-gesture-e2e ALL PASSED post-change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(ui): one-shot terminal problem-focus + tap-vs-scroll discrimination on the chat action rail Two adversarially-confirmed QA findings: - A blocked/errored coding-agent session permanently hijacked the chat surface: ChatView auto-focused any error/blocked PTY session whenever activeTerminalSessionId was null, and 'blocked' is a routine long-lived waiting-for-input state — closing the panel or selecting a conversation bounced straight back to the terminal, locking the desktop chat window out of every conversation. Auto-focus now fires at most once per transition into a problem state (pickProblemSessionToAutoFocus + a handled-set ref; viewing counts as handled; recovery evicts so a new transition focuses again). 7 new tests reproduce the loop through React's real effect scheduling. - Flick-scrolling the ChatView transcript on touch toggled the action rail (copy/edit/play/delete) on whichever message the finger started on: handleTapReveal had no move-slop or selection guard, unlike the shell ThreadLine. Touchstart position is now recorded and >10px travel (either axis) or a non-collapsed selection suppresses the toggle, mirroring ThreadLine's COPY_MOVE_CANCEL_PX pattern. 3 new tests (clean tap toggles; vertical/horizontal scrolls don't; selection suppresses). Focused suites: 17 files / 85 tests green; packages/ui typecheck clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(ui): reachable wallpaper picker (Background settings section) + credential form for mode-less connectors Two adversarially-confirmed QA findings: - BackgroundSettingsSection was orphaned dead code: the only surface with BackgroundSettingsControls is the 'background' view (viewKind: preview — hidden on every default build) and the section was never registered, so a default user could not change, undo, or preview the wallpaper from any visible UI (chat-only via the BACKGROUND action). Registered as a real system-group Settings section (Wallpaper icon, en label; other locales fall back to the default label). - Settings → Connectors dead-ended every connector without a hardcoded mode list (farcaster, bluesky, matrix, nostr, msteams, mattermost, twitch, instagram, …) with the factually-wrong '{name} uses its own setup surface.' — no link, no form, even with declared parameters. Mirrors the canonical /connectors fallback: no declared modes + declared parameters → the credential form IS the setup surface (setupPluginId ?? plugin.id). local-setup/plugin-managed/cloud-managed modes keep their dedicated panels (regression suite still green). Settings sweep: 18 files / 208 tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(evidence): audit:app 349/349 post-fix captures (broken=0 needs-work=0) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(ui): single-owner gesture arbitration for nested pagers + fine-pointer paging control at any width Two adversarially-confirmed QA findings (one root cause): - The home↔launcher rail and the launcher grid pager both attach pointer handlers on the same bubble path: one horizontal drag was tracked — and painted — by BOTH pagers (touch: ~1.35x finger motion, background gap at the screen edge, spring-back jerk on release), and for mouse/pen the outer handler's later setPointerCapture stole the pointer mid-drag, freezing the inner pager (dragRef never saw pointerup, ResizeObserver resync skipped) — mouse drag-paging on launcher page 0 could never reach the Developer page. Violated the shell-surface store invariant that a swipe claimed by two machines must be structurally impossible. useHorizontalPager now runs a shared pointer-claim registry: trackers register in bubble order (innermost first); the first pager that commits a horizontal axis AND canMove in the drag direction claims the pointer exclusively and synchronously EVICTS the rest (push, not poll — losers may never see another event once the winner holds capture). Eviction abandons the drag immediately and settles to the resting page. An unowned dead-end drag rubber-bands on the innermost pager only. finish() claims before advancing so two pagers can never both commit one pointerup. Also fixes a latent scheduleOffset bug where a synchronous rAF left the frame permanently pending, swallowing later drag paints. - PagerEdgeButtons dropped its min-width:1024px gate (hover+fine-pointer kept): with page dots off in production, a fine-pointer window under 1024px had NO control that reached launcher page 2. Also updates the springboard-migration component tests to the #10800-QA dock re-seed semantics (dock-less migrated layouts dock chat+settings; manual page order still preserved for non-dock ids) — the old expectation was invalidated by the launcher-layout upgrade-path fix in this PR. Tests: 4 new nested-harness arbitration tests + 3 composed tests on the real bubbling path (tile-origin drags) + real-browser regression in run-home-screen-e2e (mouse drags page the inner grid both directions; the rail never hijacks) — HOME-SCREEN and LAUNCHER e2e PASSED; focused suites 88/88; packages/ui typecheck clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(ui): drop stale companion+voice from view-lifecycle matrix builtin set #10434 (99cab28) removed the `companion` view from the builtin navigation set (BuiltinTab / TAB_PATHS) — and `voice` is likewise no longer a builtin tab — but the view-lifecycle matrix test still classified both, so "covers exactly the builtin tab set" failed on develop tip (classified 36 vs TAB_PATHS 34). TAB_PATHS/BuiltinTab is the authoritative builtin set and is correct; the test was stale. Drop the two stale entries; assertion stays an exact deep-equal against TAB_PATHS. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: moon <stupidlybadadvice@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Shaw <shawgotbags@gmail.com>
Closes #9144
Summary
/apps,/views) and filters docked apps out of curated pages so Chat/Settings are not duplicated in the grid.Evidence
Artifacts are committed under
.github/issue-evidence/9144-default-launcher-dock/:desktop-launcher-default-dock.png,desktop-launcher-after-swipe.png,desktop-dock-chat-launched.pngdesktop-launcher-walkthrough.webmplus contact sheet and tracemobile-launcher-default-dock.png,mobile-launcher-after-swipe.png,mobile-dock-chat-launched.pngmobile-launcher-walkthrough.webmplus contact sheet and tracedockTiles: ["chat", "settings"], first-page grids excluding docked IDs, pointer-swipe paging, final/chatnavigation, and no page/HTTP errors.Passing checks:
Results:
Repo-wide gate note:
git fetch origin && git rebase origin/developwas clean.bun installcompleted.bun run verifywas attempted in this branch and in a clean detached worktree at706d7453ef5, but stops before typecheck/lint ataudit:type-safety-ratchet.origin/develop(f08c847eb80) with the same counts:as unknown as: 107 / 77and?? 0:381 / 380. This is an existing develop baseline issue outside the launcher files.N/A: