Summary
Follow-up items deferred from the UI maturity pass (feat/ui-maturity, shipping in 0.5.0). Each was consciously left out because it is either high-risk to do without dedicated verification, or low-value relative to its effort. Collected here so they're tracked rather than lost.
1. Mantine-first grid migration (the big one)
Problem. Fast Dash still loads a Bootswatch (dbc.themes.*) stylesheet, and the output mosaic layout is built from dbc.Row / dbc.Col scaffolding that depends on the Bootstrap grid CSS (g-1 d-flex flex-fill, class_name=..., width=). So two design systems still coexist: Mantine (all the actual controls, chrome, chat) and Bootstrap (the invisible grid + the global stylesheet).
Already done in 0.5.0 (the safe parts): dropped FontAwesome; added the accent= Mantine primaryColor API; enriched the Mantine theme (type/radius/shadow scales, focus ring); swapped the Bootstrap-styled components (TextArea → dmc.Textarea, upload labels → html).
Remaining. Replace the dbc.Row/dbc.Col mosaic grid (_do_mosaic, generate_output_component, _prepare_layout in Components.py) with dmc.Grid / CSS grid, then drop the Bootswatch stylesheet and dash-bootstrap-components entirely. Reinterpret theme= as Mantine theme/scheme presets (map the Bootswatch names to curated Mantine palettes so the existing API stays backward-compatible).
Why it's its own RFC. This is load-bearing layout code driving the mosaic feature. It changes the visual baseline of every app and can't be validated by the deterministic suite — it needs a real Selenium/visual pass across mosaic shapes, all output types (Graph/Table/Image/Markdown/multiple), light + dark, and mobile. High reward (single design system, lighter payload, theme= finally themes the chrome), high risk if rushed.
Acceptance: no dbc import in fast_dash/; theme= themes the Mantine chrome; existing mosaic layouts render identically; selenium suite green.
2. Burger shows ✕ at rest
dmc.Burger(opened=True) renders as an ✕ when the sidebar is open (the default), which reads oddly on desktop where the sidebar is a permanent fixture. A clean fix means replacing the Burger (whose opened prop toggle_sidebar reads) with a static hamburger ActionIcon toggled by n_clicks — a rewire of the sidebar-toggle callback. Low value, non-trivial risk; left for this pass.
3. Scroll-to-bottom pill (chat)
The transcript uses flex-direction: column-reverse, so it auto-pins to the newest message in the common case. A "jump to latest" pill only helps the narrow "scrolled up while a reply streams" case, and getting the floating-pill positioning right inside the panel is fiddly. Marginal value.
Related chat follow-ups (from the ship review, for completeness)
run_app results aren't fed back into the agent's tool loop — the model can trigger a run but can't see the output (developer can call the fn themselves). Docs note + possible enhancement.
- A resumed HITL turn gets an empty
ctx.inputs (cosmetic; langstage agents don't consume it).
run_app outputs stream uncapped over socket.io — documented limitation; add a size cap if it bites.
- Pre-existing (not this branch):
describe_app over MCP exposes a browser-typed PasswordInput's current_value — the browser mirror already copies it. Worth redacting password current_value in _describe_static_inputs.
Non-goals
Not proposing to gate 0.5.0 on any of these — they are post-0.5.0 polish/hardening.
Summary
Follow-up items deferred from the UI maturity pass (
feat/ui-maturity, shipping in 0.5.0). Each was consciously left out because it is either high-risk to do without dedicated verification, or low-value relative to its effort. Collected here so they're tracked rather than lost.1. Mantine-first grid migration (the big one)
Problem. Fast Dash still loads a Bootswatch (
dbc.themes.*) stylesheet, and the output mosaic layout is built fromdbc.Row/dbc.Colscaffolding that depends on the Bootstrap grid CSS (g-1 d-flex flex-fill,class_name=...,width=). So two design systems still coexist: Mantine (all the actual controls, chrome, chat) and Bootstrap (the invisible grid + the global stylesheet).Already done in 0.5.0 (the safe parts): dropped FontAwesome; added the
accent=MantineprimaryColorAPI; enriched the Mantine theme (type/radius/shadow scales, focus ring); swapped the Bootstrap-styled components (TextArea→dmc.Textarea, upload labels →html).Remaining. Replace the
dbc.Row/dbc.Colmosaic grid (_do_mosaic,generate_output_component,_prepare_layoutinComponents.py) withdmc.Grid/ CSS grid, then drop the Bootswatch stylesheet anddash-bootstrap-componentsentirely. Reinterprettheme=as Mantine theme/scheme presets (map the Bootswatch names to curated Mantine palettes so the existing API stays backward-compatible).Why it's its own RFC. This is load-bearing layout code driving the mosaic feature. It changes the visual baseline of every app and can't be validated by the deterministic suite — it needs a real Selenium/visual pass across mosaic shapes, all output types (Graph/Table/Image/Markdown/multiple), light + dark, and mobile. High reward (single design system, lighter payload,
theme=finally themes the chrome), high risk if rushed.Acceptance: no
dbcimport infast_dash/;theme=themes the Mantine chrome; existing mosaic layouts render identically; selenium suite green.2. Burger shows ✕ at rest
dmc.Burger(opened=True)renders as an ✕ when the sidebar is open (the default), which reads oddly on desktop where the sidebar is a permanent fixture. A clean fix means replacing theBurger(whoseopenedproptoggle_sidebarreads) with a static hamburgerActionIcontoggled byn_clicks— a rewire of the sidebar-toggle callback. Low value, non-trivial risk; left for this pass.3. Scroll-to-bottom pill (chat)
The transcript uses
flex-direction: column-reverse, so it auto-pins to the newest message in the common case. A "jump to latest" pill only helps the narrow "scrolled up while a reply streams" case, and getting the floating-pill positioning right inside the panel is fiddly. Marginal value.Related chat follow-ups (from the ship review, for completeness)
run_appresults aren't fed back into the agent's tool loop — the model can trigger a run but can't see the output (developer can call the fn themselves). Docs note + possible enhancement.ctx.inputs(cosmetic; langstage agents don't consume it).run_appoutputs stream uncapped over socket.io — documented limitation; add a size cap if it bites.describe_appover MCP exposes a browser-typedPasswordInput'scurrent_value— the browser mirror already copies it. Worth redacting passwordcurrent_valuein_describe_static_inputs.Non-goals
Not proposing to gate 0.5.0 on any of these — they are post-0.5.0 polish/hardening.