Skip to content

Restore the stacked merges lost in #72 (layouts, realism, window chrome, UI Library) and reconcile fork main - #85

Merged
aaronsmulktis merged 89 commits into
facebookresearch:mainfrom
aaronsmulktis:aaronsmulktis/restore-stacked-merges
Oct 10, 2026
Merged

aaronsmulktis merged 89 commits into
facebookresearch:mainfrom
aaronsmulktis:aaronsmulktis/restore-stacked-merges

Conversation

@aaronsmulktis

@aaronsmulktis aaronsmulktis commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor
Screenshot 2026-10-10 at 3 17 14 PM Screenshot 2026-10-10 at 3 17 07 PM Screenshot 2026-10-08 at 1 12 41 PM

Why

#82 and #83 were merged into upstream's copies of their stacked base branches (themes-and-layouts, desktop-shell) seconds before #72 merged the fork's themes-and-layouts into main. The fork branch never had those merges, so neither reached main. Two other lines never got a PR: the realism styles sweep and the window chrome work. Fork main also carries OpenBanking (fork #4), which upstream doesn't have.

What this restores

Merged onto main, in order:

  1. app-layouts (App Layout Variants #82): calendar agenda_first/sidebar_nav, messenger split_inbox/compact_list, maps sidebar_left/bottom_sheet, code editor sidebar_right/top_tree
  2. realism/integration: every app styled like the product it imitates, in every theme
  3. desktop-chrome: global title bar (minimise / maximise / close), app dock, animated agent cursor (apps/chrome=default|windows|none); the UI Library (OpenUI - Taskable Component Library #83); record_video=True
  4. ui-library: keeps the OpenUI tile off by default
  5. fork main: OpenBanking

With this merged (as a merge commit, not a squash), fork main fast-forwards to upstream main.

Conflict resolutions worth reviewing

  • Code editor: keeps the realism chrome and carries over desktop-chrome's window-aware height (--oa-titlebar-h / --oa-dock-space).
  • Todo: 961c532's 76px row fix is re-applied in todo_app/styles.py, where f8e6142 moved the stylesheet.
  • Start-page tile position: OpenBanking and OpenUI both claimed 7. OpenBanking moves to 8, and still renders seventh because OpenUI's tile is off.
  • App inventory: every list (start page, MCP registry, state, tasks, screenshots) gets both OpenBanking and the UI Library.
  • Tests: expectations follow the 7-app inventory. test_start_page renders without the chrome, because the dock adds links the launcher tests don't own.
  • .gitignore: now ignores the leftover onlineshop JDK directory.

Test plan

  • uv run -m pytest tests/: 1621 passed
  • Screenshots regenerated for all committed variations and reviewed
  • TESTING.md lists a uv command for each restored surface
  • Reviewer: uv run launch.py, open a few apps and check the title bar, dock and cursor; then uv run launch.py apps/messenger/layout=split_inbox apps/theme=dark

Known, not addressed here (both predate these merges)

  • The desktop shortcuts use a generic glyph rather than each app's icon.
  • Under vscode_dark, the code editor's page title is dark on dark.

An eighth app: an account index and a per-account transaction ledger,
modelled on a real retail-banking dashboard. Design tokens are sampled
from that dashboard's own stylesheet rather than eyeballed.

Built in the post-migration shape: shared `theme` (design tokens) +
per-app `layout` (structure), with no `appearance/` group. Building it
the old way would have added an eighth app to the migration backlog;
a test asserts the directory stays absent.

  config/apps/theme/openbanking{,_dark}.yaml   global, shared by all apps
  config/apps/openbanking/layout/              default | card_list
  config/apps/openbanking/content/             6 variants

The banking-only tokens (--color-header-bg and friends) are consumed
through `var(--token, <fallback>)`, so the app stays legible under the
seven themes that do not define them.

Read-only by design. AppStateComparison builds every task's target by
deep-copying the initial cross-app state and then requires the whole
dict to match, so an app that drifted on its own would silently break
unrelated todo/calendar rewards. `/openbanking_all` is therefore sorted
by primary key and asserted byte-stable across fetches and unchanged
after browsing every route, including the click-to-reveal disclosure.

Account and routing numbers are masked to their last four digits and
revealed by clicking the figure itself. Disclosure is stateless --
visibility travels in the query string, nothing is written back -- and
each control carries the other row's state so opening one does not
re-hide the other. Account-number tails match the digits in each
account's display name; the three accounts belong to three different
businesses so an agent cannot assume one holder.

Tasks live in their own `tasks=openbanking` group rather than in
`all_tasks`, which is the paper's canonical 30-task inventory. Unlike
longer_horizon they deliberately do not quote their answers in the
goal -- the value is in the ledger, so the agent has to read the right
cell before it can act, and the scorable delta lands in another app.
That makes them rot silently if the seed changes, so
TestTaskAnswersMatchTheSeed re-derives each answer from the config, and
a second test pins every amount identical across content variants (a
translated balance would need a different answer per language).

Also fixes tests/save_screenshots.py, which still named an `appearance`
group for `todo` after that app was migrated -- `--variation dark_theme`
had been failing Hydra composition. Migrated apps now take the look from
a global `apps/theme=` override instead.

Test plan: uv run -m pytest tests/  ->  817 passed, 7 skipped (was 724).
Not visually verified: chromium will not launch in this environment, so
the two new screenshot baselines still need generating.
Rebased onto the appearance removal (5c267af), which had already rewritten
this section around the theme/layout split. What survives from the original
commit is the OpenBanking-specific half; the migration-status prose it also
carried described `appearance` co-existing with `theme`, which is no longer
true of any app.

* `openbanking` and `openbanking_dark` join the shipped-themes list.
* `card_list` joins the layout inventory.
* A new paragraph on `tokens` being open-ended: an app may introduce tokens
  of its own, and should read them through `var(--token, <fallback>)` so it
  stays legible under the themes that do not define them. OpenBanking is the
  worked example, so this belongs with the app rather than on its own.

Note that git applied the original patch without a conflict -- it matched on
the `#### Content` heading -- and produced a second `#### Theme and layout`
section contradicting the one above it. Resolved by hand.
1. rename banking methods for uniqueness
1. retries in `safe_get_json` and fallback return
The card account rendered through the same `account_summary` as checking:
the same balance hero, the same account/routing disclosure. Nothing on the
page said "card", and the hero read $0.00 because a card's
`available_balance` is zero by definition.

Accounts now carry a `kind` (`deposit` | `credit_card`, omitted means
deposit, so the noise variants can keep appending plain checking accounts).
A card renders instead:

  * a card graphic -- brand, chip, PAN in 4-4-4-4 groups, holder, expiry,
    invented two-disc network mark -- with the show/hide control in its
    top-right corner;
  * a payment panel: statement balance, minimum payment due, payment due
    date, current balance, available to spend, credit limit, and the
    statement close date underneath.

No routing number. That is the reason `kind` exists rather than a pile of
optional fields: a card has none, so the row is absent instead of blank,
and `routing_number` is now `Optional[str]`.

The face reuses `--color-header-bg`/`--color-header-fg` rather than adding
banking tokens, so a theme that restyles the masthead restyles the card,
and the existing fallback chain keeps it legible under the seven themes
that define neither. Chip and mark are inline SVG in `currentColor`: a
raster asset would want a per-theme light/dark pair and a remote one would
put a CDN in the request path that test_no_egress forbids.

Still read-only. Disclosure state travels in the query string exactly as
before, and a test asserts `/openbanking_all` is byte-identical after
revealing the PAN.

Seed data. The PAN is deliberately unmistakably synthetic -- leading 9 is
not an assigned network prefix, and the number fails Luhn, both asserted.
The payment figures are one coherent cycle rather than three invented
numbers: closed Aug 21 at 872.19, the Aug 23 charge of 412.00 posted after
the close, 872.19 + 412.00 = 1284.19 is today's balance, and
1284.19 + 8715.81 = the 10000.00 limit. So the statement balance genuinely
differs from the current balance, which is what gives "read the statement
balance" a single right answer.

Three new tasks read the payment panel rather than the ledger. Two
distractors do real work: an agent that takes the largest figure on the
page, or the number nearest the word "payment", gets the wrong one. The due
date scores as a *calendar event*, not a string -- the date string is
translated in the german and mandarin variants, and a string answer would
need one expected value per language.

Test plan: uv run -m pytest tests/  ->  853 passed, 7 skipped (was 825).
Also served it and fetched both states of the card page.
Not visually verified: chromium still will not launch here, so the new
`openbanking_card` screenshot baseline needs generating.
1. better dark theme
1. improve multilingual
1. CLI for adding transactions
1. view more transactions toggle
…l, fix transaction dates, fix dark theme, tests
The docs/ sources landed across this branch without a matching mkdocs
build, so site/ was missing the Inspecting the Databases page entirely
and the nav on every existing page still had no link to it.

Regenerated with `uv run mkdocs build` on the rebased tree, so the
output reflects both this branch's docs and the base's.
…itor

The theme/layout split landed with the layout axis nearly empty: calendar,
messenger, maps and code_editor all declared `- layout: default` in their
defaults but nothing read `config.<app>.layout`, so their layout groups were
inert placeholders and structure was held almost constant across sweeps.

  calendar     agenda_first   lands on the agenda, not the month grid
               sidebar_nav    month nav + view toggle become a left rail
  messenger    split_inbox    chat list stays beside the open thread
               compact_list   dense avatar-less rows; flat messages
  maps         sidebar_left   search + Saved Locations left of the map
               bottom_sheet   sidebar becomes a panel under the map
  code_editor  sidebar_right  file tree right of the editor
               top_tree       file tree as a strip above the editor

Follows the `todo` convention: a `current_layout()` helper reads the config
and the page handlers branch on it. Three supporting refactors, each of which
removes a reason to duplicate:

- code_editor: the three page handlers all built the same
  `Div(cls="flex space-x-2")(side_bar, main_screen)`; that is now a single
  `editor_page()` so a new variant is added in one place instead of three.
- messenger: the chat list is extracted to `conversation_list(selected=)` so
  `split_inbox` can render it beside a thread. The layout is applied as a
  class on <body>, because the `max-w-lg` cap that makes this app
  phone-shaped lives there and a descendant cannot widen its own ancestor.
- maps: the layout reaches templates/map.html as a <body> class; both
  variants are CSS-only, so none of the template's JS knows about them.

Layouts change structure only. Routes, element ids and the `/<app>_all`
endpoints are identical across variants, so rewards -- which read state, not
the DOM -- are unaffected. Screenshot coverage adds the eight variations plus
a `messages_thread` route: both messenger layouts change the thread view,
which the existing list route never renders. Alice exists in every content
variation.
The file tree, the "No file selected" heading and the Language/Theme labels
are all marked `text-white`, from when this app painted its panels a
hard-coded blue. The theme migration repointed `.main-content` at
`var(--color-bg)` -- white in the default theme -- so that chrome became
invisible in every layout, including `default`.

Point `.text-white` inside `.main-content` at `var(--color-fg)`, and restore
white for the elements that carry their own dark fill: the mode/theme
selects and tab strip (`bg-gray-*`) and the highlighted folder row
(`bg-blue-*`).

Found by reading the generated screenshots rather than the DOM -- the markup
assertions passed throughout, since the text is present and merely the same
color as what is behind it.

Not covered by the Code Editor Tasks PR (aaronsmulktis/editor-tasks), whose
code-editor changes are the save method and an `editor_binding()` refactor;
it touches neither `text-white` nor `.main-content`.
… system

The design system had no surface. Tokens lived in yaml, components in
src/open_apps/ui, and the only way to see what either looked like was to
open an app that happened to use them. This adds /uilibrary: a Storybook
for the library, serving two audiences deliberately.

Researchers get tokens as swatches and type specimens next to the
components those tokens paint, read from the *resolved* theme rather than a
hardcoded list -- so `apps/theme=solarized` visibly repaints the page, and a
theme that adds a token documents itself without a code change.

Agents get an app whose state is small and diffable: one row per documented
component holding its active variant and whether it is pinned. Switching a
variant or pinning a story writes through to sqlite and re-renders just that
story, so "set UIButton to the danger variant" is a checkable task. Task
classes come in a follow-up; this lands the surface and `/uilibrary_all`.

Nothing here defines a component. Atoms, molecules and the wordmark all come
from open_apps.ui and the tokens from open_apps.theme -- a storybook that
reimplements its own examples stops being evidence about the real library
the moment the two drift. Molecules render as static specimens with inert
URLs: several post to /desktop/* and swap #desktop-shell, so wiring them up
here would either 404 or mutate another app's state.

Three layouts, following the convention in config/apps/<app>/layout/:
`default` (nav rail beside a canvas), `single_column`, `grid_gallery`.
Content carries the intro and section labels, so the content axis reaches
this app's chrome the same way it reaches every other app's.

`ui_library` is excluded from the generic reward diff alongside
`codeeditor`, for a different reason: a gallery exists to be poked at, so an
agent that wanders in and flips a knob mid-task would otherwise register a
spurious diff and fail an otherwise-correct episode.

Two test expectations move because the app inventory grew: `pinned: all`
now resolves to six apps, and the generated "how many shortcuts" question
answers 6. Both were hardcoded to the old inventory and the new value is
correct.

Note for reviewers: the tile takes position 7 and a new palette icon in both
icon sets. The OpenBanking PR also claims position 7 -- whichever lands
second needs to renumber, and a duplicate is easier to spot in a conflict
than a silent gap.
Playwright sizes a headed window to the capture viewport, and the default
1440x1100 is taller than a laptop screen -- the top of the page lands
off-display with nothing to scroll back to, so --headed cannot actually be
used to watch a capture on a laptop.

Adds --viewport WxH, defaulting to the existing 1440x1100 so every captured
image keeps its current dimensions and stays comparable against
tests/reference_screenshots. Only a run that explicitly passes a different
size changes, which the help text warns about.
…title

Two bugs the generated screenshots caught, neither visible to the markup
assertions that were already passing.

The page emitted the theme's token block and then never used it, so it
rendered on the browser's default white whatever theme was selected --
`apps/theme=dark` produced dark swatches sitting on a light page. The one
page whose purpose is to show what a theme does was the one page not
demonstrating it. Style `body` from `--color-bg` / `--color-fg` /
`--font-family`, the same way the other apps do.

`logo_title_container` already renders the app icon and title, so the extra
H1 printed the name twice.
`.chat .chat-bubble` sets color with !important at higher specificity than
`.chat-bubble-primary`, so --color-on-primary never applied. Scope the
bubble rules under `.chat` so they win.
The restore-white rule matches [class*="bg-gray-"], which every tree row
carries as hover:bg-gray-700, so the previous fix never reached the tree.
Give the tree theme-token fills and plain-label folder toggles.
…tions

Search becomes a rounded field with a search glyph; Saved Locations are
place rows with a quiet remove control; Current Location Info shows a hint
until the map is clicked; Return to List of Apps is quiet chrome; Leaflet's
zoom bar, layer switcher and popups follow the theme.

sidebar_left becomes a Google Maps-style panel emitted before the map with
the search pinned on top, layers bottom-left and zoom bottom-right.
bottom_sheet becomes a mobile sheet overlapping the map with a grab handle
and chip row. Both fold the layer switcher into a button; default keeps it
open because the UI questions built from its screenshot ask about it.
Ids, labels, handlers and routes are unchanged.
The sheet is a short scroll container, so the absolutely positioned
.search-results-mini and .custom-select-options were cut off at its edge.
In bottom_sheet they become static (wrapping below their input) and the
sheet rises to 75vh while any result list is open. CSS only; default and
sidebar_left are untouched.
…yout

Month grid: today's date is a filled marker (aria-current="date"),
out-of-month cells are shaded blanks, weekends are tinted, and events are
compact title-only chips truncated with an ellipsis -- the "(None)" that a
missing location printed under every event is gone (location moves to the
chip tooltip and the agenda).

Toolbar: a "Today" link to the existing /calendar route, compact
"< Prev"/"Next >" controls (labels unchanged), and a segmented
Calendar | Agenda switcher whose selected segment is tinted, not filled, so
"Add Event" is the page's only filled primary. "Return to List of Apps"
keeps its bottom-right spot as a smaller unfilled button.

Agenda: one date header per day, an "All day" time column (events have no
times), title plus location, and an empty state that says what to do.

Layouts stay distinct: default is one left-aligned toolbar with actions in
the footer (every default-screenshot UI question still holds);
agenda_first is a centred masthead over a readable-width agenda;
sidebar_nav's rail gains an aria-hidden mini-month under the month nav.
All colours come from theme tokens via color-mix tints.
Covers the today marker, title-only chips and no "(None)", blank
out-of-month cells, the segmented toggle's single selection, resolve_view
falling back per layout, one "Add Event" per page, the Today link target,
the default toolbar order the UI questions rely on, and the structural
markers that keep the three layouts distinct. Also guards the calendar CSS
against hex/rgb literals.
Replace the Story template's flex rows and nested double tile with one
colored square tile per app (icon centred, name along the bottom edge) on a
fixed three-column grid, styled only from theme tokens: radius, gaps and
sizes follow --radius/--space, hover mixes toward --color-fg, keyboard focus
gets a --color-primary ring. The header drops the empty sub-header paragraph,
the footer becomes a slim bar pinned to the bottom, and phones get two tiles
per row.

Content variants with descriptions switch to listing cards (colored icon and
name, description below) instead of a paragraph of white text on a saturated
tile. Under dark/mono tones the single fill still collapses; the black bw
glyphs are drawn inverted so they stay visible on it.

Tile geometry keys the tokens now own (item_border_radius, item_padding,
hover_scale, ...) and the non-functional style/lightbox/use_theme_colors keys
are removed; the label ink joins the fill palette as tile_label_*. The
broken_logos shuffle moves into shuffle_icons() unchanged so tests can call it.
Render / via TestClient for each layout, theme tone and description
variant: every layout links the same five apps in position order,
clickable_logos leaves the launcher identical to default, broken_logos
still deals icons to the wrong tiles (bw set included), non-light tones
collapse the fill, and the launcher CSS carries no color literals.
…ayout

Chat list: initials avatars in a theme-tinted disc (stable per name via
crc32; group chats get two overlapping member discs) instead of identical
outline icons; bold name that ellipsises before the time, muted one-line
preview, short right-aligned date. 'Return to List of Apps' keeps its text,
href and role=button but becomes a small tonal button (a quiet pane link in
split_inbox) below the list.

Thread: header with avatar, name and (for groups) member names; consecutive
messages from one sender are grouped -- tucked corners, tight spacing, the
sender's avatar and the time only on the run's last bubble, group sender
names once per run, no label on your own bubbles. Sender and time stay in
the DOM for every message (visually hidden), so the search script and the
accessibility tree keep them. Timestamps display in one format
('Sep 17, 9:32 AM'); stored values and /messages_all are untouched.

Composer: pill input and a round send button on --color-primary /
--color-on-primary (Pico's role=group was squaring it); icon-only controls
get aria-labels. Search highlight/flash colours move from hex to tokens.

split_inbox: /messages now shows the two-pane window with an empty reading
pane; the list pane is a <nav aria-label='Conversations'>. compact_list:
one-line chat rows (name, preview, date), Slack-compact thread lines with
sender + time on the first line of a run, boxy composer.

All new rules stand on their own (theme tokens only, radii as multiples of
--radius) so the page still lays out when the daisyUI/Tailwind CDNs are
unreachable.
aaronsmulktis and others added 25 commits October 7, 2026 17:40
Turns on BrowserGym's Playwright screencast (window chrome and agent cursor
included) and copies the result out of <exp_dir>/task_video/<hash>.webm to
<record_video_dir>/<time>_<task>_<pass|fail>[_job<N>].webm, hard-linked when
possible. Works for launch_agent.py and launch_parallel_agents.py; logged to
W&B as episode_video when use_wandb is on. Relative paths resolve from the
launch directory, not the Hydra run dir (shared _absolute_path helper, also
used for logs_dir).
…SLURM

One switch (record_video) drives BrowserGym's recording; record_video_dir
defaults to ${logs_dir}/recordings and is frozen to an absolute path once, in
the launching process (freeze_recording_dir), before job configs are derived.
A sweep's videos therefore share one folder whether its jobs run locally or
on SLURM, and a relative path never resolves against a compute node's cwd.
Names gain the agent (<time>_<task>_<agent>_<pass|fail>[_job<N>]), made
filename-safe, and are claimed with an exclusive create so concurrent
conduct.sh runs cannot overwrite each other.

[Fix] Parallel root configs could not run a single job on this branch line:
no `device` (InterpolationKeyError resolving browsergym_env_args) and no
`headless` (the launcher passes headless=True to every web app subprocess),
both introduced with the device axis on desktop-shell. Also add apps/chrome,
without which sweeps silently ran without the window chrome.
A disabled app (e.g. the online shop) 404s on its /<app>_all route; retrying
only added the full backoff to every state probe.
…ions

The appended BUS ANALYSIS CHK (41288.06) outranked BUS SELECT SAVINGS, so the
expected answer was wrong in that variant. Shift its running balances down by
25000, and drop 'three accounts' from the goal since three variants append one.
The ledger controls pushed the /ledger partial's URL into history, so a reload
showed a bare fragment. The partial now pushes the account page URL via
HX-Push-Url and serves the full page to non-htmx requests. Also run the
seed-answer tests across the English content variants.
The bank's extra tokens already fall back to the active theme's primary/
accent/fg, so it renders correctly under 'dark'. Per-theme light/dark
variants are punted to a separate change.
…okens

No app-specific themes: a palette only one app reads doesn't restyle with the
rest of the environment. The bank-only tokens (--color-header-bg and friends)
collapse to the shared tokens they already fell back to, and a test pins the
stylesheet to the shared token contract.
… into fork main

Syncs fork main with upstream main (facebookresearch#78 shop rewrite) via the conflict-
resolved themes-and-layouts. Conflicts were all "both sides registered a
new app" -- OpenBanking here, the rewritten shop upstream -- and resolve as
a union across start_page, save_screenshots, test_apps and test_no_egress.
test_apps drops the old Java-gated shop test for upstream's replacement.

Also moves openbanking_app off the legacy `src.open_apps.` import prefix,
which upstream removed from every other app in 34d333a.
…ream main) into app-layouts

Brings facebookresearch#82 up to date with its base: upstream main (facebookresearch#78 shop rewrite, facebookresearch#77),
facebookresearch#72's conflict resolution, fork #7 (code editor tasks) and fork #3 (desktop
shell), plus the single online-shop gate in open_apps.apps.availability.

Conflicts:
- start_page layout/default.yaml: #3 split it into the shared
  start_page/default.yaml + layout/gallery.yaml, with `desktop` as the
  default. facebookresearch#82's edits (dead Story knobs dropped, tile_label_color/shadow
  added) are carried into the shared file; none of the dropped knobs is
  read anywhere.
- start_page/main.py: keep both sides' new helpers (shuffle_icons,
  light_glyphs; _prerender_wallpaper).
- calendar, messenger: facebookresearch#82's versions with the `open_apps.` import prefix;
  the old calendar_specific_styles block stays deleted.
- code editor: facebookresearch#82's structure and design, with #3/#7's behaviour ported
  on: editor_binding save fix, editor/design theme split, live theme
  switcher that survives navigation (incl. the Copilot removeProperty fix),
  no_egress, offline utility fallbacks, semantic sidebar rows and inline
  SVG icons. test_codeeditor_ui and test_codeeditor_theme both pass.
- docs/index.md: facebookresearch#82's per-app layout table (now listing desktop/gallery and
  the shop's grid/compact_table) followed by #3's start page section; drops
  the stale "shop is gated on OpenJDK 21" note.

test_start_page follows the new defaults: the launcher tests select
`gallery` explicitly, and the shop's tile is on the page.
dark_theme/ and challenging_font/ are named after appearance variations the
screenshot grid no longer has (it captures theme_dark / theme_challenging_font
now), so they only ever showed the old visuals. The split_inbox file with a
GitHub-upload name was a leftover from a manual before/after comparison.
Each gallery tab now carries the command that produces it
(`uv run launch.py apps/theme=dark`) instead of exporting a variable used by
a block further down.
The 400-line Style block made main.py hard to read as handlers. It is
request-independent, so it moves verbatim; main imports it as before and
todo_main.styles still resolves for the tests.
Port 961c532's row-height fix into todo_app/styles.py, where f8e6142 moved
the stylesheet. Keep main's open_apps.ui __init__: the incoming one was the
wordmark-only stub its own docstring says the UI Library supersedes.
…ry, episode video

Restores what facebookresearch#83 (merged into upstream's desktop-shell branch, never main)
and the unpushed desktop-chrome work carried.

Conflicts:
- codeeditor_app: keep the realism chrome; carry over desktop-chrome's
  window-chrome-aware height (--oa-titlebar-h / --oa-dock-space).
- start_page/main.py: union of availability re-exports and chrome imports.
- save_screenshots.py: UI Library routes and layouts alongside the rewritten
  shop routes and facebookresearch#82 layouts.
- tests: keep main's shop-on-by-default expectations; drop the Java-gated
  shop test; keep the UI Library tests.
- Keep the .claude/internet-mode-used marker (859063d restored it).
Conflicts were all inventory additions on both sides (OpenBanking vs the
online shop and UI Library), resolved as unions. OpenBanking moves into
start_page/default.yaml, where the app inventory lives since the desktop
shell deleted layout/default.yaml, at position 8: it and the UI Library
both claimed 7. docs/index.md keeps main's layout table plus OpenBanking's
card_list and visible_transactions. site/ is regenerated separately.
…w chrome

OpenBanking is the seventh visible tile (OpenUI's is disabled by default):
tile lists, pin resolution and the shortcut-count question grow to 7.
test_chrome's app pages swap /uilibrary for the shop and OpenBanking, the
apps actually visible by default. test_start_page renders without the
window chrome, whose dock adds links the launcher tests don't own.
TESTING.md lists uv commands to see each recently merged surface: window
chrome, the realism sweep, layout variants, desktop shell, devices, themes,
OpenBanking, the WebShop rewrite, the UI Library and episode video.
Every page now carries the window chrome, the realism styles and the
merged app inventory (OpenBanking, the rewritten shop). Adds the routes
that had no baseline: the shop's category/search pages, OpenBanking's
three pages, messages_thread and the UI Library, in every variation.
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Oct 10, 2026
@aaronsmulktis
aaronsmulktis merged commit 6e67827 into facebookresearch:main Oct 10, 2026
2 checks passed
@aaronsmulktis
aaronsmulktis deleted the aaronsmulktis/restore-stacked-merges branch October 10, 2026 19:20
@aaronsmulktis aaronsmulktis self-assigned this Oct 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant