v0.0.46 — UX polish + a hub-cloud install fix
Released: 2026-05-04. A focused UX polish release on the v0.0.43+ workspace surface plus one install fix that saved hub-cloud on prod.
Dark mode (first pass)
A CSS-variable palette and a one-click toggle in the user-avatar menu (next to Language and "Show welcome tour again").
- New token palette under
:rootandhtml[data-theme="dark"]:--hf-page-bg,--hf-surface,--hf-surface-2,--hf-surface-3,--hf-border,--hf-text,--hf-text-2,--hf-text-muted,--hf-text-faint,--hf-primary,--hf-primary-hover. Pages opt in incrementally by readingvar(--hf-*)instead of hardcoded hex. - Initial-theme resolution:
localStorage.theme→ OSprefers-color-scheme→ light. Cross-tab sync via thestorageevent so flipping the theme in one tab updates every other tab without a reload. - Theme is applied before React mounts, so the very first paint already has
data-theme=...set — no white-flash on dark-mode reloads. - Per-tenant primary-color override is unchanged — branded illustrations and accents still pick up the tenant's color in both modes.
Modal accessibility
Both global overlays (CommandPalette, KeyboardShortcuts) gain the standard WCAG dialog pattern.
role="dialog"+aria-modal="true"+ descriptive labels (aria-labelfor the palette,aria-labelledbyfor the keyboard cheatsheet).- New focus-trap hook remembers the previously-focused element on activation, focuses the first focusable child, intercepts Tab to cycle inside, and restores focus to the original trigger on dismiss.
- Search input in the palette is now a
comboboxwitharia-controls+aria-activedescendant. Result rows arerole="option"witharia-selected. Empty / loading states wrapped inrole="status"so screen readers announce them as live updates. - Decorative SVGs (magnifier, illustration art) get
aria-hidden(orrole="img"+focusable="false"where the illustration carries semantic weight).
Keyboard shortcuts: g <letter> quick-nav + cross-platform CMD
The ? cheatsheet now renders the right modifier symbol per OS:
- Mac →
⌘ - Linux / Windows →
Ctrl
And a Vim/GitHub/Linear-style quick-nav layer for fast page jumps:
| Chord | Page |
|---|---|
g d | Dashboards |
g j | Jobs |
g f | Flow |
g h | Health |
g a | Audit |
g m | Members |
g b | Backups |
g w | Webhooks |
The handler arms on g, fires the registered navigation, and auto-disarms after 800ms so a stray g doesn't lurk. Disarms also on any other keypress so typing "guide" in a search box doesn't trigger anything. Both ? and g ignore inputs / textareas / contenteditable AND any keypress with ⌘/Ctrl/Alt held — those belong to the browser.
CMD+K palette covers the v0.0.43+ surface
The palette already had PAGES + datasets + dashboards + agents. v0.0.46 closes the gap on the new admin surface:
- 11 new pages added to the static catalog: Webhooks, Backups, OIDC providers, SAML providers, SMTP, AI Keys, Custom Domains, System Health, Audit Log, Members, Usage.
- Dynamic fetch grows to 5 endpoints — adds
/connectorsand/usersso connectors and users are searchable. Both are admin-gated server-side; non-admin callers get an empty list, not a 403 toast. - New
connectoranduserresult kinds with distinct badge colors.
Open with ⌘K (Mac) or Ctrl+K (everyone else). Esc or click outside to close.
Mobile-responsive sweep
The workspace pages added in the v0.0.43+ batch were laid out for desktop — fixed-width action rows and tables overflowed on phones. v0.0.46 makes them work on narrow viewports without changing desktop appearance.
- Container padding
clamp(12px, 4vw, 24px)— keeps desktop's 24px gutter, shrinks to 12px on narrow screens. - Header rows (title + primary CTA), per-row action clusters, and form action rows all wrap so buttons drop to a new line instead of clipping.
- Tables (deliveries panel, backup list) are wrapped so the table scrolls horizontally on phones, not the whole page — the rest stays readable.
EmptyState illustrations
A shared <EmptyState> component with eight inline-SVG duotone illustrations (webhook, backup, shield, mailbox, audit, history, sparkle, cloud). Keyed off the platform's primary color via useBranding — tenant brand colors are picked up automatically with no per-tenant assets.
Refactored pages: Webhooks (webhook icon + "New webhook"), Backups (backup icon + "Create backup now", which correctly shows "Creating…" mid-flight), OIDC providers (shield icon + "New provider"), SAML providers (shield icon + "New SAML provider").
cmd_update preserves unbundled subtrees (hub-cloud fix)
The v0.0.45 prod ECS deploy crash-looped hub-cloud because the new tarball ships only iaas/scripts/ (no iaas/backend/), and cmd_update's naive rmtree+copytree wiped /opt/honeyframe/iaas/backend/ — including the .env hub-cloud needed at start-pre.
Same regression class as the v0.0.42 .env wipe but at the directory level: the v0.0.43 fix only protected nested .env files inside subtrees the tarball shipped. When a top-level subtree (iaas/) is shipped partially, the rmtree+copytree silently wipes whatever else lived under it.
cmd_update now uses a new _apply_dir_update helper that:
- Renames the live dir aside (parking).
- Copies the new tarball content into place.
- Moves back any direct child the new tarball didn't ship.
Stale files inside subtrees the tarball does ship still get cleaned (so removed-feature artifacts don't accumulate) — only top-level entries the new release didn't mention survive. cmd_install uses the same helper for symmetry.
8 regression tests in paas/tests/unit/test_honeyframe_apply_dir_update.py cover the matrix.
What's not in this release
- Full dark-mode coverage — the token system + toggle are in place but only
EmptyStatewas migrated as proof. Page-by-page migration tovar(--hf-*)continues incrementally. gchords beyond two keys — eight chords cover the pages operators hit most.- a11y on every modal — the two global overlays (
CommandPalette,KeyboardShortcuts) got the dialog pattern. Per-page modals (Share, Public Links, Confirm Delete) get the same treatment in a follow-up.