Commit Graph

364 Commits

Author SHA1 Message Date
Peter Steinberger
b550c2cf9a feat(ui): add realtime Talk camera controls (#111042) 2026-07-18 17:03:32 -07:00
Peter Steinberger
4b7d6fa3bf docs: align interactive client behavior (#111047) 2026-07-18 17:00:14 -07:00
Peter Steinberger
bb7b2bca68 feat(ui): finish the chat session → thread rename across the Control UI (#110973)
* feat(ui): finish the chat session → thread rename across the Control UI

Completes the #110933 creation-surface rename mechanically: Threads page
(title, filters, archive/delete/rename/pin menus, transcript search),
sidebar labels and menus, welcome suggestion, palette category, tools
availability copy, workboard lifecycle/card strings, dreaming history,
board/diff/workspace-rail chrome, and the untitled main/channel fallback
names. Technical identifiers stay: Session ID, session keys, terminal
sessions, protocol wording. Living docs updated (control-ui.md);
historical release notes left as shipped.

* style(ui): format session-management e2e

* fix(ui): finish thread rename in navigation labels and stale test literals

Codex review caught the palette Threads entry and the Worktrees owner
column still saying Session; CI caught test literals asserting the old
copy (Threads page overview tile, filter tooltips, group counts, catalog
terminal notice, create-rejection error, workboard lifecycle hint). Also
completes the usage-stat cluster (Threads + hints) and the tool-catalog
group label. Native app strings (iOS/Android/macOS) keep session wording
and reconcile through their own i18n pipelines as a follow-up.
2026-07-18 23:15:13 +01:00
Peter Steinberger
460e3e669c fix(canvas): restore shipped policy/host-disable contracts; harden workspaces doctor cleanup (#110927)
* fix(dashboard): harden canvas and workspace compatibility

* docs(web): add dashboard architecture

* chore: remove release-owned changelog entry

* docs: update dashboard architecture map
2026-07-18 23:00:00 +01:00
clawsweeper[bot]
b88646cf78 feat(webchat): reply-to a message with hydrated reply context (#110791)
* feat(webchat): reply-to a message with hydrated reply context

Control UI replies now carry the target transcript id as replyToId on
chat.send. The Gateway resolves the replied-to message from session
history and hydrates the channel-agnostic ReplyToId/ReplyToBody/
ReplyToSender envelope fields, so agents receive reply_to_id,
has_reply_context, and the untrusted reply-target block exactly like
Discord replies (mirrors #90263). Reply targets without a persisted
transcript id keep the inline-quote fallback.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(webchat): keep non-reply chat.send dispatch ordering and satisfy CI gates

* docs(webchat): match reply-context doc to webchat conversation-info policy

* fix(webchat): hydrate reply bodies from display-visible content only

---------

Co-authored-by: openclaw-clawsweeper[bot] <openclaw-clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: fuller-stack-dev <263060202+fuller-stack-dev@users.noreply.github.com>
2026-07-18 15:57:59 -06:00
Peter Steinberger
09a64f7ab0 feat(models): make per-agent allowlists explicit (#110888) 2026-07-18 21:42:05 +01:00
Peter Steinberger
6589788c02 docs: The main session concept page and shipped-sidebar updates (#110905)
* docs: add The main session concept page and cross-links

* docs: precise memory-priming wording on the main-session page

* docs: update Control UI sidebar description to the Home and zones model
2026-07-18 20:23:09 +01:00
Peter Steinberger
5fdb0cd24e feat(chat): switch between session transcript branches from the chat header (#110857)
* feat(chat): switch between session transcript branches from the chat header

* fix(chat): type fixes and protocol regen for branch switcher CI
2026-07-18 20:06:36 +01:00
Peter Steinberger
33f9c47e3c fix(ui): label the local-only chat message delete honestly as hide (#110801) 2026-07-18 17:27:51 +01:00
Peter Steinberger
a115af2774 feat(ui): add reactive OpenClaw health nudges (#110708)
* feat(ui): add reactive custodian health nudges

* fix(ui): distinguish stopped channels from startup failures

* test(ui): update custodian route gateway fixture

* fix(ui): preserve current channel health failures

* fix(ui): ignore recovered channel errors
2026-07-18 15:44:29 +01:00
Peter Steinberger
0acece4591 feat(chat): rewind and fork a session from a message bubble (#110660)
* feat(chat): rewind and fork a session from a message bubble

* docs(web): document chat rewind and fork bubble actions

* fix(chat): lint cleanups, protocol regen, and test splits for rewind/fork CI

* fix(ui): fit chat rewind disabled styles inside the startup CSS budget
2026-07-18 14:46:34 +01:00
Peter Steinberger
9710a1339e refactor(canvas): promote inline-widget hosting and show_widget to core (#110475)
* refactor(canvas): promote inline widgets to core

* docs(agents): note discord show_widget ownership at core registration

* ci: retrigger after GitHub scheduling outage

* fix(canvas): satisfy dead-code and test type checks
2026-07-18 14:40:45 +01:00
Peter Steinberger
42133d0c3c feat(mac): show native notification permission in dashboard Notifications settings (#110646)
* feat(mac): show native notification permission in dashboard Notifications settings

The Mac app's embedded Control UI showed the web-push section as
Unsupported/Not subscribed even though the app delivers notifications
natively. The dashboard now installs an openclawNotifications WebKit
bridge (status / request-permission / send-test) and the Notifications
settings page renders native permission state with Enable, Open System
Settings, and Send test actions when hosted in the Mac app. Browsers
keep the existing web-push UI. The notifications section renderer moved
out of the oversized config view module.

* fix(ui): break config view import cycle and satisfy lint/deadcode/i18n gates

Move the notifications section props to a leaf contract (no view.ts
type import), unexport the status-event constant, use bracket access
for the injected dunder global, default-case the status switch, and
refresh the native i18n inventory line offset.
2026-07-18 14:13:06 +01:00
Peter Steinberger
74880cb56f feat(ui): manage MCP servers directly from Settings → MCP (#110654)
* feat(ui): manage MCP servers directly on the Settings MCP page

* refactor(ui): mcp config section owned by the MCP settings page only

* chore(ui): drop test-only McpServersCard export for knip
2026-07-18 12:54:05 +01:00
Peter Steinberger
3b2797f09b improve(ui): settings cleanup batch — universal config.changed emitter, synced chat prefs, dedupe and copy fixes (#110581)
* fix(gateway): emit config.changed from the reload committer for every accepted write

Agent config_set, CLI, and doctor writes reach the gateway through the file
watcher's reload path, which never broadcast config.changed - only direct RPC
writes did. Move the broadcast to a single onConfigCandidateCommitted hook in
the reload committer so all writers notify connected UIs, including
runtime-skipped commits (writer-intent echo suppression, reload mode off),
and delete the duplicate RPC-side broadcasts.

* feat(ui): sync chat follow-up and commentary prefs across devices

Add chatPersistCommentary and chatFollowUpMode to the ui.prefs sync surface
(schema, types, docs) with clearable null removal for the follow-up override.
Rewrite server-prefs around a descriptor table so a synced pref is one entry
instead of five hand-written code sites. Caption synced rows/sections
(chat prefs, theme, language) and refresh the stale Settings subtitle.

* refactor(ui): dedupe settings constants, drop dead composer branch, refresh copy and docs

Derive the Security tool-profile options from PROFILE_OPTIONS and General's
thinking levels from BASE_THINKING_LEVELS instead of parallel literals.
Remove the unused composer mode:"model" branch, the orphaned
.config-view-toggle CSS family, and stale quick-settings wording. Add static
settings-search entries for the Sessions and Managed Worktrees pages plus a
provenance-row test, and update docs/cli/openclaw.md to describe the current
system-agent config-write policy (denylist roots, route-backing plugin guard,
per-agent routing escalations).

* chore: refresh plugin SDK API baseline after rebase onto current main
2026-07-18 12:10:20 +01:00
Peter Steinberger
a068d38b66 refactor(plugins)!: remove experimental workspaces plugin (#110416)
* refactor(plugins)!: remove experimental workspaces plugin

* fix(doctor): remove retired workspaces plugin state

* refactor(doctor): settle retired-workspaces cleanup before legacy-state detect

* chore(i18n): leave workflow-owned locale artifacts to the locale refresh

* ci: retrigger after GitHub scheduling outage
2026-07-18 10:56:37 +01:00
Peter Steinberger
654560f289 feat(ui): add Apps & extensions page to the Control UI (#110563)
* feat(ui): add Apps & extensions page

* feat(ui): add per-theme app-art card illustrations

* docs: describe the Apps and extensions page in control-ui

* fix(ui): keep icons.ts under max-lines, drop unused export, regen docs map
2026-07-18 09:52:34 +01:00
Peter Steinberger
64aebb996a improve(ui): settings follow-ups — live pref sync, model provenance, Agent Defaults, Memory Import restyle (#110494)
- gateway broadcasts a hash-only config.changed event after every
  persisted config write (operator.read scoped); the Control UI refreshes
  its snapshot on the event so agent-approved ui.prefs changes apply live
  on every connected client (skipped while a local draft is dirty)
- the chat composer's model picker shows provenance — 'Using default
  from Settings' vs 'Session override' with an icon reset back to the
  default — mirroring the existing reasoning-row anatomy
- the AI & Agents settings page is renamed Agent Defaults to separate it
  from the per-agent Agents manager
- Memory Import renders through the settings design language (sections,
  rows, toggle, status badges); only the collection review list, apply
  report, skeleton, and confirm dialog keep custom markup, and the dead
  bespoke CSS is pruned
2026-07-18 08:14:11 +01:00
Peter Steinberger
723f5ba4fc improve(ui): restructure Settings around user-facing pages with full agent parity (#110445)
* refactor(ui): restructure Settings IA around user-facing pages

Settings sidebar shrinks to settings-only destinations grouped by attention:
General/Appearance/Notifications up top, Connections, Agents & Tools,
Privacy & Security, System. Sessions, Worktrees, Activity, and Memory
Import leave the takeover: Sessions/Activity return to the workspace
sidebar, Worktrees becomes a Sessions hub tab, Memory Import is reached
from the Agents memory panel. Model Setup becomes a Models subpage.

New config pages: Notifications (web push), Privacy & Security (curated
policy rows + security/approvals schema sections), Advanced (uncurated
schema sections + raw editor, replacing the General quick/advanced
toggle). General slims to model defaults, language, and gateway host;
identity moves to Profile, lobster appearance rows to Appearance.

* feat(agents): widen system-agent config writes to operator parity

Every config surface the Control UI can edit is now agent-writable behind
the exact-operation human approval gate, except a small documented
denylist ($include, auth, env, models, secrets). tools.* and
plugins.entries.* writes are allowed; plugin_uninstall works for plugins
that provably do not back the active default inference route (fail closed
otherwise); set_default_model takes an optional agentId and live-tests a
per-agent model with the same rigor as the default route. Per-agent
routing fields on non-default agents are direct-writable; the default
agent's route keeps the verified set_default_model/onboard paths. A new
config-write-parity contract test forces explicit classification of every
top-level config key.

* feat(ui): sync operator display prefs through config ui.prefs

Theme, theme mode, text scale, locale, and chat display prefs get a
canonical server-side home in config ui.prefs. The Control UI mirrors
them into localStorage for instant boot, writes local changes through to
the gateway (best-effort; viewer-scope or offline clients stay
device-local), and applies server-side deltas on connect and on every
config snapshot reload — so an agent changing the theme through the
approval gate takes effect in the UI, and prefs follow the operator
across devices.

* chore: prune quick.ts from max-lines baseline after slim-down

* style: oxfmt changed files

* chore: regenerate plugin-sdk api baseline for ui.prefs config surface

* fix: dedupe runPluginUninstall dep type and narrow locale extraction

* docs: update Control UI settings structure and ui.prefs sync

* fix: address autoreview findings on parity guards and prefs sync

- plugins.entries.* config writes get the same active-route ownership
  check as plugin_uninstall (fail closed when unprovable)
- system-agent prompt now describes the guarded write policy instead of
  the old blanket refusals
- per-agent set_default_model logs the agent-scoped label
- legacy /config?section=... deep links redirect to the Advanced page
- prefs sync: pushes coalesce and drain serially (no CAS races dropping
  updates), replaced config hashes mark pre-patch snapshots as stale, and
  the last-seen server value persists per gateway scope so reloads cannot
  revert unpushable viewer-scope edits
- lint: theme membership checks use Sets

* fix: harden uninstall route guard and scope prefs queue per gateway

- plugin uninstall ownership now covers execution owners (runtime policy,
  embedded harness override) in addition to the provider, and re-verifies
  inside the commit boundary so a concurrent route switch cannot slip a
  destructive uninstall past the pre-approval check
- prefs push queue binds to one gateway client; switching gateways drops
  the old queue (device-local fallback) instead of cross-writing prefs

* style: top-level type import in config-page test

* fix: close review races in config-write guards and prefs reconciliation

- config_set/config_set_ref re-verify the inference-route guard inside
  the commit boundary so conditional verdicts (per-agent routing, plugin
  entries) cannot be flipped by a concurrent edit after approval
- server prefs apply per changed field, so a server change to one pref
  no longer reverts unpushable local edits of the others
- replaced-hash staleness retires once post-patch state is observed, so
  a genuine restore of the pre-patch config becomes authoritative again
- moved-section deep links (communications notifications, automation
  approvals) redirect to their new pages

* style: satisfy no-useless-assignment and loop-condition lints in prefs sync

* fix(ci): resolve unhandled profile-test rejections and knip unused exports

The profile page's new identity section reads context.config; the test
context mock now provides it, eliminating the unhandled rejections that
failed checks-ui and the compact-large shard. Exports flagged by the
dependency gate (extract/patch helpers, section-key and prop types) go
module-private; extraction coverage moves behind applyServerUiPrefs.

* refactor(agents): move config-write policy to its own module

The static path classifier and documented denylist move to
config-write-policy.ts, shared by the execution guard and the parity
contract test — no test-only exports left for the dependency gate to
flag. Blocked-root refusals now cite the denylist's documented
escalation for that root.
2026-07-18 07:03:31 +01:00
Peter Steinberger
781913025b improve: stream native sessions as hosts finish (#110211)
* perf: stream native session catalogs by host

* fix: satisfy session catalog CI contracts

* fix: retain changed-session refresh timing

* fix: keep catalog refresh helpers private
2026-07-17 23:59:57 +01:00
Peter Steinberger
a838c68dbe feat(talk): add Gemini Live video (#109719)
Stream bounded browser camera frames directly to Gemini Live and keep camera media off the Gateway. Add lifecycle, function-calling, fake-camera E2E, and live-smoke coverage.

Co-authored-by: shushushu <1064076525@qq.com>
2026-07-16 23:55:06 -07:00
Peter Steinberger
7be5d78fd0 feat(workspaces): add full-bleed single-widget tabs (#109627)
* feat(workspaces): add full-bleed app tabs

* fix(workspaces): harden full-bleed rendering

* fix(workspaces): eliminate full-bleed iframe gap

* fix(workspaces): keep tab layout type internal

---------

Co-authored-by: Eva <eva@100yen.org>
2026-07-16 21:56:57 -07:00
Peter Steinberger
9ce8ac94b9 feat(ui): fold the mobile navigation row into the chat title bar (#109635)
* feat(ui): fold the mobile navigation row into the chat title bar

On plain-browser mobile layouts the chat route drops the 58px shell topbar;
the pane title bar gains a leading nav-drawer toggle and a trailing
command-palette search button (~50px more chat). The shared mobile-nav
breakpoint moves into one module used by shell and chat; native shells and
non-chat routes keep today's chrome.

* improve(ui): anchor the workspace chip right after the session title

The chip now hugs the title text with the header's standard gap instead of
sitting at the far right; the action cluster claims the leftover width and
stays right-pinned. Where field-sizing is supported the rename input hugs
its text too, so the chip tracks the title while typing.

* chore(ui): keep hasNativeShellClass module-local
2026-07-16 21:44:29 -07:00
Peter Steinberger
a0fac37f14 feat: add OpenAI Video Talk (#109579)
* feat(talk): add OpenAI Video Talk

Co-authored-by: wuxuanshu <1064076525@qq.com>

* fix(protocol): refresh native Talk capability model

* chore(i18n): refresh control UI fallback baseline

* chore(i18n): defer locale refresh to workflow

---------

Co-authored-by: wuxuanshu <1064076525@qq.com>
2026-07-16 21:25:09 -07:00
Peter Steinberger
61bec3a2de fix(ui): follow Gateway queue mode for active-run messages (#109441)
* fix(ui): inherit Gateway queue mode for follow-ups

* fix(ui): honor session queue overrides

* fix(ui): preserve Gateway follow-up semantics

* fix(ui): retain pane queue mode ownership

* fix(ui): keep Gateway queue policy authoritative

* chore(ui): leave locale refresh to workflow

* fix(ui): keep unresolved follow-ups neutral

* refactor(ui): isolate session queue projection
2026-07-16 20:59:11 -07:00
EVA
09575bd20f feat(workspaces): show agent status and custom-widget decisions (#101826)
* feat(workspaces): add operations widgets

* fix(workspaces): format agent progress translation

* fix(workspaces): keep operations widget helpers private

* feat(workspaces): harden operations widgets

Co-authored-by: EVA <eva@100yen.org>

* chore(i18n): defer generated locale refresh

* refactor(workspaces): isolate approval state

* fix(release): declare direct checklist execution

* fix(release): satisfy checklist declaration lint

* fix(release): align checklist declaration order

---------

Co-authored-by: Eva <eva@100yen.org>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 20:19:49 -07:00
Peter Steinberger
00a6ecb906 feat(ui): always-on chat title bar with inline rename and workspace actions (#109422)
* feat(gateway): add sessions.files.reveal to open a session workspace on the gateway host

Resolves the session's workspace root server-side (same resolution as
sessions.files.list), refuses exec-node and cloud-worker placements, and
opens the directory with the platform opener. The opener helpers move out
of config.ts into a shared open-path module that config.openFile now uses.

* feat(ui): always-on chat title bar with inline rename and workspace menu

Every chat pane now renders its header: click the session title to rename
it inline (Enter commits via sessions.patch, Escape cancels), a workspace
chip names the session's checkout with reveal/copy-path/copy-branch
actions, and cloud-worker sessions show a globe. The single-pane floating
toggle cluster and the transcript's reserved titlebar drag band fold into
the header, which keeps native macOS window dragging.

* fix(ui): resolve title-bar session aliases and clear the collapsed-nav overlay

Live verification found two gaps: route aliases like ?session=main showed
the generic key-derived title instead of the session's label (resolve via
hello defaults + key equivalence, matching the pane), and the floating
sidebar-expand pill overlapped the header title on plain web while the nav
was collapsed (52px inset, mirroring the native-shell clearances).

* fix(ui): keep the protocol schema layer out of the Control UI startup bundle

The title-bar change made session-row-badges runtime-import the
gateway-protocol barrel for one classifier, dragging typebox and every
schema into startup JS (395 KiB gzip vs the 370 KiB budget). The placement
vocabulary now lives in a dependency-free session-placement-state module:
the schema union derives from it, the barrel re-exports it, and the UI
deep-imports it (startup back to 361.8 KiB).

* fix(gateway-protocol): keep SessionPlacementStateSchema statically typed

Type.Union over a mapped array loses tuple inference and collapses Static
to never; the literal list stays explicit with a compile-time guard tying
it to the shared SESSION_PLACEMENT_STATES vocabulary.

* chore(protocol): regenerate Swift/Kotlin bindings for sessions.files.reveal

* chore: narrow new exports flagged by the deadcode gate

* chore(i18n): leave generated locale artifacts to the locale-refresh workflow

The generated-artifact isolation gate (067635cb51) landed mid-flight;
source PRs now carry en.ts only.
2026-07-16 20:04:12 -07:00
Peter Steinberger
28a3540f32 feat: add native inline widget support (#109212)
* feat: add native inline widget support

* refactor: simplify plugin surface refresh

* fix: preserve plugin surface refresh API

* fix: reload widgets after WebKit termination

* fix: harden native widget refresh

* fix: bound native widget recovery

* docs: defer native widget release note

* chore: refresh native i18n inventory

* fix: harden native widget delivery

* refactor: simplify native widget API surface

* fix: serialize native widget capability refresh

* fix: harden native widget recovery

* fix: recover native widget capabilities

* style: format widget refresh role selection

* fix: correct widget refresh formatting

* fix: harden cross-platform widget recovery

* fix: bind widget trust and recovery to routes

* chore: refresh native i18n inventory

* chore: regenerate Android gateway protocol

* test: remove unused release workflow read
2026-07-16 19:24:41 -07:00
EVA
368941ae7a feat(workspaces): add secure preview widget (#101354)
* feat(workspaces): add secure preview widget

* fix(workspaces): type preview reload assertion

* fix(workspaces): harden preview widget

* fix(workspaces): honor preview URL binding ownership

* chore(workspaces): remove unused widget exports

---------

Co-authored-by: Eva <eva@100yen.org>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 18:21:54 -07:00
EVA
4a7abe1556 Workspaces: add trusted chart widgets (#101792)
* feat(workspaces): add trusted chart widgets

* fix(workspaces): keep chart helpers private

* test(workspaces): prove chart widgets in control UI

* fix(workspaces): validate empty chart bounds

* fix(workspaces): expand subnormal chart ranges

* fix(workspaces): normalize chart ranges

* fix(workspaces): keep zero bars at baseline

* fix(ui): sync chart widget locales

* fix(ui): translate chart widget locales

---------

Co-authored-by: Eva <eva@100yen.org>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 16:50:49 -07:00
Peter Steinberger
a9f82837a1 feat: inspect background tasks across web and mobile (#109150)
* feat: add background task details across clients

* fix: refresh background task clients and translations

* fix: keep background task details fresh

* fix: ignore deleted background task details

* refactor: split background task rendering

* fix: use canonical background task ids

* refactor: extract background task view types

* fix(apps): regenerate task localizations

* fix(ios): remove unused task screen import

* fix(apps): refresh task localization inventory
2026-07-16 13:08:42 -07:00
Peter Steinberger
e71ef76e8e feat(onboarding): offer detected Claude Code/Codex/Hermes memory imports across CLI, macOS, and Linux onboarding (#108977)
* feat(migrate): add Hermes memory-only import and a shared memory-import core

* feat(onboarding): offer detected memory imports during CLI setup and guided onboarding

* feat(ui): show a first-run memory-import offer in Control UI onboarding mode

* feat(linux-app): open the first-run dashboard in onboarding mode

* feat(macos): add the onboarding memory-import page

* docs: document the onboarding memory-import page across surfaces

* chore(i18n): translate onboarding memory-import strings for control-ui and native locales

* refactor: keep memory-import internals unexported for deadcode gates

* fix(ci): resolve lint findings in onboarding memory import

* chore(i18n): refresh native inventory after lint refactor

* fix(ci): skip updater artifacts in the unsigned Linux companion PR lane

* chore(i18n): reconcile locale artifacts after rebase
2026-07-16 10:10:01 -07:00
Peter Steinberger
20d748a4f0 feat(agents): agent-owned gateway terminals with operator co-attach 2026-07-16 09:12:50 -07:00
Peter Steinberger
16d1f487fe feat(widgets): unify show_widget across surfaces (#108983)
* feat(widgets): unify show_widget across surfaces

* docs(canvas): keep lazy show_widget descriptor in sync with the loaded tool
2026-07-16 05:24:11 -07:00
Peter Steinberger
2488d794ca feat(ui): expand child sessions in sidebar (#108838)
* feat(ui): expand child sessions in sidebar

* test(ui): type child session list options

* refactor(ui): split child session data helpers

* fix(ui): preserve session link semantics

* fix(ui): retry incomplete child session loads

* chore: keep release changelog owner-only
2026-07-16 03:26:49 -07:00
Peter Steinberger
0f32033d78 fix(ui): add thinking level to new cloud sessions (#108679) 2026-07-15 23:54:00 -07:00
Peter Steinberger
5bfcd779b1 fix(ui): local sessions show no placement icon (#108615)
* fix(ui): distinguish cloud worker sessions

* chore: defer session icon release note

* fix(ui): keep placement helper private
2026-07-15 22:05:09 -07:00
xydt-tanshanshan
d201acd6e8 refactor(push-web): move web push store to shared SQLite state DB (#103294)
* refactor(push-web): move state to shared SQLite

Co-authored-by: hailory <hailory@xydigit.com>

* fix(push-web): harden legacy migration retries

* fix(push-web): format migration lock errors

* fix(push-web): gate runtime during legacy migration

* fix(push-web): keep store internals private

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: hailory <hailory@xydigit.com>
2026-07-15 12:54:22 -07:00
clawsweeper[bot]
5afb1fb381 feat(ui): add follow-up behavior setting for active runs (steer by default) (#108032)
* feat(ui): add follow-up behavior setting (queue vs steer) for active runs

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* default follow-up behavior to steer

Follow-ups sent while a run is active now steer into the running turn by
default; queue mode becomes the persisted opt-out. Offline/disconnected
sends still always queue.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(ui): steer active follow-ups by default

---------

Co-authored-by: openclaw-clawsweeper[bot] <openclaw-clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-14 23:28:27 -07:00
Peter Steinberger
86772735ac fix: pin sessions dropped into Pinned (#107854)
* fix(ui): pin sessions dropped into pinned group

* test(ui): capture pinned session drop proof

* chore: keep release note in PR metadata
2026-07-14 17:14:39 -07:00
Peter Steinberger
520e2580cb feat(control-ui): show terminal upload progress (#107789)
* feat(control-ui): add terminal upload recovery

* fix(control-ui): harden terminal upload recovery
2026-07-14 15:10:01 -07:00
Peter Steinberger
a6a0716486 feat(setup): rename Crestodian to OpenClaw system agent
User-facing name is now OpenClaw (the system speaks); internal code name is
system-agent. Gateway methods crestodian.* -> openclaw.chat/openclaw.setup.*,
agent tool -> openclaw, reserved agent ids openclaw + retired crestodian.
openclaw setup routes: onboarding flags -> onboard, -m/--yes -> system agent,
bare configured interactive -> OpenClaw chat, unconfigured -> onboarding.
Hidden crestodian CLI and /crestodian TUI aliases kept; docs moved to
docs/cli/openclaw.md with redirect stub. macOS/Android strings in lockstep.

Refs #107237
2026-07-14 11:03:02 -07:00
Peter Steinberger
084d1d9637 feat(control-ui): upload files into terminals (#107364)
* feat(control-ui): add terminal file uploads

* fix(control-ui): protect Windows terminal uploads

* fix(control-ui): satisfy terminal upload gates

* chore(ui): translate terminal upload labels

* fix(control-ui): reject unknown Windows upload shells

* fix(control-ui): harden Windows upload paths

* fix(control-ui): retry terminal upload cleanup

* chore(ui): reconcile locale translation memory

* fix(control-ui): validate terminal upload inputs

* fix(control-ui): retry failed upload cleanup

* chore(ui): refresh terminal upload locale metadata

* fix(terminal): integrate uploads with session recovery

* refactor(control-ui): isolate terminal upload transport

* fix(control-ui): keep upload helper types private
2026-07-14 09:33:39 -07:00
Peter Steinberger
d8d2f83cc1 feat(terminal): open Codex/Claude catalog sessions in a terminal on their owning host
Catalog session rows (sidebar context menu + click), the built-in viewer
header, and a new "Open Codex/Claude sessions in" preference can launch the
native CLI (codex resume / claude --resume) in the operator terminal on the
machine that owns the session.

- Gateway-local sessions spawn through the existing terminal launch policy
  (sandbox/enabled gates preserved) with the resume command in the session cwd.
- Paired-node sessions run through a new seq-ordered node PTY relay: a
  duplex node-host command streams PTY output via node.invoke.progress and
  receives keystrokes/resize via a new node.invoke.input event, behind the
  unchanged terminal.* client protocol (TerminalSessionManager gains a backend
  abstraction; node relay reuses the streaming-invoke controller).
- Owner boundary: each plugin owns its resume command and builds argv from a
  validated thread id; the gateway routes node opens through the node command
  allowlist and plugin invoke policy (no advertisement-only trust), and nodes
  re-verify session eligibility before spawning.
- UI setting catalogOpenTarget + canOpenTerminal capability gate every entry
  point; capability requires the owning host to actually have the CLI.

Node PATH is normalized before command-availability probes, Windows .cmd/.bat
shims spawn via ComSpec, and catalog terminal opens reattach persisted tabs
before opening the new tab.
2026-07-13 22:20:50 -07:00
Peter Steinberger
cf8b57e7d0 feat(skills): scan session history for workshop ideas (#106766)
* feat: scan past sessions for skill proposals

* feat(ui): add progressive skill history scans

* fix(ui): keep skill history scans synchronized

* refactor: split skill history scan ownership

* style: fix mock helper formatting

* style: format skill history scan

* build: refresh skill history schema baselines

* build: refresh plugin SDK baseline after rebase

* perf(ui): keep startup request budget bounded

* fix(skills): satisfy history scan integration gates

* fix(ui): bound control ui startup chunks

* build: refresh plugin SDK API baseline

* build(ui): refresh self-learning translation memory

* refactor(ui): split skill workshop state

* fix(ci): refresh skill workshop gates

* fix(ci): satisfy skill history lint

* build: refresh plugin SDK baseline after main rebase
2026-07-13 16:15:50 -07:00
Peter Steinberger
4319ddbe8c feat(control-ui): import Codex and Claude Code memory (#106406)
* feat(control-ui): import coding assistant memory

* test(migrate): clean memory import temp dirs

* chore: move memory import note to PR body

* build: refresh memory import generated artifacts

* fix(control-ui): complete memory import checks

* build(control-ui): localize memory recovery labels

* fix(control-ui): harden memory import recovery

* refactor(migrate): keep memory import surfaces bounded

* fix(control-ui): use canonical agent row type

* fix(codex): drop dead migration type exports

* fix(migrate): restrict imported memory permissions

* fix(control-ui): preserve memory import recovery state

* fix(control-ui): retain memory import results

* build(control-ui): preserve translation memory history

* fix(control-ui): bind memory import state to agent

* fix(control-ui): unlock memory import after refresh

* test(gateway): preserve memory method suffix

* fix(migrate): bind reviewed memory imports

* fix(migrate): make memory imports retry-safe

* perf(ui): keep memory import lazy

* build: refresh generated artifacts after rebase

* chore: keep migration runtime within LOC guard

* build: refresh Swift protocol model
2026-07-13 15:30:06 -07:00
Peter Steinberger
00b38ebc20 feat(web): show session branch row for local changed files (#106835)
* feat(web): show session branch row for local changed files

The pre-PR branch row above the composer only appeared once the branch
was pushed and ahead of the default branch. Sessions with local work
(committed, uncommitted, or untracked changes) showed nothing.

The gateway now emits the branch payload whenever the working tree has
changed files vs the default-branch merge base; createUrl is withheld
until GitHub's pull/new page has something to compare, and the UI only
renders the Create PR link when it is present.

* refactor(gateway): keep control-ui-session-prs under LOC ratchet

* docs(gateway): note explicit-base diff counts conflict paths
2026-07-13 15:17:37 -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
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
156f4c89ed refactor(ui): fold sidebar More section into a popup menu (#105906)
The sidebar's expandable "MORE" section (uppercase header, chevron, persisted
sidebarMoreExpanded pref, dedicated "Edit pinned items" row) collapses into a
single More nav row that opens a transient popup menu with the unpinned
routes, dynamic plugin tabs, and the pin editor entry. Menu rows are real
anchors, so Cmd/middle-click keeps native link behavior; the More row carries
the active highlight when the current route lives inside the menu. The
sessions list gets the reclaimed vertical space, and one persisted setting is
gone (stale keys are ignored on load). The nav rows and menus move to
app-sidebar-nav-menus.ts to keep app-sidebar.ts under the TS LOC ratchet.

Docs: docs/web/control-ui.md sidebar-navigation section updated.

Fixes #105905
2026-07-12 20:33:51 -07:00