Commit Graph

64199 Commits

Author SHA1 Message Date
Peter Steinberger
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
Bartok
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
Peter Steinberger
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 Steinberger
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
Vishal Jain
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 Steinberger
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
Peter Steinberger
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 Steinberger
f9e194e4a1 fix(ui): keep login recovery accessible 2026-07-05 06:13:00 -07:00
Peter Steinberger
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 Steinberger
d54fc627bd docs(changelog): note mobile login improvements 2026-07-05 06:09:10 -07:00
Peter Steinberger
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 Steinberger
99845cfddf fix(ui): mobile-optimize gateway dashboard login gate (#100208) 2026-07-05 06:07:52 -07:00
Peter Steinberger
9ba14b80ab fix(ios): own gateway setup deep-link delivery (#100328) 2026-07-05 06:01:15 -07:00
Peter Steinberger
8e84715b93 docs: document result fallback classifier contracts (#89558) 2026-07-05 05:56:17 -07:00
Vincent Koc
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 Steinberger
a5f0a37373 docs: document compaction retry timeout contracts (#89585) 2026-07-05 05:54:41 -07:00
Chunyue Wang
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
Peter Lee
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
Peter Steinberger
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
Peter Steinberger
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 Steinberger
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 Steinberger
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 Steinberger
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
Masato Hoshino
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
Ben.Li
8df18050d5 fix(android): default manual TLS port to 18789 except Tailscale hosts (#99865)
* fix(android): default manual TLS port to 18789 except Tailscale hosts

Match iOS resolveManualPort so blank-port TLS manual connects use 443 only for .ts.net hosts and 18789 elsewhere; update Connect port hints accordingly.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(android): sync i18n and align manual port hints with resolver

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(android): unify blank manual gateway ports

* fix(android): normalize tailnet port hints

* refactor(android): drop legacy connection UI delta

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-05 03:17:08 -07:00
Peter Steinberger
3f493aa6d0 chore(android): add deterministic chat streaming replay test harness (#100200)
* test(android): add deterministic chat streaming replay harness (#100196)

* test(android): emit protocol-valid chat replay events
2026-07-05 03:16:55 -07:00
Peter Steinberger
5af24d16bf chore(ci): fail CI when gateway events go unhandled by the mobile apps (#100206)
* ci: guard gateway protocol event coverage for iOS/Android clients (#100198)

Adds scripts/check-protocol-event-coverage.mjs, which derives the
server->client event catalog from GATEWAY_EVENTS in
src/gateway/server-methods-list.ts, extracts the events each mobile app
handles from Swift/Kotlin dispatch sites, and fails on gateway events no
client handles unless allowlisted with a reason in
scripts/protocol-event-coverage.allowlist.json. Wired as
pnpm check:protocol-coverage in the CI guards shard.

* fix(ci): scope Kotlin event extraction to handle*Event dispatch functions (#100198)

Bare event == "..." literals in predicate helpers outside the dispatch
path (gatewayEventInvalidatesNodesDevices in NodeRuntime.kt, which has no
production caller) counted as Android coverage, silently masking that
node.pair.requested/resolved have no live handler. Kotlin extraction now
only reads when(event) labels and event comparisons inside fun
handle*Event(...) bodies; node.pair.* moved to the Android allowlist with
a truthful reason. Swift extraction stays tree-wide because consumption
there always reads .event off a received EventFrame.

* fix(android): remove dead node pairing event helper

* fix(ci): preserve protocol allowlist parse errors

* test(ci): align tooling import plan
2026-07-05 03:06:52 -07:00
Vincent Koc
29857e25aa fix(tui): keep skill approvals in the terminal (#100251)
* fix(tui): keep skill approvals in the terminal

* fix(tui): keep skill approvals in the terminal
2026-07-05 03:06:44 -07:00
Vincent Koc
10ca94ef1a fix(gateway): reuse startup channel manifests 2026-07-05 11:58:58 +02:00
Peter Steinberger
7137be38e8 docs(maint): raise PR close batch limit (#100253)
* docs(maint): raise PR close batch limit

* docs(maint): raise PR close batch limit
2026-07-05 02:57:18 -07:00
Peter Steinberger
49302fcb7d fix: DashScope and Moonshot endpoints misclassified as custom when the provider plugin is not installed (#100125)
Externalized provider plugins (qwen, moonshot, zai, deepseek, groq, cerebras, chutes) are excluded from dist packaging, so their manifest-declared endpoint classes were invisible to installed gateways and built source checkouts: DashScope/Moonshot-class base URLs classified as custom, breaking image prompt placement, streaming-usage and developer-role compat defaults, and deterministically failing image.test.ts / model-compat DashScope cases after pnpm build. The official external provider catalog now mirrors each plugin's providerEndpoints and provider attribution appends catalog metadata after installed/bundled manifests (first match wins; repo-bundled catalog only, hosted feeds never influence classification). Includes a catalog-manifest mirror contract test and a dist-simulation regression test.
2026-07-05 02:53:51 -07:00
Peter Steinberger
0720b322fe fix(ios): remove debug icon outer rim (#100259) 2026-07-05 02:50:07 -07:00
Peter Steinberger
78685aec46 fix(ui): center terminal new-session button (#100256) 2026-07-05 02:36:12 -07:00
LZY3538
e6ec74c254 fix(compaction): preserve Anthropic context usage (#99864) 2026-07-05 02:33:43 -07:00