Commit Graph

66965 Commits

Author SHA1 Message Date
Peter Steinberger
fa1a40a3c7 docs(changelog): credit Control UI fixes (#100740) 2026-07-06 10:09:10 +01:00
Peter Steinberger
aa0b5b1fb4 improve(ui): pin sidebar nav above a scrollable session list (#100742)
Nav routes (Overview, Workboard, Agents, More) now render first and stay
pinned; the session list owns the remaining sidebar height and scrolls
internally instead of being capped at min(42vh, 400px). Mobile drawer
matches the pinned-nav layout.
2026-07-06 10:08:29 +01:00
Peter Steinberger
d6801f23d4 feat(browser): restore driver "extension" via a loopback Chrome extension relay (no remote-debugging prompt) (#100619)
* feat(browser): restore driver "extension" via loopback Chrome extension relay

Reintroduces browser profile driver "extension" (removed in 2026.3.22) as a
loopback relay that drives the user's signed-in Chrome through an MV3 extension
instead of the remote-debugging port. This avoids Chrome's blocking "Allow
remote debugging?" prompt, which cannot be clicked when the operator drives
OpenClaw from a phone. Automated tabs live in an "OpenClaw" tab group (the
consent boundary), mirroring the Codex/Claude-in-Chrome model.

- relay bridge synthesizes the CDP browser target surface for Playwright
  connectOverCDP and forwards session-scoped commands to chrome.debugger
- relay server binds loopback only; both sides authenticate with a token
  derived (HMAC-SHA256) from gateway auth, so the raw credential never reaches
  Chrome; extension origin + loopback Host checks guard the upgrade
- built-in "chrome" profile; distinct relay ports per extension profile;
  relay reconciles on auth rotation / cdpPort change and prunes removed profiles
- doctor + status surface the extension transport; doctor keeps repairing the
  retired relay endpoint URL on legacy "extension" profiles

Refs #53599

* feat(browser): bundle the OpenClaw MV3 Chrome extension

Thin MV3 extension (chrome-extension/): a WebSocket client to the loopback
relay plus chrome.debugger forwarding and OpenClaw tab-group management. All
CDP target synthesis lives server-side in the relay bridge, so the extension
stays a dumb transport (the removed 2026.3 extension put that logic in a
1000-line untestable service worker). Popup handles pairing and per-tab share
toggle; `openclaw browser extension path|pair` load and pair it. A build copy
hook stages it into dist so the load path is stable.

Refs #53599

* docs(browser): document the Chrome extension profile

Adds docs/tools/chrome-extension for the restored extension driver (install,
pair, tab-group consent model, security posture) and wires it into the browser
docs profile section and nav.

Refs #53599

* feat(browser): make the extension relay work on remote browser nodes

Derives the relay auth token from a host-local secret in the credentials dir
(created on first use) instead of gateway auth. Each machine that runs a
browser — the gateway host and every browser node host — owns its own token, so
the extension pairs with whichever machine hosts its Chrome and no gateway
credential travels to a node. The node host already runs the shared browser
control bootstrap, so this is all that was missing for cross-machine control.

Also removes the "relay needs gateway auth before it can start" failure mode:
startup and `openclaw browser extension pair` ensure the secret exists.

Refs #53599

* fix(browser): harden relay secret creation and satisfy CI lint/typecheck

- Make the host-local relay secret creation atomic (O_CREAT|O_EXCL + adopt the
  winner on EEXIST) so the gateway service and `extension pair` CLI cannot mint
  divergent tokens on a fresh host (would 401 until restart); credentials dir
  created mode 0700. (adversarial review finding)
- Resolve type-aware oxlint findings across the relay + extension: unknown catch
  vars, addEventListener over ws.on* in the MV3 worker, void async listeners,
  drop useless returns/spreads, Object.assign over map-spread, safe ws frame
  decode (Buffer[]/ArrayBuffer), toSorted.
- Add extensionRelayDefaultPort/extensionRelayPorts to remaining test config
  literals; type the extension relay-core module (.d.ts, excluded from dist);
  regenerate docs_map.

* fix(browser): satisfy OpenGrep security policy on the relay

- Hash both operands before timingSafeEqual so token comparison has no
  length short-circuit (GHSA-JJ6Q-RRRF-H66H).
- Bound the relay WebSocketServer with maxPayload (64 MiB, headroom for CDP
  screenshots/bodies) against oversized frames (GHSA-VW3H-Q6XQ-JJM5).
- Rewrite the config test env helper to avoid the skill-env-host-injection
  shape (GHSA-82G8-464F-2MV7); it is a test-only env swap.
2026-07-06 10:08:27 +01:00
Peter Steinberger
ae6dc52da9 fix(control-ui): restore staged media filenames (#100743)
* fix(control-ui): restore staged media filenames

* fix(media): preserve inbound reference origin
2026-07-06 10:07:58 +01:00
xingzhou
37022833c5 fix(anthropic): include Fable 5 in context1m wrapper (#100572) 2026-07-06 02:07:36 -07:00
cxbAsDev
3dc00f4670 fix(agents): suppress unhandled stdout/stderr stream errors in execDockerRaw (#100523)
* fix(agents): suppress unhandled stdout/stderr stream errors in execDockerRaw

* proof(agents): add real behavior proof script for docker sandbox stream error catch

* proof(agents): replace wrapper with real docker sandbox stream error proof

* style: apply oxfmt to changed files

* chore(agents): align docker stream error handling

* fix(agents): fail Docker commands on stream errors

---------

Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 02:06:16 -07:00
Leonidas Lux
0f01930c8e fix(plugins): discover config load.paths plugins when index has entries (#99196)
* fix(plugins): discover config load.paths plugins when index has entries

Installing a managed npm plugin populates the persisted plugin index.
Once the index has entries (index.plugins.length > 0),
loadPluginManifestRegistryForInstalledIndex is used instead of the
full discovery path. This path only processes plugins that already
exist in the index — if workspace plugins from config plugins.load.paths
are missing from the index, they are silently dropped from the manifest
registry, producing 'plugin not found (stale config entry ignored)'
warnings on gateway startup and in CLI commands.

Fix: after converting index records to plugin candidates, also
discover plugins from config plugins.load.paths and merge any
candidates that are not already represented in the index-based
list. This ensures config-origin workspace plugins are always
included in the manifest registry regardless of index completeness.

Fixes #99185

* fix(plugins): address clawsweeper review — config-only scope, pluginId scoping, regression tests

- P1: Limit extra discovery scope to config-origin candidates only
  (filter by origin === 'config') instead of full discoverOpenClawPlugins
- P2: Preserve pluginId scoping for load-path candidates
  (filter extra candidates by pluginIdSet when present)
- Add 3 regression tests: load.paths discovery, empty-load no-op,
  pluginId scoping preservation
- Add L2 real behavior proof with direct function call evidence

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

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

* fix(plugins): replace discoverOpenClawPlugins with config-only discoverFromConfigPaths

P1: The installed-index fallback previously called discoverOpenClawPlugins,
which scans bundled/global/workspace roots and returns their diagnostics.
This allowed unrelated shared-root diagnostics to leak into the
installed-index config validation surface.

Replace it with discoverFromConfigPaths — a new helper that scans only
the user-configured plugins.load.paths entries via discoverFromPath
directly, producing zero bundled/global candidates or diagnostics.

P2: pluginId scoping is preserved for load-path candidates.

Added discoverFromConfigPaths to src/plugins/discovery.ts to keep the
config-only discovery path reusable and explicit.

🦞 diamond lobster: L2 evidence (terminal output from real dev build)

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

* fix(plugins): preserve bundled-load-path alias filtering in discoverFromConfigPaths

P2: The new discoverFromConfigPaths helper (added in Round 1 to fix the
P1 full-discovery issue) bypassed normal discovery's bundled-load-path
alias guard. If a user had a bundled plugin directory in their
plugins.load.paths, the installed-index fallback would treat it as a
valid config-origin candidate and potentially override/duplicate bundled
plugins.

Add resolvePackagedBundledLoadPathAlias check in discoverFromConfigPaths
before calling discoverFromPath, so bundled paths are skipped with a
warning diagnostic matching normal discovery behavior.

Add P2 regression test verifying bundled plugin load paths are ignored
on the installed-index path while real workspace load paths still work.

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

* fix(plugins): forward load-path diagnostics unconditionally in installed-index path

Previously, diagnostics from discoverFromConfigPaths were only forwarded
when at least one extra candidate survived filtering. Configs whose
plugins.load.paths contained only bundled aliases, missing paths, duplicates
already in the index, or scoped-out entries silently lost the normal
discovery warning or doctor hint.

Now extraDiagnostics is assigned outside the extraCandidates.length > 0
guard, so every config load-path diagnostic reaches the caller regardless
of whether a new candidate is merged.

Adds a focused regression test verifying that a bundled-only load path
still surfaces the expected alias-guard warning diagnostic.

🦞 diamond lobster: P2 fix, no new L2 evidence needed (regression test
covers the diagnostic-forwarding contract directly)

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

* fix(plugins): preserve requiresPlugins diagnostics for load paths in installed-index path

- [P2] Export addMissingRequiredPluginDiagnostics from discovery.ts for reuse
- [P2] Call addMissingRequiredPluginDiagnostics on combined index + load-path candidates before passing to loadPluginManifestRegistry
- [P2] Add regression tests: warns when load-path plugin requires missing plugin, does not false-warn when required plugin is already in index

🦞 diamond lobster: L2 + test coverage

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

* fix(plugins): add missing discovery.js mock exports for addMissingRequiredPluginDiagnostics

plugin-install.test.ts mocks discovery.js but the mock didn't include the
newly exported addMissingRequiredPluginDiagnostics, causing CI failures in
tests that exercise loadPluginManifestRegistryForInstalledIndex.

Also add discoverFromConfigPaths to the mock (already imported but was
only latent because the mock's code path wasn't triggered with load paths).

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

* fix(plugins): rebuild stale configured plugin indexes

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-06 02:01:00 -07:00
Peter Steinberger
0423c142c1 fix(ui): open embedded terminal before login gate (#100727) 2026-07-06 10:00:56 +01:00
github-actions[bot]
66ad841b3e chore(i18n): refresh native locales 2026-07-06 09:00:16 +00:00
zhangqueping
adc4136a3b fix(memory-wiki): strip fenced code and inline code before wikilink extraction (#98095)
* fix(memory-wiki): strip fenced code and inline code before wikilink extraction

The wikilink extractor in extractWikiLinks previously scanned
the full markdown content including fenced code blocks and
inline code spans.  Literal [[...]] syntax inside code regions
(e.g. bash test syntax, Scala generics like
Future[Option[User]]) produced false-positive broken-wikilink
lint warnings.

Add FENCED_CODE_BLOCK_PATTERN and INLINE_CODE_PATTERN and
strip those regions from the searchable text before running
the Obsidian and Markdown link regexes.  Five regression tests
cover backtick-fenced, tilde-fenced, 6-backtick-fenced, and
inline code scenarios plus a full vault lint round-trip.

Fixes #97945

* fix(memory-wiki): accept longer closing fence in code block stripping

The FENCED_CODE_BLOCK_PATTERN used a regex backreference (\1)
that required the closing fence to be exactly identical to the
opening fence.  CommonMark allows the closing fence to be the
same character type and at least as long — e.g. ``` opening
with ```` closing is valid.  Switch to a function-based
replacement that compares fence character type and length.

Add regression test for the longer-closing-fence case per
ClawSweeper review feedback (#98095).

* style(memory-wiki): add braces to if-body in fence replacement callback

Fixes ESLint curly rule violation at line 403.

* fix(memory-wiki): replace fence regex with line scanner for wikilink extraction

Replace FENCED_CODE_BLOCK_RE regex/callback with a line-by-line scanner
that keeps searching past invalid fence-looking lines (e.g. a shorter
``` line inside a longer `````` block) until a valid closing
fence of the same character type and at least as long is found.

Also handles tilde fences and longer closing fences per CommonMark spec.

🦞 diamond lobster: L2 evidence (5 real function-call scenarios, all passing)

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

* fix(memory-wiki): use CommonMark code masking

---------

Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
2026-07-06 02:00:12 -07:00
Vincent Koc
2b9bd7c65f docs(changelog): remove generated main entries 2026-07-06 10:56:01 +02:00
Peter Steinberger
2f44350351 perf(test): drop duplicate model alias coverage 2026-07-06 04:54:59 -04:00
Peter Steinberger
3170bfa489 fix(ui): proxy canonical inbound media previews (#100725)
Co-authored-by: Cornna <96944678+ymylive@users.noreply.github.com>
2026-07-06 09:54:19 +01:00
Vincent Koc
8b2e9ddc64 improve(skills): reactive-correction capture with shared workshop invariant (#100576) (#100576)
Reactive corrections ("that's not what I asked", "stop doing X") now
count as durable signals: expanded extraction patterns, vocabulary
routing to existing workspace skills, per-skill grouping. Both capture
modes share one invariant: a bounded signal-fingerprint ring on the
session entry prevents replaying applied/rejected corrections, pending
autocapture-owned proposals are revised instead of skipped, /learn-style
turns suppress duplicate agent-end capture, and extraction runs before
any skill discovery. Autonomy off keeps the suggest-tier offer; autonomy
on files/revises proposals directly.

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 09:50:46 +01:00
Masato Hoshino
e7158a581d Surface config hot-reload watcher status in health (#99267)
* fix(gateway): surface config hot-reload watcher status in health

Thread the config reloader's existing hotReloadStatus() accessor through
the managed reloader handle (previously only stop() survived the handoff)
and into openclaw health as an optional configReload.hotReloadStatus
field, so operators can tell when the watcher has permanently disabled
itself after exhausting retries instead of silently running with stale
config.

* fix(gateway): keep configReload.hotReloadStatus fresh on cached health responses

Thread getConfigReloaderHotReloadStatus through GatewayRequestContext
(mirroring the existing getEventLoopHealth pattern) so the health RPC's
cache-hit merge path picks up a live watcher disable within the same
request instead of waiting up to HEALTH_REFRESH_INTERVAL_MS for the
background refresh to catch up.

* fix(health): move config reload status type to leaf contract

Move GatewayHotReloadStatus out of config-reload.ts into a leaf
config-reload-status.types.ts so health/request-context/runtime-handles
callers no longer pull the full config-reload implementation into the
shared server-method type graph (ClawSweeper-flagged architecture cycle).

* test(gateway): update config reloader fixture

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-06 01:48:54 -07:00
jincheng-xydt
ba9700d59a fix #99163: harden large chat attachment parsing (#99213)
* fix(gateway): harden large chat attachment parsing

* test(ui): prove large chat image paste

* fix(media): preserve short MIME rejection

---------

Co-authored-by: xjch <267882353+jincheng-xydt@users.noreply.github.com>
Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
2026-07-06 01:47:21 -07:00
Masato Hoshino
310c2f58b9 improve(cron): show consecutive failure count and last error in cron CLI output (#99602)
* improve(cron): show consecutive failure count and last error in cron list/show

* improve(cron): show consecutive failure count and last error in cron CLI output

* fix(clownfish): address review for live-pr-inventory-20260706T074223-002 (1)

---------

Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
2026-07-06 01:44:51 -07:00
Peter Steinberger
1b44efec8c feat(ui): redesign session goal into interactive composer pill with elapsed time and /goal edit (#100736)
* feat(ui): redesign session goal into interactive composer pill with elapsed time and /goal edit

* docs: align goal command table cell padding

* docs: regenerate docs map for goal Control UI section
2026-07-06 09:42:49 +01:00
cxbAsDev
b80c276f13 fix(crestodian): catch rejection from async respond in sendChat (#100341)
* fix(crestodian): catch rejection from async respond in sendChat

* test(crestodian): fix type cast in sendChat rejection test

* proof(crestodian): remove unused finish binding in proof script

* test(crestodian): make sendChat proof fail on current main by rejecting respond itself

* test(crestodian): remove unused eslint-disable directives

* fix(crestodian): isolate TUI event consumer failures

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-06 01:42:47 -07:00
Peter Steinberger
5f3629e944 fix(ui): show selected agent default model (#100719)
Co-authored-by: Harry Xie <harryhsieh963@yahoo.com>
2026-07-06 09:41:38 +01:00
Ben.Li
489af13dbd fix(android): accept boolean flag aliases in node invoke params (#99873)
* fix(android): accept boolean flag aliases in node invoke params

Extend parseJsonBooleanFlag to recognize yes/no/1/0 like TalkDirectiveParser so node handlers honor common string boolean inputs.

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

* fix(android): route CameraHandler includeAudio through alias parser

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

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 01:36:53 -07:00
zhangLei99586
9f8bc7fa37 fix(mcp-grant): guard sessionKey.trim() against undefined input (#99488)
The mintAttachGrant caller resolves sessionKey via readString() ??
resolveMainSessionKey(). If both return undefined, .trim() throws
TypeError. Use optional chaining + nullish coalescing so the existing
if (!sessionKey) validation guard executes instead of crashing.
2026-07-06 01:36:44 -07:00
Peter Steinberger
cc88aa6c3c fix(channels): canonicalize bundled module boundaries (#100758)
Co-authored-by: Peter Steinberger <steipete@openai.com>
2026-07-06 09:34:49 +01:00
NianJiu
a0c0f43ab3 fix(android): serialize PTT microphone ownership (#99986)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>
2026-07-06 09:33:00 +01:00
Peter Steinberger
ca2e508f87 perf(test): isolate doctor migration plugin discovery 2026-07-06 04:31:06 -04:00
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