* 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>
The dreams page's generic sleeper is replaced by the agent's own seeded
lobster (same look system as the sidebar pet) rendered with a new
sleeping option: pupils hidden, closed-lid curves inline-visible so the
cameo needs no lobster-pet CSS context. Palette vars are supplied by
the cameo wrapper. Deletes the bespoke dreams svg.
December visitors can roll a santa hat and Oct 20-31 a pumpkin (extra
weighted entries joining the accessory pool on the right dates; one
roll either way so seeds keep the rest of their look). On Nov 24 - the
repository's birthday (GitHub created_at 2025-11-24) - every visitor
dresses as the classic-logo retro with a party hat and confetti-colored
z's. Look generation takes an injectable date so seasonal behavior is
pure and testable; existing look tests pin a neutral date.
* 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
~12% of loads plan a molt: during the first idle act the pet shivers,
squashes, and pops one size tier bigger, leaving its old shell behind
as a frozen, washed-out silhouette that fades over a minute. The shell
keeps the true pre-molt size, respects dismissal and the visits
setting, and its timer resets with the seed. ~4% of loads are twin
days: a mini copycat ('<name> Jr.') tags along on the parent's trailing
side and mirrors every act a beat later via an act-delay variable
threaded through the act animations. Rare-event plans are pure
per-seed functions so tests probe them directly.
Every pet gets a seeded name shown via native hover tooltip (rare
palettes carry signature names: Goldie, Boo, Picasso, Patches, Lantern,
Blueberry, OG). A busy->idle mode flip now earns a cheer act (double hop
with a mid-air twirl, claws up) instead of a startle, so the lobster
celebrates finished runs. Three fast pokes make it grumpy for a minute
(angry brows + frown overlay); ten pokes send it off in a huff until a
later scheduled visit (offline pets are on duty and never huff).
Visits between 22:00 and 06:00 local always act sleepy regardless of
personality.
* fix(telegram): deliver content instead of throwing when tag overhead fills chunk
When HTML tag overhead (open + close tags) exceeds the chunk limit,
appendText threw an error causing complete message delivery failure.
Instead, force the text into the chunk so the message is still delivered
even if the chunk slightly exceeds the limit.
Closes#102910
* fix(telegram): strip rich formatting when tag overhead fills chunk
When HTML tag overhead fills an empty chunk with no room for text, strip
rich formatting and retry as plain text instead of delivering an oversized
chunk or throwing. Orphan close tags from the stripped formatting are
skipped to keep the output well-formed and within the chunk limit.
This preserves the existing plain-text fallback paths in send.ts and
rich-message.ts.
Closes#102910
* fix(telegram): preserve delivery when HTML tag overhead overflows
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(gateway): guard thinkingLevel re-validation against only relevant patch fields
The second thinkingLevel validation block used `if (next.thinkingLevel)`,
which enters on ANY patch when the session already has a thinkingLevel
inherited from the existing entry. This caused unnecessary model catalog
loading and could silently delete or modify the existing value.
Fix: change guard to also check that the patch explicitly touches
thinkingLevel or changes the model (which may alter the effective
provider/model that thinkingLevel is validated against).
Ref: BUG-002 (local finding)
Co-Authored-By: Claude <claude@anthropic.com>
* test(gateway): prove session patch catalog isolation
---------
Co-authored-by: Claude <claude@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(browser): reject ambiguous tab references
Co-authored-by: llagy007 <0668001470@xydigit.com>
* fix(browser): close tracked tabs by raw target id
* fix(browser): harden raw tab cleanup routing
* test(browser): type raw close request mock
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Carry typed forum/media parent metadata through the message-send path so implicit thread creation uses the configured default archive duration.
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* refactor(android): align talk levels and thinking state with iOS/macOS
TalkAudioLevel.kt ports OpenClawKit's level scale exactly: PCM16 RMS
through the shared 50 dB window replaces mean-abs (mic/talk/playback)
and linear peak (voice notes), so Android waveforms read identically to
iOS/macOS at the same loudness. The waveform's Thinking phase now comes
from a typed awaitingAgent StateFlow set alongside every status change
in TalkModeManager instead of the UI matching status string literals;
forgetting the flag at a new status site fails safe to Listening/Idle.
* fix(android): keep awaiting-agent flag intact on no-op status republishes
* chore(i18n): resync native inventory
Reasoning header drops the '(Default is Off)' reset text and the verbose
'Default (Off)' value: inherited defaults render as a muted level word with
no reset, overrides render strong with an icon-only reset. The Faster/
Smarter scale row is removed along with its i18n keys, and the menu gets
tighter dimensions (392px wide, shorter model rows). Screen readers keep the
verbose default phrasing via aria-valuetext.
* fix(agent-core): keep file info basename on Windows paths
* fix(agent-core): use platform path basenames
* chore: sync PR branch before changelog
* docs(changelog): credit Windows file metadata fix
* fix(agent-core): use platform path basenames
* test(agent-core): isolate Windows shell discovery
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
The sidebar pet becomes a seeded guest: ~25% of loads never get a
visit, the rest see arrivals after 15s-3min, stays of 1.5-5min, and
returns after 6-18min, all from a dedicated seeded RNG stream. Each
arrival re-rolls its perch: the classic ledge above the footer divider
or standing inside the footer bar next to the gateway status dot
(size-clamped). Gateway disconnects always summon the pet - even shy
ones - until the connection returns. Right-click shoos it away for the
rest of the page load and also beats offline summons. A new 'Lobster
visits' toggle in Settings -> Appearance (client-side UiSettings pref,
only opt-out persists, live via the theme.refresh republish channel)
disables visits entirely. New quickSettings.appearance i18n strings
synced across locale bundles.
* feat(ui): redesign cron/tasks summary cards and give both nav routes distinct icons
* fix(i18n): translate new control-ui strings and resync raw-copy baseline