Commit Graph

3200 Commits

Author SHA1 Message Date
Peter Steinberger 3ffd0ac8d8 fix: show catalog pagination failures (#106518)
* fix(ui): surface catalog pagination failures

* test(ui): scope catalog retry assertion
2026-07-13 09:32:52 -07:00
lwy-2 7becac8a70 fix(ui): clear pending Talk mark timers on stop (#105805)
* fix(ui): clear pending Talk mark timers

Co-authored-by: WenyuanLee <li.wenyuan2@xydigit.com>

* refactor(ui): keep Talk relay within LOC budget

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-13 09:21:08 -07:00
Peter Steinberger bf7131a2c2 improve(ui): redesign managed worktrees list as status-chip rows (#106514)
Replaces the Settings -> Worktrees column grid (which collapsed to unlabeled
stacked cells at common window widths) with list-item rows: name + status
chip, repo/branch/owner meta line, right-aligned last-active + actions.
Rows sort by most recent activity. Deletes the now-unused generic .table
CSS family and stale column-header i18n keys.
2026-07-13 09:20:40 -07:00
Peter Steinberger 6ec75967b0 refactor(ui): reuse shared record normalization (#106472) 2026-07-13 09:16:25 -07:00
Peter Steinberger 8898118422 Merge pull request #106535 from openclaw/codex/privatize-ui-settings-exports 2026-07-13 17:03:33 +01:00
Peter Steinberger 21a59dfcf7 refactor(ui): privatize settings internals 2026-07-13 17:00:06 +01:00
Peter Steinberger aa5cb8c423 refactor(ui): remove dead Skill Workshop handoff styles (#106486) 2026-07-13 08:56:53 -07:00
Peter Steinberger abf4e86ea6 fix(ui): align settings page headline with the content column (#106521)
The settings shell capped page headers at 1120px while narrow settings
pages use a 760px column, leaving the title floating left of the
content. The header now adopts the column width of the page below it
(760px default, 1120px for wide pages); fill-height surfaces without a
settings-page column are unchanged.
2026-07-13 08:51:42 -07:00
Peter Steinberger 2ac723282c refactor(ui): unified settings design language across all Control UI settings surfaces (#106470)
* feat(ui): add settings design-language foundation (tokens, settings.css, helpers)

* refactor(ui): move settings workspace shell styles into settings.css

* refactor(ui): migrate all settings surfaces to the unified settings design language

Every settings surface (General quick+advanced schema form, Appearance,
Communications, Automation, MCP, Infrastructure, AI Agents, Channels,
Connection, About, Profile, Model Providers, Plugins, Skills, Skill
Workshop chrome, Devices, Worktrees, Debug, Logs, Activity, Automations,
Sessions, Usage chrome) now renders through the settings-ui helpers and
settings.css: sections as plain uppercase headings outside one flat
group surface, hairline-divided rows, a single toggle/segmented/status
vocabulary, status dots instead of pills, and no cards-in-cards or enter
animations. Deletes the qs-*/cfg-*/config-section-card/account-card/
plugins-row/cron-editor-card/session-badge/agent-pill families and
orphaned shared rules.

* style(ui-docs): format design-system docs

* fix(ui): make activity statusKind lookup exhaustive for consistent-return lint

* fix(ui): address settings design-language review findings

Label-wrapped toggle rows with required accessible names, named selects
and cron form controls, busy-disabled segmented controls with restored
theme-transition anchors, collapsible skill groups, semantic plugin
headings, gateway connected status, paired-devices empty state, logs
subtitle, cron prompt help, and keyboard-accessible session goal
objectives.

* fix(ui): harden settings primitives per review round two

Wrap row action clusters, fully-inset nav focus ring, restore number
steppers in the schema form, cap node capability lines, keep the named
Activity region landmark, and associate cron help text via the row
label.

* fix(ui): skip empty section headings and fix the toggle doc example

* docs(ui): import renderSettingsToggleRow in the settings example

* fix(ui): rename number stepper delta to avoid shadowing
2026-07-13 08:40:58 -07:00
Jason (Json) b32f59c8c1 feat(ui): create catalog sessions from the sidebar (#105810)
* feat(ui): create sessions from catalog headers

* fix(ui): deduplicate catalog-owned sessions

* fix(ui): preserve catalog session routing state

* fix(ui): keep per-agent session creation in switcher

* fix(anthropic): normalize runtime config snapshot

* test(plugin-sdk): account for model runtime export

* test(plugin-sdk): classify current deprecated surface

* test(ui): follow agent chip menu trigger

* fix(ui): bind catalog drafts to validated agent

* fix(ui): resolve catalog targets from gateway

* refactor(ui): split sidebar session helpers

* chore(ci): complete LOC baseline migration

* fix(ui): extract sidebar session catalog rendering

* fix(anthropic): use provider-relative catalog model id

* chore(ci): ratchet sidebar LOC baselines

* test(ui): cover catalog draft retargeting

* chore(plugin-sdk): refresh API baseline

* style: format catalog session changes

* fix(ui): retry catalog drafts after reconnect

* fix(ui): back off catalog target retries

* fix(ui): keep unresolved catalog drafts locked

* fix(ui): gate catalog creation in core

* fix(ui): keep catalog renderer private

* style(ui): format catalog session target

* chore(plugin-sdk): refresh API baseline

* style(ui): format catalog group state

* Merge latest origin/main CI fixes

* fix(ui): preserve catalog session agent selection

* fix(ui): preserve catalog session agent

* chore(plugin-sdk): refresh API baseline

* fix(ui): type catalog route data

* chore(plugin-sdk): refresh API baseline

* refactor(sessions): centralize transcript path archival

* fix(ui): target expanded agent catalog sessions

* fix(ui): scope catalog actions to expanded agent

* docs(ui): clarify catalog loader fallback

* fix(ui): scope catalog pagination to agent

* test(ui): type sidebar lifecycle refresh

* fix(anthropic): preserve node catalog bindings
2026-07-13 09:25:22 -06:00
Peter Steinberger f110687cfe refactor(ui): align plugin filter chips with the hub tab strip (#106168)
* refactor(ui): align plugin filter chips with the hub tab strip

Drop the segmented inventory meter above the installed filters and
restyle the filter chips to match the tab strip above them: same
radius, hover, active fill, and count badges. Removes the unused
pluginsPage.pulseLabel key and prunes generated locales.

* ci: trigger PR checks
2026-07-13 08:00:35 -07:00
Peter Steinberger 111e84af43 fix: show Sessions custom-group failures (#106451)
* fix(ui): surface Sessions group mutation failures

* refactor(ui): split session group mutation helpers
2026-07-13 07:52:08 -07:00
Shakker ee80377a22 fix: keep lobster pet above sidebar footer (#106457) 2026-07-13 15:49:48 +01:00
Peter Steinberger 471f60bc84 fix: show sidebar session action failures (#106435)
* fix(ui): surface sidebar session mutation failures

* test(ui): type sidebar session patch mock
2026-07-13 07:04:13 -07:00
Peter Steinberger 879ed1d859 fix(ui): make tabs, dialogs, and skill cards keyboard accessible (#106320)
* fix(ui): improve keyboard accessibility

* fix(ui): remove unused toggle event

* docs(changelog): note control UI keyboard access

* chore(ui): keep release note in PR body

* chore(ui): translate accessibility labels
2026-07-13 06:20:14 -07:00
wuqxuan 94f018caad fix(ui): preserve sidebar collapsed state when group rename/delete fails (#106152)
* fix(ui): preserve sidebar collapsed state when group rename/delete fails

* test(ui): cover group rename/delete rejection error publish

* fix(ui): harden session group mutations

* fix(ui): guard group mutations across reconnects

* fix(ui): keep session group result internal

* style(ui): format sidebar tests

* fix(ui): preserve confirmed group mutations

* chore: keep release notes out of contributor PR

* style(ui): refresh session test formatting

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-13 06:13:58 -07:00
Peter Steinberger df3fe6a4f2 feat(worktrees): configurable cleanup limits (max count, max total size) with Settings UI (#106224)
Config surface worktrees.cleanup.{maxCount,maxTotalSizeGb} (0/unset disables),
enforced by hourly gc, worktrees.gc RPC, and openclaw worktrees gc: least
recently active session/Workboard worktrees are snapshotted and removed until
count and total size fit. Manual worktrees, live locks, run leases, and active
session owners are never limit-evicted. Settings -> Worktrees gains a Cleanup
section with debounced, quota-aware stepper controls. Closes #106213.
2026-07-13 06:00:33 -07:00
Peter Steinberger f87a74602a refactor(gateway): simplify canonical WebSocket client (#106316)
* refactor(gateway): simplify canonical websocket client

* refactor(gateway): keep protocol options internal
2026-07-13 05:34:57 -07:00
Peter Steinberger 5922027b9f improve(ui): fold agent-menu help links into a Help submenu (#106191)
* feat(ui): fold agent-menu help links into a Help flyout

Docs, Get help, Discord community, and View changelog move from
top-level agent-menu rows into a Help flyout submenu (hover on mouse,
click elsewhere; right/left/overlay placement by available space).

* chore(ui): translate agentChip.help across locales
2026-07-13 05:18:04 -07:00
Peter Steinberger 882b2fe900 feat(channels): bundle Reef guarded claw-to-claw channel (#106232)
* feat(channels): bundle Reef guarded claw-to-claw channel

Moves the Reef channel extension from openclaw/reef into the bundled extensions tree with the wire protocol vendored under extensions/reef/protocol. Includes channelConfigs manifest metadata, runtime status reporting via setStatus/buildAccountSnapshot, abort-aware inbox shutdown, monotonic device-auth timestamps, and immutable-model guard admission (dated snapshots plus documented gpt-5.6 ids).

* fix(reef): pin zod exactly per dependency pin guard

* style(reef): satisfy extension lint gates

Curly braces in vendored protocol, explicit type re-exports, typed catch callbacks, Object.assign over map-spread, abort-aware loop restructure.

* fix(reef): CI gates — knip workspace, boundary tsconfig, facade imports, cycle break, contract baselines

- knip: reef workspace project includes vendored protocol/ (owns noble deps)
- tsconfig: conform to canonical extension package-boundary include/exclude; add @openclaw/plugin-sdk devDependency
- imports: channel-inbound/channel-outbound facades instead of deprecated subpaths
- protocol: home ReplayStore contract in envelope.ts to break the envelope<->replay type cycle
- baselines: reef in unguarded runtime-api list; regenerate bundled channel config metadata

* feat(reef): plugin catalog cover art, channel label, changelog revert

* fix(reef): drop unused error-class exports, register lint suppression

* fix(reef): knip entry surface for vendored protocol, explicit WebSocketLike export
2026-07-13 05:17:44 -07:00
Peter Steinberger 6c5084f1ad feat(xai): add realtime voice provider (#106267)
* feat(xai): add realtime voice provider

Co-authored-by: Vitor Cepeda Lopes <vitor@vitorcepedalopes.com>

* fix(xai): satisfy realtime voice validation

* fix(xai): harden realtime relay boundaries

* chore: drop release-owned changelog edit

* chore(i18n): refresh native voice catalogs

* chore(i18n): refresh Control UI raw-copy baseline

* chore(plugin-sdk): refresh API baseline hashes

* chore(i18n): use canonical main catalogs

* chore(i18n): refresh realtime voice source inventory

* chore: refresh xai voice landing head [skip ci]

* chore: refresh integrated protocol artifacts [skip ci]

---------

Co-authored-by: Vitor Cepeda Lopes <vitor@vitorcepedalopes.com>
2026-07-13 05:17:24 -07:00
Peter Steinberger 3e21c2f256 feat(ui): dismissible sidebar attention chips (#106223)
* feat(ui): dismissible sidebar attention chips

* fix(ui): use toSorted for attention signatures

* refactor(ui): move attention dismissal store to its own module

* fix(ui): make attention dismissals safe across tabs

* style(ui): drop redundant String() in storage mock

* fix(ui): prune dismissals only after fresh data and key overdue snoozes by incident
2026-07-13 05:11:59 -07:00
Peter Steinberger 200103a72b fix(ci): remove chat test export debt 2026-07-13 13:11:35 +01:00
Peter Steinberger a03df5fd58 fix(ci): stamp event envelope type in chat-state test 2026-07-13 05:01:04 -07:00
Peter Steinberger bd2be839ce fix(ci): update route and agents page tests for agent selection scope 2026-07-13 04:52:11 -07:00
Peter Steinberger 497662f0fc perf(ui): batch streaming chat renders (#106353) 2026-07-13 04:44:39 -07:00
Peter Steinberger 8f7df1b94b fix(ci): stub agent selection in gateway source replacement test context 2026-07-13 04:41:45 -07:00
Peter Steinberger 418dd85e66 improve: speed up focused test execution (#106307)
* test: speed up focused test execution

* style: format vitest config test

* test: preserve targeted watch routing
2026-07-13 04:38:05 -07:00
Peter Steinberger cad6df0a7c fix(ui): trim unused export surface 2026-07-13 12:35:26 +01:00
Peter Steinberger a487d6b41d improve(ui): lazy-load MCP Apps chat bridge (#106288)
* perf(ui): lazy-load MCP Apps bridge

* test(ui): align lazy MCP Apps checks
2026-07-13 04:05:57 -07:00
Peter Steinberger 9086389527 feat(control-ui): agent identity editor, Settings-homed Agents page, scalable chip switcher (#106058)
* feat(control-ui): agent identity editor, settings-homed agents page, chip switcher pinning

* test(control-ui): pinned-agent persistence coverage; persist pins only when set

* refactor(control-ui): split agent menu, identity actions, model staging out of oversized files

* chore(i18n): sync control-ui locale bundles for agent identity/switcher keys

* fix(control-ui): stabilize new sidebar switcher tests; ratchet LOC + export baselines

* chore(review): document identity clear limitation; drop unused export

* feat(control-ui): scope pages to selected agent

* fix(control-ui): keep scoped page state consistent

* docs(control-ui): explain shared agent scope

* fix(control-ui): reconcile agent scope with current ui

* fix(control-ui): preserve complete agent filtering

* fix(control-ui): bound uploaded agent avatars

* test(control-ui): keep pinned-route fixture valid

* test(control-ui): keep pinned-route fixture valid

* chore(i18n): sync locale bundles for agent scoping keys
2026-07-13 04:03:26 -07:00
Peter Steinberger e0e0394d05 refactor(ui): remove dead export seams (#106220) 2026-07-13 03:54:00 -07:00
Peter Steinberger a17058d191 feat(usage): show the account email with plan windows in the chat context popover (#106200)
* feat(usage): surface plan windows and account email in the chat context popover

The context-window popover now shows which account a session runs on:
provider usage snapshots carry an accountEmail resolved from the auth
profile when stored, the ChatGPT access-token JWT claims (openai/codex),
or the Claude CLI config file (~/.claude.json oauthAccount) for
keychain-synced logins. models.authStatus embeds it, quota groups keep
distinct accounts separate, and the popover renders the email under the
plan header for local CLI sessions and OpenClaw-configured subscriptions
alike.

* test(openai): assemble the fake usage JWT from parts

* test(usage): keep fixture tokens and identity plumbing scanner-safe

* fix(usage): verify the Claude CLI login before labeling usage with its email

Review findings: the CLI-config email fallback now requires the usage token
to match the cached CLI credential (and honors CLAUDE_CONFIG_DIR), so an
ambient login for another account never labels a snapshot; token-type
credentials propagate their stored email alongside oauth ones.

* style(anthropic): scanner-safe local for the CLI login read

* fix(usage): capture the Claude CLI account email on the credential

Review findings: reading ambient CLI config at usage-fetch time could not
verify keychain-only logins and could go stale across account switches.
The credential reader now captures oauthAccount.emailAddress next to the
credential it belongs to, the synced claude-cli profile carries it, and
the anthropic fetcher uses only the credential-borne identity.

* style(usage): scanner-safe credential fixtures and helper naming

* fix(auth): backfill the CLI account email onto existing synced profiles

Profiles synced before identity capture stay usable and skip CLI reads,
so upgraded installs would never gain the email until token rotation.
While the stored token material matches the CLI login, merge the
non-secret email onto the stored profile.

* style(test): scanner-safe email assertion

* test(auth): pin the no-reread invariant to identity-complete profiles
2026-07-13 03:39:16 -07:00
Peter Steinberger 62e53919fd improve(ui): move Devices into Settings and redesign the device inventory (#106055)
* feat(ui): move Devices page into settings and redesign device inventory

- Devices now lives at /settings/devices (System group); /nodes stays as alias
- per-device form-factor icons (phone/browser/terminal/machine) with status dot
- equal-height header actions; stale cleanup and pairing only
- drop manual Refresh button; page already auto-refreshes via presence events + 30s poll
- dynamic connected/pending summary replaces static card subtitle

* style(ui): oxfmt pass + loading empty state for devices inventory

* chore(ui): sync locale bundles for devices settings copy; docs point at Settings → Devices

* refactor(ui): split device tile + pending rows out of view-inventory; drop unused icons

Keeps the TypeScript LOC ratchet green: view-inventory.ts returns below its
baseline and icons.ts sheds unused folderOpen/micOff/volumeOff glyphs.

* fix(ui): ratchet LOC baseline, drop unused DeviceIconSource export, settle devices settings copy

- baseline: icons.ts 693, view-inventory.ts back under the 500 ceiling
- subtitles.nodes now describes the settings page; nav tests updated
- locale bundles resynced (fallbacks=0)

* refactor(ui): rename token row param for reviewer-tool clarity

* fix(ui): collapse device rows in narrow containers and classify the TUI as a terminal client

Review findings: the nodes-entry grid override beat the shared 560px
list-item collapse, overflowing phone-width rows; openclaw-tui connects
with mode ui so only its client id marks it as a terminal.

* chore(ui): translate pending locale keys after rebase (fallbacks=0)
2026-07-13 03:18:17 -07:00
Peter Steinberger d65ec597a1 improve(ui): restyle composer send button as filled accent circle (#106046)
* feat(ui): restyle composer send button as filled accent circle

The send button was an outline ghost (transparent bg, 1px accent border,
outlined paper plane) while every other primary action uses the solid
.btn.primary fill. Send now matches: solid accent circle, white arrow-up
glyph, accent-hover + glow on hover, muted fill when disabled. Stop and
voice variants drop their borders and escalate via fill strength instead.

* fix(ui): keep send button focus ring visible under hover

Hover rules now set box-shadow and out-specify :focus-visible, so a
box-shadow focus ring vanished for keyboard users hovering the control.
Use an offset outline instead; hover shadows cannot override it.

* chore(ui): compact arrow icons to satisfy TS LOC ratchet

icons.ts is over the 500-line ratchet cap, so the new arrowUp entry
must not grow the file; merge each arrow's two paths into one
(identical rendering) for a net -4 lines.
2026-07-13 03:17:16 -07:00
Peter Steinberger b395dfca85 improve(ui): load optional shell surfaces on demand (#106243)
* perf(ui): lazy-load optional shell surfaces

* fix(ui): align lazy shell static contracts
2026-07-13 03:15:00 -07:00
Peter Steinberger 7c9b8baa2b refactor(gateway): consolidate TypeScript WebSocket clients (#106113)
* refactor(gateway): unify websocket clients

* fix(gateway): preserve adapter lifecycle behavior

* test(gateway): keep reconnect proof black-box

* chore(gateway): satisfy shared client lint

* refactor(gateway): keep protocol decisions internal

* refactor(gateway): preserve shared reconnect supervision

* test(gateway): use canonical browser barrel

* fix(gateway): resolve browser retry workspace source

* refactor(gateway): tighten shared protocol types
2026-07-13 03:08:21 -07:00
Peter Steinberger 938d41014f feat(mobile): default pairing to full node access (#105928)
* feat(mobile): default pairing to full node access

* chore: leave release notes to release workflow

* refactor(mobile): bound pairing helpers

* chore(i18n): refresh mobile access inventory

* chore(ci): lower mobile pairing LOC baseline

* fix(mobile): complete pairing validation artifacts

* ci: remove stale transcript target export baseline

* fix(ios): wrap access upgrade guidance

* fix(ios): preserve localized access key

* fix(ci): dedupe read-only SQLite guardrail

* fix(mobile): secure full-access node setup
2026-07-13 02:30:45 -07:00
Vincent Koc c43c960aad refactor(ui): trim private realtime type exports (#106221) 2026-07-13 17:27:01 +08:00
Peter Steinberger d280c20aab fix(ui): simplify Settings titlebar controls (#106228)
* fix(ui): simplify Settings titlebar controls

* chore(ui): leave release notes to release flow
2026-07-13 02:25:17 -07:00
Peter Steinberger 95d9457465 fix(ui): preserve worktree mutation errors (#106196) 2026-07-13 02:24:33 -07:00
Peter Steinberger 8e0c82ba0a fix(ui): stroke new-session target icons instead of black fills (#106193) 2026-07-13 02:18:18 -07:00
Peter Steinberger 5daeb86570 test(ui): fix Workboard sidebar E2E timeout (#106160) 2026-07-13 02:13:14 -07:00
openclaw-mantis[bot] ea5758dd13 chore(ui): refresh control ui locales (#106214)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-13 02:07:43 -07:00
Peter Steinberger a8ae27fd35 fix(ui): drop duplicated runNotStarted locale blocks
Two UI PRs landed near-simultaneously and their generated locale syncs
each carried a runNotStarted block, breaking check-prod-types (TS1117
duplicate object keys) in all 20 generated locales. en.ts was correct.
Keep the newer block (TS last-wins, so this is the already-live text).
2026-07-13 02:01:30 -07:00
Peter Steinberger dc89ee258e improve(ui): replace the chat settings popover with a composer view menu (#105904)
The composer gear popover mixed misplaced, mislabeled, and dead controls.
Replace it with a three-row View menu (Reasoning, Tool calls, Keep
commentary); drop the manual-refresh machinery and the auto-scroll modes
(near-bottom stays the only behavior); move the cron-session filter to the
sidebar sort menu as a working persisted toggle; move the send shortcut and
microphone picker to Settings -> Appearance -> Chat; delete the ephemeral
voice/model/sensitivity overrides in favor of the server talk config.
Settings keep an in-memory fallback when localStorage is blocked, and talk
sessions re-read persisted settings at launch.
2026-07-13 01:41:00 -07:00
Peter Steinberger e460ad1536 feat(control-ui): one-row automations toolbar, failing drill-down, visible row actions (#106044)
* feat(control-ui): redesign automations toolbar, stats, and row actions

* refactor(control-ui): split cron run-history rendering into view-runs

* refactor(control-ui): leaf props contract for cron run-history module

* chore(i18n): reconcile locale metadata after rebase
2026-07-13 01:40:48 -07:00
Peter Steinberger 1eb3956355 fix(ui): hide empty native session categories (#106119)
* fix(ui): hide empty native session categories

* docs(changelog): note hidden empty session groups

* chore: keep changelog release-owned

* fix(ui): preserve native catalog errors

* style(ui): format session catalog renderer
2026-07-13 01:33:28 -07:00
Peter Steinberger bae913ba0c fix(ui): retry session group catalog loads (#106169) 2026-07-13 01:29:45 -07:00
Peter Steinberger 8c740891e1 perf(ui): load page styles with lazy routes (#106183)
* perf(ui): load page styles with lazy routes

* fix(ui): preserve shared styles across lazy routes

* chore(ui): keep release note in PR
2026-07-13 01:28:40 -07:00