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.
* 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
#106332 landed using revokeAttachGrantsForSession after #106038 removed it
as dead, breaking prod-types compile on every PR merge ref. Restores the
helper verbatim from 2deb696ef4 with a doc comment.
* feat(gateway-protocol): add session placement schema
Closed state discriminator for session execution placement (local/requested/provisioning/syncing/starting/active/draining/reconciling/reclaimed/failed), sessions.dispatch params, and worker-admission transcript/live cursor extensions. Swift protocol models mirror the schema.
* feat(state): add worker session placement table
worker_session_placements rows carry placement state, transition generation, worker ownership metadata, ACK cursors, and the turn claim columns used for atomic admission.
* feat(cloud-workers): add durable placement state machine store
SQLite-backed placement store split by concern: state table (placement-state), discriminated record types + shape invariants (placement-record), row codec + CAS transition values (placement-row-codec), atomic turn-claim admission/release/waiters (placement-turn-claims), and lifecycle CAS transitions (placement-store).
* feat(cloud-workers): sync workspaces and attach sessions to worker environments
Environment service session attachment + turn credentials, tunnel workspace commands over a dedicated SSH runner, and git/plain workspace sync into $HOME/.openclaw-worker/workspaces with an immutable manifest. Symlink escapes are rejected locally before transfer (macOS openrsync stat-fails them opaquely) and again by the remote manifest guard.
* feat(worker): run one-shot embedded turns from launch descriptors
Worker runtime executes a single embedded turn from a stdin launch descriptor and reports completed/failed/fenced on stdout for the gateway launcher. Terminal lifecycle live events are deferred past the final transcript flush; transcript projection helpers are shared via transcript-message instead of duplicated in the runtime.
* feat(cloud-workers): dispatch placements and route worker turns
Dispatch service drives local->requested->provisioning->syncing->starting->active with failure teardown (placement-dispatch-failure) and restart/runtime recovery incl. lost-worker reclaim (placement-dispatch-recovery). Worker turn launcher claims the placement turn atomically, builds a windowed launch descriptor (worker-turn-payload), runs the remote one-shot worker, and reconciles the committed transcript; agent runners route turns through the session placement admission provider.
* feat(gateway): expose session placement RPCs and startup reconciliation
sessions.dispatch RPC with lifecycle admission barriers, operator-facing placement projection on session listings, placement-aware session reset guard, and startup/interval reconciliation wiring for worker placements.
Mirror the iOS gateway settings ordering: nav-bar QR scan action,
Scan QR to Pair hero while unpaired, one Add Gateway panel (scan,
setup code + connect, discovered gateways with per-row connect),
paired gateways below, manual host/credential plumbing at the bottom.
Add facts rows (Discovered, Default Agent, Agents, Instance ID) and a
Diagnose action, plus a deterministic 'gateway' screenshot scene.
Closes#106186
* 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
* ci: enforce changed-file TypeScript LOC ratchet
* ci: derive release-gate LOC base from PR
* test(ci): exclude repository test helpers from LOC ratchet
* ci: validate LOC ratchet on PR merge tree
* style: format release maintainer skill
* ci: run LOC ratchet for fast-only changes
* fix(ci): harden LOC ratchet comparisons
* fix(ci): cover native TypeScript in LOC ratchet
* fix(ci): compare LOC against tested merge tree
* test(ci): cover LOC manifest routing
* fix(auto-reply): retry reply-session init CAS conflicts with backoff
Reply-session initialization retried a lost optimistic-concurrency commit
exactly once, with no delay, inside the store writer lane. When another
writer (restart recovery, a concurrent dashboard tab, an active reply run)
was mid-commit on the same session key, both attempts lost the revision CAS
within milliseconds and "reply session initialization conflicted" escaped to
the caller — silently dropping the inbound event on webchat/Slack/heartbeat
paths (#102400).
Introduce a typed ReplySessionInitConflictError and retry the whole unlocked
init attempt up to 5 times with jittered exponential backoff (250ms..4s).
The sleep happens outside runExclusiveSessionStoreWrite so the writer lane
is never held while waiting, each retry re-reads a fresh snapshot, and the
error message shape is preserved for channel monitors (e.g. the Telegram
poller) that already classify it as retryable.
Fixes#102400
* fix(auto-reply): cancel conflict backoff on abort
* refactor(auto-reply): unify session init cancellation
* refactor(auto-reply): isolate session conflict retry
---------
Co-authored-by: oabdelmaksoud <oabdelmaksoud@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* 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>