Skip to content

fix(ui): remove launcher featured-views dock, single-pager 50%-threshold swipe, per-surface notifications - #11174

Merged
lalalune merged 6 commits into
developfrom
shaw/launcher-notifications-ui-fixes
Jul 2, 2026
Merged

lalalune merged 6 commits into
developfrom
shaw/launcher-notifications-ui-fixes

Conversation

@lalalune

@lalalune lalalune commented Jul 2, 2026

Copy link
Copy Markdown
Member

Summary

UI fixes for the launcher + notifications the user flagged as "messed up and wrong and bad" on real devices:

  1. Removed the launcher "featured views" dock (the top header). Every view now tiles on the swipeable springboard pages — no dock reservation, no pin (★/+) affordance, no controlled-favorites props. Chat/Settings simply lead the apps page like any other tile.
  2. Fixed the "two swipe actions stacked on top of each other." The launcher had two pagers tracking one finger: the outer home↔launcher rail AND the inner page pager were both live on the launcher. Now the inner launcher owns every horizontal gesture on its surface (paging + swipe-right-back-to-home); the rail stands its gesture down while the launcher shows. Exactly one pager per surface. Desktop keeps a click-to-home < rail button at launcher page 0 (routes through goPrev/goNext; hidden on touch).
  3. Smooth, 50%-threshold swipe. The commit threshold went 24% → 50% of the viewport: a slow drag springs back unless it crosses halfway ("past the 50% point if I let go it animates over"); a fast flick still commits early via velocity. The drag tracks the finger 1:1 edge-to-edge.
  4. Per-surface NotificationCenter + the real "notifications look awful" bug. The overlay now renders a surface-appropriate shell — a top-right anchored panel on mouse-driven wide surfaces (desktop shell + desktop web), the refined full-width pull-down sheet on touch/narrow. HomeScreen's affordance uses a new variant="auto" so desktop no longer forces the mobile sheet. Root-cause fix: the sheet/panel were position: fixed but inline children of the home↔launcher rail, whose paging transform on a w-[200%] element made it the containing block — so the overlays anchored to the 2360px rail and rendered clipped off-screen (desktop panel at ~2× viewport width; mobile sheet half off-screen right). Portaled both to document.body so fixed is viewport-relative again. Flat aesthetic throughout (no shadows / header divider — matches the app's PopoverContent).

Evidence (real browsers, checked in)

  • Home-screen e2e (test:home-screen-e2e) — PASSES end-to-end. New checked-in captures output-home/02-mobile-notification-sheet.png (full-width, centered, on-screen) and output-home/09-desktop-notification-panel.png (compact top-right panel). Assertions now verify on-screen geometry (panel right-edge within viewport; sheet centered) so the containing-block regression can't return, and the fixture got the real app's <meta viewport> so CSS vw measures like the device. Also green: no dock, Chat tiles on the page, read-only long-press, swipe-back returns HOME, inner paging (the rail did not hijack the drag), desktop < (→home) present on the launcher.
  • Launcher e2e (test:launcher-e2e) — output-launcher/{mobile,desktop}-rest.png show the pure springboard (no dock, Chat first). De-flaked the reorder + telemetry-ring assertions (3/3 clean).
  • Unit — 115 launcher/pager/home/notification tests green (incl. 2 new variant="auto" tests + 2 flat-shell tests); packages/ui typecheck + biome clean. Rebased onto latest develop.

