Commit Graph
64209 Commits
Author SHA1 Message Date
ff759b3f1a fix(outbound): report honest message delivery status (#99928)
* fix(outbound): report delivery status in best-effort message send results

Best-effort sends (forced on for implicit message_tool_only source
replies) previously collapsed failed and partial_failed durable send
results into a success-shaped MessageSendResult, so agents saw a
normal-looking envelope while delivery had actually failed. Surface
deliveryStatus, a formatted error, sentBeforeError, and per-payload
outcomes without changing throw semantics.

* fix(outbound): centralize message delivery outcomes

Co-authored-by: masatohoshino <g515hoshino@gmail.com>

* docs(changelog): split aggregate entries from code landing

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-05 07:18:03 -07:00
Peter SteinbergerandGitHub 060a5dbf88 test(logging): reset diagnostic capture state 2026-07-05 07:15:07 -07:00
61ac4ec8a0 fix(plugins): keep openclaw chunks native in jiti (#88384)
* fix(plugins): keep OpenClaw chunks native in jiti

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>

* docs(changelog): move plugin fix to unreleased

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-05 07:08:42 -07:00
3f1dea7875 fix(tui): render delta-only assistant streams (#83000)
* Fix delta-only assistant chat projection

* fix(tui): project delta-only assistant events

* fix(tui): sanitize merged assistant streams

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-05 06:59:40 -07:00
Peter SteinbergerandGitHub 2bc50d0656 feat: verify AI access during macOS onboarding before the first chat (#100288)
* feat(crestodian): add live-tested structured inference setup (detect/activate gateway RPCs)

* feat(macos): redesign onboarding around a verified Connect-your-AI step

* docs: describe the verified AI onboarding step and gemini setup ladder entry

* chore(macos): drop replaced OnboardingView+CrestodianSetup source

* fix(macos): keep the AI-detect error card from pairing with an unproven empty-state claim

* chore(protocol): regenerate Swift gateway models for crestodian.setup methods

* test(crestodian): give setup-inference mocks explicit params for test-types lane

* chore(i18n): sync native app string inventory for onboarding redesign

* chore(i18n): sync native app string inventory for onboarding redesign
2026-07-05 06:59:30 -07:00
Peter SteinbergerandGitHub a5fdc07121 fix(ui): simplify grouped tool activity (#100318) 2026-07-05 06:56:58 -07:00
Vincent Koc c3bcbf59b1 fix(plugin-sdk): refresh api baseline hash 2026-07-05 15:56:28 +02:00
16865d58ca fix(gateway): keep local CLI shared auth off device scopes (#96002)
* fix(gateway): keep local CLI shared auth off device scopes

* fix(gateway): preserve auth-none CLI device identity

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-05 06:52:56 -07:00
Deepak JainandGitHub 8a698108e0 fix(pre-commit): use single pytest dependency specifier (#91276)
[pytest>=8, <9] is parsed as two items; pip fails on '<9'.
Use ["pytest>=8,<9"] so pip gets one valid PEP 440 spec.
Pre-commit-only fix from closed #39109.
2026-07-05 06:51:26 -07:00
42464de58d fix(whatsapp): restore malformed credentials from backup (#99070)
* fix(whatsapp): wrap JSON.parse with try-catch in auth store and test helpers

Add defensive try-catch around JSON.parse calls in WhatsApp extension
to prevent crashes from corrupted state files.

- restoreCredsFromBackupIfNeeded: wrap creds.json/backup validation
  JSON.parse with try-catch; corrupted creds.json now properly falls
  through to backup restoration instead of skipping it entirely
- updateLastRouteMock: wrap JSON.parse with try-catch, initialize
  empty store on corrupted file

* test(whatsapp): add regression test for malformed creds.json longer than one byte

- Add a focused regression test for the exact case ClawSweeper
  flagged: readWebCredsJsonRawSync returns non-null content for
  files with stat.size > 1, so malformed JSON like "{x" (2 bytes)
  reaches JSON.parse — the inner try-catch now catches the parse
  failure and falls through to backup restoration
- Without this patch, JSON.parse("{x") throws to the outer catch
  and restoreCredsFromBackupIfNeeded returns false, skipping backup

🦞 diamond lobster: L2 evidence (real function call + real filesystem objects)

Ref. https://github.com/openclaw/openclaw/pull/99070

* fix(whatsapp): restore malformed creds from backup

Co-authored-by: LeonidasLux <LeonidasLux@users.noreply.github.com>

* docs(changelog): defer credential recovery entry to aggregate

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: LeonidasLux <LeonidasLux@users.noreply.github.com>
2026-07-05 06:50:28 -07:00
cd305b3b0c fix(tui): run new sessions through lifecycle hooks (#100241)
* fix(tui): run new sessions through lifecycle hooks

Co-authored-by: chunqiu <caopu@bupt.edu.cn>

* test(tui): wait for idle before PTY new-session checks

* docs(changelog): defer TUI batch entries

---------

Co-authored-by: chunqiu <caopu@bupt.edu.cn>
2026-07-05 06:48:05 -07:00
ccdbb70cf0 fix(whatsapp): preserve bot-authored quote replies (#94879)
* fix(whatsapp): cache bot's own outbound messages for quote metadata

When a user swipe-replies to a message the bot itself sent, the outbound
quote-key lookup misses the inbound-only metadata cache and falls back to
fromMe:false with the replying user's JID as participant. That mismatched
quoted.key is silently dropped by WhatsApp Desktop, so the bot's reply
bubble never renders there (it renders on Android, which is more lenient).

Cache quote metadata for the bot's own outbound messages at the send
choke point (rememberOutboundMessage) with fromMe:true and the bot's own
participant JID (group only; omitted for direct chats, matching WhatsApp
semantics). Future swipe-reply lookups then build a correct quoted.key.

Closes #91445.

* fix(whatsapp): preserve outbound quote metadata

Co-authored-by: Bartok9 <danielrpike9@gmail.com>

* docs(changelog): defer quoted replies entry to aggregate

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-05 06:47:50 -07:00
ba821e7220 fix(models): resolve provider-qualified aliases (#100209)
* fix(models): resolve provider-qualified aliases

Co-authored-by: Sahil Satralkar <62758655+sahilsatralkar@users.noreply.github.com>

* docs(changelog): defer TUI batch entries

---------

Co-authored-by: Sahil Satralkar <62758655+sahilsatralkar@users.noreply.github.com>
2026-07-05 06:44:54 -07:00
Peter SteinbergerandGitHub 245092dc3a feat(ios): add Apple Watch voice turns (#100283)
* feat(ios): add Apple Watch voice turns

* chore(ios): sync native i18n inventory

* fix(ios): preserve Watch message label
2026-07-05 06:40:03 -07:00
4c42815348 fix(whatsapp): bound reconnect catch-up replies (#80642)
* fix(whatsapp): bound reconnect catch-up replies

Co-authored-by: Vishal Jain <jainvishal2212@gmail.com>

* docs(changelog): defer reconnect entry to aggregate

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-05 06:34:57 -07:00
github-actions[bot] 80801be738 chore(ui): refresh control ui locales 2026-07-05 13:33:08 +00:00
Peter SteinbergerandGitHub db96218c05 feat(ui): show context usage details (#100264)
* feat(ui): show context usage details

* fix(ui): translate context usage labels

* fix(ui): translate context usage labels

* test: route e2e tempfile helper dependencies

* chore: drop superseded test routing change

* chore: drop superseded test routing change

* chore: drop superseded test routing change
2026-07-05 06:24:05 -07:00
c3b479b8e2 fix(voice-call): auto-respond to webhook transcripts (#100255)
Co-authored-by: dvy <dvy@users.noreply.github.com>
2026-07-05 06:21:45 -07:00
Peter SteinbergerandGitHub f9e194e4a1 fix(ui): keep login recovery accessible 2026-07-05 06:13:00 -07:00
f535b2a3ec fix(voice-call): normalize mapped proxy addresses (#100261)
Co-authored-by: Rohit <rohitjavvadi2@gmail.com>
2026-07-05 06:10:36 -07:00
Peter Steinberger f886ce7339 fix(ui): keep the connection-error disclosure collapsed by default
Restore the maintainer-requested collapsed <details> failure callout that
a parallel session reverted, adapt the e2e expectations, and drop the
PR-side CHANGELOG edit (changelog is release-generation-owned).
2026-07-05 06:09:31 -07:00
Peter SteinbergerandGitHub d54fc627bd docs(changelog): note mobile login improvements 2026-07-05 06:09:10 -07:00
1349027171 fix(google): normalize Live function declarations (#100260)
Co-authored-by: happydog-bot <bot@happydog.digital>
2026-07-05 06:08:23 -07:00
Peter SteinbergerandGitHub 99845cfddf fix(ui): mobile-optimize gateway dashboard login gate (#100208) 2026-07-05 06:07:52 -07:00
Peter SteinbergerandGitHub 9ba14b80ab fix(ios): own gateway setup deep-link delivery (#100328) 2026-07-05 06:01:15 -07:00
Peter SteinbergerandGitHub 8e84715b93 docs: document result fallback classifier contracts (#89558) 2026-07-05 05:56:17 -07:00
0ab7942956 refactor(plugins): narrow manifest stat cache reads (#87695)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-05 05:55:39 -07:00
Peter SteinbergerandGitHub a5f0a37373 docs: document compaction retry timeout contracts (#89585) 2026-07-05 05:54:41 -07:00
e29448df08 fix(gateway): stop terminal WhatsApp restart loops (#78511)
* fix(gateway): prevent restart loops after terminal WhatsApp disconnects

Track `terminalDisconnect` through the WhatsApp status controller, channel
runtime snapshot, and `ChannelAccountSnapshot` so the health-monitor and
the `ChannelManager` task-exit handler both skip auto-restart when Baileys
signals a terminal session end (loggedOut / connectionReplaced).

Adds a `terminal-disconnect` `ChannelHealthEvaluationReason` so the policy
layer returns a stable, named reason rather than falling through to
`not-running`, preventing unbounded WebSocket/heap growth on multi-tenant
gateways. Fixes #78419.

* fix(gateway): prioritize terminal disconnect recovery

Co-authored-by: openperf <16864032@qq.com>

* docs(changelog): move WhatsApp restart fix to unreleased

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-05 05:49:33 -07:00
66081c09ee fix(core): keep backend truncation UTF-16 safe (#100244)
* fix(core): use UTF-16-safe truncation for chat display, ACP stream relay, and native hook relay

* fix(core): narrow UTF-16 truncation repair

Co-authored-by: xialonglee <li.xialong@xydigit.com>

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>
2026-07-05 05:48:35 -07:00
Peter Steinberger 601b80c5f4 ci: pin website checkout branch 2026-07-05 08:37:59 -04:00
+2 deac98eb72 fix: harden small runtime and installer edge cases (#100258)
* fix(media): preserve dollar sequences in transcript echoes

Co-authored-by: uditDewan <udit.dewan21@gmail.com>

* fix(mcp): catch rejected gateway event handlers

Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>

* fix(auto-reply): support punctuated silent token prefixes

Co-authored-by: simon-w <weng.qimeng@xydigit.com>

* fix(discord): keep voice log previews UTF-16 safe

Co-authored-by: sunlit-deng <yang.jiajun1@xydigit.com>

* fix(clawrouter): bound usage response reads

Co-authored-by: 杨浩宇0668001029 <yang.haoyu@xydigit.com>

* fix(browser): bound CDP JSON response reads

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

* fix(status): include current time in session status

Co-authored-by: connermo <conner.mo@gmail.com>

* fix(installer): require Arch detection before pacman

Co-authored-by: Iliya Abolghasemi <gfaerny@gmail.com>

* fix(apps): default TLS gateway deep links to port 443

Co-authored-by: ben.li <li.yang6@xydigit.com>

* fix(infra): keep Undici terminated exceptions nonfatal

Co-authored-by: harjoth <harjoth.khara@gmail.com>

* fix(auto-reply): avoid Unicode-unsafe token spread

---------

Co-authored-by: uditDewan <udit.dewan21@gmail.com>
Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>
Co-authored-by: simon-w <weng.qimeng@xydigit.com>
Co-authored-by: sunlit-deng <yang.jiajun1@xydigit.com>
Co-authored-by: 杨浩宇0668001029 <yang.haoyu@xydigit.com>
Co-authored-by: hailory <hailory@xydigit.com>
Co-authored-by: connermo <conner.mo@gmail.com>
Co-authored-by: Iliya Abolghasemi <gfaerny@gmail.com>
Co-authored-by: ben.li <li.yang6@xydigit.com>
Co-authored-by: harjoth <harjoth.khara@gmail.com>
2026-07-05 05:33:11 -07:00
43fd44a28c fix(voice-call): share webhook replay tracking (#100263)
* fix(voice-call): share webhook replay tracking

Co-authored-by: xialonglee <li.xialong@xydigit.com>

* fix(voice-call): share webhook replay tracking

* fix(voice-call): share webhook replay tracking

* fix(voice-call): share webhook replay tracking

* fix(voice-call): share webhook replay tracking

* fix(voice-call): share webhook replay tracking

* fix(voice-call): share webhook replay tracking

* fix(voice-call): share webhook replay tracking

---------

Co-authored-by: xialonglee <li.xialong@xydigit.com>
2026-07-05 05:32:41 -07:00
Peter SteinbergerandGitHub 1a7f1133db chore: sync canonical autoreview skill (#100210)
* chore: sync canonical autoreview skill

* fix: preserve autoreview Cursor aliases

* fix: harden autoreview isolation

* fix: require explicit trust for Cursor reviews

* fix: preserve autoreview closeout integrity

* fix: close autoreview isolation gaps

* fix: reject incomplete autoreview inputs

* fix: isolate tool-less autoreview engines

* fix: fail closed for unsupported Droid isolation

* fix: fail closed for unsupported Droid isolation

* fix: fail closed for unsupported Droid isolation

* test: route package git fixture through temp dir tests

* fix: fail closed for unsupported Droid isolation

* fix: fail closed for unsupported Droid isolation

* fix: fail closed for unsupported Droid isolation
2026-07-05 05:31:13 -07:00
Vincent Koc fd2e4da006 fix(e2e): avoid browser cdp doctor race 2026-07-05 14:21:14 +02:00
Vincent Koc 931f13c20f test(gateway): add session ids to resolver fixtures 2026-07-05 05:20:55 -07:00
Peter Steinberger 4a2629ebe3 ci: pin ClawHub docs checkout branch 2026-07-05 08:17:32 -04:00
Peter Steinberger e490171ff2 fix: narrow secret target fast-path types 2026-07-05 08:08:37 -04:00
Peter Steinberger 1f484a8dbd test: speed up and stabilize full suite 2026-07-05 08:00:23 -04:00
Peter Steinberger 785ab74779 test(tooling): route package-git-fixture through the temp-dir helper plan
694f5ac7e5 added a temp-dir import to test/scripts/package-git-fixture.test.ts
without updating the top-level helper routing expectation, breaking the
checks-node-compact-small-whole-2 shard on main and PR merge runs (same
class as 824d8af0d6).
2026-07-05 12:56:00 +01:00
Vincent Koc 0fc29969d9 fix(e2e): provide crestodian rescue gateway token 2026-07-05 13:36:27 +02:00
Vincent Koc 694f5ac7e5 fix(e2e): stage ai runtime in git fixtures 2026-07-05 13:25:36 +02:00
Peter SteinbergerandGitHub 14eb460dd2 feat(scripts): serialize pr prepare gates and add remote Testbox test gate (#100242)
* feat(scripts): serialize pr prepare gates and add remote testbox test gate

Concurrent scripts/pr gate runs across .worktrees queued on the shared
heavy-check lock mid-test: the queued run's children hit the 10-minute
lock timeout while its unlocked build stage piled CPU load onto the
holder's vitest shards, which then stalled past the 120s no-output
watchdog and were SIGTERMed with zero real test failures (observed
landing PRs #99935/#100026 on a loaded maintainer Mac).

- scripts/pr-gates-lock.mjs holds the shared heavy-check lock for the
  whole local gate block; gate stages inherit the existing *_LOCK_HELD
  child contract, so concurrent gate runs now queue as whole units
  before their first command.
- OPENCLAW_PR_GATES_REMOTE=testbox runs the full-suite pnpm test gate on
  a Blacksmith Testbox via scripts/crabbox-wrapper.mjs (same delegation
  as check:changed). The tbx_ lease id and Actions run URL from the
  crabbox --timing-json report are recorded in .local/gates.env
  (REMOTE_GATES_*) and .local/prep.md. Local remains the default;
  pnpm build/check stay local.

Formatting verified with the primary checkout's oxfmt (hook bypassed:
linked worktree has no hydrated node_modules).

* fix(scripts): refresh the gate stamp when lease-retry gates rerun for a rebased head

The lease-retry path reran build/check/test for the rebased prep head but
left .local/gates.env describing the pre-push head, so prep.md/prep.env
attributed stale evidence (including the new remote testbox lease id) to
the pushed commit. Extract write_gates_env_stamp as the single stamp
writer, rewrite the stamp from the retry path for all modes, and re-source
gates.env in prepare_push after the push settles.

Found by autoreview (codex/gpt-5.5); formatting verified with the primary
checkout's oxfmt (hook bypassed: linked worktree has no node_modules).

* fix(scripts): harden remote PR gate evidence

* fix(scripts): serialize complete gate setup

* fix(scripts): clear stale docs gate proof
2026-07-05 04:23:58 -07:00
Peter SteinbergerandGitHub c00d79a1d1 fix(imessage): false group drop-all startup warning when groupAllowFrom is set without groups (#100046)
* fix(imessage): only warn about empty group allowlist when messages actually drop

With groupPolicy="allowlist", a non-empty effective groupAllowFrom admits
group messages even when channels.imessage.groups is empty (senderFilterBypass
in src/config/group-policy.ts), so the startup warning "Every inbound group
message will be dropped" fired as a false positive for that configuration.

The warning now mirrors the runtime gate's effective sender allowlist (same
allowFrom fallback + legacy chat-target merge) and fires only when both the
groups registry and the effective group sender allowlist are empty - the only
startup-provable drop-all config. The message now names groupAllowFrom as the
fix, since adding groups entries alone leaves the sender gate blocking.

Docs: describe the two group gates' warnings separately with per-warning
remedies instead of implying both fire for the same config.

* docs(imessage): format migration guide

* fix(imessage): warn on empty group sender allowlist

* docs: move iMessage fix to unreleased
2026-07-05 04:21:22 -07:00
cbb920c7d9 fix(qqbot): channel status keeps reporting connected after the gateway websocket dies (#100127)
* fix(qqbot): publish disconnected channel status when the gateway closes or gives up

The QQBot channel only ever set connected: true (onReady/onResumed);
no close path updated the status, so a fatal close (bot banned or
offline, 4914/4915) or reconnect exhaustion left channels.status
claiming a live connection forever, and the channel-health monitor
never saw connected=false for a dead gateway.

Thread an onDisconnected callback from GatewayConnection.handleClose
(fatal and pre-reconnect branches) and the reconnect-exhaustion path
through the engine/bridge layers into channel.ts, which now records
connected: false and, for fatal closes, the close reason as lastError.
The running flag stays owned by the gateway lifecycle store, matching
the sibling channel convention.

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

* fix(qqbot): import ChannelAccountSnapshot from the channel-contract subpath

The monolithic openclaw/plugin-sdk root entry is a legacy surface;
plugin-sdk contract guardrails and extension boundary checks require
focused subpath imports in bundled plugin sources.

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

* fix(qqbot): ignore stale socket closes from superseded gateway connections

A server-driven RECONNECT / INVALID_SESSION tears the old socket down
and brings up a replacement; the old socket's close event can arrive
after the replacement is live. Reacting to it again would tear down the
new socket and regress the connected status, so the close handler now
ignores closes from sockets that are no longer current.

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

* fix(qqbot): harden disconnect status recovery

* fix(qqbot): report opcode-driven reconnects

* fix(qqbot): keep fatal disconnect health visible

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-05 04:18:01 -07:00
Vincent Koc 57ca1b0254 fix(docker): materialize ai runtime package 2026-07-05 13:10:15 +02:00
Peter Steinberger 824d8af0d6 test(tooling): route e2e-shell-tempfiles through the temp-dir helper plan
17a1993f13 made test/scripts/e2e-shell-tempfiles.test.ts import the
temp-dir helper without updating the helper-routing expectation, so
checks-node-compact-small-whole-2 fails on every PR merge snapshot.
2026-07-05 04:05:05 -07:00
Vincent Koc 17a1993f13 fix(e2e): stop waiting for skipped skills prompt 2026-07-05 12:40:31 +02:00
Peter Steinberger 1403c64799 fix(protocol): regenerate Swift gateway models for approvalReviewerDeviceIds
The plugin-approvals schema gained approvalReviewerDeviceIds (#100251)
without refreshing the generated Swift model, so the bundled-protocol
drift gate fails on every PR. Mechanical pnpm protocol:gen:swift output.
2026-07-05 03:38:08 -07:00
Vincent Koc 8a8af77236 fix(plugin-sdk): refresh api baseline hash 2026-07-05 12:17:14 +02:00