# Control UI

> Browser-based control UI for the Gateway (chat, activity, nodes, config)

- 网址：https://funcoding.ai/agents/openclaw/web/control-ui/
- 来源：OpenClaw 官方文档原文（英文），MIT 许可，同步于 2026-10-11
- 官方原文：https://docs.openclaw.ai/zh-CN/web/control-ui

---
The Control UI is a small **Vite + Lit** single-page app served by the Gateway:

- default: `http://<host>:18789/`
- optional prefix: set `gateway.controlUi.basePath` (e.g. `/openclaw`)

`gateway.controlUi.enabled` hot-applies. Disable it to stop serving dashboard
pages and assets while bots and existing Gateway connections keep running.
Re-enable it to resume serving; missing assets are prepared in the background.
Changing the serving base path or asset root still requires a Gateway restart.

For unmatched HTTP paths, the app-shell fallback respects the request's `Accept` header. An explicit HTML rejection such as `text/html;q=0, */*` overrides the broader wildcard, so the request reaches the startup `503` or final `404` response. Headerless and wildcard-only requests retain the browser navigation fallback.

It speaks **directly to the Gateway WebSocket** on the same port.

## Browser requirements

Use Safari 26.2 or later on macOS 26.2, iOS 26.2, or iPadOS 26.2 or later,
or Chrome or Firefox released within the last six months (Chrome 147+ and
Firefox 150+ as of October 2026). Embedded web views need the same browser capabilities.

Browsers missing required overlay features show an update screen before the
dashboard starts. In the native apps, **Open in browser** opens the current
page in your default browser. Update the browser or operating system if that
browser also shows the update screen.

In **Settings → Appearance → Browser tab icon**, choose **Agent avatar** to use
the selected agent’s image. The **Shape** row offers **Square**, **Rounded corners**,
and **Circle**. Square preserves the full image; rounded and circular icons use a
centered crop. The choice is saved with your tab-icon preference, and activity
badges remain visible on every shape.

After a Gateway restart, an agent may need a few minutes to prepare its database. The chat view shows "Starting up" and the sidebar stays quiet while preparation is pending. Both reload automatically when the agent is ready; an actual preparation failure still shows its diagnostic and repair instructions.

Automatic read acknowledgements and identity refreshes pause while the Gateway reports a restart or suspension. Pending read acknowledgements are shared across repeated session updates. If an acknowledgement is rejected, later updates respect the server's retry delay and use randomized backoff instead of immediately sending another patch.

Reconnect bootstrap reads also pause together: agent identity, session subscriptions, session groups, pending questions, and the session list. An announced restart or suspension holds these reads until readiness or a new connection resumes loading. If a restart rejection arrives without an announcement, one delayed probe at a time checks for recovery after at least a minute, in case the restart is canceled. Writes are never replayed by this mechanism.

Agent identities are shared across views on the same connection and refresh after configuration or agent changes, including `IDENTITY.md` saves through the Gateway, rather than expiring while a tab is idle. Reload the tab to pick up direct filesystem edits to workspace `IDENTITY.md` or avatar image files.

If the Gateway's request queue is full, automatic sidebar session discovery keeps the current rows and retries up to three times, respecting the server's retry delay. A persistent failure shows "The server is busy. Please try again in a moment." Other actions can show this message immediately; wait briefly, then retry the action.

While the initial connection or a route loads, shimmer placeholders reserve the chat layout. Home and System busyness open directly in their destination panels, with working headers and Close controls while the content loads. Brief loads do not flash placeholders; slower loads show placeholders inside the panel, and load errors offer Retry in the same place. The rest of the page stays usable. Drag the System busyness title bar to move the panel; its position is remembered in this browser. You can also focus the title bar and use the arrow keys (Shift moves farther). Compact/expanded transitions animate briefly, respect reduced motion, and keep the panel inside the window. Loading indicators respect your theme and reduced-motion preference; Gateway startup progress remains visible when available.

The selected chat loads before automatic sidebar session lists refresh. Live events remain subscribed during startup, and explicit sidebar actions remain available. Background lists resume after the transcript loads or reports an error.

Session details share concurrent reads across the sidebar, chat, and resource panels. Returning to an unchanged session reuses its details on the same connection. Session changes, explicit refreshes, and reconnects fetch current details; failed reads remain retryable.

Sidebar pull-request indicators reuse the last known snapshot. Opening a session, its progress card, or its Git activity requests current checkout facts; sidebar rows alone do not poll Git. Active panels detect branch and staged changes from Git metadata. Tool completion refreshes working-tree stats, with a five-minute fallback for edits made outside OpenClaw.

Background pull-request comparisons use local Git objects and never fetch missing history or blobs. If a partial clone lacks objects needed for the comparison, statistics can remain unavailable until those objects are fetched. A timed-out comparison skips its dependent checks, keeps the branch visible without statistics or a Create PR link, and logs a warning to fetch repository history and retry.

The sidebar’s **Online** list shows compact person rows with avatar presence indicators: solid green means active, amber means idle, and a hollow green ring means connected with activity unavailable. Names stay on one line and fade at the edge when space is tight. The indicators, hovercard, and accessible description preserve the activity distinctions. A compact group at the end of each row shows a theme-accent spinner and running count, then a small message-circle icon and muted open count. Each icon-number pair uses tabular digits and keeps its natural width, with a wider gap between running and open groups. The group rests at the right edge; names and counts share a text baseline, without fixed digit columns. Counts have no pill background at rest, with explanatory tooltips; hovering or keyboard-focusing the row reveals a subtle grouping pill without shifting the content. Reduced motion keeps the spinner still. Known zero counts are omitted. Open counts each person’s owned, unarchived conversations that you can access across configured agents, excluding hidden subagents, automation, system, and global/unknown sessions. Running counts each conversation once while its own agent turn executes or its delegated subagents remain active, including when the parent is waiting for their results. Queued direct turns without active delegated work do not count. Counts cover the matching sessions before pagination and do not change with your session-list filters. By default, all connected people remain visible, ordered Active, Idle, then Online with activity unavailable. Hover the **Online** block or focus it with the keyboard to reveal **Filter & sort**; the action stays available on touch devices. Its compact menu uses the existing dropdown controls: choose **All** or **Running**, and sort by **Active people first**, **Running sessions**, **Total sessions**, or **Name**. Mouse hover opens the choice submenus; selecting an option dismisses the menu. Count sorts put larger values first and unavailable counts last; **Total sessions** uses the open count above, not lifetime history. **Reset to defaults** appears only after a setting changes, below a single separator, and restores the default view. These controls only filter or order people; they do not change session-list queries or hide either counter. Unavailable counts show no placeholder; the row tooltip and accessible description identify them as unavailable rather than zero. A failed refresh keeps the last counts with a retry notice.

Person hovercards keep their **Recent sessions** selection and order stable while open, so background activity does not move links under the pointer or keyboard focus. Reopening the card selects the latest sessions. Timestamps stay live, and sessions that leave the visible, eligible roster disappear without replacing them with other sessions. **Viewing now** continues to follow presence.

Sidebar live narration pauses while the browser tab is hidden and resumes from current activity when you return. The selected chat and pending outbox keep their separately owned subscriptions.

The sidebar’s **Unsent draft** pencil covers saved text, attachments, replies, and goals, including drafts saved in another tab or before a reload, without reopening the conversation. A newer edit or clear always replaces an older saved draft. Incognito conversations never show a saved-draft pencil. Outbox attention badges also count queued messages with attachments that need review once the connection finishes restoring.

If this browser has saved drafts or messages that could not be restored to a chat, a **saved drafts** or **saved messages to review** notice shows their content and attachment names. Empty records are not counted. The original chat is named only when it can be identified from your available conversations. Choose **Review in this chat** in a non-Incognito chat with an empty message box and no pending messages; confirmation restores the saved copy without sending it. Messages with unconfirmed delivery stay paused—check the original chat before retrying. **Delete saved copy** asks for confirmation and removes only the saved draft, messages, and attachments shown together, not messages already sent to a chat.

With sidebar previews enabled, running sessions show a small, static tool icon beside the progress text on the second row beneath the session name. The title row stays unchanged, and the tool name is available only in the icon’s tooltip and accessible label rather than repeated as visible text. The compact one-row sidebar and team roster add no tool icon or tool text, so tool changes do not shift the list. Tool progress uses only explicitly public progress text from the Gateway, never argument-derived metadata or raw command output. If a call’s progress becomes hidden, its displayed progress is withdrawn. Pending questions and other critical status keep their existing priority. The existing session indicator remains the only activity animation, and tool state clears when its live subscription ends.

Live narration retains up to six visible running background sessions, plus the open session. Recency changes keep that window stable; when a session finishes or leaves the visible rows, the most recent eligible session fills its slot. Reconnecting selects a fresh window.

If a narration subscription encounters a retryable failure or times out, it retries automatically with randomized exponential backoff, honoring the server's retry delay. Sidebar updates share the pending retry instead of sending more requests. Retries stop when that session leaves the narration window, the tab is hidden, or the connection closes; non-retryable errors wait for a new subscription intent or connection.

Failed narration releases use the same backoff, including while the tab is hidden. If a session is needed again, its queued release is canceled and its subscription is renewed safely. Closing the Gateway connection cancels release retries.

Closed Terminal, Browser, and Desktop panels initialize when you open them rather than during initial navigation. Home/Ask OpenClaw and System busyness keep lightweight frames ready and defer their conversation or diagnostic contents until opened. Home preserves its saved dock position and size throughout loading. Panels saved as open still restore after a reload. Settings does not automatically reopen Ask OpenClaw; its control and diagnostic actions can still open it explicitly.

Hidden retained chats defer command and model metadata refreshes until you return to them. Returning to a recently opened chat reuses its completed metadata on the same connection until a Gateway change invalidates it. Concurrent readers share the same request. Session events with an unchanged model-selection revision retain the model catalog, and session-only changes retain agent commands. Native sessions without a model-selection revision wait for a 2.5-second quiet period after ordinary patches before refreshing the catalog and session facts. Explicit model, account, and runtime selections refresh promptly. Configuration and command changes refresh commands; catalog and session lifecycle changes refresh affected model choices. Repeated changes during a request share one trailing refresh instead of issuing overlapping requests.

New Session keeps previously fetched model choices selectable while their catalog
refreshes in the background. Before the first catalog arrives, it does not turn a
configured default into a model option. Command palette model results use the same
catalog cache and appear independently of slower search categories.

Provider authentication status is shared across views and refreshes after account changes and near credential warning or expiry deadlines. Credentials without an expiry do not need periodic refreshes. Hidden tabs defer deadline refreshes until visible again.

The sidebar loads automation status once per connection and refreshes after automation or configuration changes. Failed reads retry once per minute while the tab is visible and stop retrying after success. Sidebar health and Automations page refreshes pause during announced restarts or suspension and catch up when the Gateway is available again. Overdue warnings advance on a local deadline without polling the Gateway. Hidden tabs catch up when visible; returning to an unchanged tab does not poll automations. Command palette searches reuse their automation inventory on the same connection until one of those changes or a reconnect.

Automation inputs appear as compact, collapsed activity rows instead of message bubbles. Expand a row to read the full prompt and access its message actions. Each automation input stays separate, even when several jobs run in the same conversation. The expanded **From** link opens that automation's History tab and highlights the originating run; open the run's transcript from History when needed.

Thinking, speed, and context-window changes stay synchronized across panes showing the same session. While a change is pending, the latest selection remains visible. A rejected change restores the latest confirmed value. Delayed events from a replaced session leave the current transcript and unsent draft intact.

While an agent works, completed commentary or preambles appear inline in the
conversation when the model and runtime provide them. Narration keeps its
formatting and position alongside tool activity; the working indicator remains
a separate status for execution, startup, or approval. **Keep commentary** in
the chat view menu controls whether commentary stays visible after the run,
not whether the active run’s narration survives a history refresh. Completed
dashboard turns collapse their narration and tool activity under **Worked for …**
above the answer, with durations such as **Worked for 2 minutes, 3 seconds**.
Expanding it restores the sequence with the existing tool-call groups and shows
the total tool-call count. When no run duration is available, the heading reads
**Worked** rather than estimating from message timestamps. Failures and other
non-success outcomes remain visible even when collapsed, such as
**Worked for 2 minutes, 3 seconds · 2 failed**.

Still-streaming assistant text stays at the bottom of its run, below saved output, and
takes its transcript position once saved.

Accepted steering messages keep their saved transcript positions. Earlier saved
output stays above the message; later answers and live output appear below it,
including when the same run continues after steering. Reloading or reconnecting
does not move the message to the end of that run. Unsaved assistant text remains
one live tail until saved rows replace it; the UI does not split or rewrite
stored assistant messages.

Consecutive tool activity shares one expandable log, including when background
work resumes in a new run. Visible messages, media, and conversation markers
keep their place and separate logs; live response text and the working indicator
stay outside the log. Grouping changes only the presentation, not the transcript.

Inter-session messages appear as compact **updates from** activity rows instead
of chat bubbles. Consecutive updates from the same source share one row; other
messages and conversation markers keep them separate. Select the row to show
the original messages and timestamps in one step, or select the source name to
open that session. Search results and reply navigation reveal the matching
messages. This changes only presentation, not stored messages or run ownership.

When an incoming message causes an unstarted tool call to be skipped, its card
and work summary show **Skipped**, including after reloading the conversation.
Approval blocks and tool failures keep their separate outcomes.

Open the parent conversation's side panel and select **Subagents** from its **+**
menu to inspect child runs, including swarm workers. The panel loads all child
pages automatically and groups running and finished work,
keeping children waiting on their own descendants under **Running**. It shows
elapsed time and available tool activity, and opens each child's existing
view-only transcript beside the parent. Avatar-free child transcripts do not reserve
empty avatar columns, and narrow panes use compact horizontal insets while wide
transcripts retain the reading-width limit. It does not add rows to the left sidebar.
The parallel-tasks view also shows aggregate swarm progress. A directly opened child page
offers **Open parent session**. The `/subagents list`, `/subagents info <id|#>`,
and `/subagents log <id|#>` commands remain available.

Open **Processes** from the chat header's **Panels** menu or the side-panel **+**
menu to inspect the conversation's background exec commands. It is separate from
**Subagents**. Running and retained finished processes show status and elapsed
time. **Finished** starts collapsed; click its heading to expand or collapse the
list. Selecting a process opens its recent output. **Stop** targets that exact
process, not the parent conversation or another command with the same name.
Hidden panels stop refreshing. Output follows the process owner's temporary
retention limits; viewing it does not drain output waiting for the agent.

Select a session's title in the chat header to rename it. Enter saves the name;
Escape cancels the edit. While an input method is composing text, Enter and
Escape stay with composition. Finish composing before saving or canceling.
Once the Gateway confirms a rename, the saved name stays visible while the session
list refreshes, even if an older snapshot arrives late.

Dragging a session between sidebar groups updates its placement immediately. A successful
save keeps that placement even if the subsequent list refresh fails; the UI reports
the refresh error separately. If a connection failure leaves the save unconfirmed,
refresh and check the session's group before retrying. Other clients' newer group
changes still reconcile through session events.

The sidebar keeps unread child failures visible on their ancestors. These warnings
name the child session that failed, even when its parent has finished or continues
working. Select the warning to open the child session and acknowledge its failure;
a subagent chat opens without adding a sidebar row.

