Commit Graph

66965 Commits

Author SHA1 Message Date
dongdong
54be942e6b fix: avoid reminder-guard false positives for plain memory promises (#47586) (#93862)
* fix(auto-reply): narrow reminder guard remember matches

* test(auto-reply): prove reminder guard final payload

* fix(auto-reply): classify explicit reminder commitments

* fix(auto-reply): cover repeated reminder modals

* refactor(auto-reply): require explicit reminder actions

---------

Co-authored-by: Jasmine Zhang <jasminezhang@JasminedeMac-mini.local>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 06:29:29 +01:00
Peter Steinberger
3a482a71be fix(windows): remove findstr from restart probe (#101366)
* fix(windows): remove findstr from restart probe

Co-authored-by: Deepak Jain <deepujain@gmail.com>

* docs(changelog): note Windows restart probe fix

* docs(changelog): defer release note

---------

Co-authored-by: Deepak Jain <deepujain@gmail.com>
2026-07-07 06:29:13 +01:00
Ben.Li
f75782ee01 fix(ios): full-row Settings toggles on iOS 26 (#99888)
* fix(ios): use full-row Settings toggles on iOS 26

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

* chore(ios): refresh native string inventory

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 06:26:40 +01:00
Qiong
7db7487a5d fix(security): route temp workspaces through private OpenClaw temp root (#101224) (#101246)
* fix(security): route temp workspaces through private OpenClaw temp root (#101224)

* test(infra): skip POSIX mode proof on Windows

* chore: align release changelog before main sync

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-07 06:25:35 +01:00
Josh Avant
531c7a5f4c fix(android): preserve hardware Enter key sequences (#101360) 2026-07-07 00:25:33 -05:00
Peter Steinberger
5d7a451b15 fix(tests): reorder initializer arguments so the shared-kit test module compiles (#101372) 2026-07-07 06:25:06 +01:00
snowzlmbot
53580e13a4 fix(usage): preserve provider-billed zero totals (#101177)
* fix(usage): preserve provider-billed zero totals

* fix(usage): harden provider-billed cost provenance

* fix(openrouter): retry delayed generation metadata

* fix(openrouter): satisfy retry lint

* refactor(openrouter): consume streamed billed cost

* chore: keep release notes out of contributor PR

---------

Co-authored-by: snowzlmbot <293528334+snowzlmbot@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 06:22:28 +01:00
Ashd.LW.
70c2e837cd fix(gateway): show last error when status probe fails (#95902)
* fix(gateway): show last error when status probe fails

* fix(gateway): scope status log diagnostics

---------

Co-authored-by: wAngByg <wAngByg@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-06 22:22:19 -07:00
Peter Steinberger
01d6ea1f0e feat(browser): expose agent download actions (#101369)
* feat(browser): expose agent download actions

Co-authored-by: changcy <742592895@qq.com>

* chore: keep release notes in PR context

---------

Co-authored-by: changcy <742592895@qq.com>
2026-07-07 06:17:52 +01:00
Peter Steinberger
473b3cf789 fix(anthropic): keep error tool results non-empty (#101373)
Co-authored-by: Galin Iliev <5711535+galiniliev@users.noreply.github.com>
2026-07-07 06:17:27 +01:00
Josh Lehman
5d9a2b114f feat(context-engine): report compaction successors as typed session targets (#101182) 2026-07-06 22:14:46 -07:00
Peter Lee
6192b037bb fix(tui): deduplicate assistant messages across sessions.changed reload (#96980)
* fix(tui): suppress adjacent history-replay/live-final duplicate in ChatLog (#96967)

When sessions.changed triggers loadHistory(), assistant rows are replayed
via finalizeAssistant(text) without a runId. A late live final with the
same text and a runId can land immediately afterward, producing a visible
duplicate assistant reply.

Track the most recent history-replay assistant component in ChatLog and
suppress a following live final when the text matches and no other
component was appended in between. This is simpler and more targeted
than the prior event-handler approach because it operates at the
rendering layer where the duplicate is actually visible.

Fixes #96967

* fix(tui): bound replay-final dedupe window in ChatLog

* fix(tui): bound replay-final dedupe marker with TTL expiration

* fix(tui): satisfy no-promise-executor-return lint rule in chat-log test

* fix(tui): replace ChatLog text heuristic with runId-based surrender tracking

Drop the lastHistoryAssistant text-matching dedupe in ChatLog
(posed P1 false-suppression risk). Instead, track active runIds
surrendered to loadHistory() on sessions.changed 'new' — late
events for surrendered runs are suppressed by exact runId match.

Add ChatLog.hasStreamingRun() so the event handler can detect
when loadHistory restored a surrendered run as in-flight streaming.

Retain chatFinalizedRuns / chatFinalizedRunsWithDisplay from the
original fix for post-reload delta/error dedup of finalized runs.

Incorporates the precise surrender-tracking approach from closed
PRs #96979/#96986 while keeping the scoped ChatLog API minimal.

* fix(tui): render displayable late final for surrendered non-streaming run

When a sessions.changed 'new' surrenders an in-flight run and
loadHistory does not restore it as streaming, a late displayable
final must still be rendered — otherwise the user never sees the
assistant reply. Only suppress non-displayable finals (empty
message, no errorMessage).

Add focused test for non-displayable final suppression.

* test(tui): add coverage for empty in-flight restore + late displayable final

Covers the rank-up scenario from #96979: surrendered run restored
by loadHistory as empty streaming, late displayable final passes
through surrender check and renders to chatLog.

* fix(tui): suppress late finals for surrendered finalized runs to prevent history-replay duplicate

When sessions.changed 'new' fires, now surrender chatFinalizedRuns entries
too (as 'finalized'), not just sessionRuns ('in-flight'). This prevents
the finalized-before-reload history-replay duplicate: a late final for an
already-displayed run gets suppressed because the history-replay static
row covers the visible content.

In-flight surrendered runs still render displayable finals because the
user may not have seen the streaming text before the reload.

SurrenderedToHistoryRunIds is now Map<string,'in-flight'|'finalized'>
so the surrender check can branch on source. Move surrender check before
the finalizedRuns/chatFinalizedRuns guard so surrendered finalized runs
are routed correctly.

Add focused tests for history-replayed-visible (suppress) and
history-replay-missing (render) late finals.

* fix(tui): extend surrender coverage to sessions.changed reset reload path

Reset also calls clearTrackedRunState() + loadHistory() with the same
sessionKey, so late chat events for runs from the old session window
can race with the history replay the same way as 'new'. Surrender
sessionRuns and chatFinalizedRuns on both reasons (#96979 P1 rank-up).

* fix(tui): keep surrendered finalized marker after late delta to block later final

For finalized surrendered runs, a late delta must not clear the
surrender marker — otherwise a subsequent late final would slip
through and produce a duplicate. Only in-flight surrendered runs
clear the marker on delta (their final needs to render).

* fix(tui): gate session history reloads on persistence

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

* docs(changelog): note TUI external-run dedupe

* test(tui): type history load harness results

* test(tui): defer history results without async mocks

* chore(changelog): defer TUI note to release

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 06:06:53 +01:00
Jodok Batlogg
a2f95de750 feat(voice-call): support Twilio regions (#95832)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Jodok Batlogg <158125+jodok@users.noreply.github.com>
2026-07-07 06:05:31 +01:00
Vincent Koc
f643c9b2f8 perf(ci): raise Node shard parallelism to 28 (#101174) 2026-07-06 21:59:22 -07:00
Wynne668
78e4672d65 fix: pace delivery recovery after startup outages (#101118)
* fix: pace delivery recovery replays

* fix: preserve paced delivery recovery budget

* fix(delivery): preserve recovery deadline while pacing

* fix(delivery): coordinate recovery replay pacing

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 05:58:12 +01:00
Peter Steinberger
1898afe076 perf(test): overlap PowerShell installer exit checks 2026-07-07 00:57:24 -04:00
Peter Steinberger
ac24461252 fix(feishu): keep operator logs UTF-16 safe (#101364)
Co-authored-by: Wynne668 <ceng.wen@xydigit.com>
2026-07-07 05:54:50 +01:00
Vincent Koc
85d6d94afd refactor(memory): remove unused host SDK exports (#101362) 2026-07-06 21:54:06 -07:00
Peter Steinberger
90b680435a fix(minimax): clarify TTS volume boundary (#101359)
Co-authored-by: Quratulain-bilal <umayaimanshah@gmail.com>
2026-07-07 05:53:08 +01:00
shushushu
a596ca1795 fix(openai): allow fake-IP Realtime requests (#86526)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 05:48:57 +01:00
Peter Steinberger
e5798e5477 refactor(codex): raise app-server floor to 0.142, drop range compat, fix deferred spawn_agent steering (#101221)
* refactor(codex): raise app-server floor to 0.142 and drop range-compat protocol paths

* refactor(codex): model subagent mirror state as one map

* style(codex): format event-projector

* test(codex): drop unused shared-client test import

* refactor(codex): drop v1-era notification field aliases

* fix(codex): teach models to load deferred native spawn_agent via tool_search

* docs(codex): realign harness config tables

* docs(changelog): note Codex app-server protocol update
2026-07-07 05:48:53 +01:00
Wynne668
1ef4544871 fix(mattermost): strip internal tool-trace banners from outbound text (#98693)
* fix(mattermost): strip internal tool-trace banners from outbound text

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

* test(mattermost): prove outbound sanitizer send path

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 05:48:41 +01:00
Vincent Koc
d39d57edc3 ci(sdk): refresh plugin api baseline hash 2026-07-07 06:46:57 +02:00
Peter Steinberger
c5d42593be fix(anthropic): guard SDK client transport (#101357)
Co-authored-by: wangmiao0668000666 <wang.miao86@xydigit.com>
2026-07-07 05:45:49 +01:00
NickNMorty
59097783e2 fix(markdown-core): CJK-friendly emphasis flanking so **标签:**正文 renders bold (#101120) (#101230)
* test(telegram): reproduce CJK emphasis flanking bug

* fix(markdown-core): support CJK emphasis flanking

* fix(markdown-core): type CJK delimiter state (#101120)

* fix(markdown-core): mirror markdown-it Unicode whitespace in CJK delimiter override

Preserves markdown-it isWhiteSpace classification (U+3000, U+00A0, U+2000-200A, etc.) before forcing CJK-adjacent delimiter flags, and adds U+3000/U+2009 regressions. Addresses clawsweeper P1 finding on #101230.

* refactor(markdown): use maintained CJK flanking plugin

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 05:43:42 +01:00
Vincent Koc
bbd01c169e test(update): seed extended-stable install preflight 2026-07-07 06:35:44 +02:00
Vincent Koc
84e5327720 fix(text): keep bounded outputs UTF-16 safe (#101355)
Co-authored-by: Alix-007 <li.long15@xydigit.com>
2026-07-06 21:33:24 -07:00
lzw112
da20b65231 fix(telegram): add UND_ERR_CONNECT_TIMEOUT to PRE_CONNECT_ERROR_CODES (#101258)
* fix(telegram): add UND_ERR_CONNECT_TIMEOUT to PRE_CONNECT_ERROR_CODES

UND_ERR_CONNECT_TIMEOUT occurs during TCP/TLS connect handshake,
before any HTTP request data is sent. Adding it to the pre-connect
set allows isSafeToRetrySendError to safely retry sendMessage when
undici's connect timeout fires — the message was never transmitted.

* test(telegram): cover connect-timeout retry funnels

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 05:33:02 +01:00
Peter Steinberger
db42f05efe perf(test): batch source directory routing assertions 2026-07-07 00:27:23 -04:00
cxbAsDev
325cdb7f1a fix(infra): swallow mid-stream read errors in session-cost readJsonlRecords (#101062)
* fix(infra): swallow mid-stream read errors in session-cost readJsonlRecords

* fix(infra): keep usage cache strict on read errors

---------

Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-06 21:23:30 -07:00
Buddy Hadry
964fd53076 fix(update): keep self-updates on the running install's global root (#101228)
* fix(update): keep self-updates on the running install's global root

Package self-updates resolved their install target from `npm root -g`
even when the running install's package root was already known. In an
environment where PATH's npm does not belong to the running install's
Node tree (a launchd/systemd service PATH, or mixed Homebrew + nvm
setups), the probe points at a different global root — or derives a
brand-new one — so the update installs there, reports success, and
leaves the running install stale.

Observed in the wild: a gateway-managed `openclaw update --yes` on
2026.5.28 ran nvm's npm under Homebrew's node, npm derived its default
prefix from the realpathed execPath, and the update installed a full
copy into /opt/homebrew/Cellar/node/26.3.1/lib/node_modules/openclaw
("before": null — a tree that had never existed) while the running nvm
install stayed on the old version until a manual shell update.

resolveGlobalInstallTarget now prefers the package root's own global
root for npm targets; the `npm root -g` probe only decides the target
when no package root is known, and an ephemeral per-Node probe result
(Homebrew Cellar, nvm/n/asdf/volta version dirs — the same set
#93650 filters npm commands against) is never adopted.

* fix(update): infer global roots for scoped package roots

The running-root fallback missed scoped installs because
inferGlobalRootFromPackageRoot only accepted an immediate node_modules
parent. Hop over an @scope segment so node_modules/@scope/name resolves
to the same global root. Regression test: scoped package root with an
ephemeral probe now falls back to the running root.

* fix(update): scope running-root selection

* docs(changelog): note npm self-update root fix

* chore(changelog): defer release note

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 05:21:14 +01:00
Jason (Json)
9b2bb9c0a6 fix(models): refresh provider auth after CLI login (#101256)
* fix(models): refresh gateway auth after login

* docs(changelog): note model auth live refresh

* chore(changelog): defer release note

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 05:20:35 +01:00
Vincent Koc
835e6a7532 refactor(ui): localize unused module exports (#101339) 2026-07-06 21:20:18 -07:00
Marcus Castro
31432bf101 fix(reply): preserve steered audio for inbound TTS (#95596)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 05:18:36 +01:00
Vincent Koc
a7031832ec fix(browser): refresh extension relay token rotation 2026-07-07 06:12:50 +02:00
Peter Steinberger
7a5e5e1852 fix(codex): register the ring-zero crestodian tool directly instead of relying on a dead per-run plugin config override (#101281) 2026-07-07 05:08:08 +01:00
Vincent Koc
1d128b4dd2 fix(whatsapp): gate poll sends during reachout timelock 2026-07-07 06:03:09 +02:00
Peter Steinberger
b337164916 ci: fail Android PRs on ktlint formatting drift (#101275)
* style(android): fix ktlint drift in ShellScreen.kt

Formatting drift landed via #101161; :app:ktlintCheck fails on main
without this. Generated with ./gradlew :app:ktlintFormat.

* ci(android): add ktlint lane to the Android CI job

Android formatting drift kept landing on main because CI never ran
ktlintCheck (see the #100304 manual sweep). Adds an android-ktlint
matrix lane mirroring pnpm android:lint.

* chore(i18n): sync native inventory after ShellScreen.kt format

The ktlint format fix shifted line numbers tracked in
apps/.i18n/native-source.json; regenerated via pnpm native:i18n:sync.

* style(android): fix new ktlint drift in NodeRuntime and ChatHardwareKeyTest

Import-order/blank-line drift landed via the hardware-Enter changes
(#101321 and follow-up) while this PR was open — the exact recurrence
the new android-ktlint lane prevents. Generated with ktlintFormat;
native i18n inventory resynced for the shifted line numbers.
2026-07-07 05:01:26 +01:00
cxbAsDev
08349608f2 QA-lab credentials-admin response bound (#101131)
* fix(qa-lab): bound credentials admin response reads

* test(qa-lab): verify streamed response cancellation

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

* test(qa-lab): satisfy cleanup callback lint

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

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 04:56:07 +01:00
Marcus Castro
6ba19c5ad0 fix: block WhatsApp sends during reachout timelock (#101264) 2026-07-07 00:54:43 -03:00
Ayaan Zaidi
dc5d4138f9 test(gateway): isolate reload handler plugin records
The reload handler no-op config test enables fake timers and drains all timers. In cross-file non-isolated runs, server-startup-post-attach closes the shared state DB first, so this test reopens it through the managed config reloader's default installed-plugin record read.

That DB open schedules SQLite WAL maintenance at src/infra/sqlite-wal.ts:345 while fake timers are active, and vi.runAllTimersAsync spins the interval until Vitest aborts after 10000 timers. Mock installed plugin record reads in this handler test so the test owns only the reload debounce timer it is trying to drain.
2026-07-06 20:52:42 -07:00
Peter Steinberger
ad5b81e884 fix(memory): trust structured cron archive provenance (#101322)
Prevent user-authored [cron:] text from clearing reset or deleted session memory while preserving structured cron-run opacity.

Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
2026-07-07 04:52:21 +01:00
Yuval Dinodia
7900ff4731 fix(macos): preserve device identity storage (#101105)
* fix(macos): preserve device identity storage

Avoid selecting App Group identity storage when the running app lacks the matching application-groups entitlement, so unentitled macOS builds fall back to the legacy writable identity directory. Existing unrecognized identity files are now preserved instead of being replaced by a newly generated identity, matching the no-overwrite behavior already used for recognized invalid identity data.

* fix(macos): repair identity CI coverage

Limit the App Group entitlement probe to macOS builds so iOS keeps its existing App Group path behavior. Update the state-dir identity regression to assert the new no-overwrite contract for invalid identity-shaped files.

* fix(macos): migrate existing app group identity on legacy fallback

Unentitled macOS builds now migrate a readable App Group device identity
into the selected legacy store before falling back, so an upgrade preserves
the existing device id instead of minting a new one.

* fix(macos): migrate device auth store with identity on app group fallback

The app group to legacy identity migration now carries the sibling
device-auth store file, so an unentitled build keeps its stored device
tokens (keyed by the migrated deviceId) instead of re-pairing. The
process-immutable entitlement check is resolved once per process rather
than creating a SecTask on every state-dir lookup, and the migration
source API returns an identity+auth pair struct.

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 04:49:46 +01:00
Jesse Merhi
4112e3a0f3 Add native Signal reply quotes (#95718)
* feat(signal): quote native replies

* Fix Signal native reply edge cases

* fix(signal): tighten native reply quotes

* fix(signal): harden native reply quotes

* fix(signal): preserve approval reaction state

* fix(signal): target native replies to edited messages

* fix(signal): preserve plugin approval reaction kind

* fix(signal): keep edit event reply ids distinct
2026-07-07 13:49:13 +10:00
Vincent Koc
de8db74058 fix(android): handle hardware enter in chat sheet 2026-07-07 05:48:25 +02:00
Peter Steinberger
1834592be1 fix(auth): use OpenClaw lobster logo on OAuth callback pages
The shared provider OAuth success/error page (OpenAI/Codex and Anthropic
login flows) still embedded the legacy Pi logo SVG. Swap it for the
OpenClaw lobster mascot, matching ui/public/favicon.svg.
2026-07-07 04:48:01 +01:00
Vincent Koc
0fd69dc3d2 fix(wizard): honor configured auth dir in finalize 2026-07-07 05:41:02 +02:00
Peter Steinberger
780ca1d253 fix(android): send chat with hardware Enter (#101321) 2026-07-07 04:36:06 +01:00
Ayaan Zaidi
107a9d6d9b fix(qa-lab): skip runtime-context carrier in mock last-user matching 2026-07-06 20:34:01 -07:00
Ayaan Zaidi
c718afe247 refactor(agents): thread runtime-context carrier indexes 2026-07-06 20:34:01 -07:00