Queue position becomes an explicit, operator-owned fact on ChatQueueItem
instead of an accident of arrival time and storage array order. One
comparator now serves the visible projection, the drain head selection,
the steer rebuild, and the alias merge, so what the composer shows is
what the Gateway receives.
Reordering lives entirely on one handle at the left of a queued row:
drag it, or focus it and press the arrow keys. Keyed rows keep focus on
the handle as it moves. Rows already handed to a run keep their place.
Also routes .chat-image-action through var(--cursor-action); its
hardcoded pointer was failing the cursor-policy test on main.
* feat(ui): mark GitHub links in Control UI chat
Chat markdown anchors pointing at github.com now carry a decorative GitHub mark before their text, so a bare URL and a [#3434] shorthand read as the same destination. The mark is painted from the bundled brand path through a CSS mask on currentColor: it stays out of the accessibility tree and out of copied text, tracks the chat text size, and follows the link color in every theme. Image-only links such as badges and code spans stay undecorated.
* feat(ui): break long autolinked URLs at any character in chat
An autolinked URL is one unbreakable word, so the inherited overflow-wrap only splits it after every other option is exhausted: a long URL was pushed whole onto the next line, and with the new GitHub mark ahead of it the mark was left stranded alone at the end of the previous line. Autolinked anchors now carry markdown-bare-url and get unconditional character break opportunities, so the URL fills the line it starts on. Authored link labels keep word-boundary wrapping.
* fix(ui): drop resting underline on chat GitHub links
* test(ui): split markdown link tests into a sibling file
markdown.test.ts crossed the 1000-line oxlint budget once the GitHub-link
cases landed. Move the link-rendering describes (autolinks, explicit
protocol links, file links, bare-url marks, GitHub marks) into
markdown-links.test.ts. Pure move; no assertion changes.
* test(ui): assert GitHub links rest without an underline
Covers the resting/hover decoration contract through the real rendered
page, and pins the rule's scope with a non-GitHub link that keeps the
base underline.
Give Control UI managed images bounded previews and shared full-image Open, Download, and Copy actions. Keep artifact access transcript-bound; the existing ticket is intentionally attachment-scoped to the lower-fidelity thumbnail.
Co-authored-by: Ittiz <github@daein.org>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
* feat(ui): add people session sorting
Offer People sorting in the Control UI session sidebar when the Gateway reports multiple session-sharing identities.
* fix(ui): restore sidebar translation dependency
* fix(ui): preserve session sort ordering contracts
* fix(gateway): close task terminals at run end
* refactor(agents): keep terminal task ownership internal
* test(gateway): type task-owned terminal fixtures
* test(infra): split agent run task ownership coverage
* fix(codex): pin catalog CODEX_HOME onto terminal resume spawns
The Codex session catalog lists threads through the plugin's supervision
app-server connection, which can run on the agent-scoped Codex home
(homeScope: "agent"). The terminal resume plan spawned a bare
'codex resume <threadId>' under the operator login shell, so the CLI
resolved its default ~/.codex and failed with "No saved session found".
Terminal plans now carry the catalog connection's CODEX_HOME (local and
paired-node paths), the gateway merges plan env into the PTY spawn, and
the triplicated home-scope resolution collapses into one shared
resolveCodexAppServerLocalHomeDir.
* feat(ui): add main-content terminal placement
The terminal panel gains a third dock placement, "main", filling the
content region next to the sidebar like the transcript pane. The panel
header gets a bottom/right/main placement switcher (persisted in the
existing openclaw.terminal.panel.v1 store), and opening a Codex/Claude
session from the session catalog selects main mode so resumed sessions
appear as a full window instead of a bottom strip.
Remove the localStorage-backed per-browser hide action ("Hide in this browser only") so the transcript mirrors agent context. The action was un-undoable because restore() had no UI path.
Stale openclaw:deleted:* localStorage keys become inert.
* improve(ui): consolidate dashboard chat visibility into one Chat/Split/Dashboard toggle
The dashboard face spread chat visibility across three separate
affordances: a two-option face toggle, an icon-only dock dropdown among
the header actions, and a floating vertically-rotated "Show chat"
button on the board edge that users could not discover. One concept,
three controls.
The header now renders a single segmented control - Chat | Split |
Dashboard - where Split is dashboard plus docked chat and Dashboard is
board-only (the former "Hide chat"). A compact caret attached to the
pill picks the dock side (left/right/bottom) and only appears in Split
mode when dock mutation is allowed; read-only sessions keep the plain
two-option Chat | Dashboard toggle. The floating reopen button, the
standalone dock menu button, and their CSS (including the mobile
overrides) are deleted, so the header ends up with fewer buttons than
before.
Verified in the mock-gateway dev harness: mode mapping, caret dropdown,
unhide-to-remembered-side, and hidden dock rendering board-only.
* fix(ci): unexport board dock settings union and repair stale plugin-sdk baseline
BoardVisibleChatDock lost its last external consumer when the board
view switch consolidated dock controls; keep it file-local so the
production unused-export scan stays clean.
Also regenerate docs/.generated/plugin-sdk-api-baseline.sha256: the
session-catalog module hash was stale on main (check fails on clean
origin/main after the agent-attribution reverts), which blocks every
PR's check-plugin-sdk-api-baseline job.
* docs(web): describe the Chat/Split/Dashboard switch and dock-side picker
* fix(ui): hide connection form during initial auth
Use the authoritative gateway connecting/error state so trusted-proxy, Tailscale, bootstrap, device, and token auth all keep the centered loading screen until the first handshake resolves. Real failures still reveal the login gate, manual retries stay pinned, and established reconnects retain the shell.
* fix(ui): preserve approval document login gate
Scope the neutral unresolved first-connect splash to the normal Control UI document. Standalone approval links continue to expose their authentication gate without losing the deep link, while embedded terminal behavior remains unchanged.
* feat(webchat): expand truncated assistant messages inline
Replace the per-message Open in canvas button with an inline Show more /
Show less disclosure on truncated assistant messages that fetches full
content via chat.message.get on demand.
* test(webchat): stabilize inline expansion e2e
* fix(ui): satisfy lint and export gates for inline show-more
* test(ui): update shared disclosure selector
---------
Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
* docs(automation): rename scheduled-tasks feature wording to Automations
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WhJ8EiMXue6ADLmHfb7FL6
* docs: regenerate docs map and add Automations glossary entries
* docs(templates): follow renamed automations-vs-heartbeat anchor
* docs(automation): fix markdown formatting drift
* docs(automation): teach the canonical automations tool and sync the copied heartbeat default
Review follow-ups: normal instructions use the automations tool with cron as
an explicit compatibility alias; every verbatim copy of the default heartbeat
prompt matches the new shipped text from the strings PR.
---------
Co-authored-by: Omar Shahine <10343873+omarshahine@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* fix(ui): rename the Memory Palace browser to Memory Wiki and document it
* refactor(memory-wiki): drop the old memory-palace module files
* docs: refresh generated docs map
* test(ui): align dream-diary hub-tab assertion with the wiki sub-tab id
* docs: describe memory wiki clustering behavior accurately
* docs(memory-wiki): record the wiki.overview rename decision at the registration site
* test(ui): query the Agents channels hub tab by tab role after the hub-tabs refactor
* refactor(ui): dissolve the General settings page into Appearance
* test(ui): drop dissolved config route expectation
* test(ui): cover legacy General model redirect
* style(ui): format legacy redirect test