Collaboration note: the home-dashboard widgets in the e2e (finances/goals/calendar/health/relationships/inbox) were gated off until the concurrently-landed auth-stub (#11166); with it + this PR's portal fix the whole home-screen e2e is green.

🤖 Generated with Claude Code

@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 2, 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: 8e9e7d2e-9e85-429f-bfb6-4c5c1cd78860

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 shaw/launcher-notifications-ui-fixes

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 2, 2026

Copy link
Copy Markdown
Member Author

QA review: verified on the PR head in a clean worktree — 646 unit tests pass across pages/shell (incl. the reworked launcher/pager/notification suites), packages/ui typecheck + biome clean. Inspected the checked-in evidence: mobile-rest shows the pure springboard (no dock, Chat first), 05-desktop-launcher shows the single home < / next > pair. The 50% threshold keeps the velocity commit path so flicks don't need half the viewport, and the dock removal is complete through the layout reconciler — the availability-completeness invariant means persisted favorites re-place onto pages rather than vanish. The disclosed pre-existing home-widget fixture failures are indeed in untouched files.

Shaw and others added 5 commits July 2, 2026 01:18
…+ per-surface notification shells

Launcher: remove the top favorites/'featured views' dock entirely (the
header the user called out as wrong). Every view now tiles on the swipeable
pages — no dock reservation, no pin (★/+) affordance, no controlled-favorites
props. launcher-layout drops the favorites/dockCleared model + toggleFavorite
+ withSeededDock + DEFAULT_LAUNCHER_FAVORITES; LAUNCHER_DOCK_LIMIT is kept
(the desktop-tab pinning model reuses it). Old persisted 'favorites' arrays
parse away and those ids flow back onto the grid via reconcile. Tests/stories/
fixture/e2e updated; vacuous 'no launcher-fav button' read-only checks now
assert the real edit-mode signal (animate-pulse).

NotificationCenter: split the controlled overlay into surface-appropriate
shells. Mouse-driven wide surfaces (desktop shell + desktop web) get a native
top-RIGHT anchored panel (400px, content-sized, outside-click + Escape
dismiss); touch/narrow get the refined full-width pull-down sheet (accent
unread pill, comfortable empty floor, short-landscape cap). Height model
hardened so header+close stay pinned and the list scrolls. Toast-sink guard
tightened to variant!=='bell' so the spawned panel never hijacks the sink.

76 launcher tests + 8 notification tests green; ui typecheck + biome clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e stacked gestures)

The launcher had TWO pagers tracking the same finger: the outer home↔launcher
rail AND the inner launcher page pager were both enabled on the launcher, because
the inner pager's swipe-right-back-to-home was gated off (edgeSwipeRightEnabled
was tied to showPageDots, which LauncherSurface sets false). That left the rail
to own 'swipe right → home' while the inner owned page paging — the 'two swipe
left/right actions on top of each other' the user reported.

Now the inner launcher owns EVERY horizontal gesture on its surface (paging +
edge-swipe-right-home); the rail stands its gesture down whenever the launcher is
showing (rail gesture = home || editing only). Desktop keeps a click-to-home rail
button at launcher page 0 (buttons route through goPrev/goNext, independent of the
gesture gate; hidden on touch). Exactly one pager tracks the finger.

Swipe feel: commit threshold raised from 24% to 50% of the viewport — a slow drag
now springs back unless it crosses halfway ('past the 50% point if I let go it
animates over'); a fast flick still commits early via the velocity path, so quick
swipes never need the full 50%. The drag already tracks the finger 1:1 edge to
edge.

Tests: composed swipe-back-home now fires on the inner page window (where a real
finger lands); momentum-settle test distances bumped past the 50% threshold.
1045 shell/pages/hooks/launcher tests green; ui typecheck + biome clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The launcher-e2e's real-browser Framer reorder occasionally over-fires (a
straight-down drag in a 4-column axis=y grid thrashes onReorder), which both
(a) leaves the DOM order[0] unchanged and (b) floods the bounded interaction
telemetry ring, evicting the earlier tap 'launch' event. Two hardenings:

- Capture the 'launch' telemetry right after the tap, before the reorder burst,
  so the launch assertion no longer depends on reorder volume.
- Accept EITHER a DOM-order change OR a persisted page-0 order change as proof
  the reorder committed (a grid drag can settle back to the same DOM head while
  still persisting a different arrangement); drag one row further with a longer
  per-step dwell.

3/3 clean runs (was ~1-in-2 flaky).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…er, desktop edge buttons)

Regenerated screenshots/bundles from the de-flaked launcher-e2e + home-screen-e2e
runs: mobile+desktop launcher now render as a pure springboard (no featured-views
dock, Chat as the first grid tile), desktop shows one Home < button + one next-page
> button at launcher page 0 (no stacked arrows).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ed tree

