Skip to content

fix(ui): restore default launcher dock - #10800

Merged
lalalune merged 1 commit into
developfrom
fix/9144-default-launcher-dock
Jul 1, 2026
Merged

lalalune merged 1 commit into
developfrom
fix/9144-default-launcher-dock

Conversation

@lalalune

@lalalune lalalune commented Jul 1, 2026

Copy link
Copy Markdown
Member

Closes #9144

Summary

  • Seeds fresh launcher layouts with the expected Chat + Settings dock.
  • Keeps the dock visible for grouped launcher surfaces (/apps, /views) and filters docked apps out of curated pages so Chat/Settings are not duplicated in the grid.
  • Extends launcher unit/surface tests and the app smoke flow to prove default dock rendering, swipe paging, and launching Chat from the dock on desktop and mobile.

Evidence

Artifacts are committed under .github/issue-evidence/9144-default-launcher-dock/:

  • Desktop screenshots: desktop-launcher-default-dock.png, desktop-launcher-after-swipe.png, desktop-dock-chat-launched.png
  • Desktop recording: desktop-launcher-walkthrough.webm plus contact sheet and trace
  • Mobile screenshots: mobile-launcher-default-dock.png, mobile-launcher-after-swipe.png, mobile-dock-chat-launched.png
  • Mobile recording: mobile-launcher-walkthrough.webm plus contact sheet and trace
  • Observation JSON files show dockTiles: ["chat", "settings"], first-page grids excluding docked IDs, pointer-swipe paging, final /chat navigation, and no page/HTTP errors.

Passing checks:

bunx biome check packages/ui/src/state/launcher-layout.ts packages/ui/src/state/launcher-layout.test.ts packages/ui/src/components/pages/launcher-curation.ts packages/ui/src/components/pages/launcher-curation.test.ts packages/ui/src/components/pages/Launcher.tsx packages/ui/src/components/pages/Launcher.test.tsx packages/ui/src/components/pages/LauncherSurface.test.tsx packages/app/test/ui-smoke/launcher-interaction.spec.ts
bun run --cwd packages/ui test -- src/state/launcher-layout.test.ts src/state/launcher-layout.property.test.ts src/components/pages/Launcher.test.tsx src/components/pages/Launcher.gestures.test.tsx src/components/pages/LauncherSurface.test.tsx src/components/pages/launcher-curation.test.ts --coverage.enabled=false
bun run --cwd packages/ui typecheck
E2E_RECORD=1 ELIZA_UI_SMOKE_PORT=2183 ELIZA_UI_SMOKE_API_PORT=31383 ELIZA_API_PORT=31383 bunx playwright test --config packages/app/playwright.ui-smoke.config.ts packages/app/test/ui-smoke/launcher-interaction.spec.ts --project=chromium
ELIZA_UI_SMOKE_PORT=2187 ELIZA_UI_SMOKE_API_PORT=31387 ELIZA_API_PORT=31387 bunx playwright test --config packages/app/playwright.ui-smoke.config.ts packages/app/test/ui-smoke/all-views-aesthetic-audit.spec.ts --project=audit-app --grep "builtin-(apps|views|phone) mobile-(portrait|landscape)"
ELIZA_UI_SMOKE_PORT=2186 ELIZA_UI_SMOKE_API_PORT=31386 ELIZA_API_PORT=31386 bun run --cwd packages/app audit:app

Results:

  • Focused UI tests: 73 passed.
  • Launcher smoke: 2 passed with desktop + mobile recordings.
  • Targeted audit: 6 passed.
  • Full app audit: 349 passed.

Repo-wide gate note:

  • git fetch origin && git rebase origin/develop was clean.
  • bun install completed.
  • bun run verify was attempted in this branch and in a clean detached worktree at 706d7453ef5, but stops before typecheck/lint at audit:type-safety-ratchet.
  • The same ratchet command fails on clean origin/develop (f08c847eb80) with the same counts: as unknown as: 107 / 77 and ?? 0: 381 / 380. This is an existing develop baseline issue outside the launcher files.

N/A:

  • Real-LLM trajectories: N/A - launcher layout/navigation only; no model, prompt, action, provider, or evaluator behavior changed.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@coderabbitai

coderabbitai Bot commented Jul 1, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5b84f690-11f0-4563-981c-d017851c9702

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/9144-default-launcher-dock

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@lalalune

lalalune commented Jul 1, 2026

Copy link
Copy Markdown
Member Author

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 DIRTY against develop; please rebase/resolve conflicts and rerun checks/audit evidence if behavior changes during the rebase.

@lalalune
lalalune force-pushed the fix/9144-default-launcher-dock branch from 706d745 to c5e3452 Compare July 1, 2026 17:07

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@lalalune

lalalune commented Jul 1, 2026

Copy link
Copy Markdown
Member Author

Rebased #10800 onto current origin/develop and resolved the launcher conflicts from the already-merged no-favorites-row PR. The resolution keeps the current pager/edge-button work, but restores #10800's intended default Chat + Settings launcher dock: docked ids are excluded from launcher pages, explicit empty stored docks remain respected, and grouped /apps//views surfaces render the dock without duplicating Chat/Settings in the grid.

Pushed head: c5e3452f2ecbccc9ce620b3c47ace2325d38ce29.

Validation run locally in /tmp/eliza-pr-10800:

  • bun run --cwd packages/ui test -- src/state/launcher-layout.test.ts src/state/launcher-layout.property.test.ts src/components/pages/Launcher.test.tsx src/components/pages/Launcher.gestures.test.tsx src/components/pages/LauncherSurface.test.tsx src/components/pages/launcher-curation.test.ts --coverage.enabled=false PASS (6 files, 74 tests)
  • bunx biome check packages/ui/src/state/launcher-layout.ts packages/ui/src/state/launcher-layout.test.ts packages/ui/src/state/launcher-layout.property.test.ts packages/ui/src/components/pages/Launcher.tsx packages/ui/src/components/pages/Launcher.test.tsx packages/ui/src/components/pages/LauncherSurface.test.tsx packages/ui/src/components/pages/launcher-curation.ts packages/ui/src/components/pages/launcher-curation.test.ts packages/app/test/ui-smoke/launcher-interaction.spec.ts PASS
  • git diff --check origin/develop...HEAD PASS

GitHub now reports the PR as MERGEABLE; fresh CI is queued on the rebased head, so I did not merge yet.

@lalalune
lalalune force-pushed the fix/9144-default-launcher-dock branch from c5e3452 to 4ae6376 Compare July 1, 2026 17:14

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@lalalune
lalalune merged commit 95bbc93 into develop Jul 1, 2026
34 of 62 checks passed
@lalalune
lalalune deleted the fix/9144-default-launcher-dock branch July 1, 2026 17:19
lalalune pushed a commit that referenced this pull request Jul 1, 2026
…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>
lalalune added a commit that referenced this pull request Jul 1, 2026
…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Springboard favorites dock defaults to empty — seed a sensible default dock and add the missing gesture/dock tests

1 participant