Choose **New agent** in the sidebar or Agents home to open the custodian chat.
It recommends a chief of staff, researcher, writer, reviewer, or a small team
with all four. Reply with a choice, or describe custom work and a name. Role
choices use the same [role templates](https://funcoding.ai/agents/openclaw/cli/agents/#role-templates) as the CLI;
creation waits for operator approval. For custom work, the approved purpose is
saved in the new workspace's `AGENTS.md`; the normal identity ceremony still runs.
With `skipBootstrap` enabled, only these requested instructions are seeded, without
the generic identity or bootstrap files.
Existing workspace instructions are never overwritten. If `AGENTS.md` already
contains different instructions, choose a new workspace for the custom agent.
Created agents appear in Agents home and
the agent switcher.

The sidebar agent menu uses horizontal rows with a bounded, scrollable list.
With more than six agents, **Find an agent…** filters by display name or agent ID;
matching names retain their existing pinned order. Duplicate names show their
IDs underneath. New-agent, directory, capability, and settings actions stay outside
the scrolling list. Reopening the menu clears the filter and brings the selected
agent into view.
Opening **New agent** keeps your existing Ask OpenClaw conversation. Finish any
pending wizard or approval before opening the creation choices.
If team creation stops partway through, the custodian reports the retained
agents so you can inspect them before creating the missing members.

## Take a photo in chat

Choose **Add attachment → Take photo** in chat or New Session to open a camera
preview. Allow camera access when your browser asks, then choose **Capture**,
**Retake**, or **Use photo**. The chosen photo becomes a draft attachment; it does
not send the message. The preview stays in your browser and does not request
microphone access.

The live preview requires HTTPS or localhost and a browser that supports camera
access. On plain HTTP LAN addresses or browsers without the camera API, choose
**Use device camera** to open the native capture picker instead. This preserves
mobile camera capture without silently substituting a picker for the preview;
your browser decides whether it shows a camera or a file picker. If access is denied,
allow the site in your browser and operating-system camera settings and retry.
The explicit **Use device camera** option also remains available after a preview
request fails, including permission denial; it never opens automatically.
If no camera is available, choose **Upload photo** instead.

The camera stops when you capture a photo, close the dialog, or leave its draft.
File and photo uploads remain available through their existing pickers, including
the combined **Attach…** picker on iOS Safari.

## Watch a desktop in Picture-in-Picture

Connect the Desktop viewer, then choose **Open desktop in Picture-in-Picture** in
its toolbar. The browser opens a view-only, always-on-top window so you can watch
the remote computer while using other tabs or apps. The same action is available
in the docked panel, chat side panel, and focused desktop window.

This requires a secure context (HTTPS or localhost) and a desktop browser that
exposes the Document Picture-in-Picture API, including supported Chrome and
Firefox versions. The control is disabled when the API is unavailable or the
desktop is not connected. Browser permissions can still deny the request; check
those permissions and click the control again to retry. OpenClaw does not replace
unsupported PiP with an ordinary popup.

PiP mirrors the existing live connection without taking control or opening a
second desktop connection. Closing PiP leaves the original viewer and remote task
running. Disconnecting, changing the viewer's source or session, or closing the
originating viewer closes PiP; it does not stop the remote task. Keep the opener
tab open. A sleeping computer or a browser that suspends the entire page cannot
continue streaming.

## Quick open (local)

If the Gateway is running on the same computer, open [http://127.0.0.1:18789/](http://127.0.0.1:18789/) (or [http://localhost:18789/](http://localhost:18789/)).

If the page fails to load, start the Gateway first: `openclaw gateway`.

<div class="callout callout-note">

On native Windows LAN binds, Windows Firewall or organization-managed Group Policy can still block the advertised LAN URL even when `127.0.0.1` works on the Gateway host. Run `openclaw gateway status --deep` on the Windows host; it reports likely-blocked ports, profile mismatches, and local firewall rules that policy may ignore.

</div>

Auth is supplied during the WebSocket handshake via:

- the configured shared secret in either `connect.params.auth.token` or
  `connect.params.auth.password`; `gateway.auth.mode` selects the configured
  value (`gateway.auth.token` or `gateway.auth.password`)
- Tailscale Serve identity headers when `gateway.auth.allowTailscale: true`
- trusted-proxy identity headers when `gateway.auth.mode: "trusted-proxy"`

Gateway auth runs before device pairing. A direct loopback connection does not bypass token or password auth. The login screen and **Settings → Gateway** use one **Gateway secret** field: paste the token or type the password. After a successful connection, the UI keeps the secret in session storage for the current browser tab and Gateway origin only when the Gateway reports token auth. Passwords stay in memory and are never persisted. After pairing, the browser can use its stored per-device token on later connections.

If you paste a setup code from **Devices → Pair device → Copy setup code** into **Gateway secret**, the UI shows an inline hint before you connect. Paste that code into **Settings → Gateway** in the OpenClaw mobile app. For the Control UI, run `openclaw gateway auth-token --show` in an interactive terminal on the Gateway host and paste the shared token instead. If a connection with a setup code is rejected for a token or password mismatch, the login screen repeats this guidance.

Local onboarding generates a Gateway secret in token mode by default, without a token/password picker, and preserves existing password mode. Use `--gateway-auth password` or `--gateway-password <value>` for explicit password setup; Tailscale Funnel requires password mode. If the Gateway starts in token mode without a configured token, it generates an ephemeral runtime token for that process instead. The runtime token is not written to config, so it cannot be recovered and a loopback browser without that token is rejected. Run `openclaw doctor --generate-gateway-token`, restart the Gateway, then run `openclaw gateway auth-token --show` in an interactive terminal and paste the output into **Gateway secret**.

## Agents home

Open **Agents** in the sidebar, choose **See all agents** in the agent menu, or
visit `/agents` to see your configured agents as a roster. Each card shows the
agent's identity, model, current work status, last activity, and a preview from its
main chat. **Open chat** opens that agent's
main session. Working agents appear first, followed by the most recently active.

**Manage agents** opens `/settings/agents`. **New agent** opens the existing
agent creation flow when available, or agent settings otherwise. `/agents` now
opens the roster; agent configuration remains at `/settings/agents`.

To browse sessions across agents, choose the **Show all** tile in the agent
switcher. It appears with two or more agents and groups their own avatars: two
overlap diagonally, three or four form a two-column grid, and five or more show
three avatars plus a remaining-agent count. This enables **team mode**, a browser
preference that is off by default. The top row becomes a workspace header with
the configured Gateway display name, or **OpenClaw**, and a small static OpenClaw mark.
Both modes use the same menu: agent tiles, **New agent**, **See all agents**, then
a divider before **What can Harbor do?** and **Harbor settings**, named for the
active agent. **See all agents** opens `/agents`; the named settings action opens
that agent’s configuration. The selected tile has an avatar ring. Help and its
links remain in the account menu. Pinned sessions stay in **Pages**, using their
agent's avatar as the icon.
Other sessions appear under collapsible agent headers in configured roster order,
which stays stable as activity changes. **Home** disappears from Pages: click an agent header's avatar or name to
open that agent's main chat. The separate collapse control only folds its sessions.
The top **+**, labeled **New conversation**, opens an agent menu with avatars and names in
the same order as the groups; choosing an agent opens New session for that agent.
Each group's **+** does this directly, appearing on hover or keyboard focus and remaining visible on touch devices. Selecting a session switches the active
agent for chat. Choose a named agent tile in the workspace menu to leave team
mode with that agent selected, restoring the agent chip, Home row, and direct
New session button.

Choosing **Show all** defaults the shared page scope to **All agents**. That scope,
including an explicit **All agents** selection, is saved in this browser for each
gateway. It survives reloads and switching to another gateway and back, even if
you open a different agent's chat in team mode. Choosing a named agent tile leaves
team mode and scopes pages to that agent. You can still choose a narrower page
scope while in team mode; navigating between pages does not reset that choice.
Automations, Dashboards, Sessions, and Usage support all-agent views, with
agent identity shown on mixed-agent rows. In Settings, choose an agent below the
sidebar title to keep the same target across Agents, Models, Memory, and Skills.
Global settings remain global. Skill Workshop uses the agent selected through
chat; open an agent's main chat from its group header to select it. Chat actions
always belong to the conversation's agent.

Choose **All sessions** from an agent group’s options menu to open the Sessions
page filtered to that agent. Open **Agents** in the sidebar to return to the roster
page. See [Sidebar navigation](https://funcoding.ai/agents/openclaw/web/control-ui/sessions-and-sidebar/#sidebar-navigation)
for group controls and filtering.

Agent names and avatars follow agent and identity updates. While a configured avatar image loads,
the avatar keeps its tinted background with no face or text. The image appears when ready;
an emoji or generated face appears only when no image is configured or the image fails to load.
Repeated views reuse prepared avatar thumbnails; updating the avatar refreshes its thumbnail.
This behavior is shared by the roster, agent switcher, identity chips, settings, and chat.

Activity and previews on the page and sidebar roster refresh on session events
and Gateway reconnects. Reusing cached ancestry for the selected session does not
trigger another list read. Events collect in a randomized four-to-five-second window
that later events cannot postpone, spreading automatic reads across browsers.
After an automatic read, the next waits three times its duration,
bounded between five and 15 seconds. Navigation, reconnects, and explicit refreshes
bypass that delay. When both are visible, they share one activity window and
one refresh, so opening **Agents** while team mode is visible does not duplicate requests. Activity loading
stops when neither roster is visible. Each refresh reads at most 300 sessions
across agents, loading pinned sessions first and then the most recent sessions.
Pinned sessions count toward that limit; sessions outside the window do not appear
in the grouped sidebar or contribute to activity summaries, except that the open
conversation remains visible so direct links keep a selected row. When a main session
is absent from the window, its agent's most recent session supplies the preview.

## What each page covers

- [Connect and pair](https://funcoding.ai/agents/openclaw/web/control-ui/connect-and-pair/) — pair a browser or phone, reach the UI over Tailscale, and fix a blank page.
- [Sessions and sidebar](https://funcoding.ai/agents/openclaw/web/control-ui/sessions-and-sidebar/) — sidebar zones, session menus, and the New session page.
- [Systems workspace](https://funcoding.ai/agents/openclaw/web/control-ui/sessions-and-sidebar/#systems-workspace) — contextual machine navigation and a desktop-first workspace.
- [Chat](https://funcoding.ai/agents/openclaw/web/control-ui/chat/) — composer controls, the session rail, transcript rendering, and hosted embeds.
- [Panels and docks](https://funcoding.ai/agents/openclaw/web/control-ui/panels/) — Ask OpenClaw, the Home dock, the operator terminal, and the browser panel.
- [Settings](https://funcoding.ai/agents/openclaw/web/control-ui/settings/) — identity, appearance, plugins, updates, MCP, activity, and meetings.
- [Feature and RPC reference](https://funcoding.ai/agents/openclaw/web/control-ui/feature-reference/) — every capability with the Gateway RPC behind it.
- [Offline and reconnect](https://funcoding.ai/agents/openclaw/web/control-ui/offline-and-reconnect/) — what survives a dropped connection.
- [Security model](https://funcoding.ai/agents/openclaw/web/control-ui/security-model/) — content security policy, media route auth, and approval links.
- [Build and develop](https://funcoding.ai/agents/openclaw/web/control-ui/development/) — build the UI and run the dev server against a Gateway.

Running the Gateway in Docker? See [Using the Control UI browser](https://funcoding.ai/agents/openclaw/install/docker/#using-the-control-ui-browser) for the browser-equipped image and setup requirements.

## Where each section moved

Every section heading from the previous single-page version keeps its anchor here, so an existing link such as `/web/control-ui#chat-behavior` still resolves. Each entry points at the page that now holds the content.

- <a id="session-rail-and-side-chat" />[Session rail and side chat](https://funcoding.ai/agents/openclaw/web/control-ui/chat/#session-rail-and-side-chat)
- <a id="session-links-in-messages" />[Session links in messages](https://funcoding.ai/agents/openclaw/web/control-ui/chat/#session-links-in-messages)
- <a id="composer-capability-menu" />[Composer capability menu](https://funcoding.ai/agents/openclaw/web/control-ui/chat/#composer-capability-menu)
- <a id="chat-behavior" />[Chat behavior](https://funcoding.ai/agents/openclaw/web/control-ui/chat/#chat-behavior)
- <a id="source-previews-and-copying-code" />[Source previews and copying code](https://funcoding.ai/agents/openclaw/web/control-ui/chat/#source-previews-and-copying-code)
- <a id="markdown-tables" />[Markdown tables](https://funcoding.ai/agents/openclaw/web/control-ui/chat/#markdown-tables)
- <a id="mermaid-diagrams" />[Mermaid diagrams](https://funcoding.ai/agents/openclaw/web/control-ui/chat/#mermaid-diagrams)
- <a id="hosted-embeds" />[Hosted embeds](https://funcoding.ai/agents/openclaw/web/control-ui/chat/#hosted-embeds)
- <a id="chat-transcript-layout" />[Chat transcript layout](https://funcoding.ai/agents/openclaw/web/control-ui/chat/#chat-transcript-layout)
- <a id="chat-message-width" />[Chat message width](https://funcoding.ai/agents/openclaw/web/control-ui/chat/#chat-message-width)
- <a id="send-and-history-semantics" />[send and history semantics](https://funcoding.ai/agents/openclaw/web/control-ui/chat/#send-and-history-semantics)
- <a id="talk-mode-browser-realtime" />[talk mode browser realtime](https://funcoding.ai/agents/openclaw/web/control-ui/chat/#talk-mode-browser-realtime)
- <a id="stop-and-abort" />[stop and abort](https://funcoding.ai/agents/openclaw/web/control-ui/chat/#stop-and-abort)
- <a id="abort-partial-retention" />[abort partial retention](https://funcoding.ai/agents/openclaw/web/control-ui/chat/#abort-partial-retention)
- <a id="strict" />[strict](https://funcoding.ai/agents/openclaw/web/control-ui/chat/#strict)
- <a id="scripts-default" />[scripts default](https://funcoding.ai/agents/openclaw/web/control-ui/chat/#scripts-default)
- <a id="trusted" />[trusted](https://funcoding.ai/agents/openclaw/web/control-ui/chat/#trusted)
- <a id="device-pairing-(first-connection)" />[device pairing (first connection)](https://funcoding.ai/agents/openclaw/web/control-ui/connect-and-pair/#device-pairing-(first-connection))
- <a id="pair-a-mobile-device" />[Pair a mobile device](https://funcoding.ai/agents/openclaw/web/control-ui/connect-and-pair/#pair-a-mobile-device)
- <a id="runtime-config-endpoint" />[Runtime config endpoint](https://funcoding.ai/agents/openclaw/web/control-ui/connect-and-pair/#runtime-config-endpoint)
- <a id="pwa-install-and-web-push" />[PWA install and web push](https://funcoding.ai/agents/openclaw/web/control-ui/connect-and-pair/#pwa-install-and-web-push)
- <a id="tailnet-access-(recommended)" />[tailnet access (recommended)](https://funcoding.ai/agents/openclaw/web/control-ui/connect-and-pair/#tailnet-access-(recommended))
- <a id="insecure-http" />[Insecure HTTP](https://funcoding.ai/agents/openclaw/web/control-ui/connect-and-pair/#insecure-http)
- <a id="blank-control-ui-page" />[Blank Control UI page](https://funcoding.ai/agents/openclaw/web/control-ui/connect-and-pair/#blank-control-ui-page)
- <a id="device-pairing-first-connection" />[Device pairing (first connection)](https://funcoding.ai/agents/openclaw/web/control-ui/connect-and-pair/#device-pairing-first-connection)
- <a id="tailnet-access-recommended" />[Tailnet access (recommended)](https://funcoding.ai/agents/openclaw/web/control-ui/connect-and-pair/#tailnet-access-recommended)
- <a id="list-pending-requests" />[list pending requests](https://funcoding.ai/agents/openclaw/web/control-ui/connect-and-pair/#list-pending-requests)
- <a id="approve-by-request-id" />[approve by request id](https://funcoding.ai/agents/openclaw/web/control-ui/connect-and-pair/#approve-by-request-id)
- <a id="open-mobile-pairing" />[open mobile pairing](https://funcoding.ai/agents/openclaw/web/control-ui/connect-and-pair/#open-mobile-pairing)
- <a id="connect-the-phone" />[connect the phone](https://funcoding.ai/agents/openclaw/web/control-ui/connect-and-pair/#connect-the-phone)
- <a id="confirm-the-connection" />[confirm the connection](https://funcoding.ai/agents/openclaw/web/control-ui/connect-and-pair/#confirm-the-connection)
- <a id="trusted-proxy-note" />[trusted proxy note](https://funcoding.ai/agents/openclaw/web/control-ui/connect-and-pair/#trusted-proxy-note)
- <a id="build-and-develop-the-ui" />[Build and develop the UI](https://funcoding.ai/agents/openclaw/web/control-ui/development/#build-and-develop-the-ui)
- <a id="debugging%2Ftesting%3A-dev-server-%2B-remote-gateway" />[debugging%2Ftesting%3A dev server %2B remote gateway](https://funcoding.ai/agents/openclaw/web/control-ui/development/#debugging%2Ftesting%3A-dev-server-%2B-remote-gateway)
- <a id="debugging/testing-dev-server-+-remote-gateway" />[debugging/testing dev server + remote gateway](https://funcoding.ai/agents/openclaw/web/control-ui/development/#debugging/testing-dev-server-+-remote-gateway)
- <a id="start-the-ui-dev-server" />[start the ui dev server](https://funcoding.ai/agents/openclaw/web/control-ui/development/#start-the-ui-dev-server)
- <a id="connect-the-remote-gateway" />[connect the remote gateway](https://funcoding.ai/agents/openclaw/web/control-ui/development/#connect-the-remote-gateway)
- <a id="origin-security-notes" />[origin security notes](https://funcoding.ai/agents/openclaw/web/control-ui/development/#origin-security-notes)
- <a id="feature-and-rpc-reference" />[Feature and RPC reference](https://funcoding.ai/agents/openclaw/web/control-ui/feature-reference/#feature-and-rpc-reference)
- <a id="chat-and-talk" />[chat and talk](https://funcoding.ai/agents/openclaw/web/control-ui/feature-reference/#chat-and-talk)
- <a id="channels-sessions-memory" />[channels sessions memory](https://funcoding.ai/agents/openclaw/web/control-ui/feature-reference/#channels-sessions-memory)
- <a id="cron-tasks-plugins-skills-devices-exec-approvals" />[cron plugins skills devices exec approvals](https://funcoding.ai/agents/openclaw/web/control-ui/feature-reference/#cron-tasks-plugins-skills-devices-exec-approvals)
- <a id="config" />[config](https://funcoding.ai/agents/openclaw/web/control-ui/feature-reference/#config)
- <a id="usage" />[usage](https://funcoding.ai/agents/openclaw/web/control-ui/feature-reference/#usage)
- <a id="debug-logs-update" />[debug logs update](https://funcoding.ai/agents/openclaw/web/control-ui/feature-reference/#debug-logs-update)
- <a id="automations-panel-notes" />[automations panel notes](https://funcoding.ai/agents/openclaw/web/control-ui/feature-reference/#automations-panel-notes)
- <a id="connection-loss-and-reconnect" />[Connection loss and reconnect](https://funcoding.ai/agents/openclaw/web/control-ui/offline-and-reconnect/#connection-loss-and-reconnect)
- <a id="openclaw-system-care" />[OpenClaw system care](https://funcoding.ai/agents/openclaw/web/control-ui/panels/#openclaw-system-care)
- <a id="home-dock" />[Home dock](https://funcoding.ai/agents/openclaw/web/control-ui/panels/#home-dock)
- <a id="operator-terminal" />[Operator terminal](https://funcoding.ai/agents/openclaw/web/control-ui/panels/#operator-terminal)
- <a id="browser-panel" />[Browser panel](https://funcoding.ai/agents/openclaw/web/control-ui/panels/#browser-panel)
- <a id="content-security-policy" />[Content security policy](https://funcoding.ai/agents/openclaw/web/control-ui/security-model/#content-security-policy)
- <a id="avatar-route-auth" />[Avatar route auth](https://funcoding.ai/agents/openclaw/web/control-ui/security-model/#avatar-route-auth)
- <a id="assistant-media-route-auth" />[Assistant media route auth](https://funcoding.ai/agents/openclaw/web/control-ui/security-model/#assistant-media-route-auth)
- <a id="approval-links" />[Approval links](https://funcoding.ai/agents/openclaw/web/control-ui/security-model/#approval-links)
- <a id="new-session-names" />[New session names](https://funcoding.ai/agents/openclaw/web/control-ui/sessions-and-sidebar/#new-session-names)
- <a id="new-session-preferences-and-recents" />[New-session preferences and recents](https://funcoding.ai/agents/openclaw/web/control-ui/sessions-and-sidebar/#new-session-preferences-and-recents)
- <a id="sidebar-navigation" />[Sidebar navigation](https://funcoding.ai/agents/openclaw/web/control-ui/sessions-and-sidebar/#sidebar-navigation)
- <a id="session-menu" />[Session menu](https://funcoding.ai/agents/openclaw/web/control-ui/sessions-and-sidebar/#session-menu)
- <a id="session-placement" />[Session placement](https://funcoding.ai/agents/openclaw/web/control-ui/sessions-and-sidebar/#session-placement)
- <a id="session-icons" />[Session icons](https://funcoding.ai/agents/openclaw/web/control-ui/sessions-and-sidebar/#session-icons)
- <a id="session-colors" />[Session colors](https://funcoding.ai/agents/openclaw/web/control-ui/sessions-and-sidebar/#session-colors)
- <a id="new-session-page" />[New session page](https://funcoding.ai/agents/openclaw/web/control-ui/sessions-and-sidebar/#new-session-page)
- <a id="start-a-native-coding-cli" />[Start a native coding CLI](https://funcoding.ai/agents/openclaw/web/control-ui/sessions-and-sidebar/#start-a-native-coding-cli)
- <a id="openclaw-chat-workspace-startup" />[OpenClaw Chat workspace startup](https://funcoding.ai/agents/openclaw/web/control-ui/sessions-and-sidebar/#openclaw-chat-workspace-startup)
- <a id="environment-identity" />[Environment identity](https://funcoding.ai/agents/openclaw/web/control-ui/settings/#environment-identity)
- <a id="community-invitation" />[Community invitation](https://funcoding.ai/agents/openclaw/web/control-ui/settings/#community-invitation)
- <a id="personal-identity" />[Personal identity](https://funcoding.ai/agents/openclaw/web/control-ui/settings/#personal-identity)
- <a id="gateway-host-status" />[Gateway host status](https://funcoding.ai/agents/openclaw/web/control-ui/settings/#gateway-host-status)
- <a id="language-support" />[Language support](https://funcoding.ai/agents/openclaw/web/control-ui/settings/#language-support)
- <a id="appearance-themes" />[Appearance themes](https://funcoding.ai/agents/openclaw/web/control-ui/settings/#appearance-themes)
- <a id="manage-plugins" />[Manage plugins](https://funcoding.ai/agents/openclaw/web/control-ui/settings/#manage-plugins)
- <a id="updates" />[Updates](https://funcoding.ai/agents/openclaw/web/control-ui/settings/#updates)
- <a id="apps-and-extensions" />[Apps and extensions](https://funcoding.ai/agents/openclaw/web/control-ui/settings/#apps-and-extensions)
- <a id="side-panel-keyboard-shortcuts" />[Side panel keyboard shortcuts](https://funcoding.ai/agents/openclaw/web/control-ui/settings/#side-panel-keyboard-shortcuts)
- <a id="this-mac-(macos-app)" />[This device (macOS and iOS apps)](https://funcoding.ai/agents/openclaw/web/control-ui/settings/#this-mac-macos-app)
- <a id="custom-plugin-ui" />[Custom plugin UI](https://funcoding.ai/agents/openclaw/web/control-ui/settings/#custom-plugin-ui)
- <a id="import-assistant-memory" />[Import assistant memory](https://funcoding.ai/agents/openclaw/web/control-ui/settings/#import-assistant-memory)
- <a id="mcp-page" />[MCP page](https://funcoding.ai/agents/openclaw/web/control-ui/settings/#mcp-page)
- <a id="activity-tab" />[Activity tab](https://funcoding.ai/agents/openclaw/web/control-ui/settings/#activity-tab)
- <a id="meetings-page" />[Meetings page](https://funcoding.ai/agents/openclaw/web/control-ui/settings/#meetings-page)
- <a id="this-mac-macos-app" />[This Mac (macOS app)](https://funcoding.ai/agents/openclaw/web/control-ui/settings/#this-mac-macos-app)

## Related

- [Dashboard](https://funcoding.ai/agents/openclaw/web/dashboard/) — gateway dashboard
- [Health Checks](https://funcoding.ai/agents/openclaw/gateway/health/) — gateway health monitoring
- [TUI](https://funcoding.ai/agents/openclaw/web/tui/) — terminal user interface
- [WebChat](https://funcoding.ai/agents/openclaw/web/webchat/) — browser-based chat interface
- [Codex session catalog and supervision](https://funcoding.ai/agents/openclaw/plugins/codex-supervision/) — the Native Session Discovery settings surface