Both suites pass fully post-rebase — develop's #11166 auth-stub fixture fix
also cleared the 11 home-widget failures this PR had disclosed as
pre-existing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lalalune
lalalune force-pushed the shaw/launcher-notifications-ui-fixes branch from 9866e43 to 52e739b Compare July 2, 2026 05:20

@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.

…per-surface HomeScreen shell

Root cause of the broken notifications UI: the sheet/panel are position:fixed but
rendered as inline children of the home<->launcher rail, which sets a paging
transform on a w-[200%] element. A transformed ancestor becomes the containing
block for fixed descendants, so the overlays anchored to the 2360px rail instead
of the viewport and rendered clipped off-screen (desktop panel right-edge ~2x
viewport; mobile sheet half off-screen right). The bell popover escaped via
Radix's portal; the controlled shells did not.

- Portal the sheet + panel to document.body so position:fixed is viewport-
  relative again (panel right-edge 1168/vw1180; sheet x8/w386/vw402 — centered).
- HomeScreen's notification affordance now uses variant="auto" (new): renders
  the surface-appropriate shell — desktop top-right panel, mobile pull-down sheet
  — instead of forcing the mobile sheet on every surface.

e2e: home-screen-e2e captures BOTH shells and asserts on-screen geometry so the
containing-block regression can't return; added the real app's viewport meta to
the fixture so CSS vw units measure like the device. With the concurrently-landed
auth-stub (#11166) the full home-screen-e2e now PASSES end-to-end (home widgets +
both notification shells). +2 variant=auto unit tests. 115 ui unit tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@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 188b73e into develop Jul 2, 2026
38 of 63 checks passed
@lalalune
lalalune deleted the shaw/launcher-notifications-ui-fixes branch July 2, 2026 05:37
lalalune added a commit that referenced this pull request Jul 2, 2026
…cape deferral for the desktop notification panel (#11211)

Two required fixes from the #11174 review, landed as a follow-up since the PR
was squash-merged before they could be pushed to its branch:

1. packages/app/test/ui-smoke/launcher-interaction.spec.ts still asserted the
   removed featured-views dock (docked chat/settings, absent from page 0).
   Updated to the new contract: no launcher-dock element; Chat/Settings are
   ordinary page tiles leading the curated Apps page (launcher-curation.ts
   APPS_PAGE_ORDER); chat launches from its page tile. Evidence dir renamed
   9144-default-launcher-dock -> 9144-launcher-page-tiles; swipe helper made
   bidirectional so the test returns to page 0 before launching.

2. ContinuousChatOverlay Escape-deferral selector matched only
   [data-testid="notification-sheet"], not the new desktop anchored
   [data-testid="notification-panel"] (role=dialog, no data-state=open), so
   Escape with the panel open over an open chat sheet closed both. Added the
   panel testid + a unit test mirroring the transcript-viewer deferral test.

Co-authored-by: Shaw <shawgotbags@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
lalalune pushed a commit that referenced this pull request Jul 2, 2026
…ite telemetry (post-#11174 audit)

The #11174 post-merge audit flagged view-manager-actual-flow.spec.ts as
keying its edit-mode helpers on the removed launcher-fav-* badges. Root
cause is deeper: the 'Dynamic view management' form the whole spec drives
was REMOVED from the product in the June springboard->launcher curation
(last rendered by SpringboardSurface.tsx at 3c42a85; no component has
rendered it since), so the spec's entry ready-check
(form[aria-label="Dynamic view management"]) cannot pass and the spec has
been rotting in the default chromium ui-smoke lane ever since — verified
against the live stack: 180s timeout at the ready check while
launcher-interaction passes 2/2 on the same boot.

A test for a surface that no longer exists is larp; delete it. The launcher
edit/delete affordances that replaced per-view management are covered by
run-launcher-e2e.mjs (long-press edit mode, launcher-edit-*/launcher-delete-*)
and Launcher unit tests. Residual gap — e2e coverage for CREATING dynamic
views through the current product flow — noted in the PR.

Also prunes the emitterless 'favorite' | 'unfavorite' members from
ViewInteractionAction (the pin affordance left with the dock; only stale
dist and unrelated feed/bip39 files mention the words).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
lalalune added a commit that referenced this pull request Jul 2, 2026
…ite telemetry (post-#11174 audit) (#11250)

The #11174 post-merge audit flagged view-manager-actual-flow.spec.ts as
keying its edit-mode helpers on the removed launcher-fav-* badges. Root
cause is deeper: the 'Dynamic view management' form the whole spec drives
was REMOVED from the product in the June springboard->launcher curation
(last rendered by SpringboardSurface.tsx at 3c42a85; no component has
rendered it since), so the spec's entry ready-check
(form[aria-label="Dynamic view management"]) cannot pass and the spec has
been rotting in the default chromium ui-smoke lane ever since — verified
against the live stack: 180s timeout at the ready check while
launcher-interaction passes 2/2 on the same boot.

A test for a surface that no longer exists is larp; delete it. The launcher
edit/delete affordances that replaced per-view management are covered by
run-launcher-e2e.mjs (long-press edit mode, launcher-edit-*/launcher-delete-*)
and Launcher unit tests. Residual gap — e2e coverage for CREATING dynamic
views through the current product flow — noted in the PR.

Also prunes the emitterless 'favorite' | 'unfavorite' members from
ViewInteractionAction (the pin affordance left with the dock; only stale
dist and unrelated feed/bip39 files mention the words).

Co-authored-by: lalalune <shaw.nicola.walters@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
lalalune pushed a commit that referenced this pull request Jul 2, 2026
…d bugs)

Adversarial fable review of the merged per-surface NotificationCenter (#11174)
surfaced 6 confirmed in-scope defects; all fixed here:

1. Focus management: the sheet/panel are hand-rolled role=dialog shells portaled
   to body but did nothing for keyboard/AT — no aria-modal, no focus-in, no trap,
   no focus return. Added aria-modal, save/restore activeElement across open, a
   Tab-wrap handler, and tabIndex=-1 on the invisible backdrops so the first Tab
   lands on a real control.
2. Bell popover stayed open after a deep-link row navigated (uncontrolled Radix
   Popover). Made it controlled (bellOpen) so a row click closes it after nav.
3. Filter chips claimed role=tablist/tab+aria-selected without any tabs keyboard
   semantics. Switched to role=group + aria-pressed toggle buttons, matching the
   adjacent sort toggle.
4. Stale category filter could silently resurrect: the drain-to-all fallback was
   computed-only, so a later notification of the drained category snapped the
   open shell back to the old filter. Now committed to state so it is sticky.
5. Empty state showed the definitive "all caught up" before the inbox hydrated
   (conflating not-loaded with empty). Gate on the store hydrated flag; show
   "Loading" until it settles.
6. Overlay z-indexes were raw z-[9500]/[9501] off the floating-layers scale,
   tying/colliding with Z_TUTORIAL. Added Z_NOTIFICATION_BACKDROP/OVERLAY
   (9550/9560, above the pointer-events:none tutorial spotlight, below the
   system-banner band) and mirrored them with the standard comment.

+3 unit tests (a11y dialog focus flow, hydration-gated empty state, aria-pressed
filter toggles) + a __setHydratedForTests store seam. 13 notification + 19
home/store tests green; ui typecheck + biome clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
lalalune added a commit that referenced this pull request Jul 2, 2026
…verified bugs) (#11316)

* fix(ui/notifications): a11y + state correctness follow-ups (6 verified bugs)

Adversarial fable review of the merged per-surface NotificationCenter (#11174)
surfaced 6 confirmed in-scope defects; all fixed here:

1. Focus management: the sheet/panel are hand-rolled role=dialog shells portaled
   to body but did nothing for keyboard/AT — no aria-modal, no focus-in, no trap,
   no focus return. Added aria-modal, save/restore activeElement across open, a
   Tab-wrap handler, and tabIndex=-1 on the invisible backdrops so the first Tab
   lands on a real control.
2. Bell popover stayed open after a deep-link row navigated (uncontrolled Radix
   Popover). Made it controlled (bellOpen) so a row click closes it after nav.
3. Filter chips claimed role=tablist/tab+aria-selected without any tabs keyboard
   semantics. Switched to role=group + aria-pressed toggle buttons, matching the
   adjacent sort toggle.
4. Stale category filter could silently resurrect: the drain-to-all fallback was
   computed-only, so a later notification of the drained category snapped the
   open shell back to the old filter. Now committed to state so it is sticky.
5. Empty state showed the definitive "all caught up" before the inbox hydrated
   (conflating not-loaded with empty). Gate on the store hydrated flag; show
   "Loading" until it settles.
6. Overlay z-indexes were raw z-[9500]/[9501] off the floating-layers scale,
   tying/colliding with Z_TUTORIAL. Added Z_NOTIFICATION_BACKDROP/OVERLAY
   (9550/9560, above the pointer-events:none tutorial spotlight, below the
   system-banner band) and mirrored them with the standard comment.

+3 unit tests (a11y dialog focus flow, hydration-gated empty state, aria-pressed
filter toggles) + a __setHydratedForTests store seam. 13 notification + 19
home/store tests green; ui typecheck + biome clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(ui/pager): rail-pager gesture + a11y hardening (7 verified bugs)

Adversarial fable review of the merged single-owner 50%-threshold pager surfaced
several gesture defects — two are regressions from the 50% change itself:

1. Release velocity, not gesture average (regression): the flick escape-hatch used
   dx/total-elapsed, so the common "drag slowly to ~40%, then flick" read as slow
   and sprang back. Now a trailing 100ms sample window derives RELEASE velocity;
   falls back to the average for tap-flicks/single-sample. Direction-guarded so a
   drag-forward-then-fling-back release can't commit the wrong page. The same
   release velocity now feeds the momentum-settle duration.
2. Edge-swipe-home needed a half-screen drag (regression): the right-drag-home at
   page 0 is damped by EDGE_RESISTANCE, so the 50% raw-distance floor demanded a
   half-screen pull that read as "you can't do this". It now commits at the 64px
   MIN threshold; inter-page swipes keep the 50% floor.
3. Committed-swipe click suppression only covered rail commits (regression from the
   single-owner refactor): inner launcher paging and the edge-swipe-home path could
   still tap-launch the element under the release. Moved suppression into the hook
   (armed on every commit) and exposed handlers.onClickCapture; Launcher +
   HomeLauncherSurface use it, replacing HomeLauncherSurface's local ref.
4. Mouse-button guards: pointerdown ignores non-primary (right/middle/pen-barrel)
   buttons; a mouse/pen move with buttons=0 after a button-down abandons the stale
   drag (released off-surface before capture → no pointerup → hover was panning the
   rail). Gated on hadButtons so synthetic/touch events aren't spuriously abandoned.
5. Settle-teleport: touching down during a momentum settle grabbed the rail at the
   animation's END position; now it reads the live transform and catches the rail
   under the finger.

+9 pager unit tests (release-velocity flick + direction guard, edge-swipe-home
reduced threshold on/off, non-primary-button ignore, stale-hover abandon,
click-suppression) — 17 pager + 112 launcher/home tests green; ui typecheck +
biome clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(ui): reduced-motion, offscreen inert, filter-chip crush, alias-launch route (5 verified bugs)

Continued fable-review cleanup across the launcher/notification/rail surfaces:

1. Reduced-motion was silently defeated: the pager writes an inline
   `style.transition`, which always overrides the `motion-reduce:transition-none`
   CSS class. Gate it in writeOffset (one seam for settle/snap-back/abandon/edge-
   buttons/mount) via a fresh prefers-reduced-motion read, and drop the now-dead
   motion-reduce classes from both rails.
2. Offscreen home↔launcher rail half was aria-hidden but still keyboard-focusable
   — added `inert` to each half (matches the Launcher's inert page pattern) so Tab
   can't reach controls hidden behind the visible page.
3. Notification category-filter chip bar (a horizontal scroll container) got
   vertically crushed when the list overflowed the flex-column shell — added
   `shrink-0` so only the intended list `ul` is the flex scroller.
4. Launcher curation dedup rewrote a winning alias to the canonical id but kept
   the alias `path`, and handleLaunch prefers `path` — so an alias win navigated
   to the alias route while recents/telemetry recorded the canonical id. Drop the
   path when (and only when) the id is rewritten, so launch falls back to
   /apps/<canonicalId> and all three agree.
5. Viewport resize DURING a drag left the rail permanently mis-offset after
   snap-back — finish()/abandonDrag() now re-measure width for the settle
   geometry (the commit threshold still uses the gesture's original width).

+4 unit tests (reduced-motion transition drop, alias-path drop + non-alias path
kept). 128 launcher/pager/notification/home tests green; ui typecheck + biome
clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(ui): WS validation, page-clamp source, sheet grabber, launcher docs (5 verified bugs)

Final batch of the fable-review cleanup on the launcher/notification surfaces:

1. WS notification boundary was a double-cast that trusted every field but `id`.
   Replace with validateWsNotification: require id + title (drop otherwise),
   coerce category/priority to their canonical union defaults, createdAt→now,
   and pass optional string/timestamp fields through only when well-typed.
2. Standalone page clamp read `layout.pages.length` while the RENDERED pages come
   from `curatedPages` in grouped mode — wrong count source. Clamp against
   `pages` (the actually-rendered list) and move the effect below its memo.
3. Notification sheet grabber implied a drag-to-dismiss gesture that didn't exist;
   made it a real dismiss button (tap the pill closes the sheet) — no whole-sheet
   pull gesture, which would fight the list's own scroll.
4. LAUNCHER_PAGE_SIZE doc claimed a fixed 4-col grid though the launcher is
   grid-cols-4 → sm:grid-cols-5; corrected the comment (value unchanged).
5. Launcher header doc claimed "fully token-themed" though the springboard
   intentionally uses a fixed white-on-wallpaper treatment; corrected the doc and
   clarified that production (LauncherSurface) renders read-only curated pages.

+3 tests (WS drop-on-missing + enum coercion) + a __getStateForTests store seam.
123 launcher/notification/store/home tests green; ui typecheck + biome clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test(ui): regenerate home-screen e2e evidence (notifications a11y + gesture follow-ups)

Home-screen e2e passes end-to-end on the rebased tree: mobile sheet + desktop
panel render on-screen, read-only launcher, swipe-back returns home, 0 page errors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Shaw <shawgotbags@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
lalalune pushed a commit that referenced this pull request Jul 2, 2026
…h remount (post-#11174 rebase repair)

develop's #11174 renders launcher tiles through different JSX branches per
mode, so exiting edit mode REMOUNTS the tile and a tile-local
longPressFired ref died with the old instance — the click the browser
synthesizes from the same press then ghost-launched the tile (the exact
regression L3's test pinned). The guard is now parent-owned
(longPressClickGuard on Launcher, passed to IconTile), surviving the
remount. Gesture suite 14/14; Launcher suites green; typecheck + biome
clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
lalalune added a commit that referenced this pull request Jul 2, 2026
…ixes + gesture-matrix hardening (interaction epic) (#11334)

* feat(ui,core): launcher content policy — developer views OFF by default in ALL builds, dev included (L1, ui-interaction epic)

Two dev-mode leaks closed through the one existing seam (viewKind taxonomy +
Settings 'Developer views' toggle):
- useDeveloperMode: remove the import.meta.env.DEV default — Developer Mode
  now defaults OFF on every build; only the persisted Settings toggle turns
  it on, so 'bun run dev' shows exactly the user launcher.
- launcher-curation: the curated Developer page (trajectories/database/
  runtime/logs/skills/plugins) no longer bypasses the toggle — every
  developer entry (viewKind, legacy developerOnly, or curated-by-id) is
  gated on enabledKinds.developer.
- Collapse the dead 'rolodex' builtin tab (no directViews renderer →
  'view unavailable' tile) onto 'relationships'.
- Launcher-button visibility: added deep-link-into-launcher (hidden on first
  paint) + restore-on-navigate-away coverage; the hide behavior itself
  already unmounts (not disables) via PagerEdgeButtons.

Full 3-source launcher inventory + verified non-leaks + ui-smoke
compatibility audit in the evidence README. 34 targeted + 1133/1140 shell/
pages/state suites green; ui+core typecheck clean; before/after/toggled
screenshots captured via a reproducible harness.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ui,app): gesture-matrix hardening — long-press ghost-launch, pull-zone ghost-open, kiosk window drag, portaled notification sheet + real-input e2e (L3, ui-interaction epic)

- Launcher IconTile: swallow the compat click synthesized from a fired
  long-press (every long-press in the shipped curated launcher
  ghost-launched the tile; edit-exit did too in free-form mode).
- HomeScreen notification pull zone: pointer clicks open only within the
  gesture tap slop (PULL_GESTURE_TAP_SLOP, now exported) — an upward or
  sub-threshold drag's trailing click can no longer defeat the pull-down
  direction gate; keyboard activation unchanged.
- KioskViewCanvas floating-window drag: pointer-id tracking,
  pointercancel/lostpointercapture teardown (kills the ghost drag),
  touch-action none on the handle, on-canvas clamp so the title bar stays
  grabbable, guarded capture calls.
- NotificationCenter sheet: portal to body — its position:fixed resolved
  against the translate3d home↔launcher rail, painting the sheet
  half-clipped off the right viewport edge and letting top-band taps leak
  under the backdrop. CAUGHT LIVE by the new e2e's first run.
- New real-input e2e: gesture-matrix.spec.ts + gesture-inputs.ts helper —
  chromium 3/3 + Pixel-7 CDP-touch 4/4; auto-discovered by the PR lane;
  mobile project registration in the ui-smoke config.

11 new unit tests (ghost-click/ghost-drag cases proven red on pre-fix
code); shell+Launcher lane 623 passed; home-screen e2e PASSED; typecheck +
biome clean; 18-surface gesture inventory in the evidence README.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ui): voice/collapse state — mic ends transcription mid-reply (#9880), audio-unlock chip reachable while sheet open, transcription re-listen survives composer drafts, maximized never leaks past leave-full (L2, ui-interaction epic)

- ContinuousChatOverlay: transcription OFF path in handleMicClick now
  precedes the responding gate — a wake-word inline reply no longer leaves
  a lit, dead 'stop transcription' mic.
- ContinuousChatOverlay: new isOverlayControlTarget predicate (whole
  overlay root = inside; the pointer-transparent backdrop is the one
  documented exception) used by BOTH document-level outside-tap detectors,
  so the audio-unlock chip is tappable while the sheet is open (not
  swallowed, no collapse) and genuine outside taps still collapse.
- ContinuousChatOverlay: setMaximized(false) on the two leave-full paths
  that bypass goToDetent (tutorial pill action, onSettleFree gap-rest) —
  no surprise re-maximize on the next return to full.
- useShellController: transcription re-listen loop no longer pauses on a
  composer draft (additive layer: composer keeps working, mic stays on) —
  a one-shot backend no longer silently drops audio while the badge says
  Transcribing; the hands-free loop keeps its draft pause.

Provenance: the original L2 agent's product edits were lost to a
rate-limit kill (tests survived); reimplemented to the committed tests as
spec. Pre-edit red baseline: exactly the 4 target tests failed. Post-edit:
shell suite 583 passed/0 failed; chat-sheet real-browser e2e PASSED twice
(55 screenshots, 7 new assertions: 4 UNLOCK + 3 TRANSCRIBING+REPLY);
typecheck + biome clean. Adversarially verified (approve-with-nits).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ui): launcher long-press click-guard survives the edit-mode branch remount (post-#11174 rebase repair)

develop's #11174 renders launcher tiles through different JSX branches per
mode, so exiting edit mode REMOUNTS the tile and a tile-local
longPressFired ref died with the old instance — the click the browser
synthesizes from the same press then ghost-launched the tile (the exact
regression L3's test pinned). The guard is now parent-owned
(longPressClickGuard on Launcher, passed to IconTile), surviving the
remount. Gesture suite 14/14; Launcher suites green; typecheck + biome
clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(ui): regenerate home-screen e2e artifacts on the rebased tree

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Shaw <shawgotbags@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: moon <thefutureisaweirdplace@gmail.com>
@github-actions github-actions Bot added the ui label Jul 2, 2026
@github-actions github-actions Bot added the Tests label Jul 2, 2026
@claude

claude Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error —— View job


I'll analyze this and get back to you.

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.

1 participant