The sidebar's expandable "MORE" section (uppercase header, chevron, persisted
sidebarMoreExpanded pref, dedicated "Edit pinned items" row) collapses into a
single More nav row that opens a transient popup menu with the unpinned
routes, dynamic plugin tabs, and the pin editor entry. Menu rows are real
anchors, so Cmd/middle-click keeps native link behavior; the More row carries
the active highlight when the current route lives inside the menu. The
sessions list gets the reclaimed vertical space, and one persisted setting is
gone (stale keys are ignored on load). The nav rows and menus move to
app-sidebar-nav-menus.ts to keep app-sidebar.ts under the TS LOC ratchet.
Docs: docs/web/control-ui.md sidebar-navigation section updated.
Fixes#105905
* feat(ui): make the sidebar agent chip body the menu trigger
The footer chip's big name/avatar area now opens the agent menu directly
and the chevron toggle button is removed. New-session plus stays as the
only trailing action; the unread dot moves onto the chip body.
* chore(ui): prune removed agentChip.openConversation key from locale bundles
* fix(ui): keep the agent name in the chip menu trigger accessible name
* feat(ui): agent-centric sidebar footer chip with utility menu
* feat(ui): agent chip menu anchoring, link styling, locale sync
* fix(ui): keep agent chip presence announcement out of the aria-hidden avatar
* fix(ui): resolve agent chip resume sessions against the target agent, not the route agent
* fix(ui): tie unprefixed session keys to the system default agent in chip resume
* style(ui): oxfmt layout.css
* feat(chat): native session scroll-back with import-aware history paging
* fix(chat): page imported session history
* fix(chat): restore terminal import snapshots
* fix(chat): gate cli import resolver on ignore flag to stop history recursion
* fix(chat): correct scroll-back types and drop orphaned recent-messages reader
* fix(ui): explain grayed-out rows in the new-session folder picker
Disabled device rows now carry a reason tooltip (device offline vs. no
folder-browsing support), the admin-gated folder trigger says it needs an
admin connection, and dimmed dot-directories are labeled as hidden folders.
* chore(i18n): sync locale bundles for new-session picker tooltips
* feat(ui): add a Create PR branch row with rate-limit staleness to session PR chips
* fix(ui): gate the Create PR row on a pushed branch
* improve(ui): gate the Create PR row on comparable pushed commits and count untracked work
* fix(ui): satisfy spread lint and align branch-row test fixtures
* chore(ui): translate Create PR branch row copy
* chore(ui): drop zh-CN retranslation churn from the aborted backfill
* fix(ui): guard branch diff stats against checkout diff drivers and fail closed without a default branch
* improve(ui): fold the new-session targets into click menus
The /new target controls become Cursor-style trigger menus instead of an
inline control row: a folder trigger opens the directory browser as a
floating panel (with editable path in its head for manual entry), and a
where trigger opens one menu holding Gateway/node selection plus the
worktree toggle with labeled base-branch/name fields; the agent picker
becomes a menu when several agents exist. Triggers show live labels
(folder basename, node name, a branch badge when a worktree is on), so
the row stays one quiet line even on phones. Menus reuse the shared
session-menu item styles and the chat composer's details/summary
dismissal contract (outside pointerdown, Escape restores trigger focus).
Node-bound drafts no longer show an inert worktree toggle; the item
disappears because managed worktrees are Gateway-only.
* fix(ui): harden the new-session trigger menus
Review fixes: the folder trigger no longer shows the Gateway workspace
basename for node sessions (an empty node folder means that node's
default directory); sibling menus now close on the details toggle so
keyboard-opened menus stay mutually exclusive; and phone menus anchor to
the trigger row full-width so a wide browser panel under a non-leftmost
trigger cannot overflow the viewport.
* fix(ui): keep filesystem roots visible in the folder trigger
folderDisplayName falls back to the raw path so picking '/' (or a drive
root) labels the trigger instead of leaving it blank.
* fix(ui): give the new-session menus the native-select keyboard contract
Opening a menu moves focus to its first item, ArrowUp/Down wrap through
the items (browser rows included), and Home/End jump to the edges,
restoring what the replaced native selects provided. Re-picking the
checked agent no longer resets the draft (the native select never fired
change for the same option).
* fix(ui): keep native key behavior in menu text fields
Menu arrow/Home/End navigation now ignores events from text inputs so
the browser path, base-branch (datalist), and worktree-name fields keep
their native caret and picker behavior.
* fix(ui): let typed paths apply without a directory listing
Admins on hosts without a working fs.listDir keep manual folder entry:
the browser head input tracks a draft path and Use this folder applies a
typed absolute path even when listing fails; shapeless fs.listDir
payloads render as an empty directory instead of crashing the render.
The folder menu also initializes browser state before the focus hook
captures updateComplete, so keyboard-opened menus focus their first row
as advertised.
* fix(ui): apply exactly the shown browser path
Use this folder now applies the head input's absolute path only; the
draft syncs to every listed directory, so browsing is unchanged while an
edited path can never lose to a stale listing.
* fix(ui): let the browser express host-default directories
Review fixes: a cleared path input now applies '' — the host's default
directory (workspace on the Gateway, home on a node) — restoring the
state the replaced clearable folder textbox could express, and directory
results no longer overwrite a path the user typed while the listing was
in flight. E2E covers clearing back to the node default.
* fix(ui): apply the requested directory during browser navigation
loadBrowser assigns the head input the destination it is fetching, so a
mid-flight Use this folder applies where the user is heading instead of
the directory they just left.
* feat(ui): auto-load older catalog transcript on scroll with a stable viewport
* fix(ui): surface the load-older fallback when auto-load is blocked on a short thread
* fix(ui): clamp oversized aggregated tool output in catalog transcripts
* fix(ui): stop catalog auto-pagination when an older read makes no progress
* fix(ui): continue catalog paging through advancing empty pages; exhaust only on a stalled cursor
* fix(ui): detect catalog cursor cycles to bound auto-pagination
* feat(mac): swap dashboard titlebar buttons with sidebar state
The Control UI reports sidebar collapsed/width over a new openclawNav
WKScriptMessage; the titlebar accessory shows toggle+back/forward
right-aligned to the sidebar edge while expanded, and
toggle+search+new-session while collapsed. Search opens the command
palette and + opens the new-session surface via openclaw:native-*
events. Older gateway bundles that never report keep the shipped
toggle/back/forward layout.
Refs #105129
* docs: describe state-dependent mac titlebar buttons
The /new draft page now renders the same welcome block as the empty-chat
start screen, with the draft controls folded in launcher-style: hero on
top, a quiet borderless target row (agent, node, folder, worktree)
directly above the mid-screen composer, and the recent chats below. The
page reuses renderWelcomeState via hint/composer slots so the surfaces
cannot drift apart; the shell treats /new as a chat-like route that owns
its scrolling, with the top inset doubling as the native titlebar drag
band. The welcome is content-sized on this route so a tall draft (open
folder browser, short window) stays scrollable from the top. Also
repairs the stale new-session e2e heading wait (the h1 was removed in
Closes#105068
Rebuilds the Control UI cron page as a sidebar-first Automations master-detail workspace: a task list pane (All/Active/Paused tabs, search, filter popover, curated emoji suggestion cards, scheduler footer) beside a detail pane that edits the selected task inline (prompt, row-style Details/Frequency groups, collapsible Advanced, per-task run history) and shows all-task recent activity when nothing is selected. Create & run now kicks a new task immediately after creation. The modal editor and quick-create wizard are retired; the automation-ideas catalog from #104761 is ported into the new suggestions list. Nav item renamed to Automations and pinned by default; route (/cron) and cron.* RPC contracts unchanged.
Closes#104217
Co-authored-by: Claude <noreply@anthropic.com>
* feat(gateway): standalone approval deep-link page
Squash-rebased #103698 segment onto the typed-actions tip on current main.
Adds the tokenless /approve/{id} standalone approval UI served by the
gateway control-UI router, gateway-store ephemeral login fix (selectGateway
only on changed URL), and approval-page i18n strings.
Drift reconciliation: union-merged i18n translation-memory caches and
regenerated locale metadata via control-ui-i18n sync (33 approvalPage keys
remain English fallbacks in minor locales, as on the original branch).
(cherry picked from commit c82f56011bfe9f0debb8ebe052f14590c187340d)
(cherry picked from commit 80f5636a8b67a3d6a5f330620541a39d4ef3fe6f)
(cherry picked from commit a3e300d337a92bf1b593a0bb52b7ec4549910a21)
(cherry picked from commit 860ad01f9658bba54cb3d59644e5e1a032c0bb3f)
(cherry picked from commit d8b697b28a847950a1797da07fc0ae4c24928492)
(cherry picked from commit 8a654e3271fd5721358812f961a7a7bb386d6726)
(cherry picked from commit 2f776d2e7bf910271fcbd9697597f6f5478b0f30)
(cherry picked from commit 14e64e6e4d763be830830801eeec1a6f17441688)
(cherry picked from commit 4df9ec828d0034fdc76540ff0fe341e599b0f281)
(cherry picked from commit e52968f4ab)
(cherry picked from commit 7214fc25013966f99ff4b2d506aa2f5f789e2113)
(cherry picked from commit c6259ff79787c759c136086e1a54c9ead8e89539)
(cherry picked from commit a58d9f271d27481615f0c94a828704c563d5354f)
(cherry picked from commit dcf1cb6d98)
* fix(ui): preserve approval page gateway auth
* fix(ui): keep approval disconnects fail closed
* style(ui): format approval disconnect copy
* feat(ui): replace Overview page with Connection settings and sidebar attention chips
* feat(ui): open new-session drafts on the chat start screen hero
* refactor(ui): drop old overview-hints paths after rename
* chore(i18n): sync control-ui locale bundles for connection/palette/attention keys
* test(ui): expect attention slot above the sidebar update card
* chore(i18n): re-sync locale bundles after rebase onto main
* test(ui): stub sidebar-attention RPCs in app-sidebar unit tests
* test(ui): use a non-secret-shaped token fixture in connection view test
* refactor(ui): destructure gateway connection in connection settings draft
* refactor(ui): keep connection settings code out of secret-scanner shapes
* test(ui): expect Connection in the settings Connections group
* improve(ui): idle-refresh sidebar attention chips for always-visible windows
* chore(i18n): refresh raw-copy baseline after rebase
* docs(ui): note the unknown-route chat fallback covers retired paths
* feat(ui): redesign composer run-status indicator as chrome-free status text
* feat(ui): replace run-status text with transcript working spark
* fix(ui): keep working spark through reloads, dodge running tool rows, show mobile interrupted toast
* fix(ui): satisfy lint on tool-stream marker access
* fix(control-ui): use canonical thinkingDefault key in Quick Config
The Control UI Quick Config panel was reading and writing the
non-canonical key agents.defaults.thinkingLevel, which is rejected
by the gateway's strict Zod schema with INVALID_REQUEST errors.
Fix: read from and write to agents.defaults.thinkingDefault instead.
The schema already defines this key and the runtime already reads it
at cfg.agents?.defaults?.thinkingDefault, so this is purely a UI path
correction with zero runtime changes.
The fast-mode control is left unchanged pending a maintainer decision
on its intended scope (per-agent, per-model, or new global default).
Refs #104501
* test(control-ui): prove quick thinking persistence
* docs(changelog): note Quick Config thinking fix
* chore: keep changelog release-owned
---------
Co-authored-by: Erick Kinnee <erick@ekinnee.dev>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
The Codex/Claude sidebar sections leaked long titles across the row
timestamps and past the sidebar edge because the row body was never a
flex container, so the title span stayed inline and ellipsis rules did
not apply. The sections also rendered every loaded session (Codex swept
up to 100 catalog pages per host every 30s) with no height cap, growing
past the sidebar shell and painting over the footer.
Rows now reuse the regular session-row __text anatomy so titles
ellipsize, the sidebar renders only the newest 10 sessions per host
with a derived truncation note (the full catalog stays on the sessions
page), each section shrinks and scrolls inside the sidebar body, and
the shell body clips as a final guard. The sidebar full-catalog
hydration loop and the one-off __body class are deleted.
Formatting proof: oxfmt --check clean on changed files via Testbox
tbx_01kx92cwpr1x9ccp2fgn441y8h (local hook skipped: no node_modules).
Fixes#104584