* fix(doctor): gate cross-state-dir legacy imports behind explicit doctor opt-in
A gateway or CLI command started with OPENCLAW_STATE_DIR pointing at a
non-default directory used to import legacy files FROM the default
~/.openclaw state dir (exec-approvals.json, plugin-binding-approvals.json)
and archive the originals with a .migrated suffix. Any isolated, test, or
staging run on a host with production state silently captured and archived
the production files.
Cross-state-dir imports now run only with the new crossStateDirImports
opt-in: openclaw doctor --fix (or an interactive doctor confirm) performs
the import; the implicit CLI/gateway preflight leaves the default dir
untouched and emits a notice pointing at doctor instead.
* test(doctor): include notices in legacy-state detector mocks
A fun field guide for the Control UI lobster: what it is, when it
visits, how to interact (hover names, pokes, right-click shoo), the
Appearance toggle, the Lobsterdex, reduced-motion and privacy notes.
Deliberately teases rather than documents the rare variants, events,
and the anniversary. Registered in the Web interfaces nav group and the
generated docs map.
* fix(msteams): read file attachments on Teams channel messages
Three bugs blocked reading files attached to channel messages:
- Graph /teams/{id} used channelData.team.id (the 19:..@thread.tacv2 thread id)
instead of team.aadGroupId (the AAD group GUID) -> 400.
- The Graph fetch was gated on an <attachment id> HTML marker that channel
@mention activities don't carry -> fetch skipped.
- A thread reply was fetched at /messages/{replyId} (404) then fell back to the
bare thread root, returning the root's file for every reply. Replies live at
/messages/{root}/replies/{replyId}.
Fixes#89594
* fix(msteams): gate Graph media fallback on text/html stub; run trigger tests in channel context
* fix(msteams): canonicalize Graph attachment recovery
Build one canonical Graph message URL per Teams activity, recover marker-free channel and group-chat file shares, and retain bounded current-main attachment handling.
Co-authored-by: Colton Williams <colton@coltons-apps.tech>
* fix(msteams): canonicalize Graph media recovery
Recover channel and group-chat files through one fail-closed Graph identity path, bound inbound enrichment, and remove invalid app-only Graph fallbacks.
Co-authored-by: Colton Williams <colton@coltons-apps.tech>
Co-authored-by: Joshua Packwood <joshua.packwood@gmail.com>
---------
Co-authored-by: Colton Williams <colton@coltons-apps.tech>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Joshua Packwood <joshua.packwood@gmail.com>
* refactor(pairing): move device pairing store to shared SQLite state DB
Device pairing, pending requests, and bootstrap tokens now live in the
device_pairing_* / device_bootstrap_tokens tables of state/openclaw.sqlite
instead of devices/{paired,pending,bootstrap}.json. Gateways import legacy
paired records once at startup (before the node-surface fold) and archive
the JSON files with a .migrated suffix; transient pending/bootstrap rows
are dropped. The unshipped node_pairing_* tables are removed from the
schema and dropped from existing DBs. Doctor now flags un-imported legacy
store files instead of corrupt-JSON reads.
* refactor(pairing): drop stale awaits now that store persistence is synchronous
* refactor(pairing): extract leaf record types to break store/domain module cycle
The README led with a transparent mascot cutout floating on the GitHub
background. Swap in generated full-bleed banners (ink starfield dark
variant, warm paper light variant) with the wordmark, tagline, and
one-liner baked in, and drop the now-redundant EXFOLIATE text line.
* fix(anthropic): don't crash models list when a configured Sonnet 5 model has no cost
applyAnthropicSonnet5Cost read params.model.cost.input unconditionally, so
'openclaw models list' aborted with 'Cannot read properties of undefined
(reading input)' whenever config supplied an anthropic Sonnet 5 model row
without cost metadata (e.g. an agents.defaults.models runtime binding).
Guard with optional chaining — a costless model now falls through and gets
the canonical Sonnet 5 cost applied.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(models): normalize missing Sonnet 5 costs
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
* chore(plugin-sdk): refresh API baseline
* ci(plugin-sdk): update surface budgets
---------
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
The docs landing page and README still led with the retired cartoon
crawfish wordmark while the rest of the site uses the round mascot brand.
Swap in generated hero banners (dark/light), add the missing fourth
quick-start card (Connect a Channel), align the Mintlify backup palette
with the site coral tokens, and drop the old logo assets.
* fix(nvidia): refresh bundled featured models
* fix(nvidia): match featured model feed exactly
* fix(nvidia): remove transient feed detail
* fix(nvidia): correct super context window
* fix(nvidia): align auth choice expectation
* fix(nvidia): hide deprecated models from selection
Refresh the bundled featured catalog while retaining deprecated model metadata for exact-reference compatibility. Route NVIDIA onboarding and catalog picker surfaces through selectable-only provider builders.
* fix(nvidia): simplify featured model table
* fix(nvidia): restore shipped compatibility rows
* feat(voice): universal talk waveform driven by real audio levels
One shared Siri-style talk animation across iOS, watchOS, macOS, and
Android (TalkWaveformView + exact Compose port), replacing per-platform
fakes: synthetic speaking pulses, constant speech-detected power, static
Android bar rows, flat realtime listening. Listening/recording follow
live mic levels on every route; agent speech follows the real playback
envelope (AVAudioPlayer metering + playback-aligned PCM envelope +
WebRTC stats); voice-note recording shows a live capture wave.
* fix(android): order waveform imports and sync native i18n inventory
* chore(i18n): resync native inventory after rebase
Add explicit Simplified Chinese glossary terms for the separate device- and node-pairing workflows and preserve the four CLI commands verbatim during translation.
Thanks @zeuming.
* feat(ui): drop the desktop top bar in favor of sidebar navigation
The Control UI top bar only rendered the OpenClaw › agent › page breadcrumb
on desktop, duplicating the sidebar. Desktop now renders no topbar row; the
row returns solely as the chat split toolbar's backdrop. Narrow viewports
keep the header (drawer toggle, brand, command-palette search) and now show
the brand across the whole drawer range. Routing already uses pushState, so
browser back/forward traverses navigation.
* feat(macos): add back/forward controls to the dashboard window
Native titlebar buttons next to the traffic lights drive WKWebView history,
which carries the Control UI's pushState navigation; enabled state tracks
canGoBack/canGoForward via KVO and trackpad swipe gestures are enabled too.
Back/forward traversals to entries from a replaced gateway endpoint cancel
silently instead of opening a dead URL in the system browser.
* fix(macos): keep the dashboard drag strip off the web content column
With the desktop topbar row removed, the 28px mid-window drag region sat on
top of the content column (chat thread has no top padding) and swallowed
clicks as window drags. Shrink it to a 12px edge strip; the sidebar region
over the reserved native-chrome padding stays the primary drag surface.
* feat(usage): route claude-cli to Anthropic plan usage with plan label and billing
* feat(webchat): redesign context popover with plan-usage bars and API-cost gating
* fix(usage): match plan usage across CLI provider aliases and source plan label from synced auth profile
* docs(plugins): document plan metadata on usage auth token
* chore(usage): document provider-level billing attribution limits, fix overview test types
* fix(webchat): avoid map-spread in quota group collection
* test(webchat): deflake subscription popover reset fixture