Commit Graph

3179 Commits

Author SHA1 Message Date
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
Peter Steinberger
b9ab918354 feat(ui): surface still-running background tasks after the chat turn settles (#106115)
Control UI chat now keeps still-running background tasks visible after the agent turn settles: a status row above the composer shows the claw glyph parked nose-down (static, opacity breath only), a live elapsed time with tabular digits so the row never shifts, and a "1 running task"/"N running tasks" link that opens the background-tasks rail. The row hides while the agent is working, while disconnected, and once the last task finishes. Reuses the pane's existing tasks.list snapshot and live task events — no new polling or RPC. Includes a mock-dev-harness running-task fixture and generated locale translations for the two new strings.

Closes #106107

Evidence: focused suites green on Blacksmith Testbox (chat-background-tasks 16 tests, chat-view 185 tests); live mock-gateway verification with screenshots on the PR; autoreview (gpt-5.6-sol, xhigh) clean after fixing its two findings (aria-hidden ticking timer, disconnected suppression).
2026-07-13 01:25:56 -07:00
Peter Steinberger
d3f6d63fec feat(ui): surface self-learning toggle in the Skill Workshop tab (#106093)
Surfaces skills.workshop.autonomous.enabled in the Control UI Workshop tab:
a Self-learning header toggle plus an enable pitch card on the empty
proposal board. Reads the include-resolved config snapshot, patches the
canonical key over the existing runtimeConfig RFC 7396 merge-patch seam,
and surfaces patch failures in the workshop error banner. Copy states the
token cost and that drafts arrive as pending proposals (no unconditional
review guarantee, which would be false under approvalPolicy "auto").
Splits workshop empty states, header controls, and the self-learning
module out of the oversized page/view files. Locale bundles synced
(fallbacks=0 across 20 locales).

Closes #106054
2026-07-13 00:54:14 -07:00
Peter Steinberger
c2521d7c47 fix(ui): catalog sessions select in place and continue from desktop-app sources (#106074)
* fix(ui): make catalog sessions selectable in place and continuable from desktop-app sources

- sidebar: no phantom chat row for catalog keys, active highlight on catalog rows,
  adopted sessions render as their live row inside the catalog group (deduped from
  the regular list), host subtitle only for paired-node rows
- chat: view-only banner only after catalog metadata proves canContinue=false
- chat->sidebar continued event binds the adopted row before the next catalog poll
- anthropic: local claude-desktop sessions share the ~/.claude/projects store, so
  list them as continuable and allow catalog continue to fork-resume them

* refactor(ui): extract catalog row rendering and lookup into shared modules

Keeps app-sidebar/chat-pane/anthropic session-catalog under the LOC ratchet by
moving cohesive blocks: sidebar catalog groups + adopted-row binding into
app-sidebar-session-catalogs.ts, the catalog metadata lookup into
catalog-key.ts, and the Claude node-host commands into
session-catalog-node-commands.ts; ratchet baselines down for all three.

* fix(ui): explain the disabled composer when catalog metadata cannot resolve a session

* style(ui): keep chat-pane within the LOC ratchet

* fix(anthropic): keep catalog node-command helpers module-local and repin SDK surface

The node-command module now owns its capability constant, projects-store
probe, and params parsing, so the catalog engine exports nothing new.
Repin the SDK surface budgets (+1 export/+1 callable landed on main
without a pin bump); unexport the UI helper types knip flagged.
2026-07-13 00:49:35 -07:00
Peter Steinberger
e168443123 refactor(ui): direct enable/disable and remove actions on plugin cards (#106040)
* refactor(ui): direct enable/disable and remove actions on plugin cards

Replace the state chip + kebab menu on plugin cards, installed rows,
ClawHub results, and MCP server rows with a direct Enable/Disable
button and a trash icon for removable entries. Drop the redundant
'View details' menu item (the whole card opens details) and delete the
now-unused menu machinery, document listeners, and CSS.

* style: oxfmt plugins-page test helper

* chore(i18n): prune removed pluginsPage menu keys from locale bundles
2026-07-13 00:38:35 -07:00
Peter Steinberger
da6221d08e test: speed timing-sensitive UI and process suites (#105882)
* test: replace fixed waits with controlled time

* fix(ci): scope LOC ratchet to changed files

* fix(ci): stabilize changed-file ratchets

* test: stabilize sidebar session checks

* test(ui): isolate retained runtime modules

* test(ui): align streaming markdown assertions
2026-07-13 00:35:19 -07:00
Peter Steinberger
afe907f8f5 improve(ui): friendlier panel load error state with reload prompt for stale chunks (#106033) 2026-07-13 00:34:32 -07:00
Peter Steinberger
5d86f9dcaf fix(ui): allow session creation during refresh (#106045) 2026-07-13 00:34:12 -07:00
Peter Steinberger
73da94f06f improve(ui): move Sessions from the sidebar More menu into Settings (#106032)
Sessions is session management, not a day-to-day workspace destination.
It now lives in Settings under Agents & Tools at /settings/sessions,
with the old /sessions path kept as a route alias; stale pinned-route
prefs drop automatically via normalizeSidebarPinnedRoutes. Also repairs
the sidebar-customization e2e that #105777 broke on main by opening
Settings through the agent-chip menu.
2026-07-13 00:30:20 -07:00
Peter Steinberger
b2b87e956e fix(macos): center dashboard traffic lights with the hosted titlebar buttons (#106099)
* fix(macos): center dashboard traffic lights with the hosted titlebar buttons

Give the dashboard window an empty unified toolbar so its titlebar grows
to 52pt, vertically centering the macOS traffic lights against the row of
web-hosted titlebar buttons (sidebar toggle, back/forward) instead of
hugging the top edge. Bump the injected --openclaw-native-titlebar-height
to match, and nudge the hosted controls' left offset from 78px to 92px so
the traffic-light cluster and the first web button read as separate groups.

The toolbar exists only to size the titlebar, so View > Hide Toolbar (and
the corresponding shortcut) are refused; hiding it would collapse the
titlebar while the web inset stays pinned at 52pt, resurrecting the
misalignment. Smoke tests cover toolbar presence/style, hide refusal, and
the exact injected height.

* chore(i18n): resync native inventory line metadata
2026-07-13 00:17:13 -07:00
Peter Steinberger
b5273e78d6 fix(ui): restore app-sidebar content with IconName type import
The previous commit accidentally truncated app-sidebar.ts to an empty
file while fixing the missing IconName import from #105850. This
restores the full component with the corrected icons import.
2026-07-13 00:15:43 -07:00
Peter Steinberger
08843c74de fix(ui): restore IconName type import in app-sidebar
#105850 added AGENT_MENU_LINKS typed with IconName without importing
the type, breaking check-prod-types/check-test-types on main.
2026-07-13 00:14:34 -07:00
Peter Steinberger
3c30634de4 fix(ui): order model-dependent chat settings (#106095)
* fix(ui): order model-dependent chat settings

* fix(ui): serialize picker model transitions

* chore: remove release-owned changelog edit
2026-07-13 00:08:15 -07:00
Peter Steinberger
cb1b5779ea feat(ui): docs, help, Discord, and changelog links in the agent chip menu (#105850)
* feat(ui): docs, help, Discord, and changelog links in the agent chip menu

* chore(i18n): normalize locale bundle metadata after rebase

* refactor(ui): move the agent menu links into the nav-menus module for the LOC ratchet

* Revert "refactor(ui): move the agent menu links into the nav-menus module for the LOC ratchet"

This reverts commit 0e4d72f4c6.
2026-07-13 00:05:42 -07:00
Peter Steinberger
adf6b08ab4 refactor: consolidate duration parsing and formatting (#105988)
* refactor: consolidate duration handling

* docs: leave release notes to release workflow

* fix: preserve build timing precision

* ci: align plugin sdk surface budgets
2026-07-12 23:38:22 -07:00
Peter Steinberger
ab8cbfd73c fix(ui): allow manual folders on exec-only nodes (#106012)
* fix(ui): allow manual folders on exec-only nodes

* test(ui): type exec-node request params

* style(ui): format exec-node request assertion
2026-07-12 23:23:06 -07:00
Peter Steinberger
16fa19cd72 improve(control-ui): compress and cache bundled assets (#105890)
* perf(control-ui): compress bundled assets

* chore(control-ui): remove release-owned changelog edit

* fix(control-ui): release assets before compression

* refactor(control-ui): split static response helpers

* perf(control-ui): precompress bundled assets

* refactor(control-ui): keep encoding internals private

* chore(control-ui): refresh LOC baseline
2026-07-12 23:13:04 -07:00
Peter Steinberger
fcb45b4400 feat(ui): render streaming chat markdown live instead of plain text (#106062)
Streaming assistant replies in the Control UI now render markdown live: the in-flight tail is repaired with remend (zero-dep, Apache-2.0, extracted from Vercel's Streamdown) before the existing markdown-it + DOMPurify pipeline, and open code fences stream as live-highlighted code blocks. Deletes the plain-text streaming tail path (toStreamingPlainTextHtml) and extracts an uncached render core so tail deltas stop churning the markdown LRU cache. Closes #106053
2026-07-12 23:11:45 -07:00
Peter Steinberger
03d4b05593 style(ui): format tool card tests 2026-07-13 02:05:04 -04:00
Peter Steinberger
bebcf52d23 ci: isolate Control UI tool card tests 2026-07-13 02:00:58 -04:00
Jason (Json)
30cbc1118a fix(ui): keep restored prompts visible during runs (#106001) 2026-07-12 23:55:53 -06:00
Peter Steinberger
e4a17ee160 refactor(ui): split Workboard controller modules (#105995)
* refactor(ui): split Workboard controller modules

* chore(ui): track moved Workboard export

* chore(ui): avoid unrelated LOC baseline validation

* ci: refresh TypeScript LOC baseline

* ci: drop stale transcript export baseline
2026-07-12 22:55:07 -07:00