Commit Graph

66940 Commits

Author SHA1 Message Date
Masato Hoshino
e7ca90e3af fix(hooks): flag hook event names that no core trigger emits (#99456)
* fix(hooks): flag hook event names that no trigger site emits

* docs(hooks): clarify bare family subscriptions in unknown-event note

* fix(hooks): word unknown-event diagnostics around core-emitted keys

* fix(hooks): apply unknown-event advisory to legacy config handlers too
2026-07-06 01:30:13 -07:00
Vincent Koc
3ea875b5d8 docs(changelog): remove generated main entries 2026-07-06 10:28:09 +02:00
cxbAsDev
d6c880ae92 fix(link-understanding): honor global or largest model timeout for link fetches (#100660) (#100731) 2026-07-06 09:26:39 +01:00
Vincent Koc
e27202a5c2 test(channels): satisfy bundled source guard lint 2026-07-06 01:26:03 -07:00
lin-hongkuan
9607c3a2bf fix(discord): preserve text after oversized uploads (#99577)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: lin-hongkuan <lin-hongkuan@users.noreply.github.com>
2026-07-06 09:25:05 +01:00
Masato Hoshino
9b0c3abbca improve(status): group disabled plugins by reason in /status plugins (#99598) 2026-07-06 01:22:42 -07:00
NianJiu
1a07bd760c fix sessions_send Telegram topic guard (#99845)
Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>
2026-07-06 01:22:26 -07:00
Masato Hoshino
ef1c83274d improve(health): surface dead-lettered delivery queue entries (#99842)
* improve(health): surface dead-lettered delivery queue entries

Deliveries that exhaust retries are moved to the failed status in the
SQLite delivery queue for diagnostics, but no health surface ever read
them back: openclaw health stayed all-green while messages sat
dead-lettered, visible only in gateway logs. Add a per-queue failed
count accessor and report dead-lettered entries in the health snapshot
(JSON field plus a warning line), following the existing plugin and
context-engine health section pattern. Observer-only: no retry, purge,
or behavior change.

* test(health): cover snapshot and CLI dead-letter reporting

Add getHealthSnapshot coverage against an isolated state dir, an
openclaw health text-output test for the warning line, exact
oldest-failure timestamp assertions via fake timers, and a debug log
when the delivery-queue health read fails.

* fix(health): recompute dead-letter counts for cached gateway responses

The gateway health handler can serve a cached snapshot for up to a
refresh interval, so a delivery dead-lettered after the cache was
filled stayed hidden from openclaw health. Recompute the delivery
queue summary in mergeCachedHealthRuntimeState alongside the existing
context-engine and model-pricing live merges, and cover the cached
handler path with a regression test.
2026-07-06 01:22:16 -07:00
chenyangjun-xy
a152a45284 fix(usage-bar): bound template file cache to prevent unbounded watche… (#98990)
* fix(usage-bar): bound template file cache to prevent unbounded watcher growth

Add MAX_CACHED_TEMPLATE_FILES=64 limit; evict the oldest entry (closing
its fs.watch watcher) before allocating a watcher for a new key when
the cache is full.

Eviction runs before watcher allocation so we never create a watcher
only to close it immediately. Eviction triggers only when inserting a
new key (!fileCache.has(path)) — retries for an existing key must
not evict other entries.

Fixes #98960

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

* refactor(test): replace mutable dir variable with cleanup-stack pattern in template.test.ts

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

* chore(test): add curly braces for eslint curly rule

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

* test(usage-bar): register watcher proof cleanup

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-06 01:21:32 -07:00
Vincent Koc
0c38082c6d fix(maint): use canonical hosted gate verifier 2026-07-06 01:18:19 -07:00
Peter Steinberger
8d1668c441 fix(ios): harden Apple Watch pairing activation (#100732) 2026-07-06 09:16:02 +01:00
chenxiaoyu209
5e64c61368 fix(google): resolve thought_signature gate for Gemini latest aliases (#100605) 2026-07-06 09:12:35 +01:00
Andy Ye
e24d4426fe Run memory flush before preflight compaction (#84792)
* Run memory flush before preflight compaction

* test: align current-main provider and cron checks

* fix(reply): align memory flush ordering on current main

* fix(reply): preserve memory flush cycle invariant

* fix(reply): recover exhausted memory flushes

* fix(reply): preserve preflight failure handling

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 09:11:22 +01:00
Momo
e0d23cfc5a fix(telegram): dedupe visible assistant prompt context (#100573)
Summary:
- Merged fix(telegram): dedupe visible assistant prompt context after ClawSweeper review.

Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(telegram): align directive reply prompt timestamps

Validation:
- ClawSweeper review passed for head 5c4cc7245e.
- Required merge gates passed before the squash merge.

Prepared head SHA: 5c4cc7245e
Review: https://github.com/openclaw/openclaw/pull/100573#issuecomment-4890518598

Co-authored-by: momothemage <niuzhengnan@163.com>
Approved-by: momothemage
2026-07-06 08:11:08 +00:00
SunnyShu
89104d74ba fix(agents): include sender in duplicate-user-message dedup key (#98336)
* fix(agents): include senderId in duplicate-user-message dedup key (#98336)

* refactor(agents): harden sender-aware compaction dedup

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 09:08:32 +01:00
Vincent Koc
336a78b01e docs(changelog): remove generated release-note entries 2026-07-06 10:07:51 +02:00
cxbAsDev
6ae4bbafb0 fix(transcripts): handle read stream errors gracefully in TranscriptsStore (#100524)
* fix(transcripts): handle read stream errors gracefully in TranscriptsStore

* proof(transcripts): add real behavior proof script for store stream error catch

* fix(transcripts): reject with Error in stream error handler

* proof(transcripts): replace wrapper with real EISDIR stream error proof

* fix(transcripts): reject non-ENOENT stream errors after stream close
2026-07-06 01:07:32 -07:00
Alix-007
bf5c9d1748 fix(feishu): bound Feishu API JSON response reads to prevent OOM (#97782)
* fix(feishu): bound Feishu API JSON response reads to prevent OOM

Replace the bare `response.json()` in `fetchFeishuJson`
(`extensions/feishu/src/app-registration.ts`) with a `readResponseWithLimit`
call capped at 16 MiB. A misconfigured or adversarial Feishu endpoint that
streams an unbounded body previously had no defence; the bounded reader now
cancels the stream at the cap and throws a labelled `feishu.api` error.

Tests: over-cap (32 MiB stream, no Content-Length — stream cancelled, error
matches feishu.api), under-cap (chunked valid JSON — parsed and returned),
and malformed-JSON (labelled feishu.api error). All five tests pass.

* fix(feishu): delegate JSON reads to provider helper

* test(feishu): add real node:http server proof for readProviderJsonResponse bound

* test(feishu): fix lint errors in real HTTP server proof (curly + no-promise-executor-return)

* test(feishu): prove bound reads through SSRF guard

* fix(feishu): satisfy overloaded LookupFn type in hermetic test lookup stub
2026-07-06 01:06:08 -07:00
Peter Steinberger
34c26a8047 fix(channels): resolve source-only bundled entries (#100737)
Co-authored-by: Peter Steinberger <steipete@openai.com>
2026-07-06 09:05:47 +01:00
Peter Steinberger
eae4000c38 fix(control-ui): preserve assistant download filenames (#100728)
* fix(gateway): preserve assistant media filenames

Co-authored-by: Rovy <xiaxia@rovy.dev>

* test(ui): verify assistant media download filename

---------

Co-authored-by: Rovy <xiaxia@rovy.dev>
2026-07-06 09:04:22 +01:00
Vincent Koc
535ab05dcd test(release): reach Claude ACP transcript fallback 2026-07-06 01:00:32 -07:00
Super-Cabbage
5acabfd897 fix(commands): guard shortenText against non-positive maxLen (#99917)
* fix(commands): guard shortenText against non-positive maxLen

* fix(commands): guard shortenText against non-positive maxLen

---------

Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
2026-07-06 01:00:08 -07:00
NIO
3b189dfd34 fix(qa-lab): bound Telegram live transport JSON response reads (#99151)
* fix(qa-lab): bound Telegram live transport JSON response reads

* fix(scripts): satisfy oxlint in qa-lab telegram bound proof

* chore: drop local proof script from qa-lab telegram bound PR

---------

Co-authored-by: NIO <nocodet@mail.com>
2026-07-06 00:59:59 -07:00
lin-hongkuan
d0fdfe845b fix(codex): return JSON-RPC codes for handler errors (#100713)
Co-authored-by: lin-hongkuan <lin-hongkuan@users.noreply.github.com>
2026-07-06 08:59:20 +01:00
lwy-2
f1f8c1ed16 fix(providers): bound successful OAuth and webhook responses (#98098)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 08:58:58 +01:00
Yzx
3d837cce23 fix: surface delayed sessions_send delivery failures (#99907) 2026-07-06 00:58:32 -07:00
wm0018
e53131ea1c fix(mistral): correct model id typo in usesReasoningEffort helper (#100688)
* fix(mistral): correct model id typo in usesReasoningEffort helper

* chore: re-trigger CI

* test(mistral): cover medium reasoning effort

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 08:57:27 +01:00
xingzhou
cecb6cf600 fix(openai): keep missing-auth hint on default model (#100579) 2026-07-06 08:56:20 +01:00
Vincent Koc
bfdd60bd30 test(release): match pinned Claude CLI setup (#100723)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 08:53:32 +01:00
cxbAsDev
c9a0783922 fix(secrets): suppress unhandled stdout/stderr stream errors in exec resolver (#100521)
* fix(secrets): suppress unhandled stdout/stderr stream errors in exec resolver

* proof(secrets): add real behavior proof script for exec resolver stream error catch

* proof(secrets): replace wrapper with real exec resolver stream error proof

* style: apply oxfmt to changed files
2026-07-06 00:52:22 -07:00
Peter Steinberger
2585d6b2e8 fix(ui): localize cron action menu 2026-07-06 03:48:46 -04:00
ZOOWH
5c7c2961fb fix(tui): preserve balanced parentheses in markdown link URL extraction (#100661) (#100697)
The markdown link regex character class [^)\s>]+ stopped at the first
closing paren, truncating URLs like wikipedia.org/wiki/URL_(disambiguation)
at the opening (. Replace with a balanced-parens pattern that supports
one level of parenthetical groups inside the URL path.

Add trimUnbalancedTrailingParens for bare URLs in prose where a trailing
) belongs to surrounding punctuation rather than the URL itself.
2026-07-06 00:47:38 -07:00
lzw-xydt
7b68306949 fix(telegram): add missing "edit" retry context for editMessageTelegram (#100543) 2026-07-06 00:46:37 -07:00
Leonidas Lux
be48a430bf fix(tools-manager): replace spawnSync extraction with safe extractArchive API (#98988)
* fix(tools-manager): replace spawnSync extraction with safe extractArchive API

Replace the synchronous spawnSync-based archive extraction (unzip/tar)
with the safe extractArchive from @openclaw/fs-safe, which enforces:

- maxArchiveBytes: 100 MB (prevents oversized compressed input)
- maxExtractedBytes: 500 MB (prevents decompression bomb OOM)
- maxEntries: 1000 (prevents zip bomb from exhausting inodes)
- timeoutMs: 60,000 (prevents hung extraction)
- Path traversal and symlink/hardlink protection (built-in)

Removes 5 functions (formatSpawnFailure, runExtractionCommand,
extractTarGzArchive, getWindowsTarCommand, extractZipArchive) and their
associated imports, replacing them with a single async wrapper around
the existing @openclaw/fs-safe infrastructure (re-exported from
src/infra/archive.ts).

Net: -83 lines, + security boundaries across all platforms.

* fix(tools-manager): add download-stream byte cap and regression tests

Add a maxBytes parameter to downloadFile that checks Content-Length
before reading the body and enforces a streaming byte cap during
transfer, so oversized archives are rejected before hitting disk.

Extract MAX_ARCHIVE_BYTES as a module-level constant shared between
downloadFile and extractArchiveSafe, ensuring both gates use the same
100 MB limit.

Add two regression tests:
- rejects downloads with Content-Length exceeding the archive byte cap
- accepts downloads with Content-Length under the archive byte cap

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

* fix(tools-manager): replace PassThrough with Transform stream limiter

- Replace PassThrough data listener with Transform that rejects overflow
  chunks *before* they are forwarded to the file pipeline, preventing the
  offending chunk from landing on disk.
- Add completion guard and cleanup of partial downloads on failure so
  downloadTool does not leave a partial archive on disk.
- Add real behavior proof: test output and live fd/rg download and
  extraction through the safe extractArchive code path.

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

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

* fix(tools-manager): replace PassThrough with Transform stream limiter

Uses a Transform to reject overflow chunks *before* they are forwarded
to the file pipeline (a PassThrough data listener acts *after* emission
and cannot prevent the offending chunk from landing on disk).

Wraps the pipeline in a completion-guarded block so that partial
downloads are removed when the transfer fails mid-way.

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

* fix(agents): harden helper archive downloads

* fix(agents): preserve archive extraction cause

---------

Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-06 00:43:03 -07:00
Vincent Koc
23f492fcaf test(release): cover pinned Claude CLI install 2026-07-06 00:41:41 -07:00
ZOOWH
b8b946e43d fix(infra): include update timeout in managed-service handoff parent exit wait (#99695)
* fix(infra): include update timeout in managed-service handoff parent exit wait

The handoff parent exit grace was hard-coded to 60s regardless of
the overall update timeout. When the gateway is draining active
tasks, 60s is often not enough, causing
managed-service-handoff-parent-timeout.

Use the existing timeoutMs parameter as a floor for the parent
exit wait so callers can extend it for long-running drains.

Refs #99666

* fix(infra): add shutdown reserve to managed-service handoff parent exit wait

* fix(infra): align update handoff with restart drain

Co-authored-by: 徐闻涵0668001344 <xu.wenhan1@xydigit.com>

* fix(infra): arm restart with managed handoff

* fix(infra): use live restart drain for auto-update

* fix(infra): force process exit for managed updates

* fix(infra): normalize managed handoff restart delay

* test(infra): cover handoff drain argument

* fix(gateway): upgrade accepted restarts for managed updates

* fix(gateway): bound managed update restart upgrades

* test(gateway): stabilize managed update handoff proof

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 08:40:14 +01:00
Peter Steinberger
f6f3423ce9 refactor(infra): canonicalize session usage timestamps (#100687)
Co-authored-by: sheyanmin <44184140+sheyanmin@users.noreply.github.com>
2026-07-06 08:39:46 +01:00
Peter Steinberger
c1cbc15e60 fix(agents): preserve completed post-tool replies (#100655)
* fix(agents): prefer current attempt terminal state

Co-authored-by: weiqinl <liu.weiqin@xydigit.com>

* test(agents): model current attempt terminal state

---------

Co-authored-by: weiqinl <liu.weiqin@xydigit.com>
2026-07-06 08:38:30 +01:00
Wynne668
8380667bd0 fix(agents): keep bounded exec output UTF-16 safe (#98721)
* fix(agents): keep background exec exit notifications UTF-16 safe at the snippet cut

Background exec exit notifications truncate the command's tail output with a
raw String.slice, which can split a UTF-16 surrogate pair when an emoji lands
at the cut. Use the existing truncateUtf16Safe helper so the message delivered
to the channel never ends with a dangling surrogate half.

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

* fix(agents): protect exec notify tail boundaries

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

* fix(agents): protect node exec follow-up tails

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

* test(agents): type node exec follow-up assertions

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

* fix(agents): keep bounded exec output Unicode-safe

* docs(changelog): note exec output Unicode safety

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 08:36:40 +01:00
Peter Steinberger
9302c80ca6 fix(openai): route mp3 tts as voice messages (#100715)
Co-authored-by: Hemantsudarshan <hemanthsudarshan2002@gmail.com>
2026-07-06 08:34:08 +01:00
Hiroshi Tanaka
a118b32de8 fix(talk): resolve configured transcription providers (#97170)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 08:32:58 +01:00
Vincent Koc
798d4796e7 fix(release): pin Claude live CLI to SDK version 2026-07-06 00:22:26 -07:00
github-actions[bot]
de30d2f5c3 chore(i18n): refresh native locales 2026-07-06 07:20:11 +00:00
Peter Steinberger
62d5961b5d fix(ci): restore gateway architecture and lint gates (#100703)
* fix(ci): restore gateway architecture and lint gates

* fix(state): refresh gateway boot Kysely type
2026-07-06 08:19:04 +01:00
Peter Steinberger
d7d19a3a8e fix(openai): reuse Codex auth for realtime voice (#100671)
Co-authored-by: Peter Steinberger <steipete@openai.com>
2026-07-06 08:08:26 +01:00
Peter Steinberger
92ceaa2ba5 perf(test): avoid provider runtime in auth doctor unit test 2026-07-06 03:07:12 -04:00
Peter Steinberger
988c4d45dc docs(android): credit landed app improvements (#100702)
* docs(android): credit landed app improvements

* docs: sync ClawHub map
2026-07-06 08:06:54 +01:00
Ben.Li
86d5389094 fix(android): block loopback canvas navigation (#99874)
* fix(android): block loopback canvas navigation

* fix(android): reject Unicode canvas hosts

* chore(android): sync app changelog

* style(android): format canvas navigation policy

* chore(docs): sync generated docs map

* chore(ci): sync hosted gate verifier

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 08:00:02 +01:00
cxbAsDev
e66f43e276 fix(hooks): suppress unhandled stdout/stderr stream errors in gmail watcher (#100519)
* fix(hooks): suppress unhandled stdout/stderr stream errors in gmail watcher

* proof(gmail-watcher): add real behavior proof script for stream error catch

* proof(gmail-watcher): replace wrapper with real stream error proof

* style: apply oxfmt to changed files
2026-07-06 06:58:07 +00:00
Miorbnli
7d939b6456 fix(memory-core): guard qmd mcporter JSON.parse against non-JSON stdout (#98381)
* fix(memory-core): guard qmd mcporter JSON.parse against non-JSON stdout

runQmdSearchViaMcporter parsed mcporter subprocess stdout with JSON.parse
outside the runMcporter try/catch (qmd-manager.ts:2722). A non-JSON stdout
(daemon warning bleeding onto stdout, output truncated by maxOutputChars, CLI
killed early, or flag mismatch) threw a raw SyntaxError that propagated
uncaught out of runQmdSearchViaMcporter, surfacing in agent logs as a
context-free SyntaxError with no hint of the actual mcporter failure.

Wrap JSON.parse in try/catch and throw a typed Error carrying a stdout snippet
(matching the guard pattern already used in parseListedCollections in this
file, and the recent matrix #97973 / sms #97999 / signal #98073 /
telegram-ingress #98372 JSON.parse guard series).

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

* fix(memory-core): preserve cause in qmd mcporter JSON.parse guard

Add { cause: err } to the re-thrown Error to satisfy the preserve-caught-error
lint rule; the original SyntaxError is now chained, improving diagnosability.

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

* fix(memory-core): redact raw stdout from qmd mcporter error (security-boundary)

ClawSweeper flagged that the previous error message exposed raw mcporter
stdout (first 200 chars) before session visibility filtering, which could
leak sensitive content. Drop the stdout preview from the thrown message;
keep the original SyntaxError as `cause` for diagnostics so the parse-failure
reason is still reachable without surfacing unfiltered subprocess output.

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

* fix(memory-core): keep qmd mcporter error message generic (no raw stdout leak)

The SyntaxError thrown by JSON.parse embeds a snippet of the raw input in its
message (e.g. Unexpected token '<', then the raw bytes). Including that
SyntaxError message in the thrown Error would surface unfiltered mcporter
stdout before session visibility filtering. Drop the parse-error message from
the thrown Error; keep the original SyntaxError as cause for developer
diagnostics only.

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

* fix(memory-core): keep qmd mcporter cause generic (no raw stdout leak via formatErrorMessage)

formatErrorMessage walks the .cause chain into the user-visible path.
Keeping the JSON.parse SyntaxError on .cause leaked its embedded raw
stdout snippet through formatErrorMessage even with a generic message.
Give the cause a generic message too; the raw snippet no longer reaches
the user.

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-06 06:57:41 +00:00