Ports the openclaw.ai hero mascot animation (body float 4s, eye blink 3s,
antenna wiggle 2s, staggered claw snaps 4s) to every product surface that
shows the logo:
- web: ui/public/favicon.svg now carries SMIL animations, so every <img>
usage (login gate, sidebar brand, agent avatar fallback) animates with
no markup changes; CSS animations do not run in <img>-loaded SVGs.
- iOS: new OpenClawMascotView renders the canonical 120x120 vector via
Canvas + TimelineView (30fps, honors Reduce Motion); OpenClawProMark
uses it in onboarding, sidebar, and command center. Static PNG imageset
deleted (watch app keeps its own copy).
- Android: new OpenClawMascot composable (PathParser + infinite
transitions, honors the OS animator scale) replaces the static vector
drawable in onboarding and the chat/shell/voice headers, with tint
support for the monochrome header silhouettes. Drawable deleted.
* fix(cli): shell completion omitted command aliases like capability, chat, and cron create
* fix(cli): route the dead exec-approvals root alias and single-source alias path expansion
* fix(cli): complete nested aliases in Bash
Co-authored-by: Jack-dev-ops <chen.zegui@xydigit.com>
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Co-authored-by: Jack-dev-ops <chen.zegui@xydigit.com>
Preserve fullOutputPath plus partial-spill metadata when oversized tool-result details are summarized for persistence. This keeps aggregate elision from relabeling capped or source-truncated web_fetch spill files as complete after reload.
Write truncated web_fetch extracted content to owner-only private temp files using the shared Full output footer contract. Spills use the wrapped untrusted-content form, cap recoverable content at 2,000,000 chars, and label capped or source-truncated spills as partial instead of full output.
Keep aggregate elision recoverable by preserving existing spill pointers only when the original model-visible footer already disclosed the path. This commit also keeps partial-spill markers honest, handles JSON-escaped footers, and resolves full-clear markers from the original tool-result message after partial aggregate shrinking.
Summary:
- The PR replaces QA Lab suite gateway `fetchJson` success-path `response.json()` with shared `readProviderJsonResponse` and adds an oversized-response regression test.
- PR surface: Source +1, Tests +33. Total +34 across 2 files.
- Reproducibility: yes. Current main still has the unbounded `response.json()` success path in `fetchJson`, an ... l proof for oversized streamed bodies, early cancellation, normal parsing, and the focused regression test.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(scripts): satisfy oxlint in qa-lab suite gateway bound proof
- PR branch already contained follow-up commit before automerge: fix(qa-lab): bound suite runtime gateway JSON response reads
- PR branch already contained follow-up commit before automerge: chore: drop local proof script from qa-lab gateway bound PR
Validation:
- ClawSweeper review passed for head 8c0eb49fcb.
- Required merge gates passed before the squash merge.
Prepared head SHA: 8c0eb49fcb
Review: https://github.com/openclaw/openclaw/pull/99165#issuecomment-4868175663
Co-authored-by: NIO <nocodet@mail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
* fix(infra): formatDuration rolls over near-boundary values to the next unit
The raw float was checked against the boundary before rounding, so values
like 59.5s, 59m30s, and 23h59m30s rounded up to "60 seconds", "60 minutes",
and "24 hours" in session maintenance warning messages instead of "1 minute",
"1 hour", and "1 day". Round first, then check the unit boundary.
Closes#99978
* fix(infra): fix formatDuration progressive rollover in session maintenance warning
Round seconds first, then promote to the next unit only when the
rounded lower unit reaches its overflow threshold (60s->min, 60m->hr,
24h->day). The previous approach compared raw milliseconds against the
unit boundary before rounding, causing half-unit values like 30s, 30m,
and 12h to promote one unit too early.
Closes#99978
* test(infra): expose formatDuration via testing export for direct verification
* ci: retrigger checks
* ci: retrigger checks
* test(infra): keep duration formatter private
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Allow busy TUI sessions to forward prompts into the configured queue while
keeping queued-turn admission, cancellation, restart, and transcript ownership
consistent across the TUI, Gateway, and followup queue.
Co-authored-by: Sebastien Tardif <sebtardif@ncf.ca>
* fix(agents): use CJK-aware token estimation for tool results
Preserve the conservative 2 chars/token ratio for non-CJK tool results,
while using the accurate 4 chars/token ratio for CJK-heavy tool results.
This avoids false context-overflow errors for CJK content without changing
behavior for Latin/ASCII tool results.
- Add estimateCjkRatio() helper to cjk-chars.ts
- Choose tool-result chars-per-token based on CJK ratio (threshold 0.5)
- Add regression tests for CJK, mixed, and non-CJK tool results
* fix(agents): cover JSON and fallback payloads in CJK ratio pass
* test(agents): fix type cast for non-serializable tool-result regression
* fix(agents): make CJK tool-result estimates monotonic
---------
Co-authored-by: moguangyu5-design <moguangyu5-design@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Expose an opt-in Doctor lint finding for Linux Gateway hosts where a loaded user-level systemd gateway unit has systemd lingering disabled.\n\nValidation:\n- Targeted Doctor health contribution tests passed locally.\n- Exact-head hosted checks passed on 65ec5a0acf, including QA Smoke CI, Real behavior proof, security/CodeQL, check-shrinkwrap, and selected CI shards.\n- Crabbox Azure proof exercised a loaded user systemd gateway unit with Linger=no and observed the expected lint warning.\n\nCo-authored-by: giodl73-repo <166990625+giodl73-repo@users.noreply.github.com>
The non-interactive permission failure surfaces as acpx's
PermissionPromptUnavailableError, not AcpRuntimeError; acpx 0.11.2 throws
it unwrapped (isGenericInternalAcpErrorMessage only matches "Internal
error"). Matches the corrected fact in the acp-agents-setup rewrite.
Pre-commit hook bypassed with formatting proof: repo oxfmt + Mintlify
accordion repair already run on the file (worktree has no node_modules).
* fix(gateway): truncateCloseReason drops partial UTF-8 code point instead of emitting mojibake
Buffer.subarray at a raw byte offset can cut inside a multi-byte UTF-8
sequence. Node decodes the dangling continuation bytes as U+FFFD (3 bytes
each), so the re-encoded result can exceed the intended maxBytes cap —
violating the RFC 6455 close-reason size contract and surfacing garbled
text to clients.
Back up from the cut point to the nearest UTF-8 sequence start before
slicing (UTF-8 continuation bytes match 10xxxxxx; skip them).
Closes#99976
* fix(lint): remove unnecessary non-null assertion on Buffer index
* ci: retrigger checks
Fix qa-channel final reply preview delivery when a harness or plugin path calls deliver without dispatcher metadata. Verified with remote Testbox proof plus hosted PR checks.
* feat(slack): add ignoreOtherMentions channel config
Mirrors the existing Discord `ignoreOtherMentions` option for Slack
channels. When set on a channel entry, drop channel/group/MPIM messages
that mention another user or subteam but not this bot — the inverse of
`requireMention`. Useful in busy channels where the bot would otherwise
reply to side conversations.
Implementation lives in `prepareSlackMessage` right after the
`allowBots: "mentions"` bot-drop gate and before the `shouldRequireMention`
non-mention drop, so it integrates with the new `messageIngress` ingress
pipeline. The gate is conditional on `canDetectMention` (botUserId
resolvable via `auth.test` or explicit mention regexes configured) to
avoid false drops when we have no reliable way to tell bot vs non-bot
mentions apart.
Slack implicit mentions (thread participation) are intentionally NOT
respected here — they fire for every message in a bot-participated
thread, so honoring them would defeat the feature in any active thread.
The gate matches on `wasMentioned` (explicit) and `hasAnyMention`, with
the existing `shouldBypassMention` override (e.g. authorized commands)
also respected.
Includes config types, zod schema, channel-config resolution,
prepare-message implementation, full test coverage in
`prepare.test.ts`, regenerated channel + docs baselines, and Slack
docs entry.
* refactor(slack): harden other-mention filtering
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Type.Record(Type.String(), Type.Any()) serializes via TypeBox to an empty nested value schema (patternProperties: { "^.*$": {} }). AWS Bedrock's strict tool-schema validation rejects the empty sub-schema, breaking all agent turns for Bedrock-backed Anthropic users with Feishu bitable tools enabled.
Replace the three affected free-form field maps (create_record, update_record, create_field) with an explicit non-empty FlexibleFieldValue value schema that still accepts any JSON value. Type.Unknown() is avoided because it also serializes to an empty schema. Adds regression coverage asserting the emitted value schema is non-empty.
Co-authored-by: TwinsLee <1460694+TwinsLee@users.noreply.github.com>
Tool calls in Control UI chat rendered as triple-nested cards: activity
group card + tool-shell bubble chrome + gradient summary pill with a
0 8px 22px drop shadow. Collapsed rows now render as flat single-line
rows with ellipsis, the activity group uses a flat header plus a left
rule, and expanded detail keeps soft tinted blocks without card chrome.
Also deletes the dead legacy .chat-tool-card__details/__output CSS and
the unused renderToolCardSidebar path with its never-taken
renderToolDataBlock branches.
Closes#99760